From 114a878c64ce6f8223cfd22d76a20eb16d177e5e Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdevelop@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- buildtools/Makefile.am | 48 + buildtools/ada/Makefile.am | 18 + buildtools/ada/README.dox | 17 + buildtools/ada/adaglobaloptionsdlg.cpp | 129 + buildtools/ada/adaglobaloptionsdlg.h | 50 + buildtools/ada/adaproject_optionsdlgbase.ui | 472 ++++ buildtools/ada/adaproject_part.cpp | 465 ++++ buildtools/ada/adaproject_part.h | 93 + buildtools/ada/adaproject_widget.cpp | 24 + buildtools/ada/adaproject_widget.h | 21 + buildtools/ada/adaprojectoptionsdlg.cpp | 208 ++ buildtools/ada/adaprojectoptionsdlg.h | 57 + buildtools/ada/kdevadaproject.desktop | 100 + buildtools/ada/kdevadaproject.rc | 14 + buildtools/ada/service.cpp | 75 + buildtools/ada/service.h | 27 + buildtools/ant/Makefile.am | 21 + buildtools/ant/README.dox | 8 + buildtools/ant/antoptionswidget.ui | 173 ++ buildtools/ant/antprojectpart.cpp | 608 ++++ buildtools/ant/antprojectpart.h | 117 + buildtools/ant/classpathwidget.ui | 39 + buildtools/ant/kdevantproject.desktop | 96 + buildtools/ant/kdevantproject.rc | 14 + buildtools/autotools/Makefile.am | 38 + buildtools/autotools/README | 1 + buildtools/autotools/README.dox | 39 + buildtools/autotools/addapplicationdlg.cpp | 207 ++ buildtools/autotools/addapplicationdlg.h | 45 + buildtools/autotools/addapplicationdlgbase.ui | 552 ++++ buildtools/autotools/addexistingdirectoriesdlg.cpp | 388 +++ buildtools/autotools/addexistingdirectoriesdlg.h | 74 + buildtools/autotools/addexistingdlgbase.ui | 459 ++++ buildtools/autotools/addexistingfilesdlg.cpp | 451 +++ buildtools/autotools/addexistingfilesdlg.h | 77 + buildtools/autotools/addfiledlg.cpp | 135 + buildtools/autotools/addfiledlg.h | 47 + buildtools/autotools/addfiledlgbase.ui | 289 ++ buildtools/autotools/addicondlg.cpp | 115 + buildtools/autotools/addicondlg.h | 44 + buildtools/autotools/addicondlgbase.ui | 273 ++ buildtools/autotools/addprefixdlg.cpp | 76 + buildtools/autotools/addprefixdlg.h | 45 + buildtools/autotools/addservicedlg.cpp | 233 ++ buildtools/autotools/addservicedlg.h | 46 + buildtools/autotools/addservicedlgbase.ui | 544 ++++ buildtools/autotools/addsubprojectdlg.cpp | 198 ++ buildtools/autotools/addsubprojectdlg.h | 44 + buildtools/autotools/addsubprojectdlgbase.ui | 198 ++ buildtools/autotools/addtargetdlg.cpp | 226 ++ buildtools/autotools/addtargetdlg.h | 43 + buildtools/autotools/addtargetdlgbase.ui | 348 +++ buildtools/autotools/addtranslationdlg.cpp | 109 + buildtools/autotools/addtranslationdlg.h | 36 + buildtools/autotools/autodetailsview.cpp | 728 +++++ buildtools/autotools/autodetailsview.h | 88 + buildtools/autotools/autolistviewitems.cpp | 181 ++ buildtools/autotools/autolistviewitems.h | 143 + buildtools/autotools/autoprojectpart.cpp | 1474 ++++++++++ buildtools/autotools/autoprojectpart.h | 153 ++ buildtools/autotools/autoprojectviewbase.ui | 123 + buildtools/autotools/autoprojectwidget.cpp | 748 +++++ buildtools/autotools/autoprojectwidget.h | 229 ++ buildtools/autotools/autosubprojectview.cpp | 1137 ++++++++ buildtools/autotools/autosubprojectview.h | 130 + buildtools/autotools/autotoolsaction.cpp | 156 ++ buildtools/autotools/autotoolsaction.h | 70 + buildtools/autotools/choosetargetdialog.cpp | 348 +++ buildtools/autotools/choosetargetdialog.h | 57 + buildtools/autotools/choosetargetdlgbase.ui | 222 ++ buildtools/autotools/configureoptionswidget.cpp | 431 +++ buildtools/autotools/configureoptionswidget.h | 69 + buildtools/autotools/configureoptionswidgetbase.ui | 1040 +++++++ buildtools/autotools/fileselectorwidget.cpp | 243 ++ buildtools/autotools/fileselectorwidget.h | 96 + buildtools/autotools/kdevautoproject.desktop | 97 + buildtools/autotools/kdevautoproject.rc | 30 + buildtools/autotools/kdevkdeautoproject.desktop | 92 + buildtools/autotools/kfilednddetailview.cpp | 212 ++ buildtools/autotools/kfilednddetailview.h | 136 + buildtools/autotools/kfiledndiconview.cpp | 194 ++ buildtools/autotools/kfiledndiconview.h | 128 + buildtools/autotools/kimporticonview.cpp | 87 + buildtools/autotools/kimporticonview.h | 44 + buildtools/autotools/makefilehandler.cpp | 166 ++ buildtools/autotools/makefilehandler.h | 76 + buildtools/autotools/managecustomcommand.cpp | 49 + buildtools/autotools/managecustomcommand.h | 37 + buildtools/autotools/managecustomcommandsbase.ui | 125 + buildtools/autotools/misc.cpp | 999 +++++++ buildtools/autotools/misc.h | 65 + buildtools/autotools/removefiledlg.cpp | 182 ++ buildtools/autotools/removefiledlg.h | 51 + buildtools/autotools/removefiledlgbase.ui | 233 ++ buildtools/autotools/removetargetdlg.cpp | 279 ++ buildtools/autotools/removetargetdlg.h | 55 + buildtools/autotools/removetargetdlgbase.ui | 264 ++ buildtools/autotools/subprojectoptionsdlg.cpp | 404 +++ buildtools/autotools/subprojectoptionsdlg.h | 63 + buildtools/autotools/subprojectoptionsdlgbase.ui | 989 +++++++ buildtools/autotools/targetoptionsdlg.cpp | 357 +++ buildtools/autotools/targetoptionsdlg.h | 49 + buildtools/autotools/targetoptionsdlgbase.ui | 726 +++++ buildtools/custommakefiles/Makefile.am | 26 + buildtools/custommakefiles/README.dox | 47 + .../custommakefiles/custombuildoptionswidget.cpp | 99 + .../custommakefiles/custombuildoptionswidget.h | 46 + .../custombuildoptionswidgetbase.ui | 164 ++ .../custommakefiles/custommakeconfigwidget.cpp | 134 + .../custommakefiles/custommakeconfigwidget.h | 54 + .../custommakefiles/custommakeconfigwidgetbase.ui | 395 +++ buildtools/custommakefiles/custommanagerwidget.cpp | 80 + buildtools/custommakefiles/custommanagerwidget.h | 41 + .../custommakefiles/custommanagerwidgetbase.ui | 74 + .../custommakefiles/customotherconfigwidget.cpp | 125 + .../custommakefiles/customotherconfigwidget.h | 57 + .../custommakefiles/customotherconfigwidgetbase.ui | 288 ++ buildtools/custommakefiles/customprojectpart.cpp | 1669 +++++++++++ buildtools/custommakefiles/customprojectpart.h | 158 ++ .../custommakefiles/kdevcustomproject.desktop | 91 + buildtools/custommakefiles/kdevcustomproject.rc | 30 + .../custommakefiles/selectnewfilesdialog.cpp | 131 + buildtools/custommakefiles/selectnewfilesdialog.h | 53 + .../custommakefiles/selectnewfilesdialogbase.ui | 50 + buildtools/lib/Makefile.am | 8 + buildtools/lib/base/Mainpage.dox | 19 + buildtools/lib/base/Makefile.am | 15 + buildtools/lib/base/kdevbuildtool.cpp | 38 + buildtools/lib/base/kdevbuildtool.h | 41 + buildtools/lib/parsers/Makefile.am | 8 + buildtools/lib/parsers/autotools/Mainpage.dox | 11 + buildtools/lib/parsers/autotools/Makefile.am | 24 + buildtools/lib/parsers/autotools/autotools.ll | 136 + buildtools/lib/parsers/autotools/autotools.yy | 323 +++ buildtools/lib/parsers/autotools/autotools_lex.cpp | 1894 +++++++++++++ .../lib/parsers/autotools/autotools_yacc.cpp | 1631 +++++++++++ buildtools/lib/parsers/autotools/autotools_yacc.h | 100 + buildtools/lib/parsers/autotools/autotoolsast.cpp | 117 + buildtools/lib/parsers/autotools/autotoolsast.h | 269 ++ .../lib/parsers/autotools/autotoolsdriver.cpp | 70 + buildtools/lib/parsers/autotools/autotoolsdriver.h | 76 + buildtools/lib/parsers/autotools/tests/Makefile.am | 21 + buildtools/lib/parsers/autotools/tests/runner.cpp | 33 + buildtools/lib/parsers/autotools/tests/viewer.cpp | 162 ++ buildtools/lib/parsers/autotools/tests/viewer.h | 46 + .../lib/parsers/autotools/tests/viewer_main.cpp | 34 + .../lib/parsers/autotools/tests/viewerbase.ui | 220 ++ buildtools/lib/parsers/qmake/FlexLexer.h | 205 ++ buildtools/lib/parsers/qmake/Mainpage.dox | 16 + buildtools/lib/parsers/qmake/Makefile.am | 31 + buildtools/lib/parsers/qmake/location.hh | 145 + buildtools/lib/parsers/qmake/position.hh | 142 + buildtools/lib/parsers/qmake/qmake.ll | 237 ++ buildtools/lib/parsers/qmake/qmake.yy | 430 +++ buildtools/lib/parsers/qmake/qmake_lex.cpp | 2239 +++++++++++++++ buildtools/lib/parsers/qmake/qmake_lex.h | 49 + buildtools/lib/parsers/qmake/qmake_yacc.cpp | 1243 +++++++++ buildtools/lib/parsers/qmake/qmake_yacc.hpp | 418 +++ buildtools/lib/parsers/qmake/qmakeast.cpp | 170 ++ buildtools/lib/parsers/qmake/qmakeast.h | 236 ++ buildtools/lib/parsers/qmake/qmakeastvisitor.cpp | 68 + buildtools/lib/parsers/qmake/qmakeastvisitor.h | 46 + buildtools/lib/parsers/qmake/qmakedriver.cpp | 113 + buildtools/lib/parsers/qmake/qmakedriver.h | 55 + buildtools/lib/parsers/qmake/stack.hh | 129 + buildtools/lib/parsers/qmake/tests/Makefile.am | 21 + buildtools/lib/parsers/qmake/tests/runner.cpp | 169 ++ buildtools/lib/parsers/qmake/tests/viewer.cpp | 182 ++ buildtools/lib/parsers/qmake/tests/viewer.h | 48 + buildtools/lib/parsers/qmake/tests/viewer_main.cpp | 33 + buildtools/lib/parsers/qmake/tests/viewerbase.ui | 250 ++ buildtools/lib/widgets/Mainpage.dox | 10 + buildtools/lib/widgets/Makefile.am | 30 + buildtools/lib/widgets/addenvvardlg.cpp | 84 + buildtools/lib/widgets/addenvvardlg.h | 54 + buildtools/lib/widgets/addfilesdialog.cpp | 78 + buildtools/lib/widgets/addfilesdialog.h | 57 + .../lib/widgets/environmentdisplaydialog.cpp | 54 + buildtools/lib/widgets/environmentdisplaydialog.h | 35 + .../lib/widgets/environmentdisplaydialogbase.ui | 111 + .../lib/widgets/environmentvariableswidget.cpp | 126 + .../lib/widgets/environmentvariableswidget.h | 59 + .../lib/widgets/environmentvariableswidgetbase.ui | 200 ++ buildtools/lib/widgets/envvartools.cpp | 31 + buildtools/lib/widgets/envvartools.h | 28 + buildtools/lib/widgets/makeoptionswidget.cpp | 64 + buildtools/lib/widgets/makeoptionswidget.h | 50 + buildtools/lib/widgets/makeoptionswidgetbase.ui | 194 ++ buildtools/lib/widgets/removesubprojectdialog.cpp | 52 + buildtools/lib/widgets/removesubprojectdialog.h | 52 + buildtools/lib/widgets/removesubprojectdlgbase.ui | 154 ++ buildtools/lib/widgets/runoptionswidget.cpp | 138 + buildtools/lib/widgets/runoptionswidget.h | 57 + buildtools/lib/widgets/runoptionswidgetbase.ui | 257 ++ buildtools/lib/widgets/subclassesdlg.cpp | 122 + buildtools/lib/widgets/subclassesdlg.h | 58 + buildtools/lib/widgets/subclassesdlgbase.ui | 224 ++ buildtools/pascal/Makefile.am | 24 + buildtools/pascal/README.dox | 13 + buildtools/pascal/kdevpascalproject.desktop | 93 + buildtools/pascal/kdevpascalproject.rc | 14 + buildtools/pascal/pascalglobaloptionsdlg.cpp | 132 + buildtools/pascal/pascalglobaloptionsdlg.h | 52 + buildtools/pascal/pascalproject_optionsdlgbase.ui | 474 ++++ buildtools/pascal/pascalproject_part.cpp | 493 ++++ buildtools/pascal/pascalproject_part.h | 95 + buildtools/pascal/pascalproject_widget.cpp | 26 + buildtools/pascal/pascalproject_widget.h | 25 + buildtools/pascal/pascalprojectoptionsdlg.cpp | 210 ++ buildtools/pascal/pascalprojectoptionsdlg.h | 59 + buildtools/pascal/service.cpp | 77 + buildtools/pascal/service.h | 29 + buildtools/qmake/Makefile.am | 34 + buildtools/qmake/README | 1 + buildtools/qmake/README.dox | 39 + buildtools/qmake/choosesubprojectdlg.cpp | 114 + buildtools/qmake/choosesubprojectdlg.h | 64 + buildtools/qmake/choosesubprojectdlgbase.ui | 134 + buildtools/qmake/createscopedlg.cpp | 100 + buildtools/qmake/createscopedlg.h | 45 + buildtools/qmake/createscopedlgbase.ui | 329 +++ buildtools/qmake/disablesubprojectdlg.cpp | 50 + buildtools/qmake/disablesubprojectdlg.h | 42 + buildtools/qmake/disablesubprojectdlgbase.ui | 126 + buildtools/qmake/kdevtmakeproject.desktop | 91 + buildtools/qmake/kdevtrollproject.desktop | 95 + buildtools/qmake/kdevtrollproject.rc | 33 + buildtools/qmake/newwidgetdlg.cpp | 80 + buildtools/qmake/newwidgetdlg.h | 38 + buildtools/qmake/newwidgetdlgbase.ui | 229 ++ buildtools/qmake/projectconfigurationdlg.cpp | 2174 +++++++++++++++ buildtools/qmake/projectconfigurationdlg.h | 145 + buildtools/qmake/projectconfigurationdlgbase.ui | 2897 ++++++++++++++++++++ buildtools/qmake/qmakedefaultopts.cpp | 91 + buildtools/qmake/qmakedefaultopts.h | 49 + buildtools/qmake/qmakeoptionswidget.cpp | 63 + buildtools/qmake/qmakeoptionswidget.h | 39 + buildtools/qmake/qmakeoptionswidgetbase.ui | 217 ++ buildtools/qmake/qmakescopeitem.cpp | 928 +++++++ buildtools/qmake/qmakescopeitem.h | 128 + buildtools/qmake/scope.cpp | 1710 ++++++++++++ buildtools/qmake/scope.h | 308 +++ buildtools/qmake/trolllistview.cpp | 38 + buildtools/qmake/trolllistview.h | 41 + buildtools/qmake/trollprojectpart.cpp | 931 +++++++ buildtools/qmake/trollprojectpart.h | 105 + buildtools/qmake/trollprojectwidget.cpp | 2547 +++++++++++++++++ buildtools/qmake/trollprojectwidget.h | 218 ++ buildtools/script/Makefile.am | 26 + buildtools/script/README.dox | 48 + buildtools/script/kdevscriptproject.desktop | 87 + buildtools/script/kdevscriptproject.rc | 12 + buildtools/script/scriptnewfiledlg.cpp | 119 + buildtools/script/scriptnewfiledlg.h | 39 + buildtools/script/scriptoptionswidget.cpp | 69 + buildtools/script/scriptoptionswidget.h | 35 + buildtools/script/scriptoptionswidgetbase.ui | 155 ++ buildtools/script/scriptprojectpart.cpp | 446 +++ buildtools/script/scriptprojectpart.h | 69 + 259 files changed, 57685 insertions(+) create mode 100644 buildtools/Makefile.am create mode 100644 buildtools/ada/Makefile.am create mode 100644 buildtools/ada/README.dox create mode 100644 buildtools/ada/adaglobaloptionsdlg.cpp create mode 100644 buildtools/ada/adaglobaloptionsdlg.h create mode 100644 buildtools/ada/adaproject_optionsdlgbase.ui create mode 100644 buildtools/ada/adaproject_part.cpp create mode 100644 buildtools/ada/adaproject_part.h create mode 100644 buildtools/ada/adaproject_widget.cpp create mode 100644 buildtools/ada/adaproject_widget.h create mode 100644 buildtools/ada/adaprojectoptionsdlg.cpp create mode 100644 buildtools/ada/adaprojectoptionsdlg.h create mode 100644 buildtools/ada/kdevadaproject.desktop create mode 100644 buildtools/ada/kdevadaproject.rc create mode 100644 buildtools/ada/service.cpp create mode 100644 buildtools/ada/service.h create mode 100644 buildtools/ant/Makefile.am create mode 100644 buildtools/ant/README.dox create mode 100644 buildtools/ant/antoptionswidget.ui create mode 100644 buildtools/ant/antprojectpart.cpp create mode 100644 buildtools/ant/antprojectpart.h create mode 100644 buildtools/ant/classpathwidget.ui create mode 100644 buildtools/ant/kdevantproject.desktop create mode 100644 buildtools/ant/kdevantproject.rc create mode 100644 buildtools/autotools/Makefile.am create mode 100644 buildtools/autotools/README create mode 100644 buildtools/autotools/README.dox create mode 100644 buildtools/autotools/addapplicationdlg.cpp create mode 100644 buildtools/autotools/addapplicationdlg.h create mode 100644 buildtools/autotools/addapplicationdlgbase.ui create mode 100644 buildtools/autotools/addexistingdirectoriesdlg.cpp create mode 100644 buildtools/autotools/addexistingdirectoriesdlg.h create mode 100644 buildtools/autotools/addexistingdlgbase.ui create mode 100644 buildtools/autotools/addexistingfilesdlg.cpp create mode 100644 buildtools/autotools/addexistingfilesdlg.h create mode 100644 buildtools/autotools/addfiledlg.cpp create mode 100644 buildtools/autotools/addfiledlg.h create mode 100644 buildtools/autotools/addfiledlgbase.ui create mode 100644 buildtools/autotools/addicondlg.cpp create mode 100644 buildtools/autotools/addicondlg.h create mode 100644 buildtools/autotools/addicondlgbase.ui create mode 100644 buildtools/autotools/addprefixdlg.cpp create mode 100644 buildtools/autotools/addprefixdlg.h create mode 100644 buildtools/autotools/addservicedlg.cpp create mode 100644 buildtools/autotools/addservicedlg.h create mode 100644 buildtools/autotools/addservicedlgbase.ui create mode 100644 buildtools/autotools/addsubprojectdlg.cpp create mode 100644 buildtools/autotools/addsubprojectdlg.h create mode 100644 buildtools/autotools/addsubprojectdlgbase.ui create mode 100644 buildtools/autotools/addtargetdlg.cpp create mode 100644 buildtools/autotools/addtargetdlg.h create mode 100644 buildtools/autotools/addtargetdlgbase.ui create mode 100644 buildtools/autotools/addtranslationdlg.cpp create mode 100644 buildtools/autotools/addtranslationdlg.h create mode 100644 buildtools/autotools/autodetailsview.cpp create mode 100644 buildtools/autotools/autodetailsview.h create mode 100644 buildtools/autotools/autolistviewitems.cpp create mode 100644 buildtools/autotools/autolistviewitems.h create mode 100644 buildtools/autotools/autoprojectpart.cpp create mode 100644 buildtools/autotools/autoprojectpart.h create mode 100644 buildtools/autotools/autoprojectviewbase.ui create mode 100644 buildtools/autotools/autoprojectwidget.cpp create mode 100644 buildtools/autotools/autoprojectwidget.h create mode 100644 buildtools/autotools/autosubprojectview.cpp create mode 100644 buildtools/autotools/autosubprojectview.h create mode 100644 buildtools/autotools/autotoolsaction.cpp create mode 100644 buildtools/autotools/autotoolsaction.h create mode 100644 buildtools/autotools/choosetargetdialog.cpp create mode 100644 buildtools/autotools/choosetargetdialog.h create mode 100644 buildtools/autotools/choosetargetdlgbase.ui create mode 100644 buildtools/autotools/configureoptionswidget.cpp create mode 100644 buildtools/autotools/configureoptionswidget.h create mode 100644 buildtools/autotools/configureoptionswidgetbase.ui create mode 100644 buildtools/autotools/fileselectorwidget.cpp create mode 100644 buildtools/autotools/fileselectorwidget.h create mode 100644 buildtools/autotools/kdevautoproject.desktop create mode 100644 buildtools/autotools/kdevautoproject.rc create mode 100644 buildtools/autotools/kdevkdeautoproject.desktop create mode 100644 buildtools/autotools/kfilednddetailview.cpp create mode 100644 buildtools/autotools/kfilednddetailview.h create mode 100644 buildtools/autotools/kfiledndiconview.cpp create mode 100644 buildtools/autotools/kfiledndiconview.h create mode 100644 buildtools/autotools/kimporticonview.cpp create mode 100644 buildtools/autotools/kimporticonview.h create mode 100644 buildtools/autotools/makefilehandler.cpp create mode 100644 buildtools/autotools/makefilehandler.h create mode 100644 buildtools/autotools/managecustomcommand.cpp create mode 100644 buildtools/autotools/managecustomcommand.h create mode 100644 buildtools/autotools/managecustomcommandsbase.ui create mode 100644 buildtools/autotools/misc.cpp create mode 100644 buildtools/autotools/misc.h create mode 100644 buildtools/autotools/removefiledlg.cpp create mode 100644 buildtools/autotools/removefiledlg.h create mode 100644 buildtools/autotools/removefiledlgbase.ui create mode 100644 buildtools/autotools/removetargetdlg.cpp create mode 100644 buildtools/autotools/removetargetdlg.h create mode 100644 buildtools/autotools/removetargetdlgbase.ui create mode 100644 buildtools/autotools/subprojectoptionsdlg.cpp create mode 100644 buildtools/autotools/subprojectoptionsdlg.h create mode 100644 buildtools/autotools/subprojectoptionsdlgbase.ui create mode 100644 buildtools/autotools/targetoptionsdlg.cpp create mode 100644 buildtools/autotools/targetoptionsdlg.h create mode 100644 buildtools/autotools/targetoptionsdlgbase.ui create mode 100644 buildtools/custommakefiles/Makefile.am create mode 100644 buildtools/custommakefiles/README.dox create mode 100644 buildtools/custommakefiles/custombuildoptionswidget.cpp create mode 100644 buildtools/custommakefiles/custombuildoptionswidget.h create mode 100644 buildtools/custommakefiles/custombuildoptionswidgetbase.ui create mode 100644 buildtools/custommakefiles/custommakeconfigwidget.cpp create mode 100644 buildtools/custommakefiles/custommakeconfigwidget.h create mode 100644 buildtools/custommakefiles/custommakeconfigwidgetbase.ui create mode 100644 buildtools/custommakefiles/custommanagerwidget.cpp create mode 100644 buildtools/custommakefiles/custommanagerwidget.h create mode 100644 buildtools/custommakefiles/custommanagerwidgetbase.ui create mode 100644 buildtools/custommakefiles/customotherconfigwidget.cpp create mode 100644 buildtools/custommakefiles/customotherconfigwidget.h create mode 100644 buildtools/custommakefiles/customotherconfigwidgetbase.ui create mode 100644 buildtools/custommakefiles/customprojectpart.cpp create mode 100644 buildtools/custommakefiles/customprojectpart.h create mode 100644 buildtools/custommakefiles/kdevcustomproject.desktop create mode 100644 buildtools/custommakefiles/kdevcustomproject.rc create mode 100644 buildtools/custommakefiles/selectnewfilesdialog.cpp create mode 100644 buildtools/custommakefiles/selectnewfilesdialog.h create mode 100644 buildtools/custommakefiles/selectnewfilesdialogbase.ui create mode 100644 buildtools/lib/Makefile.am create mode 100644 buildtools/lib/base/Mainpage.dox create mode 100644 buildtools/lib/base/Makefile.am create mode 100644 buildtools/lib/base/kdevbuildtool.cpp create mode 100644 buildtools/lib/base/kdevbuildtool.h create mode 100644 buildtools/lib/parsers/Makefile.am create mode 100644 buildtools/lib/parsers/autotools/Mainpage.dox create mode 100644 buildtools/lib/parsers/autotools/Makefile.am create mode 100644 buildtools/lib/parsers/autotools/autotools.ll create mode 100644 buildtools/lib/parsers/autotools/autotools.yy create mode 100644 buildtools/lib/parsers/autotools/autotools_lex.cpp create mode 100644 buildtools/lib/parsers/autotools/autotools_yacc.cpp create mode 100644 buildtools/lib/parsers/autotools/autotools_yacc.h create mode 100644 buildtools/lib/parsers/autotools/autotoolsast.cpp create mode 100644 buildtools/lib/parsers/autotools/autotoolsast.h create mode 100644 buildtools/lib/parsers/autotools/autotoolsdriver.cpp create mode 100644 buildtools/lib/parsers/autotools/autotoolsdriver.h create mode 100644 buildtools/lib/parsers/autotools/tests/Makefile.am create mode 100644 buildtools/lib/parsers/autotools/tests/runner.cpp create mode 100644 buildtools/lib/parsers/autotools/tests/viewer.cpp create mode 100644 buildtools/lib/parsers/autotools/tests/viewer.h create mode 100644 buildtools/lib/parsers/autotools/tests/viewer_main.cpp create mode 100644 buildtools/lib/parsers/autotools/tests/viewerbase.ui create mode 100644 buildtools/lib/parsers/qmake/FlexLexer.h create mode 100644 buildtools/lib/parsers/qmake/Mainpage.dox create mode 100644 buildtools/lib/parsers/qmake/Makefile.am create mode 100644 buildtools/lib/parsers/qmake/location.hh create mode 100644 buildtools/lib/parsers/qmake/position.hh create mode 100644 buildtools/lib/parsers/qmake/qmake.ll create mode 100644 buildtools/lib/parsers/qmake/qmake.yy create mode 100644 buildtools/lib/parsers/qmake/qmake_lex.cpp create mode 100644 buildtools/lib/parsers/qmake/qmake_lex.h create mode 100644 buildtools/lib/parsers/qmake/qmake_yacc.cpp create mode 100644 buildtools/lib/parsers/qmake/qmake_yacc.hpp create mode 100644 buildtools/lib/parsers/qmake/qmakeast.cpp create mode 100644 buildtools/lib/parsers/qmake/qmakeast.h create mode 100644 buildtools/lib/parsers/qmake/qmakeastvisitor.cpp create mode 100644 buildtools/lib/parsers/qmake/qmakeastvisitor.h create mode 100644 buildtools/lib/parsers/qmake/qmakedriver.cpp create mode 100644 buildtools/lib/parsers/qmake/qmakedriver.h create mode 100644 buildtools/lib/parsers/qmake/stack.hh create mode 100644 buildtools/lib/parsers/qmake/tests/Makefile.am create mode 100644 buildtools/lib/parsers/qmake/tests/runner.cpp create mode 100644 buildtools/lib/parsers/qmake/tests/viewer.cpp create mode 100644 buildtools/lib/parsers/qmake/tests/viewer.h create mode 100644 buildtools/lib/parsers/qmake/tests/viewer_main.cpp create mode 100644 buildtools/lib/parsers/qmake/tests/viewerbase.ui create mode 100644 buildtools/lib/widgets/Mainpage.dox create mode 100644 buildtools/lib/widgets/Makefile.am create mode 100644 buildtools/lib/widgets/addenvvardlg.cpp create mode 100644 buildtools/lib/widgets/addenvvardlg.h create mode 100644 buildtools/lib/widgets/addfilesdialog.cpp create mode 100644 buildtools/lib/widgets/addfilesdialog.h create mode 100644 buildtools/lib/widgets/environmentdisplaydialog.cpp create mode 100644 buildtools/lib/widgets/environmentdisplaydialog.h create mode 100644 buildtools/lib/widgets/environmentdisplaydialogbase.ui create mode 100644 buildtools/lib/widgets/environmentvariableswidget.cpp create mode 100644 buildtools/lib/widgets/environmentvariableswidget.h create mode 100644 buildtools/lib/widgets/environmentvariableswidgetbase.ui create mode 100644 buildtools/lib/widgets/envvartools.cpp create mode 100644 buildtools/lib/widgets/envvartools.h create mode 100644 buildtools/lib/widgets/makeoptionswidget.cpp create mode 100644 buildtools/lib/widgets/makeoptionswidget.h create mode 100644 buildtools/lib/widgets/makeoptionswidgetbase.ui create mode 100644 buildtools/lib/widgets/removesubprojectdialog.cpp create mode 100644 buildtools/lib/widgets/removesubprojectdialog.h create mode 100644 buildtools/lib/widgets/removesubprojectdlgbase.ui create mode 100644 buildtools/lib/widgets/runoptionswidget.cpp create mode 100644 buildtools/lib/widgets/runoptionswidget.h create mode 100644 buildtools/lib/widgets/runoptionswidgetbase.ui create mode 100644 buildtools/lib/widgets/subclassesdlg.cpp create mode 100644 buildtools/lib/widgets/subclassesdlg.h create mode 100644 buildtools/lib/widgets/subclassesdlgbase.ui create mode 100644 buildtools/pascal/Makefile.am create mode 100644 buildtools/pascal/README.dox create mode 100644 buildtools/pascal/kdevpascalproject.desktop create mode 100644 buildtools/pascal/kdevpascalproject.rc create mode 100644 buildtools/pascal/pascalglobaloptionsdlg.cpp create mode 100644 buildtools/pascal/pascalglobaloptionsdlg.h create mode 100644 buildtools/pascal/pascalproject_optionsdlgbase.ui create mode 100644 buildtools/pascal/pascalproject_part.cpp create mode 100644 buildtools/pascal/pascalproject_part.h create mode 100644 buildtools/pascal/pascalproject_widget.cpp create mode 100644 buildtools/pascal/pascalproject_widget.h create mode 100644 buildtools/pascal/pascalprojectoptionsdlg.cpp create mode 100644 buildtools/pascal/pascalprojectoptionsdlg.h create mode 100644 buildtools/pascal/service.cpp create mode 100644 buildtools/pascal/service.h create mode 100644 buildtools/qmake/Makefile.am create mode 100644 buildtools/qmake/README create mode 100644 buildtools/qmake/README.dox create mode 100644 buildtools/qmake/choosesubprojectdlg.cpp create mode 100644 buildtools/qmake/choosesubprojectdlg.h create mode 100644 buildtools/qmake/choosesubprojectdlgbase.ui create mode 100644 buildtools/qmake/createscopedlg.cpp create mode 100644 buildtools/qmake/createscopedlg.h create mode 100644 buildtools/qmake/createscopedlgbase.ui create mode 100644 buildtools/qmake/disablesubprojectdlg.cpp create mode 100644 buildtools/qmake/disablesubprojectdlg.h create mode 100644 buildtools/qmake/disablesubprojectdlgbase.ui create mode 100644 buildtools/qmake/kdevtmakeproject.desktop create mode 100644 buildtools/qmake/kdevtrollproject.desktop create mode 100644 buildtools/qmake/kdevtrollproject.rc create mode 100644 buildtools/qmake/newwidgetdlg.cpp create mode 100644 buildtools/qmake/newwidgetdlg.h create mode 100644 buildtools/qmake/newwidgetdlgbase.ui create mode 100644 buildtools/qmake/projectconfigurationdlg.cpp create mode 100644 buildtools/qmake/projectconfigurationdlg.h create mode 100644 buildtools/qmake/projectconfigurationdlgbase.ui create mode 100644 buildtools/qmake/qmakedefaultopts.cpp create mode 100644 buildtools/qmake/qmakedefaultopts.h create mode 100644 buildtools/qmake/qmakeoptionswidget.cpp create mode 100644 buildtools/qmake/qmakeoptionswidget.h create mode 100644 buildtools/qmake/qmakeoptionswidgetbase.ui create mode 100644 buildtools/qmake/qmakescopeitem.cpp create mode 100644 buildtools/qmake/qmakescopeitem.h create mode 100644 buildtools/qmake/scope.cpp create mode 100644 buildtools/qmake/scope.h create mode 100644 buildtools/qmake/trolllistview.cpp create mode 100644 buildtools/qmake/trolllistview.h create mode 100644 buildtools/qmake/trollprojectpart.cpp create mode 100644 buildtools/qmake/trollprojectpart.h create mode 100644 buildtools/qmake/trollprojectwidget.cpp create mode 100644 buildtools/qmake/trollprojectwidget.h create mode 100644 buildtools/script/Makefile.am create mode 100644 buildtools/script/README.dox create mode 100644 buildtools/script/kdevscriptproject.desktop create mode 100644 buildtools/script/kdevscriptproject.rc create mode 100644 buildtools/script/scriptnewfiledlg.cpp create mode 100644 buildtools/script/scriptnewfiledlg.h create mode 100644 buildtools/script/scriptoptionswidget.cpp create mode 100644 buildtools/script/scriptoptionswidget.h create mode 100644 buildtools/script/scriptoptionswidgetbase.ui create mode 100644 buildtools/script/scriptprojectpart.cpp create mode 100644 buildtools/script/scriptprojectpart.h (limited to 'buildtools') diff --git a/buildtools/Makefile.am b/buildtools/Makefile.am new file mode 100644 index 00000000..1c61d027 --- /dev/null +++ b/buildtools/Makefile.am @@ -0,0 +1,48 @@ +## +## Do NOT remove the comments that start with "kdevelop:" +## They are actually directives to the kdevelop plugin system +## +## The include_xxxx variables are controlled by configure.in.in +## + +#kdevelop: ADA_BUILDTOOL = ada +if include_ada +ADA_BUILDTOOL = ada +endif + +#kdevelop: ANT_BUILDTOOL = ant +if include_ant +ANT_BUILDTOOL = ant +endif + +#kdevelop: AUTOTOOLS_BUILDTOOL = autotools +if include_autoproject +AUTOTOOLS_BUILDTOOL = autotools +endif + +#kdevelop: CUSTOMMAKEFILES_BUILDTOOL = custommakefiles +if include_customproject +CUSTOMMAKEFILES_BUILDTOOL = custommakefiles +endif + +#kdevelop: PASCAL_BUILDTOOL = pascal +if include_pascal +PASCAL_BUILDTOOL = pascal +endif + +#kdevelop: QMAKE_BUILDTOOL = qmake +if include_trollproject +QMAKE_BUILDTOOL = qmake +endif + +#kdevelop: SCRIPT_BUILDTOOL = script +if include_scriptproject +SCRIPT_BUILDTOOL = script +endif + +SUBDIRS = lib $(ADA_BUILDTOOL) $(ANT_BUILDTOOL) \ + $(AUTOTOOLS_BUILDTOOL) $(CUSTOMMAKEFILES_BUILDTOOL) $(PASCAL_BUILDTOOL) \ + $(QMAKE_BUILDTOOL) $(SCRIPT_BUILDTOOL) + +DOXYGEN_EMPTY = YES +include ../Doxyfile.am diff --git a/buildtools/ada/Makefile.am b/buildtools/ada/Makefile.am new file mode 100644 index 00000000..2de845ca --- /dev/null +++ b/buildtools/ada/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(top_srcdir)/buildtools/lib/base -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external \ + -I$(top_srcdir)/lib/interfaces/extras -I$(top_srcdir)/lib/util $(all_includes) + +kde_module_LTLIBRARIES = libkdevadaproject.la +libkdevadaproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevadaproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la $(top_builddir)/lib/interfaces/extras/libkdevextras.la + +libkdevadaproject_la_SOURCES = adaproject_part.cpp adaproject_widget.cpp adaproject_optionsdlgbase.ui adaprojectoptionsdlg.cpp adaglobaloptionsdlg.cpp service.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevadaproject.desktop + +rcdir = $(kde_datadir)/kdevadaproject +rc_DATA = kdevadaproject.rc diff --git a/buildtools/ada/README.dox b/buildtools/ada/README.dox new file mode 100644 index 00000000..24e0bd7e --- /dev/null +++ b/buildtools/ada/README.dox @@ -0,0 +1,17 @@ +/** \class AdaProjectPart +Ada Project: the common project part for all available ada +compilers (currently only gnat). +It holds the project file list and tries to abstract from their specifics. + +\authors Oliver Kellogg + +\unmaintained This part is currently un-maintained + +\deprecated This class is deprecated, use GenericProjectPart (buildtools/generic) instead. + +\feature supports gnat compiler +\feature Holds the project file list and tries to abstract from their specifics + +\requirement Ada gnat compiler + +*/ diff --git a/buildtools/ada/adaglobaloptionsdlg.cpp b/buildtools/ada/adaglobaloptionsdlg.cpp new file mode 100644 index 00000000..a8171c81 --- /dev/null +++ b/buildtools/ada/adaglobaloptionsdlg.cpp @@ -0,0 +1,129 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 +#include +#include +#include + +#include +#include +#include + +#include "kdevcompileroptions.h" + +#include "service.h" +#include "adaproject_part.h" +#include "adaglobaloptionsdlg.h" + +AdaGlobalOptionsDlg::AdaGlobalOptionsDlg(AdaProjectPart *part, QWidget* parent, const char* name, WFlags fl) + :AdaProjectOptionsDlgBase(parent,name,fl), m_part(part) +{ + delete config_label; + delete config_combo; + delete addconfig_button; + delete removeconfig_button; + delete compiler_label; + delete configuration_layout; + delete configuration_line; + delete exec_label; + delete exec_edit; + delete mainSourceLabel; + delete mainSourceUrl; + delete defaultopts_button; + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + currentCompiler = QString::null; + + /*kdDebug() << ServiceComboBox::defaultCompiler() << endl; + kdDebug() << ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names) << endl; + kdDebug() << compiler_box->text(ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names)) << endl; +*/ + ServiceComboBox::setCurrentText(compiler_box, ServiceComboBox::defaultCompiler(), service_names); + compiler_box_activated(compiler_box->currentText()); +} + +AdaGlobalOptionsDlg::~AdaGlobalOptionsDlg() +{ +} + +void AdaGlobalOptionsDlg::optionsButtonClicked() +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void AdaGlobalOptionsDlg::compiler_box_activated(const QString& text) +{ + kdDebug() << "text changed from " << currentCompiler << " to " << text << endl; + if (currentCompiler == text) + return; + if (!currentCompiler.isEmpty()) + saveCompilerOpts(currentCompiler); + currentCompiler = text; + readCompilerOpts(currentCompiler); +} + +void AdaGlobalOptionsDlg::accept() +{ + saveCompilerOpts(currentCompiler); + + saveConfigCache(); +} + +void AdaGlobalOptionsDlg::saveCompilerOpts( QString compiler ) +{ + configCache[compiler] = options_edit->text(); +} + +void AdaGlobalOptionsDlg::readCompilerOpts( QString compiler ) +{ + QString settings = configCache[compiler]; + if (settings.isEmpty()) + { + KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + settings = config->readPathEntry(compiler); + } + + options_edit->setText(settings); +} + +void AdaGlobalOptionsDlg::readConfigCache( ) +{ +/* KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + + QMap settings = config->entryMap("Ada Compiler"); +*/ +} + +void AdaGlobalOptionsDlg::saveConfigCache( ) +{ + KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + + for (QMap::iterator it = configCache.begin(); it != configCache.end(); ++it) + { + config->writeEntry(it.key(), it.data()); + } +} + +#include "adaglobaloptionsdlg.moc" diff --git a/buildtools/ada/adaglobaloptionsdlg.h b/buildtools/ada/adaglobaloptionsdlg.h new file mode 100644 index 00000000..92001a1b --- /dev/null +++ b/buildtools/ada/adaglobaloptionsdlg.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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. + */ +#ifndef ADAGLOBALOPTIONSDLG_H +#define ADAGLOBALOPTIONSDLG_H + +#include + +#include + +#include "adaproject_optionsdlgbase.h" + +class AdaProjectPart; + +class AdaGlobalOptionsDlg : public AdaProjectOptionsDlgBase +{ + Q_OBJECT + +public: + AdaGlobalOptionsDlg(AdaProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~AdaGlobalOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void optionsButtonClicked(); + virtual void compiler_box_activated(const QString& text); + +private: + AdaProjectPart *m_part; + KTrader::OfferList offers; + QString currentCompiler; + QStringList service_names; + QStringList service_execs; + QMap configCache; + + void saveCompilerOpts(QString compiler); + void readCompilerOpts(QString compiler); + + void readConfigCache(); + void saveConfigCache(); +}; + +#endif diff --git a/buildtools/ada/adaproject_optionsdlgbase.ui b/buildtools/ada/adaproject_optionsdlgbase.ui new file mode 100644 index 00000000..72e99f74 --- /dev/null +++ b/buildtools/ada/adaproject_optionsdlgbase.ui @@ -0,0 +1,472 @@ + +AdaProjectOptionsDlgBase + + + AdaProjectOptionsDlgBase + + + true + + + + 0 + 0 + 600 + 480 + + + + Ada Compiler + + + + unnamed + + + + spacer1 + + + Vertical + + + Expanding + + + + 20 + 160 + + + + + + configuration_layout + + + + unnamed + + + + + config_label + + + + 1 + 5 + 0 + 0 + + + + Configuration: + + + + + config_combo + + + + 3 + 0 + 0 + 0 + + + + true + + + + + Spacer17_2 + + + Horizontal + + + Fixed + + + + 20 + 8 + + + + + + addconfig_button + + + Add + + + + + removeconfig_button + + + Remove + + + + + Spacer18_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + options_button + + + + 0 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + options_label + + + + 4 + 5 + 0 + 0 + + + + Compiler &options: + + + compiler_box + + + + + compiler_label + + + + 4 + 5 + 0 + 0 + + + + Ada &compiler: + + + compiler_box + + + + + exec_edit + + + + + options_edit + + + + + compiler_box + + + + + exec_label + + + + 4 + 5 + 0 + 0 + + + + Compiler co&mmand: + + + compiler_box + + + + + configuration_line + + + HLine + + + Sunken + + + Horizontal + + + + + spacer11 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + spacer12 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + mainSourceUrl + + + + 0 + 26 + + + + WheelFocus + + + + + mainSourceLabel + + + + 4 + 5 + 0 + 0 + + + + Main &source file: + + + compiler_box + + + + + spacer13 + + + Vertical + + + Fixed + + + + 20 + 30 + + + + + + spacer7 + + + Horizontal + + + Expanding + + + + 400 + 20 + + + + + + defaultopts_button + + + Load Default Compiler Options + + + + + + + compiler_box + activated(const QString&) + AdaProjectOptionsDlgBase + compiler_box_activated(const QString&) + + + removeconfig_button + clicked() + AdaProjectOptionsDlgBase + configRemoved() + + + config_combo + textChanged(const QString&) + AdaProjectOptionsDlgBase + configComboTextChanged(const QString&) + + + config_combo + activated(const QString&) + AdaProjectOptionsDlgBase + configChanged(const QString&) + + + addconfig_button + clicked() + AdaProjectOptionsDlgBase + configAdded() + + + options_button + clicked() + AdaProjectOptionsDlgBase + optionsButtonClicked() + + + exec_edit + textChanged(const QString&) + AdaProjectOptionsDlgBase + setDirty() + + + options_edit + textChanged(const QString&) + AdaProjectOptionsDlgBase + setDirty() + + + mainSourceUrl + textChanged(const QString&) + AdaProjectOptionsDlgBase + setDirty() + + + mainSourceUrl + urlSelected(const QString&) + AdaProjectOptionsDlgBase + setDirty() + + + compiler_box + activated(const QString&) + AdaProjectOptionsDlgBase + setDirty() + + + compiler_box + textChanged(const QString&) + AdaProjectOptionsDlgBase + setDirty() + + + defaultopts_button + clicked() + AdaProjectOptionsDlgBase + setDefaultOptions() + + + defaultopts_button + clicked() + AdaProjectOptionsDlgBase + setDirty() + + + + compiler_box + exec_edit + options_edit + options_button + mainSourceUrl + config_combo + addconfig_button + removeconfig_button + + + compiler_box_activated(const QString&) + addconfig_button_clicked() + configRemoved() + configComboTextChanged(const QString&) + configChanged(const QString&) + optionsButtonClicked() + configAdded() + setDirty() + setDefaultOptions() + + + kdialog.h + + + + + qwidget.h + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/ada/adaproject_part.cpp b/buildtools/ada/adaproject_part.cpp new file mode 100644 index 00000000..33ba166b --- /dev/null +++ b/buildtools/ada/adaproject_part.cpp @@ -0,0 +1,465 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 "adaproject_part.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "kdevlanguagesupport.h" +#include "kdevcompileroptions.h" +#include "kdevgenericfactory.h" +#include + +#include "adaproject_widget.h" +#include "adaprojectoptionsdlg.h" +#include "adaglobaloptionsdlg.h" + +typedef KDevGenericFactory AdaProjectFactory; +static const KDevPluginInfo data("kdevadaproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevadaproject, AdaProjectFactory( data ) ) + +AdaProjectPart::AdaProjectPart(QObject *parent, const char *name, const QStringList& ) + :KDevBuildTool(&data, parent, name ? name : "AdaProjectPart" ) +{ + setInstance(AdaProjectFactory::instance()); + setXMLFile("kdevadaproject.rc"); + + KAction *action; + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + action = new KAction( i18n("Execute Program"), "exec", 0, + this, SLOT(slotExecute()), + actionCollection(), "build_execute" ); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); + + connect( core(), SIGNAL(configWidget(KDialogBase*)), + this, SLOT(configWidget(KDialogBase*)) ); + +// m_widget = new AdaProjectWidget(this); + +// QWhatsThis::add(m_widget, i18n("WHAT DOES THIS PART DO?")); + + // now you decide what should happen to the widget. Take a look at kdevcore.h + // or at other plugins how to embed it. + + // if you want to embed your widget as an outputview, simply uncomment + // the following line. + + // mainWindow()->embedOutputView( m_widget, "name that should appear", "enter a tooltip" ); + +} + +AdaProjectPart::~AdaProjectPart() +{ +// delete m_widget; +} + +/** + * This should really be merged with FileTreeWidget::matchesHidePattern() + * and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp + */ +static bool matchesPattern(const QString &fileName, const QStringList &patternList) +{ + QStringList::ConstIterator it; + for (it = patternList.begin(); it != patternList.end(); ++it) { + QRegExp re(*it, true, true); + if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length()) + return true; + } + + return false; +} + +void AdaProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_buildDir = dirName; + m_projectDir = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevadaproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevadaproject/run/directoryradio", "executable"); + } + + loadProjectConfig(); + + // Put all files from all subdirectories into file list + QValueStack s; + int prefixlen = m_projectDir.length()+1; + s.push(m_projectDir); + + QStringList includepatternList; + + if ( languageSupport() ) + { + KMimeType::List list = languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + } + + QString excludepatterns = "*~"; + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug() << "AdaProjectPart::openProject examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + if( !dirEntries ) + break; + + QPtrListIterator it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + kdDebug() << "AdaProjectPart::openProject pushing: " << path << endl; + s.push(path); + } + else { + if (matchesPattern(path, includepatternList) + && !matchesPattern(path, excludepatternList)) { + kdDebug() << "AdaProjectPart::openProject adding: " << path << endl; + m_sourceFiles.append(path.mid(prefixlen)); + } else { + kdDebug() << "AdaProjectPart::openProject ignoring: " << path << endl; + } + } + } + } while (!s.isEmpty()); + + KDevProject::openProject( dirName, projectName ); +} + +void AdaProjectPart::closeProject() +{ +} + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList AdaProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevadaproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString AdaProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory("kdevadaproject"); + if (cwd.isEmpty()) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString AdaProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevadaproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the run command line arguments */ +QString AdaProjectPart::debugArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevadaproject/run/globaldebugarguments"); +} + + +/** Retuns a QString with the run command line arguments */ +QString AdaProjectPart::runArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevadaproject/run/programargs"); +} + +QString AdaProjectPart::mainSource() const +{ + return projectDirectory() + "/" + m_mainSource; +} + +void AdaProjectPart::setMainSource(QString fullPath) +{ + QString olddir = activeDirectory(); + m_mainSource = fullPath.replace(QRegExp(QString(projectDirectory() + QString("/"))),""); + emit activeDirectoryChanged( olddir, activeDirectory() ); +} + +QString AdaProjectPart::projectDirectory() const +{ + return m_projectDir; +} + +QString AdaProjectPart::projectName() const +{ + return m_projectName; +} + +QString AdaProjectPart::activeDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true).replace(QRegExp(projectDirectory()),""); +} + +QString AdaProjectPart::buildDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true); +} + +void AdaProjectPart::listOfFiles(QStringList &result, QString path) const +{ + QDir d(path); + if (!d.exists()) + return; + + const QFileInfoList *entries = d.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden); + if( !entries ) + return; + + QFileInfoListIterator it( *entries ); + while( const QFileInfo* fileInfo = it.current() ) + { + ++it; + + if (fileInfo->isDir() && fileInfo->filePath() != path) + { + kdDebug() << "entering dir " << fileInfo->dirPath() << endl; + listOfFiles(result, fileInfo->dirPath()); + } + else + { + kdDebug() << "adding to result: " << fileInfo->filePath() << endl; + result << fileInfo->filePath(); + } + } +} + +QStringList AdaProjectPart::allFiles() const +{ +// QStringList files; + +// listOfFiles(files, projectDirectory()); + +// return files; + return m_sourceFiles; +} + +void AdaProjectPart::addFile(const QString& /*fileName*/) +{ +} + +void AdaProjectPart::addFiles(const QStringList& /*fileList*/) +{ +} + +void AdaProjectPart::removeFile(const QString& /*fileName*/) +{ +} + +void AdaProjectPart::removeFiles(const QStringList& /*fileList*/) +{ +} + +void AdaProjectPart::slotBuild() +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + + QString cmdline = m_compilerExec + " " + m_compilerOpts + " "; + + if (cmdline.isEmpty()) + { + KMessageBox::sorry(0, i18n("Could not find ada compiler.\nCheck if your compiler settings are correct.")); + return; + } + + QFileInfo fi(mainSource()); + cmdline += fi.fileName(); + + QString dircmd = "cd "; + dircmd += KProcess::quote(buildDirectory()); + dircmd += " && "; + + makeFrontend()->queueCommand(buildDirectory(), dircmd + cmdline); +} + +void AdaProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + QString program = "./"; + appFrontend()->startAppCommand(buildDirectory(), mainProgram(), true); +} + +void AdaProjectPart::changedFiles( const QStringList & fileList ) +{ + KDevProject::changedFiles(fileList); +} + +void AdaProjectPart::changedFile( const QString & fileName ) +{ + KDevProject::changedFile(fileName); +} + +void AdaProjectPart::projectConfigWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Ada Compiler")); + AdaProjectOptionsDlg *w = new AdaProjectOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), this, SLOT(loadProjectConfig()) ); +} + +void AdaProjectPart::loadProjectConfig( ) +{ + QDomDocument &dom = *(projectDom()); + + QString config = DomUtil::readEntry(dom, "/kdevadaproject/general/useconfiguration", "default"); + m_mainSource = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/mainsource") ); + m_compilerOpts = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/compileroptions")); + m_compilerExec = DomUtil::readEntry(dom, QString("/kdevadaproject/configurations/") + config + QString("/compilerexec")); + + if (m_compilerExec.isEmpty()) + { + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + QValueList::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + m_compilerExec = (*it)->exec(); + break; + } + } + } +} + +void AdaProjectPart::configWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Ada Compiler")); + AdaGlobalOptionsDlg *w = new AdaGlobalOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); +} + +KDevCompilerOptions *AdaProjectPart::createCompilerOptions(const QString &name) +{ + KService::Ptr service = KService::serviceByDesktopName(name); + if (!service) { + kdDebug() << "AdaProjectPart::createCompilerOptions can't find service " << name; + return 0; + } + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + KMessageBox::error(0, i18n("There was an error loading the module %1.\n" + "The diagnostics are:\n%2").arg(service->name()).arg(errorMessage)); + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(this, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug() << "AdaProjectPart::createCompilerOptions: component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; +} + +QString AdaProjectPart::defaultOptions( const QString compiler ) +{ + KConfig *config = KGlobal::config(); + config->setGroup("Ada Compiler"); + return config->readPathEntry(compiler); +} + +#include "adaproject_part.moc" + + +/*! + \fn AdaProjectPart::distFiles() const + */ +QStringList AdaProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "Makefile"); + return sourceList + files; +} diff --git a/buildtools/ada/adaproject_part.h b/buildtools/ada/adaproject_part.h new file mode 100644 index 00000000..88966ae2 --- /dev/null +++ b/buildtools/ada/adaproject_part.h @@ -0,0 +1,93 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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. + */ +#ifndef __KDEVPART_ADAPROJECT_H__ +#define __KDEVPART_ADAPROJECT_H__ + +#include + +#include "kdevbuildtool.h" + +class AdaProjectWidget; +class KDialogBase; +class KDevCompilerOptions; + +class AdaProjectPart : public KDevBuildTool +{ + Q_OBJECT +public: + AdaProjectPart(QObject *parent, const char *name, const QStringList &); + ~AdaProjectPart(); + + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + /**Returns the name of the main source file without extension. + We assume that all Ada compilers call the binary that way. */ + virtual QString mainProgram() const; + /**Main source file (like src/main.adb)*/ + virtual QString mainSource() const; + virtual void setMainSource(QString fullPath); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString activeDirectory() const; + /**The location of the main source file*/ + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + /**Returns everything in the project directory*/ + virtual QStringList allFiles() const; + /**This does absolutelly nothing*/ + virtual void addFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void addFiles(const QStringList &fileList); + /**This does absolutelly nothing*/ + virtual void removeFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void removeFiles(const QStringList &fileList); + + virtual void changedFiles( const QStringList & fileList ); + virtual void changedFile( const QString & fileName ); + + KDevCompilerOptions *createCompilerOptions(const QString &name); + + virtual QString defaultOptions(const QString compiler); + QStringList distFiles() const; + +public slots: + /**loads config from project file*/ + void loadProjectConfig(); + +private slots: + void slotBuild(); + void slotExecute(); + void projectConfigWidget(KDialogBase *dlg); + void configWidget(KDialogBase *dlg); + +private: + QGuardedPtr m_widget; + + void listOfFiles(QStringList &result, QString path) const; + + QString m_buildDir; + QString m_projectDir; + QString m_projectName; + + QString m_mainProg; + QString m_mainSource; + QString m_compilerExec; + QString m_compilerOpts; + + QStringList m_sourceFiles; +}; + +#endif diff --git a/buildtools/ada/adaproject_widget.cpp b/buildtools/ada/adaproject_widget.cpp new file mode 100644 index 00000000..d4bdf37b --- /dev/null +++ b/buildtools/ada/adaproject_widget.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +#include + +#include "adaproject_part.h" +#include "adaproject_widget.h" + + +AdaProjectWidget::AdaProjectWidget(AdaProjectPart *part) + : QWidget(0, "AdaProject widget") +{ + Q_UNUSED( part ); +} + + +AdaProjectWidget::~AdaProjectWidget() +{ +} + + +#include "adaproject_widget.moc" diff --git a/buildtools/ada/adaproject_widget.h b/buildtools/ada/adaproject_widget.h new file mode 100644 index 00000000..dc6b4ec4 --- /dev/null +++ b/buildtools/ada/adaproject_widget.h @@ -0,0 +1,21 @@ +#ifndef __ADAPROJECT_WIDGET_H__ +#define __ADAPROJECT_WIDGET_H__ + +#include +#include + +class KDevProject; +class AdaProjectPart; + +class AdaProjectWidget : public QWidget +{ + Q_OBJECT + +public: + + AdaProjectWidget(AdaProjectPart *part); + ~AdaProjectWidget(); + +}; + +#endif diff --git a/buildtools/ada/adaprojectoptionsdlg.cpp b/buildtools/ada/adaprojectoptionsdlg.cpp new file mode 100644 index 00000000..3eafb082 --- /dev/null +++ b/buildtools/ada/adaprojectoptionsdlg.cpp @@ -0,0 +1,208 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "domutil.h" +#include "kdevcompileroptions.h" + +#include "service.h" +#include "adaproject_part.h" +#include "adaprojectoptionsdlg.h" + +AdaProjectOptionsDlg::AdaProjectOptionsDlg(AdaProjectPart *part, QWidget* parent, const char* name, WFlags fl) + : AdaProjectOptionsDlgBase(parent,name, fl), m_part(part) +{ + config_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + allConfigs = allBuildConfigs(); + config_combo->insertStringList(allConfigs); + + dirty = false; + + QDomDocument &dom = *(m_part->projectDom()); + currentConfig = QString::null; + configChanged(DomUtil::readEntry(dom, "/kdevadaproject/general/useconfiguration", "default")); +} + +AdaProjectOptionsDlg::~AdaProjectOptionsDlg() +{ +} + +QStringList AdaProjectOptionsDlg::allBuildConfigs() +{ + QDomDocument &dom = *(m_part->projectDom()); + + QStringList allConfigs; + allConfigs.append("default"); + + QDomNode node = dom.documentElement().namedItem("kdevadaproject").namedItem("configurations"); + QDomElement childEl = node.firstChild().toElement(); + while (!childEl.isNull()) { + QString config = childEl.tagName(); + kdDebug() << "Found config " << config << endl; + if (config != "default") + allConfigs.append(config); + childEl = childEl.nextSibling().toElement(); + } + + return allConfigs; +} + +void AdaProjectOptionsDlg::accept() +{ + DomUtil::writeEntry(*m_part->projectDom(), "/kdevadaproject/general/useconfiguration", currentConfig); + if (dirty) + { + saveConfig(currentConfig); + } +} + +void AdaProjectOptionsDlg::compiler_box_activated( const QString& /*s*/ ) +{ + QString exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); +} + +void AdaProjectOptionsDlg::saveConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevadaproject/configurations/" + config + "/"; + + DomUtil::writeEntry(dom, prefix + "compiler", + ServiceComboBox::currentText(compiler_box, service_names)); + DomUtil::writeEntry(dom, prefix + "compileroptions", options_edit->text()); + DomUtil::writeEntry(dom, prefix + "compilerexec", exec_edit->text()); + DomUtil::writeEntry(dom, prefix + "mainsource", mainSourceUrl->url().replace(QRegExp(m_part->projectDirectory() + QString("/")),"")); +} + +void AdaProjectOptionsDlg::readConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevadaproject/configurations/" + config + "/"; + + QString compiler = DomUtil::readEntry(dom, prefix + "compiler", ""); + + if (compiler.isEmpty()) + { + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + QValueList::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + compiler = (*it)->name(); + kdDebug() << "compiler is " << compiler << endl; + break; + } + } + } + ServiceComboBox::setCurrentText(compiler_box, compiler, service_names); + + QString exec = DomUtil::readEntry(dom, prefix + "compilerexec", ""); + if (exec.isEmpty()) + exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); + options_edit->setText(DomUtil::readEntry(dom, prefix + "compileroptions")); + mainSourceUrl->setURL(m_part->projectDirectory() + "/" + DomUtil::readEntry(dom, prefix + "mainsource")); +} + +void AdaProjectOptionsDlg::configComboTextChanged(const QString &config) +{ + bool canAdd = !allConfigs.contains(config) && !config.contains("/") && !config.isEmpty(); + bool canRemove = allConfigs.contains(config) && config != "default"; + addconfig_button->setEnabled(canAdd); + removeconfig_button->setEnabled(canRemove); +} + + +void AdaProjectOptionsDlg::configChanged(const QString &config) +{ + if (config == currentConfig || !allConfigs.contains(config)) + return; + + if (!currentConfig.isNull() && dirty) + saveConfig(currentConfig); + + currentConfig = config; + readConfig(config); + dirty = false; + + config_combo->blockSignals(true); + config_combo->setEditText(config); + config_combo->blockSignals(false); +} + + +void AdaProjectOptionsDlg::configAdded() +{ + QString config = config_combo->currentText(); + + allConfigs.append(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + configChanged(config); + setDirty(); // force saving +} + + +void AdaProjectOptionsDlg::configRemoved() +{ + QString config = config_combo->currentText(); + + QDomDocument dom = *m_part->projectDom(); + QDomNode node = dom.documentElement().namedItem("kdevadaproject").namedItem("configurations"); + node.removeChild(node.namedItem(config)); + allConfigs.remove(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + + currentConfig = QString::null; + configChanged("default"); +} + +void AdaProjectOptionsDlg::optionsButtonClicked( ) +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void AdaProjectOptionsDlg::setDirty( ) +{ + dirty = true; +} + +void AdaProjectOptionsDlg::setDefaultOptions( ) +{ + if (!compiler_box->currentText().isEmpty()) + options_edit->setText(m_part->defaultOptions(compiler_box->currentText())); +} + +#include "adaprojectoptionsdlg.moc" diff --git a/buildtools/ada/adaprojectoptionsdlg.h b/buildtools/ada/adaprojectoptionsdlg.h new file mode 100644 index 00000000..d91c5266 --- /dev/null +++ b/buildtools/ada/adaprojectoptionsdlg.h @@ -0,0 +1,57 @@ +/* Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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. + */ +#ifndef ADAPROJECTOPTIONSDLG_H +#define ADAPROJECTOPTIONSDLG_H + +#include + +#include "adaproject_optionsdlgbase.h" + +class AdaProjectPart; +class KDevCompilerOptions; + +class AdaProjectOptionsDlg : public AdaProjectOptionsDlgBase +{ + Q_OBJECT + +public: + AdaProjectOptionsDlg(AdaProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~AdaProjectOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void compiler_box_activated(const QString &s); + void configComboTextChanged(const QString &config); + void configChanged(const QString &config); + void configAdded(); + void configRemoved(); + void optionsButtonClicked(); + void setDirty(); + void setDefaultOptions(); + +private: + QStringList allConfigs; + QString currentConfig; + bool dirty; + + KTrader::OfferList offers; + QStringList service_names; + QStringList service_execs; + + AdaProjectPart *m_part; + + void saveConfig(QString config); + void readConfig(QString config); + QStringList allBuildConfigs(); +}; + +#endif + diff --git a/buildtools/ada/kdevadaproject.desktop b/buildtools/ada/kdevadaproject.desktop new file mode 100644 index 00000000..0e306f4b --- /dev/null +++ b/buildtools/ada/kdevadaproject.desktop @@ -0,0 +1,100 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Ada Project +Comment[br]=Raktres Ada +Comment[ca]=Projecte Ada +Comment[cs]=Ada projekt +Comment[da]=Ada-projekt +Comment[de]=Ada-Projekt für KDevelop +Comment[el]=Έργο Ada +Comment[es]=Proyecto Ada +Comment[et]=Ada projekt +Comment[eu]=Ada proiektua +Comment[fa]=پروژۀ آدا +Comment[fr]=Projet en Ada +Comment[ga]=Tionscadal Ada +Comment[gl]=Proxecto Ada +Comment[hi]=एडीए परियोजना +Comment[hu]=Ada-projekt +Comment[is]=Ada verkefni +Comment[it]=Progetto Ada +Comment[ja]=Ada プロジェクト +Comment[ms]=Projek Ada +Comment[nds]=Ada-Projekt +Comment[ne]=एडा परियोजना +Comment[nl]=Ada-project +Comment[pa]=Ada ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Ada +Comment[pt]=Projecto Ada +Comment[pt_BR]=Projeto Ada +Comment[ro]=Proiect Ada +Comment[ru]=Проект Ada +Comment[sk]=Ada projekt +Comment[sl]=Projekt Ada +Comment[sr]=Ada пројекат +Comment[sr@Latn]=Ada projekat +Comment[sv]=Ada-projekt +Comment[ta]=அடா பிராஜக்ட் +Comment[tg]=Лоиҳаи Ada +Comment[tr]=Ada Projesi +Comment[uz]=Ada loyihasi +Comment[uz@cyrillic]=Ada лойиҳаси +Comment[zh_CN]=Ada 工程 +Comment[zh_TW]=Ada 專案 +Name=KDevAdaProject +Name[da]=KDevelop Ada-projekt +Name[de]=Ada-Projekt (KDevelop) +Name[fr]=Projet Ada pour KDevelop +Name[hi]=के-डेव-एडीए-परियोजना +Name[nds]=Ada-Projekt (KDevelop) +Name[ne]=केडीई विकास एडा परियोजना +Name[pl]=KDevProjektAda +Name[sk]=KDevAdaProjekt +Name[sv]=KDevelop Ada-projekt +Name[ta]=கெடெவ் அடா பிராஜக்ட் +Name[tg]=Лоиҳаи KDevAda +Name[zh_TW]=KDevelop Ada 專案 +GenericName=Ada Project +GenericName[br]=Raktres Ada +GenericName[ca]=Projecte Ada +GenericName[da]=Ada-projekt +GenericName[de]=Ada-Projekt +GenericName[el]=Έργο Ada +GenericName[es]=Proyecto Ada +GenericName[et]=Ada projekt +GenericName[eu]=Ada proiektua +GenericName[fa]=پروژۀ آدا +GenericName[fr]=Projet en Ada +GenericName[ga]=Tionscadal Ada +GenericName[gl]=Proxecto Ada +GenericName[hi]=एडीए परियोजना +GenericName[hu]=Ada-projekt +GenericName[is]=Ada verkefni +GenericName[it]=Project con Ada +GenericName[ja]=Ada プロジェクト +GenericName[ms]=Projek Ada +GenericName[nds]=Ada-Projekt +GenericName[ne]=एडा परियोजना +GenericName[nl]=Ada-project +GenericName[pa]=Ada ਪ੍ਰੋਜੈਕਟ +GenericName[pl]=Projekt: Ada +GenericName[pt]=Projecto Ada +GenericName[pt_BR]=Projeto Ada +GenericName[ru]=Проект Ada +GenericName[sk]=Ada projekt +GenericName[sl]=Projekt Ada +GenericName[sr]=Ada пројекат +GenericName[sr@Latn]=Ada projekat +GenericName[sv]=Ada-projekt +GenericName[ta]=அடா பிராஜக்ட் +GenericName[tg]=Лоиҳаи Ada +GenericName[tr]=Ada Projesi +GenericName[uz]=Ada loyihasi +GenericName[uz@cyrillic]=Ada лойиҳаси +GenericName[zh_CN]=Ada 工程 +GenericName[zh_TW]=Ada 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevadaproject +X-KDevelop-Version=5 +X-KDevelop-Language=Ada diff --git a/buildtools/ada/kdevadaproject.rc b/buildtools/ada/kdevadaproject.rc new file mode 100644 index 00000000..d7f260e1 --- /dev/null +++ b/buildtools/ada/kdevadaproject.rc @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/buildtools/ada/service.cpp b/buildtools/ada/service.cpp new file mode 100644 index 00000000..02081a58 --- /dev/null +++ b/buildtools/ada/service.cpp @@ -0,0 +1,75 @@ +/* Copyright (C) 2001-2002 by Bernd Gehrmann + * bernd@kdevelop.org + * Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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 +#include + +#include +#include + +#include "service.h" + + +void ServiceComboBox::insertStringList(QComboBox *combo, const QValueList &list, + QStringList *names, QStringList *execs) +{ + QValueList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + combo->insertItem((*it)->comment()); + (*names) << (*it)->desktopEntryName(); + (*execs) << (*it)->exec(); + kdDebug() << "insertStringList item " << (*it)->name() << "," << (*it)->exec() << endl; + } +} + +QString ServiceComboBox::currentText(QComboBox *combo, const QStringList &names) +{ + if (combo->currentItem() == -1) + return QString::null; + return names[combo->currentItem()]; +} + +void ServiceComboBox::setCurrentText(QComboBox *combo, const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + combo->setCurrentItem(i); + break; + } + ++i; + } +} + +int ServiceComboBox::itemForText(const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + return i; + } + ++i; + } + return 0; +} + +QString ServiceComboBox::defaultCompiler() +{ + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Ada'"); + QValueList::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + return (*it)->name();; + } + } + return ""; +} diff --git a/buildtools/ada/service.h b/buildtools/ada/service.h new file mode 100644 index 00000000..f9671d0a --- /dev/null +++ b/buildtools/ada/service.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2001-2002 by Bernd Gehrmann + * bernd@kdevelop.org + * Copyright (C) 2003 Oliver Kellogg + * okellogg@users.sourceforge.net + * + * 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. + */ +#ifndef SERVICE_H +#define SERVICE_H + +#include + +class ServiceComboBox +{ +public: + static void insertStringList(QComboBox *combo, const QValueList &list, + QStringList *names, QStringList *execs); + static QString currentText(QComboBox *combo, const QStringList &names); + static void setCurrentText(QComboBox *combo, const QString &str, const QStringList &names); + static int itemForText(const QString &str, const QStringList &names); + static QString defaultCompiler(); +}; + +#endif diff --git a/buildtools/ant/Makefile.am b/buildtools/ant/Makefile.am new file mode 100644 index 00000000..6a92a5b1 --- /dev/null +++ b/buildtools/ant/Makefile.am @@ -0,0 +1,21 @@ +# Here resides the ant project part. + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_builddir)/buildtools/lib/widgets \ + $(all_includes) + +kde_module_LTLIBRARIES = libkdevantproject.la +libkdevantproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevantproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevantproject_la_SOURCES = antprojectpart.cpp antoptionswidget.ui classpathwidget.ui + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevantproject.desktop + +rcdir = $(kde_datadir)/kdevantproject +rc_DATA = kdevantproject.rc diff --git a/buildtools/ant/README.dox b/buildtools/ant/README.dox new file mode 100644 index 00000000..b4b8a7c9 --- /dev/null +++ b/buildtools/ant/README.dox @@ -0,0 +1,8 @@ +/** \class AntProjectPart +ant build tool part. + +\authors Matthias Hoelzer-Kluepfel + +\unmaintained This part is currently un-maintained + +*/ diff --git a/buildtools/ant/antoptionswidget.ui b/buildtools/ant/antoptionswidget.ui new file mode 100644 index 00000000..fa78e97f --- /dev/null +++ b/buildtools/ant/antoptionswidget.ui @@ -0,0 +1,173 @@ + +AntOptionsWidget + + + AntOptionsWidget + + + + 0 + 0 + 410 + 266 + + + + + unnamed + + + + + Quiet + + + + + Verbose + + + + + Debug + + + + Verbosity + + + + + Spacer1 + + + Vertical + + + Expanding + + + + 16 + 86 + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 16 + 86 + + + + + + TextLabel1 + + + &Build file: + + + BuildXML + + + + + TextLabel2 + + + &Verbosity: + + + Verbosity + + + + + TextLabel3 + + + &Properties: + + + AlignTop + + + Properties + + + + + + Property + + + + + Value + + + + Properties + + + 0 + + + 2 + + + + + Spacer3 + + + Horizontal + + + Expanding + + + + 240 + 16 + + + + + + BuildXML + + + + + + BuildXML + Verbosity + Properties + + + kcombobox.h + klineedit.h + kpushbutton.h + kdialog.h + + + + + kcombobox.h + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/ant/antprojectpart.cpp b/buildtools/ant/antprojectpart.cpp new file mode 100644 index 00000000..a7f0ea25 --- /dev/null +++ b/buildtools/ant/antprojectpart.cpp @@ -0,0 +1,608 @@ +#include "antprojectpart.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + + +#include "antoptionswidget.h" +#include "classpathwidget.h" + + + + +typedef KDevGenericFactory AntProjectFactory; +static const KDevPluginInfo data("kdevantproject"); +K_EXPORT_COMPONENT_FACTORY(libkdevantproject, AntProjectFactory( data )) + + +AntOptions::AntOptions() + : m_buildXML("build.xml"), m_verbosity(AntOptions::Quiet) +{ +} + + +AntProjectPart::AntProjectPart(QObject *parent, const char *name, const QStringList &) + : KDevBuildTool(&data, parent, name ? name : "AntProjectPart") +{ + setInstance(AntProjectFactory::instance()); + + setXMLFile("kdevantproject.rc"); + + m_buildProjectAction = new KAction(i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + m_buildProjectAction->setToolTip(i18n("Build project")); + m_buildProjectAction->setWhatsThis(i18n("Build project

Executes ant dist command to build the project.")); + + KActionMenu *menu = new KActionMenu(i18n("Build &Target"), + actionCollection(), "build_target" ); + menu->setToolTip(i18n("Build target")); + menu->setWhatsThis(i18n("Build target

Executes ant target_name command to build the specified target.")); + + m_targetMenu = menu->popupMenu(); + + connect(m_targetMenu, SIGNAL(activated(int)), this, SLOT(slotTargetMenuActivated(int))); + connect(core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*))); + connect(core(), SIGNAL(contextMenu(QPopupMenu *, const Context *)), this, SLOT(contextMenu(QPopupMenu *, const Context *))); + + m_antOptionsWidget = 0; +} + + +AntProjectPart::~AntProjectPart() +{ +} + + +void AntProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_projectDirectory = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + /// \FIXME there is no kdevantproject so this will not work ! + if (DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevantproject/run/directoryradio", "executable"); + } + + /// @todo read alternative build file from properties + m_antOptions.m_buildXML = "build.xml"; + + parseBuildXML(); + + fillMenu(); + + QFile f(dirName + "/" + projectName.lower() + ".kdevelop" + ".filelist"); + if (f.open(IO_ReadOnly)) + { + QTextStream stream(&f); + while (!stream.atEnd()) + { + QString s = stream.readLine(); + if (!s.startsWith("#")) + m_sourceFiles << s; + } + } + else + populateProject(); + + KDevProject::openProject( dirName, projectName ); +} + + +void AntProjectPart::populateProject() +{ + QApplication::setOverrideCursor(Qt::waitCursor); + + QValueStack s; + int prefixlen = m_projectDirectory.length()+1; + s.push(m_projectDirectory); + + QDir dir; + do + { + dir.setPath(s.pop()); + kdDebug() << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + QPtrListIterator it(*dirEntries); + for (; it.current(); ++it) + { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) + { + kdDebug() << "Pushing: " << path << endl; + s.push(path); + } + else + { + kdDebug() << "Adding: " << path << endl; + m_sourceFiles.append(path.mid(prefixlen)); + } + } + } + while (!s.isEmpty()); + + QApplication::restoreOverrideCursor(); +} + + +void AntProjectPart::closeProject() +{ + m_projectDirectory = ""; + m_projectName = ""; + m_buildProjectAction->setEnabled(false); + + m_targetMenu->clear(); + + m_antOptions = AntOptions(); + + QFile f(m_projectDirectory + "/" + m_projectName.lower() + ".kdevelop" + ".filelist"); + if (!f.open(IO_WriteOnly)) + return; + + QTextStream stream(&f); + stream << "# KDevelop Ant Project File List" << endl; + + QStringList::ConstIterator it; + for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) + stream << (*it) << endl; + f.close(); +} + + +QString AntProjectPart::projectDirectory() const +{ + return m_projectDirectory; +} + + +QString AntProjectPart::buildDirectory() const +{ + return m_projectDirectory; +} + +QString AntProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList AntProjectPart::runEnvironmentVars() const +{ + /// \FIXME there is no kdevantproject so this will not work ! + return DomUtil::readPairListEntry(*projectDom(), "/kdevantproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString AntProjectPart::runDirectory() const +{ + return buildDirectory(); + /// \FIXME put the code below into use! + + QDomDocument &dom = *projectDom(); + + /// \FIXME there is no kdevantproject so this will not work ! + QString directoryRadioString = DomUtil::readEntry(dom, "/kdevantproject/run/directoryradio"); + QString DomMainProgram = DomUtil::readEntry(dom, "/kdevantproject/run/mainprogram"); + + if ( directoryRadioString == "build" ) + return buildDirectory(); + + if ( directoryRadioString == "custom" ) + return DomUtil::readEntry(dom, "/kdevantproject/run/customdirectory"); + + int pos = DomMainProgram.findRev('/'); + if (pos != -1) + return buildDirectory() + "/" + DomMainProgram.left(pos); + + return buildDirectory() + "/" + DomMainProgram; + +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString AntProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevantproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + + +QString AntProjectPart::debugArguments() const +{ + return QString(""); +} + +/** Retuns a QString with the run command line arguments */ +QString AntProjectPart::runArguments() const +{ + /// \FIXME there is no kdevantproject so this will not work ! + return DomUtil::readEntry(*projectDom(), "/kdevantproject/run/programargs"); +} + + +QString AntProjectPart::activeDirectory() const +{ + /// \FIXME + +// return m_projectDirectory; + + // returning m_projectDirectory is wrong, the path returned should be _relative_ to the project dir + // returning an empty string until antproject supports the idea of an active directory + return QString(""); +} + + +QStringList AntProjectPart::allFiles() const +{ +/* QStringList res; + + QStringList::ConstIterator it; + for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) + { + QString fileName = *it; + if (!fileName.startsWith("/")) + { + fileName.prepend("/"); + fileName.prepend(m_projectDirectory); + } + res += fileName; + } + + return res;*/ + + // return all files relative to the project directory! + return m_sourceFiles; +} + + +void AntProjectPart::addFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void AntProjectPart::addFiles ( const QStringList& fileList ) +{ + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.append (*it ); + } + + kdDebug() << "Emitting addedFilesToProject" << endl; + emit addedFilesToProject(fileList); +} + +void AntProjectPart::removeFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->removeFiles ( fileList ); +} + +void AntProjectPart::removeFiles ( const QStringList& fileList ) +{ + kdDebug() << "Emitting removedFilesFromProject" << endl; + emit removedFilesFromProject(fileList); + + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.remove ( *it ); + } +} + +void AntProjectPart::parseBuildXML() +{ + m_antOptions.m_targets.clear(); + m_antOptions.m_properties.clear(); + m_antOptions.m_defineProperties.clear(); + + // open build file + QFile bf(m_projectDirectory + "/" + m_antOptions.m_buildXML); + if (!bf.open(IO_ReadOnly)) + return; + + // parse build file + QDomDocument dom; + if (!dom.setContent(&bf)) + { + bf.close(); + return; + } + bf.close(); + + m_projectName = dom.documentElement().attribute("name", m_projectName); + m_antOptions.m_defaultTarget = dom.documentElement().attribute("default", ""); + + QDomNode node = dom.documentElement().firstChild(); + while (!node.isNull()) + { + if (node.toElement().tagName() == "target") + { + if (m_antOptions.m_defaultTarget.isEmpty()) + m_antOptions.m_defaultTarget = node.toElement().attribute("name"); + m_antOptions.m_targets.append(node.toElement().attribute("name")); + } + else if (node.toElement().tagName() == "property") + { + m_antOptions.m_properties.insert(node.toElement().attribute("name"), node.toElement().attribute("value")); + m_antOptions.m_defineProperties.insert(node.toElement().attribute("name"), false); + } + + /// @todo Handle property files + /// @todo evaluate properties' values + + node = node.nextSibling(); + } +} + + +void AntProjectPart::fillMenu() +{ + m_buildProjectAction->setEnabled(!m_antOptions.m_defaultTarget.isEmpty()); + + m_targetMenu->clear(); + int id = 0; + QStringList::ConstIterator it; + for (it = m_antOptions.m_targets.begin(); it != m_antOptions.m_targets.end(); ++it) + m_targetMenu->insertItem(*it, id++); +} + + +void AntProjectPart::slotBuild() +{ + ant(m_antOptions.m_defaultTarget); +} + + +void AntProjectPart::slotTargetMenuActivated(int id) +{ + ant(m_antOptions.m_targets[id]); +} + + +void AntProjectPart::ant(const QString &target) +{ + QString cmd = "%0 cd %1 && ant %2 -buildfile %3 %4 %5"; + + QString verb = ""; + switch (m_antOptions.m_verbosity) + { + case AntOptions::Quiet: + verb = "-quiet"; + break; + case AntOptions::Verbose: + verb = "-verbose"; + break; + default: + verb = "-debug"; + break; + } + + QString options = ""; + QMap::Iterator it; + for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) + if (m_antOptions.m_defineProperties[it.key()]) + options += "-D" + it.key() + "=\"" + it.data() + "\" "; + + QString cp; + if (!m_classPath.count() == 0) + cp = "CLASSPATH="+m_classPath.join(":"); + + makeFrontend()->queueCommand(m_projectDirectory, cmd.arg(cp).arg(m_projectDirectory).arg(target).arg(m_antOptions.m_buildXML).arg(verb).arg(options)); +} + + +void AntProjectPart::projectConfigWidget(KDialogBase *dlg) +{ + QVBox *vbox = dlg->addVBoxPage(i18n("Ant Options")); + m_antOptionsWidget = new AntOptionsWidget(vbox); + + m_antOptionsWidget->BuildXML->setURL(m_antOptions.m_buildXML); + + switch (m_antOptions.m_verbosity) + { + case AntOptions::Quiet: + m_antOptionsWidget->Verbosity->setCurrentItem(0); + break; + case AntOptions::Verbose: + m_antOptionsWidget->Verbosity->setCurrentItem(1); + break; + default: + m_antOptionsWidget->Verbosity->setCurrentItem(2); + break; + } + + m_antOptionsWidget->Properties->setNumRows(m_antOptions.m_properties.count()); + m_antOptionsWidget->Properties->setNumCols(2); + + QMap::Iterator it; + int i=0; + for (it = m_antOptions.m_properties.begin(); it != m_antOptions.m_properties.end(); ++it) + { + QCheckTableItem *citem = new QCheckTableItem(m_antOptionsWidget->Properties, it.key()); + citem->setChecked(m_antOptions.m_defineProperties[it.key()]); + m_antOptionsWidget->Properties->setItem(i,0, citem); + QTableItem *item = new QTableItem(m_antOptionsWidget->Properties, QTableItem::WhenCurrent, it.data()); + m_antOptionsWidget->Properties->setItem(i,1, item); + ++i; + } + + connect(dlg, SIGNAL(okClicked()), this, SLOT(optionsAccepted())); + + vbox = dlg->addVBoxPage(i18n("Classpath")); + m_classPathWidget = new ClassPathWidget(vbox); + + m_classPathWidget->ClassPath->insertStringList(m_classPath); +} + + +void AntProjectPart::optionsAccepted() +{ + if (!m_antOptionsWidget || !m_classPathWidget) + return; + + m_antOptions.m_buildXML = m_antOptionsWidget->BuildXML->url(); + + switch (m_antOptionsWidget->Verbosity->currentItem()) + { + case 1: + m_antOptions.m_verbosity = AntOptions::Verbose; + break; + case 2: + m_antOptions.m_verbosity = AntOptions::Debug; + break; + default: + m_antOptions.m_verbosity = AntOptions::Quiet; + break; + } + + for (int i=0; iProperties->numRows(); ++i) + { + QString key = m_antOptionsWidget->Properties->text(i,0); + m_antOptions.m_properties.replace(key, m_antOptionsWidget->Properties->text(i,1)); + kdDebug() << "PROP: " << key << " = " << m_antOptionsWidget->Properties->text(i,1); + + QCheckTableItem *item =(QCheckTableItem*) m_antOptionsWidget->Properties->item(i,0); + m_antOptions.m_defineProperties.replace(key, item->isChecked()); + } + + m_classPath = m_classPathWidget->ClassPath->items(); + + m_antOptionsWidget = 0; + m_classPathWidget = 0; +} + + +void AntProjectPart::contextMenu(QPopupMenu *popup, const Context *context) +{ + if (!context->hasType( Context::FileContext )) + return; + + const FileContext *fcontext = static_cast(context); + KURL url = fcontext->urls().first(); + if (URLUtil::isDirectory(url)) + return; + + m_contextFileName = url.fileName(); + bool inProject = project()->allFiles().contains(m_contextFileName.mid ( project()->projectDirectory().length() + 1 ) ); + QString popupstr = QFileInfo(m_contextFileName).fileName(); + if (m_contextFileName.startsWith(projectDirectory()+ "/")) + m_contextFileName.remove(0, projectDirectory().length()+1); + + popup->insertSeparator(); + if (inProject) + { + int id = popup->insertItem( i18n("Remove %1 From Project").arg(popupstr), + this, SLOT(slotRemoveFromProject()) ); + popup->setWhatsThis(id, i18n("Remove from project

Removes current file from the project.")); + } + else + { + int id = popup->insertItem( i18n("Add %1 to Project").arg(popupstr), + this, SLOT(slotAddToProject()) ); + popup->setWhatsThis(id, i18n("Add to project

Adds current file from the project.")); + } +} + + +void AntProjectPart::slotAddToProject() +{ + QStringList fileList; + fileList.append ( m_contextFileName ); + addFiles ( fileList ); +} + + +void AntProjectPart::slotRemoveFromProject() +{ + QStringList fileList; + fileList.append ( m_contextFileName ); + removeFiles ( fileList ); +} + + +#include "antprojectpart.moc" + + +/*! + \fn AntProjectPart::distFiles() const + */ +QStringList AntProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "build.xml"); + return sourceList + files; +} diff --git a/buildtools/ant/antprojectpart.h b/buildtools/ant/antprojectpart.h new file mode 100644 index 00000000..d6540c48 --- /dev/null +++ b/buildtools/ant/antprojectpart.h @@ -0,0 +1,117 @@ +#ifndef _ANTPROJECTPART_H_ +#define _ANTPROJECTPART_H_ + + +#include +#include +#include + + +class QPopupMenu; + + +class KAction; +class KDialogBase; +class Context; +class ClassPathWidget; + + +#include "kdevbuildtool.h" + + +class AntOptionsWidget; + + +class AntOptions +{ +public: + + AntOptions(); + + enum Verbosity { Quiet, Verbose, Debug }; + + QString m_buildXML; + QString m_defaultTarget; + QStringList m_targets; + QMap m_properties; + QMap m_defineProperties; + Verbosity m_verbosity; + +}; + + +class AntProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + + AntProjectPart(QObject *parent, const char *name, const QStringList &args); + ~AntProjectPart(); + QStringList distFiles() const; + + +protected: + + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString runArguments() const; + virtual QString debugArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + virtual void addFile(const QString &fileName); + virtual void addFiles ( const QStringList &fileList ); + virtual void removeFile(const QString &fileName); + virtual void removeFiles ( const QStringList& fileList ); + + +private slots: + + void slotBuild(); + void slotTargetMenuActivated(int id); + + void projectConfigWidget(KDialogBase *dlg); + void contextMenu(QPopupMenu *popup, const Context *context); + + void optionsAccepted(); + + void slotAddToProject(); + void slotRemoveFromProject(); + + +private: + + void parseBuildXML(); + void fillMenu(); + void populateProject(); + + void ant(const QString &target); + + QString m_projectDirectory, m_projectName; + QStringList m_classPath; + + QStringList m_sourceFiles; + + AntOptions m_antOptions; + + KAction *m_buildProjectAction; + + QPopupMenu *m_targetMenu; + + AntOptionsWidget *m_antOptionsWidget; + ClassPathWidget *m_classPathWidget; + + QString m_contextFileName; + +}; + + +#endif diff --git a/buildtools/ant/classpathwidget.ui b/buildtools/ant/classpathwidget.ui new file mode 100644 index 00000000..8bfde971 --- /dev/null +++ b/buildtools/ant/classpathwidget.ui @@ -0,0 +1,39 @@ + +ClassPathWidget + + + ClassPathWidget + + + + 0 + 0 + 471 + 288 + + + + + unnamed + + + + ClassPath + + + Class&path + + + + + + keditlistbox.h + kdialog.h + + + + + keditlistbox.h + klineedit.h + + diff --git a/buildtools/ant/kdevantproject.desktop b/buildtools/ant/kdevantproject.desktop new file mode 100644 index 00000000..231339ea --- /dev/null +++ b/buildtools/ant/kdevantproject.desktop @@ -0,0 +1,96 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Ant Project +Comment[br]=Raktres Ant +Comment[ca]=Projecte Ant +Comment[cs]=Ant projekt +Comment[da]=Ant-projekt +Comment[de]=Ant-Projekt für KDevelop +Comment[el]=Έργο Ant +Comment[es]=Proyecto Ant +Comment[et]=Ant projekt +Comment[eu]=Ant proiektua +Comment[fa]=پروژۀ Ant +Comment[fr]=Projet avec Ant +Comment[ga]=Comhad tionscadail Ant +Comment[gl]=Proxecto Ant +Comment[hi]=एएनटी परियोजना +Comment[hu]=Ant-projekt +Comment[is]=Ant verkefni +Comment[it]=Progetto Ant +Comment[ja]=Ant プロジェクト +Comment[ms]=Projek Ant +Comment[nds]=Ant-Projekt +Comment[ne]=एन्ट परियोजना +Comment[nl]=Ant-project +Comment[pa]=Ant ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Ant +Comment[pt]=Projecto Ant +Comment[pt_BR]=Projeto Ant +Comment[ru]=Проект Ant +Comment[sk]=Ant projekt +Comment[sl]=Projekt Ant +Comment[sr]=Ant пројекат +Comment[sr@Latn]=Ant projekat +Comment[sv]=Ant-projekt +Comment[ta]=ஆன்ட்பிராஜக்ட் +Comment[tg]=Лоиҳаи Ant +Comment[tr]=Ant Projesi +Comment[uz]=Ant loyihasi +Comment[uz@cyrillic]=Ant лойиҳаси +Comment[zh_CN]=Ant 工程 +Comment[zh_TW]=Ant 專案 +Name=KDevAntProject +Name[da]=KDevelop Ant-projekt +Name[de]=Ant-Projekt (KDevelop) +Name[hi]=के-डेव-एएनटी-परियोजना +Name[nds]=Ant-Projekt (KDevelop) +Name[ne]=केडीई विकास एन्ट परियोजना +Name[pl]=KDevProjektAnt +Name[sk]=KDevAntProjekt +Name[sv]=KDevelop Ant-projekt +Name[ta]=கெடெவ்ஆன்ட் பிராஜக்ட் +Name[tg]=Лоиҳаи KDevAnt +Name[zh_TW]=KDevelop Ant 專案 +GenericName=Ant Project +GenericName[br]=Raktres Ant +GenericName[ca]=Projecte Ant +GenericName[da]=Ant-projekt +GenericName[de]=Ant-Projekt +GenericName[el]=Έργο Ant +GenericName[es]=Proyecto Ant +GenericName[et]=Ant projekt +GenericName[eu]=Ant proiektua +GenericName[fa]=پروژۀ Ant +GenericName[fr]=Projet avec Ant +GenericName[ga]=Comhad tionscadail Ant +GenericName[gl]=Proxecto Ant +GenericName[hi]=एएनटी परियोजना +GenericName[hu]=Ant-projekt +GenericName[it]=Project con Ant +GenericName[ja]=Ant プロジェクト +GenericName[ms]=Projek Ant +GenericName[nds]=Ant-Projekt +GenericName[ne]=एन्ट परियोजना +GenericName[nl]=Ant-project +GenericName[pl]=Projekt: Ant +GenericName[pt]=Projecto Ant +GenericName[pt_BR]=Projeto Ant +GenericName[ru]=Проект Ant +GenericName[sk]=Ant projekt +GenericName[sl]=Projekt Ant +GenericName[sr]=Ant пројекат +GenericName[sr@Latn]=Ant projekat +GenericName[sv]=Ant-projekt +GenericName[ta]=ஆன்ட்பிராஜக்ட் +GenericName[tg]=Лоиҳаи Ant +GenericName[tr]=Ant Projesi +GenericName[uz]=Ant loyihasi +GenericName[uz@cyrillic]=Ant лойиҳаси +GenericName[zh_CN]=Ant 工程 +GenericName[zh_TW]=Ant 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevantproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/ant/kdevantproject.rc b/buildtools/ant/kdevantproject.rc new file mode 100644 index 00000000..df892b3c --- /dev/null +++ b/buildtools/ant/kdevantproject.rc @@ -0,0 +1,14 @@ + + + +

+ + + + + + + + diff --git a/buildtools/autotools/Makefile.am b/buildtools/autotools/Makefile.am new file mode 100644 index 00000000..5972b662 --- /dev/null +++ b/buildtools/autotools/Makefile.am @@ -0,0 +1,38 @@ +# Here resides the automake project part. + +INCLUDES = -I$(top_srcdir)/buildtools/lib -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/parsers/autotools -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external \ + -I$(top_srcdir)/lib/interfaces/extras -I$(top_srcdir)/lib/util $(all_includes) \ + -I$(top_builddir)/buildtools/lib/widgets + + +kde_module_LTLIBRARIES = libkdevautoproject.la +libkdevautoproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevautoproject_la_LIBADD = \ + $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la \ + $(top_builddir)/buildtools/lib/parsers/autotools/libkdevautotoolsparser.la $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la \ + $(top_builddir)/lib/interfaces/extras/libkdevextras.la $(top_builddir)/lib/libkdevelop.la + +libkdevautoproject_la_SOURCES = autoprojectpart.cpp autoprojectwidget.cpp \ + configureoptionswidget.cpp configureoptionswidgetbase.ui subprojectoptionsdlg.cpp \ + subprojectoptionsdlgbase.ui targetoptionsdlg.cpp targetoptionsdlgbase.ui addservicedlg.cpp \ + addservicedlgbase.ui addapplicationdlg.cpp addapplicationdlgbase.ui addtargetdlg.cpp \ + addtargetdlgbase.ui addsubprojectdlg.cpp addfiledlgbase.ui addfiledlg.cpp \ + removefiledlgbase.ui removefiledlg.cpp addicondlgbase.ui addicondlg.cpp \ + addtranslationdlg.cpp addprefixdlg.cpp kfilednddetailview.cpp kfiledndiconview.cpp \ + fileselectorwidget.cpp misc.cpp addsubprojectdlgbase.ui removetargetdlg.cpp \ + removetargetdlgbase.ui choosetargetdialog.cpp choosetargetdlgbase.ui addexistingdlgbase.ui \ + addexistingfilesdlg.cpp addexistingdirectoriesdlg.cpp kimporticonview.cpp \ + autosubprojectview.cpp autodetailsview.cpp autolistviewitems.cpp managecustomcommandsbase.ui \ + managecustomcommand.cpp autoprojectviewbase.ui autotoolsaction.cpp makefilehandler.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevautoproject.desktop kdevkdeautoproject.desktop + +rcdir = $(kde_datadir)/kdevautoproject +rc_DATA = kdevautoproject.rc + +noinst_HEADERS = managecustomcommand.h autotoolsaction.h makefilehandler.h diff --git a/buildtools/autotools/README b/buildtools/autotools/README new file mode 100644 index 00000000..487cec41 --- /dev/null +++ b/buildtools/autotools/README @@ -0,0 +1 @@ +Please read the README.dox file diff --git a/buildtools/autotools/README.dox b/buildtools/autotools/README.dox new file mode 100644 index 00000000..acad3e64 --- /dev/null +++ b/buildtools/autotools/README.dox @@ -0,0 +1,39 @@ +/** \class AutoProjectPart +Autoprojectpart is a projectmanager for Automake based projects. + +Loads and maintains Makefile.am files. + +\authors Bernd Gehrmann + +\maintainer Victor Rder +\maintainer Amilcar do Carmo Lucas + +\feature supports creating subprojects, targets, services (.desktop) and applications (.desktop). +\feature Automake projects can be configured on subprojects, targets (except DATA and HEADER targets). +\feature It will regenerate the projects Makefile.am files dynamically as you add or +reconfigure subprojects**. +\feature Unsupported automake features will be left unchanged +(hopefully), no major testing has been run yet (at least not by myself). + +\bug bugs in autoproject component at Bugzilla database +\bug Lower Automake Manager view does not update it's view when adding a subproject (and targets, etc to the new subproject) +\bug If removing the Active Target, update the .kdevelop file, too! + + +\note +If you want to change the default implemention for running/starting the binary +please add the following to your project file +\verbatim + + + true + + +\endverbatim +with this configuration the "Automake Manager" doesn't insert the menuentry "execute program" +and doesn't show the "Run Options" in the project configuration.
+Now you can implement this features with your own special plugin. +For an example please look at the projects generated for GBA using the VisualBoy Advance Plugin. +This plugin starts a GBA binary with an emulator. -- Sandy Meier + +*/ diff --git a/buildtools/autotools/addapplicationdlg.cpp b/buildtools/autotools/addapplicationdlg.cpp new file mode 100644 index 00000000..04e132dd --- /dev/null +++ b/buildtools/autotools/addapplicationdlg.cpp @@ -0,0 +1,207 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addapplicationdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + + +AddApplicationDialog::AddApplicationDialog(AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent, const char *name) + : AddApplicationDialogBase(parent, name, true) +{ + filename_edit->setText(".desktop"); + filename_edit->home(false); + filename_edit->setFocus(); + chosentypes_listview->header()->hide(); + availtypes_listview->header()->hide(); + QString addApplication = add_button->text(); + QString removeApplication = remove_button->text(); + + add_button->setText( QApplication::reverseLayout() ? removeApplication : addApplication ); + remove_button->setText( QApplication::reverseLayout() ? addApplication : removeApplication ); + + m_widget = widget; + subProject = spitem; + + // Fill the combo box with program names in the directory + QPtrListIterator tit(spitem->targets); + for (; tit.current(); ++tit) { + if ((*tit)->primary == "PROGRAMS") + executable_combo->insertItem(QString((*tit)->name)); + } + + // Fill the list of available mime types + KMimeType::List l = KMimeType::allMimeTypes(); + KMimeType::List::Iterator it; + for (it = l.begin(); it != l.end(); ++it) + new QListViewItem(availtypes_listview, (*it)->name()); + + setIcon ( SmallIcon ( "window_new" ) ); +} + + +AddApplicationDialog::~AddApplicationDialog() +{} + + +void AddApplicationDialog::iconClicked() +{ + KIconLoader *loader = AutoProjectFactory::instance()->iconLoader(); + QString name = KIconDialog::getIcon(KIcon::Desktop); + if (!name.isNull()) { + iconName = name; + icon_button->setPixmap(loader->loadIcon(name, KIcon::Desktop)); + } +} + + +void AddApplicationDialog::addTypeClicked() +{ + QListViewItem *selitem = availtypes_listview->selectedItem(); + if (!selitem) + return; + + QListViewItem *olditem = chosentypes_listview->firstChild(); + while (olditem) { + if (selitem->text(0) == olditem->text(0)) + return; + olditem = olditem->nextSibling(); + } + new QListViewItem(chosentypes_listview, selitem->text(0)); +} + + +void AddApplicationDialog::removeTypeClicked() +{ + delete chosentypes_listview->currentItem(); +} + + +void AddApplicationDialog::accept() +{ + // Create list of mime types + QStringList mimeTypes; + QListViewItem *item = chosentypes_listview->firstChild(); + while (item) { + mimeTypes.append(item->text(0)); + item = item->nextSibling(); + } + + // Some plausibility tests + QString fileName = filename_edit->text(); + if (fileName.isEmpty() || fileName == ".desktop") { + KMessageBox::sorry(this, i18n("You have to enter a file name.")); + filename_edit->setFocus(); + return; + } + + QString executable = executable_combo->currentText(); + if (executable.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to enter the file name of an executable program.")); + executable_combo->setFocus(); + return; + } + + QString name = name_edit->text(); + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to enter an application name.")); + name_edit->setFocus(); + return; + } + + QFile f(subProject->path + "/" + fileName); + if (f.exists()) { + KMessageBox::sorry(this, i18n("A file with this name exists already.")); + filename_edit->setFocus(); + return; + } + if (!f.open(IO_WriteOnly)) { + KMessageBox::sorry(this, i18n("Could not open file for writing.")); + return; + } + + QTextStream stream(&f); + stream << "[Desktop Entry]" << endl; + stream << "Type=Application" << endl; + stream << "Name=" << name << endl; + stream << "Exec=" << (executable + " -caption \"%c\" %i %m %u") << endl; + stream << "Comment=" << comment_edit->text() << endl; + if (!iconName.isNull()) + stream << "Icon=" << iconName << endl; + stream << "MimeTypes=" << mimeTypes.join(";") << endl; + stream << "Terminal=" << (terminal_box->isChecked()? "true" : "false") << endl; + f.close(); + + // Find a prefix that points to the applnk directory. + // If there is none, use appslnksection + QString section = section_combo->currentText(); + QString appsdir = "$(kde_appsdir)/" + section; + QMap::ConstIterator it; + for (it = subProject->prefixes.begin(); it != subProject->prefixes.end(); ++it) + if (it.data() == appsdir) + break; + + QMap replaceMap; + QString prefix; + if (it == subProject->prefixes.end()) { + prefix = "applnk" + section; + replaceMap.insert(prefix + "dir", appsdir); + subProject->prefixes.insert(prefix, appsdir); + } else { + prefix = it.key(); + } + QString varname = prefix + "_DATA"; + + // Look if a list view item for this prefix exists already. + // Create a new one otherwise + TargetItem *titem = 0; + for (uint i=0; i < subProject->targets.count(); ++i) { + TargetItem *tmptitem = subProject->targets.at(i); + if ("DATA" == tmptitem->primary && prefix == tmptitem->prefix) { + titem = tmptitem; + break; + } + } + if (!titem) { + titem = m_widget->createTargetItem("", prefix, "DATA", false); + subProject->targets.append(titem); + } + // Add this file to the target + FileItem *fitem = m_widget->createFileItem(fileName, subProject); + titem->sources.append(fitem); + + subProject->variables[varname] += (" " + fileName); + replaceMap.insert(varname, subProject->variables[varname]); + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + QDialog::accept(); +} + +#include "addapplicationdlg.moc" diff --git a/buildtools/autotools/addapplicationdlg.h b/buildtools/autotools/addapplicationdlg.h new file mode 100644 index 00000000..d9f8e6fc --- /dev/null +++ b/buildtools/autotools/addapplicationdlg.h @@ -0,0 +1,45 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDAPPLICATIONDLG_H_ +#define _ADDAPPLICATIONDLG_H_ + +#include "addapplicationdlgbase.h" + +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddApplicationDialog : public AddApplicationDialogBase +{ + Q_OBJECT + +public: + AddApplicationDialog( AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent = 0, const char *name = 0 ); + ~AddApplicationDialog(); + +protected: + virtual void iconClicked(); + virtual void addTypeClicked(); + virtual void removeTypeClicked(); + virtual void accept(); + +private: + AutoProjectWidget *m_widget; + SubprojectItem *subProject; + QString iconName; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/addapplicationdlgbase.ui b/buildtools/autotools/addapplicationdlgbase.ui new file mode 100644 index 00000000..5e6def81 --- /dev/null +++ b/buildtools/autotools/addapplicationdlgbase.ui @@ -0,0 +1,552 @@ + +AddApplicationDialogBase + + + add_application_dialog + + + + 0 + 0 + 586 + 425 + + + + Add New Application .desktop File + + + false + + + + unnamed + + + + GroupBox7 + + + &Application File + + + + unnamed + + + + terminal_box + + + Start in t&erminal + + + + + comment_edit + + + + + filename_edit + + + + + Layout2 + + + + unnamed + + + 0 + + + + icon_button + + + + 24 + 24 + + + + + + + false + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + executable_combo + + + true + + + + + name_edit + + + + + + Application + + + + + Games + + + + + Development + + + + + Editors + + + + + Graphics + + + + + Internet + + + + + Multimedia + + + + + Office + + + + + Settings + + + + + System + + + + + Toys + + + + + Utilities + + + + + WordProcessing + + + + section_combo + + + + + name_label_2 + + + + + + + E&xecutable: + + + AlignVCenter|AlignRight + + + executable_combo + + + + + icon_label + + + + + + + &Icon: + + + AlignVCenter|AlignRight + + + icon_button + + + + + section_label + + + + + + + &Section: + + + AlignVCenter|AlignRight + + + section_combo + + + + + filename_label + + + + + + + &File name: + + + AlignVCenter|AlignRight + + + filename_edit + + + + + name_label + + + + + + + &Name: + + + AlignVCenter|AlignRight + + + name_edit + + + + + comment_label + + + + + + + Co&mment: + + + AlignVCenter|AlignRight + + + comment_edit + + + + + + + Spacer11 + + + Vertical + + + Preferred + + + + 20 + 20 + + + + + + GroupBox6 + + + Mime &Types + + + + unnamed + + + + Layout5 + + + + unnamed + + + 0 + + + + + + + + true + + + true + + + + chosentypes_listview + + + LastColumn + + + + + Layout3 + + + + unnamed + + + 0 + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + add_button + + + <- + + + + + remove_button + + + -> + + + + + Spacer5 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + true + + + true + + + + availtypes_listview + + + LastColumn + + + + + + + + + Layout1 + + + + unnamed + + + 0 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okbutton + + + &OK + + + true + + + true + + + + + cancelbutton + + + &Cancel + + + true + + + + + + + + + cancelbutton + clicked() + add_application_dialog + reject() + + + okbutton + clicked() + add_application_dialog + accept() + + + icon_button + clicked() + add_application_dialog + iconClicked() + + + add_button + clicked() + add_application_dialog + addTypeClicked() + + + remove_button + clicked() + add_application_dialog + removeTypeClicked() + + + + filename_edit + executable_combo + name_edit + icon_button + terminal_box + section_combo + comment_edit + chosentypes_listview + add_button + remove_button + availtypes_listview + okbutton + cancelbutton + + + kdialog.h + + + addTypeClicked() + iconClicked() + removeTypeClicked() + + + + diff --git a/buildtools/autotools/addexistingdirectoriesdlg.cpp b/buildtools/autotools/addexistingdirectoriesdlg.cpp new file mode 100644 index 00000000..625d6af1 --- /dev/null +++ b/buildtools/autotools/addexistingdirectoriesdlg.cpp @@ -0,0 +1,388 @@ +/*************************************************************************** + ------------------- + begin : 12/21/2002 + copyright : (C) 2002 by Victor R�er + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 +#include + +#include +#include +#include +#include + +#include "autolistviewitems.h" +#include "autosubprojectview.h" + +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + +#include "kimporticonview.h" + +#include "urlutil.h" + +#include "addexistingdirectoriesdlg.h" + +AddExistingDirectoriesDialog::AddExistingDirectoriesDialog ( AutoProjectPart* part, AutoProjectWidget *widget, SubprojectItem* spitem, QWidget* parent, const char* name, bool modal, WFlags fl ) + : AddExistingDlgBase ( parent, name, modal, fl ) +{ + setIcon ( SmallIcon ( "fileimport.png" ) ); + + m_spitem = spitem; + + m_part = part; + m_widget = widget; + + KFile::Mode mode = KFile::Directory; + +// if ( spitem && spitem->type() == ProjectItem::Subproject ) +// { +// destStaticLabel->setText ( i18n ( "Subproject:" ) ); +// destLabel->setText ( spitem->subdir ); +// targetLabel->setText ( i18n ( "none" ) ); +// directoryLabel->setText ( i18n ( spitem->path ) ); +// } + + sourceSelector = new FileSelectorWidget ( part, mode, sourceGroupBox, "source file selector" ); + sourceGroupBoxLayout->addWidget ( sourceSelector ); + + importView = new KImportIconView ( i18n("Drag one or more directories with an existing Makefile.am from the left view and drop it here."), destGroupBox, "destination icon view" ); + destGroupBoxLayout->addWidget ( importView ); + + setIcon ( SmallIcon ( "fileimport.png" ) ); + + QWidget::setTabOrder(sourceSelector, addAllButton); + QWidget::setTabOrder(addAllButton, addSelectedButton); + QWidget::setTabOrder(addSelectedButton, importView); + QWidget::setTabOrder(importView, removeAllButton); + QWidget::setTabOrder(removeAllButton, removeSelectedButton); + QWidget::setTabOrder(removeSelectedButton, okButton); + QWidget::setTabOrder(okButton, cancelButton); + + sourceSelector->setFocus(); + + init(); +} + + +AddExistingDirectoriesDialog::~AddExistingDirectoriesDialog() +{ +} + +void AddExistingDirectoriesDialog::init() +{ + progressBar->hide(); + + importView->setMode ( KIconView::Select ); + importView->setItemsMovable ( false ); + + connect ( okButton, SIGNAL ( clicked () ), this, SLOT ( slotOk () ) ); + + connect ( addSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotAddSelected() ) ); + connect ( addAllButton, SIGNAL ( clicked () ), this, SLOT ( slotAddAll() ) ); + connect ( removeSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveSelected() ) ); + connect ( removeAllButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveAll() ) ); + + connect ( importView, SIGNAL ( dropped( QDropEvent* ) ), this, SLOT ( slotDropped ( QDropEvent* ) ) ); + + importView->setSelectionMode ( KFile::Multi ); + + sourceSelector->setDir ( m_spitem->path ); +} + +void AddExistingDirectoriesDialog::importItems() +{ + if( !importView->items() ) + return; + + // items added via button or drag 'n drop + KFileItemListIterator itemList ( m_importList ); + + // items already added to the importView + KFileItemListIterator importedList ( *importView->items() ); + + QStringList duplicateList; + + importedList.toFirst(); + + for ( ; importedList.current(); ++importedList ) + { + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( ( *importedList )->name() == ( *itemList )->name() ) + { + m_importList.remove ( ( *itemList ) ); + + // to avoid that a item is added twice + if ( !duplicateList.remove ( ( *importedList )->name() ) ) + { + duplicateList.append ( ( *importedList )->name() ); + } + } + } + } + + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + KURL amURL = itemList.current()->url(); + amURL.addPath("Makefile.am"); + if (KIO::NetAccess::exists(amURL)) + { + importView->insertItem ( ( *itemList ) ); + } + } + + importView->somethingDropped ( true ); + + m_importList.clear(); + + importView->update (); +} + +void AddExistingDirectoriesDialog::slotOk() +{ + if ( importView->items()->count() == 0 ) QDialog::reject(); + + KFileItemListIterator items ( *importView->items() ); + + QStringList dirs; + + for ( ; items.current(); ++items ) + { + //if the directory is outside the project directory +// kdDebug( 9020 ) << "dir to add " << items.current()->url().path() << " subproject " << m_spitem->path << endl; + if (items.current()->url().path() != m_spitem->path) + { + //copy + //FIXME: check this after 3.0 release and add a possibility to link, not just copy + KProcess proc; + + proc << "cp"; + proc << "-r"; + proc << items.current()->url().path(); + proc << m_spitem->path; + proc.start(KProcess::Block); + } + dirs << items.current()->name(); + } + + for (QStringList::const_iterator it = dirs.begin(); it != dirs.end(); ++it) + { + QString name = *it; + + // Adjust SUBDIRS variable in containing Makefile.am + if (m_spitem->variables["SUBDIRS"].find("$(TOPSUBDIRS)") != -1) + { + QFile subdirsfile( m_spitem->path + "/subdirs" ); + if ( subdirsfile.open( IO_WriteOnly | IO_Append ) ) + { + QTextStream subdirsstream( &subdirsfile ); + subdirsstream << name << endl; + subdirsfile.close(); + } + } + else if (m_spitem->variables["SUBDIRS"].find("$(AUTODIRS)") != -1) + { + } + else + { + m_spitem->variables["SUBDIRS"] += (" " + name); + QMap replaceMap; + replaceMap.insert("SUBDIRS", m_spitem->variables["SUBDIRS"]); + AutoProjectTool::addToMakefileam(m_spitem->path + "/Makefile.am", replaceMap); + } + + // Create new item in tree view + SubprojectItem *newitem = new SubprojectItem(m_spitem, name); + newitem->subdir = name; + newitem->path = m_spitem->path + "/" + name; + newitem->variables["INCLUDES"] = m_spitem->variables["INCLUDES"]; + newitem->setOpen(true); + + // Move to the bottom of the list + QListViewItem *lastItem = m_spitem->firstChild(); + while (lastItem->nextSibling()) + lastItem = lastItem->nextSibling(); + if (lastItem != newitem) + newitem->moveItem(lastItem); + + // Create a Makefile in the new subdirectory + + QDir dir( m_spitem->path + "/" + name ); + QFile f( dir.filePath("Makefile.am") ); + if (f.exists()) { + m_widget->getSubprojectView()->parse( newitem ); + } else { + if (!f.open(IO_WriteOnly)) { +// KMessageBox::sorry(this, i18n("Could not create Makefile.am in subdirectory %1.").arg(name)); + continue; + } + QTextStream stream(&f); + stream << "INCLUDES = " << newitem->variables["INCLUDES"] << endl << "METASOURCES = AUTO" << endl; + f.close(); + } + + + + // if !isKDE: add the new sub-proj to configure.in or configure.ac + if ( !m_part->isKDE() ) { + QString projroot = m_part->projectDirectory() + "/"; + QString subdirectory = dir.path(); + QString relpath = subdirectory.replace(0, projroot.length(),""); + + QString configureFile = m_part->getAutoConfFile(projroot); + + QStringList list = AutoProjectTool::configureinLoadMakefiles(configureFile); + if ( !list.isEmpty() ) + { + list.push_back( relpath + "/Makefile" ); + AutoProjectTool::configureinSaveMakefiles(configureFile, list); + } + } + + m_part->needMakefileCvs(); + + } + QDialog::accept(); +} + +void AddExistingDirectoriesDialog::slotAddSelected() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->selectedItems() ); + + for ( ; it.current(); ++it ) + { + QString relPath = URLUtil::extractPathNameRelative(m_part->projectDirectory(), ( *it )->url()); + if (relPath[relPath.length()-1] == '/') + relPath = relPath.left(relPath.length()-1); + if ( (relPath.isEmpty()) || (! m_widget->allSubprojects().contains( relPath )) ) + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + +void AddExistingDirectoriesDialog::slotAddAll() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->view()->items() ); + + for ( ; it.current(); ++it ) + { + QString relPath = URLUtil::extractPathNameRelative(m_part->projectDirectory(), ( *it )->url()); + if (relPath[relPath.length()-1] == '/') + relPath = relPath.left(relPath.length()-1); + if ( (relPath.isEmpty()) || ( ! m_widget->allSubprojects().contains( relPath )) ) + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + +void AddExistingDirectoriesDialog::slotRemoveAll() +{ + KURL::List deletedFiles; + KFileItemListIterator it ( *importView->items() ); + + for ( ; it.current(); ++it ) + { + kdDebug ( 9020 ) << "AddExistingDirectoriesDialog::slotRemoveAll()" << endl; + //deletedFiles.append ( ( *it )->url() ); + if ( (*it ) ) importView->removeItem ( *it ); + } + + importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + +void AddExistingDirectoriesDialog::slotRemoveSelected() +{ + KFileItemListIterator items ( *importView->items() ); + + KFileItemList* selectedList = (KFileItemList*) importView->selectedItems(); + + KFileItem * deleteItem = 0L; + + for ( ; items.current(); ++items ) + { + deleteItem = selectedList->first(); + + while ( deleteItem ) + { + if ( deleteItem == ( *items ) ) + { + importView->removeItem ( deleteItem ); + deleteItem = selectedList->current(); + } + else + { + deleteItem = selectedList->next(); + } + } + } + + if ( importView->items()->count() == 0 ) importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + +void AddExistingDirectoriesDialog::slotDropped ( QDropEvent* ev ) +{ + kdDebug ( 9020 ) << "AddExistingDirectoriesDialog::dropped()" << endl; + + KURL::List urls; + + KURLDrag::decode( ev, urls ); + + KFileItem* item = 0L; + KMimeType::Ptr type = 0L; + + + for ( KURL::List::Iterator it = urls.begin(); it != urls.end(); ++it ) + { + //check if this subproject is already in project + QString relPath = URLUtil::extractPathNameRelative(m_part->projectDirectory(), *it); + if (relPath[relPath.length()-1] == '/') + relPath = relPath.left(relPath.length()-1); + if ( (relPath.isEmpty()) || ( ! m_widget->allSubprojects().contains( relPath )) ) + { + type = KMimeType::findByURL ( ( *it ) ); + + if ( type->name() != KMimeType::defaultMimeType() ) + { + item = new KFileItem ( ( *it ) , type->name(), 0 ); + } + else + { + item = new KFileItem ( ( *it ), "inode/directory", 0 ); + } + + m_importList.append ( item ); + } + } + + importItems(); +} + +#include "addexistingdirectoriesdlg.moc" + +//kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/autotools/addexistingdirectoriesdlg.h b/buildtools/autotools/addexistingdirectoriesdlg.h new file mode 100644 index 00000000..c4dd048e --- /dev/null +++ b/buildtools/autotools/addexistingdirectoriesdlg.h @@ -0,0 +1,74 @@ +/*************************************************************************** + ------------------- + begin : 12/21/2002 + copyright : (C) 2002 by Victor R�er + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _ADDEXISTINGDIRECTORIESDLG_H_ +#define _ADDEXISTINGDIRECTORIESDLG_H_ + +#include "addexistingdlgbase.h" + +#include +#include + +#include "misc.h" +#include "fileselectorwidget.h" + +class FileSelectorWidget; +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; +class KFileItem; +class KImportIconView; + +class AddExistingDirectoriesDialog : public AddExistingDlgBase +{ + Q_OBJECT + +public: + AddExistingDirectoriesDialog ( AutoProjectPart* part, AutoProjectWidget *widget, + SubprojectItem* spitem, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~AddExistingDirectoriesDialog(); + +private: + FileSelectorWidget* sourceSelector; + KImportIconView* importView; + + AutoProjectPart* m_part; + AutoProjectWidget* m_widget; + + TargetItem* m_titem; + SubprojectItem* m_spitem; + + KFileItemList m_importList; + +protected: + void init(); + void importItems (); + +protected slots: + void slotAddSelected(); + void slotAddAll(); + void slotRemoveAll(); + void slotRemoveSelected(); + void slotDropped ( QDropEvent* ev ); + + void slotOk(); +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/addexistingdlgbase.ui b/buildtools/autotools/addexistingdlgbase.ui new file mode 100644 index 00000000..cf73ee21 --- /dev/null +++ b/buildtools/autotools/addexistingdlgbase.ui @@ -0,0 +1,459 @@ + +AddExistingDlgBase + + + AddExistingDlgBase + + + + 0 + 0 + 592 + 445 + + + + + 5 + 5 + 0 + 0 + + + + ImportExistingDlgBase + + + + unnamed + + + + layout10 + + + + unnamed + + + + buttonSpacer + + + Horizontal + + + Expanding + + + + 317 + 20 + + + + + + okButton + + + &OK + + + true + + + + + cancelButton + + + &Cancel + + + + + + + progressBar + + + true + + + + + infoGroupBox + + + + 5 + 0 + 0 + 0 + + + + + 32767 + 32767 + + + + Box + + + Sunken + + + Subproject Information + + + + unnamed + + + + infoLayout1 + + + + unnamed + + + 0 + + + + directoryStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + + + + Directory: + + + + + targetStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + + + + Target: + + + + + + + infoLayout2 + + + + unnamed + + + 0 + + + + directoryLabel + + + + 5 + 5 + 0 + 0 + + + + [DIRECTORY] + + + + + targetLabel + + + [TARGET] + + + + + + + + + splitter2 + + + + 7 + 7 + 0 + 0 + + + + Horizontal + + + + layout12 + + + + unnamed + + + + layout10 + + + + unnamed + + + + arrowSpacer1 + + + Horizontal + + + Expanding + + + + 84 + 20 + + + + + + addAllButton + + + A&dd All + + + Import by creating symbolic links (recommended) + + + + + addSelectedButton + + + &Add Selected + + + Import by copying (not recommended) + + + + + arrowSpacer2 + + + Horizontal + + + Expanding + + + + 84 + 20 + + + + + + + + sourceGroupBox + + + + 240 + 250 + + + + + 32767 + 32767 + + + + &Source Directory + + + + + + + unnamed + + + + + + + + layout13 + + + + unnamed + + + + layout11 + + + + unnamed + + + + arrowSpacer1_2 + + + Horizontal + + + Expanding + + + + 21 + 20 + + + + + + removeAllButton + + + R&emove All + + + Removes all added files. + + + + + removeSelectedButton + + + &Remove Selected + + + Removes the selected files. + + + + + arrowSpacer2_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + destGroupBox + + + + 140 + 100 + + + + + 32767 + 32767 + + + + Add &Following + + + + unnamed + + + + + + + + + + + + + cancelButton + clicked() + AddExistingDlgBase + reject() + + + + addAllButton + addSelectedButton + removeAllButton + removeSelectedButton + okButton + cancelButton + + + ksqueezedtextlabel.h + kprogress.h + kdialog.h + + + + + kprogress.h + ksqueezedtextlabel.h + + diff --git a/buildtools/autotools/addexistingfilesdlg.cpp b/buildtools/autotools/addexistingfilesdlg.cpp new file mode 100644 index 00000000..00f3e61b --- /dev/null +++ b/buildtools/autotools/addexistingfilesdlg.cpp @@ -0,0 +1,451 @@ +/*************************************************************************** + ------------------- + begin : Frag' mich was leichteres + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +/** Here resides the Import-existing-files-dialog of the Automake Manager (a KDevelop build tool part) **/ + +#include +#include +#include +//#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "urlutil.h" + +#include "autolistviewitems.h" + +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + +#include "kimporticonview.h" + +#include "addexistingfilesdlg.h" + +/* + * Constructs a AddExistingFilesDialog which is a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ + +AddExistingFilesDialog::AddExistingFilesDialog ( AutoProjectPart* part, AutoProjectWidget *widget, SubprojectItem* spitem, TargetItem* titem, QWidget* parent, const char* name, bool modal, WFlags fl ) + : AddExistingDlgBase ( parent, name, modal, fl ) +{ + m_spitem = spitem; + m_titem = titem; + + m_part = part; + m_widget = widget; + + KFile::Mode mode = KFile::Files; + + if ( titem && spitem && titem->type() == ProjectItem::Target && spitem->type() == ProjectItem::Subproject ) + { + + if ( titem->name.isEmpty() ) + { + QString target = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + targetLabel->setText ( target ); + } + else + { + targetLabel->setText ( titem->name ); + } + directoryLabel->setText ( spitem->path ); + } + + sourceSelector = new FileSelectorWidget ( m_part, mode, sourceGroupBox, "source file selector" ); + sourceGroupBoxLayout->addWidget ( sourceSelector ); + + importView = new KImportIconView ( i18n ( "Drag one or more files from the left view and drop it here." ), destGroupBox, "destination icon view" ); + destGroupBoxLayout->addWidget ( importView ); + //destGroupBoxLayout->setStretchFactor(dir, 2); + + QWidget::setTabOrder(sourceSelector, addAllButton); + QWidget::setTabOrder(addAllButton, addSelectedButton); + QWidget::setTabOrder(addSelectedButton, importView); + QWidget::setTabOrder(importView, removeAllButton); + QWidget::setTabOrder(removeAllButton, removeSelectedButton); + QWidget::setTabOrder(removeSelectedButton, okButton); + QWidget::setTabOrder(okButton, cancelButton); + + sourceSelector->setFocus(); + + setIcon ( SmallIcon ( "fileimport.png" ) ); + + init(); +} + + +/* + * Destroys the object and frees any allocated resources + */ +AddExistingFilesDialog::~AddExistingFilesDialog() +{ + // no need to delete child widgets, Qt does it all for me +} + + +// void AddExistingFilesDialog::resizeEvent ( QResizeEvent* ev ) +// { +// AddExistingDlgBase::resizeEvent ( ev ); +// //importView->update(); +// } + + +void AddExistingFilesDialog::init() +{ + progressBar->hide(); + + importView->setMode ( KIconView::Select ); + importView->setItemsMovable ( false ); + + connect ( okButton, SIGNAL ( clicked () ), this, SLOT ( slotOk () ) ); + + connect ( addSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotAddSelected() ) ); + connect ( addAllButton, SIGNAL ( clicked () ), this, SLOT ( slotAddAll() ) ); + connect ( removeSelectedButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveSelected() ) ); + connect ( removeAllButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveAll() ) ); + + connect ( importView, SIGNAL ( dropped( QDropEvent* ) ), this, SLOT ( slotDropped ( QDropEvent* ) ) ); + + importView->setSelectionMode ( KFile::Multi ); + + Q_ASSERT( m_spitem ); + sourceSelector->setDir ( m_spitem->path ); +} + +void AddExistingFilesDialog::importItems() +{ + if( !importView->items() ) + return; + + // items added via button or drag 'n drop + KFileItemListIterator itemList ( m_importList ); + + // items already added to the importView + KFileItemListIterator importedList ( *importView->items() ); + + QListViewItem* child = m_titem->firstChild(); + + QStringList duplicateList; + + while ( child ) + { + FileItem* curItem = static_cast ( child ); + + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( ( *itemList )->name() == curItem->name ) + { + duplicateList.append ( ( *itemList )->name() ); + m_importList.remove ( ( *itemList ) ); + } + } + + child = child->nextSibling(); + } + + importedList.toFirst(); + + for ( ; importedList.current(); ++importedList ) + { + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( ( *importedList )->name() == ( *itemList )->name() ) + { + m_importList.remove ( ( *itemList ) ); + + // to avoid that a item is added twice + if ( !duplicateList.remove ( ( *importedList )->name() ) ) + { + duplicateList.append ( ( *importedList )->name() ); + } + } + } + } + + if ( duplicateList.count() > 0 ) + { + if ( KMessageBox::warningContinueCancelList ( this, i18n ( + "The following file(s) already exist(s) in the target!\n" + "Press Continue to import only the new files.\n" + "Press Cancel to abort the complete import." ), + duplicateList, "Warning", KGuiItem ( i18n ( "Continue" ) ) ) == KMessageBox::Cancel ) + { + m_importList.clear(); + return; + } + } + + itemList.toFirst(); + + for ( ; itemList.current(); ++itemList ) + { + if ( !( *itemList )->isDir() ) + { + importView->insertItem ( ( *itemList ) ); + } + } + + importView->somethingDropped ( true ); + + m_importList.clear(); + + importView->update (); +} + +void AddExistingFilesDialog::slotOk() +{ + if ( importView->items()->count() == 0 ) QDialog::reject(); + + progressBar->show(); + progressBar->setFormat ( i18n ( "Importing... %p%" ) ); + + qApp->processEvents(); + + KFileItemListIterator items ( *importView->items() ); + + // contains at the end only the imported files outside the subproject directory + KFileItemList outsideList; + + QStringList stringList; + + for ( ; items.current(); ++items ) + { + // kdDebug ( 9020 ) << " **** " << ( *items )->url().directory() << "***** " << m_spitem->path << endl; + if ( ( *items )->url().directory() != m_spitem->path ) + { + stringList.append ( ( *items )->name() ); + outsideList.append ( ( *items ) ); + } + } + + progressBar->setTotalSteps ( outsideList.count() + importView->items()->count() ); + + if ( outsideList.count() > 0 ) + { + if ( KMessageBox::questionYesNoList ( this, i18n ( + "The following file(s) are not in the Subproject directory.\n" + "Press Link to add the files by creating symbolic links.\n" + "Press Copy to copy the files into the directory." ), + stringList, i18n("Warning"), KGuiItem ( i18n ( "Link (recommended)" ) ), KGuiItem ( i18n ( "Copy (not recommended)" ) ) ) == KMessageBox::No ) + { + // Copy files into the Subproject directory + KFileItemListIterator it ( outsideList ) ; + + for ( ; it.current(); ++it ) + { + KProcess proc; + + proc << "cp"; + proc << ( *it )->url().path(); + proc << m_spitem->path; + proc.start(KProcess::DontCare); + + progressBar->setValue ( progressBar->value() + 1 ); + } + } + else + { + // Link them into the Subproject directory + KFileItemListIterator it ( outsideList ) ; + + for ( ; it.current(); ++it ) + { + KProcess proc; + + proc << "ln"; + proc << "-s"; + proc << URLUtil::relativePathToFile( m_spitem->path, ( *it )->url().path() ); + proc << m_spitem->path; + proc.start(KProcess::DontCare); + + progressBar->setValue ( progressBar->value() + 1 ); + } + } + } + + items.toFirst(); + + QString canontargetname = AutoProjectTool::canonicalize ( m_titem->name ); + QString varname; + if( m_titem->primary == "PROGRAMS" || m_titem->primary == "LIBRARIES" || m_titem->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = m_titem->prefix + "_" + m_titem->primary; + + QMap replaceMap; + FileItem* fitem = 0L; + QStringList fileList; + + for ( ; items.current(); ++items ) + { + m_spitem->variables [ varname ] += ( " " + ( *items )->name() ); + replaceMap.insert ( varname, m_spitem->variables [ varname ] ); + + fitem = m_widget->createFileItem ( ( *items )->name(), m_spitem ); + m_titem->sources.append ( fitem ); + m_titem->insertItem ( fitem ); + + fileList.append ( m_spitem->path.mid ( m_part->projectDirectory().length() + 1 ) + "/" + ( *items )->name() ); + + progressBar->setValue ( progressBar->value() + 1 ); + } + + m_widget->emitAddedFiles ( fileList ); + + AutoProjectTool::addToMakefileam ( m_spitem->path + "/Makefile.am", replaceMap ); + + QDialog::accept(); + +} + +void AddExistingFilesDialog::slotAddSelected() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->selectedItems() ); + + for ( ; it.current(); ++it ) + { + if ( ( *it )->url().isLocalFile() ) // maybe unnecessary + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + + +void AddExistingFilesDialog::slotAddAll() +{ + KFileItemListIterator it ( *sourceSelector->dirOperator()->view()->items() ); + + for ( ; it.current(); ++it ) + { + if ( ( *it )->url().isLocalFile() ) // maybe unnecessary + { + m_importList.append ( ( *it ) ); + } + } + + importItems(); +} + +void AddExistingFilesDialog::slotRemoveAll() +{ + KURL::List deletedFiles; + KFileItemListIterator it ( *importView->items() ); + + for ( ; it.current(); ++it ) + { + kdDebug ( 9020 ) << "AddExistingFilesDialog::slotRemoveAll()" << endl; + //deletedFiles.append ( ( *it )->url() ); + if ( (*it ) ) importView->removeItem ( *it ); + } + + importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + +void AddExistingFilesDialog::slotRemoveSelected() +{ + KFileItemListIterator items ( *importView->items() ); + + KFileItemList* selectedList = (KFileItemList*) importView->selectedItems(); + + KFileItem * deleteItem = 0L; + + for ( ; items.current(); ++items ) + { + deleteItem = selectedList->first(); + + while ( deleteItem ) + { + if ( deleteItem == ( *items ) ) + { + importView->removeItem ( deleteItem ); + deleteItem = selectedList->current(); + } + else + { + deleteItem = selectedList->next(); + } + } + } + + if ( importView->items()->count() == 0 ) importView->somethingDropped ( false ); + + importView->viewport()->update(); +} + + +void AddExistingFilesDialog::slotDropped ( QDropEvent* ev ) +{ + kdDebug ( 9020 ) << "AddExistingFilesDialog::dropped()" << endl; + + KURL::List urls; + + KURLDrag::decode( ev, urls ); + + KFileItem* item = 0L; + KMimeType::Ptr type = 0L; + + + for ( KURL::List::Iterator it = urls.begin(); it != urls.end(); ++it ) + { + if ( ( *it ).isLocalFile() ) // maybe unnecessary + { + type = KMimeType::findByURL ( ( *it ) ); + + if ( type->name() != KMimeType::defaultMimeType() ) + { + item = new KFileItem ( ( *it ) , type->name(), 0 ); + } + else + { + // take a text-file-icon instead of the ugly question-mark-icon + item = new KFileItem ( ( *it ), "text/plain", 0 ); + } + + m_importList.append ( item ); + } + } + + importItems(); +} + +#include "addexistingfilesdlg.moc" diff --git a/buildtools/autotools/addexistingfilesdlg.h b/buildtools/autotools/addexistingfilesdlg.h new file mode 100644 index 00000000..5bee18b6 --- /dev/null +++ b/buildtools/autotools/addexistingfilesdlg.h @@ -0,0 +1,77 @@ +/*************************************************************************** + ------------------- + begin : Frag' mich was leichteres + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +/** Here resides the Import-existing-files-dialog of the Automake Manager **/ +/** (a KDevelop build tool part) **/ + +#ifndef ADDEXISTINGFILESDLG_H +#define ADDEXISTINGFILESDLG_H + +#include +#include + +#include "addexistingdlgbase.h" +#include "fileselectorwidget.h" + +#include "misc.h" + +class KImportIconView; +class FileSelectorWidget; +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; +class KFileItem; + +class AddExistingFilesDialog : public AddExistingDlgBase +{ + Q_OBJECT + +public: + AddExistingFilesDialog( AutoProjectPart* part, AutoProjectWidget *widget, + SubprojectItem* spitem, TargetItem* titem, QWidget* parent = 0, + const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~AddExistingFilesDialog(); + +private: + FileSelectorWidget* sourceSelector; + KImportIconView* importView; + + AutoProjectPart* m_part; + AutoProjectWidget* m_widget; + + TargetItem* m_titem; + SubprojectItem* m_spitem; + + KFileItemList m_importList; + +protected: + // virtual void resizeEvent ( QResizeEvent* ev ); + void init(); + void importItems (); + +protected slots: + void slotAddSelected(); + void slotAddAll(); + void slotRemoveAll(); + void slotRemoveSelected(); + void slotDropped ( QDropEvent* ev ); + + void slotOk(); +}; + +#endif // ADDEXISTINGFILESDLG_H +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/addfiledlg.cpp b/buildtools/autotools/addfiledlg.cpp new file mode 100644 index 00000000..46529086 --- /dev/null +++ b/buildtools/autotools/addfiledlg.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addfiledlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "autolistviewitems.h" + +#include "filetemplate.h" +#include "misc.h" +#include "urlutil.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + +#include "kdevpartcontroller.h" + +AddFileDialog::AddFileDialog(AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *item, + QWidget *parent, const char *name) + : AddFileDlgBase(parent, name, true) +{ + connect ( createButton, SIGNAL ( clicked() ), this, SLOT ( accept() ) ); + connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) ); + + directoryLabel->setText ( spitem->path ); + if ( item->name.isEmpty() ) + targetLabel->setText ( i18n ( "%1 in %2" ).arg ( item->primary ).arg ( item->prefix ) ); + else + targetLabel->setText ( item->name ); + + setIcon ( SmallIcon ( "filenew.png" ) ); + + m_part = part; + m_widget = widget; + subProject = spitem; + target = item; +} + + +AddFileDialog::~AddFileDialog() +{} + + +void AddFileDialog::accept() +{ + QString name = fileEdit->text(); + if (name.find('/') != -1) { + KMessageBox::sorry(this, i18n("Please enter the file name without '/' and so on.")); + return; + } + + QListViewItem *child = target->firstChild(); + while (child) { + FileItem *item = static_cast(child); + if (name == item->name) { + KMessageBox::sorry(this, i18n("This file is already in the target.")); + return; + } + child = child->nextSibling(); + } + + if (templateCheckBox->isChecked()) { + QString srcdir = m_part->projectDirectory(); + QString destdir = subProject->path; + QString destpath = destdir + "/" + name; + if (QFileInfo(destpath).exists()) { + KMessageBox::sorry(this, i18n("A file with this name already exists.

Please use the \"Add existing file\" dialog.")); + return; + } + if( !FileTemplate::copy(m_part, QFileInfo(name).extension(), destpath) ) + kdDebug(9020) << "cannot create file " << destpath << endl; + } else { + // create an empty file + QString srcdir = m_part->projectDirectory(); + QString destdir = subProject->path; + QString destpath = destdir + "/" + name; + + if (QFileInfo(destpath).exists()) { + KMessageBox::sorry(this, i18n("A file with this name already exists.

Please use the \"Add existing file\" dialog.")); + return; + } + + QFile f( destpath ); + if( f.open(IO_WriteOnly) ) + f.close(); + } + + FileItem *fitem = m_widget->createFileItem(name, subProject); + target->sources.append(fitem); + target->insertItem(fitem); + + QString canontargetname = AutoProjectTool::canonicalize(target->name); + QString varname; + if( target->primary == "PROGRAMS" || target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = target->prefix + "_" + target->primary; + subProject->variables[varname] += (" " + name); + + QMap replaceMap; + replaceMap.insert(varname, subProject->variables[varname]); + + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + m_widget->emitAddedFile( subProject->path.mid ( m_part->project()->projectDirectory().length() + 1 ) + "/" + name ); + m_part->partController()->editDocument ( KURL ( subProject->path + "/" + name ) ); + + QDialog::accept(); +} + +#include "addfiledlg.moc" diff --git a/buildtools/autotools/addfiledlg.h b/buildtools/autotools/addfiledlg.h new file mode 100644 index 00000000..328e3593 --- /dev/null +++ b/buildtools/autotools/addfiledlg.h @@ -0,0 +1,47 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDFILEDLG_H_ +#define _ADDFILEDLG_H_ + +#include + +#include "addfiledlgbase.h" + +class QCheckBox; +class QLineEdit; +class AutoProjectPart; +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddFileDialog : public AddFileDlgBase +{ + Q_OBJECT + +public: + AddFileDialog( AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *item, + QWidget *parent = 0, const char *name = 0 ); + ~AddFileDialog(); + +protected: + virtual void accept(); + +private: + AutoProjectPart *m_part; + AutoProjectWidget *m_widget; + SubprojectItem *subProject; + TargetItem *target; +}; + +#endif diff --git a/buildtools/autotools/addfiledlgbase.ui b/buildtools/autotools/addfiledlgbase.ui new file mode 100644 index 00000000..dc8e38b2 --- /dev/null +++ b/buildtools/autotools/addfiledlgbase.ui @@ -0,0 +1,289 @@ + +AddFileDlgBase + + + AddFileDlgBase + + + + 0 + 0 + 521 + 217 + + + + + 5 + 5 + 0 + 0 + + + + + 32767 + 32767 + + + + + 0 + 0 + + + + Add New Created File to Target + + + + unnamed + + + + targetBox + + + Box + + + Sunken + + + Subproject Information + + + + unnamed + + + + targetLayout + + + + unnamed + + + 0 + + + + directoryLabel + + + [TARGET DIRECTORY] + + + + + targetLabel + + + [TARGET NAME] + + + + + directoryStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + + + + Directory: + + + + + targetStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + + + + Target: + + + + + + + + + fileGroupBox + + + File Information + + + + unnamed + + + + fileEdit + + + + 5 + 5 + 0 + 0 + + + + + 0 + 0 + + + + + + templateCheckBox + + + + 1 + 0 + 0 + 0 + + + + &Use file template + + + true + + + + + fileStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + 0 + 0 + + + + + + + + New file &name (with extension): + + + fileEdit + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + buttonLayout + + + + unnamed + + + 0 + + + + buttonSpacer + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + createButton + + + &OK + + + true + + + + + cancelButton + + + &Cancel + + + + + + + + ksqueezedtextlabel.h + klineedit.h + kdialog.h + + + + + ksqueezedtextlabel.h + klineedit.h + + diff --git a/buildtools/autotools/addicondlg.cpp b/buildtools/autotools/addicondlg.cpp new file mode 100644 index 00000000..251601f7 --- /dev/null +++ b/buildtools/autotools/addicondlg.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addicondlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include // fix me! + +#include "autolistviewitems.h" + +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + + +const char *type_map[] = { + "app", "action", "device", "filesys", "mime" +}; + + +const char *size_map[] = { + "hi16", "hi22", "hi32", "hi48", "hi64", "hi128" +}; + + +AddIconDialog::AddIconDialog(AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *titem, + QWidget *parent, const char *name) + : AddIconDialogBase(parent, name, true) +{ + type_combo->insertItem(i18n("Application")); + type_combo->insertItem(i18n("Action")); + type_combo->insertItem(i18n("Device")); + type_combo->insertItem(i18n("File System")); + type_combo->insertItem(i18n("MIME Type")); + + size_combo->insertItem("16"); + size_combo->insertItem("22"); + size_combo->insertItem("32"); + size_combo->insertItem("48"); + size_combo->insertItem("64"); + size_combo->insertItem("128"); + + somethingChanged(); + + setIcon ( SmallIcon ( "iconadd_kdevelop" ) ); + + m_part = part; + m_widget = widget; + m_subProject = spitem; + m_target = titem; +} + + +AddIconDialog::~AddIconDialog() +{} + + +void AddIconDialog::somethingChanged() +{ + QString size = size_map[size_combo->currentItem()]; + QString type = type_map[type_combo->currentItem()]; + QString name = name_edit->text(); + + filename_edit->setText(size + "-" + type + "-" + name + ".png"); +} + + +void AddIconDialog::accept() +{ + QString name = filename_edit->text(); + + QString destdir = m_subProject->subdir; + QString destpath = destdir + "/" + name; + + QString size = size_combo->currentText(); + QString unknown = KIconTheme::defaultThemeName()+ "/" + size + "x" + size + "/mimetypes/unknown.png"; + + QString templateFileName = locate("icon", unknown); + kdDebug(9020) << "Unknown: " << unknown << ", template: " << templateFileName << endl; + + if (!templateFileName.isEmpty()) { + KProcess proc; + proc << "cp"; + proc << templateFileName; + proc << destpath; + proc.start(KProcess::DontCare); + } + + FileItem *fitem = m_widget->createFileItem(name, m_subProject); + m_target->sources.append(fitem); + m_target->insertItem(fitem); + + m_part->startMakeCommand(destdir, QString::fromLatin1("force-reedit")); + + m_widget->emitAddedFile(destpath); + + QDialog::accept(); +} + +#include "addicondlg.moc" diff --git a/buildtools/autotools/addicondlg.h b/buildtools/autotools/addicondlg.h new file mode 100644 index 00000000..64fac0a5 --- /dev/null +++ b/buildtools/autotools/addicondlg.h @@ -0,0 +1,44 @@ +/*************************************************************************** +* Copyright (C) 2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDICONDLG_H_ +#define _ADDICONDLG_H_ + +#include "addicondlgbase.h" + +class AutoProjectPart; +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddIconDialog : public AddIconDialogBase +{ + Q_OBJECT + +public: + AddIconDialog( AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *spitem, TargetItem *titem, + QWidget *parent = 0, const char *name = 0 ); + ~AddIconDialog(); + + +private: + virtual void somethingChanged(); + virtual void accept(); + + AutoProjectPart *m_part; + AutoProjectWidget *m_widget; + SubprojectItem *m_subProject; + TargetItem *m_target; +}; + +#endif diff --git a/buildtools/autotools/addicondlgbase.ui b/buildtools/autotools/addicondlgbase.ui new file mode 100644 index 00000000..7fec5097 --- /dev/null +++ b/buildtools/autotools/addicondlgbase.ui @@ -0,0 +1,273 @@ + +AddIconDialogBase + + + add_icon_dialog + + + + 0 + 0 + 301 + 218 + + + + Add New Icon + + + false + + + + unnamed + + + + + type_label + + + + + + + &Type: + + + AlignVCenter|AlignRight + + + type_combo + + + + + size_label + + + + + + + &Size: + + + AlignVCenter|AlignRight + + + size_combo + + + + + size_combo + + + + + filename_label + + + + + + + File name: + + + AlignVCenter|AlignRight + + + filename_edit + + + + + name_label + + + + + + + &Name: + + + AlignVCenter|AlignRight + + + name_edit + + + + + Line1 + + + HLine + + + Sunken + + + Horizontal + + + + + Layout1 + + + + unnamed + + + 0 + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okbutton + + + &OK + + + true + + + true + + + + + cancelbutton + + + &Cancel + + + true + + + + + + + name_edit + + + unknown + + + + + type_combo + + + + + filename_edit + + + + 5 + 0 + 0 + 0 + + + + StyledPanel + + + Sunken + + + + + Spacer22 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + + + okbutton + clicked() + add_icon_dialog + accept() + + + cancelbutton + clicked() + add_icon_dialog + reject() + + + name_edit + textChanged(const QString&) + add_icon_dialog + somethingChanged() + + + type_combo + activated(int) + add_icon_dialog + somethingChanged() + + + size_combo + activated(int) + add_icon_dialog + somethingChanged() + + + + type_combo + size_combo + name_edit + okbutton + cancelbutton + + + somethingChanged() + + + kdialog.h + + + + + + diff --git a/buildtools/autotools/addprefixdlg.cpp b/buildtools/autotools/addprefixdlg.cpp new file mode 100644 index 00000000..d1557114 --- /dev/null +++ b/buildtools/autotools/addprefixdlg.cpp @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addprefixdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +AddPrefixDialog::AddPrefixDialog( const QString& nameEdit, const QString& pathEdit, + QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("Add Prefix")); + + QLabel *name_label = new QLabel(i18n("&Name:"), this); + name_edit = new KLineEdit(nameEdit, this); + name_edit->setFocus(); + name_label->setBuddy(name_edit); + connect( name_edit, SIGNAL( textChanged ( const QString & ) ), SLOT( slotPrefixChanged() ) ); + + QLabel *path_label = new QLabel(i18n("&Path:"), this); + path_edit = new KLineEdit(pathEdit, this); + path_label->setBuddy(path_edit); + QFontMetrics fm(path_edit->fontMetrics()); + path_edit->setMinimumWidth(fm.width('X')*35); + connect( path_edit, SIGNAL( textChanged ( const QString & ) ), SLOT( slotPrefixChanged() ) ); + + QVBoxLayout *layout = new QVBoxLayout(this, 10); + + QGridLayout *grid = new QGridLayout(2, 2); + layout->addLayout(grid); + grid->addWidget(name_label, 0, 0); + grid->addWidget(name_edit, 0, 1); + grid->addWidget(path_label, 1, 0); + grid->addWidget(path_edit, 1, 1); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + layout->addWidget(frame, 0); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + m_pOk = buttonbox->addButton(KStdGuiItem::ok()); + QPushButton *cancel = buttonbox->addButton(KStdGuiItem::cancel()); + m_pOk->setDefault(true); + connect( m_pOk, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + layout->addWidget(buttonbox, 0); + slotPrefixChanged(); +} + + +AddPrefixDialog::~AddPrefixDialog() +{} + +void AddPrefixDialog::slotPrefixChanged() +{ + m_pOk->setEnabled( !name_edit->text().isEmpty() && !path_edit->text().isEmpty() ); +} + +#include "addprefixdlg.moc" diff --git a/buildtools/autotools/addprefixdlg.h b/buildtools/autotools/addprefixdlg.h new file mode 100644 index 00000000..a20bc63a --- /dev/null +++ b/buildtools/autotools/addprefixdlg.h @@ -0,0 +1,45 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDPREFIXDLG_H_ +#define _ADDPREFIXDLG_H_ + +#include +#include +class QPushButton; + +class AddPrefixDialog : public QDialog +{ + Q_OBJECT + +public: + AddPrefixDialog( const QString& nameEdit = "", const QString& pathEdit = "", + QWidget *parent = 0, const char *name = 0 ); + ~AddPrefixDialog(); + + QString name() const + { + return name_edit->text(); + } + QString path() const + { + return path_edit->text(); + } +private slots: + void slotPrefixChanged(); + +private: + KLineEdit *name_edit; + KLineEdit *path_edit; + QPushButton *m_pOk; +}; + +#endif diff --git a/buildtools/autotools/addservicedlg.cpp b/buildtools/autotools/addservicedlg.cpp new file mode 100644 index 00000000..2dc76e5e --- /dev/null +++ b/buildtools/autotools/addservicedlg.cpp @@ -0,0 +1,233 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addservicedlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + + +AddServiceDialog::AddServiceDialog(AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent, const char *name) + : AddServiceDialogBase(parent, name, true) +{ + filename_edit->setText(".desktop"); + filename_edit->home(false); + filename_edit->setFocus(); + chosentypes_listview->header()->hide(); + availtypes_listview->header()->hide(); + + m_widget = widget; + subProject = spitem; + + // Fill the combo box with library names in the directory + QPtrListIterator tit(spitem->targets); + for (; tit.current(); ++tit) { + if ((*tit)->primary == "LTLIBRARIES") + library_combo->insertItem(QString((*tit)->name)); + } + + // Fill the list of available service types + KServiceType::List l = KServiceType::allServiceTypes(); + KServiceType::List::Iterator it; + for (it = l.begin(); it != l.end(); ++it) + if (!(*it)->isType(KST_KMimeType)) + new QListViewItem(availtypes_listview, (*it)->name()); + + setIcon ( SmallIcon ( "servicenew_kdevelop.png" ) ); +} + + +AddServiceDialog::~AddServiceDialog() +{} + + +void AddServiceDialog::updateProperties() +{ + QStringList props; + + QListViewItem *item = static_cast(chosentypes_listview->firstChild()); + while (item) { + KServiceType::Ptr type = KServiceType::serviceType(item->text(0)); + if (type) { + QStringList stprops = type->propertyDefNames(); + QStringList::ConstIterator stit; + for (stit = stprops.begin(); stit != stprops.end(); ++stit) + if (props.find(*stit) == props.end() && (*stit) != "Name" && (*stit) != "Comment" + && (*stit) != "Icon") + props.append(*stit); + } + item = item->nextSibling(); + } + + properties_listview->clear(); + QStringList::ConstIterator it; + for (it = props.begin(); it != props.end(); ++it) + new QListViewItem(properties_listview, *it); +} + + +void AddServiceDialog::iconClicked() +{ + KIconLoader *loader = AutoProjectFactory::instance()->iconLoader(); + QString name = KIconDialog::getIcon(KIcon::Desktop); + if (!name.isNull()) { + iconName = name; + icon_button->setPixmap(loader->loadIcon(name, KIcon::Desktop)); + } +} + + +void AddServiceDialog::addTypeClicked() +{ + QListViewItem *selitem = availtypes_listview->selectedItem(); + if (!selitem) + return; + + QListViewItem *olditem = chosentypes_listview->firstChild(); + while (olditem) { + if (selitem->text(0) == olditem->text(0)) + return; + olditem = olditem->nextSibling(); + } + new QListViewItem(chosentypes_listview, selitem->text(0)); + + updateProperties(); +} + + +void AddServiceDialog::removeTypeClicked() +{ + delete chosentypes_listview->currentItem(); + + updateProperties(); +} + + +void AddServiceDialog::propertyExecuted(QListViewItem *item) +{ + if (!item) + return; + + QString prop = item->text(0); + QString value = item->text(1); + bool ok; + value = KInputDialog::getText(i18n("Enter Value"), i18n("Property %1:").arg(prop), value, &ok, this); + if (!ok) + return; + + item->setText(1, value); +} + + +void AddServiceDialog::accept() +{ + // Create list of service types + QStringList serviceTypes; + QListViewItem *item = chosentypes_listview->firstChild(); + while (item) { + serviceTypes.append(item->text(0)); + item = item->nextSibling(); + } + + // Some plausibility tests + QString fileName = filename_edit->text(); + if (fileName.isEmpty() || fileName == ".desktop") { + KMessageBox::sorry(this, i18n("You have to enter a file name.")); + filename_edit->setFocus(); + return; + } + + QString name = name_edit->text(); + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to enter a service name.")); + name_edit->setFocus(); + return; + } + + QFile f(subProject->path + "/" + fileName); + if (f.exists()) { + KMessageBox::sorry(this, i18n("A file with this name exists already.")); + filename_edit->setFocus(); + return; + } + if (!f.open(IO_WriteOnly)) { + KMessageBox::sorry(this, i18n("Could not open file for writing.")); + return; + } + + QTextStream stream(&f); + stream << "[Desktop Entry]" << endl; + stream << "Type=Service" << endl; + stream << "Name=" << name << endl; + stream << "Comment=" << comment_edit->text() << endl; + if (!iconName.isNull()) + stream << "Icon=" << iconName << endl; + stream << "ServiceTypes=" << serviceTypes.join(",") << endl; + item = properties_listview->firstChild(); + while (item) { + stream << item->text(0) << "=" << item->text(1) << endl; + item = item->nextSibling(); + } + f.close(); + + // Find a prefix that points to the services directory. + // If there is none, use kde_services + QMap::ConstIterator it; + for (it = subProject->prefixes.begin(); it != subProject->prefixes.end(); ++it) + if (it.data() == "$(kde_servicesdir)") + break; + QString prefix = (it == subProject->prefixes.end())? QString("kde_services") : it.key(); + QString varname = prefix + "_DATA"; + + // Look if a list view item for this prefix exists already. + // Create a new one otherwise + TargetItem *titem = 0; + for (uint i=0; i < subProject->targets.count(); ++i) { + TargetItem *tmptitem = subProject->targets.at(i); + if ("DATA" == tmptitem->primary && prefix == tmptitem->prefix) { + titem = tmptitem; + break; + } + } + if (!titem) { + titem = m_widget->createTargetItem("", prefix, "DATA", false); + subProject->targets.append(titem); + } + // Add this file to the target + FileItem *fitem = m_widget->createFileItem(fileName, subProject); + titem->sources.append(fitem); + + subProject->variables[varname] += (" " + fileName); + QMap replaceMap; + replaceMap.insert(varname, subProject->variables[varname]); + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + QDialog::accept(); +} + +#include "addservicedlg.moc" diff --git a/buildtools/autotools/addservicedlg.h b/buildtools/autotools/addservicedlg.h new file mode 100644 index 00000000..c8b694a5 --- /dev/null +++ b/buildtools/autotools/addservicedlg.h @@ -0,0 +1,46 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDSERVICEDLG_H_ +#define _ADDSERVICEDLG_H_ + +#include "addservicedlgbase.h" + +class AutoProjectWidget; +class SubprojectItem; +class TargetItem; + + +class AddServiceDialog : public AddServiceDialogBase +{ + Q_OBJECT + +public: + AddServiceDialog( AutoProjectWidget *widget, SubprojectItem *spitem, + QWidget *parent = 0, const char *name = 0 ); + ~AddServiceDialog(); + +protected: + virtual void iconClicked(); + virtual void addTypeClicked(); + virtual void removeTypeClicked(); + virtual void propertyExecuted( QListViewItem *item ); + virtual void accept(); + +private: + void updateProperties(); + + AutoProjectWidget *m_widget; + SubprojectItem *subProject; + QString iconName; +}; + +#endif diff --git a/buildtools/autotools/addservicedlgbase.ui b/buildtools/autotools/addservicedlgbase.ui new file mode 100644 index 00000000..050f8066 --- /dev/null +++ b/buildtools/autotools/addservicedlgbase.ui @@ -0,0 +1,544 @@ + +AddServiceDialogBase + + + add_service_dialog + + + + 0 + 0 + 602 + 422 + + + + Add New Service + + + false + + + + unnamed + + + + + GroupBox1 + + + &Service File + + + + unnamed + + + + + filename_edit + + + + + + + + icon_label + + + + + + + &Icon: + + + AlignVCenter|AlignRight + + + icon_button + + + + + Layout2 + + + + unnamed + + + 0 + + + + + icon_button + + + + 24 + 24 + + + + + + + false + + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + comment_edit + + + + + name_edit + + + + + library_combo + + + true + + + + + library_label + + + + + + + &Library: + + + AlignVCenter|AlignRight + + + library_combo + + + + + filename_label + + + + + + + &File name: + + + AlignVCenter|AlignRight + + + filename_edit + + + + + name_label + + + + + + + &Name: + + + AlignVCenter|AlignRight + + + name_edit + + + + + comment_label + + + + + + + Co&mment: + + + AlignVCenter|AlignRight + + + comment_edit + + + + + + + GroupBox2 + + + Service &Types + + + + unnamed + + + + + Layout5 + + + + unnamed + + + 0 + + + + + + + + + true + + + true + + + + chosentypes_listview + + + + 7 + 7 + 0 + 0 + + + + LastColumn + + + + + Layout3 + + + + unnamed + + + 0 + + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + add_button + + + <- + + + + + remove_button + + + -> + + + + + Spacer5 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + true + + + true + + + + availtypes_listview + + + + 7 + 7 + 0 + 0 + + + + LastColumn + + + + + + + + Property + + + true + + + true + + + + + Value + + + true + + + true + + + + properties_listview + + + + 7 + 5 + 0 + 0 + + + + true + + + AllColumns + + + + + properties_label + + + + 5 + 5 + 0 + 0 + + + + + + + + &Properties: + + + AlignTop|AlignRight + + + properties_listview + + + + + + + Layout1 + + + + unnamed + + + 0 + + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okbutton + + + &OK + + + true + + + true + + + + + cancelbutton + + + &Cancel + + + true + + + + + + + + + okbutton + clicked() + add_service_dialog + accept() + + + cancelbutton + clicked() + add_service_dialog + reject() + + + remove_button + clicked() + add_service_dialog + removeTypeClicked() + + + properties_listview + doubleClicked(QListViewItem*) + add_service_dialog + propertyExecuted(QListViewItem*) + + + properties_listview + returnPressed(QListViewItem*) + add_service_dialog + propertyExecuted(QListViewItem*) + + + icon_button + clicked() + add_service_dialog + iconClicked() + + + add_button + clicked() + add_service_dialog + addTypeClicked() + + + + filename_edit + library_combo + name_edit + icon_button + comment_edit + chosentypes_listview + add_button + remove_button + availtypes_listview + properties_listview + okbutton + cancelbutton + + + iconClicked() + addTypeClicked() + propertyExecuted(QListViewItem*) + removeTypeClicked() + + + kdialog.h + + + + diff --git a/buildtools/autotools/addsubprojectdlg.cpp b/buildtools/autotools/addsubprojectdlg.cpp new file mode 100644 index 00000000..8011886b --- /dev/null +++ b/buildtools/autotools/addsubprojectdlg.cpp @@ -0,0 +1,198 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addsubprojectdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "autolistviewitems.h" + +#include "kdevmakefrontend.h" +#include "misc.h" +#include "autoprojectpart.h" +#include "autosubprojectview.h" + + +AddSubprojectDialog::AddSubprojectDialog(AutoProjectPart *part, AutoSubprojectView *view, + SubprojectItem *item, QWidget *parent, const char *name) + : AddSubprojectDlgBase(parent, name, true) +{ + setIcon(SmallIcon("folder_new.png")); + + connect( createButton, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancelButton, SIGNAL(clicked()), this, SLOT(reject()) ); + + m_subProject = item; + m_subprojectView = view; + m_part = part; +} + + +AddSubprojectDialog::~AddSubprojectDialog() +{} + + +void AddSubprojectDialog::accept() +{ + QString name = spEdit->text().stripWhiteSpace(); + + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to give the subproject a name.")); + return; + } + + QListViewItem *childItem = m_subProject->firstChild(); + while (childItem) { + if (name == static_cast(childItem)->subdir) { + KMessageBox::sorry(this, i18n("A subproject with this name already exists.")); + return; + } + childItem = childItem->nextSibling(); + } + + +#if 0 + // check for config.status + if( !QFileInfo(m_part->projectDirectory(), "config.status").exists() ){ + KMessageBox::sorry(this, i18n("There is no config.status in the project root directory. Run 'Configure' first")); + QDialog::accept(); + return; + } +#endif + + QDir dir( m_subProject->path ); + QFileInfo file( dir, name ); + + if( file.exists() && !file.isDir() ) { + KMessageBox::sorry(this, i18n("A file named %1 already exists.").arg(name)); + QDialog::accept(); + return; + } else if( file.isDir() ) { + if( KMessageBox::warningContinueCancel(this, + i18n("A subdirectory %1 already exists. " + "Do you wish to add it as a subproject?").arg(name)) + == KMessageBox::Cancel ){ + QDialog::accept(); + return; + } + } else if (!dir.mkdir(name)) { + KMessageBox::sorry(this, i18n("Could not create subdirectory %1.").arg(name)); + QDialog::accept(); + return; + } + + if(!dir.cd(name)) { + KMessageBox::sorry(this, i18n("Could not access the subdirectory %1.").arg(name)); + QDialog::accept(); + return; + } + + // Adjust SUBDIRS variable in containing Makefile.am + if (m_subProject->variables["SUBDIRS"].find("$(TOPSUBDIRS)") != -1) + { + QFile subdirsfile( m_subProject->path + "/subdirs" ); + if ( subdirsfile.open( IO_WriteOnly | IO_Append ) ) + { + QTextStream subdirsstream( &subdirsfile ); + subdirsstream << name << endl; + subdirsfile.close(); + } + } + else if (m_subProject->variables["SUBDIRS"].find("$(AUTODIRS)") != -1) + { + } + else + { + m_subProject->variables["SUBDIRS"] += (" " + name); + QMap replaceMap; + replaceMap.insert("SUBDIRS", m_subProject->variables["SUBDIRS"]); + AutoProjectTool::addToMakefileam(m_subProject->path + "/Makefile.am", replaceMap); + } + + // Create new item in tree view + SubprojectItem *newitem = new SubprojectItem(m_subProject, name); + newitem->subdir = name; + newitem->path = m_subProject->path + "/" + name; + newitem->variables["INCLUDES"] = m_subProject->variables["INCLUDES"]; + newitem->setOpen(true); + + // Move to the bottom of the list + QListViewItem *lastItem = m_subProject->firstChild(); + while (lastItem->nextSibling()) + lastItem = lastItem->nextSibling(); + if (lastItem != newitem) + newitem->moveItem(lastItem); + + // Create a Makefile in the new subdirectory + + QFile f( dir.filePath("Makefile.am") ); + if (f.exists()) { + m_subprojectView->parse( newitem ); + } else { + if (!f.open(IO_WriteOnly)) { + KMessageBox::sorry(this, i18n("Could not create Makefile.am in subdirectory %1.").arg(name)); + return; + } + QTextStream stream(&f); + stream << "INCLUDES = " << newitem->variables["INCLUDES"] << endl << "METASOURCES = AUTO" << endl; + f.close(); + } + + + + // if !isKDE: add the new sub-proj to configure.in + if ( !m_part->isKDE() ) { + QString projroot = m_part->projectDirectory() + "/"; + QString subdirectory = dir.path(); + QString relpath = subdirectory.replace(0, projroot.length(),""); + + QString configureFile = m_part->getAutoConfFile(projroot); + + QStringList list = AutoProjectTool::configureinLoadMakefiles(configureFile); + if ( !list.isEmpty() ) + { + list.push_back( relpath + "/Makefile" ); + AutoProjectTool::configureinSaveMakefiles(configureFile, list); + } + } + +#if 0 + QString relmakefile = (m_subProject->path + "/" + name + "/Makefile").mid(m_part->projectDirectory().length()+1); + kdDebug(9020) << "Relative makefile path: " << relmakefile << endl; + + QString cmdline = "cd "; + cmdline += KProcess::quote(m_part->projectDirectory()); + cmdline += " && automake "; + cmdline += KProcess::quote(relmakefile); + cmdline += " && CONFIG_HEADERS=config.h CONFIG_FILES="; + cmdline += KProcess::quote(relmakefile); + cmdline += " ./config.status"; + + m_part->makeFrontend()->queueCommand( m_part->projectDirectory(), cmdline ); + m_part->makeFrontend()->queueCommand( m_part->projectDirectory(), m_part->configureCommand() ); +#endif + + m_part->needMakefileCvs(); + + QDialog::accept(); +} + +#include "addsubprojectdlg.moc" diff --git a/buildtools/autotools/addsubprojectdlg.h b/buildtools/autotools/addsubprojectdlg.h new file mode 100644 index 00000000..eabfc0e1 --- /dev/null +++ b/buildtools/autotools/addsubprojectdlg.h @@ -0,0 +1,44 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDSUBPROJECTDLG_H_ +#define _ADDSUBPROJECTDLG_H_ + +#include +#include + +#include "addsubprojectdlgbase.h" + +class AutoProjectPart; +class AutoSubprojectView; +class SubprojectItem; + + +class AddSubprojectDialog : public AddSubprojectDlgBase +{ + Q_OBJECT + +public: + AddSubprojectDialog( AutoProjectPart *part, AutoSubprojectView *widget, + SubprojectItem *item, QWidget *parent = 0, const char *name = 0 ); + ~AddSubprojectDialog(); + +private: + virtual void accept(); + + KLineEdit *name_edit; + + SubprojectItem *m_subProject; + AutoSubprojectView *m_subprojectView; + AutoProjectPart *m_part; +}; + +#endif diff --git a/buildtools/autotools/addsubprojectdlgbase.ui b/buildtools/autotools/addsubprojectdlgbase.ui new file mode 100644 index 00000000..b4c762b1 --- /dev/null +++ b/buildtools/autotools/addsubprojectdlgbase.ui @@ -0,0 +1,198 @@ + +AddSubprojectDlgBase + + + AddSubprojectDlgBase + + + + 0 + 0 + 445 + 126 + + + + + 5 + 5 + 0 + 0 + + + + + 32767 + 32767 + + + + + 0 + 0 + + + + Add New Subproject + + + + unnamed + + + + fileGroupBox + + + Subproject + + + + unnamed + + + + Layout3 + + + + unnamed + + + 0 + + + + spStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + 0 + 0 + + + + + + + + Subproject &name: + + + spEdit + + + + + spEdit + + + + 5 + 5 + 0 + 0 + + + + + 0 + 0 + + + + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + buttonLayout + + + + unnamed + + + 0 + + + + buttonSpacer + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + createButton + + + &OK + + + true + + + + + cancelButton + + + &Cancel + + + + + + + + spEdit + createButton + cancelButton + + + klineedit.h + kdialog.h + + + + + klineedit.h + + diff --git a/buildtools/autotools/addtargetdlg.cpp b/buildtools/autotools/addtargetdlg.cpp new file mode 100644 index 00000000..b01b5b82 --- /dev/null +++ b/buildtools/autotools/addtargetdlg.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addtargetdlg.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autodetailsview.h" +#include "autoprojectwidget.h" + + +AddTargetDialog::AddTargetDialog(AutoProjectWidget *widget, SubprojectItem *item, + QWidget *parent, const char *name) + : AddTargetDialogBase(parent, name, true) +{ + m_subproject = item; + m_widget = widget; +// m_detailsView = view; + + primary_combo->setFocus(); + primary_combo->insertItem(i18n("Program")); + primary_combo->insertItem(i18n("Library")); + primary_combo->insertItem(i18n("Libtool Library")); + primary_combo->insertItem(i18n("Script")); + primary_combo->insertItem(i18n("Header")); + primary_combo->insertItem(i18n("Data File")); + primary_combo->insertItem(i18n("Java")); + + primaryChanged(); // updates prefix combo + + if (widget->kdeMode()) + ldflagsother_edit->setText("$(all_libraries)"); + + connect( filename_edit, SIGNAL( textChanged(const QString&) ), this, SLOT( slotFileNameChanged (const QString&) ) ); + + setIcon ( SmallIcon ( "targetnew_kdevelop.png" ) ); + + canonicalLabel->setText ( QString::null ); +} + + +AddTargetDialog::~AddTargetDialog() +{} + + +void AddTargetDialog::primaryChanged() +{ + QStringList list; + switch (primary_combo->currentItem()) { + case 0: // Program + list.append("bin"); + list.append("sbin"); + list.append("libexec"); + list.append("pkglib"); + list.append("noinst"); + break; + case 1: // Library + case 2: // Libtool library + list.append("lib"); + list.append("pkglib"); + list.append("noinst"); + if (m_widget->kdeMode()) + list.append("kde_module"); + break; + case 3: // Script + list.append("bin"); + list.append("sbin"); + list.append("libexec"); + list.append("pkgdata"); + list.append("noinst"); + break; + case 4: // Header + list.append("include"); + list.append("oldinclude"); + list.append("pkginclude"); + list.append("noinst"); + break; + case 5: // Data + list.append("bin"); + list.append("sbin"); + list.append("noinst"); + break; + case 6: // Java + list.append("java"); + list.append("noinst"); + break; + } + + prefix_combo->clear(); + + prefix_combo->insertStringList(list); + QStringList prefixes; + QMap::ConstIterator it; + for (it = m_subproject->prefixes.begin(); it != m_subproject->prefixes.end(); ++it) + prefix_combo->insertItem(it.key()); + + // Only enable ldflags stuff for libtool libraries + bool lt = primary_combo->currentItem() == 2; + bool prog = primary_combo->currentItem() == 0; + allstatic_box->setEnabled(lt); + avoidversion_box->setEnabled(lt); + module_box->setEnabled(lt); + noundefined_box->setEnabled(lt); + ldflagsother_edit->setEnabled(lt || prog); +} + + +void AddTargetDialog::accept() +{ + QString name = filename_edit->text().stripWhiteSpace(); + QString prefix = prefix_combo->currentText(); + + QString primary; + switch (primary_combo->currentItem()) { + case 0: primary = "PROGRAMS"; break; + case 1: primary = "LIBRARIES"; break; + case 2: primary = "LTLIBRARIES"; break; + case 3: primary = "SCRIPTS"; break; + case 4: primary = "HEADERS"; break; + case 5: primary = "DATA"; break; + case 6: primary = "JAVA"; break; + default: ; + } + + if (name.isEmpty()) { + KMessageBox::sorry(this, i18n("You have to give the target a name")); + return; + } + +#if 0 + if (primary == "LIBRARIES" && !name.startsWith("lib")) { + KMessageBox::sorry(this, i18n("Libraries must have a lib prefix.")); + return; + } + + if (primary == "LTLIBRARIES" && !name.startsWith("lib")) { + KMessageBox::sorry(this, i18n("Libtool libraries must have a lib prefix.")); + return; + } + + if (primary == "LTLIBRARIES" && name.right(3) != ".la") { + KMessageBox::sorry(this, i18n("Libtool libraries must have a .la suffix.")); + return; + } + +#endif + + if( primary.endsWith("LIBRARIES") && !name.startsWith("lib") && !module_box->isChecked() ) + name.prepend( QString::fromLatin1("lib") ); + + if( primary == "LTLIBRARIES" && !name.endsWith(".la") ) + name.append( QString::fromLatin1(".la") ); + + if ( primary == "LIBRARIES" && !name.endsWith(".a") ) + name.append ( QString::fromLatin1(".a") ); + + QPtrListIterator it(m_subproject->targets); + for (; it.current(); ++it) + if (name == (*it)->name) { + KMessageBox::sorry(this, i18n("A target with this name already exists.")); + return; + } + + QStringList flagslist; + if (primary == "LTLIBRARIES") { + if (allstatic_box->isChecked()) + flagslist.append("-all-static"); + if (avoidversion_box->isChecked()) + flagslist.append("-avoid-version"); + if (module_box->isChecked()) + flagslist.append("-module"); + if (noundefined_box->isChecked()) + flagslist.append("-no-undefined"); + } + flagslist.append(ldflagsother_edit->text()); + QString ldflags = flagslist.join( " " ); + + TargetItem *titem = m_widget->createTargetItem(name, prefix, primary, false); + // m_detailsView->insertItem ( titem ); + m_subproject->targets.append(titem); + + QString canonname = AutoProjectTool::canonicalize(name); + + QMap replaceMap; + + if( primary == "PROGRAMS" || primary == "LIBRARIES" || primary == "LTLIBRARIES" || primary == "DATA" ){ + QString varname = prefix + "_" + primary; + m_subproject->variables[varname] += (" " + name); + replaceMap.insert(varname, m_subproject->variables[varname]); + if ( primary != "DATA" ){ + replaceMap.insert(canonname + "_SOURCES", ""); + } + } + if (primary == "LTLIBRARIES" || primary == "PROGRAMS") + replaceMap.insert(canonname + "_LDFLAGS", ldflags); + + AutoProjectTool::addToMakefileam(m_subproject->path + "/Makefile.am", replaceMap); + + QDialog::accept(); +} + +void AddTargetDialog::slotFileNameChanged ( const QString& text ) +{ + canonicalLabel->setText ( AutoProjectTool::canonicalize ( text ) ); +} + +#include "addtargetdlg.moc" diff --git a/buildtools/autotools/addtargetdlg.h b/buildtools/autotools/addtargetdlg.h new file mode 100644 index 00000000..98708531 --- /dev/null +++ b/buildtools/autotools/addtargetdlg.h @@ -0,0 +1,43 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDTARGETDLG_H_ +#define _ADDTARGETDLG_H_ + +#include "addtargetdlgbase.h" + +class AutoDetailsView; +class AutoProjectWidget; +class SubprojectItem; + + +class AddTargetDialog : public AddTargetDialogBase +{ + Q_OBJECT + +public: + AddTargetDialog( AutoProjectWidget *widget, SubprojectItem *item, + QWidget *parent = 0, const char *name = 0 ); + ~AddTargetDialog(); + +protected slots: + virtual void slotFileNameChanged ( const QString& ); + +private: + virtual void primaryChanged(); + virtual void accept(); + + SubprojectItem *m_subproject; + AutoProjectWidget *m_widget; + AutoDetailsView* m_detailsView; +}; + +#endif diff --git a/buildtools/autotools/addtargetdlgbase.ui b/buildtools/autotools/addtargetdlgbase.ui new file mode 100644 index 00000000..25687563 --- /dev/null +++ b/buildtools/autotools/addtargetdlgbase.ui @@ -0,0 +1,348 @@ + +AddTargetDialogBase + + + add_target_dialog + + + + 0 + 0 + 585 + 356 + + + + Add New Target + + + false + + + + unnamed + + + + groupBox2 + + + &Target + + + + unnamed + + + + primary_label + + + + + + + &Primary: + + + AlignVCenter|AlignRight + + + primary_combo + + + + + primary_combo + + + + + prefix_label + + + + + + + Pre&fix: + + + AlignVCenter|AlignRight + + + prefix_combo + + + + + prefix_combo + + + + + filename_label + + + + + + + File &name: + + + AlignVCenter|AlignRight + + + filename_edit + + + + + filename_edit + + + + + Spacer21 + + + Horizontal + + + Expanding + + + + 246 + 20 + + + + + + canonicalLabel + + + [CANONICALIZED NAME] + + + + + textLabel1 + + + + 1 + + + + + + + image0 + + + + + + + Spacer22 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + ldflags_group + + + Linker Flags (&LDFLAGS) + + + + unnamed + + + + allstatic_box + + + Do not link against shared libraries (-all-static) + + + + + avoidversion_box + + + Do not assign version numbers to libraries (-avoid-version) + + + + + module_box + + + Create a library that can be dynamically loaded (-module) + + + + + noundefined_box + + + Library does not depend on external symbols (-no-undefined) + + + + + Layout11_2 + + + + unnamed + + + 0 + + + + ldflagsother_label + + + + + + + Ot&her: + + + ldflagsother_edit + + + + + ldflagsother_edit + + + + + + + + + Layout1 + + + + unnamed + + + 0 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okbutton + + + &OK + + + true + + + true + + + + + cancelbutton + + + &Cancel + + + true + + + + + + + + + 789cd3d7528808f055d0d2e72a2e492cc94c5648ce482c52d04a29cdcdad8c8eb5ade6523234530022230543251d2e253d856405bffcbc54105b19c856360003b0141ac02ba68c4d4c199b98323631656c62cad8c494891423ce0ee2dc4c6418208bd55a7301009c7f45ef + + + + + okbutton + clicked() + add_target_dialog + accept() + + + cancelbutton + clicked() + add_target_dialog + reject() + + + primary_combo + activated(int) + add_target_dialog + primaryChanged() + + + + primary_combo + prefix_combo + filename_edit + allstatic_box + avoidversion_box + module_box + noundefined_box + ldflagsother_edit + okbutton + cancelbutton + + + kdialog.h + + + primaryChanged() + + + + + ksqueezedtextlabel.h + + diff --git a/buildtools/autotools/addtranslationdlg.cpp b/buildtools/autotools/addtranslationdlg.cpp new file mode 100644 index 00000000..993dee7d --- /dev/null +++ b/buildtools/autotools/addtranslationdlg.cpp @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "addtranslationdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "misc.h" +#include "autoprojectpart.h" + + +AddTranslationDialog::AddTranslationDialog(AutoProjectPart *part, QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("Add Translation")); + + m_part = part; + + QHBox *hbox = new QHBox(this); + (void) new QLabel(i18n("Language:"), hbox); + lang_combo = new QComboBox(hbox); + + QVBoxLayout *layout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + layout->addWidget(hbox); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + layout->addWidget(frame, 0); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + QPushButton *ok_button = buttonbox->addButton(KStdGuiItem::ok()); + QPushButton *cancel_button = buttonbox->addButton(KStdGuiItem::cancel()); + ok_button->setDefault(true); + connect( ok_button, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel_button, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + layout->addWidget(buttonbox, 0); + + QStringList rawlist, list; + rawlist << "af" << "ar" << "bg" << "bo" << "br" << "bs" << "ca" << "cs" << "cy" << "da" + << "de" << "el" << "en_GB" << "eo" << "es" << "et" << "eu" << "fi" << "fr"; + rawlist << "ga" << "gl" << "gu" << "he" << "hi" << "hu" << "id" << "is" << "it" << "ja" + << "km" << "ko" << "lt" << "lv" << "mi" << "mk" << "mr" << "nl" << "no" << "no_NY"; + rawlist << "oc" << "pl" << "pt" << "pt_BR" << "ro" << "ru" << "sk" << "sl" << "sr" << "sv" + << "ta" << "th" << "tr" << "uk" << "wa" << "zh_CN.GB2312" << "zh_TW.Big5"; + + // Remove already added languages + QStringList::ConstIterator it; + for (it = rawlist.begin(); it != rawlist.end(); ++it) { + QFileInfo fi(m_part->projectDirectory() + "/po/" + (*it) + ".po"); + if (!fi.exists()) + list.append(*it); + } + + if (list.isEmpty()) { + KMessageBox::information(this, i18n("Your sourcecode is already translated to all supported languages.")); + ok_button->setEnabled(false); + } + lang_combo->insertStringList(list); +} + + +AddTranslationDialog::~AddTranslationDialog() +{} + + +void AddTranslationDialog::accept() +{ + QString dir = m_part->projectDirectory() + "/po"; + QString fileName = dir + "/" + lang_combo->currentText() + ".po"; + + QFile f(fileName); + if (f.exists()) { + KMessageBox::information(this, i18n("A translation file for the language %1 exists already.")); + return; + } + f.open(IO_WriteOnly); + f.close(); + + dir = m_part->buildDirectory() + "/po"; + m_part->startMakeCommand(dir, QString::fromLatin1("force-reedit")); + + QDialog::accept(); +} + +#include "addtranslationdlg.moc" diff --git a/buildtools/autotools/addtranslationdlg.h b/buildtools/autotools/addtranslationdlg.h new file mode 100644 index 00000000..cd14ddf2 --- /dev/null +++ b/buildtools/autotools/addtranslationdlg.h @@ -0,0 +1,36 @@ +/*************************************************************************** +* Copyright (C) 1999 by Sandy Meier * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _ADDTRANSLATIONDLG_H_ +#define _ADDTRANSLATIONDLG_H_ + +#include + +class QComboBox; +class AutoProjectPart; + + +class AddTranslationDialog : public QDialog +{ + Q_OBJECT + +public: + AddTranslationDialog( AutoProjectPart *part, QWidget *parent = 0, const char *name = 0 ); + ~AddTranslationDialog(); + +private: + virtual void accept(); + + QComboBox *lang_combo; + AutoProjectPart *m_part; +}; + +#endif diff --git a/buildtools/autotools/autodetailsview.cpp b/buildtools/autotools/autodetailsview.cpp new file mode 100644 index 00000000..26255fd3 --- /dev/null +++ b/buildtools/autotools/autodetailsview.cpp @@ -0,0 +1,728 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder + Copyright (c) 2005 by Matt Rogers + + *************************************************************************** + * * + * 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 "autodetailsview.h" + +/** Qt */ +#include +#include +#include +#include +#include + + /** KDE Libs */ +#include +#include +#include +#include +#include +#include +#include + +/** KDevelop */ +#include "kdevappfrontend.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevpartcontroller.h" +#include "kdevcreatefile.h" +#include "kdevlanguagesupport.h" +#include "kdevmakefrontend.h" +#include "urlutil.h" + +#include "domutil.h" + +#include "targetoptionsdlg.h" +#include "addfiledlg.h" +#include "addicondlg.h" +#include "addexistingfilesdlg.h" +#include "removefiledlg.h" +#include "removetargetdlg.h" + +#include "autolistviewitems.h" +#include "autotoolsaction.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + +#include "subclassesdlg.h" + +AutoDetailsView::AutoDetailsView(AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name) + : AutoProjectViewBase(parent, name) +{ + m_widget = widget; + m_part = part; + + initActions(); + QDomDocument dom = *(m_part->projectDom()); + m_subclasslist = DomUtil::readPairListEntry(dom, "/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + + m_listView->setAllColumnsShowFocus( true ); + m_listView->setRootIsDecorated( true ); + m_listView->setResizeMode( QListView::LastColumn ); + m_listView->addColumn( QString::null ); + m_listView->header()->hide(); + targetOptionsAction->setEnabled( false ); + addNewFileAction->setEnabled( false ); + addExistingFileAction->setEnabled( false ); + buildTargetAction->setEnabled( false ); + executeTargetAction->setEnabled( false ); + removeDetailAction->setEnabled(false); + connect( m_listView, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotSelectionChanged( QListViewItem* ) ) ); + connect( m_listView, SIGNAL( selectionChanged() ), + this, SLOT( slotSelectionChanged( ) ) ); +} + + +AutoDetailsView::~AutoDetailsView() +{ +} + +/** + * If nothing selected, disable all the icons. + */ +void AutoDetailsView::slotSelectionChanged( ){ + + if ( m_listView->selectedItems().isEmpty()){ + targetOptionsAction->setEnabled( false ); + addNewFileAction->setEnabled( false ); + addExistingFileAction->setEnabled( false ); + buildTargetAction->setEnabled( false ); + executeTargetAction->setEnabled( false ); + removeDetailAction->setEnabled(false); + } +} + +/** + * Change the enabled icons depending on what is selected. + * This is never called if nothing is selected.. + * @param item + */ +void AutoDetailsView::slotSelectionChanged( QListViewItem* item ) +{ + bool isTarget = false; + bool isRegularTarget = false; + bool isFile = false; + bool isProgram = false; + + if ( item ) + { + // We assume here that ALL items in the detail list view + // are ProjectItem's + ProjectItem * pvitem = static_cast( item ); + TargetItem* titem = 0; + + if ( pvitem->type() == ProjectItem::File ) + { + titem = static_cast ( pvitem->parent() ); + + QString primary = titem->primary; + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || + primary == "LTLIBRARIES" || primary == "JAVA" ) + { + isRegularTarget = true; // not a data group + isFile = true; + } + } + else + { + titem = static_cast ( pvitem ); + isTarget = true; + } + + QString primary = titem->primary; + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || + primary == "LTLIBRARIES" || primary == "JAVA" ) + { + isRegularTarget = true; // not a data group + } + + if ( primary == "PROGRAMS" ) + isProgram = true; + } + + targetOptionsAction->setEnabled( isRegularTarget && !isFile ); + addNewFileAction->setEnabled( isTarget ); + addExistingFileAction->setEnabled( isTarget ); + removeDetailAction->setEnabled ( true ); + + if ( isRegularTarget && isFile || isRegularTarget ) + { + buildTargetAction->setEnabled ( true ); + if( isProgram ) + executeTargetAction->setEnabled ( true ); + } + else + { + buildTargetAction->setEnabled ( false ); + executeTargetAction->setEnabled ( false ); + } + emit selectionChanged( item ); +} + +void AutoDetailsView::initActions() +{ + KActionCollection * actions = new KActionCollection( this ); + + targetOptionsAction = new AutoToolsAction( i18n( "Options..." ), "configure", 0, + this, SLOT( slotTargetOptions() ), actions, + "target options" ); + targetOptionsAction->setWhatsThis(i18n("Options

Target options dialog that " + "provides settings for linker flags and lists " + "of dependencies and external libraries that " + "are used when compiling the target.")); + targetOptionsAction->plug( m_optionsButton ); + targetOptionsAction->setEnabled( false ); + + QToolTip::add( m_button1, tr2i18n( "Create New File..." ) ); + addNewFileAction = new AutoToolsAction( i18n( "Create New File..." ), "filenew", 0, + this, SLOT( slotAddNewFile() ), actions, + "add new file" ); + addNewFileAction->setWhatsThis(i18n("Create new file

Creates a new file and " + "adds it to a currently selected target.")); + addNewFileAction->plug( m_button1 ); + addNewFileAction->setEnabled( false ); + + QToolTip::add( m_button2, tr2i18n( "Add Existing Files..." ) ); + addExistingFileAction = new AutoToolsAction( i18n( "Add Existing Files..." ), "fileimport", 0, + this, SLOT( slotAddExistingFile() ), actions, + "add existing file" ); + addExistingFileAction->setWhatsThis(i18n("Add existing files

Adds existing " + "file to a currently selected target. Header " + "files will not be included in SOURCES list " + "of a target. They will be added to " + "noinst_HEADERS instead.")); + addExistingFileAction->plug( m_button2 ); + addExistingFileAction->setEnabled( false ); + + addIconAction = new KAction( i18n( "Add Icon..." ), "iconadd_kdevelop", 0, + this, SLOT( slotAddIcon() ), actions, "add icon" ); + addIconAction->setWhatsThis(i18n("Add icon

Adds an icon to a KDEICON target.")); + + QToolTip::add( m_button4, tr2i18n( "Build Target")); + buildTargetAction = new AutoToolsAction( i18n( "Build Target..." ), "launch", 0, + this, SLOT( slotBuildTarget() ), actions, + "build target" ); + buildTargetAction->setWhatsThis(i18n("Build target

Constructs a series of " + "make commands to build the selected target. " + "Also builds dependent targets.")); + buildTargetAction->plug( m_button4 ); + buildTargetAction->setEnabled( false ); + + QToolTip::add( m_button5, tr2i18n( "Execute Target...")); + executeTargetAction = new AutoToolsAction( i18n( "Execute Target..." ), "exec", 0, + this, SLOT( slotExecuteTarget() ), actions, + "execute target" ); + executeTargetAction->setWhatsThis(i18n("Execute target

Executes the target " + "and tries to build in case it is not built.")); + executeTargetAction->plug( m_button5 ); + executeTargetAction->setEnabled( false ); + + setActiveTargetAction = new KAction( i18n( "Make Target Active" ), "", 0, + this, SLOT( slotSetActiveTarget() ), actions, + "set active target" ); + setActiveTargetAction->setWhatsThis(i18n("Make target active

Marks the " + "currently selected target as 'active'. New " + "files and classes by default go to an active " + "target. " + "Using the Build Active Target menu " + "command builds it.")); + + QToolTip::add( m_button3, tr2i18n( "Remove")); + removeDetailAction = new AutoToolsAction( i18n( "Remove" ), "editdelete", 0, this, + SLOT( slotRemoveDetail() ), actions, + "remove detail" ); + removeDetailAction->setWhatsThis(i18n("Remove

Shows a list of targets " + "dependent on the selected target or file and " + "asks for removal. Also asks if the target or " + "file should be removed from disk.")); + removeDetailAction->plug( m_button3 ); + removeDetailAction->setEnabled( false ); + + connect( m_listView, SIGNAL( executed( QListViewItem* ) ), + this, SLOT( slotDetailsExecuted( QListViewItem* ) ) ); + connect( m_listView, SIGNAL( returnPressed( QListViewItem* ) ), + this, SLOT( slotDetailsExecuted( QListViewItem* ) ) ); + connect( m_listView, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotDetailsContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); +} + +QString AutoDetailsView::getUiFileLink(const QString& relpath, const QString& filename) +{ + DomUtil::PairList::iterator it; + + for (it=m_subclasslist.begin(); it != m_subclasslist.end(); ++it) + { + if ((*it).first == QString("/")+relpath+filename) + return (*it).second; + } + + return QString::null; +} + +void AutoDetailsView::slotTargetOptions() +{ + kdDebug( 9020 ) << "AutoDetailsView::slotTargetOptions()" << endl; + TargetItem *titem = dynamic_cast ( m_listView->selectedItem() ); + + if ( !titem ) + return; + + TargetOptionsDialog dlg( m_widget, titem, this, "target options dialog" ); + + dlg.setCaption ( i18n ( "Target Options for '%1'" ).arg ( titem->name ) ); + + dlg.exec(); +} + + +void AutoDetailsView::slotAddNewFile() +{ + TargetItem * titem = dynamic_cast ( m_listView->selectedItem() ); + if ( !titem ) + return; + + KDevCreateFile * createFileSupport = m_part->extension("KDevelop/CreateFile"); + if (createFileSupport) + { + KDevCreateFile::CreatedFile crFile = + createFileSupport->createNewFile(QString::null, + m_widget->selectedSubproject()->path); +/* if (crFile.status == KDevCreateFile::CreatedFile::STATUS_OK) + { + FileItem *fitem = m_widget->createFileItem(crFile.filename, m_widget->selectedSubproject()); + titem->sources.append(fitem); + titem->insertItem(fitem); + emit selectionChanged( titem ); // update list view + }*/ + } else { + AddFileDialog dlg( m_part, m_widget, m_widget->selectedSubproject(), titem, + this, "add file dialog" ); + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + dlg.setCaption ( i18n ( "Add New File to '%1'" ).arg ( caption ) ); + + if ( dlg.exec() ) + emit selectionChanged( titem ); // update list view + } +} + + +void AutoDetailsView::slotAddExistingFile() +{ + TargetItem * titem = dynamic_cast ( m_listView->selectedItem() ); + if ( !titem ) + return; + + AddExistingFilesDialog dlg( m_part, m_widget, m_widget->selectedSubproject(), titem, + this, "add existing files" ); + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + dlg.setCaption( i18n( "Add Existing Files to '%1'" ).arg ( caption ) ); + + dlg.exec(); +} + + +void AutoDetailsView::slotAddIcon() +{ + TargetItem * titem = dynamic_cast ( m_listView->selectedItem() ); + if ( !titem ) + return ; + + AddIconDialog dlg( m_part, m_widget, m_widget->selectedSubproject(), titem, + this, "add icon" ); + dlg.exec(); +} + + +void AutoDetailsView::slotBuildTarget() +{ + ProjectItem * pvitem = dynamic_cast( m_listView->selectedItem() ); + if ( !pvitem ) + return; + + TargetItem* titem = 0; + + if ( pvitem->type() == ProjectItem::File ) + titem = static_cast ( pvitem->parent() ); + else + titem = static_cast ( m_listView->selectedItem() ); + + QString relpath = URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + m_widget->selectedSubproject()->relativePath(); + + m_part->buildTarget(relpath, titem); +} + +void AutoDetailsView::slotExecuteTarget() +{ + ProjectItem * pvitem = dynamic_cast( m_listView->selectedItem() ); + if ( !pvitem ) + return; + + TargetItem* titem = 0; + + if ( pvitem->type() == ProjectItem::File ) + titem = static_cast ( pvitem->parent() ); + else + titem = static_cast ( m_listView->selectedItem() ); + + QString relpath = URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + m_part->activeDirectory(); + m_part->executeTarget(QDir( DomUtil::readEntry( *m_part->projectDom(), "/kdevautoproject/run/cwd/"+titem->name )), titem); +} + +void AutoDetailsView::slotRemoveDetail() +{ + ProjectItem * pvitem = dynamic_cast( m_listView->selectedItem() ); + + if ( pvitem && ( pvitem->type() == ProjectItem::File ) ) + { + FileItem * fitem = static_cast ( m_listView->selectedItem() ); + if(fitem && fitem->is_subst) + { + fitem->changeMakefileEntry(""); + return; + } + + QListViewItem* sibling = fitem->nextSibling(); + + if ( !fitem ) + return; + + TargetItem *titem = static_cast( fitem->parent() ); + + RemoveFileDialog dlg( m_widget, m_part, m_widget->selectedSubproject(), + titem, fitem->text( 0 ), this, "remove file dialog" ); + + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + dlg.setCaption ( i18n ( "Remove File From '%1'" ).arg ( caption ) ); + + if ( dlg.exec() ) + { + emit selectionChanged( titem ); + + if ( sibling) + { + m_listView->setSelected ( sibling, true ); + m_listView->ensureItemVisible ( sibling ); + } + } + + return; + } + + if ( pvitem && ( pvitem->type() == ProjectItem::Target ) ) + { + TargetItem* titem = static_cast ( m_listView->selectedItem() ); + QListViewItem* sibling = titem->nextSibling(); + + if ( !titem ) return; + + bool isactive = ( titem == m_widget->activeTarget() ); + RemoveTargetDialog dlg ( m_widget, m_part, m_widget->selectedSubproject(), + titem, this, "remove target dialog" ); + + dlg.setCaption ( i18n ( "Remove Target From '%1'" ).arg ( m_widget->selectedSubproject()->subdir ) ); + + if ( dlg.exec() ) + { + //details->takeItem ( titem ); + + m_widget->slotOverviewSelectionChanged ( m_widget->selectedSubproject() ); + + if( isactive ) + m_widget->setActiveTarget(""); + if ( sibling) + { + m_listView->setSelected ( sibling, true ); + m_listView->ensureItemVisible ( sibling ); + } + } + + return; + } +} + + +void AutoDetailsView::slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return; + + ProjectItem *pvitem = dynamic_cast( item ); + if ( !pvitem ) + { + kdDebug(9020) << k_funcinfo << "Cast to type of ProjectItem* failed." + << "Details context menu will be empty!"; + return; + } + + if ( pvitem->type() == ProjectItem::Target ) + { + + TargetItem * titem = dynamic_cast( pvitem ); + if ( !titem ) + { + kdDebug(9020) << k_funcinfo << "Unable to populate target item menu" + << " due to failed cast. " << endl; + return; + } + + QString caption; + if ( titem->name.isEmpty() ) + caption = i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ); + else + caption = titem->name; + + KPopupMenu popup( i18n( "Target: %1" ).arg( caption ), this ); + + if ( titem->primary == "PROGRAMS" || titem->primary == "LIBRARIES" + || titem->primary == "LTLIBRARIES" || titem->primary == "JAVA" ) + { + targetOptionsAction->plug( &popup ); + popup.insertSeparator(); + addNewFileAction->plug( &popup ); + addExistingFileAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + popup.insertSeparator(); + setActiveTargetAction->plug( &popup ); + popup.insertSeparator(); + buildTargetAction->plug( &popup ); + if( titem->primary == "PROGRAMS") + executeTargetAction->plug( &popup ); + } + else if ( titem->primary == "KDEDOCS" ) + { + addNewFileAction->plug( &popup ); + addExistingFileAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + popup.insertSeparator(); + buildTargetAction->plug( &popup ); + } + else if ( titem->primary == "KDEICON" ) + { + addIconAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + } + else + { + addNewFileAction->plug( &popup ); + addExistingFileAction->plug( &popup ); + popup.insertSeparator(); + removeDetailAction->plug( &popup ); + } + + popup.exec( p ); + + } + else if ( pvitem->type() == ProjectItem::File ) + { + + FileItem * fitem = dynamic_cast( pvitem ); + if ( !fitem ) + { + kdDebug(9020) << k_funcinfo << "Unable to populate file item menu" + << " due to failed cast. " << endl; + return; + } + + KPopupMenu popup( i18n( "File: %1" ).arg( fitem->name ), this ); + + removeDetailAction->plug( &popup ); + KURL::List urls; + urls.append(m_widget->selectedSubproject()->path + "/" + fitem->name); + FileContext context(urls); + + int idSubclassWidget = popup.insertItem(SmallIconSet("qmake_subclass"), + i18n("Subclassing Wizard...") ); + popup.setWhatsThis(idSubclassWidget, i18n("Subclass widget

Launches " + "Subclassing wizard. " + "It allows to create a subclass from the " + "class defined in .ui file. " + "There is also possibility to implement " + "slots and functions defined in the base " + "class.")); + int idUISubclasses = popup.insertItem(SmallIconSet("qmake_subclass"), + i18n("List of Subclasses...")); + popup.setWhatsThis(idUISubclasses, i18n("List of subclasses

Shows " + "subclasses list editor. " + "There is possibility to add or remove " + "subclasses from the list.")); + int idUpdateWidgetclass = popup.insertItem(SmallIconSet("qmake_subclass"), + i18n("Edit ui-Subclass...")); + popup.setWhatsThis(idUpdateWidgetclass, i18n("Edit ui-subclass

Launches " + "Subclassing wizard and prompts " + "to implement missing in childclass " + "slots and functions.")); + int idViewUIH = popup.insertItem(SmallIconSet("qmake_ui_h"), + i18n("Open ui.h File")); + popup.setWhatsThis(idViewUIH, i18n("Open ui.h file

Opens .ui.h file " + "associated with the selected .ui.")); + + if (!fitem->name.contains(QRegExp("ui$")) || fitem->is_subst == true) + { + popup.removeItem(idUISubclasses); + popup.removeItem(idViewUIH); + popup.removeItem(idSubclassWidget); + } + + if (fitem->uiFileLink.isEmpty()) + popup.removeItem(idUpdateWidgetclass); + + if(fitem->is_subst == false) + m_part->core()->fillContextMenu( &popup, &context ); + + int r = popup.exec( p ); + + if(r == idViewUIH) + { + m_part->partController()->editDocument(KURL(m_widget->selectedSubproject()->path + + "/" + QString(fitem->name + ".h"))); + } + else if (r == idSubclassWidget) + { + QStringList newFileNames; + newFileNames = m_part->languageSupport()->subclassWidget(m_widget->selectedSubproject()->path + "/" + fitem->name); + if (!newFileNames.empty()) + { + QDomDocument &dom = *(m_part->projectDom()); + for (uint i=0; iprojectDirectory().length()); + QString uifile_relpath = QString(m_widget->selectedSubproject()->path + "/" + fitem->name).remove(0,m_part->projectDirectory().length()); + DomUtil::PairList list = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + + list << DomUtil::Pair(srcfile_relpath,uifile_relpath); + DomUtil::writePairListEntry(dom, "/kdevautoproject/subclassing", + "subclass", "sourcefile", "uifile", list); + newFileNames[i] = newFileNames[i].replace(QRegExp(m_part->projectDirectory()+"/"),""); + } + m_subclasslist = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + m_part->addFiles(newFileNames); + } + } + else if (r == idUpdateWidgetclass) + { + QString noext = m_widget->selectedSubproject()->path + "/" + fitem->name; + + if (noext.findRev('.')>-1) + noext = noext.left(noext.findRev('.')); + + QStringList dummy; + QString uifile = fitem->uiFileLink; + + if (uifile.findRev('/')>-1) + { + QStringList uisplit = QStringList::split('/',uifile); + uifile=uisplit[uisplit.count()-1]; + } + + m_part->languageSupport()->updateWidget(m_widget->selectedSubproject()->path + + "/" + uifile, noext); + } + else if (r == idUISubclasses) + { + QDomDocument &dom = *(m_part->projectDom()); + DomUtil::PairList list = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + SubclassesDlg *sbdlg = new SubclassesDlg( QString(m_widget->selectedSubproject()->path + "/" +fitem->name).remove(0,m_part->projectDirectory().length()), + list, m_part->projectDirectory()); + + if (sbdlg->exec()) + { + QDomElement el = DomUtil::elementByPath( dom, "/kdevautoproject"); + QDomElement el2 = DomUtil::elementByPath( dom, "/kdevautoproject/subclassing"); + if ( (!el.isNull()) && (!el2.isNull()) ) + { + el.removeChild(el2); + } + + DomUtil::writePairListEntry(dom, "/kdevautoproject/subclassing", "subclass", + "sourcefile", "uifile", list); + + m_subclasslist = DomUtil::readPairListEntry(dom,"/kdevautoproject/subclassing", + "subclass","sourcefile", "uifile"); + } + } + } +} + + +void AutoDetailsView::slotDetailsExecuted( QListViewItem *item ) +{ + if ( !item ) + return ; + + ProjectItem *pvitem = static_cast( item ); + if ( pvitem->type() != ProjectItem::File ) + return ; + + if ( !m_widget->selectedSubproject() ) + return; + + QString dirName = m_widget->selectedSubproject()->path; + FileItem *fitem = static_cast( item ); + if(fitem->is_subst) + { + fitem->changeSubstitution(); + return; + } + + m_part->partController()->editDocument( KURL( dirName + "/" + fitem->name ) ); +} + +void AutoDetailsView::slotSetActiveTarget() +{ + TargetItem * titem = static_cast( m_listView->selectedItem() ); + if ( !titem ) return ; + + SubprojectItem * subpitem = m_widget->selectedSubproject(); + if ( !subpitem ) return; + + QString targetPath = subpitem->path + "/" + titem->name; + targetPath = targetPath.mid( m_part->projectDirectory().length() + 1 ); + kdDebug( 9020 ) << "Setting active " << targetPath << endl; + m_widget->setActiveTarget( targetPath ); + QDomDocument &dom = *m_part->projectDom(); + DomUtil::writeEntry( dom, "/kdevautoproject/general/activetarget", targetPath ); +} + +void AutoDetailsView::focusOutEvent(QFocusEvent */*e*/) +{ + m_widget->setLastFocusedView(AutoProjectWidget::DetailsView); +} + +#include "autodetailsview.moc" + +//kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/autotools/autodetailsview.h b/buildtools/autotools/autodetailsview.h new file mode 100644 index 00000000..ee67558d --- /dev/null +++ b/buildtools/autotools/autodetailsview.h @@ -0,0 +1,88 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder + Copyright (c) 2005 by Matt Rogers + +*************************************************************************** +* * +* 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. * +* * +*************************************************************************** +*/ + +#ifndef AUTODETAILSVIEW_H +#define AUTODETAILSVIEW_H + +#include "autoprojectviewbase.h" + +#include "domutil.h" +#include "autolistviewitems.h" + +class KAction; + +class AutoProjectPart; +class AutoProjectWidget; +class AutoToolsAction; + +class AutoDetailsView : protected AutoProjectViewBase +{ + friend class RemoveFileDialog; + friend class FileItem; + Q_OBJECT + +public: + AutoDetailsView( AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name ); + virtual ~AutoDetailsView(); + + QString getUiFileLink( const QString &path, const QString& filename ); + KListView* listView() + { + return m_listView; + } + +public slots: + void slotSelectionChanged( QListViewItem* item ); + void slotSelectionChanged(); + +signals: + void selectionChanged( QListViewItem* ); + +protected: + void initActions (); + virtual void focusOutEvent( QFocusEvent *e ); + +private slots: + void slotDetailsExecuted( QListViewItem *item ); + void slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + + void slotTargetOptions (); + void slotAddNewFile(); + void slotAddExistingFile(); + void slotAddIcon(); + void slotBuildTarget(); + void slotExecuteTarget(); + void slotRemoveDetail(); + void slotSetActiveTarget(); + +private: + AutoProjectWidget* m_widget; + AutoProjectPart* m_part; + + DomUtil::PairList m_subclasslist; + + AutoToolsAction* targetOptionsAction; + AutoToolsAction* addNewFileAction; + AutoToolsAction* addExistingFileAction; + KAction* addIconAction; + AutoToolsAction* buildTargetAction; + AutoToolsAction* executeTargetAction; + KAction* setActiveTargetAction; + AutoToolsAction* removeDetailAction; + +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autolistviewitems.cpp b/buildtools/autotools/autolistviewitems.cpp new file mode 100644 index 00000000..454d12f5 --- /dev/null +++ b/buildtools/autotools/autolistviewitems.cpp @@ -0,0 +1,181 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* Copyright (C) 2002 by Victor Rder * +* victor_roeder@gmx.de * +* * +* 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 +#include +#include + +#include +#include "misc.h" +#include "autolistviewitems.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" +#include "autodetailsview.h" + +/** +* Class ProjectItem +*/ + +ProjectItem::ProjectItem( Type type, QListView *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{ + bld = false; +} + + +ProjectItem::ProjectItem( Type type, ProjectItem *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{ + bld = false; +} + + +void ProjectItem::paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ) +{ + if ( isBold() ) + { + QFont font( p->font() ); + font.setBold( true ); + p->setFont( font ); + } + QListViewItem::paintCell( p, cg, column, width, alignment ); +} + + +/** +* Class SubprojectItem +*/ + +SubprojectItem::SubprojectItem( QListView *parent, const QString &text ) + : ProjectItem( Subproject, parent, text ) +{ + init(); +} + + +SubprojectItem::SubprojectItem( SubprojectItem *parent, const QString &text ) + : ProjectItem( Subproject, parent, text ) +{ + init(); +} + + +void SubprojectItem::init() +{ + targets.setAutoDelete( true ); + setPixmap( 0, SmallIcon( "folder" ) ); +} + + +QString SubprojectItem::relativePath() +{ + QString relpath = subdir; + + SubprojectItem *it = this; + while ( (it= dynamic_cast(it->parent())) ) + { + relpath.prepend(it->subdir + "/"); + } + relpath.remove(0, 2); + + return relpath; +} + + +/** +* Class TargetItem +*/ + +TargetItem::TargetItem( QListView *lv, bool group, const QString &text ) + : ProjectItem( Target, lv, text ) +{ + sources.setAutoDelete( true ); + setPixmap( 0, group ? SmallIcon( "tar" ) : SmallIcon( "binary" ) ); +} + + +/** +* Class FileItem +*/ + +FileItem::FileItem( QListView *lv, const QString &text, bool set_is_subst ) + : ProjectItem( File, lv, text ) , is_subst(set_is_subst) +{ + if(!is_subst) + { + setPixmap( 0, SmallIcon( "document" ) ); + } + else + { + setPixmap( 0, SmallIcon( "variablenew" ) ); + } +} + + +void FileItem::changeSubstitution() +{ +if(!is_subst) +return; + + bool ok; + QString text = QInputDialog::getText( + i18n("Edit Substitution"), i18n("Substitution:"), QLineEdit::Normal, + name, &ok ); + if ( ok && !text.isEmpty() ) + { + // user entered something and pressed OK + QString new_name = text; + if(new_name == name) + return; + setText(0,new_name); + changeMakefileEntry(new_name); + name = new_name; + } + else + { + // user entered nothing or pressed Cancel + + } +} + +void FileItem::changeMakefileEntry(const QString& new_name) +{ + TargetItem* target = dynamic_cast(parent()); + + QMap replaceMap; + + QString canontargetname = AutoProjectTool::canonicalize(target->name); + QString varname; + if( target->primary == "PROGRAMS" || target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = target->prefix + "_" + target->primary; + if( AutoDetailsView* lv = dynamic_cast(listView()) ) + { + if ( SubprojectItem* subProject = lv->m_part->m_widget->selectedSubproject() ) + { + QStringList sources = QStringList::split(QRegExp("[ \t\n]"), subProject->variables[varname]); + QStringList::iterator it = sources.find(name); + (*it) = new_name; + subProject->variables[varname] = sources.join(" "); + replaceMap.insert(varname, subProject->variables[varname]); + + AutoProjectTool::addToMakefileam(subProject->path + "/Makefile.am", replaceMap); + + if(new_name == "") + target->sources.remove(this); + } + } +} diff --git a/buildtools/autotools/autolistviewitems.h b/buildtools/autotools/autolistviewitems.h new file mode 100644 index 00000000..0dece2a2 --- /dev/null +++ b/buildtools/autotools/autolistviewitems.h @@ -0,0 +1,143 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* Copyright (C) 2002 by Victor Rder * +* victor_roeder@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef AUTOLISTVIEWITEMS_H +#define AUTOLISTVIEWITEMS_H + +#include + +#include + +class TargetItem; +class FileItem; +class AutoProjectPart; + +/** +* Base class for all items appearing in ProjectOverview and ProjectDetails. +*/ +class ProjectItem : public QListViewItem +{ +public: + enum Type { Subproject, Target, File }; + + ProjectItem( Type type, QListView *parent, const QString &text ); + ProjectItem( Type type, ProjectItem *parent, const QString &text ); + + void paintCell( QPainter *p, const QColorGroup &cg, + int column, int width, int alignment ); + void setBold( bool b ) + { + bld = b; + } + bool isBold() const + { + return bld; + } + Type type() + { + return typ; + } + +private: + Type typ; + bool bld; + +}; + + +/** +* Stores the content of one Makefile.am +*/ +class SubprojectItem : public ProjectItem +{ +public: + SubprojectItem( QListView *parent, const QString &text ); + SubprojectItem( SubprojectItem *parent, const QString &text ); + + /** name of the directory */ + QString subdir; + /** absolute path */ + QString path; + /** mapping from prefix to path */ + QMap prefixes; + /** mapping from variable name to value */ + QMap variables; + /** list of targets */ + QPtrList targets; + + QString relativePath(); + +private: + void init(); +}; + + +/** +* Stores one target +* For e.g. the line +* bin_LTLIBRARIES = foo.la +* generates a target with name 'foo.la', primary LTLIBRARIES and prefix 'bin' +* In order to make things not too simple ;-) headers and data are handled +* a bit different from programs, libraries and scripts: All headers for a +* certain prefix (analogously for data) are put in _one_ TargetItem object, +* and the names of the files are put in the sources variable. This avoids +* cluttering the list view with lots of header items. +*/ +class TargetItem : public ProjectItem +{ +public: + //enum TargetKind { Program, Library, DataGroup, IconGroup, DocGroup }; + + TargetItem( QListView *lv, bool group, const QString &text ); + + // Target kind - not used currently + //TargetKind kind; + //! Name of target, e.g. foo + QString name; + //! One of PROGRAMS, LIBRARIES, LTLIBRARIES, SCRIPTS, HEADERS, DATA, JAVA + //! In addition to these automake primaries, we use KDEICON and KDEDOCS + //! for am_edit magic + QString primary; + //! May be bin, pkglib, noinst, check, sbin, pkgdata, java... + QString prefix; + //! Content of foo_SOURCES (or java_JAVA) assignment + QPtrList sources; + //! Content of foo_LDFLAGS assignment + QString ldflags; + //! Content of foo_LDADD assignment + QString ldadd; + //! Content of foo_LIBADD assignment + QString libadd; + //! Content of foo_DEPENDENCIES assignment + QString dependencies; +}; + + +// Not sure if this complexity is really necessary... +class FileItem : public ProjectItem +{ + +public: + FileItem( QListView *lv, const QString &text, bool set_is_subst = false ); + void changeSubstitution(); + void changeMakefileEntry( const QString& ); + + QString name; + QString uiFileLink; + const bool is_subst; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/autoprojectpart.cpp b/buildtools/autotools/autoprojectpart.cpp new file mode 100644 index 00000000..ea0b6896 --- /dev/null +++ b/buildtools/autotools/autoprojectpart.cpp @@ -0,0 +1,1474 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * Copyright (C) 2002 by Victor Roeder * + * victor_roeder@gmx.de * + * * + * 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 + +#include "autoprojectpart.h" +#include "autolistviewitems.h" +#include "configureoptionswidget.h" +#include "addtranslationdlg.h" +#include "addicondlg.h" +#include "autoprojectwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define CONFIGURE_OPTIONS 1 +#define RUN_OPTIONS 2 +#define MAKE_OPTIONS 3 + +static const KDevPluginInfo data("kdevautoproject"); + +K_EXPORT_COMPONENT_FACTORY( libkdevautoproject, AutoProjectFactory( data ) ) + +AutoProjectPart::AutoProjectPart(QObject *parent, const char *name, const QStringList &args) + : KDevBuildTool(&data, parent, name ? name : "AutoProjectPart") + , m_lastCompilationFailed(false) +{ + setInstance(AutoProjectFactory::instance()); + + setXMLFile("kdevautoproject.rc"); + + m_executeAfterBuild = false; + m_isKDE = (args[0] == "kde"); + m_needMakefileCvs = false; + + m_widget = new AutoProjectWidget(this, m_isKDE); + m_widget->setIcon(SmallIcon( info()->icon() )); + m_widget->setCaption(i18n("Automake Manager")); + QWhatsThis::add(m_widget, i18n("Automake manager

" + "The project tree consists of two parts. The 'overview' " + "in the upper half shows the subprojects, each one having a " + "Makefile.am. The 'details' view in the lower half shows the " + "targets and files for the subproject selected in the overview.")); + + mainWindow()->embedSelectViewRight(m_widget, i18n("Automake Manager"), i18n("Automake manager")); + KAction *action; + + action = new KAction( i18n("Add Translation..."), 0, + this, SLOT(slotAddTranslation()), + actionCollection(), "project_addtranslation" ); + action->setToolTip(i18n("Add translation")); + action->setWhatsThis(i18n("Add translation

Creates .po file for the selected language.")); + action->setGroup("autotools"); + + + if (!m_isKDE) + action->setEnabled(false); + + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + action->setToolTip(i18n("Build project")); + action->setWhatsThis(i18n("Build project

Runs make from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Build &Active Target"), "make_kdevelop", Key_F7, + this, SLOT(slotBuildActiveTarget()), + actionCollection(), "build_buildactivetarget" ); + action->setToolTip(i18n("Build active target")); + action->setWhatsThis(i18n("Build active target

Constructs a series of make commands to build an active target. " + "Also builds dependent targets.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Compile &File"), "make_kdevelop", + this, SLOT(slotCompileFile()), + actionCollection(), "build_compilefile" ); + action->setToolTip(i18n("Compile file")); + action->setWhatsThis(i18n("Compile file

Runs make filename.o command from the directory where 'filename' is the name of currently opened file.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Run Configure"), 0, + this, SLOT(slotConfigure()), + actionCollection(), "build_configure" ); + action->setToolTip(i18n("Run configure")); + action->setWhatsThis(i18n("Run configure

Executes configure with flags, arguments " + "and environment variables specified in the project settings dialog, " + "Configure Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Run automake && friends"), 0, + this, SLOT(slotMakefilecvs()), + actionCollection(), "build_makefilecvs" ); + action->setToolTip(i18n("Run automake && friends")); + action->setWhatsThis(i18n("Run automake && friends

Executes
make -f Makefile.cvs
./configure
commands from the project directory.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Install"), 0, + this, SLOT(slotInstall()), + actionCollection(), "build_install" ); + action->setToolTip(i18n("Install")); + action->setWhatsThis(i18n("Install

Runs make install command from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Install (as root user)"), 0, + this, SLOT(slotInstallWithKdesu()), + actionCollection(), "build_install_kdesu" ); + action->setToolTip(i18n("Install as root user")); + action->setWhatsThis(i18n("Install

Runs make install command from the project directory with root privileges.
" + "It is executed via kdesu command.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("&Clean Project"), 0, + this, SLOT(slotClean()), + actionCollection(), "build_clean" ); + action->setToolTip(i18n("Clean project")); + action->setWhatsThis(i18n("Clean project

Runs make clean command from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("&Distclean"), 0, + this, SLOT(slotDistClean()), + actionCollection(), "build_distclean" ); + action->setToolTip(i18n("Distclean")); + action->setWhatsThis(i18n("Distclean

Runs make distclean command from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + action = new KAction( i18n("Make Messages && Merge"), 0, + this, SLOT(slotMakeMessages()), + actionCollection(), "build_messages" ); + action->setToolTip(i18n("Make messages && merge")); + action->setWhatsThis(i18n("Make messages && merge

Runs make package-messages command from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + action->setGroup("autotools"); + + if (!m_isKDE) + action->setEnabled(false); + + buildConfigAction = new KSelectAction( i18n("Build Configuration"), 0, + actionCollection(), "project_configuration" ); + buildConfigAction->setToolTip(i18n("Build configuration menu")); + buildConfigAction->setWhatsThis(i18n("Build configuration menu

Allows to switch between project build configurations.
" + "Build configuration is a set of build and top source directory settings, " + "configure flags and arguments, compiler flags, etc.
" + "Modify build configurations in project settings dialog, Configure Options tab.")); + buildConfigAction->setGroup("autotools"); + + QDomDocument &dom = *projectDom(); + if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default")) { + //ok we handle the execute in this kpart + action = new KAction( i18n("Execute Program"), "exec", SHIFT+Key_F9, + this, SLOT(slotExecute()), + actionCollection(), "build_execute" ); + action->setToolTip(i18n("Execute program")); + action->setWhatsThis(i18n("Execute program

Executes the currently active target or the main program specified in project settings, Run Options tab.")); + action->setGroup("autotools"); + } + + connect( buildConfigAction, SIGNAL(activated(const QString&)), + this, SLOT(slotBuildConfigChanged(const QString&)) ); + connect( buildConfigAction->popupMenu(), SIGNAL(aboutToShow()), + this, SLOT(slotBuildConfigAboutToShow()) ); + +// connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), this, SLOT(projectConfigWidget(KDialogBase*)) ); + + _configProxy = new ConfigWidgetProxy( core() ); + _configProxy->createProjectConfigPage( i18n("Configure Options"), CONFIGURE_OPTIONS, info()->icon() ); + _configProxy->createProjectConfigPage( i18n("Run Options"), RUN_OPTIONS, info()->icon() ); + _configProxy->createProjectConfigPage( i18n("Make Options"), MAKE_OPTIONS, info()->icon() ); + connect( _configProxy, SIGNAL(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )), + this, SLOT(insertConfigWidget(const KDialogBase*, QWidget*, unsigned int )) ); + + + connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), + this, SLOT(slotCommandFinished(const QString&)) ); + connect( makeFrontend(), SIGNAL(commandFailed(const QString&)), + this, SLOT(slotCommandFailed(const QString&)) ); + + setWantautotools(); + + +} + + +AutoProjectPart::~AutoProjectPart() +{ + if (m_widget) + { + mainWindow()->removeView(m_widget); + } + delete m_widget; + delete _configProxy; +} + + +void AutoProjectPart::insertConfigWidget( const KDialogBase* dlg, QWidget * page, unsigned int pagenumber ) +{ + switch ( pagenumber ) + { + case CONFIGURE_OPTIONS: + { + ConfigureOptionsWidget *w2 = new ConfigureOptionsWidget(this, page ); + connect( dlg, SIGNAL(okClicked()), w2, SLOT(accept()) ); + } + break; + + case RUN_OPTIONS: + { + QDomDocument &dom = *projectDom(); + if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/run/disable_default")) + { + //ok we handle the execute in this kpart + RunOptionsWidget *w3 = new RunOptionsWidget(*projectDom(), "/kdevautoproject", buildDirectory(), page ); + connect( dlg, SIGNAL(okClicked()), w3, SLOT(accept()) ); + } + } + break; + + case MAKE_OPTIONS: + { + MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevautoproject", page ); + connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) ); + } + break; + } +} + +void AutoProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_projectName = projectName; + m_projectPath =dirName; + + m_widget->openProject(dirName); + + QDomDocument &dom = *projectDom(); + QString activeTarget = DomUtil::readEntry(dom, "/kdevautoproject/general/activetarget"); + kdDebug(9020) << k_funcinfo << "activeTarget " << activeTarget << endl; + if (!activeTarget.isEmpty()) + m_widget->setActiveTarget(activeTarget); + else + { + KMessageBox::information( m_widget, i18n("No active target specified, running the application will\n" + "not work until you make a target active in the Automake Manager\n" + "on the right side or use the Main Program options under\n" + "Project -> Project Options -> Run Options"), i18n("No active target specified"), "kdevelop_open_project_no_active_target"); + } + + KDevProject::openProject( dirName, projectName ); +} + + +void AutoProjectPart::closeProject() +{ + m_widget->closeProject(); +} + + +QString AutoProjectPart::projectDirectory() const +{ + return m_projectPath; +} + + +QString AutoProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList AutoProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * If no main Program was selected in the Run Options dialog + * use the currently active target instead to calculate it. + * The returned string can be: + * if /kdevautoproject/run/directoryradio == executable + * The directory where the executable is + * if /kdevautoproject/run/directoryradio == build + * The directory where the executable is relative to build directory + * if /kdevautoproject/run/directoryradio == custom + * The custom directory absolute path + */ +QString AutoProjectPart::runDirectory() const +{ + + QDomDocument &dom = *projectDom(); + + QString cwd; + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() ) + { + cwd = defaultRunDirectory("kdevautoproject"); + }else + { + cwd = DomUtil::readEntry( dom, "/kdevautoproject/run/cwd/"+m_widget->activeTarget()->name ); + } + if( cwd.isEmpty() ) + cwd = buildDirectory() +"/"+ URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) +"/"+m_widget->activeDirectory(); + + return cwd; +} + + +/** Retuns the currently selected main program + * If no main Program was selected in the Run Options dialog + * use the currently active target instead. + * The returned string can be: + * if /kdevautoproject/run/directoryradio == executable + * The executable name + * if /kdevautoproject/run/directoryradio == build + * The path to executable relative to build directory + * if /kdevautoproject/run/directoryradio == custom or relative == false + * The absolute path to executable + */ + +QString AutoProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + if( DomUtil::readBoolEntry(*dom, "/kdevautoproject/run/useglobalprogram", false) ) + { + QString DomMainProgram = DomUtil::readEntry(*dom, "/kdevautoproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume builddir relative path + { + QString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ); + if( !relprojectpath.isEmpty() ) + relprojectpath = "/" + relprojectpath; + return buildDirectory() + relprojectpath + "/" + DomMainProgram; + } + + } + else // If no Main Program was specified, return the active target + { + TargetItem* titem = m_widget->activeTarget(); + + if ( !titem ) { + KMessageBox::error( m_widget, i18n("There is no active target.\n" + "Unable to determine the main program."), i18n("No active target found") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + return QString::null; + } + + if ( titem->primary != "PROGRAMS" ) { + KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n" + "Unable to determine the main program. If you want this\n" + "to be the active target, set a main program under\n" + "Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + return QString::null; + } + + QString relprojectpath = URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ); + if( !relprojectpath.isEmpty() ) + relprojectpath = "/" + relprojectpath; + return buildDirectory() + relprojectpath + "/" + activeDirectory() + "/" + titem->name; + } +} + + +/** Retuns a QString with the debug command line arguments */ +QString AutoProjectPart::debugArguments() const +{ + QDomDocument &dom = *projectDom(); + + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() ) + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/globaldebugarguments"); + }else + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/debugarguments/" + m_widget->activeTarget()->name); + } +} + + +/** Retuns a QString with the run command line arguments */ +QString AutoProjectPart::runArguments() const +{ + QDomDocument &dom = *projectDom(); + + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) || !m_widget->activeTarget() ) + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/programargs"); + }else + { + return DomUtil::readEntry(dom, "/kdevautoproject/run/runarguments/" + m_widget->activeTarget()->name); + } +} + + +QString AutoProjectPart::activeDirectory() const +{ + return m_widget->activeDirectory(); +} + + +QStringList AutoProjectPart::allFiles() const +{ + return m_widget->allFiles(); +} + + +void AutoProjectPart::setWantautotools() +{ + QDomDocument &dom = *projectDom(); + QDomElement el = DomUtil::elementByPath(dom, "/kdevautoproject/make"); + if ( el.namedItem("envvars").isNull() ) { + DomUtil::PairList list; + list << DomUtil::Pair("WANT_AUTOCONF_2_5", "1"); + list << DomUtil::Pair("WANT_AUTOMAKE_1_6", "1"); + DomUtil::writePairListEntry(dom, "/kdevautoproject/make/envvars", "envvar", "name", "value", list); + } +} + + +QString AutoProjectPart::makeEnvironment() const +{ + // Get the make environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), "/kdevautoproject/make/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) + { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + + KConfigGroup grp( kapp->config(), "MakeOutputView" ); + if( grp.readBoolEntry( "ForceCLocale", true ) ) + environstr += "LC_MESSAGES="+EnvVarTools::quote("C")+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" "; + + return environstr; +} + + +void AutoProjectPart::addFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void AutoProjectPart::addFiles ( const QStringList& fileList ) +{ + QString directory, name; + QStringList::ConstIterator it; + bool messageBoxShown = false; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + int pos = ( *it ).findRev('/'); + if (pos != -1) + { + directory = ( *it ).left(pos); + name = ( *it ).mid(pos+1); + } + else + { + directory = ""; + name = ( *it ); + } + + if (directory != m_widget->activeDirectory() || + directory.isEmpty()) + { + if ( !messageBoxShown ) + { + KMessageBox::information(m_widget, i18n("The directory you selected is not the active directory.\n" + "You should 'activate' the target you're currently working on in Automake Manager.\n" + "Just right-click a target and choose 'Make Target Active'."), + i18n ( "No Active Target Found" ), "No automake manager active target warning" ); + messageBoxShown = true; + } + } + } + + m_widget->addFiles(fileList); +} + +void AutoProjectPart::removeFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->removeFiles ( fileList ); +} + +void AutoProjectPart::removeFiles ( const QStringList& fileList ) +{ + /// \FIXME m_widget->removeFiles does nothing! + m_widget->removeFiles ( fileList ); + + emit removedFilesFromProject ( fileList ); +} + +QStringList AutoProjectPart::allBuildConfigs() const +{ + QDomDocument &dom = *projectDom(); + + QStringList allConfigs; + allConfigs.append("default"); + + QDomNode node = dom.documentElement().namedItem("kdevautoproject").namedItem("configurations"); + QDomElement childEl = node.firstChild().toElement(); + while (!childEl.isNull()) + { + QString config = childEl.tagName(); + kdDebug(9020) << k_funcinfo << "Found config " << config << endl; + if (config != "default") + allConfigs.append(config); + childEl = childEl.nextSibling().toElement(); + } + + return allConfigs; +} + + +QString AutoProjectPart::currentBuildConfig() const +{ + QDomDocument &dom = *projectDom(); + + QString config = DomUtil::readEntry(dom, "/kdevautoproject/general/useconfiguration"); + if (config.isEmpty() || !allBuildConfigs().contains(config)) + config = "default"; + + return config; +} + + +QString AutoProjectPart::buildDirectory() const +{ + QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/"; + + QString builddir = DomUtil::readEntry(*projectDom(), prefix + "builddir"); + if (builddir.isEmpty()) + return topsourceDirectory(); + else if (builddir.startsWith("/")) + return builddir; + else + return projectDirectory() + "/" + builddir; +} + +QString AutoProjectPart::topsourceDirectory() const +{ + QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/"; + + QString topsourcedir = DomUtil::readEntry(*projectDom(), prefix + "topsourcedir"); + if (topsourcedir.isEmpty()) + return projectDirectory(); + else if (topsourcedir.startsWith("/")) + return topsourcedir; + else + return projectDirectory() + "/" + topsourcedir; +} + +QString AutoProjectPart::constructMakeCommandLine(const QString &dir, const QString &target) const +{ + + QString preCommand; + QFileInfo fi1(); + kdDebug(9020) << k_funcinfo << "Looking for Makefile in " << dir << endl; + if ( !QFile::exists(dir + "/GNUmakefile") && !QFile::exists(dir + "/makefile") + && ! QFile::exists(dir + "/Makefile") ) + { + if (!QFile::exists(buildDirectory() + "/configure")) + { + int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory\n" + "and no configure script for this project.\n" + "Run automake & friends and configure first?").arg(buildDirectory()), QString::null, i18n("Run Them"), i18n("Do Not Run")); + if (r == KMessageBox::No) + return QString::null; + preCommand = makefileCvsCommand(); + if (preCommand.isNull()) + return QString::null; + preCommand += " && "; + preCommand += configureCommand() + " && "; + } + else + { + int r = KMessageBox::questionYesNo(m_widget, i18n("%1\nThere is no Makefile in this directory. Run 'configure' first?").arg(dir), QString::null, i18n("Run configure"), i18n("Do Not Run")); + if (r == KMessageBox::No) + return QString::null; + preCommand = configureCommand() + " && "; + } + } + QDomDocument &dom = *projectDom(); + + QString cmdline = DomUtil::readEntry(dom, "/kdevautoproject/make/makebin"); + int prio = DomUtil::readIntEntry(dom, "/kdevautoproject/make/prio"); + QString nice; + kdDebug(9020) << k_funcinfo << "nice = " << prio<< endl; + if (prio != 0) + { + nice = QString("nice -n%1 ").arg(prio); + } + + if (cmdline.isEmpty()) + cmdline = MAKE_COMMAND; + if (!DomUtil::readBoolEntry(dom, "/kdevautoproject/make/abortonerror")) + cmdline += " -k"; + bool runmultiple = DomUtil::readBoolEntry(dom, "/kdevautoproject/make/runmultiplejobs"); + int jobs = DomUtil::readIntEntry(dom, "/kdevautoproject/make/numberofjobs"); + if (runmultiple && jobs != 0) + { + cmdline += " -j"; + cmdline += QString::number(jobs); + } + if (DomUtil::readBoolEntry(dom, "/kdevautoproject/make/dontact")) + cmdline += " -n"; + + cmdline += " "; + cmdline += target; + cmdline.prepend(nice); + cmdline.prepend(makeEnvironment()); + + QString dircmd = "cd "; + dircmd += KProcess::quote(dir); + dircmd += " && "; + + return preCommand + dircmd + cmdline; +} + + +void AutoProjectPart::startMakeCommand(const QString &dir, const QString &target, bool withKdesu) +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + kdDebug(9020) << "startMakeCommand:" << dir << ": "<< target << endl; + m_buildCommand = constructMakeCommandLine(dir, target); + + if (withKdesu) + m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'"; + + if (!m_buildCommand.isNull()) + makeFrontend()->queueCommand(dir, m_buildCommand); +} + + +/** Adds the make command for the libraries that the target depends on + * to the make frontend queue (this is a recursive function) */ +bool AutoProjectPart::queueInternalLibDependenciesBuild(TargetItem* titem, QStringList& alreadyScheduledDeps) +{ + + QString addstr = (titem->primary == "PROGRAMS")? titem->ldadd : titem->libadd; + QStringList l2 = QStringList::split(QRegExp("[ \t]"), addstr); // list of dependencies + QString tdir; // temp target directory + QString tname; // temp target name + QString tcmd; // temp command line + QStringList::Iterator l2it; + for (l2it = l2.begin(); l2it != l2.end(); ++l2it) + { + QString dependency = *l2it; + if (dependency.startsWith("$(top_builddir)/")) + { + // These are the internal libraries + dependency.remove("$(top_builddir)/"); + + if( !alreadyScheduledDeps.contains(*l2it) ) + { + alreadyScheduledDeps << *l2it; + tdir = buildDirectory(); + if (!tdir.endsWith("/") && !tdir.isEmpty()) + tdir += "/"; + int pos = dependency.findRev('/'); + if (pos == -1) + { + tname = dependency; + } + else + { + tdir += dependency.left(pos+1); + tname = dependency.mid(pos+1); + } + kdDebug(9020) << "Scheduling : <" << tdir << "> target <" << tname << ">" << endl; + // Recursively queue the dependencies for building + SubprojectItem *spi = m_widget->subprojectItemForPath( dependency.left(pos) ); + if (spi) + { + QPtrList< TargetItem > tl = spi->targets; + // Cycle through the list of targets to find the one we're looking for + TargetItem *ti = tl.first(); + do + { + if (ti->name == tname) + { + // found it: queue it and stop looking + if( !queueInternalLibDependenciesBuild(ti, alreadyScheduledDeps) ) + return false; + break; + } + ti = tl.next(); + } + while (ti); + } + + kdDebug(9020) << "queueInternalLibDependenciesBuild:" << tdir << ": "<< tname << endl; + tcmd = constructMakeCommandLine(tdir, tname); + if (!tcmd.isNull()) + { + makeFrontend()->queueCommand( tdir, tcmd); + } + }else + { + //Message box about circular deps. + tdir = buildDirectory(); + if (!tdir.endsWith("/") && !tdir.isEmpty()) + tdir += "/"; + int pos = dependency.findRev('/'); + if (pos == -1) + { + tname = dependency; + } + else + { + tdir += dependency.left(pos+1); + tname = dependency.mid(pos+1); + } + KMessageBox::error( 0, i18n("Found a circular dependency in the project, between this target and %1.\nCannot build this project until this is resolved.").arg(tname), i18n("Circular Dependency found") ); + return false; + } + } + } + return true; +} + + +void AutoProjectPart::slotBuild() +{ + //m_lastCompilationFailed = false; + + if( m_needMakefileCvs ) + { + slotMakefilecvs(); + slotConfigure(); + m_needMakefileCvs = false; + } + + startMakeCommand(buildDirectory(), QString::fromLatin1("")); +} + + +void AutoProjectPart::buildTarget(QString relpath, TargetItem* titem) +{ + + if ( !titem ) + return; + + //m_lastCompilationFailed = false; + + // Calculate the complete name of the target and store it in name + QString name = titem->name; + if ( titem->primary == "KDEDOCS" ) + name = "index.cache.bz2"; + + // Calculate the full path of the target and store it in path + QString path = buildDirectory(); + if (!path.endsWith("/") && !path.isEmpty()) + path += "/"; + if (relpath.at(0) == '/') + path += relpath.mid(1); + else + path += relpath; + + // Save all files once + partController()->saveAllFiles(); + + // Add the make command for the libraries that the target depends on to the make frontend queue + // if this recursive behavour is un-wanted comment the next line + QStringList deps; + if( !queueInternalLibDependenciesBuild(titem, deps) ) + return; + + // Calculate the "make" command line for the target + //QString relpath = dir.path().mid( projectDirectory().length() ); + m_runProg=buildDirectory() + "/" + relpath+"/"+name; + kdDebug(9020) << "buildTarget:" << buildDirectory()<< endl; + kdDebug(9020) << "buildTarget:" << relpath << " " << path << ": "<< name << " : " << m_runProg << endl; + QString tcmd = constructMakeCommandLine( path, name ); + + // Call make + if (!tcmd.isNull()) + { + m_buildCommand = tcmd; + makeFrontend()->queueCommand( path, tcmd); + } +} + + +void AutoProjectPart::slotBuildActiveTarget() +{ + // Get a pointer to the active target + TargetItem* titem = m_widget->activeTarget(); + + if ( !titem ) + return; + + // build it + buildTarget( URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + activeDirectory(), titem); +} + + +void AutoProjectPart::slotCompileFile() +{ + KParts::ReadWritePart *part = dynamic_cast(partController()->activePart()); + if (!part || !part->url().isLocalFile()) + return; + + QString fileName = part->url().path(); + QFileInfo fi(fileName); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName(true); + kdDebug(9020) << "Compiling " << fileName + << " in dir " << sourceDir + << " with baseName " << baseName << endl; + + QString projectDir = projectDirectory(); + if (!sourceDir.startsWith(projectDir)) { + KMessageBox::sorry(m_widget, i18n("Can only compile files in directories which belong to the project.")); + return; + } + + QString buildDir = buildDirectory() + sourceDir.mid(projectDir.length()); + QString target = baseName + ".lo"; + kdDebug(9020) << "builddir " << buildDir << ", target " << target << endl; + + startMakeCommand(buildDir, target); +} + +QString AutoProjectPart::configureCommand() const +{ + QDomDocument &dom = *projectDom(); + QString prefix = "/kdevautoproject/configurations/" + currentBuildConfig() + "/"; + + QString cmdline = "\"" + topsourceDirectory(); + cmdline += "/configure\""; + QString cc = DomUtil::readEntry(dom, prefix + "ccompilerbinary"); + if (!cc.isEmpty()) + cmdline.prepend(QString("CC=%1 ").arg(cc)); + QString cflags = DomUtil::readEntry(dom, prefix + "cflags"); + if (!cflags.isEmpty()) + cmdline.prepend(QString("CFLAGS=\"%1\" ").arg(cflags)); + QString cxx = DomUtil::readEntry(dom, prefix + "cxxcompilerbinary"); + if (!cxx.isEmpty()) + cmdline.prepend(QString("CXX=%1 ").arg(cxx)); + QString cxxflags = DomUtil::readEntry(dom, prefix + "cxxflags"); + if (!cxxflags.isEmpty()) + cmdline.prepend(QString("CXXFLAGS=\"%1\" ").arg(cxxflags)); + QString f77 = DomUtil::readEntry(dom, prefix + "f77compilerbinary"); + if (!f77.isEmpty()) + cmdline.prepend(QString("F77=%1 ").arg(f77)); + QString fflags = DomUtil::readEntry(dom, prefix + "f77flags"); + if (!fflags.isEmpty()) + cmdline.prepend(QString("FFLAGS=\"%1\" ").arg(fflags)); + QString cppflags = DomUtil::readEntry(dom, prefix + "cppflags"); + if (!cppflags.isEmpty()) + cmdline.prepend(QString("CPPFLAGS=\"%1\" ").arg(cppflags)); + QString ldflags = DomUtil::readEntry(dom, prefix + "ldflags"); + if (!ldflags.isEmpty()) + cmdline.prepend(QString("LDFLAGS=\"%1\" ").arg(ldflags)); + + QString configargs = DomUtil::readEntry(dom, prefix + "configargs"); + if (!configargs.isEmpty()) { + cmdline += " "; + cmdline += configargs; + } + + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), prefix + "envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + cmdline.prepend(environstr); + + QString builddir = buildDirectory(); + QString dircmd; + + // if the build directory doesn't exist, add it's creation to the configureCommand + if ( !QFile::exists(builddir)) { + dircmd = "mkdir "; + dircmd += KProcess::quote(builddir); + dircmd += " && "; + } + + // add "cd into the build directory" to the configureCommand + dircmd += "cd "; + dircmd += KProcess::quote(builddir); + dircmd += " && "; + + return dircmd + cmdline; +} + +void AutoProjectPart::slotConfigure() +{ + QString cmdline = configureCommand(); + if (cmdline.isNull()) + return; + + makeFrontend()->queueCommand(buildDirectory(), cmdline); +} + +QString AutoProjectPart::makefileCvsCommand() const +{ + kdDebug(9020) << "makefileCvsCommand: runDirectory :" << runDirectory() << ":" <queueCommand(projectDirectory(), cmdline); +} + + +void AutoProjectPart::slotInstall() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("install")); +} + + +void AutoProjectPart::slotInstallWithKdesu() +{ + // First issue "make" to build the entire project with the current user + // This way we make sure all files are up to date before we do the "make install" + slotBuild(); + + // After that issue "make install" with the root user + startMakeCommand(buildDirectory(), QString::fromLatin1("install"), true); +} + + +void AutoProjectPart::slotClean() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("clean")); +} + + +void AutoProjectPart::slotDistClean() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("distclean")); +} + + +void AutoProjectPart::slotMakeMessages() +{ + startMakeCommand(buildDirectory(), QString::fromLatin1("package-messages")); +} + + +/** Checks if the currently selected main program or, + * if no main Program was selected in the Run Options dialog, + * the currently active target is up-to-date and builds it if necessary. + * In the end checks if the program is already running and if not calls the + * slotExecute2() function to execute it or asks the user what to do. + */ +void AutoProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + QDomDocument &dom = *projectDom(); + + m_runProg=m_runProg.isEmpty()?mainProgram():m_runProg; + + bool _auto = false; + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autocompile", true) && isDirty() ){ + m_executeAfterBuild = true; + if ( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/useglobalprogram", false) ){ + // A Main Program was specified, build all targets because we don't know which is it + kdDebug(9020) << "slotExecute: before slotBuild" << endl; + slotBuild(); + + } + else{ + // If no Main Program was specified, build the active target + kdDebug(9020) << "slotExecute: before slotBuildActiveTarget" << endl; + slotBuildActiveTarget(); + } + _auto = true; + } + + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autoinstall", false) && isDirty() ){ + m_executeAfterBuild = true; + // Use kdesu?? + if( DomUtil::readBoolEntry(dom, "/kdevautoproject/run/autokdesu", false) ){ + //slotInstallWithKdesu assumes that it hasn't just been build... + kdDebug(9020) << "slotExecute: before startMakeCommand" << endl; + _auto ? slotInstallWithKdesu() : startMakeCommand(buildDirectory(), QString::fromLatin1("install"), true); + } + else{ + kdDebug(9020) << "slotExecute: before slotInstall" << endl; + slotInstall(); + } + _auto = true; + } + + if ( _auto ){ + m_runProg.truncate(0); + return; + } + + if (appFrontend()->isRunning()) { + if (KMessageBox::questionYesNo(m_widget, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) + return; + connect(appFrontend(), SIGNAL(processExited()), SLOT(slotExecute2())); + appFrontend()->stopApplication(); + return; + } + kdDebug(9020) << "slotExecute: before slotExecute2" << endl; + slotExecute2(); +} + +void AutoProjectPart::executeTarget(const QDir& dir, const TargetItem* titem) +{ + m_executeAfterBuild=true; + partController()->saveAllFiles(); + + bool is_dirty = false; + QDateTime t = QFileInfo(dir , titem->name ).lastModified(); + QPtrListIterator it( titem->sources ); + for( ; it.current() ; ++it ) + { + if( t < QFileInfo(dir , (*it)->name).lastModified()) + is_dirty = true; + } + + if( DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/autocompile", true) && is_dirty ) + { + connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteTargetAfterBuild(const QString&)) ); + connect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotNotExecuteTargetAfterBuildFailed(const QString&)) ); + + m_runProg=titem->name; + m_executeTargetAfterBuild.first = dir; + m_executeTargetAfterBuild.second = const_cast(titem); + + QString relpath = "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->subdir; + kdDebug(9020) << "executeTarget: before buildTarget " << relpath << endl; + buildTarget(relpath, const_cast(titem)); + return; + } + + + bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal"); + + QString program = environString(); + + if ( !titem ) { + KMessageBox::error( m_widget, i18n("There is no active target.\n" + "Unable to determine the main program"), i18n("No active target found") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + program += titem->name; + }else if ( titem->primary != "PROGRAMS" ) { + KMessageBox::error( m_widget, i18n("Active target \"%1\" is not binary ( %2 ).\n" + "Unable to determine the main program. If you want this\n" + "to be the active target, set a main program under\n" + "Project -> Project Options -> Run Options").arg(titem->name).arg(titem->primary), i18n("Active target is not a library") ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << titem->primary << ") ! -> Unable to determine the main program in AutoProjectPart::mainProgram()" << endl; + program += titem->name; + }else + program += buildDirectory() + "/" + URLUtil::getRelativePath( topsourceDirectory(), projectDirectory() ) + "/" + m_widget->selectedSubproject()->relativePath()+ "/" + titem->name; + + QString args = DomUtil::readEntry(*projectDom(), "/kdevautoproject/run/runarguments/" + titem->name); + + program += " " + args; + kdDebug(9020) << "executeTarget:cmd=" << dir.path() << " " << program << endl; + appFrontend()->startAppCommand(dir.path(), program ,inTerminal); + m_executeAfterBuild=false; + +} + +void AutoProjectPart::slotExecuteTargetAfterBuild(const QString& command) +{ + kdDebug(9020) << "slotExecuteTargetAfterBuild " << command << endl; + if ( m_executeAfterBuild && constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command ) + { + disconnect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteAfterTargetBuild()) ); + disconnect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotExecuteAfterTargetBuildFailed()) ); + kdDebug(9020) << "slotExecuteTargetAfterBuild " << endl; + executeTarget(m_executeTargetAfterBuild.first, m_executeTargetAfterBuild.second); + } + +} + +void AutoProjectPart::slotNotExecuteTargetAfterBuildFailed(const QString& command) +{ + kdDebug(9020) << "executeTargetAfterBuildFailed" << endl; + if ( constructMakeCommandLine(m_executeTargetAfterBuild.first.path(), m_executeTargetAfterBuild.second->name) == command ) + { + m_executeAfterBuild=false; + disconnect( makeFrontend(), SIGNAL(commandFinished(const QString&)), this, SLOT(slotExecuteTargetAfterBuild()) ); + disconnect( makeFrontend(), SIGNAL(commandFailed(const QString&)), this, SLOT(slotNotExecuteTargetAfterBuildFailed()) ); + } +} + + +/* Get the run environment variables pairs into the environstr string + * in the form of: "ENV_VARIABLE=ENV_VALUE" + * Note that we quote the variable value due to the possibility of + * embedded spaces. */ +QString AutoProjectPart::environString() const +{ + DomUtil::PairList envvars = runEnvironmentVars(); + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + return environstr; +} + +/** Executes the currently selected main program. + * If no main Program was selected in the Run Options dialog + * the currently active target is executed instead. + */ +void AutoProjectPart::slotExecute2() +{ + disconnect(appFrontend(), SIGNAL(processExited()), this, SLOT(slotExecute2())); + + if (m_runProg.isEmpty()){ + // Do not execute non executable targets + return; + } + + QString program = environString(); + // Adds the ./ that is necessary to execute the program in bash shells + if (!m_runProg.startsWith("/")){ + program += "./"; + } + program += m_runProg; + program += " " + runArguments(); + + bool inTerminal = DomUtil::readBoolEntry(*projectDom(), "/kdevautoproject/run/terminal"); + + kdDebug(9020) << "slotExecute2: runDirectory: <" << runDirectory() << ">" <" <" <" <" <startAppCommand(runDirectory(), program, inTerminal); + m_executeAfterBuild=false; + m_runProg.truncate(0); +} + + +void AutoProjectPart::slotAddTranslation() +{ + AddTranslationDialog dlg(this, m_widget); + dlg.exec(); +} + + +void AutoProjectPart::slotBuildConfigChanged(const QString &config) +{ + DomUtil::writeEntry(*projectDom(), "/kdevautoproject/general/useconfiguration", config); + kdDebug(9020) << "Changed used configuration to " << config << endl; +} + + +void AutoProjectPart::slotBuildConfigAboutToShow() +{ + QStringList l = allBuildConfigs(); + buildConfigAction->setItems(l); + buildConfigAction->setCurrentItem(l.findIndex(currentBuildConfig())); +} + +void AutoProjectPart::restorePartialProjectSession ( const QDomElement* el ) +{ + m_widget->restoreSession ( el ); +} + +void AutoProjectPart::savePartialProjectSession ( QDomElement* el ) +{ + QDomDocument domDoc = el->ownerDocument(); + + KMessageBox::information ( 0, "Hallo, Welt!" ); + + kdDebug ( 9020 ) << k_funcinfo << "1" << endl; + + if ( domDoc.isNull() ) + { + kdDebug ( 9020 ) << k_funcinfo << "2" << endl; + return; + } + + kdDebug ( 9020 ) << k_funcinfo << "3" << endl; + + m_widget->saveSession ( el ); +} + +void AutoProjectPart::slotCommandFinished( const QString& command ) +{ + kdDebug(9020) << k_funcinfo << endl; + + if( m_buildCommand != command ) + return; + + m_buildCommand = QString::null; + + m_timestamp.clear(); + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified(); + } + + emit projectCompiled(); + + // reset the "last compilation has failed" flag + m_lastCompilationFailed = false; + + if( m_executeAfterBuild ){ + slotExecute(); + } +} + +void AutoProjectPart::slotCommandFailed( const QString& /*command*/ ) +{ + kdDebug(9020) << "slotCommandFinished " << k_funcinfo << endl; + + m_lastCompilationFailed = true; + m_executeAfterBuild=false; +} + +bool AutoProjectPart::isDirty() +{ + if (m_lastCompilationFailed) return true; + + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + QMap::Iterator it = m_timestamp.find( fileName ); + QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified(); + if( it == m_timestamp.end() || *it != t ){ + return true; + } + } + + return false; +} + +void AutoProjectPart::needMakefileCvs( ) +{ + m_needMakefileCvs = true; +} + +bool AutoProjectPart::isKDE() const +{ + return m_isKDE; +} + +KDevProject::Options AutoProjectPart::options() const +{ + return UsesAutotoolsBuildSystem; +} + +QStringList recursiveATFind( const QString &currDir, const QString &baseDir ) +{ + kdDebug(9020) << "Dir " << currDir << endl; + QStringList fileList; + + if( !currDir.contains( "/..") && !currDir.contains("/.") ) + { + QDir dir(currDir); + QStringList dirList = dir.entryList(QDir::Dirs ); + QStringList::Iterator idx = dirList.begin(); + for( ; idx != dirList.end(); ++idx ) + { + fileList += recursiveATFind( currDir + "/" + (*idx),baseDir ); + } + QStringList newFiles = dir.entryList("*.am *.in"); + idx = newFiles.begin(); + for( ; idx != newFiles.end(); ++idx ) + { + QString file = currDir + "/" + (*idx); + fileList.append( file.remove( baseDir ) ); + } + } + + + return fileList; +} + +/*! + \fn AutoProjectPart::distFiles() const + */ +QStringList AutoProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QDir admin(projectDir +"/admin"); + QStringList files = dir.entryList( "Makefile.cvs Makefile.am configure* INSTALL README NEWS TODO ChangeLog COPYING AUTHORS stamp-h.in acinclude.m4 config.h.in Makefile.in install-sh config.sub config.guess mkinstalldirs missing ltmain.sh depcomp"); + QStringList adminFiles = admin.entryList(QDir::Files); + QStringList::Iterator idx = adminFiles.begin(); + for( ; idx != adminFiles.end(); ++idx) + { + files.append( "admin/" + (*idx) ); + } + QStringList srcDirs = dir.entryList(QDir::Dirs); + idx = srcDirs.begin(); + for(; idx != srcDirs.end(); ++idx) + { + sourceList += recursiveATFind( projectDirectory() + "/" + (*idx), projectDirectory()); + } + return sourceList + files; +} + +void AutoProjectPart::startSimpleMakeCommand( const QString & dir, const QString & command, bool withKdesu ) +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + + // m_buildCommand = constructMakeCommandLine(dir, target); + + QString cmdline = command; + cmdline.prepend(makeEnvironment()); + + QString dircmd = "cd "; + dircmd += KProcess::quote(dir); + dircmd += " && "; + + m_buildCommand = dircmd + cmdline; + + if (withKdesu) + m_buildCommand = "kdesu -t -c '" + m_buildCommand + "'"; + + if (!m_buildCommand.isNull()) + makeFrontend()->queueCommand(dir, m_buildCommand); +} + +QString AutoProjectPart::getAutoConfFile(const QString& dir){ + + QFile inFile(dir + "/configure.in"); + QFile acFile(dir + "/configure.ac"); + if ( inFile.exists()){ + return inFile.name(); + }else if (acFile.exists()){ + return acFile.name(); + } + return acFile.name();; +} + +#include "autoprojectpart.moc" + +// kate: space-indent on; indent-width 4; diff --git a/buildtools/autotools/autoprojectpart.h b/buildtools/autotools/autoprojectpart.h new file mode 100644 index 00000000..d0862cc3 --- /dev/null +++ b/buildtools/autotools/autoprojectpart.h @@ -0,0 +1,153 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* Copyright (C) 2002 by Victor R�er * +* victor_roeder@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _AUTOPROJECTPART_H_ +#define _AUTOPROJECTPART_H_ + +#include +#include +#include +#include +#include +#include +#include "kdevbuildtool.h" + +class QDomElement; +class QStringList; +class KDialogBase; +class AutoProjectWidget; +class KSelectAction; +class TargetItem; +class ConfigWidgetProxy; + +class AutoProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + AutoProjectPart( QObject *parent, const char *name, const QStringList &args ); + virtual ~AutoProjectPart(); + + /** + * Implementation of the KDevProject interface. + */ + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual DomUtil::PairList runEnvironmentVars() const; + virtual QString runDirectory() const; + virtual QString mainProgram() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual QString environString() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile( const QString &fileName ); + virtual void addFiles ( const QStringList& fileList ); + virtual void removeFile( const QString &fileName ); + virtual void removeFiles ( const QStringList& fileList ); + virtual QString buildDirectory() const; + virtual Options options() const; + + /** + * Implementation of the KDevPlugin interface. + */ + virtual void restorePartialProjectSession ( const QDomElement* el ); + virtual void savePartialProjectSession ( QDomElement* el ); + + /** + * automake specific methods. + */ + QStringList allBuildConfigs() const; + QString currentBuildConfig() const; + QString topsourceDirectory() const; + void startMakeCommand( const QString &dir, const QString &target, bool withKdesu = false ); + void startSimpleMakeCommand( const QString &dir, const QString &command, bool withKdesu = false ); + void buildTarget( QString relpath, TargetItem* titem ); + void executeTarget( const QDir& dir, const TargetItem* titem ); + + void needMakefileCvs(); + bool isDirty(); + bool isKDE() const; + QStringList distFiles() const; + QString getAutoConfFile(const QString& dir); + +protected: + /** + * Reimplemented from KDevProject. These methods are only + * for use by the application core. + */ + virtual void openProject( const QString &dirName, const QString &projectName ); + virtual void closeProject(); + +private slots: + // void projectConfigWidget(KDialogBase *dlg); + void slotAddTranslation(); + void slotBuild(); + void slotBuildActiveTarget(); + void slotCompileFile(); + void slotClean(); + void slotDistClean(); + void slotInstall(); + void slotInstallWithKdesu(); + void slotMakefilecvs(); + void slotMakeMessages(); + void slotConfigure(); + void slotExecute(); + void slotExecute2(); + void slotExecuteTargetAfterBuild( const QString& command ); + void slotNotExecuteTargetAfterBuildFailed( const QString& command ); + void slotBuildConfigChanged( const QString &config ); + void slotBuildConfigAboutToShow(); + void slotCommandFinished( const QString& command ); + void slotCommandFailed( const QString& command ); + //void slotImportExisting(); + void insertConfigWidget( const KDialogBase* dlg, QWidget * page, unsigned int ); + + +private: + QGuardedPtr m_widget; + QString m_projectName; + QString m_projectPath; + KSelectAction *buildConfigAction; + + QString makeEnvironment() const; + void setWantautotools(); + QString makefileCvsCommand() const; + QString configureCommand() const; + + QMap m_timestamp; + bool m_executeAfterBuild; + QString m_buildCommand; + bool m_needMakefileCvs; + bool m_lastCompilationFailed; + bool m_isKDE; + QPair m_executeTargetAfterBuild; + QString m_runProg; + + ConfigWidgetProxy * _configProxy; + + // Enble AutoProjectWidget to emit our signals + friend class AutoProjectWidget; + friend class AddSubprojectDialog; + friend class FileItem; + + // For make commands queuing + QString constructMakeCommandLine( const QString &dir, const QString &target ) const; + bool queueInternalLibDependenciesBuild( TargetItem* titem, QStringList& list ); +}; + +typedef KDevGenericFactory AutoProjectFactory; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autoprojectviewbase.ui b/buildtools/autotools/autoprojectviewbase.ui new file mode 100644 index 00000000..ad5142ba --- /dev/null +++ b/buildtools/autotools/autoprojectviewbase.ui @@ -0,0 +1,123 @@ + +AutoProjectViewBase + + + AutoProjectViewBase + + + + 0 + 0 + 245 + 334 + + + + + unnamed + + + 4 + + + + layout3 + + + + unnamed + + + 2 + + + + m_button1 + + + + + + + + m_button2 + + + + + + + + m_button3 + + + + + + + + m_button4 + + + + + + + + m_button5 + + + + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + m_optionsButton + + + + + + Options + + + + + + + m_listView + + + true + + + LastColumn + + + false + + + + + + + klistview.h + + diff --git a/buildtools/autotools/autoprojectwidget.cpp b/buildtools/autotools/autoprojectwidget.cpp new file mode 100644 index 00000000..c3248504 --- /dev/null +++ b/buildtools/autotools/autoprojectwidget.cpp @@ -0,0 +1,748 @@ +/* + KDevelop Autotools Support + Copyright (c) 2001-2002 by Bernd Gehrmann + Copyright (c) 2002 by Victor Roeder + Copyright (c) 2005 by Matt Rogers + + *************************************************************************** + * * + * 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 "autoprojectwidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kdevcore.h" +#include "domutil.h" +#include "misc.h" +#include "choosetargetdialog.h" + +#include "autolistviewitems.h" + +#include "autoprojectpart.h" +#include "autosubprojectview.h" +#include "autodetailsview.h" +#include "urlutil.h" +#include "makefilehandler.h" + +static QString nicePrimary( const QString &primary ) +{ + if ( primary == "PROGRAMS" ) + return i18n( "Program" ); + else if ( primary == "LIBRARIES" ) + return i18n( "Library" ); + else if ( primary == "LTLIBRARIES" ) + return i18n( "Libtool Library" ); + else if ( primary == "SCRIPTS" ) + return i18n( "Script" ); + else if ( primary == "HEADERS" ) + return i18n( "Header" ); + else if ( primary == "DATA" ) + return i18n( "Data" ); + else if ( primary == "JAVA" ) + return i18n( "Java" ); + else + return QString::null; +} + + +AutoProjectWidget::AutoProjectWidget( AutoProjectPart *part, bool kde ) + : QVBox( 0, "auto project widget" ) +{ + m_part = part; + m_kdeMode = kde; + m_activeSubproject = 0; + m_activeTarget = 0; + m_shownSubproject = 0; + m_choosenTarget = 0; + m_makefileHandler = new MakefileHandler(); + + QSplitter *splitter = new QSplitter(Vertical, this); + + initOverview ( splitter ); + initDetailview ( splitter ); + + initActions (); +} + + +AutoProjectWidget::~AutoProjectWidget() +{ + delete m_makefileHandler; +} + +void AutoProjectWidget::initOverview ( QWidget* parent ) +{ + m_subprojectView = new AutoSubprojectView( this, m_part, parent, "project overview widget" ); +} + +void AutoProjectWidget::initDetailview ( QWidget* parent ) +{ + m_detailView = new AutoDetailsView( this, m_part, parent, "project details widget" ); +} + +void AutoProjectWidget::initActions() +{ + connect( m_subprojectView, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotOverviewSelectionChanged( QListViewItem* ) ) ); +} + +AutoSubprojectView* AutoProjectWidget::getSubprojectView () +{ + return m_subprojectView; +} + +AutoDetailsView* AutoProjectWidget::getDetailsView () +{ + return m_detailView; +} + +void AutoProjectWidget::openProject( const QString &dirName ) +{ + m_subprojectView->loadMakefileams ( dirName ); + MakefileHandler mfh; + mfh.parse( m_part->projectDirectory(), true ); + +} + + +void AutoProjectWidget::closeProject() +{ + m_shownSubproject = 0; + m_subprojectView->listView()->clear(); + m_detailView->listView()->clear(); +} + +SubprojectItem* AutoProjectWidget::activeSubproject () +{ + return m_activeSubproject; +} + +TargetItem* AutoProjectWidget::activeTarget () +{ + return m_activeTarget; +} + +QStringList AutoProjectWidget::allSubprojects() +{ + int prefixlen = m_part->projectDirectory().length() + 1; + QStringList res; + + QListViewItemIterator it( m_subprojectView->listView() ); + for ( ; it.current(); ++it ) + { + // Skip root subproject + // if ( it.current() == m_subprojectView->firstChild() ) + // continue; + QString path = static_cast( it.current() ) ->path; + res.append( path.mid( prefixlen ) ); + } + + return res; +} + +QPtrList AutoProjectWidget::allSubprojectItems() +{ + QPtrList res; + + QListViewItemIterator it ( m_subprojectView->listView() ); + + for ( ; it.current(); ++it ) + { + // Skip root subproject + // if ( it.current() == m_subprojectView->firstChild() ) + // continue; + + SubprojectItem* spitem = static_cast ( it.current() ); + res.append ( spitem ); + } + + return res; +} + +SubprojectItem* AutoProjectWidget::subprojectItemForPath(const QString & path, bool pathIsAbsolute) +{ + kdDebug(9020) << "Looking for path " << path << endl; + + int prefixLen = m_part->projectDirectory().length() + 1; + QListViewItemIterator it( m_subprojectView->listView() ); + for(; it.current(); ++it) + { + SubprojectItem* spitem = static_cast(it.current() ); + QString relpath = (spitem->path).mid(prefixLen); + kdDebug(9020) << " ... checking -" << spitem->path << "-" << endl; + kdDebug(9020) << " ... (tailored: -" << relpath << "- against -" << (pathIsAbsolute ? path.mid(prefixLen) : path) << "- )" << endl; + if ( relpath == (pathIsAbsolute ? path.mid(prefixLen) : path)) + { + kdDebug(9020) << "Found it!" << endl; + return spitem; + } + } + kdDebug(9020) << "Not found" << endl; + return NULL; +} + +QString AutoProjectWidget::pathForTarget(const TargetItem *titem) const +{ + + if (!titem) + return QString::null; + + kdDebug(9020) << "Looking for target " << titem->name << endl; + int prefixLen = m_part->projectDirectory().length() + 1; + QListViewItemIterator it( m_subprojectView->listView() ); + for(; it.current(); ++it) + { + SubprojectItem* spitem = static_cast(it.current() ); + kdDebug(9020) << "Checking: " << spitem->path << endl; + if (spitem->targets.containsRef(titem)) + { + kdDebug(9020) << "Found it!" << endl; + QString relpath = (spitem->path).mid(prefixLen); + return relpath; + } + } + kdDebug(9020) << "Not found" << endl; + return QString::null; +} + +QStringList AutoProjectWidget::allLibraries() +{ + int prefixlen = m_part->projectDirectory().length() + 1; + QStringList res; + + QListViewItemIterator it( m_subprojectView->listView() ); + for ( ; it.current(); ++it ) + { + SubprojectItem *spitem = static_cast( it.current() ); + QString path = spitem->path; + QPtrListIterator tit( spitem->targets ); + for ( ; tit.current(); ++tit ) + { + QString primary = ( *tit ) ->primary; + if ( primary == "LIBRARIES" || primary == "LTLIBRARIES" ) + { + QString fullname = path + "/" + ( *tit ) ->name; + res.append( fullname.mid( prefixlen ) ); + } + } + } + + return res; +} + + +QStringList AutoProjectWidget::allFiles() +{ + QPtrStack s; + QMap dict; + + for ( QListViewItem * item = m_subprojectView->listView()->firstChild(); item; + item = item->nextSibling() ? item->nextSibling() : s.pop() ) + { + if ( item->firstChild() ) + s.push( item->firstChild() ); + + SubprojectItem *spitem = static_cast( item ); + // use URLUtil so paths in root project dir are worked out correctly + QString relPath = URLUtil::relativePath(m_part->projectDirectory(), spitem->path, URLUtil::SLASH_SUFFIX); + QPtrListIterator tit( spitem->targets ); + for ( ; tit.current(); ++tit ) + { + QPtrListIterator fit( tit.current() ->sources ); + for ( ; fit.current(); ++fit ) + { + + if((*fit)->is_subst) + continue; + + QFileInfo fileInfo( (*fit)->name ); + if( fileInfo.extension() == "ui" ) + { + dict.insert( relPath + fileInfo.baseName() + ".h", true ); + dict.insert( relPath + fileInfo.baseName() + ".cpp", true ); + } + + dict.insert( relPath + ( *fit ) ->name, true ); + } + } + } + + // Files may be in multiple targets, so we have to remove + // duplicates + QStringList res; + QMap::Iterator it = dict.begin(); + while( it != dict.end() ){ + res << it.key(); + ++it; + } + + return res; +} + + +QString AutoProjectWidget::subprojectDirectory() +{ + if ( !selectedSubproject() ) + return QString::null; + + return selectedSubproject()->path; +} + + +void AutoProjectWidget::setActiveTarget( const QString &targetPath ) +{ + int prefixlen = m_part->projectDirectory().length() + 1; + QString olddir = m_part->activeDirectory(); + m_activeSubproject = 0; + m_activeTarget = 0; + + QListViewItemIterator it( m_subprojectView->listView() ); + for ( ; it.current(); ++it ) + { + SubprojectItem *spitem = static_cast( it.current() ); + QString path = spitem->path; + QPtrListIterator tit( spitem->targets ); + for ( ; tit.current(); ++tit ) + { + QString primary = ( *tit ) ->primary; + if ( primary != "PROGRAMS" && primary != "LIBRARIES" + && primary != "LTLIBRARIES" && primary != "JAVA" ) + continue; + + QString currentTargetPath = ( path + "/" + ( *tit ) ->name ).mid( prefixlen ); + + bool hasTarget = ( targetPath == currentTargetPath ); + ( *tit )->setBold( hasTarget ); + if ( hasTarget ) + { + spitem->setBold( true ); + m_activeSubproject = spitem; + m_activeTarget = ( *tit ); + m_subprojectView->listView()->setSelected( m_activeSubproject, true ); + m_subprojectView->listView()->ensureItemVisible ( m_activeSubproject ); + m_subprojectView->listView()->viewport()->update(); + m_detailView->listView()->setSelected ( m_activeTarget, true ); + m_detailView->listView()->ensureItemVisible ( m_activeTarget ); + m_detailView->listView()->viewport()->update(); + } + else + { + // to avoid a setBold ( false ) if there's another target in the current Subproject (i.e. spitem) ... + spitem->setBold ( ( m_activeSubproject == spitem ) ); + m_detailView->listView()->viewport()->update(); + } + } + } + if( olddir != m_part->activeDirectory() ) + { + emit m_part->activeDirectoryChanged( olddir, m_part->activeDirectory() ); + } + + if ( m_activeSubproject == 0 && m_activeTarget == 0 ) + { + m_subprojectView->listView()->setSelected ( m_subprojectView->listView()->firstChild(), true ); + m_subprojectView->listView()->ensureItemVisible ( m_subprojectView->listView()->firstChild() ); + m_subprojectView->listView()->viewport()->update(); + } +} + + +QString AutoProjectWidget::activeDirectory() +{ + if ( m_activeSubproject ) + return m_activeSubproject->path.mid( m_part->projectDirectory().length() + 1 ); + else + { +/* if ( selectedSubproject() ) + return selectedSubproject()->path; + else*/ + return QString::null; + } +} + + +void AutoProjectWidget::addFiles( const QStringList &list ) +{ + QDomDocument &dom = *m_part->projectDom(); + QStringList fileList = list; + + if ( DomUtil::readBoolEntry( dom, "/kdevautoproject/general/useactivetarget" ) ) + { + QStringList::iterator it; + + QString fileName; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + int pos = ( *it ).findRev('/'); + if (pos != -1) + fileName = ( *it ).mid(pos+1); + else + fileName = ( *it ); + + //FileItem * fitem = createFileItem( fileName,m_activeSubproject ); + //m_activeTarget->sources.append( fitem ); + //m_activeTarget->insertItem( fitem ); + + /// @todo Merge with code in addfiledlg.cpp + // Check wether a selected subproject+target exists and matches this file + // If so use that as target. + if( m_detailView->listView()->selectedItem() && m_subprojectView->listView()->selectedItem() ) + { + TargetItem *titem = dynamic_cast ( m_detailView->listView()->selectedItem() ); + SubprojectItem * subitem = dynamic_cast ( m_subprojectView->listView()->selectedItem() ); + QString relativeDir = URLUtil::directory(*it); + SubprojectItem* spitem = subprojectItemForPath(relativeDir); + + if( titem && subitem && subitem == spitem ) + { + addToTarget(fileName, subitem, titem); + }else + { + addToTarget(fileName, m_activeSubproject, m_activeTarget); + } + }else + { + addToTarget(fileName, m_activeSubproject, m_activeTarget); + } + +// QString canontargetname = AutoProjectTool::canonicalize( m_activeTarget->name ); +// QString varname = canontargetname + "_SOURCES"; +// m_activeSubproject->variables[ varname ] += ( " " + fileName ); +// +// QMap replaceMap; +// replaceMap.insert( varname, m_activeSubproject->variables[ varname ] ); +// +// AutoProjectTool::addToMakefileam( m_activeSubproject->path + "/Makefile.am", replaceMap ); + } + + emitAddedFiles ( list ); + } + else + { + QStringList doManually, doneAutomatically; + // First check wether the detail view has a selected target and the subproject + // view selected subproject matches the path of the new file. Then + // we can assume the user used the right-click option on the target + for( QStringList::iterator it = fileList.begin(); it != fileList.end(); ++it) + { + bool autoAdded = false; + if( m_detailView->listView()->selectedItem() && m_subprojectView->listView()->selectedItem() ) + { + TargetItem *titem = dynamic_cast ( m_detailView->listView()->selectedItem() ); + SubprojectItem * subitem = dynamic_cast ( m_subprojectView->listView()->selectedItem() ); + QString relativeDir = URLUtil::directory(*it); + SubprojectItem* spitem = subprojectItemForPath(relativeDir); + if( titem && subitem && subitem == spitem ) + { + addToTarget(URLUtil::filename(*it), subitem, titem); + autoAdded = true; + doneAutomatically << *it; + } + } + if(!autoAdded) doManually << *it; + } + + // See if we can figure out the target for each file without asking the user + // I think it's a valid assumption that if a directory contains only one target + // the file can be added to that target (Julian Rockey linux at jrockey.com) + QStringList temp = doManually; + doManually.clear(); + for(QStringList::iterator it = temp.begin();it!=temp.end();++it) + { + bool autoAdded = false; + QString relativeDir = URLUtil::directory(*it); + SubprojectItem* spitem = subprojectItemForPath(relativeDir); + if (spitem) + { + QPtrList titemList = spitem->targets; + if (titemList.count()==1) { + addToTarget( URLUtil::filename(*it), spitem, titemList.first() ); + doneAutomatically.append(*it); + autoAdded = true; + } + } + + // add to manual list if this file wasn't auto-added + if (!autoAdded) doManually.append(*it); + } + if (doneAutomatically.count()>0) emitAddedFiles(doneAutomatically); + + // raise dialog for any files that weren't added automatically + if (doManually.count()>0) { + ChooseTargetDialog chooseTargetDlg ( this, m_part, doManually, this, "choose target dialog" ); + + //chooseTargetDlg = new ChooseTargetDialog ( this, this, "choose target dialog" ); + + if ( chooseTargetDlg.exec() && chooseTargetDlg.alwaysUseActiveTarget() ) + DomUtil::writeBoolEntry( dom, "/kdevautoproject/general/useactivetarget", true ); + } + } +} + +void AutoProjectWidget::addToTarget(const QString & fileName, SubprojectItem* spitem, TargetItem* titem) +{ + QString varname; + /// \FIXME a quick hack to prevent adding header files to _SOURCES and display them in noinst_HEADERS + if (AutoProjectPrivate::isHeader(fileName) && + ( titem->primary == "PROGRAMS" || titem->primary == "LIBRARIES" || titem->primary == "LTLIBRARIES" ) ) + { + kdDebug ( 9020 ) << "Ignoring header file and adding it to noinst_HEADERS: " << fileName << endl; + TargetItem* noinst_HEADERS_item = getSubprojectView()->findNoinstHeaders(spitem); + FileItem *fitem = createFileItem( fileName, spitem ); + noinst_HEADERS_item->sources.append( fitem ); + noinst_HEADERS_item->insertItem( fitem ); + varname = "noinst_HEADERS"; + } + else + { + FileItem * fitem = createFileItem( fileName, spitem ); + titem->sources.append( fitem ); + titem->insertItem( fitem ); + + QString canontargetname = AutoProjectTool::canonicalize( titem->name ); + varname = canontargetname + "_SOURCES"; + } + spitem->variables[ varname ] += ( " " + fileName ); + + QMap replaceMap; + replaceMap.insert( varname, spitem->variables[ varname ] ); + + AutoProjectTool::addToMakefileam( spitem->path + "/Makefile.am", replaceMap ); + + m_detailView->slotSelectionChanged( spitem ); +} + +void AutoProjectWidget::removeFiles( const QStringList &list ) +{ + Q_UNUSED( list ) +} + +void AutoProjectWidget::slotOverviewSelectionChanged( QListViewItem *item ) +{ + if ( !item ) + return; + + // Delete the items from the details view first. + if ( m_shownSubproject ) + { + // Remove all TargetItems and all of their children from the view + kdDebug ( 9020 ) << "m_shownSubproject (before takeItem()): " << m_shownSubproject->subdir << endl; + + QListViewItem* i = m_detailView->listView()->firstChild(); + while( i ) + { + QListViewItem* o = i; + i = i->nextSibling(); + m_detailView->listView()->takeItem(o); + } + } + + // We assume here that ALL items in the over list view + // are SubprojectItem's + m_shownSubproject = dynamic_cast( item ); + if ( !m_shownSubproject) return; + kdDebug ( 9020 ) << "m_shownSubproject (after takeItem()): " << selectedSubproject()->subdir << endl; + + // Insert all TargetItems and all of their children into the view + QPtrListIterator it2( selectedSubproject()->targets ); + for ( ; it2.current(); ++it2 ) + { + kdDebug ( 9020 ) << "insertItem in detail " << ( *it2 )->name << endl; + m_detailView->listView()->insertItem( *it2 ); + QPtrListIterator it3( ( *it2 ) ->sources ); + for ( ; it3.current(); ++it3 ) + ( *it2 )->insertItem( *it3 ); + QString primary = ( *it2 ) ->primary; + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || + primary == "LTLIBRARIES" || primary == "JAVA" ) + ( *it2 ) ->setOpen( true ); + } +} + +TargetItem *AutoProjectWidget::selectedTarget() +{ + ProjectItem * pvitem = static_cast( m_detailView->listView()->selectedItem() ); + if ( !pvitem || ( pvitem->type() != ProjectItem::Target ) ) + return 0; + + return static_cast( pvitem ); +} + + +FileItem *AutoProjectWidget::selectedFile() +{ + ProjectItem * pvitem = static_cast( m_detailView->listView()->selectedItem() ); + if ( !pvitem || ( pvitem->type() != ProjectItem::File ) ) + return 0; + + return static_cast( pvitem ); +} + +SubprojectItem* AutoProjectWidget::selectedSubproject() +{ + ProjectItem * pvitem = static_cast ( m_subprojectView->listView()->selectedItem() ); + + if ( !pvitem || ( pvitem->type() != ProjectItem::Subproject ) ) + return 0; + + return static_cast ( pvitem ); +} + +TargetItem *AutoProjectWidget::createTargetItem( const QString &name, + const QString &prefix, const QString &primary, + bool take ) +{ + bool docgroup = ( primary == "KDEDOCS" ); + bool icongroup = ( primary == "KDEICON" ); + bool group = !(docgroup || icongroup); + + QString text; + if ( docgroup ) + text = i18n( "Documentation data" ); + else if ( icongroup ) + text = i18n( "KDE Icon data" ).arg( prefix ); + else + text = i18n( "%1 (%2 in %3)" ).arg( name ).arg( nicePrimary( primary ) ).arg( prefix ); + + // Workaround because of QListView not being able to create + // items without actually inserting them + TargetItem *titem = new TargetItem( m_detailView->listView(), group, text ); + titem->name = name; + titem->prefix = prefix; + titem->primary = primary; + if( take ) + m_detailView->listView()->takeItem( titem ); + + return titem; +} + + +FileItem *AutoProjectWidget::createFileItem( const QString &name, SubprojectItem *subproject ) +{ + bool is_subst; + if(name.find("$(") == 0 || name.find("${") == 0) + is_subst = true; + else + is_subst = false; + + FileItem * fitem = new FileItem( m_subprojectView->listView(), name, is_subst ); + fitem->uiFileLink = m_detailView->getUiFileLink(subproject->relativePath()+"/", name ); + m_subprojectView->listView()->takeItem( fitem ); + fitem->name = name; + + return fitem; +} + + +void AutoProjectWidget::emitAddedFiles( const QStringList &fileList ) +{ + emit m_part->addedFilesToProject( fileList ); +} + +void AutoProjectWidget::emitAddedFile( const QString &name ) +{ + QStringList fileList; + fileList.append ( name ); + emit m_part->addedFilesToProject( fileList ); +} + +void AutoProjectWidget::emitRemovedFiles( const QStringList &fileList ) +{ + emit m_part->removedFilesFromProject( fileList ); +} + +void AutoProjectWidget::emitRemovedFile( const QString &name ) +{ + QStringList fileList; + fileList.append ( name ); + emit m_part->removedFilesFromProject( fileList ); +} + +void AutoProjectWidget::restoreSession ( const QDomElement* el ) +{ + Q_UNUSED( el ); +} + +void AutoProjectWidget::saveSession ( QDomElement* el ) +{ + if ( m_activeTarget && m_activeSubproject ) + { + QDomDocument domDoc = el->ownerDocument(); + + QString activeTargetPath = m_activeSubproject->path.mid ( m_part->project()->projectDirectory().length() + 1 ); + activeTargetPath = activeTargetPath + "/" + m_activeTarget->name; + + QDomElement generalEl = domDoc.createElement("general"); + + kdDebug ( 9020 ) << k_funcinfo << "Saving session data of AutoProjectWidget: " << activeTargetPath << endl; + + generalEl.setAttribute("activetarget", activeTargetPath); + el->appendChild(generalEl); + } +} + +void AutoProjectWidget::setActiveSubproject( SubprojectItem * spitem ) +{ + QString olddir = m_part->activeDirectory(); + m_activeSubproject = spitem; + emit m_part->activeDirectoryChanged( olddir, m_part->activeDirectory() ); +} + +void AutoProjectWidget::focusInEvent( QFocusEvent */*e*/ ) +{ + switch (m_lastFocusedView) + { + case DetailsView: + m_detailView->listView()->setFocus(); + break; + case SubprojectView: + default: + m_subprojectView->listView()->setFocus(); + } +} + +void AutoProjectWidget::setLastFocusedView( AutoProjectView view ) +{ + m_lastFocusedView = view; +} + +#include "autoprojectwidget.moc" + +MakefileHandler* AutoProjectWidget::makefileHandler() +{ + return m_makefileHandler; +} +//kate: indent-mode csands; tab-width 4; space-indent off; + diff --git a/buildtools/autotools/autoprojectwidget.h b/buildtools/autotools/autoprojectwidget.h new file mode 100644 index 00000000..0f4a8b13 --- /dev/null +++ b/buildtools/autotools/autoprojectwidget.h @@ -0,0 +1,229 @@ +/* + KDevelop Autotools Support + Copyright (c) 2001-2002 by Bernd Gehrmann + Copyright (c) 2002 by Victor Roeder + Copyright (c) 2005 by Matt Rogers + +*************************************************************************** +* * +* 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. * +* * +*************************************************************************** +*/ + +#ifndef _AUTOPROJECTWIDGET_H_ +#define _AUTOPROJECTWIDGET_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "domutil.h" +#include "makefilehandler.h" + +class AutoProjectPart; +class AutoSubprojectView; +class AutoDetailsView; +class SubprojectItem; +class TargetItem; +class FileItem; +class KAction; +class QDomElement; +class QToolButton; +class QStringList; +class QFocusEvent; +class KListViewItem; +class QListViewItem; +class MakefileHandler; + +class AutoProjectWidget : public QVBox +{ + Q_OBJECT + friend class RemoveFileDialog; + friend class TargetOptionsDialog; // to access projectDom() via m_part->projectDom() +public: + AutoProjectWidget( AutoProjectPart *part, bool kde ); + ~AutoProjectWidget(); + + void openProject( const QString &dirName ); + void closeProject(); + + /** + * A list of the (relative) names of all subprojects (== subdirectories) + */ + QStringList allSubprojects(); + /** + * A list of all Subproject items in the overview KListView + */ + QPtrList allSubprojectItems(); + /** + * A list of the (relative) names of all libraries + */ + QStringList allLibraries(); + /** + * A list of all files that belong to the project + **/ + QStringList allFiles(); + /** + * The top level directory of the project. + **/ + QString projectDirectory() const; + /** + * The directory of the currently shown subproject. + */ + QString subprojectDirectory(); + /** + * Are we in KDE mode? + */ + bool kdeMode() const + { + return m_kdeMode; + } + + /** + * Sets the given target active. The argument is given + * relative to the project directory. + */ + void setActiveTarget( const QString &targetPath ); + /** + * Returns the active target as path relative to + * the project directory. + */ + QString activeDirectory(); + + /** + * Adds a file to the active target. + * If the file does not contain a "/" character, it is added + * to the active target. + * If it does contain "/" character(s), ... @todo .. add to appropriate target + */ + void addFiles( const QStringList &list ); + /** + * Removes the file fileName from the directory directory. + * (not implemented currently) + */ + void removeFiles( const QStringList &list ); + + /** + * Returns the currently selected target. Returns 0 if + * no target is selected. + */ + TargetItem *selectedTarget(); + + /** + * Returns the currently selected file. Returns 0 if + * no file is selected. + */ + FileItem *selectedFile(); + + /** + * Returns the currently selected subproject (directory with Makefile.am). Returns 0 if + * no subproject is selected. + */ + SubprojectItem* selectedSubproject(); + + /** + * Creates a TargetItem instance without a parent item. + */ + TargetItem *createTargetItem( const QString &name, + const QString &prefix, const QString &primary, + bool take = true ); + /** + * Creates a FileItem instance without a parent item. + */ + FileItem *createFileItem( const QString &name, SubprojectItem *subproject ); + + /** + * Returns the Subproject that contains the Active Target. The Active Target is a special target + * to which e.g. all files are added to. + */ + SubprojectItem* activeSubproject (); + void setActiveSubproject( SubprojectItem* spitem ); + + /** + * Returns the Active Target. The Active Target is a special target + * to which e.g. all files are added to. + */ + TargetItem* activeTarget(); + + /** + * Returns the sub project item, if any, for a given path. The path supplied can be either + * absolute, or relative to the project directory. If no subproject item is found for the + * path, null is returned. + */ + SubprojectItem* subprojectItemForPath( const QString & path, bool pathIsAbsolute = false ); + + /** + * Returns the projectdir-relative path for a target item + */ + QString pathForTarget( const TargetItem *item ) const; + + /** + * Adds file fileName to target titem in subproject spitem + */ + void addToTarget( const QString & fileName, SubprojectItem* spitem, TargetItem* titem ); + + /** + * Restores the last settings of the AutoProjectWidget + */ + void restoreSession ( const QDomElement* el ); + + /** + * Saves the latest changes of the AutoProjectWidget to the session file. + */ + void saveSession ( QDomElement* el ); + + AutoSubprojectView* getSubprojectView (); + AutoDetailsView* getDetailsView (); + + + void emitAddedFile ( const QString& name ); + void emitAddedFiles( const QStringList &fileList ); + void emitRemovedFile ( const QString& name ); + void emitRemovedFiles( const QStringList &fileList ); + + void parse( SubprojectItem *item ); + + enum AutoProjectView { SubprojectView, DetailsView }; + void setLastFocusedView( AutoProjectView view ); + + MakefileHandler* makefileHandler(); + +public slots: + void slotOverviewSelectionChanged( QListViewItem *item ); + +protected: + void initOverview ( QWidget* parent ); + void initDetailview ( QWidget* parent ); + void initActions (); + + virtual void focusInEvent( QFocusEvent *e ); + +private: + + AutoSubprojectView* m_subprojectView; + AutoDetailsView* m_detailView; + + bool m_kdeMode; + AutoProjectPart *m_part; + SubprojectItem *m_activeSubproject; + TargetItem *m_activeTarget; + TargetItem *m_choosenTarget; + SubprojectItem *m_shownSubproject; + + AutoProjectView m_lastFocusedView; + + MakefileHandler *m_makefileHandler; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autosubprojectview.cpp b/buildtools/autotools/autosubprojectview.cpp new file mode 100644 index 00000000..efa3a358 --- /dev/null +++ b/buildtools/autotools/autosubprojectview.cpp @@ -0,0 +1,1137 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder + Copyright (c) 2005 by Matt Rogers + + *************************************************************************** + * * + * 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. * + * * + *************************************************************************** +*/ + +/** Qt */ +#include +#include +#include +#include +#include + +/** KDE Libs */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** KDevelop */ +#include +#include +#include +#include +#include + +/** AutoProject */ +#include "subprojectoptionsdlg.h" +#include "addsubprojectdlg.h" +#include "addtargetdlg.h" +#include "addservicedlg.h" +#include "addapplicationdlg.h" +#include "addexistingdirectoriesdlg.h" +#include "autolistviewitems.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" +#include "autosubprojectview.h" +#include "autotoolsaction.h" +#include "removesubprojectdialog.h" +#include "managecustomcommand.h" + +namespace AutoProjectPrivate +{ + +bool isHeader( const QString& fileName ) +{ + return QStringList::split( ";", "h;H;hh;hxx;hpp;tcc;h++" ).contains( QFileInfo(fileName).extension(false) ); +} + +static QString cleanWhitespace( const QString &str ) +{ + QString res; + + QStringList l = QStringList::split( QRegExp( "[ \t]" ), str ); + QStringList::ConstIterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + res += *it; + res += " "; + } + + return res.left( res.length() - 1 ); +} + +static void removeDir( const QString& dirName ) +{ + QDir d( dirName ); + const QFileInfoList* fileList = d.entryInfoList(); + if( !fileList ) + return; + + QFileInfoListIterator it( *fileList ); + while( it.current() ){ + const QFileInfo* fileInfo = it.current(); + ++it; + + if( fileInfo->fileName() == "." || fileInfo->fileName() == ".." ) + continue; + + if( fileInfo->isDir() && !fileInfo->isSymLink() ) + removeDir( fileInfo->absFilePath() ); + + kdDebug(9020) << "remove " << fileInfo->absFilePath() << endl; + d.remove( fileInfo->fileName(), false ); + } + + kdDebug(9020) << "remove dir " << dirName << endl; + d.rmdir( d.absPath(), true ); +} + +} + + +AutoSubprojectView::AutoSubprojectView(AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name) +: AutoProjectViewBase(parent, name) +{ + + m_widget = widget; + m_part = part; + + m_listView->setSorting(-1); + m_listView->header()->hide(); + m_listView->addColumn( QString::null ); + + connect( m_listView, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotSelectionChanged( QListViewItem* ) ) ); + + initActions(); +} + + +AutoSubprojectView::~AutoSubprojectView() +{ +} + +void AutoSubprojectView::slotSelectionChanged( QListViewItem* item ) +{ + if ( m_listView->selectedItems().count() <= 0 ) + { + subProjectOptionsAction->setEnabled( false ); + addSubprojectAction->setEnabled( false ); + addTargetAction->setEnabled( false ); + addServiceAction->setEnabled( false ); + addApplicationAction->setEnabled( false ); + buildSubprojectAction->setEnabled( false ); + } + else + { + subProjectOptionsAction->setEnabled( true ); + addSubprojectAction->setEnabled( true ); + addTargetAction->setEnabled( true ); + addServiceAction->setEnabled( true ); + addApplicationAction->setEnabled( true ); + buildSubprojectAction->setEnabled( true ); + } + + emit selectionChanged( item ); +} + +void AutoSubprojectView::loadMakefileams ( const QString& dir ) +{ + SubprojectItem * item = new SubprojectItem( m_listView, m_part->projectName() ); + item->setPixmap ( 0, SmallIcon ( "kdevelop" ) ); + item->subdir = "/"; + item->path = dir; + parse( item ); + item->setOpen( true ); + + //setSelected( item, true ); + + expandCollapseFirst( m_listView->firstChild(), false ); +} + + +void AutoSubprojectView::initActions() +{ + KActionCollection * actions = new KActionCollection( this ); + + subProjectOptionsAction = new AutoToolsAction( i18n( "Options..." ), "configure", 0, + this, SLOT( slotSubprojectOptions() ), actions, "subproject options" ); + subProjectOptionsAction->setWhatsThis(i18n("Options

Shows subproject options dialog " + "that provides settings for compiler, include paths, " + "prefixes and build order.")); + subProjectOptionsAction->plug( m_optionsButton ); + + QToolTip::add( m_button1, tr2i18n( "Add new subproject...")); + addSubprojectAction = new AutoToolsAction( i18n( "Add new subproject..." ), "folder_new", 0, + this, SLOT( slotAddSubproject() ), actions, "add subproject" ); + addSubprojectAction->setWhatsThis(i18n("Add new subproject

Creates a new " + "subproject in currently selected subproject.")); + addSubprojectAction->plug( m_button1 ); + + removeSubprojectAction = new KAction( i18n( "Remove Subproject..." ), "remove_subdir", 0, + this, SLOT( slotRemoveSubproject() ), actions, "remove subproject" ); + removeSubprojectAction->setWhatsThis(i18n("Remove subproject

Removes the subproject. Asks if the " + "subproject should be also removed from disk. Only subprojects " + "which do not hold other subprojects can be removed.")); + addExistingSubprojectAction = new KAction( i18n( "Add Existing Subprojects..." ), "fileimport", 0, + this, SLOT( slotAddExistingSubproject() ), actions, "add existing subproject" ); + addExistingSubprojectAction->setWhatsThis(i18n("Add existing subprojects

Imports existing " + "subprojects containing Makefile.am.")); + + QToolTip::add( m_button2, tr2i18n( "Add Target...")); + addTargetAction = new AutoToolsAction( i18n( "Add Target..." ), "targetnew_kdevelop", 0, + this, SLOT( slotAddTarget() ), actions, "add target" ); + addTargetAction->setWhatsThis(i18n( "Add target

Adds a new target to " + "the currently selected subproject. Target can be a " + "binary program, library, script, also a collection of " + "data or header files.")); + addTargetAction->plug( m_button2 ); + + QToolTip::add( m_button3, tr2i18n( "Add Service...")); + addServiceAction = new AutoToolsAction( i18n( "Add Service..." ), "servicenew_kdevelop", 0, this, + SLOT( slotAddService() ), actions, "add service" ); + addServiceAction->setWhatsThis(i18n("Add service

Creates a .desktop file describing the service.")); + addServiceAction->plug( m_button3 ); + + QToolTip::add( m_button4, tr2i18n( "Add Application...")); + addApplicationAction = new AutoToolsAction( i18n( "Add Application..." ), "window_new", 0, this, + SLOT( slotAddApplication() ), actions, "add application" ); + addApplicationAction->setWhatsThis(i18n("Add application

Creates an application .desktop file.")); + addApplicationAction->plug( m_button4 ); + + QToolTip::add( m_button5, tr2i18n( "Build")); + buildSubprojectAction = new AutoToolsAction( i18n( "Build" ), "launch", 0, this, + SLOT( slotBuildSubproject() ), actions, "build subproject" ); + buildSubprojectAction->setWhatsThis(i18n("Build

Runs make from the directory of " + "the selected subproject.
Environment variables and " + "make arguments can be specified in the project settings " + "dialog, Make Options tab.")); + buildSubprojectAction->plug( m_button5 ); + + forceReeditSubprojectAction = new KAction( i18n( "Force Reedit" ), 0, 0, this, + SLOT( slotForceReeditSubproject() ), actions, "force-reedit subproject" ); + forceReeditSubprojectAction->setWhatsThis(i18n("Force Reedit

Runs make force-reedit " + "from the directory of the selected subproject.
This " + "recreates makefile (tip: and solves most of .moc related " + "problems)
Environment variables and make arguments can " + "be specified in the project settings dialog, " + "Make Options tab.")); + + if (!m_part->isKDE()) + forceReeditSubprojectAction->setEnabled(false); + + cleanSubprojectAction = new KAction( i18n( "Clean" ), 0, 0, this, + SLOT( slotCleanSubproject() ), actions, "clean subproject" ); + cleanSubprojectAction->setWhatsThis(i18n("Clean

Runs make clean from the directory of " + "the selected subproject.
Environment variables and make " + "arguments can be specified in the project settings dialog, " + "Make Options tab.")); + + installSubprojectAction = new KAction( i18n( "Install" ), 0, 0, this, + SLOT( slotInstallSubproject() ), actions, "install subproject" ); + installSubprojectAction->setWhatsThis(i18n("Install

Runs make install from the directory " + "of the selected subproject.
Environment variables and " + "make arguments can be specified in the project settings " + "dialog, Make Options tab.")); + installSuSubprojectAction = new KAction( i18n( "Install (as root user)" ), 0, 0, + this, SLOT( slotInstallSuSubproject() ), actions, "install subproject as root" ); + installSuSubprojectAction->setWhatsThis(i18n("Install as root user

Runs make install " + "command from the directory of the selected subproject " + "with root privileges.
It is executed via kdesu " + "command.
Environment variables and make arguments " + "can be specified in the project settings dialog, " + "Make Options tab.")); + + expandAction = new KAction( i18n( "Expand Subtree" ), 0, 0, this, + SLOT(slotExpandTree()), actions, "expandAction" ); + collapseAction = new KAction( i18n( "Collapse Subtree" ), 0, 0, this, + SLOT(slotCollapseTree()), actions, "collapseAction" ); + + otherAction = new KAction( i18n( "Manage Custom Commands..." ), 0, 0, this, + SLOT( slotManageBuildCommands() ), actions, "manage custom commands" ); + otherAction->setWhatsThis(i18n("Manage custom commands

Allows to create, edit and " + "delete custom build commands which appears in the subproject " + "context menu.
")); + + connect( m_listView, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); +} + +void AutoSubprojectView::slotContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return ; + + KPopupMenu popup( i18n( "Subproject: %1" ).arg( item->text( 0 ) ), this ); + + subProjectOptionsAction->plug( &popup ); + popup.insertSeparator(); + addSubprojectAction->plug( &popup ); + addTargetAction->plug( &popup ); + addServiceAction->plug( &popup ); + addApplicationAction->plug( &popup ); + popup.insertSeparator(); + addExistingSubprojectAction->plug( &popup ); + popup.insertSeparator(); + removeSubprojectAction->plug( &popup ); + popup.insertSeparator(); + buildSubprojectAction->plug( &popup ); + popup.insertSeparator(); + forceReeditSubprojectAction->plug( &popup ); + cleanSubprojectAction->plug( &popup ); + popup.insertSeparator(); + installSubprojectAction->plug( &popup ); + installSuSubprojectAction->plug( &popup ); + popup.insertSeparator(); + collapseAction->plug( &popup ); + expandAction->plug( &popup ); + + KConfig *config = m_part->instance()->config(); + bool separate = true; + QMap customBuildCommands = config->entryMap("CustomCommands"); + for (QMap::const_iterator it = customBuildCommands.constBegin(); + it != customBuildCommands.constEnd(); ++it) + { + if (separate) + { + popup.insertSeparator(); + separate = false; + } + int id = popup.insertItem(it.key(), this, SLOT(slotCustomBuildCommand(int))); + m_commandList.append(it.data()); + popup.setItemParameter(id, m_commandList.findIndex(it.data())); + } + + popup.insertSeparator(); + otherAction->plug( &popup ); + + KURL::List urls; + urls.append(m_widget->selectedSubproject()->path); + FileContext context(urls); + m_part->core()->fillContextMenu( &popup, &context ); + + popup.exec( p ); +} + +void AutoSubprojectView::slotSubprojectOptions() +{ + kdDebug( 9020 ) << "AutoSubprojectView::slotSubprojectOptions()" << endl; + + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + SubprojectOptionsDialog dlg( m_part, m_widget, spitem, this, "subproject options dialog" ); + dlg.exec(); +} + + +void AutoSubprojectView::slotAddSubproject() +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddSubprojectDialog dlg( m_part, this, spitem, this, "add subproject dialog" ); + + dlg.setCaption ( i18n ( "Add New Subproject to '%1'" ).arg ( spitem->subdir ) ); + dlg.exec(); +} + + +void AutoSubprojectView::slotAddExistingSubproject() +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddExistingDirectoriesDialog dlg ( m_part, m_widget, spitem, this, "add existing subprojects" ); + + dlg.setCaption ( i18n ( "Add Existing Subproject to '%1'" ).arg ( spitem->subdir ) ); + dlg.targetLabel->setText(""); + dlg.directoryLabel->setText(spitem->path); + + if ( dlg.exec() ) + emit selectionChanged ( spitem ); +} + +void AutoSubprojectView::slotAddTarget() +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddTargetDialog dlg( m_widget, spitem, this, "add target dialog" ); + + dlg.setCaption ( i18n ( "Add New Target to '%1'" ).arg ( spitem->subdir ) ); + + // Update the details view if a target was added + if ( dlg.exec() ) + emit selectionChanged( spitem ); +} + + +void AutoSubprojectView::slotAddService() +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddServiceDialog dlg( m_widget, spitem, this, "add service dialog" ); + + dlg.setCaption ( i18n ( "Add New Service to '%1'" ).arg ( spitem->subdir ) ); + + // Update the details view if a service was added + if ( dlg.exec() ) + emit selectionChanged( spitem ); +} + + +void AutoSubprojectView::slotAddApplication() +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + AddApplicationDialog dlg( m_widget, spitem, this, "add application dialog" ); + + dlg.setCaption ( i18n ( "Add New Application to '%1'" ).arg ( spitem->subdir ) ); + + // Update the details view if an application was added + if ( dlg.exec() ) + emit selectionChanged( spitem ); +} + + +void AutoSubprojectView::slotBuildSubproject() +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, QString::fromLatin1( "" ) ); +} + +void AutoSubprojectView::slotRemoveSubproject() +{ + kdDebug(9020) << "AutoSubprojectView::slotRemoveSubproject()" << endl; + + SubprojectItem* spitem = static_cast( m_listView->selectedItem() ); + if( !spitem ) + return; + + SubprojectItem* parent = static_cast( spitem->parent() ); + if( !parent || !parent->listView() || spitem->childCount() != 0 ){ + KMessageBox::error( 0, i18n("This item cannot be removed"), i18n("Automake Manager") ); + return; + } + + QStringList list = QStringList::split( QRegExp("[ \t]"), parent->variables["SUBDIRS"] ); + QStringList::Iterator it = list.find( spitem->subdir ); + QString subdirToRemove = spitem->subdir; + bool topsubdirs = true; + if ((parent->variables["SUBDIRS"].find("$(TOPSUBDIRS)") == -1) + && (parent->variables["SUBDIRS"].find("$(AUTODIRS)") == -1)) + { + topsubdirs = false; + if( it == list.end() ){ + KMessageBox::sorry(this, i18n("There is no subproject %1 in SUBDIRS").arg(spitem->subdir)); + return; + } + } + + RemoveSubprojectDialog dlg(i18n("Remove Subproject %1").arg(spitem->text(0)), + i18n("Do you really want to remove subproject %1 with all targets and files?").arg(spitem->text(0))); + if( dlg.exec() ){ + + bool removeSources = dlg.removeFromDisk(); + + if (!topsubdirs) + { + list.remove( it ); + parent->variables[ "SUBDIRS" ] = list.join( " " ); + } + + parent->listView()->setSelected( parent, true ); + kapp->processEvents( 500 ); + + + if( removeSources ){ + kdDebug(9020) << "remove dir " << spitem->path << endl; + AutoProjectPrivate::removeDir( spitem->path ); + } + + if( m_widget->activeSubproject() == spitem ){ + m_widget->setActiveSubproject( 0 ); + } + + // Adjust AC_OUTPUT in configure.in + if ( !m_part->isKDE() ) { + + QString projroot = m_part->projectDirectory() + "/"; + QString subdirectory = spitem->path; + QString relpath = subdirectory.replace(0, projroot.length(),""); + + QString configureFile = m_part->getAutoConfFile(projroot); + + QStringList list = AutoProjectTool::configureinLoadMakefiles(configureFile); + + QStringList::iterator it; + + for ( it = list.begin(); it != list.end(); it++ ) { + QString current = (QString) (*it); + QRegExp path_regex(relpath); + if ( path_regex.search(current) >= 0) { + list.remove(it); + break; + } + } + AutoProjectTool::configureinSaveMakefiles(configureFile, list); + + } + + // remove all targets + spitem->targets.setAutoDelete( true ); + spitem->targets.clear(); + delete( spitem ); + spitem = 0; + + // Adjust SUBDIRS variable in containing Makefile.am + + if (parent->variables["SUBDIRS"].find("$(TOPSUBDIRS)") != -1) + { + QFile subdirsfile( parent->path + "/subdirs" ); + QStringList topdirs; + if ( subdirsfile.open( IO_ReadOnly ) ) + { + QTextStream subdirsstream( &subdirsfile ); + while (!subdirsstream.atEnd()) + topdirs.append(subdirsstream.readLine()); + subdirsfile.close(); + } + topdirs.remove(subdirToRemove); + if ( subdirsfile.open( IO_WriteOnly | IO_Truncate ) ) + { + QTextStream subdirsstream( &subdirsfile ); + for (QStringList::const_iterator it = topdirs.begin(); it != topdirs.end(); ++it) + subdirsstream << *it << endl; + subdirsfile.close(); + } + } + + QMap replaceMap; + replaceMap.insert( "SUBDIRS", subdirToRemove ); + AutoProjectTool::removeFromMakefileam( parent->path + "/Makefile.am", replaceMap ); + + QString relmakefile = ( parent->path + "/Makefile" ).mid( m_part->projectDirectory().length()+1 ); + kdDebug(9020) << "Relative makefile path: " << relmakefile << endl; + + // check for config.status + if( !QFileInfo(m_part->buildDirectory(), "config.status").exists() ){ + return; + } + + QString cmdline = "cd "; + cmdline += KProcess::quote(m_part->projectDirectory()); + cmdline += " && automake "; + cmdline += KProcess::quote(relmakefile); + cmdline += " && cd "; + cmdline += KProcess::quote(m_part->buildDirectory()); + cmdline += " && CONFIG_HEADERS=config.h CONFIG_FILES="; + cmdline += KProcess::quote(relmakefile); + cmdline += " ./config.status"; + m_part->makeFrontend()->queueCommand( m_part->projectDirectory(), cmdline ); + } +} + + +void AutoSubprojectView::parsePrimary( SubprojectItem *item, + const QString &lhs, const QString &rhs ) +{ + // Parse line foo_bar = bla bla + + int pos = lhs.findRev( '_' ); + QString prefix = lhs.left( pos ); + QString primary = lhs.right( lhs.length() - pos - 1 ); + // kdDebug(9020) << "Prefix:" << prefix << ",Primary:" << primary << endl; + + +#if 0 + + QStrList prefixes; + prefixes.append( "bin" ); + prefixes.append( "pkglib" ); + prefixes.append( "pkgdata" ); + prefixes.append( "noinst" ); + prefixes.append( "check" ); + prefixes.append( "sbin" ); + QStrList primaries; + primaries.append( "PROGRAMS" ); + primaries.append( "LIBRARIES" ); + primaries.append( "LTLIBRARIES" ); + primaries.append( "SCRIPTS" ); + primaries.append( "HEADERS" ); + primaries.append( "DATA" ); +#endif + + // Not all combinations prefix/primary are possible, so this + // could also be checked... not trivial because the list of + // possible prefixes can be extended dynamically (see below) + if ( primary == "PROGRAMS" || primary == "LIBRARIES" || primary == "LTLIBRARIES" ) + { + QStringList l = QStringList::split( QRegExp( "[ \t\n]" ), rhs ); + QStringList::Iterator it1; + for ( it1 = l.begin(); it1 != l.end(); ++it1 ) + { + TargetItem *titem = m_widget->createTargetItem( *it1, prefix, primary ); + item->targets.append( titem ); + + QString canonname = AutoProjectTool::canonicalize( *it1 ); + titem->ldflags = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LDFLAGS" ] ); + titem->ldadd = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LDADD" ] ); + titem->libadd = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_LIBADD" ] ); + titem->dependencies = AutoProjectPrivate::cleanWhitespace( item->variables[ canonname + "_DEPENDENCIES" ] ); + + QString sources = item->variables[ canonname + "_SOURCES" ]; + QStringList sourceList = QStringList::split( QRegExp( "[ \t\n]" ), sources ); + QMap dict; + QStringList::Iterator it = sourceList.begin(); + while( it != sourceList.end() ){ + dict.insert( *it, true ); + ++it; + } + + QMap::Iterator dictIt = dict.begin(); + while( dictIt != dict.end() ){ + QString fname = dictIt.key(); + ++dictIt; + + FileItem *fitem = m_widget->createFileItem( fname, item ); + titem->sources.append( fitem ); + + if( AutoProjectPrivate::isHeader(fname) ) + headers += fname; + } + } + } + else if ( primary == "SCRIPTS" || primary == "HEADERS" || primary == "DATA" ) + { + // See if we have already such a group + for ( uint i = 0; i < item->targets.count(); ++i ) + { + TargetItem *titem = item->targets.at( i ); + if ( primary == titem->primary && prefix == titem->prefix ) + { + item->targets.remove( i ); + break; + } + } + // Create a new one + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + QStringList l = QStringList::split( QRegExp( "[ \t]" ), rhs ); + QStringList::Iterator it3; + for ( it3 = l.begin(); it3 != l.end(); ++it3 ) + { + QString fname = *it3; + FileItem *fitem = m_widget->createFileItem( fname, item ); + titem->sources.append( fitem ); + + if( AutoProjectPrivate::isHeader(fname) ) + headers += fname; + + } + } + else if ( primary == "JAVA" ) + { + QStringList l = QStringList::split( QRegExp( "[ \t\n]" ), rhs ); + QStringList::Iterator it1; + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + for ( it1 = l.begin(); it1 != l.end(); ++it1 ) + { + FileItem *fitem = m_widget->createFileItem( *it1, item ); + titem->sources.append( fitem ); + } + } +} + + +void AutoSubprojectView::parseKDEDOCS( SubprojectItem *item, + const QString & /*lhs*/, const QString & /*rhs*/ ) +{ + // Handle the line KDE_ICON = + // (actually, no parsing is involved here) + + QString prefix = "kde_docs"; + QString primary = "KDEDOCS"; + + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + QDir d( item->path ); + QStringList l = d.entryList( QDir::Files ); + + QRegExp re( "Makefile.*|\\..*|.*~|index.cache.bz2" ); + + QStringList::ConstIterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + if ( !re.exactMatch( *it ) ) + { + QString fname = *it; + FileItem * fitem = m_widget->createFileItem( fname, item ); + titem->sources.append( fitem ); + } + } +} + + +void AutoSubprojectView::parseKDEICON( SubprojectItem *item, + const QString &lhs, const QString &rhs ) +{ + // Parse a line foo_ICON = bla bla + + int pos = lhs.find( "_ICON" ); + QString prefix = lhs.left( pos ); + if ( prefix == "KDE" ) + prefix = "kde_icon"; + + QString primary = "KDEICON"; + + TargetItem *titem = m_widget->createTargetItem( "", prefix, primary ); + item->targets.append( titem ); + + QDir d( item->path ); + QStringList l = d.entryList( QDir::Files ); + + QString regexp; + + if ( rhs == "AUTO" ) + { + regexp = ".*\\.(png|mng|xpm)"; + } + else + { + QStringList appNames = QStringList::split( QRegExp( "[ \t\n]" ), rhs ); + regexp = ".*(-" + appNames.join( "|-" ) + ")\\.(png|mng|xpm)"; + } + + QRegExp re( regexp ); + + QStringList::ConstIterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + if ( re.exactMatch( *it ) ) + { + FileItem * fitem = m_widget->createFileItem( *it, item ); + titem->sources.append( fitem ); + } + } +} + + +void AutoSubprojectView::parsePrefix( SubprojectItem *item, + const QString &lhs, const QString &rhs ) +{ + // Parse a line foodir = bla bla + QString name = lhs.left( lhs.length() - 3 ); + QString dir = rhs; + item->prefixes.insert( name, dir ); +} + + +void AutoSubprojectView::parseSUBDIRS( SubprojectItem *item, + const QString & /*lhs*/, const QString &rhs ) +{ + // Parse a line SUBDIRS = bla bla + QString subdirs = rhs; + kdDebug( 9020 ) << "subdirs are " << subdirs << endl; + + // Take care of KDE hacks: + // TOPSUBDIRS is an alias for all directories + // listed in the subdirs file + if ( subdirs.find( "$(TOPSUBDIRS)" ) != -1 ) + { + QStringList dirs; + QFile subdirsfile( item->path + "/subdirs" ); + if( subdirsfile.exists() ) + { + if ( subdirsfile.open( IO_ReadOnly ) ) + { + QTextStream subdirsstream( &subdirsfile ); + while ( !subdirsstream.atEnd() ) + dirs.append( subdirsstream.readLine() ); + subdirsfile.close(); + } + } else + { + QDir d( item->path ); + QStringList l = d.entryList( QDir::Dirs ); + for( QStringList::const_iterator it = l.begin(); it != l.end(); ++it ) + { + if( (*it) != "CVS" && (*it) != "admin" && (*it) != ".svn" && (*it) != "." && (*it) != ".." ) + { + QDir subdir = d; + subdir.cd( *it, false ); + if( subdir.exists( "Makefile.am" ) ) + dirs.append( *it ); + } + } + + } + subdirs.replace( QRegExp( "\\$\\(TOPSUBDIRS\\)" ), dirs.join( " " ) ); + } + + // AUTODIRS is an alias for all subdirectories + if ( subdirs.find( "$(AUTODIRS)" ) != -1 ) + { + QDir d( item->path ); + QStringList dirs = d.entryList( QDir::Dirs ); + dirs.remove( "." ); + dirs.remove( ".." ); + dirs.remove( "CVS" ); + subdirs.replace( QRegExp( "\\$\\(AUTODIRS\\)" ), dirs.join( " " ) ); + } + + // If there are any variables in the subdirs line then search + // the Makefile(.am?) for its definition. Unfortunately, it may be + // defined outside this file in which case those dirs won't be added. + QRegExp varre( "\\$\\(\\s*(.*)\\s*\\)" ); + varre.setMinimal( true ); + while ( varre.search( subdirs ) != -1 ) + { + QString varname = varre.cap( 1 ); + QString varvalue; + + // Search the whole Makefile(.am?) + // Note that if the variable isn't found it just disappears + // (Perhaps we should add it back in this case?) + QMap::ConstIterator varit = item->variables.find( varname ); + if ( varit != item->variables.end() ) + { + kdDebug( 9020 ) << "Found Makefile var " << varname << ", adding dirs <" << varit.data() << ">" << endl; + varvalue = varit.data(); + } + else + { + kdDebug( 9020 ) << "Not found Makefile var " << varname << endl; + } + subdirs.replace( QRegExp( "\\$\\(\\s*" + varname + "\\s*\\)" ), varvalue ); + } + + //search for AC_SUBST variables and try to replace them with variables + //that have been already defined e.g. in a "kdevelop hint" + varre = QRegExp( "\\@(.*)\\@" ); + varre.setMinimal( true ); + while ( varre.search( subdirs ) != -1 ) + { + QString varname = varre.cap( 1 ); + QString varvalue; + + // Search the whole Makefile(.am?) + // Note that if the variable isn't found it just disappears + // (Perhaps we should add it back in this case?) + QMap::ConstIterator varit = item->variables.find( varname ); + if ( varit != item->variables.end() ) + { + kdDebug( 9020 ) << "Found Makefile var " << varname << ", adding dirs <" << varit.data() << ">" << endl; + varvalue = varit.data(); + } + else + { + kdDebug( 9020 ) << "Not found Makefile var " << varname << endl; + } + subdirs.replace( QRegExp( "\\@" + varname + "\\@" ), varvalue ); + } + + QStringList l = QStringList::split( QRegExp( "[ \t]" ), subdirs ); + l.sort(); + QStringList::Iterator it; + for ( it = l.begin(); it != l.end(); ++it ) + { + if ( *it == "." ) + continue; + SubprojectItem *newitem = new SubprojectItem( item, ( *it ) ); + newitem->subdir = ( *it ); + newitem->path = item->path + "/" + ( *it ); + parse( newitem ); + // Experience tells me this :-) + bool open = true; + if ( newitem->subdir == "doc" ) + open = false; + if ( newitem->subdir == "po" ) + open = false; + if ( newitem->subdir == "pics" ) + open = false; + if ( newitem && static_cast( newitem->parent() ) + ->subdir == "doc" ) + open = false; + if ( newitem && static_cast + ( newitem->parent() ) ->subdir == "po" ) + open = false; + if ( newitem && static_cast + ( newitem->parent() ) ->subdir == "pics" ) + open = false; + newitem->setOpen( open ); + + // Move to the bottom of the list + QListViewItem *lastItem = item->firstChild(); + while ( lastItem->nextSibling() + ) + lastItem = lastItem->nextSibling(); + if ( lastItem != newitem ) + newitem->moveItem( lastItem ); + } +} + +void AutoSubprojectView::parse( SubprojectItem *item ) +{ + headers.clear(); + AutoProjectTool::parseMakefileam( item->path + "/Makefile.am", &item->variables ); + + QMap::ConstIterator it; + for ( it = item->variables.begin(); it != item->variables.end(); ++it ) + { + QString lhs = it.key(); + QString rhs = it.data(); + if ( lhs == "KDE_DOCS" ) + parseKDEDOCS( item, lhs, rhs ); + else if ( lhs.right( 5 ) == "_ICON" ) + parseKDEICON( item, lhs, rhs ); + else if ( lhs.find( '_' ) > 0 ) + parsePrimary( item, lhs, rhs ); + else if ( lhs.right( 3 ) == "dir" ) + parsePrefix( item, lhs, rhs ); + else if ( lhs == "SUBDIRS" ) + parseSUBDIRS( item, lhs, rhs ); + } + + /// @todo only if in a c++ project + TargetItem* noinst_HEADERS_item = findNoinstHeaders(item); + + QDir dir( item->path ); + QStringList headersList = QStringList::split( QRegExp("[ \t]"), item->variables[ "noinst_HEADERS" ] ); + + headersList += dir.entryList( "*.h;*.H;*.hh;*.hxx;*.hpp;*.tcc", QDir::Files ); + headersList.sort(); + headersList = QStringList::split(QRegExp("[ \t]"), headersList.join( " " )); + + QStringList::Iterator fileIt = headersList.begin(); + while( fileIt != headersList.end() ){ + QString fname = *fileIt; + ++fileIt; + + if( AutoProjectPrivate::isHeader(fname) && !headers.contains(fname) ){ + FileItem *fitem = m_widget->createFileItem( fname, item ); + noinst_HEADERS_item->sources.append( fitem ); + } + } +} + +void AutoSubprojectView::slotForceReeditSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast ( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "force-reedit" ); +} + +void AutoSubprojectView::slotInstallSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "install" ); +} + +void AutoSubprojectView::slotInstallSuSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "install", true ); +} + +TargetItem * AutoSubprojectView::findNoinstHeaders( SubprojectItem *item ) +{ + TargetItem* noinst_HEADERS_item = 0; + QPtrListIterator itemIt( item->targets ); + while( itemIt.current() ){ + TargetItem* titem = itemIt.current(); + ++itemIt; + + if( titem->prefix == "noinst" && titem->primary == "HEADERS" ){ + noinst_HEADERS_item = titem; + break; + } + } + + if( !noinst_HEADERS_item ){ + noinst_HEADERS_item = m_widget->createTargetItem( "", "noinst", "HEADERS" ); + item->targets.append( noinst_HEADERS_item ); + } + + return noinst_HEADERS_item; +} + +void AutoSubprojectView::slotCleanSubproject( ) +{ + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + + m_part->startMakeCommand( m_part->buildDirectory() + relpath, "clean" ); +} + +void AutoSubprojectView::focusOutEvent( QFocusEvent */* e*/ ) +{ + m_widget->setLastFocusedView(AutoProjectWidget::SubprojectView); +} + +void AutoSubprojectView::slotManageBuildCommands( ) +{ + KConfig *config = m_part->instance()->config(); + //menu item name <-> command + QMap customBuildCommands = config->entryMap("CustomCommands"); + + KDialogBase dlg(KDialogBase::Plain, i18n("Manage Custom Commands"), KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok); + dlg.plainPage()->setMargin(0); + (new QVBoxLayout(dlg.plainPage(), 0, 0))->setAutoAdd(true); + + ManageCustomCommand *widget = new ManageCustomCommand(dlg.plainPage()); + + for (QMap::const_iterator it = customBuildCommands.constBegin(); + it != customBuildCommands.constEnd(); ++it) + { + widget->commandsTable->insertRows(widget->commandsTable->numRows()); + widget->setRowProperties(widget->commandsTable->numRows()-1); + widget->commandsTable->setText(widget->commandsTable->numRows() - 1, 0, it.key()); + widget->commandsTable->setText(widget->commandsTable->numRows() - 1, 1, + it.data().section(":::", 0, 0)); + static_cast(widget->commandsTable-> + item(widget->commandsTable->numRows() - 1, 2))-> + setCurrentItem(it.data().section(":::", 1, 1).toInt()); + } + + widget->commandsTable->setFocus(); + if (dlg.exec() == QDialog::Accepted) + { + config->deleteGroup("CustomCommands"); + config->setGroup("CustomCommands"); + for (int i = 0; i < widget->commandsTable->numRows(); ++i) + { + config->writeEntry(widget->commandsTable->text(i, 0), + widget->commandsTable->text(i, 1)+":::"+ + QString("%1").arg(static_cast(widget-> + commandsTable->item(i, 2))->currentItem())); + } + config->sync(); + } + +} + +void AutoSubprojectView::slotCustomBuildCommand(int val) +{ + QString cmd = m_commandList[val].section(":::", 0, 0); + int type = m_commandList[val].section(":::", 1, 1).toInt(); + + SubprojectItem* spitem = dynamic_cast( m_listView->selectedItem() ); + if ( !spitem ) return; + + QString relpath = "/" + URLUtil::getRelativePath( m_part->topsourceDirectory(), m_part->projectDirectory() ) + "/" + spitem->path.mid( m_part->projectDirectory().length() ); + switch (type) + { + case 0: //make target + m_part->startMakeCommand( m_part->buildDirectory() + relpath, cmd ); + break; + case 1: //make target as root + m_part->startMakeCommand( m_part->buildDirectory() + relpath, cmd, true ); + break; + case 2: //make command + m_part->startSimpleMakeCommand( m_part->buildDirectory() + relpath, cmd ); + break; + case 3: //make command as root + m_part->startSimpleMakeCommand( m_part->buildDirectory() + relpath, cmd, true ); + break; + case 4: //command + m_part->appFrontend()->startAppCommand(m_part->buildDirectory() + relpath, + cmd, false); + break; + case 5: //command as root + m_part->appFrontend()->startAppCommand(m_part->buildDirectory() + relpath, + "kdesu -t -c ' cd " + + KProcess::quote(m_part->buildDirectory() + relpath) + " && " + + cmd + "'", false); + break; + } +} + +void AutoSubprojectView::slotExpandTree() +{ + expandCollapseFirst( m_listView->currentItem(), true ); +} + +void AutoSubprojectView::slotCollapseTree() +{ + expandCollapseFirst( m_listView->currentItem(), false ); +} + +void AutoSubprojectView::expandCollapseFirst( QListViewItem * item, bool expand ) +{ + if ( !item ) return; + + if ( item == m_listView->firstChild() ) // special case for root node + { + item = item->firstChild(); + while ( item ) + { + expandCollapse( item, expand ); + item = item->nextSibling(); + } + } + else + { + expandCollapse( item, expand ); + } +} + +void AutoSubprojectView::expandCollapse( QListViewItem * item, bool expand ) +{ + if ( !item ) return; + + item->setOpen( expand ); + + item = item->firstChild(); + while ( item ) + { + expandCollapse( item, expand ); + item = item->nextSibling(); + } +} + +#include "autosubprojectview.moc" + +// kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/autotools/autosubprojectview.h b/buildtools/autotools/autosubprojectview.h new file mode 100644 index 00000000..e49caddd --- /dev/null +++ b/buildtools/autotools/autosubprojectview.h @@ -0,0 +1,130 @@ +/* + KDevelop Autotools Support + Copyright (c) 2002 by Victor Roeder + Copyright (c) 2005 by Matt Rogers + +*************************************************************************** +* * +* 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. * +* * +*************************************************************************** +*/ + +#ifndef AUTOSUBPROJECTVIEW_H +#define AUTOSUBPROJECTVIEW_H + +#include +#include "autoprojectviewbase.h" + + +class KAction; +class AutoToolsAction; +class AutoProjectWidget; +class AutoProjectPart; +class TargetItem; +class SubprojectItem; +class KListViewItem; +class KListView; + +namespace AutoProjectPrivate +{ + bool isHeader( const QString& fileName ); +} + + +//with protected inheritance gcc 3.2.3 complains in autoprojectwidget.cpp, line 116 +//that it cannot access the base class QObject (for the connect() call), +//so in order to be able to compile this file I made the inheritance public again, Alex +class AutoSubprojectView : public AutoProjectViewBase +{ + Q_OBJECT + +public: + AutoSubprojectView( AutoProjectWidget* widget, AutoProjectPart* part, QWidget *parent, const char *name ); + virtual ~AutoSubprojectView(); + +public: + void loadMakefileams ( const QString& dir ); + + void parse( SubprojectItem *item ); + KListView* listView() const + { + return m_listView; + } + + TargetItem *findNoinstHeaders( SubprojectItem *item ); + +signals: + void selectionChanged( QListViewItem* ); + +protected: + void initActions (); + + void parseKDEDOCS( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parseKDEICON( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parsePrimary( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parsePrefix( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + void parseSUBDIRS( SubprojectItem *item, + const QString &lhs, const QString &rhs ); + virtual void focusOutEvent( QFocusEvent *e ); + void expandCollapse( QListViewItem * item, bool expand ); + void expandCollapseFirst( QListViewItem * item, bool expand ); + +private: + AutoProjectWidget* m_widget; + AutoProjectPart* m_part; + QStringList headers; + + bool m_kdeMode; + + AutoToolsAction* addApplicationAction; + AutoToolsAction* subProjectOptionsAction; + AutoToolsAction* addSubprojectAction; + KAction* addExistingSubprojectAction; + AutoToolsAction* addTargetAction; + AutoToolsAction* addServiceAction; + AutoToolsAction* buildSubprojectAction; + KAction* removeSubprojectAction; + KAction* cleanSubprojectAction; + KAction* forceReeditSubprojectAction; + KAction* installSubprojectAction; + KAction* installSuSubprojectAction; + KAction* otherAction; + KAction* expandAction; + KAction* collapseAction; + + QStringList m_commandList; + QValueList m_commandTypeList; + +private slots: + void slotContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + //void slotSubprojectExecuted(QListViewItem* item); + void slotSelectionChanged( QListViewItem* item ); + void slotAddApplication(); + void slotSubprojectOptions(); + void slotAddSubproject(); + void slotAddExistingSubproject(); + void slotAddTarget(); + void slotAddService(); + void slotBuildSubproject(); + void slotRemoveSubproject(); + void slotForceReeditSubproject(); + void slotInstallSubproject(); + void slotInstallSuSubproject(); + void slotCleanSubproject(); + void slotManageBuildCommands(); + void slotCustomBuildCommand( int ); + void slotExpandTree(); + void slotCollapseTree(); +}; + +#endif + +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autotoolsaction.cpp b/buildtools/autotools/autotoolsaction.cpp new file mode 100644 index 00000000..63b38762 --- /dev/null +++ b/buildtools/autotools/autotoolsaction.cpp @@ -0,0 +1,156 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers + + *************************************************************************** + * * + * 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 "autotoolsaction.h" + +#include +#include +#include +#include +#include +#include + +AutoToolsAction::~AutoToolsAction() +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( text, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const KGuiItem& item, const KShortcut & cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ) +: KAction( item, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const KShortcut& cut, + QObject* parent, const char* name ) +: KAction( text, cut, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, + QObject* parent, const char* name ) +: KAction( text, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QIconSet& pix, + const KShortcut& cut, QObject* parent, const char* name ) +: KAction( text, pix, cut, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QString& pix, + const KShortcut& cut, QObject* parent, const char* name ) +: KAction( text, pix, cut, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QIconSet& pix, + const KShortcut& cut, const QObject* receiver, + const char* slot, QObject* parent, const char * name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( const QString& text, const QString& pix, + const KShortcut & cut, const QObject* receiver, + const char* slot, QObject* parent, const char * name ) +: KAction( text, pix, cut, receiver, slot, parent, name ) +{ +} + +AutoToolsAction::AutoToolsAction( QObject * parent, const char * name ) +: KAction( parent, name ) +{ +} + +int AutoToolsAction::plug( QWidget* w, int index ) +{ + if ( !w ) { + kdWarning(129) << "KAction::plug called with 0 argument\n"; + return -1; + } + + // Check if action is permitted + if (kapp && !kapp->authorizeKAction(name())) + return -1; + + if ( ::qt_cast( w ) ) + { + QToolButton* tb = static_cast( w ); + connect( tb, SIGNAL( clicked() ), this, SLOT( activate() ) ); + int id = getToolButtonID(); + + if ( !icon().isEmpty() ) + tb->setPixmap( SmallIcon( icon() ) ); + else + tb->setText( text() ); + + if ( !isEnabled() ) + tb->setEnabled( false ); + + if ( !whatsThis().isEmpty() ) + { + QWhatsThis::remove( tb ); + QWhatsThis::add( tb, whatsThisWithIcon() ); + } + + if ( !toolTip().isEmpty() ) + { + QToolTip::remove( tb ); + QToolTip::add( tb, toolTip() ); + } + + addContainer( tb, id ); + + return containerCount() - 1; + } + + return KAction::plug( w, index ); +} + +void AutoToolsAction::updateEnabled( int i ) +{ + QWidget* w = container( i ); + + if ( ::qt_cast( w ) ) + static_cast( w )->setEnabled( isEnabled() ); + else + KAction::updateEnabled( i ) ; +} + + + +//kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/autotoolsaction.h b/buildtools/autotools/autotoolsaction.h new file mode 100644 index 00000000..97c8e79e --- /dev/null +++ b/buildtools/autotools/autotoolsaction.h @@ -0,0 +1,70 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers + +*************************************************************************** +* * +* 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. * +* * +*************************************************************************** +*/ +#ifndef AUTOTOOLSACTION_H +#define AUTOTOOLSACTION_H + +#include +#include + +class QObject; +class KActionCollection; + +/** + * A KAction derivative that will work with the QToolButtons used in + * the Automake Manager + * @author Matt Rogers + */ +class AutoToolsAction : public KAction +{ +public: + virtual ~AutoToolsAction(); + + AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const KGuiItem& item, const KShortcut& cut, + const QObject* receiver, const char* slot, + KActionCollection* parent, const char* name ); + + AutoToolsAction( const QString& text, const KShortcut& cut = KShortcut(), QObject* parent = 0, const char* name = 0 ); + AutoToolsAction( const QString& text, const KShortcut& cut, + const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 ); + AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut = KShortcut(), + QObject* parent = 0, const char* name = 0 ); + AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut = KShortcut(), + QObject* parent = 0, const char* name = 0 ); + AutoToolsAction( const QString& text, const QIconSet& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, QObject* parent, const char* name = 0 ); + AutoToolsAction( const QString& text, const QString& pix, const KShortcut& cut, + const QObject* receiver, const char* slot, QObject* parent, + const char* name = 0 ); + AutoToolsAction( QObject* parent = 0, const char* name = 0 ); + + virtual int plug( QWidget *widget, int index = -1 ); + + virtual void updateEnabled( int i ); +}; + +#endif + +//kate: indent-mode csands; tab-width 4; auto-insert-doxygen on; diff --git a/buildtools/autotools/choosetargetdialog.cpp b/buildtools/autotools/choosetargetdialog.cpp new file mode 100644 index 00000000..b35c5c75 --- /dev/null +++ b/buildtools/autotools/choosetargetdialog.cpp @@ -0,0 +1,348 @@ +/*************************************************************************** + ------------------- + begin : 29.11.2002 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "choosetargetdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "choosetargetdlgbase.h" +#include "autodetailsview.h" +#include "autolistviewitems.h" +#include "autosubprojectview.h" +#include "misc.h" +#include "autoprojectwidget.h" +#include "autoprojectpart.h" + +#include "kdevpartcontroller.h" + +class ChooseTargetDialog::Private +{ +public: + AutoProjectWidget* widget; + AutoProjectPart* part; + QStringList fileList; + QPtrList subprojectList; + SubprojectItem* chosenSubproject; + TargetItem* chosenTarget; + ChooseTargetDlgBase* baseUI; +}; + +ChooseTargetDialog::ChooseTargetDialog ( AutoProjectWidget* widget, AutoProjectPart* part, + QStringList fileList, QWidget* parent, const char* name ) +: KDialogBase( parent, name, false, i18n("Automake Manager - Choose Target"), + Ok | Cancel, KDialogBase::Ok, true /* seperator */ ) + +{ + Q_UNUSED( parent ); + Q_UNUSED( name ); + d = new ChooseTargetDialog::Private; + d->widget = widget; + d->part = part; + d->fileList = fileList; + d->subprojectList = widget->allSubprojectItems(); + d->baseUI = new ChooseTargetDlgBase( this, "base ui" ); + setMainWidget( d->baseUI ); + + d->baseUI->subprojectComboBox->setAutoCompletion( true ); + d->baseUI->targetComboBox->setAutoCompletion( true ); + d->baseUI->newFileList->header()->hide(); + d->baseUI->newFileList->addColumn( QString::null ); + d->baseUI->newFileList->setSorting(-1); + + setIcon ( SmallIcon ( "target_kdevelop" ) ); + + + QPtrListIterator sit(d->subprojectList); + for ( ; (*sit); ++sit ) + { + QPtrList targetList = (*sit)->targets; + QPtrListIterator targetIt(targetList); + + // Only insert Subproject which have a "regular" target + for ( ; (*targetIt); ++targetIt ) + { + QString titemPrimary = (*targetIt)->primary; + if ( titemPrimary == "PROGRAMS" || titemPrimary == "LIBRARIES" || + titemPrimary == "LTLIBRARIES" || titemPrimary == "JAVA" ) + { + d->baseUI->subprojectComboBox->insertItem ( SmallIcon ( "folder" ), (*sit)->subdir ); + } + } + } + + if ( d->widget->activeTarget() && d->widget->activeSubproject() ) + { + d->chosenTarget = d->widget->activeTarget(); + //kdDebug ( 9020 ) << "1) Chosen target is " << d->chosenTarget->name << endl; + d->chosenSubproject = widget->activeSubproject(); + d->baseUI->chosenTargetLabel->setText( ( widget->activeSubproject()->path + "/" + + d->widget->activeTarget()->name + "" ) + .mid( d->part->projectDirectory().length() + 1 ) ); + d->baseUI->subprojectComboBox->setEnabled( false ); + d->baseUI->targetComboBox->setEnabled( false ); + + d->baseUI->subprojectComboBox->setCurrentItem( widget->activeSubproject()->subdir ); + slotSubprojectChanged( widget->activeSubproject()->subdir ); + } + else + { + d->baseUI->activeTargetRadioButton->toggle(); + d->baseUI->activeTargetRadioButton->setEnabled ( false ); + d->baseUI->neverAskAgainCheckbox->setEnabled ( false ); + + slotSubprojectChanged ( d->baseUI->subprojectComboBox->text(0) ); + } + + QStringList::iterator it; + QString fileName; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + int pos = ( *it ).findRev('/'); + if (pos != -1) + fileName = ( *it ).mid(pos+1); + else + fileName = ( *it ); + + + d->baseUI->newFileList->insertItem( new QListViewItem( d->baseUI->newFileList, fileName ) ); + } + + connect ( d->baseUI->subprojectComboBox, SIGNAL ( activated ( const QString& ) ), + this, SLOT( slotSubprojectChanged ( const QString& ) ) ); + connect ( d->baseUI->targetComboBox, SIGNAL ( activated ( const QString& ) ), + this, SLOT( slotTargetChanged ( const QString& ) ) ); +} + + +ChooseTargetDialog::~ChooseTargetDialog() +{ +} + +void ChooseTargetDialog::slotSubprojectChanged ( const QString& name ) +{ + d->chosenTarget = 0; + SubprojectItem* spitem = d->subprojectList.first(); + + for ( ; spitem; spitem = d->subprojectList.next() ) + { + if ( spitem->subdir == name ) + { + QPtrList targetList = spitem->targets; + TargetItem* titem = targetList.first(); + + d->baseUI->targetComboBox->clear(); + +/* choosenSubprojectLabel->setText ( ( spitem->path + "" + ->name + "" ).mid ( d->widget->projectDirectory().length() + 1 ) );*/ + + d->chosenSubproject = spitem; + + for ( ; titem; titem = targetList.next() ) + { + if ( titem->primary == "PROGRAMS" || titem->primary == "LIBRARIES" || + titem->primary == "LTLIBRARIES" || titem->primary == "JAVA" ) + { + d->baseUI->targetComboBox->insertItem ( SmallIcon ( "target_kdevelop" ), titem->name ); + + //d->baseUI->targetComboBox->addToHistory ( titem->name ); + + // if the Active Target is in the currently selected Subproject + if ( d->widget->activeTarget() && + titem->name == d->widget->activeTarget()->name ) + { + d->baseUI->targetComboBox->setCurrentItem( titem->name ); + d->baseUI->chosenTargetLabel->setText( ( spitem->path + "/" + titem->name + "" ).mid( d->part->projectDirectory().length() + 1 ) ); + d->chosenTarget = titem; + //kdDebug ( 9020 ) << "2) Chosen target is " << d->chosenTarget->name << endl; + } + else + { + //d->baseUI->targetComboBox->setCurrentItem ( 0 ); + if ( !d->chosenTarget ) + { + d->baseUI->chosenTargetLabel->setText( ( spitem->path + "/" + titem->name + "") + .mid( d->part->projectDirectory().length() + 1 ) ); + //choosenSubprojectLabel->setText ( ( spitem->path + "" + titem->name + "" ).mid ( d->widget->projectDirectory().length() + 1 ) ); + + d->chosenTarget = titem; + } + //kdDebug ( 9020 ) << "2a) Chosen target is " << d->chosenTarget->name << endl; + } + } + } + + break; + } + } +} + +void ChooseTargetDialog::slotTargetChanged( const QString& name ) +{ + d->baseUI->chosenTargetLabel->setText( ( d->chosenSubproject->path + "/" + name + "" ) + .mid( d->part->projectDirectory().length() + 1 ) ); + + QPtrList targetList = d->chosenSubproject->targets; + TargetItem* titem = targetList.first(); + + for ( ; titem; titem = targetList.next() ) + { + if ( titem->name == name ) + { + d->chosenTarget = titem; + //kdDebug ( 9020 ) << "4) Chosen target is " << d->chosenTarget->name << endl; + + break; + } + } +} + +void ChooseTargetDialog::slotOk() +{ + if ( d->baseUI->activeTargetRadioButton->isChecked() ) + { + d->chosenTarget = d->widget->activeTarget(); + d->chosenSubproject = d->widget->activeSubproject(); + } + if ( !d->chosenSubproject || !d->chosenTarget ) + return; + + //kdDebug ( 9020 ) << "3) Chosen target is " << d->chosenTarget->name << endl; + + QStringList newFileList; + QStringList::iterator it; + QString directory, fileName; + + for ( it = d->fileList.begin(); it != d->fileList.end(); ++it ) + { + bool found = false; + + int pos = ( *it ).findRev('/'); + if (pos != -1) + { + directory = ( *it ).left(pos); + fileName = ( *it ).mid(pos+1); + } + else + { + fileName = ( *it ); + } + + FileItem * fitem = d->chosenTarget->sources.first(); + for ( ; fitem; fitem = d->chosenTarget->sources.next() ) + { + if ( fitem->name == fileName ) + { + KMessageBox::error ( this, i18n ( "The file %1 already exists in the chosen target.\nThe file will be created but will not be added to the target.\n" + "Rename the file and select 'Add Existing Files' from the Automake Manager." ).arg ( fitem->name ), + i18n ( "Error While Adding Files" ) ); + found = true; + } + } + + if ( !found ) + { + /// \FIXME a quick hack to prevent adding header files to _SOURCES + /// and display them in noinst_HEADERS + if (AutoProjectPrivate::isHeader(fileName) && + ( d->chosenTarget->primary == "PROGRAMS" || d->chosenTarget->primary == "LIBRARIES" || d->chosenTarget->primary == "LTLIBRARIES" ) ) + { + kdDebug ( 9020 ) << "Ignoring header file and adding it to noinst_HEADERS: " << fileName << endl; + TargetItem* noinst_HEADERS_item = d->widget->getSubprojectView()->findNoinstHeaders(d->chosenSubproject); + FileItem *fitem = d->widget->createFileItem( fileName, d->chosenSubproject ); + noinst_HEADERS_item->sources.append( fitem ); + noinst_HEADERS_item->insertItem( fitem ); + + QString varname = "noinst_HEADERS"; + d->chosenSubproject->variables[ varname ] += ( " " + fileName ); + + QMap replaceMap; + replaceMap.insert( varname, d->chosenSubproject->variables[ varname ] ); + + AutoProjectTool::addToMakefileam( d->chosenSubproject->path + "/Makefile.am", replaceMap ); + } + else + { + fitem = d->widget->createFileItem( fileName,d->chosenSubproject ); + d->chosenTarget->sources.append( fitem ); + d->chosenTarget->insertItem( fitem ); + + QString canontargetname = AutoProjectTool::canonicalize( d->chosenTarget->name ); + QString varname = canontargetname + "_SOURCES"; + d->chosenSubproject->variables[ varname ] += ( " " + fileName ); + + QMap replaceMap; + replaceMap.insert( varname, d->chosenSubproject->variables[ varname ] ); + + AutoProjectTool::addToMakefileam( d->chosenSubproject->path + "/Makefile.am", replaceMap ); + } + newFileList.append ( d->chosenSubproject->path.mid ( d->part->projectDirectory().length() + 1 ) + "/" + fileName ); + } + + if ( directory.isEmpty() || directory != d->chosenSubproject->subdir ) + { + KShellProcess proc("/bin/sh"); + + proc << "mv"; + proc << KShellProcess::quote( d->part->projectDirectory() + "/" + directory + "/" + fileName ); + proc << KShellProcess::quote( d->chosenSubproject->path + "/" + fileName ); + proc.start(KProcess::DontCare); + } + + // why open the files?! +// d->part->partController()->editDocument ( KURL ( d->chosenSubproject->path + "/" + fileName ) ); + + found = false; + } + + d->widget->emitAddedFiles( newFileList ); + KDialogBase::slotOk(); +} + +TargetItem* ChooseTargetDialog::chosenTarget() +{ + return d->chosenTarget; +} + +SubprojectItem* ChooseTargetDialog::chosenSubproject() +{ + return d->chosenSubproject; +} + +bool ChooseTargetDialog::alwaysUseActiveTarget() const +{ + return d->baseUI->neverAskAgainCheckbox->isChecked(); +} + + +#include "choosetargetdialog.moc" +//kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/choosetargetdialog.h b/buildtools/autotools/choosetargetdialog.h new file mode 100644 index 00000000..44825ce5 --- /dev/null +++ b/buildtools/autotools/choosetargetdialog.h @@ -0,0 +1,57 @@ +/*************************************************************************** + ------------------- + begin : 29.11.2002 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _CHOOSETARGETDIALOG_H_ +#define _CHOOSETARGETDIALOG_H_ + +#include + +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; +class QStringList; +class QWidget; + +class ChooseTargetDialog : public KDialogBase +{ +Q_OBJECT +public: + ChooseTargetDialog( AutoProjectWidget* widget, AutoProjectPart* part, + QStringList fileList, QWidget* parent = 0, + const char* name = 0 ); + ~ChooseTargetDialog(); + +public: + TargetItem* chosenTarget(); + SubprojectItem* chosenSubproject(); + + bool alwaysUseActiveTarget() const; + +public slots: + void slotSubprojectChanged ( const QString& ); + void slotTargetChanged ( const QString& ); + +protected: + virtual void slotOk(); + +private: + class Private; + ChooseTargetDialog::Private* d; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/choosetargetdlgbase.ui b/buildtools/autotools/choosetargetdlgbase.ui new file mode 100644 index 00000000..3581e595 --- /dev/null +++ b/buildtools/autotools/choosetargetdlgbase.ui @@ -0,0 +1,222 @@ + +ChooseTargetDlgBase + + + ChooseTargetDlgBase + + + + 0 + 0 + 444 + 306 + + + + + 444 + 306 + + + + Automake Manager - Choose Target + + + + unnamed + + + + buttonGroup1 + + + NoFrame + + + Plain + + + 1 + + + + + + false + + + + unnamed + + + 0 + + + + activeTargetRadioButton + + + Add new files to m&y active target + + + true + + + + + chooseTargetRadioButton + + + Choose &another target + + + + + + + chosenTargetGroupBox + + + false + + + Choose &Target + + + + unnamed + + + + subprojectComboBox + + + false + + + + + targetComboBox + + + true + + + + + targetStaticLabel + + + + + + + Target: + + + + + chosenTargetLabel + + + + 7 + 5 + 0 + 0 + + + + [TARGET] + + + + + + + groupBox1 + + + &New Files + + + + unnamed + + + + newFileList + + + true + + + + + cancelNoticeLabel + + + <qt><b>Note:</b> If you cancel, your files will be created but will <b>not</b> be added to the project.</qt> + + + AlignVCenter + + + + + + + neverAskAgainCheckbox + + + Do &not ask me again and use always my active target + + + + + + + activeTargetRadioButton + toggled(bool) + chosenTargetGroupBox + setDisabled(bool) + + + activeTargetRadioButton + toggled(bool) + subprojectComboBox + setDisabled(bool) + + + activeTargetRadioButton + toggled(bool) + targetComboBox + setDisabled(bool) + + + + activeTargetRadioButton + chooseTargetRadioButton + subprojectComboBox + targetComboBox + newFileList + neverAskAgainCheckbox + + + kdialog.h + + + slotActiveTargetToggled(bool) + slotChooseTargetToggled(bool) + slotSubprojectChanged(const QString&) + slotTargetChanged(const QString&) + + + + kcombobox.h + klineedit.h + kcombobox.h + klineedit.h + klistview.h + + diff --git a/buildtools/autotools/configureoptionswidget.cpp b/buildtools/autotools/configureoptionswidget.cpp new file mode 100644 index 00000000..7e2db214 --- /dev/null +++ b/buildtools/autotools/configureoptionswidget.cpp @@ -0,0 +1,431 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "configureoptionswidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kdevcompileroptions.h" +#include "autoprojectpart.h" +#include "environmentvariableswidget.h" + + +class ServiceComboBox +{ +public: + static void insertStringList(QComboBox *combo, const QValueList &list, + QStringList *names, QStringList *execs) + { + QValueList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + combo->insertItem((*it)->comment()); + (*names) << (*it)->desktopEntryName(); + (*execs) << (*it)->exec(); + kdDebug(9020) << "insertStringList item " << (*it)->name() << "," << (*it)->exec() << endl; + } + } + static QString currentText(QComboBox *combo, const QStringList &names) + { + if (combo->currentItem() == -1) + return QString::null; + return names[combo->currentItem()]; + } + static void setCurrentText(QComboBox *combo, const QString &str, const QStringList &names) + { + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + combo->setCurrentItem(i); + break; + } + ++i; + } + } +}; + + +ConfigureOptionsWidget::ConfigureOptionsWidget(AutoProjectPart *part, QWidget *parent, const char *name) + : ConfigureOptionsWidgetBase(parent, name) +{ + config_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + + m_part = part; + env_groupBox->setColumnLayout( 1, Qt::Vertical ); + QDomDocument &dom = *part->projectDom(); + m_environmentVariablesWidget = new EnvironmentVariablesWidget(dom, "/kdevautoproject/general/envvars", env_groupBox); + + coffers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'C'"); + cxxoffers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'C++'"); + f77offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Fortran'"); + + ServiceComboBox::insertStringList(cservice_combo, coffers, &cservice_names, &cservice_execs); + ServiceComboBox::insertStringList(cxxservice_combo, cxxoffers, &cxxservice_names, &cxxservice_execs); + ServiceComboBox::insertStringList(f77service_combo, f77offers, &f77service_names, &f77service_execs); + + if (coffers.isEmpty()) + cflags_button->setEnabled(false); + if (cxxoffers.isEmpty()) + cxxflags_button->setEnabled(false); + if (f77offers.isEmpty()) + f77flags_button->setEnabled(false); + + allConfigs = part->allBuildConfigs(); + config_combo->insertStringList(allConfigs); + + dirty = false; + currentConfig = QString::null; + configChanged(part->currentBuildConfig()); + + fixLayout(); +} + + +ConfigureOptionsWidget::~ConfigureOptionsWidget() +{} + + +void ConfigureOptionsWidget::fixLayout() +{ + int w1 = ccompiler_label->sizeHint().width(); + int w2 = cbinary_label->sizeHint().width(); + int w3 = cflags_label->sizeHint().width(); + int w4 = cxxcompiler_label->sizeHint().width(); + int w5 = cxxbinary_label->sizeHint().width(); + int w6 = cxxflags_label->sizeHint().width(); + int w7 = f77compiler_label->sizeHint().width(); + int w8 = f77binary_label->sizeHint().width(); + int w9 = f77flags_label->sizeHint().width(); + + int w = QMAX(w1, QMAX(w2, w3)); + w = QMAX(w, QMAX(w4, w5)); + w = QMAX(w, QMAX(w6, w7)); + w = QMAX(w, QMAX(w8, w9)); + + ccompiler_label->setMinimumWidth(w); + cxxcompiler_label->setMinimumWidth(w); + f77compiler_label->setMinimumWidth(w); +} + + +void ConfigureOptionsWidget::readSettings(const QString &config) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevautoproject/configurations/" + config + "/"; + kdDebug(9020) << "Reading config from " << prefix << endl; + + configargs_edit->setText(DomUtil::readEntry(dom, prefix + "configargs")); + QString builddir = DomUtil::readEntry(dom, prefix + "builddir"); + if (builddir.isEmpty() && config != "default") + builddir = config; + builddir_edit->setText(builddir); + + topsourcedir_edit->setText(DomUtil::readEntry(dom, prefix + "topsourcedir")); + + cppflags_edit->setText(DomUtil::readEntry(dom, prefix + "cppflags")); + ldflags_edit->setText(DomUtil::readEntry(dom, prefix + "ldflags")); + + QString ccompiler = DomUtil::readEntry(dom, prefix + "ccompiler"); + QString cxxcompiler = DomUtil::readEntry(dom, prefix + "cxxcompiler"); + QString f77compiler = DomUtil::readEntry(dom, prefix + "f77compiler"); + + if (ccompiler.isEmpty()) { + kdDebug(9020) << "No c compiler set" << endl; + QValueList::ConstIterator it; + for (it = coffers.begin(); it != coffers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + kdDebug(9020) << "Found default " << (*it)->name() << endl; + ccompiler = (*it)->name(); + break; + } + } + } + if (cxxcompiler.isEmpty()) { + kdDebug(9020) << "No cxx compiler set" << endl; + QValueList::ConstIterator it; + for (it = cxxoffers.begin(); it != cxxoffers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + kdDebug(9020) << "Found default " << (*it)->name() << endl; + cxxcompiler = (*it)->name(); + break; + } + } + } + if (f77compiler.isEmpty()) { + kdDebug(9020) << "No c compiler set" << endl; + QValueList::ConstIterator it; + for (it = f77offers.begin(); it != f77offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + kdDebug(9020) << "Found default " << (*it)->name() << endl; + f77compiler = (*it)->name(); + break; + } + } + } + + ServiceComboBox::setCurrentText(cservice_combo, ccompiler, cservice_names); + ServiceComboBox::setCurrentText(cxxservice_combo, cxxcompiler, cxxservice_names); + ServiceComboBox::setCurrentText(f77service_combo, f77compiler, f77service_names); + + cbinary_edit->setText(DomUtil::readEntry(dom, prefix + "ccompilerbinary")); + cxxbinary_edit->setText(DomUtil::readEntry(dom, prefix + "cxxcompilerbinary")); + f77binary_edit->setText(DomUtil::readEntry(dom, prefix + "f77compilerbinary")); + + cflags_edit->setText(DomUtil::readEntry(dom, prefix + "cflags")); + cxxflags_edit->setText(DomUtil::readEntry(dom, prefix + "cxxflags")); + f77flags_edit->setText(DomUtil::readEntry(dom, prefix + "f77flags")); + + m_environmentVariablesWidget->readEnvironment(dom, prefix + "envvars"); +} + + +void ConfigureOptionsWidget::saveSettings(const QString &config) +{ + m_environmentVariablesWidget->accept(); + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevautoproject/configurations/" + config + "/"; + kdDebug(9020) << "Saving config under " << prefix << endl; + + DomUtil::writeEntry(dom, prefix + "configargs", configargs_edit->text()); + DomUtil::writeEntry(dom, prefix + "builddir", builddir_edit->text()); + DomUtil::writeEntry(dom, prefix + "topsourcedir", topsourcedir_edit->text()); + + DomUtil::writeEntry(dom, prefix + "cppflags", cppflags_edit->text()); + DomUtil::writeEntry(dom, prefix + "ldflags", ldflags_edit->text()); + + QFileInfo fi(m_part->buildDirectory()); + QDir dir(fi.dir()); + dir.mkdir(fi.fileName()); + + DomUtil::writeEntry(dom, prefix + "ccompiler", + ServiceComboBox::currentText(cservice_combo, cservice_names)); + DomUtil::writeEntry(dom, prefix + "cxxcompiler", + ServiceComboBox::currentText(cxxservice_combo, cxxservice_names)); + DomUtil::writeEntry(dom, prefix + "f77compiler", + ServiceComboBox::currentText(f77service_combo, f77service_names)); + + DomUtil::writeEntry(dom, prefix + "ccompilerbinary", cbinary_edit->text()); + DomUtil::writeEntry(dom, prefix + "cxxcompilerbinary", cxxbinary_edit->text()); + DomUtil::writeEntry(dom, prefix + "f77compilerbinary", f77binary_edit->text()); + + DomUtil::writeEntry(dom, prefix + "cflags", cflags_edit->text()); + DomUtil::writeEntry(dom, prefix + "cxxflags", cxxflags_edit->text()); + DomUtil::writeEntry(dom, prefix + "f77flags", f77flags_edit->text()); + + if (KMessageBox::questionYesNo(this, i18n("Re-run configure for %1 now?").arg(config), QString::null, i18n("Rerun"), i18n("Do Not Run")) == KMessageBox::Yes) + QTimer::singleShot(0, m_part, SLOT(slotConfigure())); + +} + + +void ConfigureOptionsWidget::setDirty() +{ + kdDebug(9020) << "config dirty" << endl; + dirty = true; +} + + +void ConfigureOptionsWidget::builddirClicked() +{ + QString dir = builddir_edit->text(); + dir = KFileDialog::getExistingDirectory(dir, this); + if (!dir.isNull()) + builddir_edit->setText(dir); +} + +void ConfigureOptionsWidget::topsourcedirClicked() +{ + QString dir = topsourcedir_edit->text(); + dir = KFileDialog::getExistingDirectory(dir, this); + if (!dir.isNull()) + topsourcedir_edit->setText(dir); +} + +void ConfigureOptionsWidget::configComboTextChanged(const QString &config) +{ + bool canAdd = !allConfigs.contains(config) && !config.contains("/") && !config.isEmpty(); + bool canRemove = allConfigs.contains(config) && config != "default"; + addconfig_button->setEnabled(canAdd); + removeconfig_button->setEnabled(canRemove); +} + + +void ConfigureOptionsWidget::configChanged(const QString &config) +{ + if (config == currentConfig || !allConfigs.contains(config)) + return; + + if (!currentConfig.isNull() && dirty) + saveSettings(currentConfig); + + currentConfig = config; + readSettings(config); + dirty = false; + + config_combo->blockSignals(true); + config_combo->setEditText(config); + config_combo->blockSignals(false); +} + + +void ConfigureOptionsWidget::configAdded() +{ + QString config = config_combo->currentText(); + + allConfigs.append(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + configChanged(config); + setDirty(); // force saving +} + + +void ConfigureOptionsWidget::configRemoved() +{ + QString config = config_combo->currentText(); + + QDomDocument dom = *m_part->projectDom(); + QDomNode node = dom.documentElement().namedItem("kdevautoproject").namedItem("configurations"); + node.removeChild(node.namedItem(config)); + allConfigs.remove(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + + currentConfig = QString::null; + configChanged("default"); +} + + +void ConfigureOptionsWidget::cserviceChanged() +{ + QString exec = ServiceComboBox::currentText(cservice_combo, cservice_execs); + cbinary_edit->setText(exec); + kdDebug(9020) << "exec: " << exec << endl; +} + + +void ConfigureOptionsWidget::cxxserviceChanged() +{ + QString exec = ServiceComboBox::currentText(cxxservice_combo, cxxservice_execs); + cxxbinary_edit->setText(exec); +} + + +void ConfigureOptionsWidget::f77serviceChanged() +{ + QString exec = ServiceComboBox::currentText(f77service_combo, f77service_execs); + f77binary_edit->setText(exec); + kdDebug(9020) << "exec: " << exec << endl; +} + + +void ConfigureOptionsWidget::cflagsClicked() +{ + QString name = ServiceComboBox::currentText(cservice_combo, cservice_names); + KDevCompilerOptions *plugin = createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, cflags_edit->text()); + cflags_edit->setText(flags); + delete plugin; + } +} + + +void ConfigureOptionsWidget::cxxflagsClicked() +{ + QString name = ServiceComboBox::currentText(cxxservice_combo, cxxservice_names); + KDevCompilerOptions *plugin = createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, cxxflags_edit->text()); + cxxflags_edit->setText(flags); + delete plugin; + } +} + + +void ConfigureOptionsWidget::f77flagsClicked() +{ + QString name = ServiceComboBox::currentText(f77service_combo, f77service_names); + KDevCompilerOptions *plugin = createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, f77flags_edit->text()); + f77flags_edit->setText(flags); + delete plugin; + } +} + + +KDevCompilerOptions *ConfigureOptionsWidget::createCompilerOptions(const QString &name) +{ + KService::Ptr service = KService::serviceByDesktopName(name); + if (!service) { + kdDebug(9020) << "Can't find service " << name; + return 0; + } + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + KMessageBox::error(0, i18n("There was an error loading the module %1.\n" + "The diagnostics is:\n%2").arg(service->name()).arg(errorMessage)); + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(this, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug(9020) << "Component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; +} + + +void ConfigureOptionsWidget::accept() +{ + DomUtil::writeEntry(*m_part->projectDom(), "/kdevautoproject/general/useconfiguration", currentConfig); + m_environmentVariablesWidget->accept(); + if (dirty) + { + saveSettings(currentConfig); + } +} + +#include "configureoptionswidget.moc" diff --git a/buildtools/autotools/configureoptionswidget.h b/buildtools/autotools/configureoptionswidget.h new file mode 100644 index 00000000..a973ce7d --- /dev/null +++ b/buildtools/autotools/configureoptionswidget.h @@ -0,0 +1,69 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _CONFIGUREOPTIONSWIDGET_H_ +#define _CONFIGUREOPTIONSWIDGET_H_ + +#include "configureoptionswidgetbase.h" + +#include +#include "domutil.h" + + +class KDevCompilerOptions; +class AutoProjectPart; +class EnvironmentVariablesWidget; + +class ConfigureOptionsWidget : public ConfigureOptionsWidgetBase +{ + Q_OBJECT + +public: + ConfigureOptionsWidget( AutoProjectPart *part, QWidget *parent = 0, const char *name = 0 ); + ~ConfigureOptionsWidget(); + +public slots: + void accept(); + +private: + virtual void builddirClicked(); + virtual void topsourcedirClicked(); + virtual void setDirty(); + virtual void configChanged( const QString &config ); + virtual void configComboTextChanged( const QString &config ); + virtual void configAdded(); + virtual void configRemoved(); + virtual void cflagsClicked(); + virtual void cxxflagsClicked(); + virtual void f77flagsClicked(); + virtual void cserviceChanged(); + virtual void cxxserviceChanged(); + virtual void f77serviceChanged(); + + void fixLayout(); + void readSettings( const QString &config ); + void saveSettings( const QString &config ); + + KDevCompilerOptions *createCompilerOptions( const QString &lang ); + KTrader::OfferList coffers, cxxoffers, f77offers; + QStringList cservice_names, cservice_execs; + QStringList cxxservice_names, cxxservice_execs; + QStringList f77service_names, f77service_execs; + QStringList allConfigs; + QString currentConfig; + bool dirty; + + AutoProjectPart *m_part; + EnvironmentVariablesWidget* m_environmentVariablesWidget; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/configureoptionswidgetbase.ui b/buildtools/autotools/configureoptionswidgetbase.ui new file mode 100644 index 00000000..0eb47ac7 --- /dev/null +++ b/buildtools/autotools/configureoptionswidgetbase.ui @@ -0,0 +1,1040 @@ + +ConfigureOptionsWidgetBase + + + configure_options_widget + + + + 0 + 0 + 628 + 607 + + + + Configure Options + + + + unnamed + + + 0 + + + + Layout1 + + + + unnamed + + + + config_label + + + + 1 + 5 + 0 + 0 + + + + &Configuration: + + + config_combo + + + + + config_combo + + + + 3 + 0 + 0 + 0 + + + + true + + + Different build profiles + + + profiles + + + + + Spacer17_2 + + + Horizontal + + + Fixed + + + + 20 + 8 + + + + + + addconfig_button + + + &Add + + + false + + + + + removeconfig_button + + + &Remove + + + false + + + + + Spacer18_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + tabwidget + + + + general_tab + + + &General + + + + unnamed + + + + configargs_edit + + + Options to pass to configure, e.g. --prefix=<install dir> + + + Options to pass to configure, e.g. --prefix=<install dir> + + + + + builddir_label + + + &Build directory (must be different for every different configuration): + + + builddir_edit + + + + + Spacer23 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + topsourcedir_label + + + Top source &directory: + + + topsourcedir_edit + + + + + builddir_edit + + + The build process will place the object +files and binary in this directory. + +If the name does not have a leading / +then it is relative to the project directory. +(in the General page) + +The build process also checks here for +a Makefile and a configure script. + +If you have imported a project and you were +building in the project directory, you +probably want this to be blank. + + + The build process will place the object +files and binary in this directory. + +If the name does not have a leading / +then it is relative to the project directory. +(in the General page) + +The build process also checks here for +a Makefile and a configure script. + +If you have imported a project and you were +building in the project directory, you +probably want this to be blank. + + + + + builddir_button + + + + 30 + 0 + + + + + 30 + 32767 + + + + ... + + + + + Spacer24 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + topsourcedir_button + + + + 30 + 0 + + + + + 30 + 32767 + + + + ... + + + + + topsourcedir_edit + + + Where to start looking for the src files. +If the name does not have a leading / +then it is relative to the project directory. +(in the General page) + + + Where to start looking for the src files. +If the name does not have a leading / +then it is relative to the project directory. +(in the General page) + + + + + spacer17 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + ldflags_label + + + Li&nker flags (LDFLAGS): + + + ldflags_edit + + + Linker flags, e.g. -L<lib dir> if you have libraries in a +nonstandard directory <lib dir> + + + + + spacer17_2_2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + ldflags_edit + + + Linker flags, e.g. -L<lib dir> if you have libraries in a +nonstandard directory <lib dir> + + + Linker flags, e.g. -L<lib dir> if you have libraries in a +nonstandard directory <lib dir> + + + + + cppflags_edit + + + C/C++ preprocessor flags, e.g. -I<include dir> if you have +headers in a nonstandard directory <include dir> + + + C/C++ preprocessor flags, e.g. -I<include dir> if you have +headers in a nonstandard directory <include dir> + + + + + spacer17_2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + cppflags_label + + + C/C++ &preprocessor flags (CPPFLAGS): + + + cppflags_edit + + + C/C++ preprocessor flags, e.g. -I<include dir> if you have +headers in a nonstandard directory <include dir> + + + + + configargs_label + + + Configure argu&ments: + + + configargs_edit + + + + + env_groupBox + + + + 5 + 3 + 0 + 0 + + + + Environment &Variables + + + + unnamed + + + + + + + + c_tab + + + C + + + + unnamed + + + + ccompiler_label + + + C com&piler: + + + cservice_combo + + + + + cservice_combo + + + + + Spacer11 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + cflags_label + + + Compiler f&lags (CFLAGS): + + + cflags_edit + + + + + cflags_edit + + + + + cflags_button + + + + 0 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + Spacer10 + + + Vertical + + + Expanding + + + + 20 + 168 + + + + + + cbinary_label + + + Compiler co&mmand (CC): + + + cbinary_edit + + + + + cbinary_edit + + + + + Spacer12 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + + + cxx_tab + + + C++ + + + + unnamed + + + + cxxcompiler_label + + + C++ com&piler: + + + cxxservice_combo + + + + + cxxservice_combo + + + + + Spacer13 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + cxxbinary_label + + + Compiler co&mmand (CXX): + + + cxxbinary_edit + + + + + cxxbinary_edit + + + + + Spacer13_2 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + cxxflags_label + + + Compiler flags (C&XXFLAGS): + + + cxxflags_edit + + + + + cxxflags_edit + + + + + cxxflags_button + + + + 0 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + Spacer16 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + fortran_tab + + + F&ortran + + + + unnamed + + + + f77compiler_label + + + Fortra&n compiler: + + + f77service_combo + + + + + f77service_combo + + + + + Spacer16_2 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + f77binary_label + + + Compiler co&mmand (F77): + + + f77binary_edit + + + + + f77binary_edit + + + + + Spacer17 + + + Vertical + + + Fixed + + + + 20 + 20 + + + + + + f77flags_label + + + Compiler f&lags (FFLAGS): + + + f77flags_edit + + + + + f77flags_edit + + + + + f77flags_button + + + + 0 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + Spacer18 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + + cflags_button + clicked() + configure_options_widget + cflagsClicked() + + + f77flags_button + clicked() + configure_options_widget + f77flagsClicked() + + + cservice_combo + activated(int) + configure_options_widget + cserviceChanged() + + + f77service_combo + activated(int) + configure_options_widget + f77serviceChanged() + + + cxxflags_button + clicked() + configure_options_widget + cxxflagsClicked() + + + cxxservice_combo + activated(int) + configure_options_widget + cxxserviceChanged() + + + addconfig_button + clicked() + configure_options_widget + configAdded() + + + removeconfig_button + clicked() + configure_options_widget + configRemoved() + + + config_combo + activated(const QString&) + configure_options_widget + configChanged(const QString&) + + + config_combo + textChanged(const QString&) + configure_options_widget + configComboTextChanged(const QString&) + + + builddir_button + clicked() + configure_options_widget + builddirClicked() + + + configargs_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + builddir_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + cbinary_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + cflags_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + cxxbinary_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + cxxflags_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + f77binary_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + f77flags_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + topsourcedir_button + clicked() + configure_options_widget + topsourcedirClicked() + + + topsourcedir_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + cppflags_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + ldflags_edit + textChanged(const QString&) + configure_options_widget + setDirty() + + + + configargs_edit + builddir_edit + builddir_button + topsourcedir_edit + topsourcedir_button + cppflags_edit + ldflags_edit + tabwidget + config_combo + addconfig_button + removeconfig_button + cservice_combo + cbinary_edit + cflags_edit + cflags_button + cxxservice_combo + cxxbinary_edit + cxxflags_edit + cxxflags_button + f77service_combo + f77binary_edit + f77flags_edit + f77flags_button + + + kdialog.h + + + builddirClicked() + cflagsClicked() + configAdded() + configChanged(const QString&) + configComboTextChanged(const QString&) + configRemoved() + cserviceChanged() + cxxflagsClicked() + cxxserviceChanged() + f77flagsClicked() + f77serviceChanged() + setDirty() + topsourcedirClicked() + + + + + klineedit.h + + diff --git a/buildtools/autotools/fileselectorwidget.cpp b/buildtools/autotools/fileselectorwidget.cpp new file mode 100644 index 00000000..65b87bf7 --- /dev/null +++ b/buildtools/autotools/fileselectorwidget.cpp @@ -0,0 +1,243 @@ +/**************************************************************************** + * Copyright (C) 2001 by Hugo Varotto * + * hugo@varotto-usa.com * + * * + * Based on Kate's fileselector widget by * + * Matt Newell * + * (C) 2001 by Matt Newell * + * newellm@proaxis.com * + * * + * 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 +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "fileselectorwidget.h" +#include +#include +#include +#include +#include +#include + +#include "autoprojectwidget.h" +#include "autoprojectpart.h" +#include "kdevlanguagesupport.h" + +#include "kfilednddetailview.h" +#include "kfiledndiconview.h" + +KDnDDirOperator::KDnDDirOperator ( const KURL &urlName, QWidget* parent, const char* name ) : KDirOperator ( urlName, parent, name ) +{ + +} + +KFileView* KDnDDirOperator::createView( QWidget* parent, KFile::FileView view ) +{ + KFileView* new_view = 0L; + + if( (view & KFile::Detail) == KFile::Detail ) { + new_view = new KFileDnDDetailView( parent, "detail view"); + } + else if ((view & KFile::Simple) == KFile::Simple ) { + new_view = new KFileDnDIconView( parent, "simple view"); + new_view->setViewName( i18n("Short View") ); + } + + return new_view; +} + + +FileSelectorWidget::FileSelectorWidget(AutoProjectPart* part, KFile::Mode mode, QWidget* parent, const char* name ) : QWidget(parent, name) +{ + m_part = part; + + // widgets and layout + QVBoxLayout* lo = new QVBoxLayout(this); + + QHBox *hlow = new QHBox (this); + lo->addWidget(hlow); + + home = new QPushButton( hlow ); + home->setPixmap(SmallIcon("gohome")); + QToolTip::add(home, i18n("Home directory")); + up = new QPushButton( /*i18n("&Up"),*/ hlow ); + up->setPixmap(SmallIcon("up")); + QToolTip::add(up, i18n("Up one level")); + back = new QPushButton( /*i18n("&Back"),*/ hlow ); + back->setPixmap(SmallIcon("back")); + QToolTip::add(back, i18n("Previous directory")); + forward = new QPushButton( /*i18n("&Next"),*/ hlow ); + forward->setPixmap(SmallIcon("forward")); + QToolTip::add(forward, i18n("Next directory")); + + // HACK + QWidget* spacer = new QWidget(hlow); + hlow->setStretchFactor(spacer, 1); + hlow->setMaximumHeight(up->height()); + + cmbPath = new KURLComboBox( KURLComboBox::Directories, true, this, "path combo" ); + cmbPath->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed )); + KURLCompletion* cmpl = new KURLCompletion(); + cmbPath->setCompletionObject( cmpl ); + lo->addWidget(cmbPath); + + dir = new KDnDDirOperator(KURL(), this, "operator"); + dir->setView(KFile::Simple); + dir->setMode(mode); + + lo->addWidget(dir); + lo->setStretchFactor(dir, 2); + + QHBox* filterBox = new QHBox(this); + filterIcon = new QLabel(filterBox); + filterIcon->setPixmap( BarIcon("filter") ); + filter = new KHistoryCombo(filterBox, "filter"); + filter->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed )); + filterBox->setStretchFactor(filter, 2); + lo->addWidget(filterBox); + + // slots and signals + connect( filter, SIGNAL( textChanged(const QString&) ), SLOT( slotFilterChanged(const QString&) ) ); + connect( filter, SIGNAL( activated(const QString&) ), SLOT( slotFilterChanged(const QString&) ) ); + connect( filter, SIGNAL( returnPressed(const QString&) ), SLOT( filterReturnPressed(const QString&) ) ); + + connect( home, SIGNAL( clicked() ), dir, SLOT( home() ) ); + connect( up, SIGNAL( clicked() ), dir, SLOT( cdUp() ) ); + connect( back, SIGNAL( clicked() ), dir, SLOT( back() ) ); + connect( forward, SIGNAL( clicked() ), dir, SLOT( forward() ) ); + + connect( cmbPath, SIGNAL( urlActivated( const KURL& )), this, SLOT( cmbPathActivated( const KURL& ) )); + //connect( cmbPath, SIGNAL( returnPressed( const QString& )), this, SLOT( cmbPathReturnPressed( const QString& ) )); + connect( dir, SIGNAL(urlEntered(const KURL&)), this, SLOT(dirUrlEntered(const KURL&)) ); + + connect( dir, SIGNAL(finishedLoading()), this, SLOT(dirFinishedLoading()) ); + +// dirUrlEntered( dir->url() ); + + QStringList list; + + /* read the file patterns from the project DOM */ + QDomElement docEl = m_part->projectDom()->documentElement(); + QDomElement fileviewEl = docEl.namedItem("kdevfileview").toElement(); + QDomElement groupsEl = fileviewEl.namedItem("groups").toElement(); + QDomElement groupEl = groupsEl.firstChild().toElement(); + + while ( !groupEl.isNull() ) + { + if (groupEl.tagName() == "group") + { + list << groupEl.attribute("pattern").replace ( QRegExp ( ";" ), " " ) + " (" + groupEl.attribute("name") + ")"; + } + groupEl = groupEl.nextSibling().toElement(); + } + + filter->setHistoryItems ( list ); + +} + + +FileSelectorWidget::~FileSelectorWidget() +{ +} + +void FileSelectorWidget::dragEnterEvent ( QDragEnterEvent* /*ev*/ ) +{ +} + +void FileSelectorWidget::dropEvent ( QDropEvent* /*ev*/ ) +{ + kdDebug ( 9020 ) << "Dropped" << endl; + + QString path = "Something was dropped in the Destination directory file-selector"; + + emit dropped ( path ); + +} + +void FileSelectorWidget::filterReturnPressed ( const QString& nf ) +{ + // KURL u ( m_part->project()->projectDirectory() ); + setDir ( nf ); +} + +void FileSelectorWidget::slotFilterChanged( const QString & nf ) +{ + dir->setNameFilter( nf ); + dir->updateDir(); +} + +void FileSelectorWidget::cmbPathActivated( const KURL& u ) +{ + dir->setURL( u, true ); +} + +void FileSelectorWidget::cmbPathReturnPressed( const QString& u ) +{ + dir->setFocus(); + dir->setURL( KURL(u), true ); +} + + +void FileSelectorWidget::dirUrlEntered( const KURL& u ) +{ + cmbPath->removeURL( u ); + QStringList urls = cmbPath->urls(); + urls.prepend( u.url() ); + while ( urls.count() >= (uint)cmbPath->maxItems() ) + urls.remove( urls.last() ); + cmbPath->setURLs( urls ); +} + + +void FileSelectorWidget::dirFinishedLoading() +{ + // HACK - enable the nav buttons + // have to wait for diroperator... + up->setEnabled( dir->actionCollection()->action( "up" )->isEnabled() ); + back->setEnabled( dir->actionCollection()->action( "back" )->isEnabled() ); + forward->setEnabled( dir->actionCollection()->action( "forward" )->isEnabled() ); + home->setEnabled( dir->actionCollection()->action( "home" )->isEnabled() ); +} + + +void FileSelectorWidget::focusInEvent(QFocusEvent*) +{ + dir->setFocus(); +} + +void FileSelectorWidget::setDir( KURL u ) +{ + dir->setURL(u, true); +} + +void FileSelectorWidget::setDir(const QString& path) +{ + KURL u ( path ); + dir->setURL ( u, true ); +} + + +#include "fileselectorwidget.moc" + diff --git a/buildtools/autotools/fileselectorwidget.h b/buildtools/autotools/fileselectorwidget.h new file mode 100644 index 00000000..7a981194 --- /dev/null +++ b/buildtools/autotools/fileselectorwidget.h @@ -0,0 +1,96 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _FILESELECTORWIDGET_H_ +#define _FILESELECTORWIDGET_H_ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +class AutoProjectPart; +class SubprojectItem; +class KFile; + +class KDnDDirOperator : public KDirOperator +{ + Q_OBJECT + +public: + KDnDDirOperator ( const KURL& urlName = KURL(), QWidget *parent = 0, const char* name = 0 ); + +protected: + virtual KFileView* createView( QWidget* parent, KFile::FileView view ); +}; + +class FileSelectorWidget : public QWidget +{ + Q_OBJECT + +public: + FileSelectorWidget( AutoProjectPart* part, KFile::Mode, QWidget* parent = 0, const char* name = 0 ); + ~FileSelectorWidget(); + + KDnDDirOperator * dirOperator() + { + return dir; + } + +public slots: + void slotFilterChanged( const QString& ); + void setDir( KURL ); + void setDir( const QString& ); + +private slots: + void cmbPathActivated( const KURL& u ); + void cmbPathReturnPressed( const QString& u ); + void dirUrlEntered( const KURL& u ); + void dirFinishedLoading(); + void filterReturnPressed( const QString& nf ); + +protected: + void focusInEvent( QFocusEvent* ); + void dragEnterEvent ( QDragEnterEvent* ev ); + void dropEvent ( QDropEvent* ev ); + +private: + KURLComboBox *cmbPath; + KHistoryCombo * filter; + QLabel* filterIcon; + KDnDDirOperator * dir; + QPushButton *home, *up, *back, *forward; + AutoProjectPart* m_part; + +signals: + void dropped ( const QString& ); + +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/kdevautoproject.desktop b/buildtools/autotools/kdevautoproject.desktop new file mode 100644 index 00000000..bc366556 --- /dev/null +++ b/buildtools/autotools/kdevautoproject.desktop @@ -0,0 +1,97 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Automake Project +Comment[br]=Raktres Automake +Comment[ca]=Projecte Automake +Comment[da]=Automake-projekt +Comment[de]=Automake-Projekt für KDevelop +Comment[el]=Έργο Automake +Comment[es]=Proyecto de Automake +Comment[et]=Automake'i project +Comment[eu]=Automake proiektua +Comment[fa]=پروژۀ Automake +Comment[fr]=Projet avec Automake +Comment[ga]=Comhad tionscadail Automake +Comment[gl]=Proxecto Automake +Comment[hi]=ऑटोमेक परियोजना +Comment[hu]=Automake-projekt +Comment[is]=Automake verkefni +Comment[it]=Progetto per automake +Comment[ja]=Automake プロジェクト +Comment[ms]=Projek Automake +Comment[nds]=Automake-Projekt +Comment[ne]=स्वत: निर्माण परियोजना +Comment[nl]=Automake-project +Comment[pa]=ਆਟੋਮੈਕ ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Automake +Comment[pt]=Projecto Automake +Comment[pt_BR]=Projeto Automake +Comment[ru]=Проект Automake +Comment[sk]=Automake projekt +Comment[sl]=Projekt automake +Comment[sr]=Automake пројекат +Comment[sr@Latn]=Automake projekat +Comment[sv]=Automake-projekt +Comment[ta]=ஆட்டோமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи Automake +Comment[tr]=Automake Projesi +Comment[uz]=Automake loyihasi +Comment[uz@cyrillic]=Automake лойиҳаси +Comment[zh_CN]=Automake 工程 +Comment[zh_TW]=Automake 專案 +Name=KDevAutoProject +Name[da]=KDevelop Automake-projekt +Name[de]=Automake-Projekt (KDevelop) +Name[hi]=के-डेव-ऑटो-परियोजना +Name[nds]=Automake-Projekt (KDevelop) +Name[ne]=केडीई विकास स्वत: परियोजना +Name[pl]=KDevProjektAuto +Name[pt_BR]=KDevAutoProjeto +Name[sk]=KDevAutoProjekt +Name[sv]=KDevelop autoprojekt +Name[ta]=கெடெவ்ஆட்டோ பிராஜக்ட் +Name[tg]=Лоиҳаи KDevAuto +Name[zh_TW]=KDevelop Automake 專案 +GenericName=Automake Project +GenericName[br]=Raktres Automake +GenericName[ca]=Projecte Automake +GenericName[da]=Automake-projekt +GenericName[de]=Automake-Projekt +GenericName[el]=Έργο Automake +GenericName[es]=Proyecto de Automake +GenericName[et]=Automake'i projekt +GenericName[eu]=Automake proiektua +GenericName[fa]=پروژۀ Automake +GenericName[fr]=Projet avec Automake +GenericName[ga]=Comhad tionscadail Automake +GenericName[gl]=Proxecto Automake +GenericName[hi]=ऑटोमेक परियोजना +GenericName[hu]=Automake-projekt +GenericName[it]=Progetto Automake +GenericName[ja]=Automake プロジェクト +GenericName[ms]=Projek Automake +GenericName[nds]=Automake-Projekt +GenericName[ne]=स्वत: निर्माण परियोजना +GenericName[nl]=Automake-project +GenericName[pl]=Projekt: Automake +GenericName[pt]=Projecto de Automake +GenericName[pt_BR]=Projeto Automake +GenericName[ru]=Проект Automake +GenericName[sk]=Automake projekt +GenericName[sl]=Projekt automake +GenericName[sr]=Automake пројекат +GenericName[sr@Latn]=Automake projekat +GenericName[sv]=Automake-projekt +GenericName[ta]=ஆட்டோமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи Automake +GenericName[tr]=Automake Projesi +GenericName[uz]=Automake loyihasi +GenericName[uz@cyrillic]=Automake лойиҳаси +GenericName[zh_CN]=Automake 工程 +GenericName[zh_TW]=Automake 專案 +ServiceTypes=KDevelop/Project +Icon=make +X-KDE-Library=libkdevautoproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/autotools/kdevautoproject.rc b/buildtools/autotools/kdevautoproject.rc new file mode 100644 index 00000000..89571c11 --- /dev/null +++ b/buildtools/autotools/kdevautoproject.rc @@ -0,0 +1,30 @@ + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/buildtools/autotools/kdevkdeautoproject.desktop b/buildtools/autotools/kdevkdeautoproject.desktop new file mode 100644 index 00000000..235f3071 --- /dev/null +++ b/buildtools/autotools/kdevkdeautoproject.desktop @@ -0,0 +1,92 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=KDE Automake Project +Comment[br]=Raktres KDE Automake +Comment[ca]=Projecte Automake per al KDE +Comment[da]=KDE Automake-projekt +Comment[de]=KDE-Automake-Projekt für KDevelop +Comment[el]=Έργο KDE Automake +Comment[es]=Proyecto de Automake de KDE +Comment[et]=KDE automake'i projekt +Comment[eu]=KDE automake proiektua +Comment[fa]=پروژۀ KDE Automake +Comment[fr]=Projet Automake pour KDE +Comment[ga]=Tionscadal Automake KDE +Comment[gl]=Proxecto Automake de KDE +Comment[hi]=केडीई ऑटोमेक परियोजना +Comment[hu]=KDE Automake-projekt +Comment[is]=KDE Automake verkefni +Comment[it]=Progetto KDE per automake +Comment[ja]=KDE Automake プロジェクト +Comment[ms]=Projek Automake KDE +Comment[nds]=Automake-Projekt vun KDE +Comment[ne]=केडीई स्वत: निर्माण परियोजना +Comment[nl]=KDE Automake-project +Comment[pt]=Projecto Automake do KDE +Comment[pt_BR]=Projeto Automake do KDE +Comment[ru]=Проект KDE Automake +Comment[sk]=KDE Automake projekt +Comment[sl]=Projekt KDE Automake +Comment[sr]=KDE-ов Automake пројекат +Comment[sr@Latn]=KDE-ov Automake projekat +Comment[sv]=KDE Automake-projekt +Comment[ta]=KDE ஆட்டோமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи KDE Automake +Comment[tr]=KDE Automake Projesi +Comment[zh_CN]=KDE Automake 工程 +Comment[zh_TW]=KDE Automake 專案 +Name=KDevKDEAutoProject +Name[da]=KDevelop KDE Automake-projekt +Name[de]=KDE-Automake-Projekt (KDevelop) +Name[hi]=के-डेव-केडीई-ऑटो-परियोजना +Name[nds]=Automake-Projekt (KDE/KDevelop) +Name[ne]=केडीई विकास केडीई स्वत: परियोजना +Name[pl]=KDevProjektKDEAuto +Name[pt_BR]=KDevKDEAutoProjeto +Name[sk]=KDevAutoProjekt +Name[sv]=KDevelop KDE-autoprojekt +Name[ta]=கெடெவ்ஆட்டோ பிராஜக்ட் +Name[tg]=Лоиҳаи худкори KDevKDEAuto +Name[zh_TW]=KDevelop KDE Automake 專案 +GenericName=KDE Automake Project +GenericName[br]=Raktres KDE Automake +GenericName[ca]=Projecte Automake per al KDE +GenericName[cs]=KDE Automake projekt +GenericName[da]=KDE Automake-projekt +GenericName[de]=KDE-Automake-Projekt +GenericName[el]=Έργο KDE Automake +GenericName[es]=Proyecto de Automake de KDE +GenericName[et]=KDE automake'i projekt +GenericName[eu]=KDE automake proiektua +GenericName[fa]=پروژۀ KDE Automake +GenericName[fr]=Projet avec Automake pour KDE +GenericName[ga]=Tionscadal Automake KDE +GenericName[gl]=Proxecto Automake de KDE +GenericName[hi]=केडीई ऑटोमेक परियोजना +GenericName[hu]=KDE Automake-projekt +GenericName[it]=Progetto KDE Automake +GenericName[ja]=KDE Automake プロジェクト +GenericName[ms]=Projek Automake KDE +GenericName[nds]=Automake-Projekt vun KDE +GenericName[ne]=केडीई स्वत: निर्माण परियोजना +GenericName[nl]=KDE Automake-project +GenericName[pl]=Projekt: KDE Automake +GenericName[pt]=Projecto KDE com Automake +GenericName[pt_BR]=Projeto Automake do KDE +GenericName[ru]=Проект KDE Automake +GenericName[sk]=KDE Automake projekt +GenericName[sl]=Projekt KDE Automake +GenericName[sr]=KDE-ов Automake пројекат +GenericName[sr@Latn]=KDE-ov Automake projekat +GenericName[sv]=KDE Automake-projekt +GenericName[ta]=KDE ஆட்டோமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи KDE Automake +GenericName[tr]=KDE Automake Projesi +GenericName[zh_CN]=KDE Automake 工程 +GenericName[zh_TW]=KDE Automake 專案 +ServiceTypes=KDevelop/Project +Icon=make +X-KDE-Library=libkdevautoproject +X-KDevelop-Version=5 +X-KDevelop-Args=kde diff --git a/buildtools/autotools/kfilednddetailview.cpp b/buildtools/autotools/kfilednddetailview.cpp new file mode 100644 index 00000000..c75022fb --- /dev/null +++ b/buildtools/autotools/kfilednddetailview.cpp @@ -0,0 +1,212 @@ +/*************************************************************************** +* kfilednddetailview.cpp - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bj�n Sahlstr� +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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. * +* * +***************************************************************************/ + +////////////////////////////////////////////////////// +// Qt specific includes +#include +#include +////////////////////////////////////////////////////// +// KDE specific includes +#include +#include +#include +////////////////////////////////////////////////////// +// Application specific includes +#include "kfilednddetailview.h" + +#ifndef AUTO_OPEN_TIME +#define AUTO_OPEN_TIME + static int autoOpenTime = 750; +#endif +//----------------------------------------------- +KFileDnDDetailView::KFileDnDDetailView(QWidget *parent, const char *name ) + : KFileDetailView(parent,name), m_autoOpenTimer( this ), + m_autoOpenTime( autoOpenTime ), m_useAutoOpenTimer( true ), + m_dropItem(0), m_dndEnabled( true ) +{ + setAutoUpdate( true ); + setDnDEnabled( true ); + useAutoOpenTimer( true ); +} +//----------------------------------------------- +KFileDnDDetailView::~KFileDnDDetailView(){ +} +//----------------------------------------------- +void KFileDnDDetailView::readConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + bool dnd = config->readBoolEntry("DragAndDrop", true ); + setDnDEnabled( dnd ); + KFileDetailView::readConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDDetailView::writeConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + config->writeEntry("DragAndDrop", m_dndEnabled ); + KFileDetailView::writeConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDDetailView::slotOpenFolder(){ + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + if( !m_dropItem ) + return; + } + KFileItemListIterator it( * KFileView::items() ); + for( ; it.current() ;++it ){ + if( (*it)->name() == m_dropItem->text(0) ) { + if( (*it)->isFile() ) + return; + else if( (*it)->isDir() || (*it)->isLink()) { + sig->activate( (*it) ); + return; + } + } + } +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDragEnterEvent( QDragEnterEvent *e ) { + + kdDebug (9020) << "KFileDnDDetailView::contentsDragEnterEvent" << endl; + + if ( ! acceptDrag( e ) ) { + e->accept( false ); + return; + } + e->acceptAction(); + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if ( i && m_useAutoOpenTimer ) { + m_dropItem = i; + m_autoOpenTimer.start( m_autoOpenTime ); + } +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDragMoveEvent( QDragMoveEvent *e ) { + + kdDebug (9020) << "KFileDnDDetailView::contentsDragMoveEvent" << endl; + + if ( ! acceptDrag( e ) ) { + e->accept( false ); + return; + } + e->acceptAction(); + QListViewItem *i = itemAt( contentsToViewport( e->pos() ) ); + if( ! m_useAutoOpenTimer ) + return; + if ( i ) { + if ( i != m_dropItem ) { + m_autoOpenTimer.stop(); + m_dropItem = i; + m_autoOpenTimer.start( m_autoOpenTime ); + } + } + else + m_autoOpenTimer.stop(); +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDragLeaveEvent( QDragLeaveEvent* ) { + + kdDebug (9020) << "KFileDnDDetailView::contentsDragLeaveEvent" << endl; + + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } +} +//----------------------------------------------- +void KFileDnDDetailView::contentsDropEvent( QDropEvent* e ) { + + kdDebug (9020) << "KFileDndDetailView::contentsDropEvent" << endl; + + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } + if( ! acceptDrag( e ) ) { + e->acceptAction( false ); + return; + } + e->acceptAction(); + // the drop was accepted so lets emit this to the outside world + KURL::List urls; + KURLDrag::decode( e, urls ); + emit dropped( e ); + emit dropped( this, e ); + emit dropped( this, urls ); +} +//----------------------------------------------- +void KFileDnDDetailView::startDrag(){ + + kdDebug (9020) << "KFileDnDDetailView::startDrag()" << endl; + + // create a list of the URL:s that we want to drag + KURL::List urls; + KFileItemListIterator it( * KFileView::selectedItems() ); + for ( ; it.current(); ++it ){ + urls.append( (*it)->url() ); + } + QPixmap pixmap; + if( urls.count() > 1 ){ + pixmap = DesktopIcon( "kmultiple", 16 ); + } + if( pixmap.isNull() ) + pixmap = currentFileItem()->pixmap( 16 ); + QPoint hotspot; + hotspot.setX( pixmap.width() / 2 ); + hotspot.setY( pixmap.height() / 2 ); + m_dragObject = KURLDrag::newDrag( urls, widget() ); + m_dragObject->setPixmap( pixmap, hotspot ); + m_dragObject->drag(); // start the drag +} +//----------------------------------------------- +QDragObject* KFileDnDDetailView::dragObject() const { + return m_dragObject; +} +//----------------------------------------------- +bool KFileDnDDetailView::acceptDrag(QDropEvent* e ) const { + return KURLDrag::canDecode( e ) && + ( e->action() == QDropEvent::Copy + || e->action() == QDropEvent::Move + || e->action() == QDropEvent::Link ); +} +//----------------------------------------------- +void KFileDnDDetailView::setAutoOpenTime( const int& time ){ + m_autoOpenTime = time; + useAutoOpenTimer(); +} +//----------------------------------------------- +void KFileDnDDetailView::useAutoOpenTimer( bool use ){ + m_useAutoOpenTimer = use; + if( use ) + connect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + else { + disconnect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + m_dropItem = 0L; + m_autoOpenTimer.stop(); + } +} +//----------------------------------------------- +void KFileDnDDetailView::setDnDEnabled( bool useDnD ){ + m_dndEnabled = useDnD; + setDragEnabled( useDnD ); + setDropVisualizer( useDnD ); + setAcceptDrops( useDnD ); + viewport()->setAcceptDrops( useDnD ); +} +//----------------------------------------------- +#ifndef NO_INCLUDE_MOCFILES +#include "kfilednddetailview.moc" +#endif diff --git a/buildtools/autotools/kfilednddetailview.h b/buildtools/autotools/kfilednddetailview.h new file mode 100644 index 00000000..ecb232c6 --- /dev/null +++ b/buildtools/autotools/kfilednddetailview.h @@ -0,0 +1,136 @@ +/*************************************************************************** +* kfilednddetailview.h - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bjrn Sahlstrm +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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. * +* * +**************************************************************************/ + +#ifndef KFILEDNDDETAILVIEW_H +#define KFILEDNDDETAILVIEW_H + +////////////////////////////////////////////////////////////////////// +// Qt specific include files +#include +#include +////////////////////////////////////////////////////////////////////// +// KDE specific include files +#include +#include + + +/** + *This is a fileview inherited from @ref KFileDetailView. + *It adds "drag and drop" handling to the view suitable for a @ref KFileDetailView. + * No special setup is needed, just connect to the @ref dropped signals + * and the view will take care of the rest. + *@short "Drag and drop" aware @ref KFileDetailView + *@author Bjrn Sahlstrm + */ + +class KFileDnDDetailView : public KFileDetailView +{ + Q_OBJECT +public: + /** */ + KFileDnDDetailView( QWidget *parent = 0, const char *name = 0 ); + /** */ + virtual ~KFileDnDDetailView(); + /** + * Set this to true if Drag'n drop should be enabled or not, default is enabled + */ + void setDnDEnabled( bool ); + /** + * @returns wether DnD is enabled or not. + */ + bool isDnDEnabled() const + { + return m_dndEnabled; + } + /** + *Sets the auto open time, which means the time that will + *elapse before a directory is automatically opened after entered by DnD. + *Only need to call this if you want to change the predefined time that is 750 ms. + *This also calls @ref #useAutoOpenTimer so no need to call this to. + */ + void setAutoOpenTime( const int& time ); + /** + *Set this to true if you want the view to use it's auto open functionallity otherwhise set it to false. + *By default this is turned ON. + */ + void useAutoOpenTimer( bool on = true ); + /** + *@returns true if auto open functionallity is turned ON (default), otherwhise false + *@see #useAutoOpenTimer + *@see #setAutoOpenTime + */ + bool isAutoOpening() const + { + return m_useAutoOpenTimer; + } + /** */ + virtual void readConfig( KConfig*, const QString& group = QString::null ); + /** */ + virtual void writeConfig( KConfig*, const QString& group = QString::null ); +signals: // Signals + /** + * Emitted whenever an decodable item is dropped in the view. + * Note: The @ref QDropEvent contains a @ref KURLDrag object. + */ + void dropped( QDropEvent* ); + /** + * Emitted whenever an decodable item is dropped in the view + * Note: The @ref QDropEvent contains a @ref KURLDrag object. + */ + void dropped( KFileView*, QDropEvent* ); + /** + * Emitted whenever an decodable item is dropped in the view. + *@param urls contains a list of all dropped @ref KURL + */ + void dropped( KFileView*, KURL::List& urls ); +protected slots: // Protected slots + /** + * Called when the auto timer times out. Open the current folder. + */ + void slotOpenFolder(); +protected: //Protected Methods + /** */ + virtual void contentsDragEnterEvent( QDragEnterEvent *e ); + /** */ + virtual void contentsDragMoveEvent( QDragMoveEvent *e ); + /** */ + virtual void contentsDragLeaveEvent( QDragLeaveEvent *e ); + /** */ + virtual void contentsDropEvent( QDropEvent* e ); + /** + * Create dragobject encoding the current selection and starts the drag + */ + virtual void startDrag(); + /** + * @returns the dragObject + */ + virtual QDragObject* dragObject() const; + /** + * @returns true if we can decode the drag and support the action + */ + virtual bool acceptDrag( QDropEvent* event ) const; +protected: // Private attributes + QTimer m_autoOpenTimer; + int m_autoOpenTime; + bool m_useAutoOpenTimer; + QListViewItem* m_dropItem; + KURLDrag* m_dragObject; + bool m_dndEnabled; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/kfiledndiconview.cpp b/buildtools/autotools/kfiledndiconview.cpp new file mode 100644 index 00000000..47bb32a9 --- /dev/null +++ b/buildtools/autotools/kfiledndiconview.cpp @@ -0,0 +1,194 @@ +/*************************************************************************** +* kfiledndiconview.cpp - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bjrn Sahlstrm +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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. * +* * +***************************************************************************/ + +////////////////////////////////////////////////////// +// Qt specific includes +#include +#include +////////////////////////////////////////////////////// +// KDE specific includes +#include +#include +#include +////////////////////////////////////////////////////// +// Application specific includes +#include "kfiledndiconview.h" + +#ifndef AUTO_OPEN_TIME +#define AUTO_OPEN_TIME + static int autoOpenTime = 750; +#endif +//----------------------------------------------- +KFileDnDIconView::KFileDnDIconView( QWidget *parent, const char *name ) + : KFileIconView(parent,name), m_autoOpenTimer( this ), + m_autoOpenTime( autoOpenTime ), m_useAutoOpenTimer( true ), + m_dropItem(0), m_dndEnabled( true ) +{ + setDnDEnabled( true ); + setAutoUpdate( true ); + useAutoOpenTimer( true ); +} +//----------------------------------------------- +KFileDnDIconView::~KFileDnDIconView(){ +} +//----------------------------------------------- +void KFileDnDIconView::readConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + bool dnd = config->readBoolEntry("EnableDND", true ); + setDnDEnabled( dnd ); + KFileIconView::readConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDIconView::writeConfig( KConfig* config, const QString& group ) { + KConfigGroupSaver cs( config, group ); + config->writeEntry("EnableDND", m_dndEnabled ); + KFileIconView::writeConfig( config, group ); +} +//----------------------------------------------- +void KFileDnDIconView::slotOpenFolder(){ + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + if( !m_dropItem ) + return; + } + KFileItemListIterator it( * KFileView::items() ); + for( ; it.current() ;++it ){ + if( (*it)->name() == m_dropItem->text() ) { + if( (*it)->isFile() ) + return; + else if( (*it)->isDir() || (*it)->isLink()) { + sig->activate( (*it) ); + return; + } + } + } +} +//----------------------------------------------- +void KFileDnDIconView::contentsDragEnterEvent( QDragEnterEvent *e ) { + if ( ! acceptDrag( e ) ) { // can we decode this ? + e->accept( false ); // No + return; + } + e->acceptAction(); // Yes + QIconViewItem *i = findItem( contentsToViewport( e->pos() ) ); + if ( i && m_useAutoOpenTimer) { // are we over an item ? + m_dropItem = i; // set new m_dropItem + m_autoOpenTimer.start( m_autoOpenTime ); // restart timer + } +} +//----------------------------------------------- +void KFileDnDIconView::contentsDragMoveEvent( QDragMoveEvent *e ) { + if ( ! acceptDrag( e ) ) { // can we decode this ? + e->accept( false ); // No + return; + } + e->acceptAction(); // Yes + QIconViewItem *i = findItem( contentsToViewport( e->pos() ) ); + if( ! m_useAutoOpenTimer ) + return; + if ( i ) { // are we over an item ? + if ( i != m_dropItem ) { // if so, is it a new one ? + m_autoOpenTimer.stop(); // stop timer + m_dropItem = i; // set new m_dropItem + m_autoOpenTimer.start( m_autoOpenTime ); // restart timer + } + } + else + m_autoOpenTimer.stop(); // stop timer +} +//----------------------------------------------- +void KFileDnDIconView::contentsDragLeaveEvent( QDragLeaveEvent* ) { + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } +} +//----------------------------------------------- +void KFileDnDIconView::contentsDropEvent( QDropEvent* e ) { + if( m_useAutoOpenTimer ) { + m_autoOpenTimer.stop(); + m_dropItem = 0L; + } + if( ! acceptDrag( e ) ) { + e->acceptAction( false ); + return; + } + e->acceptAction(); + // the drop was accepted so lets emit this + KURL::List urls; + KURLDrag::decode( e, urls ); + emit dropped( e ); +} +//----------------------------------------------- +void KFileDnDIconView::startDrag(){ + if ( ! currentItem() ) // is there any selected items ? + return; // nope + dragObject()->dragCopy(); // start the drag +} +//----------------------------------------------- +QDragObject* KFileDnDIconView::dragObject() { + // create a list of the URL:s that we want to drag + KURL::List urls; + KFileItemListIterator it( * KFileView::selectedItems() ); + for ( ; it.current(); ++it ){ + urls.append( (*it)->url() ); + } + QPixmap pixmap; + if( urls.count() > 1 ) + pixmap = DesktopIcon( "kmultiple", iconSize() ); + if( pixmap.isNull() ) + pixmap = currentFileItem()->pixmap( iconSize() ); + QPoint hotspot; + hotspot.setX( pixmap.width() / 2 ); + hotspot.setY( pixmap.height() / 2 ); + QDragObject* myDragObject = KURLDrag::newDrag( urls, widget() ); + myDragObject->setPixmap( pixmap, hotspot ); + return myDragObject; +} +//----------------------------------------------- +void KFileDnDIconView::setAutoOpenTime( const int& time ){ + m_autoOpenTime = time; + useAutoOpenTimer(); +} +//----------------------------------------------- +void KFileDnDIconView::useAutoOpenTimer( bool use ){ + m_useAutoOpenTimer = use; + if ( use ) + connect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + else { + disconnect( &m_autoOpenTimer, SIGNAL( timeout() ),this, SLOT( slotOpenFolder() ) ); + m_dropItem = 0L; + m_autoOpenTimer.stop(); + } +} +//----------------------------------------------- +void KFileDnDIconView::setDnDEnabled( bool useDnD ){ + m_dndEnabled = useDnD; + setAcceptDrops( useDnD ); + viewport()->setAcceptDrops( useDnD ); +} +//----------------------------------------------- +bool KFileDnDIconView::acceptDrag(QDropEvent* e ) const { + return KURLDrag::canDecode( e ) && + ( e->action() == QDropEvent::Copy + || e->action() == QDropEvent::Move + || e->action() == QDropEvent::Link ); +} +//----------------------------------------------- +#ifndef NO_INCLUDE_MOCFILES +#include "kfiledndiconview.moc" +#endif diff --git a/buildtools/autotools/kfiledndiconview.h b/buildtools/autotools/kfiledndiconview.h new file mode 100644 index 00000000..65edd91a --- /dev/null +++ b/buildtools/autotools/kfiledndiconview.h @@ -0,0 +1,128 @@ +/************************************************************************** +* kfiledndiconview.h - description +* ------------------- +* begin : Wed Nov 1 2000 +* copyright : (C) 2000 by Bjrn Sahlstrm +* email : kbjorn@users.sourceforge.net +***************************************************************************/ + +/*************************************************************************** +* * +* 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. * +* * +**************************************************************************/ + +#ifndef KFILEDNDICONVIEW_H +#define KFILEDNDICONVIEW_H + +#include +#include +#include +#include + +/** + * This is a fileview inherited from @ref KFileIconView. + * It adds "drag and drop" suitable for a @ref KFileIconView + * No special setup is needed, just connect to the @ref dropped signals + * and the view will take care of the rest. + * @short Drag and drop" aware @ref KFileIconView + * @author Bjrn Sahlstrm +*/ + +class KFileDnDIconView : public KFileIconView +{ + Q_OBJECT +public: // Public methods + + KFileDnDIconView( QWidget *parent = 0, const char *name = 0 ); + virtual ~KFileDnDIconView(); + + /** + * Set if Drag'n drop should be enabled or not, default is enabled. + */ + void setDnDEnabled( bool ); + + /** + * @returns wether DnD is enabled or not. + */ + bool isDnDEnabled() const + { + return m_dndEnabled; + } + + /** + * Sets the auto open time, which means the time that will + * elapse before a directory is automatically opened after entered by DnD. + * Only need to call this if you want to change the predefined time that is 750 ms. + * This also calls @ref #useAutoOpenTimer so no need to call this to. + */ + void setAutoOpenTime( const int& time ); + + /** + * Set this to true if you want the view to use it's auto open functionallity otherwhise set it to false. + * By default this is turned ON. + */ + void useAutoOpenTimer( bool on = true ); + + /** + * @returns true if auto open functionallity is turned ON (default), otherwhise false + * @see #useAutoOpenTimer + * @see #setAutoOpenTime + */ + bool isAutoOpening() const + { + return m_useAutoOpenTimer; + } + + virtual void readConfig( KConfig*, const QString& group = QString::null ); + virtual void writeConfig( KConfig*, const QString& group = QString::null ); +signals: + + /** + * Emitted whenever an decodable item is dropped in the view. + * Note: The @ref QDropEvent contains a @ref KURLDrag object. + */ + void dropped( QDropEvent* ); + +protected slots: + /** + * Called when the auto timer times out. Open the current folder. + */ + void slotOpenFolder(); + +protected: + virtual void contentsDragEnterEvent( QDragEnterEvent *e ); + virtual void contentsDragMoveEvent( QDragMoveEvent *e ); + virtual void contentsDragLeaveEvent( QDragLeaveEvent *e ); + virtual void contentsDropEvent( QDropEvent* e ); + + /** + * Creates a @ref QDragObject containing all urls of the selected @ref KFileItem of the view, + * @returns the @ref QDragObject + */ + virtual QDragObject* dragObject(); + + /** + *Creates the drag item and starts the drag + */ + virtual void startDrag(); + + /** + *@returns true if we can decode the drag and support the action + */ + virtual bool acceptDrag( QDropEvent* event ) const; + +protected: + + QTimer m_autoOpenTimer; + int m_autoOpenTime; + bool m_useAutoOpenTimer; + QIconViewItem* m_dropItem; + bool m_dndEnabled; +}; +#endif +// kate: indent-mode csands; tab-width 4; auto-insert-doxygen on; + diff --git a/buildtools/autotools/kimporticonview.cpp b/buildtools/autotools/kimporticonview.cpp new file mode 100644 index 00000000..9b64d3ee --- /dev/null +++ b/buildtools/autotools/kimporticonview.cpp @@ -0,0 +1,87 @@ +/*************************************************************************** + ------------------- + begin : 19.01.2003 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 +#include +#include +#include + +#include +#include +#include + +#include "kimporticonview.h" + + +KImportIconView::KImportIconView(const QString& strIntro, QWidget *parent, const char *name) + : KFileDnDIconView(parent, name) +{ + m_strIntro = strIntro; + m_bDropped = false; + + setAcceptDrops ( true ); +} + + +KImportIconView::~KImportIconView() +{ +} + +void KImportIconView::drawContents ( QPainter *p, int cx, int cy, int cw, int ch ) +{ + if ( !m_bDropped) + { + QIconView::drawContents ( p, cx, cy, cw, ch ); + + p->save(); + QFont font ( p->font() ); + font.setBold ( true ); + font.setFamily ( "Helvetica [Adobe]" ); + font.setPointSize ( 10 ); + p->setFont ( font ); + p->setPen ( QPen ( KGlobalSettings::highlightColor() ) ); + + QRect rect = frameRect(); + QFontMetrics fm ( p->font() ); + rect.setLeft ( rect.left() + 30 ); + rect.setRight ( rect.right() - 30 ); + + resizeContents ( contentsWidth(), contentsHeight() ); + + // word-wrap the string + KWordWrap* wordWrap1 = KWordWrap::formatText( fm, rect, AlignHCenter | WordBreak, m_strIntro ); + KWordWrap* wordWrap2 = KWordWrap::formatText( fm, rect, AlignHCenter | WordBreak, i18n("Or just use the buttons.") ); + + QRect introRect1 = wordWrap1->boundingRect(); + QRect introRect2 = wordWrap2->boundingRect(); + + wordWrap1->drawText ( p, ( ( frameRect().right() - introRect1.right() ) / 2 ), ( ( frameRect().bottom() - introRect1.bottom() ) / 2 ) - 20, AlignHCenter | AlignVCenter ); + wordWrap2->drawText ( p, ( ( frameRect().right() - introRect2.right() ) / 2 ), ( ( frameRect().bottom() - introRect2.bottom() ) / 2 ) + introRect1.bottom(), AlignHCenter | AlignVCenter ); + + p->restore(); + } + else + { + QIconView::drawContents ( p, cx, cy, cw, ch ); + } +} + +void KImportIconView::somethingDropped ( bool dropped ) +{ + m_bDropped = dropped; +} + +#include "kimporticonview.moc" diff --git a/buildtools/autotools/kimporticonview.h b/buildtools/autotools/kimporticonview.h new file mode 100644 index 00000000..100fc33e --- /dev/null +++ b/buildtools/autotools/kimporticonview.h @@ -0,0 +1,44 @@ +/*************************************************************************** + ------------------- + begin : 19.01.2003 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef KIMPORTICONVIEW_H +#define KIMPORTICONVIEW_H + +#include + +#include "kfiledndiconview.h" + +class KImportIconView : public KFileDnDIconView +{ + Q_OBJECT + +public: + KImportIconView( const QString& strIntro, QWidget *parent, const char *name ); + virtual ~KImportIconView(); + + void somethingDropped ( bool dropped ); + +protected: + void drawContents ( QPainter *p, int cx, int cy, int cw, int ch ); + +private: + QString m_strIntro; + bool m_bDropped; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/makefilehandler.cpp b/buildtools/autotools/makefilehandler.cpp new file mode 100644 index 00000000..03ad5277 --- /dev/null +++ b/buildtools/autotools/makefilehandler.cpp @@ -0,0 +1,166 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers + +*************************************************************************** +* * +* 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 +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "makefilehandler.h" + +typedef QValueList ASTList; + +class MakefileHandler::Private +{ +public: + QMap projects; + QMap folderToFileMap; +}; + +MakefileHandler::MakefileHandler() +{ + d = new MakefileHandler::Private; +} + +MakefileHandler::~MakefileHandler() +{ + delete d; +} + +void MakefileHandler::parse( const QString& folder, bool recursive ) +{ + //look for either Makefile.am.in, Makefile.am, or Makefile.in, in that order + AutoTools::ProjectAST* ast; + int ret = -1; + QString filePath = folder + "/Makefile.am.in"; + if ( QFile::exists( filePath ) ) + ret = AutoTools::Driver::parseFile( filePath, &ast ); + else + { + filePath = folder + "/Makefile.am"; + if ( QFile::exists( filePath ) ) + ret = AutoTools::Driver::parseFile( filePath, &ast ); + else + { + filePath = folder + "/Makefile.in"; + if ( QFile::exists( filePath ) ) + ret = AutoTools::Driver::parseFile( filePath, &ast ); + else + kdDebug(9020) << k_funcinfo << "no appropriate file to parse in " + << folder << endl; + } + } + + if ( ret != 0 ) + { + return; + } + + kdDebug(9020) << k_funcinfo << filePath << " was parsed correctly. Adding information" << endl; + Q_ASSERT( ast != 0 ); + d->projects[filePath] = ast; + d->folderToFileMap[folder] = filePath; + + if ( recursive && ast && ast->hasChildren() ) + { + QValueList astChildList = ast->children(); + QValueList::iterator it(astChildList.begin()), clEnd(astChildList.end()); + for ( ; it != clEnd; ++it ) + { + if ( (*it)->nodeType() == AutoTools::AST::AssignmentAST ) + { + AutoTools::AssignmentAST* assignment = static_cast( (*it) ); + if ( assignment->scopedID == "SUBDIRS" ) + { + QString list = assignment->values.join( QString::null ); + list.simplifyWhiteSpace(); + kdDebug(9020) << k_funcinfo << "subdirs is " << list << endl; + QStringList subdirList = QStringList::split( " ", list ); + QStringList::iterator vit = subdirList.begin(); + for ( ; vit != subdirList.end(); ++vit ) + { + QString realDir = ( *vit ); + if ( realDir.startsWith( "\\" ) ) + realDir.remove( 0, 1 ); + + realDir = realDir.stripWhiteSpace(); + if ( realDir != "." && realDir != ".." && !realDir.isEmpty() ) + { + if ( isVariable( realDir ) ) + { + kdDebug(9020) << k_funcinfo << "'" << realDir << "' is a variable" << endl; + realDir = resolveVariable( realDir, ast ); + } + + kdDebug(9020) << k_funcinfo << "Beginning parsing of '" << realDir << "'" << endl; + parse( folder + '/' + realDir, recursive ); + } + } + } + } + } + } +} + +AutoTools::ProjectAST* MakefileHandler::astForFolder( const QString& folderPath ) +{ + if ( d->folderToFileMap.contains( folderPath ) ) + { + QString filePath = d->folderToFileMap[folderPath]; + return d->projects[filePath]; + } + else + return 0; +} + +bool MakefileHandler::isVariable( const QString& item ) const +{ + if ( item.contains( QRegExp( "(\\$\\([a-zA-Z0-9_-]*\\)|@[a-zA-Z0-9_-]*@)" ) ) ) + return true; + else + return false; +} + +QString MakefileHandler::resolveVariable( const QString& variable, AutoTools::ProjectAST* ast ) +{ + if ( !ast ) + return variable; + + kdDebug(9020) << k_funcinfo << "attempting to resolve '" << variable << "'"<< endl; + ASTList childList = ast->children(); + ASTList::iterator it( childList.begin() ), clEnd( childList.end() ); + for ( ; it != clEnd; ++it ) + { + if ( ( *it )->nodeType() == AutoTools::AST::AssignmentAST ) + { + AutoTools::AssignmentAST* assignment = static_cast( ( *it ) ); + if ( variable.find( assignment->scopedID ) != -1 ) + { + kdDebug(9020) << k_funcinfo << "Resolving variable '" << variable << "' to '" + << assignment->values.join( QString::null ).stripWhiteSpace() << "'" << endl; + return assignment->values.join( QString::null ).stripWhiteSpace(); + } + } + } + + return variable; +} +//kate: space-indent on; indent-width 4; diff --git a/buildtools/autotools/makefilehandler.h b/buildtools/autotools/makefilehandler.h new file mode 100644 index 00000000..77045fe9 --- /dev/null +++ b/buildtools/autotools/makefilehandler.h @@ -0,0 +1,76 @@ +/* + KDevelop Autotools Support + Copyright (c) 2005 by Matt Rogers + +*************************************************************************** +* * +* 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. * +* * +*************************************************************************** +*/ +#ifndef MAKEFILEHANDLER_H +#define MAKEFILEHANDLER_H + +/** + * This class is responsible for taking the data from the Makefile.am parser + * and providing various data list view items can use in the automake manager + * widget + * @author Matt Rogers + */ +namespace AutoTools { +class ProjectAST; +} + +class MakefileHandler +{ +public: + MakefileHandler(); + ~MakefileHandler(); + + /** + * Parse a folder that has supported makefiles in it. The following files + * will be looked for in the following order: + * \li Makefile.am.in + * \li Makefile.am + * \li Makefile.in + * + * \param folder, the folder to parse + * \param recursive if true, subfolders will be parsed - defaults to true + */ + void parse( const QString& folder, bool recursive = true ); + + /** + * Get the AST for a certain path + * \param folderPath the path of the folder to get an AST for + * \return the AST that represents a particular folder + */ + AutoTools::ProjectAST* astForFolder( const QString& folderPath ); + + /** + * Check if a string is an automake variable + * \return true if it is an automake variable, false otherwise + */ + bool isVariable( const QString& item ) const; + + /** + * Find the value for the variable specified by \p variable + * \param variable The name of the variable to look for + * \param ast the AST to use to look for the variable in + * \return the value to substitute for the variable + */ + QString resolveVariable( const QString& variable, + AutoTools::ProjectAST* ast ); + + +private: + class Private; + Private* d; +}; + +#endif + +//kate: space-indent on; indent-width 4; + diff --git a/buildtools/autotools/managecustomcommand.cpp b/buildtools/autotools/managecustomcommand.cpp new file mode 100644 index 00000000..7d111965 --- /dev/null +++ b/buildtools/autotools/managecustomcommand.cpp @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "managecustomcommand.h" + +#include + +#include + +ManageCustomCommand::ManageCustomCommand(QWidget *parent, const char *name) + :ManageCustomBuildCommandsBase(parent, name) +{ +} + +void ManageCustomCommand::addButton_clicked() +{ + commandsTable->setNumRows(commandsTable->numRows() + 1); + setRowProperties(commandsTable->numRows()-1); +} + +void ManageCustomCommand::removeButton_clicked() +{ + commandsTable->removeRow(commandsTable->currentRow()); +} + +void ManageCustomCommand::setRowProperties(int row) +{ + commandsTable->setItem(row, 2, + new QComboTableItem(commandsTable, QStringList::split(",", + i18n("this is a list of items in the combobox", + "Make target,Make target (as root),Make command,Make command (as root),Command,Command (as root)")))); +} + +#include "managecustomcommand.moc" diff --git a/buildtools/autotools/managecustomcommand.h b/buildtools/autotools/managecustomcommand.h new file mode 100644 index 00000000..cda5e54a --- /dev/null +++ b/buildtools/autotools/managecustomcommand.h @@ -0,0 +1,37 @@ +/*************************************************************************** +* Copyright (C) 2004 by Alexander Dymo * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License as * +* published by the Free Software Foundation; either version 2 of the * +* License, or (at your option) any later version. * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#ifndef MANAGECUSTOMCOMMAND_H +#define MANAGECUSTOMCOMMAND_H + +#include "managecustomcommandsbase.h" + +class ManageCustomCommand: public ManageCustomBuildCommandsBase +{ + Q_OBJECT +public: + ManageCustomCommand( QWidget *parent = 0, const char *name = 0 ); + + void setRowProperties( int row ); +public slots: + virtual void addButton_clicked(); + virtual void removeButton_clicked(); +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/managecustomcommandsbase.ui b/buildtools/autotools/managecustomcommandsbase.ui new file mode 100644 index 00000000..43164ef5 --- /dev/null +++ b/buildtools/autotools/managecustomcommandsbase.ui @@ -0,0 +1,125 @@ + +ManageCustomBuildCommandsBase + + + ManageCustomBuildCommandsBase + + + true + + + + 0 + 0 + 435 + 218 + + + + + unnamed + + + 0 + + + + addButton + + + &Add + + + + + removeButton + + + &Remove + + + + + + Menu Text + + + + + + + + Command + + + + + + + + Command Type + + + + + + + commandsTable + + + 0 + + + 3 + + + true + + + SingleRow + + + + + spacer4 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + + + addButton + clicked() + ManageCustomBuildCommandsBase + addButton_clicked() + + + removeButton + clicked() + ManageCustomBuildCommandsBase + removeButton_clicked() + + + + commandsTable + addButton + removeButton + + + addButton_clicked() + removeButton_clicked() + + + diff --git a/buildtools/autotools/misc.cpp b/buildtools/autotools/misc.cpp new file mode 100644 index 00000000..97c449e7 --- /dev/null +++ b/buildtools/autotools/misc.cpp @@ -0,0 +1,999 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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 +#include +#include +#include +#include + +#include +#include +#include + +#include "misc.h" + +#include "kdevcompileroptions.h" + + +static KDevCompilerOptions *createCompilerOptions( const QString &name, QObject *parent ) +{ + KService::Ptr service = KService::serviceByDesktopName( name ); + if ( !service ) + { + kdDebug( 9020 ) << "Can't find service " << name << endl; + return 0; + } + + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + kdDebug(9020) << "There was an error loading the module " << service->name() << endl << + "The diagnostics is:" << endl << errorMessage << endl; + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(parent, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug(9020) << "Component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; + +/* + QStringList args; + QVariant prop = service->property( "X-KDevelop-Args" ); + if ( prop.isValid() ) + args = QStringList::split( " ", prop.toString() ); + + return KParts::ComponentFactory + ::createInstanceFromService( service, parent, + service->name().latin1(), args );*/ +} + + +QString AutoProjectTool::execFlagsDialog( const QString &compiler, const QString &flags, QWidget *parent ) +{ + KDevCompilerOptions * plugin = createCompilerOptions( compiler, parent ); + + if ( plugin ) + { + QString newflags = plugin->exec( parent, flags ); + delete plugin; + return newflags; + } + return QString::null; +} + + +QString AutoProjectTool::canonicalize( const QString &str ) +{ + QString res; + for ( uint i = 0; i < str.length(); ++i ) + res += ( str[ i ].isLetterOrNumber() || str[ i ] == '@' ) ? str[ i ] : QChar( '_' ); + + kdDebug(9020) << k_funcinfo << "normalized '" << str << "' to '" << res << "'" << endl; + return res; +} + + +/** + * Read the Makefile.am and return a map of all the variables. + * Will take notice of backslash and += constructs. + * @param fileName + * @param variables + */ +void AutoProjectTool::parseMakefileam(const QString &fileName, QMap *variables) +{ + QFile f(fileName); + if (!f.open(IO_ReadOnly)) + { + return ; + } + QTextStream stream(&f); + + QRegExp re("^(#kdevelop:[ \t]*)?([A-Za-z][@A-Za-z0-9_]*)[ \t]*([:\\+]?=)[ \t]*(.*)$"); + + QString last; + bool multiLine = false; + while (!stream.atEnd()) + { + QString s = stream.readLine().stripWhiteSpace(); + if (re.exactMatch(s)) + { + QString lhs = re.cap(2); + QString rhs = re.cap(4); + if (rhs[ rhs.length() - 1 ] == '\\') + { + multiLine = true; + last = lhs; + rhs[rhs.length() - 1] = ' '; + } + + // The need for stripWhiteSpace seems to be a Qt bug. + // make our list nice and neat. + QStringList bits = QStringList::split(" ", rhs); + rhs = bits.join(" "); + if (re.cap(3) == "+=") + { + ((*variables)[lhs] += ' ') += rhs; + } + else + { + variables->insert(lhs, rhs); + } + } + else if (multiLine) + { + if (s[s.length()-1] == '\\') + { + s[s.length()-1] = ' '; + } + else + { + multiLine = false; + } + QStringList bits = QStringList::split(" ", s); + ((*variables)[last] += ' ') += bits.join(" "); + } + } + f.close(); + + QMap list; + + for (QMap::iterator iter = variables->begin();iter != variables->end();iter++) + { + QStringList items = QStringList::split(" ", iter.data()); + QMap unique; + for (uint i = 0;i < items.size();i++) + { + unique.insert(items[i], ""); + } + QString line; + for (QMap::iterator it = unique.begin();it != unique.end();it++) + { + line += it.key() + ' '; + } + if (line.length() > 1) + { + line.setLength(line.length() - 1); + } + + list.insert(iter.key(), line); + } + *variables = list; +} + +/** + * Add entries to a variable. Will just add the variables to the existing line, removing duplicates + * Will preserve += constructs and make sure that the variable only has one copy of the value across + * all += constructs + * @param fileName + * @param variables key=value string of entries to add + */ +void AutoProjectTool::addToMakefileam(const QString &fileName, QMap variables) +{ + AutoProjectTool::addRemoveMakefileam(fileName, variables, true); +} + +/** + * Set entries to a variable. Will set the variables to the existing line, removing duplicates + * Will preserve += constructs and make sure that the variable only has one copy of the value across + * all += constructs + * Adds line if it does not exist. + * @param fileName + * @param variables key=value string of entries to add + */ +void AutoProjectTool::setMakefileam ( const QString &fileName, QMap variables ) +{ + for ( QMap::Iterator it0 = variables.begin(); it0 != variables.end(); ++it0 ) + { + kdDebug ( 9020 ) << "key (set): " << it0.key() << "=" << it0.data() << endl; + } + + // input file reading + QFile fin ( fileName ); + if ( !fin.open ( IO_ReadOnly ) ) + { + return ; + } + QTextStream ins ( &fin ); + + // output file writing. + QFile fout ( fileName + "#" ); + if ( !fout.open ( IO_WriteOnly ) ) + { + fin.close(); + return ; + } + QTextStream outs ( &fout ); + + // variables + QRegExp re ( "^(#kdevelop:[ \t]*)?([A-Za-z][@A-Za-z0-9_]*)[ \t]*([:\\+]?=)[ \t]*(.*)$" ); + + bool multiLine = false; + QString lastLhs; + QMap seenLhs; + while ( !fin.atEnd() ) + { + QString s = ins.readLine(); + if ( re.exactMatch ( s ) ) + { + QString lhs = re.cap ( 2 ); + bool notFound = ( variables.find ( lhs ) == variables.end() ); + + if ( notFound ) + { + if ( seenLhs.find ( lhs ) == seenLhs.end() ) + { + // not interested in this line at all + // write it out as is.. + outs << s << endl; + } + // we have seen this variable, but since we are setting the + // whole line - we skip this as it will be a += line. + } + else + { + // we are interested in this line.. + QString rhs = re.cap ( 4 ).stripWhiteSpace(); + if ( rhs[ rhs.length() - 1 ] == '\\' ) + { + // save it for when we have the whole line.. + multiLine = true; + lastLhs = lhs; + } + else + { + // deal with it now - a single line + // we are adding our interested values to this line and writing it + // now write the line out if it is not going to be empty. + QString newLine ( lhs ); + newLine += " = "; + bool added = false; + int len = newLine.length(); + QStringList variableList = QStringList::split ( ' ', variables[lhs] ); + for ( uint count = 0; count < variableList.size(); count++ ) + { + len += variableList[count].length() + 1; + if ( len > 80 ) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += variableList[count]; + newLine += ' '; + added = true; + + } + // only print it out if there was a value to add.. + if ( added ) + { + newLine.setLength ( newLine.length() - 1 ); + outs << newLine << endl; + } + seenLhs[lhs] = "done"; + variables.erase ( lhs ); + } + } + } + else if ( multiLine ) + { + s = s.stripWhiteSpace(); + // we are only here if were interested in this line.. + if ( s[s.length()-1] == '\\' ) + { + s.setLength ( s.length() - 1 ); + // still more multi line we wait for.. + } + else + { + // end of the multi line.. + multiLine = false; + } + + if ( !multiLine ) + { + // we are adding our interested values to this line and writing it + // now write the line out if it is not going to be empty. + QString newLine ( lastLhs ); + newLine += " = "; + bool added = false; + int len = newLine.length(); + QStringList variableList = QStringList::split ( ' ', variables[lastLhs] ); + for ( uint count = 0; count < variableList.size(); count++ ) + { + len += variableList[count].length() + 1; + if ( len > 80 ) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += variableList[count]; + newLine += ' '; + added = true; + } + // only print it out if there was a value to add.. + if ( added ) + { + newLine.setLength ( newLine.length() - 1 ); + outs << newLine << endl; + } + seenLhs[lastLhs] = "done"; + variables.erase ( lastLhs ); + lastLhs.setLength ( 0 ); + } + } + else + { + // can write this line out.. + // not a match, not a multi line, + outs << s << endl; + } + } + + for ( QMap::Iterator it0 = variables.begin(); it0 != variables.end(); ++it0 ) + { + QString newLine ( it0.key() ); + newLine += " = "; + bool added = false; + int len = newLine.length(); + QStringList variableList = QStringList::split ( ' ', it0.data() ); + for ( uint count = 0; count < variableList.size(); count++ ) + { + len += variableList[count].length() + 1; + if ( len > 80 ) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += variableList[count]; + newLine += ' '; + added = true; + + } + // only print it out if there was a value to add.. + if ( added ) + { + newLine.setLength ( newLine.length() - 1 ); + outs << newLine << endl; + } + } + + fin.close(); + fout.close(); + + QDir().rename ( fileName + "#", fileName ); +} + + +/** + * Add entries to a variable. Will just add the variables to the existing line, removing duplicates + * Will preserve += constructs and make sure that the variable only has one copy of the value across + * all += constructs + * @param fileName + * @param variables key=value string of entries to add + * @param add true= add these key,value pairs, false = remove. You can have empty values for an add - the whole line is + * removed. For adding, we will not add an empty line. + */ +void AutoProjectTool::addRemoveMakefileam(const QString &fileName, QMap variables, bool add) +{ + // input file reading + QFile fin(fileName); + if (!fin.open(IO_ReadOnly)) + { + return ; + } + QTextStream ins(&fin); + + // output file writing. + QFile fout(fileName + "#"); + if (!fout.open(IO_WriteOnly)) + { + fin.close(); + return ; + } + QTextStream outs(&fout); + + // variables + QRegExp re("^(#kdevelop:[ \t]*)?([A-Za-z][@A-Za-z0-9_]*)[ \t]*([:\\+]?=)[ \t]*(.*)$"); + + // build key=map of values to add + // map can be empty.we never add an empty key, but do remove empty keys from the file.. + QDict< QMap > interest; + for (QMap::Iterator it0 = variables.begin(); it0 != variables.end(); ++it0) + { + kdDebug(9020) << "key (" << add<<"): " << it0.key() << "="<< it0.data() << endl; + + QMap* set = new QMap(); + if (!it0.data().stripWhiteSpace().isEmpty()) + { + QStringList variableList = QStringList::split(' ', it0.data()); + + for (uint i = 0; i < variableList.count(); i++) + { + set->insert(variableList[i], true); + } + } + interest.insert(it0.key(), set); + } + + bool multiLine = false; + QString lastLhs; + QStringList lastRhs; + QMap seenLhs; + while (!fin.atEnd()) + { + QString s = ins.readLine(); + if (re.exactMatch(s)) + { + QString lhs = re.cap(2); + QMap* ourRhs = interest.find(lhs); + + if (!ourRhs) + { + // not interested in this line at all + // write it out as is.. + outs << s << endl; + } + else + { + // we are interested in this line.. + QString rhs = re.cap(4).stripWhiteSpace(); + if (rhs[ rhs.length() - 1 ] == '\\') + { + // save it for when we have the whole line.. + multiLine = true; + lastLhs = lhs; + rhs.setLength(rhs.length() - 1); + lastRhs += QStringList::split(" ", rhs); + } + else + { + // deal with it now. + + QStringList bits = QStringList::split(" ", rhs); + if (add) + { + // we are adding our interested values to this line and writing it + + // add this line to we we want to add to remove duplicates. + for (uint index = 0; index < bits.size(); index++) + { + QMap::iterator findEntry = ourRhs->find(bits[index]); + if (findEntry == ourRhs->end()) + { + // we haven't seen it, so add it, so we don't add it again later.. + ourRhs->insert(bits[index], true); + } + // else we have this value in our 'to add list' , it is either already been + // added, so we don't want to add it again, or it hasn't been added, in which + // case we will do so soon. so we can ignore this now.. + } + // now write the line out if it is not going to be empty. + QString newLine(lhs); + if (seenLhs.find(lhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lhs] = ""; + } + else + { + newLine += " += "; + } + + int len = newLine.length(); + bool added = false; + QValueList keys = ourRhs->keys(); + for (uint count = 0; count < keys.size(); count++) + { + // if out entry is true, add it.. + if ((*ourRhs)[keys[count]]) + { + added = true; + len += keys[count].length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += keys[count]; + newLine += ' '; + // set our value so we don't add it again. + (*ourRhs)[keys[count]] = false; + } + } + // only print it out if there was a value to add.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + else + { + // we are removing our interested values from this line + + // special case - no values, remove the line.. + if (!ourRhs->empty()) + { + // check if any of these values are down to remove. + QString newLine(lhs); + if (seenLhs.find(lhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lhs] = ""; + } + else + { + newLine += " += "; + } + + int len = newLine.length(); + bool added = false; + for (QStringList::Iterator posIter = bits.begin(); posIter != bits.end();posIter++) + { + QMap::iterator findEntry = ourRhs->find(*posIter); + if (findEntry == ourRhs->end()) + { + // we do not want to remove it.. + added = true; + len += (*posIter).length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += (*posIter); + newLine += ' '; + } + // else we have this value in our 'to remove list', so don't add it. + } + // only print it out if there was a value on it.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + }//if (add) + }//if ( rhs[ rhs.length() - 1 ] == '\\' ) + }//if ( found == interest.end()) + } + else if (multiLine) + { + s = s.stripWhiteSpace(); + // we are only here if were interested in this line.. + if (s[s.length()-1] == '\\') + { + s.setLength(s.length() - 1); + // still more multi line we wait for.. + } + else + { + // end of the multi line.. + multiLine = false; + } + lastRhs += QStringList::split(" ", s); + + if (!multiLine) + { + // now we have to deal with this multiLine value.. + // ourRhs will always be a value, as we only get multiLine if we're interested in it.. + QMap* ourRhs = interest.find(lastLhs); + + if (add) + { + // we are adding our interested values to this line and writing it + + // add this line to we we want to add to remove duplicates. + for (uint index = 0; index < lastRhs.size(); index++) + { + QMap::iterator findEntry = ourRhs->find(lastRhs[index]); + if (findEntry == ourRhs->end()) + { + // we haven't seen it, so add it, so we don't add it again later.. + ourRhs->insert(lastRhs[index], true); + } + // else we have this value in our 'to add list' , it is either already been + // added, so we don't want to add it again, or it hasn't been added, in which + // case we will do so soon. so we can ignore this now.. + } + // now write the line out if it is not going to be empty. + QString newLine(lastLhs); + if (seenLhs.find(lastLhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lastLhs] = ""; + } + else + { + newLine += " += "; + } + + int len = newLine.length(); + bool added = false; + QValueList keys = ourRhs->keys(); + for (uint count = 0; count < keys.size(); count++) + { + // if out entry is true, add it.. + if ((*ourRhs)[keys[count]]) + { + added = true; + len += keys[count].length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += keys[count]; + newLine += ' '; + // set our value so we don't add it again. + (*ourRhs)[keys[count]] = false; + } + } + // only print it out if there was a value to add.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + else + { + // we are removing our interested values from this line + // special case - no values, remove the line.. + if (!ourRhs->empty()) + { + // check if any of these values are down to remove. + QString newLine(lastLhs); + if (seenLhs.find(lastLhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lastLhs] = ""; + } + else + { + newLine += " += "; + } + int len = newLine.length(); + bool added = false; + for (QStringList::Iterator posIter = lastRhs.begin(); posIter != lastRhs.end();posIter++) + { + QMap::iterator findEntry = ourRhs->find(*posIter); + if (findEntry == ourRhs->end()) + { + // we do not want to remove it.. + added = true; + len += (*posIter).length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += (*posIter); + newLine += ' '; + } + // else we have this value in our 'to remove list', so don't add it. + } + // only print it out if there was a value on it.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + } + + lastLhs.setLength(0); + lastRhs.clear(); + } + } + else + { + // can write this line out.. + // not a match, not a multi line, + outs << s << endl; + } + } + + if (add) + { + QDictIterator > it(interest); + for (; it.current(); ++it) + { + QString lhs = it.currentKey(); + QMap* ourRhs = it.current(); + + QString newLine(lhs); + if (seenLhs.find(lhs) == seenLhs.end()) + { + newLine += " = "; + seenLhs[lastLhs] = ""; + } + else + { + newLine += " += "; + } + int len = newLine.length(); + bool added = false; + QValueList keys = ourRhs->keys(); + for (uint count = 0; count < keys.size(); count++) + { + if ((*ourRhs)[keys[count]]) + { + added = true; + len += keys[count].length() + 1; + if (len > 80) + { + newLine += "\\\n\t"; + len = 8; + } + newLine += keys[count]; + newLine += ' '; + // set our value so we don't add it again. + (*ourRhs)[keys[count]] = false; + } + } + // only print it out if there was a value to add.. + if (added) + { + newLine.setLength(newLine.length() - 1); + outs << newLine << endl; + } + } + } + interest.setAutoDelete(true); + interest.clear(); + + fin.close(); + fout.close(); + + QDir().rename(fileName + "#", fileName); +} + +/** + * Any items in the map will be removed from the Makefile.am + * Empty lines are removed. eg. foo_LDDADD if empty is removed. + * @param fileName full path to Makefile.am + * @param variables lines to remove items from. + */ +void AutoProjectTool::removeFromMakefileam(const QString &fileName, QMap variables) +{ + AutoProjectTool::addRemoveMakefileam(fileName, variables, false); +} + + +/** + * Open the file and parse out the AC_OUTPUT line. following backslash continue lines.. + * @param configureinpath + * @return list of all the values + */ +QStringList AutoProjectTool::configureinLoadMakefiles(QString configureinpath) +{ + QFile configurein(configureinpath); + + if (!configurein.open(IO_ReadOnly)) + { + kdDebug(9020) << k_funcinfo << " - couldn't open file: " << configureinpath << endl; + return QStringList(); + } + + QTextStream stream(&configurein); + QStringList list; + + QString ac_match("^AC_OUTPUT"); + + QRegExp ac_regex(ac_match); + bool multiLine = false; + QChar cont('\\'); + QRegExp close("\\)"); + QRegExp open("\\("); + while (!stream.eof()) + { + QString line = stream.readLine().stripWhiteSpace(); + if (multiLine) + { + if (close.search(line) >= 0) + { + line = line.replace(close.search(line), 1, ""); + list += QStringList::split(" ", line); + break; + } + else + { + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + } + list += QStringList::split(" ", line); + } + } + else if (ac_regex.search(line) >= 0) + { + line = line.replace(ac_regex.search(line), ac_match.length() - 1, ""); + + if (open.search(line) >= 0) + { + line = line.replace(open.search(line), 1, ""); + } + + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + multiLine = true; + } + else + { + if (close.search(line) >= 0) + { + line = line.replace(close.search(line), 1, ""); + } + } + + list = QStringList::split(" ", line); + + if (!multiLine) + { + break; + } + } + } + + configurein.close(); + + // make a new object on the heap + return list; + +} + +/** + * Write the items to the AC_OUTPUT line. This replaces the exiting line. + * @param configureinpath + * @param makefiles + */ +void AutoProjectTool::configureinSaveMakefiles(QString fileName, QStringList makefiles) +{ + // input file reading + QFile fin(fileName); + if (!fin.open(IO_ReadOnly)) + { + return ; + } + QTextStream ins(&fin); + + // output file writing. + QFile fout(fileName + "#"); + if (!fout.open(IO_WriteOnly)) + { + fin.close(); + return ; + } + QTextStream outs(&fout); + + // remove duplicates if any.. + QMap toAdd; + for (uint i = 0; i < makefiles.size();i++) + { + toAdd.insert(makefiles[i].stripWhiteSpace(), ""); + } + + QString ac_match("^AC_OUTPUT"); + QRegExp ac_regex(ac_match); + bool multiLine = false; + QChar cont('\\'); + QRegExp close("\\)"); + QRegExp open("\\("); + bool done = false; + while (!fin.atEnd()) + { + QString line = ins.readLine(); + if (done) + { + outs << line << endl; + } + else + { + if (multiLine) + { + line = line.stripWhiteSpace(); + if (close.search(line) >= 0) + { + int len = 10; + QString acline("AC_OUTPUT("); + for (QMap::iterator iter = toAdd.begin();iter != toAdd.end();iter++) + { + len += iter.key().length(); + if (len > 80) + { + acline += "\\\n\t"; + len = 8; + } + acline += iter.key(); + acline += ' '; + } + acline.setLength(acline.length() - 1); + acline = acline.append(")"); + outs << acline << endl; + done = true; + } + else + { + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + } + } + } + else if (ac_regex.search(line) >= 0) + { + line = line.stripWhiteSpace(); + line = line.replace(ac_regex.search(line), ac_match.length() - 1, ""); + if (line.endsWith(cont)) + { + line.setLength(line.length() - 1); + multiLine = true; + } + if (open.search(line) >= 0) + { + line = line.replace(open.search(line), 1, ""); + } + if (close.search(line) >= 0) + { + line = line.replace(close.search(line), 1, ""); + } + + if (!multiLine) + { + int len = 10; + QString acline("AC_OUTPUT("); + for (QMap::iterator iter = toAdd.begin();iter != toAdd.end();iter++) + { + len += iter.key().length(); + if (len > 80) + { + acline += "\\\n\t"; + len = 8; + } + acline += iter.key(); + acline += ' '; + } + acline.setLength(acline.length() - 1); + acline = acline.append(")"); + outs << acline << endl; + done = true; + } + } + else + { + outs << line << endl; + } + } + } + + fin.close(); + fout.close(); + + QDir().rename(fileName + "#", fileName); + +} + +//kate: indent-mode csands; space-indent off; tab-width 4; diff --git a/buildtools/autotools/misc.h b/buildtools/autotools/misc.h new file mode 100644 index 00000000..9db9919e --- /dev/null +++ b/buildtools/autotools/misc.h @@ -0,0 +1,65 @@ +/*************************************************************************** +* Copyright (C) 2001-2002 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _MISC_H_ +#define _MISC_H_ + +#include +#include +#include + +/** + * Very small helper class. It has just static methods. + */ +class AutoProjectTool +{ +public: + + /** + * Loads the compiler options plugin for the given compiler, executes the dialog + * with some initial flags, and returns the new flags. + */ + static QString execFlagsDialog( const QString &compiler, const QString &flags, QWidget *parent ); + + /** + * Returns the canonicalized version of a file name, i.e. + * the file name with special characters replaced by underscores + */ + static QString canonicalize( const QString &str ); + + /** + * Parses a Makefile.am and stores its variable assignments + * in a map. + */ + static void parseMakefileam( const QString &filename, QMap *variables ); + + static void addToMakefileam( const QString &filename, QMap variables ); + static void removeFromMakefileam( const QString &filename, QMap variables ); + static void setMakefileam ( const QString &fileName, QMap variables ); + + static void addRemoveMakefileam(const QString &fileName, QMap variables, bool add); + + /** + * Parses configure.in and splits AC_OUTPUT into a QStringList + */ + static QStringList configureinLoadMakefiles( QString configureinpath ); + + /** + * Receives a QStringList and puts it into + * configure.in as arguments to AC_OUTPUT + */ + static void configureinSaveMakefiles( QString configureinpath, QStringList makefiles ); + +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/removefiledlg.cpp b/buildtools/autotools/removefiledlg.cpp new file mode 100644 index 00000000..2c3bc37f --- /dev/null +++ b/buildtools/autotools/removefiledlg.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "removefiledlg.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" +#include "autodetailsview.h" + +static bool fileListContains(const QPtrList &list, const QString &name) +{ + QPtrListIterator it(list); + for (; it.current(); ++it) + if ((*it)->text(0) == name) + return true; + return false; +} + + +RemoveFileDialog::RemoveFileDialog(AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *item, const QString &filename, + QWidget *parent, const char *name) + : RemoveFileDlgBase(parent, name, true) +{ + removeFromTargetsCheckBox = 0; + + QStringList targets; + + QPtrListIterator it(spitem->targets); + for (; it.current(); ++it) + if (fileListContains((*it)->sources, filename)) + targets.append((*it)->name); + + if (targets.count() > 1) + { + removeFromTargetsCheckBox = new QCheckBox( fileGroupBox, "removeFromTargetsCheckBox" ); + removeFromTargetsCheckBox->setMinimumSize( QSize( 0, 45 ) ); + fileLayout->addWidget( removeFromTargetsCheckBox ); + + QString joinedtargets = " *" + targets.join("\n *"); + removeFromTargetsCheckBox->setText ( i18n ( "The file %1 is still used by the following targets:\n%2\n" + "Remove it from all of them?").arg(filename).arg(joinedtargets) ); + setMinimumSize(QSize(size().width(), size().height() + removeFromTargetsCheckBox->size().height()*2) ); + } + + removeLabel->setText ( i18n ( "Do you really want to remove %1?" ).arg ( filename ) ); + + directoryLabel->setText ( spitem->path ); + if ( item->name.isEmpty() ) + targetLabel->setText ( i18n ( "%1 in %2" ).arg ( item->primary ).arg ( item->prefix ) ); + else + targetLabel->setText ( item->name ); + + connect ( removeButton, SIGNAL ( clicked() ), this, SLOT ( accept() ) ); + connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) ); + + setIcon ( SmallIcon ( "editdelete.png" ) ); + + m_widget = widget; + m_part = part; + subProject = spitem; + target = item; + fileName = filename; +} + + +RemoveFileDialog::~RemoveFileDialog() +{} + + +void RemoveFileDialog::accept() +{ + m_widget->emitRemovedFile ( subProject->path.mid ( m_part->projectDirectory().length() + 1 ) + "/" + fileName ); + + QMap replaceMap; + + if (removeFromTargetsCheckBox && removeFromTargetsCheckBox->isChecked()) { + QPtrListIterator it(subProject->targets); + for (; it.current(); ++it) { + if ((*it) != target && fileListContains((*it)->sources, fileName)) { + FileItem *fitem = static_cast((*it)->firstChild()); + while (fitem) { + FileItem *nextitem = static_cast(fitem->nextSibling()); + if (fitem->text(0) == fileName) { + QListView *lv = fitem->listView(); + lv->setSelected(fitem, false); + (*it)->sources.remove(fitem); + } + fitem = nextitem; + } + QString canontargetname = AutoProjectTool::canonicalize((*it)->name); + QString varname; + if( (*it)->primary == "PROGRAMS" || (*it)->primary == "LIBRARIES" || (*it)->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = (*it)->prefix + "_" + (*it)->primary; + QStringList sources = QStringList::split(QRegExp("[ \t\n]"), subProject->variables[varname]); + sources.remove(fileName); + subProject->variables[varname] = sources.join(" "); + replaceMap.insert(varname, fileName); + } + } + } + + QString fileItemName; + FileItem *fitem = static_cast(target->firstChild()); + while (fitem) { + if (fitem->text(0) == fileName) { + QListView *lv = fitem->listView(); + lv->setSelected(fitem, false); + fileItemName = fitem->name; + target->sources.remove(fitem); + break; + } + fitem = static_cast(fitem->nextSibling()); + } + QString canontargetname = AutoProjectTool::canonicalize(target->name); + QString varname; + if( target->primary == "PROGRAMS" || target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES" ) + varname = canontargetname + "_SOURCES"; + else + varname = target->prefix + "_" + target->primary; + QStringList sources = QStringList::split(QRegExp("[ \t\n]"), subProject->variables[varname]); + sources.remove(fileName); + subProject->variables[varname] = sources.join(" "); + replaceMap.insert(varname, fileName); + + AutoProjectTool::removeFromMakefileam(subProject->path + "/Makefile.am", replaceMap); + +// review configuration cleanup in the project file after removing subclassing related source + QDomDocument &dom = *(m_part->projectDom()); + + QDomElement el = dom.documentElement(); + QDomNode el2 = el.namedItem("kdevautoproject"); + QDomNode el3 = el2.namedItem("subclassing"); + + QDomNode n = el3.firstChild(); + QValueList nodesToRemove; + while ( !n.isNull() ) { + QDomNamedNodeMap attr = n.attributes(); + QString fpath = subProject->path + QString("/") + fileItemName; + QString relpath = fpath.remove(0, m_part->projectDirectory().length()); + if ((attr.item(0).nodeValue() == relpath) + || (attr.item(1).nodeValue() == relpath) ) + nodesToRemove.append(n); + n = n.nextSibling(); + } + QValueList::iterator it; + for ( it = nodesToRemove.begin(); it != nodesToRemove.end(); ++it ) + el3.removeChild(*it); + + if (removeCheckBox->isChecked()) + QFile::remove(subProject->path + "/" + fileName); + + QDialog::accept(); +} + +#include "removefiledlg.moc" diff --git a/buildtools/autotools/removefiledlg.h b/buildtools/autotools/removefiledlg.h new file mode 100644 index 00000000..ab843dda --- /dev/null +++ b/buildtools/autotools/removefiledlg.h @@ -0,0 +1,51 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _REMOVEFILEDLG_H_ +#define _REMOVEFILEDLG_H_ + +#include + +#include "removefiledlgbase.h" + +class QCheckBox; +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; + + +class RemoveFileDialog : public RemoveFileDlgBase +{ + Q_OBJECT + +public: + RemoveFileDialog( AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *item, const QString &filename, + QWidget *parent = 0, const char *name = 0 ); + ~RemoveFileDialog(); + +protected: + virtual void accept(); + +private: + QCheckBox *removeFromTargetsCheckBox; + //QCheckBox *removefromdisk_box; + + AutoProjectWidget* m_widget; + AutoProjectPart *m_part; + SubprojectItem *subProject; + TargetItem *target; + QString fileName; +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/removefiledlgbase.ui b/buildtools/autotools/removefiledlgbase.ui new file mode 100644 index 00000000..d7b66011 --- /dev/null +++ b/buildtools/autotools/removefiledlgbase.ui @@ -0,0 +1,233 @@ + +RemoveFileDlgBase + + + RemoveFileDlgBase + + + + 0 + 0 + 447 + 284 + + + + Remove File From This Target + + + + unnamed + + + + layout4 + + + + unnamed + + + + buttonSpacer + + + Horizontal + + + Expanding + + + + 247 + 20 + + + + + + removeButton + + + &OK + + + true + + + + + cancelButton + + + &Cancel + + + + + + + fileGroupBox + + + + 0 + 0 + + + + &File Information + + + + unnamed + + + + fileLayout + + + + unnamed + + + + removeLabel + + + [REMOVE QUESTION] + + + + + removeCheckBox + + + Also &remove it from disk + + + + + noticeLabel + + + + 200 + 0 + + + + <b>Note:</b> You will not be able to undelete the file. + + + + + + + + + targetBox + + + + 5 + 0 + 0 + 0 + + + + Subproject Information + + + + unnamed + + + + targetLabel + + + + 5 + 1 + 0 + 0 + + + + [TARGET NAME] + + + + + directoryStaticLabel + + + + 0 + 1 + 0 + 0 + + + + + + + + Directory: + + + + + targetStaticLabel + + + + 0 + 1 + 0 + 0 + + + + + + + + Target: + + + + + directoryLabel + + + + 5 + 1 + 0 + 0 + + + + [DIRECTORY NAME] + + + + + + + + removeCheckBox + removeButton + cancelButton + + + ksqueezedtextlabel.h + kdialog.h + + + + diff --git a/buildtools/autotools/removetargetdlg.cpp b/buildtools/autotools/removetargetdlg.cpp new file mode 100644 index 00000000..6104e404 --- /dev/null +++ b/buildtools/autotools/removetargetdlg.cpp @@ -0,0 +1,279 @@ +/*************************************************************************** + ------------------- + begin : 21.11.2002 + copyright : (C) 2002 by Victor R�er + email : victor_roeder@gmx.de + ***************************************************************************/ + +/*************************************************************************** + * * + * 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 "removetargetdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "autolistviewitems.h" + +#include "misc.h" + +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + + +RemoveTargetDialog::RemoveTargetDialog( AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *titem, QWidget* parent, const char* name ) + : RemoveTargetDlgBase ( parent, name, true, 0 ) +{ + removeLabel->setText ( i18n ( "Do you really want to remove %1
with all files that are attached to it
and all dependencies?" ).arg ( titem->name ) ); + directoryLabel->setText ( spitem->path ); + + if ( titem->name.isEmpty() ) + targetLabel->setText ( i18n ( "%1 in %2" ).arg ( titem->primary ).arg ( titem->prefix ) ); + else + targetLabel->setText ( titem->name ); + + connect ( removeButton, SIGNAL ( clicked() ), this, SLOT ( accept() ) ); + connect ( cancelButton, SIGNAL ( clicked() ), this, SLOT ( reject() ) ); + + setIcon ( SmallIcon ( "editdelete" ) ); + + progressBar->hide(); + + m_spitem = spitem; + m_titem = titem; + m_widget = widget; + m_part = part; + + //kdDebug ( 9020 ) << "+++++ " << titem->primary << " " << titem->prefix << " " << titem->name << endl; + + init(); +} + + +RemoveTargetDialog::~RemoveTargetDialog() +{ +} + +void RemoveTargetDialog::init() +{ + QPtrList subprojectItems = m_widget->allSubprojectItems(); + + TargetItem* titem = 0; + + for ( SubprojectItem* spitem = subprojectItems.first(); spitem; spitem = subprojectItems.next() ) + { + if ( m_titem->name.isEmpty() ) + break; + + for ( titem = spitem->targets.first(); titem; titem = spitem->targets.next() ) + { + if ( m_titem->name == titem->name ) + continue; + + if ( titem->primary == "LTLIBRARIES" || titem->primary == "PROGRAMS" + || titem->primary == "LIBRARIES" || titem->primary == "JAVA" ) + { + QString canonname = AutoProjectTool::canonicalize ( titem->name ); + + if ( spitem->variables[canonname + "_LIBADD"].contains ( m_titem->name ) > 0 || + spitem->variables[canonname + "_LDADD"].contains ( m_titem->name ) > 0 ) + { + dependencyListBox->insertItem ( SmallIcon ( "target_kdevelop" ), spitem->path + " (" + titem->name + ")" ); + + dependentSubprojects.append ( spitem ); + } + } + } + } + + if ( dependencyListBox->count() == 0 ) + dependencyListBox->insertItem ( i18n("no dependency", "") ); +} + +void RemoveTargetDialog::accept () +{ + progressBar->show(); + progressBar->setFormat ( i18n ( "Removing Target... %p%" ) ); + + qApp->processEvents(); + + QString canonname = AutoProjectTool::canonicalize ( m_titem->name ); + QString varname = m_titem->prefix + "_" + m_titem->primary; + + SubprojectItem* spitem = 0; + TargetItem* titem = 0; + + QMap removeMap; + QMap replaceMap; + + // Remove dependencies to other targets first (stored by init() in 'dependentTargets') + for ( spitem = dependentSubprojects.first(); spitem; spitem = dependentSubprojects.next() ) + { + for ( titem = spitem->targets.first(); titem; titem = spitem->targets.next() ) + { + QString curVarname; + QString curCanonname = AutoProjectTool::canonicalize ( titem->name ); + QStringList dependencies; + + if ( spitem->variables[curCanonname + "_LIBADD"].contains ( m_titem->name ) ) + curVarname = curCanonname + "_LIBADD"; + else + curVarname = curCanonname + "_LDADD"; + + dependencies = QStringList::split(QRegExp("[ \t\n]"), spitem->variables[curVarname]); + + //QStringList::Iterator it = dependencies.begin(); + + for ( uint i = 0; i < dependencies.size(); ++i ) + { + QString s = dependencies[i]; + if ( s.contains ( m_titem->name ) > 0 ) + dependencies.remove ( s ); + } + + // if we removed the last entry of "blabla_LDADD" or "blabla_LIBADD", remove the complete line + if ( dependencies.count() == 0 ) + { + removeMap.insert ( curVarname, "" ); + AutoProjectTool::removeFromMakefileam ( spitem->path + "/Makefile.am", removeMap ); + removeMap.clear(); + } + else + { + spitem->variables[curVarname] = dependencies.join ( " " ); + replaceMap.insert ( curVarname, spitem->variables[curVarname] ); + AutoProjectTool::addToMakefileam ( spitem->path + "/Makefile.am", replaceMap ); + replaceMap.clear(); + } + } + } + + // handling am_edit stuff + if ( m_titem->primary == "KDEICON" ) + removeMap.insert ( "KDE_ICON", "" ); + else if ( m_titem->primary == "KDEDOCS" ) + removeMap.insert ( "KDE_DOCS", "" ); + else + { + // if we have bin_PROGRAMS = [target to be deleted] [other target] + // delete only the [target to be deleted], not the whole line! + QStringList targets = QStringList::split(QRegExp("[ \t\n]"), m_spitem->variables[varname]); + + if ( targets.count() > 1 ) + { + targets.remove ( m_titem->name ); + m_spitem->variables[varname] = targets.join ( " " ); + replaceMap.insert ( varname, m_spitem->variables[varname] ); + AutoProjectTool::addToMakefileam ( m_spitem->path + "/Makefile.am", replaceMap ); + replaceMap.clear(); + } + else + { + removeMap.insert ( varname, m_titem->name ); + } + } + + // if we have no such line containing blabla_SOURCES, blabla_LDFLAGS, etc. + // they are ignored + removeMap.insert ( canonname + "_SOURCES", "" ); + + // remove from our internal list + m_spitem->variables.erase(canonname+"_SOURCES"); + + if ( m_titem->primary == "PROGRAMS" || m_titem->primary == "LTLIBRARIES" ) + { + removeMap.insert ( canonname + "_LDFLAGS", "" ); + removeMap.insert ( canonname + "_DEPENDENCIES", "" ); + removeMap.insert ( canonname + "_LDADD", "" ); + removeMap.insert ( canonname + "_LIBADD", "" ); + } + + AutoProjectTool::removeFromMakefileam ( m_spitem->path + "/Makefile.am", removeMap ); + + removeMap.clear(); + + // if we have another "blabla_PROGRAMS" or "blabla_LTLIBRARIES" target in the same subproject + // check if it has an empty "blabla_LIBADD"-entry + if ( m_titem->primary == "PROGRAMS" || m_titem->primary == "LTLIBRARIES" ) + { + for ( titem = m_spitem->targets.first(); titem; titem = m_spitem->targets.next() ) + { + //kdDebug (9020) << "******** " << m_spitem->subdir << endl; + if ( titem->primary == "PROGRAMS" || titem->primary == "LTLIBRARIES" ) + { + QString curCanonname = AutoProjectTool::canonicalize ( titem->name ); + + if ( m_spitem->variables[curCanonname + "_LIBADD"].isEmpty() ) + { + removeMap.insert ( curCanonname + "_LIBADD", "" ); + + //kdDebug (9020) << "Removing from " << m_spitem->subdir << " " << curCanonname << "_LIBADD" << endl; + + AutoProjectTool::removeFromMakefileam ( m_spitem->path + "/Makefile.am", removeMap ); + + removeMap.clear(); + } + } + } + } + + + progressBar->setTotalSteps ( m_titem->sources.count() ); + + QStringList fileList; + + for ( FileItem* fitem = m_titem->sources.first(); fitem; fitem = m_titem->sources.next() ) + { + if (removeCheckBox->isChecked()) + { + // before removing the files, check if they are mentioned in "noinst_HEADERS = blabla1.h blabla2.h" + QStringList noInstHeaders = QStringList::split ( QRegExp ( "[ \t\n]" ), m_spitem->variables["noinst_HEADERS"] ); + + if ( noInstHeaders.contains ( fitem->name ) ) + { + noInstHeaders.remove ( fitem->name ); + + m_spitem->variables["noinst_HEADERS"] = noInstHeaders.join ( " " ); + replaceMap.insert ( "noinst_HEADERS", m_spitem->variables["noinst_HEADERS"] ); + AutoProjectTool::addToMakefileam ( m_spitem->path + "/Makefile.am", replaceMap ); + replaceMap.clear(); + } + + QFile::remove(m_spitem->path + "/" + fitem->name); + } + + fileList.append ( m_spitem->path.mid ( m_part->projectDirectory().length() + 1 ) + "/" + fitem->name ); + + qApp->processEvents(); + + progressBar->setValue ( progressBar->value() + 1 ); + } + + m_widget->emitRemovedFiles ( fileList ); + + m_spitem->targets.remove ( m_titem ); + + + QDialog::accept(); +} diff --git a/buildtools/autotools/removetargetdlg.h b/buildtools/autotools/removetargetdlg.h new file mode 100644 index 00000000..6953d2bf --- /dev/null +++ b/buildtools/autotools/removetargetdlg.h @@ -0,0 +1,55 @@ +/*************************************************************************** + ------------------- + begin : 21.11.2002 + copyright : (C) 2002 by Victor Rder + email : victor_roeder@gmx.de +***************************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _REMOVETARGETDLG_H_ +#define _REMOVETARGETDLG_H_ + +#include "removetargetdlgbase.h" + +#include + +class AutoProjectWidget; +class AutoProjectPart; +class SubprojectItem; +class TargetItem; + +/** + * + * KDevelop Authors + **/ +class RemoveTargetDialog : public RemoveTargetDlgBase +{ + +public: + RemoveTargetDialog( AutoProjectWidget *widget, AutoProjectPart* part, SubprojectItem *spitem, + TargetItem *titem, QWidget* parent = 0, const char* name = 0 ); + ~RemoveTargetDialog(); + +private: + SubprojectItem* m_spitem; + TargetItem* m_titem; + AutoProjectWidget* m_widget; + AutoProjectPart* m_part; + + QPtrList dependentSubprojects; + +protected: + void init (); + virtual void accept(); +}; + +#endif +// kate: indent-mode csands; tab-width 4; diff --git a/buildtools/autotools/removetargetdlgbase.ui b/buildtools/autotools/removetargetdlgbase.ui new file mode 100644 index 00000000..8e3660d3 --- /dev/null +++ b/buildtools/autotools/removetargetdlgbase.ui @@ -0,0 +1,264 @@ + +RemoveTargetDlgBase + + + RemoveTargetDlgBase + + + + 0 + 0 + 472 + 477 + + + + Remove Target From [SUBPROJECT] + + + + unnamed + + + + targetBox + + + Subproject Information + + + + unnamed + + + + directoryLabel + + + + 5 + 5 + 0 + 0 + + + + [TARGET DIRECTORY] + + + + + targetLabel + + + [TARGET NAME] + + + + + directoryStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + + + + Directory: + + + + + targetStaticLabel + + + + 0 + 5 + 0 + 0 + + + + + + + + Target: + + + + + + + fileGroupBox + + + + 0 + 0 + + + + + 32767 + 140 + + + + &Target Information + + + + unnamed + + + + removeLabel + + + [REMOVE QUESTION] + + + + + removeCheckBox + + + Also &remove it from disk + + + + + textLabel + + + + 200 + 0 + + + + <b>Note:</b> You will not be able to undo this operation. Please check your Makefile.am afterwards. + + + + + + + groupBox3 + + + &Dependencies to Other Subprojects + + + + unnamed + + + + dependencyListBox + + + false + + + NoSelection + + + + + + + progressBar + + + true + + + + + Spacer2 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + buttonLayout + + + + unnamed + + + 0 + + + + buttonSpacer + + + Horizontal + + + Expanding + + + + 30 + 20 + + + + + + removeButton + + + &OK + + + true + + + + + cancelButton + + + &Cancel + + + + + + + + kdialog.h + + + + + ksqueezedtextlabel.h + klistbox.h + kprogress.h + + diff --git a/buildtools/autotools/subprojectoptionsdlg.cpp b/buildtools/autotools/subprojectoptionsdlg.cpp new file mode 100644 index 00000000..5ad6bf10 --- /dev/null +++ b/buildtools/autotools/subprojectoptionsdlg.cpp @@ -0,0 +1,404 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "subprojectoptionsdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "domutil.h" +#include "misc.h" +#include "addprefixdlg.h" + +#include "autolistviewitems.h" + +#include "autoprojectpart.h" +#include "autoprojectwidget.h" + + +SubprojectOptionsDialog::SubprojectOptionsDialog(AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *item, QWidget *parent, const char *name) + : SubprojectOptionsDialogBase(parent, name, true) +{ + setCaption(i18n("Subproject Options for '%1'").arg(item->subdir)); + + subProject = item; + m_part = part; + + QFontMetrics fm(cflags_edit->fontMetrics()); + int wid = fm.width('X')*35; + cflags_edit->setMinimumWidth(wid); + cxxflags_edit->setMinimumWidth(wid); + fflags_edit->setMinimumWidth(wid); + + QDomDocument &dom = *part->projectDom(); + QString prefix = "/kdevautoproject/configurations/" + m_part->currentBuildConfig() + "/"; + + ccompiler = DomUtil::readEntry(dom, prefix + "ccompiler", "kdevgccoptions"); + cxxcompiler = DomUtil::readEntry(dom, prefix + "cxxcompiler", "kdevgppoptions"); + f77compiler = DomUtil::readEntry(dom, prefix + "f77compiler", "kdevg77options"); + + if (!KService::serviceByDesktopName(ccompiler)) + cflags_button->setEnabled(false); + if (!KService::serviceByDesktopName(cxxcompiler)) + cxxflags_button->setEnabled(false); + if (!KService::serviceByDesktopName(f77compiler)) + fflags_button->setEnabled(false); + + insideinc_listview->header()->hide(); + outsideinc_listview->header()->hide(); + buildorder_listview->header()->hide(); + + insideinc_listview->setSorting(-1); + outsideinc_listview->setSorting(-1); + prefix_listview->setSorting(-1); + buildorder_listview->setSorting(-1); + + connect( prefix_listview, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT( editPrefixClicked() ) ); + + // Insert all subdirectories as possible include directories + QStringList l = widget->allSubprojects(); + QCheckListItem *lastItem = 0; + QStringList::ConstIterator it; + for (it = l.begin(); it != l.end(); ++it) { + kdDebug(9020) << "----------> subproject = " << (*it) << endl; + QString subProjectName = *it; + + if( subProjectName.isEmpty() ){ + subProjectName = QString::fromLatin1( "." ); + } + QCheckListItem *clitem = new QCheckListItem(insideinc_listview, subProjectName, QCheckListItem::CheckBox); + if (lastItem) + clitem->moveItem(lastItem); + lastItem = clitem; + } + + setIcon ( SmallIcon ( "configure" ) ); + + readConfig(); +} + + +SubprojectOptionsDialog::~SubprojectOptionsDialog() +{} + + +void SubprojectOptionsDialog::readConfig() +{ + + cflags_edit->setText(subProject->variables["AM_CFLAGS"]); + cxxflags_edit->setText(subProject->variables["AM_CXXFLAGS"]); + fflags_edit->setText(subProject->variables["AM_FFLAGS"]); + + metasources_checkbox->setChecked(subProject->variables["METASOURCES"].stripWhiteSpace() == "AUTO"); + + QString includes = subProject->variables["INCLUDES"]; + QStringList includeslist = QStringList::split(QRegExp("[ \t]"), QString(includes)); + + QListViewItem *lastItem = 0; + QStringList::Iterator it; + for (it = includeslist.begin(); it != includeslist.end(); ++it) { + QCheckListItem *clitem = static_cast(insideinc_listview->firstChild()); + while (clitem) { + if (*it == ("-I$(top_srcdir)/" + clitem->text())) { + clitem->setOn(true); + break; + } + clitem = static_cast(clitem->nextSibling()); + } + if (!clitem) { + QListViewItem *item = new QListViewItem(outsideinc_listview, *it); + if (lastItem) + item->moveItem(lastItem); + lastItem = item; + } + } + + QMap::ConstIterator it2; + for (it2 = subProject->prefixes.begin(); it2 != subProject->prefixes.end(); ++it2) + new QListViewItem(prefix_listview, it2.key(), it2.data()); + + QString subdirs = subProject->variables["SUBDIRS"]; + kdDebug(9020) << "Subdirs variable: " << subdirs << endl; + QStringList subdirslist = QStringList::split(QRegExp("[ \t]"), QString(subdirs)); + lastItem = 0; + for (it = subdirslist.begin(); it != subdirslist.end(); ++it) { + QListViewItem *item = new QListViewItem(buildorder_listview, *it); + if (lastItem) + item->moveItem(lastItem); + lastItem = item; + } +} + + +void SubprojectOptionsDialog::storeConfig() +{ + QMap replaceMap; + + QString old_cflags = subProject->variables["AM_CFLAGS"]; + QString new_cflags = cflags_edit->text(); + if (new_cflags != old_cflags) { + subProject->variables["AM_CFLAGS"] = new_cflags; + replaceMap.insert("AM_CFLAGS", new_cflags); + } + + QString old_cxxflags = subProject->variables["AM_CXXFLAGS"]; + QString new_cxxflags = cxxflags_edit->text(); + if (new_cxxflags != old_cxxflags) { + subProject->variables["AM_CXXFLAGS"] = new_cxxflags; + replaceMap.insert("AM_CXXFLAGS", new_cxxflags); + } + + QString old_fflags = subProject->variables["AM_FFLAGS"]; + QString new_fflags = fflags_edit->text(); + if (new_fflags != old_fflags) { + subProject->variables["AM_FFLAGS"] = new_fflags; + replaceMap.insert("AM_FFLAGS", new_fflags); + } + + QString old_metasources = subProject->variables["METASOURCES"]; + QString new_metasources = metasources_checkbox->isChecked() ? QString::fromLatin1("AUTO") : QString::null; + if (new_metasources != old_metasources) { + subProject->variables["METASOURCES"] = new_metasources; + replaceMap.insert("METASOURCES", new_metasources); + } + + QStringList includeslist; + QCheckListItem *clitem = static_cast(insideinc_listview->firstChild()); + while (clitem) { + if (clitem->isOn()) + includeslist.append("-I$(top_srcdir)/" + clitem->text()); + clitem = static_cast(clitem->nextSibling()); + } + clitem = static_cast(outsideinc_listview->firstChild()); + while (clitem) { + includeslist.append(clitem->text()); + clitem = static_cast(clitem->nextSibling()); + } + QString includes = includeslist.join(" "); + subProject->variables["INCLUDES"] = includes; + replaceMap.insert("INCLUDES", includes); + + subProject->prefixes.clear(); + for (QListViewItem *item = prefix_listview->firstChild(); + item; item = item->nextSibling()) { + QString key = item->text(0); + QString data = item->text(1); + subProject->prefixes[key] = data; + replaceMap.insert(key + "dir", data); + } + /// \FIXME take removed prefixes into account + + QStringList subdirslist; + for (QListViewItem *item = buildorder_listview->firstChild(); + item; item = item->nextSibling()) + subdirslist.append(item->text(0)); + QString subdirs = subdirslist.join(" "); + kdDebug() << "New subdirs variable: " << subdirs << endl; + subProject->variables["SUBDIRS"] = subdirs; + replaceMap.insert("SUBDIRS", subdirs); + + AutoProjectTool::setMakefileam(subProject->path + "/Makefile.am", replaceMap); +} + + +void SubprojectOptionsDialog::cflagsClicked() +{ + QString new_cflags = AutoProjectTool::execFlagsDialog(ccompiler, cflags_edit->text(), this); +// if (!new_cflags.isNull()) + cflags_edit->setText(new_cflags); +} + + +void SubprojectOptionsDialog::cxxFlagsClicked() +{ + QString new_cxxflags = AutoProjectTool::execFlagsDialog(cxxcompiler, cxxflags_edit->text(), this); +// if (!new_cxxflags.isNull()) + cxxflags_edit->setText(new_cxxflags); +} + + +void SubprojectOptionsDialog::fflagsClicked() +{ + QString new_fflags = AutoProjectTool::execFlagsDialog(f77compiler, fflags_edit->text(), this); +// if (!new_fflags.isNull()) + fflags_edit->setText(new_fflags); +} + + +void SubprojectOptionsDialog::insideMoveUpClicked() +{ + if (insideinc_listview->currentItem() == insideinc_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = insideinc_listview->firstChild(); + while (item->nextSibling() != insideinc_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(insideinc_listview->currentItem()); +} + + +void SubprojectOptionsDialog::insideMoveDownClicked() +{ + if (insideinc_listview->currentItem() == 0 || insideinc_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + insideinc_listview->currentItem()->moveItem(insideinc_listview->currentItem()->nextSibling()); +} + + +void SubprojectOptionsDialog::outsideMoveUpClicked() +{ + if (outsideinc_listview->currentItem() == outsideinc_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = outsideinc_listview->firstChild(); + while (item->nextSibling() != outsideinc_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(outsideinc_listview->currentItem()); +} + + +void SubprojectOptionsDialog::outsideMoveDownClicked() +{ + if (outsideinc_listview->currentItem() == 0 || outsideinc_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + outsideinc_listview->currentItem()->moveItem(outsideinc_listview->currentItem()->nextSibling()); +} + +void SubprojectOptionsDialog::outsideAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add Include directory: Choose directory, give -Idirectory or use a variable with -I$(FOOBAR)" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if ( !file.isEmpty() ) + { + if( file.startsWith("-I") ) + new QListViewItem( outsideinc_listview, file ); + else + { + new QListViewItem( outsideinc_listview, "-I"+file ); + } + } + } +} + + +void SubprojectOptionsDialog::outsideEditClicked() +{ + if ( (outsideinc_listview->childCount()==0) || (outsideinc_listview->currentItem() == 0) ) + return; + bool ok; + QString dir = KInputDialog::getText(i18n("Edit Include Directory"), i18n("Edit include directory:"), + outsideinc_listview->currentItem()-> text(0), &ok, 0); + if (ok && !dir.isEmpty()) + outsideinc_listview->currentItem()-> setText(0, dir); +} + + +void SubprojectOptionsDialog::outsideRemoveClicked() +{ + delete outsideinc_listview->currentItem(); +} + + +void SubprojectOptionsDialog::addPrefixClicked() +{ + AddPrefixDialog dlg; + if (!dlg.exec() || dlg.name().isEmpty() || dlg.path().isEmpty() ) + return; + + new QListViewItem(prefix_listview, dlg.name(), dlg.path()); +} + + +void SubprojectOptionsDialog::editPrefixClicked() +{ + QListViewItem* lvItem = prefix_listview->currentItem(); + if ( (prefix_listview->childCount()==0) || (lvItem == 0) ) + return; + AddPrefixDialog dlg(lvItem-> text(0), lvItem-> text(1)); + dlg.setCaption(i18n("Edit Prefix")); + if (!dlg.exec() || dlg.name().isEmpty() || dlg.path().isEmpty() ) + return; + lvItem-> setText(0, dlg.name()); + lvItem-> setText(1, dlg.path()); +} + +void SubprojectOptionsDialog::removePrefixClicked() +{ + delete prefix_listview->currentItem(); +} + + +void SubprojectOptionsDialog::buildorderMoveUpClicked() +{ + if (buildorder_listview->currentItem() == buildorder_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = buildorder_listview->firstChild(); + while (item->nextSibling() != buildorder_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(buildorder_listview->currentItem()); +} + + +void SubprojectOptionsDialog::buildorderMoveDownClicked() +{ + if (buildorder_listview->currentItem() == 0 || buildorder_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + buildorder_listview->currentItem()->moveItem(buildorder_listview->currentItem()->nextSibling()); +} + + +void SubprojectOptionsDialog::accept() +{ + storeConfig(); + QDialog::accept(); +} + +#include "subprojectoptionsdlg.moc" diff --git a/buildtools/autotools/subprojectoptionsdlg.h b/buildtools/autotools/subprojectoptionsdlg.h new file mode 100644 index 00000000..7ec1fbf0 --- /dev/null +++ b/buildtools/autotools/subprojectoptionsdlg.h @@ -0,0 +1,63 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _SUBPROJECTOPTIONSDLG_H_ +#define _SUBPROJECTOPTIONSDLG_H_ + +#include "subprojectoptionsdlgbase.h" + +class AutoProjectPart; +class AutoProjectWidget; +class SubprojectItem; + + +class SubprojectOptionsDialog : public SubprojectOptionsDialogBase +{ + Q_OBJECT + +public: + SubprojectOptionsDialog( AutoProjectPart *part, AutoProjectWidget *widget, + SubprojectItem *item, QWidget *parent = 0, const char *name = 0 ); + ~SubprojectOptionsDialog(); + +private: + virtual void cflagsClicked(); + virtual void cxxFlagsClicked(); + virtual void fflagsClicked(); + virtual void insideMoveUpClicked(); + virtual void insideMoveDownClicked(); + virtual void outsideMoveUpClicked(); + virtual void outsideMoveDownClicked(); + virtual void outsideAddClicked(); + virtual void outsideRemoveClicked(); + virtual void outsideEditClicked(); + virtual void addPrefixClicked(); + virtual void editPrefixClicked(); + virtual void removePrefixClicked(); + virtual void buildorderMoveUpClicked(); + virtual void buildorderMoveDownClicked(); + virtual void accept(); + + void readConfig(); + void storeConfig(); + + SubprojectItem *subProject; + AutoProjectWidget *m_widget; + AutoProjectPart *m_part; + + QString ccompiler; + QString cxxcompiler; + QString f77compiler; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/subprojectoptionsdlgbase.ui b/buildtools/autotools/subprojectoptionsdlgbase.ui new file mode 100644 index 00000000..f2723e5a --- /dev/null +++ b/buildtools/autotools/subprojectoptionsdlgbase.ui @@ -0,0 +1,989 @@ + +SubprojectOptionsDialogBase + + + sub project options widget + + + + 0 + 0 + 442 + 437 + + + + Subproject Options + + + + unnamed + + + + subprojectoptions_tabwidget + + + + tab + + + Co&mpiler + + + + unnamed + + + + cflags_label + + + + + + + Compiler flags for C compiler (CFLA&GS): + + + cflags_edit + + + + + Layout5 + + + + unnamed + + + 0 + + + + cflags_edit + + + + 7 + 0 + 0 + 0 + + + + + + cflags_button + + + + 0 + 0 + 0 + 0 + + + + + 30 + 25 + + + + ... + + + false + + + + + + + Spacer2 + + + Vertical + + + Preferred + + + + 20 + 20 + + + + + + cxxflags_label + + + + + + + Compiler flags for C++ compiler (C&XXFLAGS): + + + cxxflags_edit + + + + + Layout3 + + + + unnamed + + + 0 + + + + cxxflags_edit + + + + + cxxflags_button + + + + 1 + 0 + 0 + 0 + + + + + 30 + 25 + + + + ... + + + false + + + + + + + Spacer3 + + + Vertical + + + Preferred + + + + 20 + 20 + + + + + + fflags_label + + + + + + + Compiler flags for Fortran compiler (&FFLAGS): + + + fflags_edit + + + + + Layout4 + + + + unnamed + + + 0 + + + + fflags_edit + + + + + fflags_button + + + + 1 + 0 + 0 + 0 + + + + + 30 + 25 + + + + ... + + + false + + + + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + tab + + + &Includes + + + + unnamed + + + + layout11 + + + + unnamed + + + + metasources_checkbox + + + Automatically &generate metasources + + + + + layout9 + + + + unnamed + + + + Layout9 + + + + unnamed + + + 0 + + + + Spacer2_3 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + insidemoveup_button + + + Move &Up + + + + + insidemovedown_button + + + Move &Down + + + + + Spacer3_2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + insideinc_label + + + + + + + Directories in&side project: + + + insideinc_listview + + + + + + + + + true + + + true + + + + insideinc_listview + + + LastColumn + + + + + + + layout10 + + + + unnamed + + + + Layout10 + + + + unnamed + + + 0 + + + + Spacer1_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + outsideadd_button + + + &Add... + + + + + outsideedit_button + + + &Edit... + + + + + outsideremove_button + + + &Remove + + + + + outsidemoveup_button + + + Move U&p + + + + + outsidemovedown_button + + + Move Dow&n + + + + + Spacer2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + TextLabel2_2 + + + + + + + Directories ou&tside project: + + + outsideinc_listview + + + + + + + + + true + + + true + + + + outsideinc_listview + + + LastColumn + + + + + + + + + + + tab + + + &Prefixes + + + + unnamed + + + + + Name + + + true + + + true + + + + + Path + + + true + + + true + + + + prefix_listview + + + true + + + AllColumns + + + + + prefixes_label + + + + + + + C&ustom prefixes: + + + prefix_listview + + + + + Layout6 + + + + unnamed + + + 0 + + + + Spacer5 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + addprefix_button + + + &Add... + + + + + editprefix_button + + + &Edit... + + + + + removeprefix_button + + + &Remove + + + + + Spacer6 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + tab + + + &Build Order + + + + unnamed + + + + Layout9_2 + + + + unnamed + + + 0 + + + + Spacer2_3_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + buildmoveup_button + + + Move &Up + + + + + buildmovedown_button + + + Move &Down + + + + + Spacer3_2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + true + + + true + + + + buildorder_listview + + + LastColumn + + + + + buildorder_label + + + + + + + O&rder in which sub projects are built: + + + buildorder_listview + + + + + + + + Layout2 + + + + unnamed + + + 0 + + + + Spacer1 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okbutton + + + &OK + + + true + + + + + cancelbutton + + + &Cancel + + + + + + + + + cflags_button + clicked() + sub project options widget + cflagsClicked() + + + cxxflags_button + clicked() + sub project options widget + cxxFlagsClicked() + + + removeprefix_button + clicked() + sub project options widget + removePrefixClicked() + + + insidemoveup_button + clicked() + sub project options widget + insideMoveUpClicked() + + + insidemovedown_button + clicked() + sub project options widget + insideMoveDownClicked() + + + outsideadd_button + clicked() + sub project options widget + outsideAddClicked() + + + outsideedit_button + clicked() + sub project options widget + outsideEditClicked() + + + outsidemovedown_button + clicked() + sub project options widget + outsideMoveDownClicked() + + + outsidemoveup_button + clicked() + sub project options widget + outsideMoveUpClicked() + + + outsideremove_button + clicked() + sub project options widget + outsideRemoveClicked() + + + okbutton + clicked() + sub project options widget + accept() + + + cancelbutton + clicked() + sub project options widget + reject() + + + fflags_button + clicked() + sub project options widget + fflagsClicked() + + + buildmovedown_button + clicked() + sub project options widget + buildorderMoveDownClicked() + + + buildmoveup_button + clicked() + sub project options widget + buildorderMoveUpClicked() + + + addprefix_button + clicked() + sub project options widget + addPrefixClicked() + + + editprefix_button + clicked() + sub project options widget + editPrefixClicked() + + + + cflags_edit + cflags_button + cxxflags_edit + cxxflags_button + fflags_edit + fflags_button + subprojectoptions_tabwidget + metasources_checkbox + insideinc_listview + insidemoveup_button + insidemovedown_button + outsideinc_listview + outsideadd_button + outsideedit_button + outsideremove_button + outsidemoveup_button + outsidemovedown_button + prefix_listview + addprefix_button + editprefix_button + removeprefix_button + buildorder_listview + buildmoveup_button + buildmovedown_button + okbutton + cancelbutton + + + kdialog.h + + + buildorderMoveDownClicked() + cflagsClicked() + cxxFlagsClicked() + fflagsClicked() + insideMoveDownClicked() + insideMoveUpClicked() + buildorderMoveUpClicked() + outsideAddClicked() + outsideEditClicked() + outsideMoveDownClicked() + outsideMoveUpClicked() + outsideRemoveClicked() + removePrefixClicked() + addPrefixClicked() + editPrefixClicked() + + + + diff --git a/buildtools/autotools/targetoptionsdlg.cpp b/buildtools/autotools/targetoptionsdlg.cpp new file mode 100644 index 00000000..c8d49c55 --- /dev/null +++ b/buildtools/autotools/targetoptionsdlg.cpp @@ -0,0 +1,357 @@ +/*************************************************************************** + * Copyright (C) 2001 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "targetoptionsdlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "autolistviewitems.h" + +#include "misc.h" +#include "autoprojectpart.h" +#include "autoprojectwidget.h" +#include "urlutil.h" + +TargetOptionsDialog::TargetOptionsDialog(AutoProjectWidget *widget, TargetItem *item, + QWidget *parent, const char *name) + : TargetOptionsDialogBase(parent, name, true) +{ + setCaption( i18n("Target Options for '%1'").arg(item->name) ); + setIcon( SmallIcon("configure") ); + + target = item; + m_widget = widget; + + if (item->primary == "PROGRAMS") { + insidelib_label->setText(i18n("Link convenience libraries inside project (LDADD)")); + outsidelib_label->setText(i18n("Link libraries outside project (LDADD)")); + } + else + argumentBox->setEnabled( false ); +// run_arguments_edit->setEnabled(false); + + insidelib_listview->header()->hide(); + outsidelib_listview->header()->hide(); + insidelib_listview->setSorting(-1); + outsidelib_listview->setSorting(-1); + + + m_cwdEdit->completionObject()->setMode(KURLCompletion::DirCompletion); + m_cwdEdit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + + // Insert all convenience libraries as possible linked libraries + QStringList l = widget->allLibraries(); + QStringList::ConstIterator it; + QString fulltargetname = m_widget->subprojectDirectory() + "/" + item->name; + for (it = l.begin(); it != l.end(); ++it) + // Do not list the target itself (a target can not link with itself) + if ( !fulltargetname.endsWith(*it) ) + (void) new QCheckListItem(insidelib_listview, *it, QCheckListItem::CheckBox); + readConfig(); +} + + +TargetOptionsDialog::~TargetOptionsDialog() +{} + + +void TargetOptionsDialog::readConfig() +{ + QString flagsstr = target->ldflags; + flagsstr.replace(QRegExp("$(KDE_PLUGIN)"), "-avoid-version -module -no-undefined $(KDE_RPATH)"); + QStringList l1 = QStringList::split(QRegExp("[ \t]"), flagsstr); + QStringList::Iterator l1it; + + l1it = l1.find("-all-static"); + if (l1it != l1.end()) { + allstatic_box->setChecked(true); + l1.remove(l1it); + } + l1it = l1.find("-avoid-version"); + if (l1it != l1.end()) { + avoidversion_box->setChecked(true); + l1.remove(l1it); + } + l1it = l1.find("-module"); + if (l1it != l1.end()) { + module_box->setChecked(true); + l1.remove(l1it); + } + l1it = l1.find("-no-undefined"); + if (l1it != l1.end()) { + noundefined_box->setChecked(true); + l1.remove(l1it); + } + ldflagsother_edit->setText(l1.join(" ")); + dependencies_edit->setText(target->dependencies); + + QString addstr = (target->primary == "PROGRAMS")? target->ldadd : target->libadd; + QStringList l2 = QStringList::split(QRegExp("[ \t]"), addstr); + + kdDebug(9020) << "ls=: " << addstr << endl; + + bool inlistItem; + QListViewItem *lastItem = 0; + QStringList::Iterator l2it; + QCheckListItem *flitem = static_cast(insidelib_listview->firstChild()); + for (l2it = l2.begin(); l2it != l2.end(); ++l2it) { + inlistItem = false; + QCheckListItem *clitem = static_cast(insidelib_listview->firstChild()); + if (flitem) { + while (clitem) { + if (*l2it == ("$(top_builddir)/" + clitem->text())) { + clitem->setOn(true); + // move this item to the "top of the list" + if (flitem != clitem) + clitem->moveItem(flitem); + // move the "top of the list" one item down + flitem = static_cast(flitem->nextSibling()); + inlistItem = true; + break; + } + clitem = static_cast(clitem->nextSibling()); + } + } + if ( inlistItem == false ) { + QListViewItem *item = new QListViewItem(outsidelib_listview, *l2it); + if (lastItem) + item->moveItem(lastItem); + lastItem = item; + } + } + + if (target->primary == "PROGRAMS") + { + run_arguments_edit->setText(DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/runarguments/" + target->name)); + if( DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name).isEmpty() ) + { + m_cwdEdit->setURL( m_widget->m_part->buildDirectory()+"/"+URLUtil::getRelativePath(m_widget->m_part->topsourceDirectory(), m_widget->m_part->projectDirectory())+"/"+m_widget->activeDirectory() ); + m_cwdEdit->fileDialog()->setURL( KURL::fromPathOrURL( m_widget->m_part->buildDirectory()+"/"+URLUtil::getRelativePath(m_widget->m_part->topsourceDirectory(), m_widget->m_part->projectDirectory())+"/"+m_widget->activeDirectory() ) ); + }else + { + m_cwdEdit->setURL( DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name) ); + m_cwdEdit->fileDialog()->setURL( KURL::fromPathOrURL( DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name) ) ); + } + debug_arguments_edit->setText(DomUtil::readEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/debugarguments/" + target->name)); + } +} + + +void TargetOptionsDialog::storeConfig() +{ + QStringList flagslist; + if (allstatic_box->isChecked()) + flagslist.append("-all-static"); + if (avoidversion_box->isChecked()) + flagslist.append("-avoid-version"); + if (module_box->isChecked()) + flagslist.append("-module"); + if (noundefined_box->isChecked()) + flagslist.append("-no-undefined"); + flagslist.append(ldflagsother_edit->text()); + QString new_ldflags = flagslist.join(" "); + + QStringList liblist; + QCheckListItem *clitem = static_cast(insidelib_listview->firstChild()); + while (clitem) { + if( clitem->isOn() ) + liblist.append("$(top_builddir)/" + clitem->text()); + clitem = static_cast(clitem->nextSibling()); + } + clitem = static_cast(outsidelib_listview->firstChild()); + while (clitem) { + liblist.append(clitem->text()); + clitem = static_cast(clitem->nextSibling()); + } + QString new_addstr = liblist.join(" "); + + QString canonname = AutoProjectTool::canonicalize(target->name); + QMap replaceMap; + + if (target->primary == "PROGRAMS") { + QString old_ldadd = target->ldadd; + if (new_addstr != old_ldadd) { + target->ldadd = new_addstr; + replaceMap.insert(canonname + "_LDADD", new_addstr); + } + } + + if (target->primary == "LIBRARIES" || target->primary == "LTLIBRARIES") { + QString old_libadd = target->libadd; + if (new_addstr != old_libadd) { + target->libadd = new_addstr; + replaceMap.insert(canonname + "_LIBADD", new_addstr); + } + } + + QString old_ldflags = target->ldflags; + if (new_ldflags != old_ldflags) { + target->ldflags = new_ldflags; + replaceMap.insert(canonname + "_LDFLAGS", new_ldflags); + } + + QString new_dependencies = dependencies_edit->text(); + QString old_dependencies = target->dependencies; + if (new_dependencies != old_dependencies) { + target->dependencies = new_dependencies; + if (!new_dependencies.isEmpty()) + replaceMap.insert(canonname + "_DEPENDENCIES", new_dependencies); + } + + // We can safely assume that this target is in the active sub project + AutoProjectTool::setMakefileam(m_widget->subprojectDirectory() + "/Makefile.am", replaceMap); + + if (target->primary == "PROGRAMS") + { + DomUtil::writeEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/runarguments/" + target->name, run_arguments_edit->text()); + DomUtil::writeEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/debugarguments/" + target->name, debug_arguments_edit->text()); + DomUtil::writeEntry(*m_widget->m_part->projectDom(), "/kdevautoproject/run/cwd/" + target->name, m_cwdEdit->url()); + } +} + + +void TargetOptionsDialog::insideMoveUpClicked() +{ + if (!insidelib_listview->currentItem()) + return; + if (insidelib_listview->currentItem() == insidelib_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = insidelib_listview->firstChild(); + while (item->nextSibling() != insidelib_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(insidelib_listview->currentItem()); +} + + +void TargetOptionsDialog::insideMoveDownClicked() +{ + if (!insidelib_listview->currentItem()) + return; + + if (insidelib_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + insidelib_listview->currentItem()->moveItem(insidelib_listview->currentItem()->nextSibling()); +} + + +void TargetOptionsDialog::outsideMoveUpClicked() +{ + if (!outsidelib_listview->currentItem()) + return; + if (outsidelib_listview->currentItem() == outsidelib_listview->firstChild()) { + KNotifyClient::beep(); + return; + } + + QListViewItem *item = outsidelib_listview->firstChild(); + while (item->nextSibling() != outsidelib_listview->currentItem()) + item = item->nextSibling(); + item->moveItem(outsidelib_listview->currentItem()); +} + + +void TargetOptionsDialog::outsideMoveDownClicked() +{ + if (!outsidelib_listview->currentItem()) + return; + if (outsidelib_listview->currentItem()->nextSibling() == 0) { + KNotifyClient::beep(); + return; + } + + outsidelib_listview->currentItem()->moveItem(outsidelib_listview->currentItem()->nextSibling()); +} + + +void TargetOptionsDialog::outsideAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add Library: Choose the .a/.so file, give -l or use a variable with $(FOOBAR)" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + dialog.urlRequester() ->setFilter( "*.so|"+i18n("Shared Library (*.so)")+"\n*.a|"+i18n("Static Library (*.a)") ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( m_widget->selectedSubproject()->path ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL::fromPathOrURL( m_widget->selectedSubproject()->path ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if ( !file.isEmpty() ) + { + if( file.startsWith("-l") ) + new QListViewItem( outsidelib_listview, file ); + else + { + QFileInfo fi(file); + if( !fi.exists() ) + new QListViewItem( outsidelib_listview, file ); + if( fi.extension(false) == "a" ) + { + new QListViewItem( outsidelib_listview, file ); + }else if ( fi.extension(false) == "so" ) + { + QString name = fi.fileName(); + if( name.startsWith( "lib" ) ) + name = name.mid(3); + name = "-l"+name.left( name.length() - 3 ); + new QListViewItem( outsidelib_listview, name ); + } + } + } + } +} + + +void TargetOptionsDialog::outsideEditClicked() +{ + if ( (outsidelib_listview->childCount()==0) || (outsidelib_listview->currentItem() == 0) ) + return; + bool ok; + QString dir = KInputDialog::getText(i18n("Edit External Library"), i18n("Edit external library:"), + outsidelib_listview->currentItem()-> text(0), &ok, 0); + if (ok && !dir.isEmpty()) + outsidelib_listview->currentItem()-> setText(0, dir); +} + + +void TargetOptionsDialog::outsideRemoveClicked() +{ + delete outsidelib_listview->currentItem(); +} + + +void TargetOptionsDialog::accept() +{ + storeConfig(); + QDialog::accept(); +} + +#include "targetoptionsdlg.moc" +// kate: indent-mode csands; space-indent on; indent-width 4; replace-tabs on; diff --git a/buildtools/autotools/targetoptionsdlg.h b/buildtools/autotools/targetoptionsdlg.h new file mode 100644 index 00000000..c1dea20a --- /dev/null +++ b/buildtools/autotools/targetoptionsdlg.h @@ -0,0 +1,49 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _TARGETOPTIONSDLG_ +#define _TARGETOPTIONSDLG_ + +#include "targetoptionsdlgbase.h" + +class AutoProjectWidget; +class TargetItem; + + +class TargetOptionsDialog : public TargetOptionsDialogBase +{ + Q_OBJECT + +public: + TargetOptionsDialog( AutoProjectWidget *widget, TargetItem *item, + QWidget *parent = 0, const char *name = 0 ); + ~TargetOptionsDialog(); + +private: + virtual void insideMoveUpClicked(); + virtual void insideMoveDownClicked(); + virtual void outsideMoveUpClicked(); + virtual void outsideMoveDownClicked(); + virtual void outsideAddClicked(); + virtual void outsideEditClicked(); + virtual void outsideRemoveClicked(); + virtual void accept(); + + void readConfig(); + void storeConfig(); + + TargetItem *target; + AutoProjectWidget *m_widget; +}; + +#endif +// kate: indent-mode csands; tab-width 4; + diff --git a/buildtools/autotools/targetoptionsdlgbase.ui b/buildtools/autotools/targetoptionsdlgbase.ui new file mode 100644 index 00000000..07487ac2 --- /dev/null +++ b/buildtools/autotools/targetoptionsdlgbase.ui @@ -0,0 +1,726 @@ + +TargetOptionsDialogBase + + + target_options_dialog + + + + 0 + 0 + 627 + 474 + + + + Target Options + + + false + + + + unnamed + + + + tabWidget + + + + Widget5 + + + Fl&ags + + + + unnamed + + + + TextLabel1 + + + + + + + Li&nker flags (LDFLAGS): + + + allstatic_box + + + + + Layout12 + + + + unnamed + + + 0 + + + + allstatic_box + + + &Do not link against shared libraries (-all-static) + + + + + avoidversion_box + + + Do not &assign version numbers to libraries (-avoid-version) + + + + + module_box + + + Create a library that can &be dynamically loaded (-module) + + + + + noundefined_box + + + Library does not depend on external symbols (-no-&undefined) + + + + + Layout11 + + + + unnamed + + + 0 + + + + ldflagsother_label + + + + + + + O&ther: + + + ldflagsother_edit + + + + + ldflagsother_edit + + + + + + + + + Spacer1 + + + Vertical + + + Preferred + + + + 20 + 20 + + + + + + Spacer2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + dependencies_edit + + + + + dependencies_label + + + + + + + E&xplicit dependencies (DEPENDENCIES): + + + dependencies_edit + + + + + Spacer3 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + Spacer4 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + Widget6 + + + Li&braries + + + + unnamed + + + + insidelib_label + + + + + + + Lin&k convenience libraries inside project (LIBADD): + + + insidelib_listview + + + + + Spacer9 + + + Vertical + + + Fixed + + + + 20 + 7 + + + + + + + + + + true + + + true + + + + outsidelib_listview + + + LastColumn + + + + + outsidelib_label + + + + + + + Link libraries ou&tside project (LIBADD): + + + outsidelib_listview + + + + + Layout9_3 + + + + unnamed + + + 0 + + + + Spacer5 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + insidemoveup_button + + + Move &Up + + + + + insidemovedown_button + + + Move &Down + + + + + Spacer6 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + true + + + true + + + + insidelib_listview + + + LastColumn + + + + + Layout10_4 + + + + unnamed + + + 0 + + + + Spacer7 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + outsideadd_button + + + &Add... + + + + + outsideedit_button + + + &Edit... + + + + + outsideremove_button + + + &Remove + + + + + outsidemoveup_button + + + Mo&ve Up + + + + + outsidemovedown_button + + + Move Dow&n + + + + + Spacer8 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + arguments_page + + + Ar&guments + + + + unnamed + + + + argumentBox + + + Program Arguments (only valid for executable targets) + + + + unnamed + + + + run_arguments_edit + + + + + arguments_label_1 + + + + + + + &Run arguments: + + + run_arguments_edit + + + + + m_cwdEdit + + + + + textLabel1 + + + Working Directory: + + + + + arguments_label_2 + + + + + + + &Debug arguments: + + + run_arguments_edit + + + + + debug_arguments_edit + + + + + + + Spacer4_2 + + + Vertical + + + Expanding + + + + 20 + 120 + + + + + + + + + Layout1 + + + + unnamed + + + 0 + + + + Spacer10 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + okbutton + + + &OK + + + true + + + true + + + + + cancelbutton + + + &Cancel + + + true + + + + + + + + + + + okbutton + clicked() + target_options_dialog + accept() + + + cancelbutton + clicked() + target_options_dialog + reject() + + + insidemoveup_button + clicked() + target_options_dialog + insideMoveUpClicked() + + + outsidemoveup_button + clicked() + target_options_dialog + outsideMoveUpClicked() + + + outsidemovedown_button + clicked() + target_options_dialog + outsideMoveDownClicked() + + + outsideadd_button + clicked() + target_options_dialog + outsideAddClicked() + + + outsideedit_button + clicked() + target_options_dialog + outsideEditClicked() + + + outsideremove_button + clicked() + target_options_dialog + outsideRemoveClicked() + + + insidemovedown_button + clicked() + target_options_dialog + insideMoveDownClicked() + + + + allstatic_box + avoidversion_box + module_box + noundefined_box + ldflagsother_edit + dependencies_edit + tabWidget + insidelib_listview + insidemoveup_button + insidemovedown_button + outsidelib_listview + outsideadd_button + outsideedit_button + outsideremove_button + outsidemoveup_button + outsidemovedown_button + okbutton + cancelbutton + + + kdialog.h + + + insideMoveDownClicked() + insideMoveUpClicked() + outsideAddClicked() + outsideEditClicked() + outsideMoveDownClicked() + outsideMoveUpClicked() + outsideRemoveClicked() + + + + + klineedit.h + klineedit.h + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + klineedit.h + + diff --git a/buildtools/custommakefiles/Makefile.am b/buildtools/custommakefiles/Makefile.am new file mode 100644 index 00000000..fab92b8b --- /dev/null +++ b/buildtools/custommakefiles/Makefile.am @@ -0,0 +1,26 @@ +# Here resides the custom project part. + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util $(all_includes) \ + -I$(top_builddir)/buildtools/lib/widgets + +kde_module_LTLIBRARIES = libkdevcustomproject.la +libkdevcustomproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevcustomproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevcustomproject_la_SOURCES = selectnewfilesdialog.cpp selectnewfilesdialogbase.ui \ + custombuildoptionswidget.cpp custombuildoptionswidgetbase.ui custommakeconfigwidget.cpp \ + custommakeconfigwidgetbase.ui custommanagerwidget.cpp custommanagerwidgetbase.ui \ + customotherconfigwidget.cpp customotherconfigwidgetbase.ui customprojectpart.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevcustomproject.desktop + +rcdir = $(kde_datadir)/kdevcustomproject +rc_DATA = kdevcustomproject.rc +noinst_HEADERS = selectnewfilesdialog.h custommanagerwidget.h \ + customotherconfigwidget.h diff --git a/buildtools/custommakefiles/README.dox b/buildtools/custommakefiles/README.dox new file mode 100644 index 00000000..28762d87 --- /dev/null +++ b/buildtools/custommakefiles/README.dox @@ -0,0 +1,47 @@ +/** \class CustomProjectPart +This is the custom build tools part. +Put a more detailed description of your part in these lines. It can span +over several lines. You can even use some html commands in these lines like: +This is code, html links link text, +and images. + +\authors Bernd Gehrmann + +\unmaintained This part is currently un-maintained + +\feature Describe the first feature +\feature Describe the second feature +... +\feature Describe the last feature + +\bug bugs in customproject component at Bugzilla database +\bug Describe a the 1st bug that you know of, but probably hasn't been reported yet. +.. +\bug Describe a the nth bug that you know of, but probably hasn't been reported yet. + +\requirement Describe a the 1st requirement of your part. +\requirement Describe a the 2nd requirement of your part. +... +\requirement Describe a the nth requirement of your part. + +\todo Describe a the 1st TODO of your part. +\todo Describe a the 2nd TODO of your part. +... +\todo Describe a the nth TODO of your part. + +\faq First frequenly asked question about your part ? Answer. +\faq Second frequenly asked question about your part ? Answer. +... +\faq Last frequenly asked question about your part ? Answer. + +\note First note text. +\note Second note text. +... +\note Last note text. + +\warning First warning text. +\warning Second warning text. +... +\warning Last warning text. + +*/ diff --git a/buildtools/custommakefiles/custombuildoptionswidget.cpp b/buildtools/custommakefiles/custombuildoptionswidget.cpp new file mode 100644 index 00000000..37b087b2 --- /dev/null +++ b/buildtools/custommakefiles/custombuildoptionswidget.cpp @@ -0,0 +1,99 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "custombuildoptionswidget.h" + +#include +#include +#include +#include +#include +#include +#include +#include "domutil.h" + + +CustomBuildOptionsWidget::CustomBuildOptionsWidget(QDomDocument &dom, + QWidget *parent, const char *name) + : CustomBuildOptionsWidgetBase(parent, name), + m_dom(dom) +{ + ant_button->setChecked(DomUtil::readEntry(dom, "/kdevcustomproject/build/buildtool") == "ant"); + other_button->setChecked(DomUtil::readEntry(dom, "/kdevcustomproject/build/buildtool") == "other"); + if( !DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir").isEmpty() + && QFileInfo( DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir") ).exists() ) + { + builddir_edit->setURL(DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir")); + builddir_edit->fileDialog()->setURL( DomUtil::readEntry(dom, "/kdevcustomproject/build/builddir") ); + } + else + { + builddir_edit->setURL( QString() ); + builddir_edit->fileDialog()->setURL( QString() ); + } + builddir_edit->completionObject()->setMode(KURLCompletion::DirCompletion); + builddir_edit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + + // This connection must not be made before the ant->setChecked() line, + // because at this time makeToggled() would crash + connect( make_button, SIGNAL(toggled(bool)), + this, SLOT(makeToggled(bool)) ); + connect( other_button, SIGNAL(toggled(bool)), + this, SLOT(otherToggled(bool)) ); +} + + +CustomBuildOptionsWidget::~CustomBuildOptionsWidget() +{} + + +void CustomBuildOptionsWidget::accept() +{ + QString buildtool; + if (ant_button->isChecked()) + { + buildtool = "ant"; + } + else if (other_button->isChecked()) + { + buildtool = "other"; + } + else + { + buildtool = "make"; + } + DomUtil::writeEntry(m_dom, "/kdevcustomproject/build/buildtool", buildtool); + DomUtil::writeEntry(m_dom, "/kdevcustomproject/build/builddir", builddir_edit->url()); +} + + +void CustomBuildOptionsWidget::setMakeOptionsWidget(QTabWidget *tw, QWidget *mow, QWidget* oow) +{ + m_tabWidget = tw; + m_makeOptions = mow; + m_otherOptions = oow; + makeToggled(make_button->isChecked()); + otherToggled(other_button->isChecked()); +} + +void CustomBuildOptionsWidget::otherToggled(bool b) +{ + m_tabWidget->setTabEnabled(m_otherOptions, b); +} + +void CustomBuildOptionsWidget::makeToggled(bool b) +{ + m_tabWidget->setTabEnabled(m_makeOptions, b); +} + +#include "custombuildoptionswidget.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custombuildoptionswidget.h b/buildtools/custommakefiles/custombuildoptionswidget.h new file mode 100644 index 00000000..1b049574 --- /dev/null +++ b/buildtools/custommakefiles/custombuildoptionswidget.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _CUSTOMBUILDOPTIONSWIDGET_H_ +#define _CUSTOMBUILDOPTIONSWIDGET_H_ + +#include "custombuildoptionswidgetbase.h" +#include + +class QTabWidget; + + +class CustomBuildOptionsWidget : public CustomBuildOptionsWidgetBase +{ + Q_OBJECT + +public: + CustomBuildOptionsWidget( QDomDocument &dom, QWidget *parent=0, const char *name=0 ); + ~CustomBuildOptionsWidget(); + + void setMakeOptionsWidget(QTabWidget *tw, QWidget *mow, QWidget *oow); + +public slots: + void accept(); + +private: + virtual void makeToggled(bool b); + virtual void otherToggled(bool b); + + QDomDocument &m_dom; + QTabWidget *m_tabWidget; + QWidget *m_makeOptions; + QWidget *m_otherOptions; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custombuildoptionswidgetbase.ui b/buildtools/custommakefiles/custombuildoptionswidgetbase.ui new file mode 100644 index 00000000..59ca9ba2 --- /dev/null +++ b/buildtools/custommakefiles/custombuildoptionswidgetbase.ui @@ -0,0 +1,164 @@ + +CustomBuildOptionsWidgetBase + + + configure_options_widget + + + + 0 + 0 + 592 + 480 + + + + Custom Build Options + + + + unnamed + + + + buildtool_group + + + Build Tool + + + + unnamed + + + + make_button + + + &Make + + + true + + + + + ant_button + + + A&nt + + + + + other_button + + + Other + + + + + + other custom build tool, e.g. script + + + There are myriads of buildtools out there that are not ant or make. If you use one of them (or have your own scripts), select this option. + + + + + + + Spacer19 + + + Vertical + + + Minimum + + + + 20 + 20 + + + + + + builddir_label + + + Run &the build tool in the following directory: + + + builddir_edit + + + + + layout2 + + + + unnamed + + + + Spacer38 + + + Horizontal + + + Fixed + + + + 16 + 20 + + + + + + builddir_edit + + + + + + + Spacer39 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + kdialog.h + + + makeToggled(bool) + otherToggled(bool) + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/custommakefiles/custommakeconfigwidget.cpp b/buildtools/custommakefiles/custommakeconfigwidget.cpp new file mode 100644 index 00000000..2af0d137 --- /dev/null +++ b/buildtools/custommakefiles/custommakeconfigwidget.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** + * Copyright (C) 2003 by Hendrik Kueck * + * kueck@cs.ubc.ca * + * * + * 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 "custommakeconfigwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +CustomMakeConfigWidget::CustomMakeConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent) + : CustomMakeConfigWidgetBase(parent), + m_part(part), m_configGroup(configGroup), m_dom( *part->projectDom() ) +{ + abort_box->setChecked(DomUtil::readBoolEntry(m_dom, m_configGroup + "/make/abortonerror")); + int numjobs = DomUtil::readIntEntry(m_dom, m_configGroup + "/make/numberofjobs"); + jobs_box->setValue(numjobs); + runMultiJobs->setChecked( (numjobs > 0 ) ); + + prio_box->setValue(DomUtil::readIntEntry(m_dom, m_configGroup + "/make/prio")); + dontact_box->setChecked(DomUtil::readBoolEntry(m_dom, m_configGroup + "/make/dontact")); + makebin_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/make/makebin")); + defaultTarget_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/make/defaulttarget")); + makeoptions_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/make/makeoptions")); + + envs_combo->setValidator(new QRegExpValidator(QRegExp("^\\D[^\\s]*"), this)); + m_allEnvironments = m_part->allMakeEnvironments(); + m_currentEnvironment = m_part->currentMakeEnvironment(); + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_envWidget = new EnvironmentVariablesWidget(m_dom, m_configGroup + "/make/environments/" + m_currentEnvironment, env_var_group); + envs_combo->insertStringList(m_allEnvironments); + envs_combo->setEditText(m_currentEnvironment); +} + + +CustomMakeConfigWidget::~CustomMakeConfigWidget() +{ + +} + +void CustomMakeConfigWidget::envNameChanged(const QString& envName) +{ + QStringList allEnvNames = m_part->allMakeEnvironments(); + bool canAdd = !allEnvNames.contains(envName) && !envName.contains("/") && !envName.isEmpty(); + bool canRemove = allEnvNames.contains(envName) && allEnvNames.count() > 1; + addenvs_button->setEnabled(canAdd); + copyenvs_button->setEnabled(canAdd); + removeenvs_button->setEnabled(canRemove); +} + +void CustomMakeConfigWidget::envChanged(const QString& envName) +{ + if (envName == m_currentEnvironment || !m_allEnvironments.contains(envName)) + return; + + // save settings of previously active environment + if (!m_currentEnvironment.isNull() ) + m_envWidget->accept(); + + m_currentEnvironment = envName; + m_envWidget->readEnvironment(m_dom, m_configGroup + "/make/environments/" + envName); + envs_combo->setEditText(envName); +} + +void CustomMakeConfigWidget::envAdded() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + envChanged(env); +} + +void CustomMakeConfigWidget::envRemoved() +{ + QString env = envs_combo->currentText(); + QDomNode node = DomUtil::elementByPath(m_dom, m_configGroup + "/make/environments"); + node.removeChild(node.namedItem(env)); + m_allEnvironments.remove(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = QString::null; + envChanged( m_allEnvironments[0] ); +} + +void CustomMakeConfigWidget::envCopied() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = env; + m_envWidget->changeConfigGroup(m_configGroup + "/make/environments/" + env); + envs_combo->setEditText(env); +} + +void CustomMakeConfigWidget::accept() +{ + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/abortonerror", abort_box->isChecked()); + if( runMultiJobs->isChecked() ) + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/numberofjobs", jobs_box->value()); + else + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/numberofjobs", 0); + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/prio", prio_box->value()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/dontact", dontact_box->isChecked()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/makebin", makebin_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/defaulttarget", defaultTarget_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/makeoptions", makeoptions_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/selectedenvironment", m_currentEnvironment); + m_envWidget->accept(); +} + +#include "custommakeconfigwidget.moc" diff --git a/buildtools/custommakefiles/custommakeconfigwidget.h b/buildtools/custommakefiles/custommakeconfigwidget.h new file mode 100644 index 00000000..ae8376c1 --- /dev/null +++ b/buildtools/custommakefiles/custommakeconfigwidget.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2003 by Hendrik Kueck * + * kueck@cs.ubc.ca * + * * + * 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. * + * * + ***************************************************************************/ +#ifndef CUSTOMMAKECONFIGWIDGET_H +#define CUSTOMMAKECONFIGWIDGET_H + +#include "domutil.h" + +#include + +class CustomProjectPart; +class EnvironmentVariablesWidget; + +/** +@author KDevelop Authors +*/ +class CustomMakeConfigWidget : public CustomMakeConfigWidgetBase +{ + Q_OBJECT + +public: + CustomMakeConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent); + + ~CustomMakeConfigWidget(); + +public slots: + void accept(); + +protected: + CustomProjectPart* m_part; + QString m_configGroup; + QDomDocument& m_dom; + + QStringList m_allEnvironments; + QString m_currentEnvironment; + + EnvironmentVariablesWidget* m_envWidget; + + virtual void envNameChanged(const QString& envName); + virtual void envChanged(const QString& envName); + virtual void envAdded(); + virtual void envRemoved(); + virtual void envCopied(); + +}; + +#endif diff --git a/buildtools/custommakefiles/custommakeconfigwidgetbase.ui b/buildtools/custommakefiles/custommakeconfigwidgetbase.ui new file mode 100644 index 00000000..b864a18f --- /dev/null +++ b/buildtools/custommakefiles/custommakeconfigwidgetbase.ui @@ -0,0 +1,395 @@ + +CustomMakeConfigWidgetBase + + + CustomMakeConfigWidgetBase + + + + 0 + 0 + 659 + 600 + + + + Make Options + + + + unnamed + + + + abort_box + + + A&bort on first error + + + + + dontact_box + + + Only di&splay commands without actually executing them + + + + + layout3 + + + + unnamed + + + + defaultTarget_edit + + + + + makebin_edit + + + + + makeoptions_label + + + A&dditional make options: + + + makeoptions_edit + + + + + makeoptions_edit + + + + + makebin_label + + + Name of make e&xecutable: + + + makebin_edit + + + + + defTarget_label + + + Default make &target: + + + defaultTarget_edit + + + + + + + layout6 + + + + unnamed + + + + runMultiJobs + + + Run multiple jobs + + + + + jobs_label + + + false + + + Number of simultaneous &jobs: + + + jobs_box + + + + + jobs_box + + + false + + + + 0 + 0 + 0 + 0 + + + + 30 + + + 1 + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 200 + 20 + + + + + + + + layout5 + + + + unnamed + + + + prio_label + + + Make &priority: + + + jobs_box + + + + + prio_box + + + + 0 + 0 + 0 + 0 + + + + 19 + + + -20 + + + 0 + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 192 + 20 + + + + + + + + layout3 + + + + unnamed + + + + envs_label + + + + 1 + 5 + 0 + 0 + + + + E&nvironment: + + + envs_combo + + + + + envs_combo + + + + 3 + 0 + 0 + 0 + + + + true + + + + + addenvs_button + + + &Add + + + false + + + + + copyenvs_button + + + Co&py + + + false + + + + + removeenvs_button + + + Re&move + + + false + + + + + + + env_var_group + + + + 5 + 3 + 0 + 0 + + + + Environment &Variables + + + + + + + envs_combo + textChanged(const QString&) + CustomMakeConfigWidgetBase + envNameChanged(const QString&) + + + envs_combo + activated(const QString&) + CustomMakeConfigWidgetBase + envChanged(const QString&) + + + copyenvs_button + clicked() + CustomMakeConfigWidgetBase + envCopied() + + + addenvs_button + clicked() + CustomMakeConfigWidgetBase + envAdded() + + + removeenvs_button + clicked() + CustomMakeConfigWidgetBase + envRemoved() + + + runMultiJobs + toggled(bool) + jobs_label + setEnabled(bool) + + + runMultiJobs + toggled(bool) + jobs_box + setEnabled(bool) + + + + abort_box + dontact_box + makebin_edit + makeoptions_edit + jobs_box + envs_combo + addenvs_button + copyenvs_button + removeenvs_button + + + kdialog.h + + + envNameChanged(const QString &) + envChanged(const QString&) + envAdded() + envRemoved() + envCopied() + + + + + klineedit.h + klineedit.h + klineedit.h + + diff --git a/buildtools/custommakefiles/custommanagerwidget.cpp b/buildtools/custommakefiles/custommanagerwidget.cpp new file mode 100644 index 00000000..9001480e --- /dev/null +++ b/buildtools/custommakefiles/custommanagerwidget.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 "custommanagerwidget.h" + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "customprojectpart.h" +#include "domutil.h" + +CustomManagerWidget::CustomManagerWidget( CustomProjectPart* part, QWidget* parent ) + : CustomManagerWidgetBase( parent ), m_part( part), m_dom( *part->projectDom() ) +{ + m_filetypes->insertStringList( DomUtil::readListEntry( m_dom, "kdevcustomproject/filetypes", "filetype" ) ); + KURLRequester* urlselector = new KURLRequester( ); + urlselector->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + urlselector->setURL( QString::null ); + urlselector->completionObject() ->setDir( part->projectDirectory() ); + urlselector->fileDialog() ->setURL( KURL( part->projectDirectory() ) ); + m_blacklistBox = new KEditListBox( i18n("blacklisted files and directories are not" + " considered part of the project, even if they fit one of " + "the wildcard patterns in the project file list", + "Blacklisted files/dirs"), urlselector->customEditor(), this); + m_blacklistBox->setButtons( KEditListBox::Add | KEditListBox::Remove ); + m_blacklistBox->insertStringList( DomUtil::readListEntry( m_dom, "kdevcustomproject/blacklist","path") ); + grid->addWidget( m_blacklistBox, 0, 1 ); + connect(m_blacklistBox, SIGNAL(added(const QString&)), this, SLOT(checkUrl(const QString&))); +} + +void CustomManagerWidget::checkUrl(const QString& url) +{ + kdDebug(9025) << "got file:" << url << endl; + if( !QFileInfo(url).isRelative() ) + { + kdDebug(9025) << "seems to be non-relative" << endl; + QString relpath = m_part->relativeToProject( url ); + QListBoxItem* item = m_blacklistBox->listBox()->findItem( url ); + m_blacklistBox->listBox()->takeItem( item ); + kdDebug(9025) << "relative path:" << relpath << endl; + if( !relpath.isEmpty() ) + m_blacklistBox->insertItem( relpath ); + } +} + +CustomManagerWidget::~CustomManagerWidget() +{ +} + +void CustomManagerWidget::accept() +{ + DomUtil::writeListEntry( m_dom, "kdevcustomproject/filetypes", "filetype", + m_filetypes->items() ); + DomUtil::writeListEntry( m_dom, "kdevcustomproject/blacklist", "path", + m_blacklistBox->items() ); +} + + +#include "custommanagerwidget.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custommanagerwidget.h b/buildtools/custommakefiles/custommanagerwidget.h new file mode 100644 index 00000000..4f15f156 --- /dev/null +++ b/buildtools/custommakefiles/custommanagerwidget.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef CUSTOMMANAGERWIDGET_H +#define CUSTOMMANAGERWIDGET_H + +#include "custommanagerwidgetbase.h" + + +#include + +class CustomProjectPart; +class KEditListBox; + +class CustomManagerWidget : public CustomManagerWidgetBase +{ +Q_OBJECT + +public: + CustomManagerWidget( CustomProjectPart* part, QWidget* parent ); + ~CustomManagerWidget(); +public slots: + void checkUrl(const QString& url); + void accept(); +private: + CustomProjectPart* m_part; + QDomDocument& m_dom; + KEditListBox* m_blacklistBox; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/custommanagerwidgetbase.ui b/buildtools/custommakefiles/custommanagerwidgetbase.ui new file mode 100644 index 00000000..a388b288 --- /dev/null +++ b/buildtools/custommakefiles/custommanagerwidgetbase.ui @@ -0,0 +1,74 @@ + +CustomManagerWidgetBase + + + CustomManagerWidgetBase + + + + 0 + 0 + 467 + 393 + + + + Custom Manager Options + + + + unnamed + + + + grid + + + + unnamed + + + + m_filetypes + + + Filetypes used in Project + + + Remove|Add + + + Add filetypes to be used in Projects, can be full filenames or shell wildcards + + + Each entry contains a filetype used in the project in the form of a filename or a filename wildcard (using shell wildcards). +This will be used when adding/removing files in directories and re-populating the project + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 108 + + + + + + + + + + keditlistbox.h + klineedit.h + + diff --git a/buildtools/custommakefiles/customotherconfigwidget.cpp b/buildtools/custommakefiles/customotherconfigwidget.cpp new file mode 100644 index 00000000..47fe4b4d --- /dev/null +++ b/buildtools/custommakefiles/customotherconfigwidget.cpp @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2005 by Achim Herwig * + * achim.herwig@wodca.de * + * * + * 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 "customotherconfigwidget.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +CustomOtherConfigWidget::CustomOtherConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent) + : CustomOtherConfigWidgetBase(parent), + m_part(part), m_configGroup(configGroup), m_dom( *part->projectDom() ) +{ + prio_box->setValue(DomUtil::readIntEntry(m_dom, m_configGroup + "/other/prio")); + makebin_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/other/otherbin")); + defaultTarget_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/other/defaulttarget")); + makeoptions_edit->setText(DomUtil::readEntry(m_dom, m_configGroup + "/other/otheroptions")); + + envs_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + m_allEnvironments = m_part->allMakeEnvironments(); + m_currentEnvironment = m_part->currentMakeEnvironment(); + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_envWidget = new EnvironmentVariablesWidget(m_dom, m_configGroup + "/other/environments/" + m_currentEnvironment, env_var_group); + envs_combo->insertStringList(m_allEnvironments); + envs_combo->setEditText(m_currentEnvironment); +} + + +CustomOtherConfigWidget::~CustomOtherConfigWidget() +{ + +} + +void CustomOtherConfigWidget::envNameChanged(const QString& envName) +{ + QStringList allEnvNames = m_part->allMakeEnvironments(); + bool canAdd = !allEnvNames.contains(envName) && !envName.contains("/") && !envName.isEmpty(); + bool canRemove = allEnvNames.contains(envName) && allEnvNames.count() > 1; + addenvs_button->setEnabled(canAdd); + copyenvs_button->setEnabled(canAdd); + removeenvs_button->setEnabled(canRemove); +} + +void CustomOtherConfigWidget::envChanged(const QString& envName) +{ + if (envName == m_currentEnvironment || !m_allEnvironments.contains(envName)) + return; + + // save settings of previously active environment + if (!m_currentEnvironment.isNull() ) + m_envWidget->accept(); + + m_currentEnvironment = envName; + m_envWidget->readEnvironment(m_dom, m_configGroup + "/other/environments/" + envName); + envs_combo->setEditText(envName); +} + +void CustomOtherConfigWidget::envAdded() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + envChanged(env); +} + +void CustomOtherConfigWidget::envRemoved() +{ + QString env = envs_combo->currentText(); + QDomNode node = DomUtil::elementByPath(m_dom, m_configGroup + "/other/environments"); + node.removeChild(node.namedItem(env)); + m_allEnvironments.remove(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = QString::null; + envChanged( m_allEnvironments[0] ); +} + +void CustomOtherConfigWidget::envCopied() +{ + QString env = envs_combo->currentText(); + m_allEnvironments.append(env); + envs_combo->clear(); + envs_combo->insertStringList(m_allEnvironments); + m_currentEnvironment = env; + m_envWidget->changeConfigGroup(m_configGroup + "/other/environments/" + env); + envs_combo->setEditText(env); +} + +void CustomOtherConfigWidget::accept() +{ + DomUtil::writeIntEntry(m_dom, m_configGroup + "/other/prio", prio_box->value()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/otherbin", makebin_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/defaulttarget", defaultTarget_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/otheroptions", makeoptions_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/other/selectedenvironment", m_currentEnvironment); + m_envWidget->accept(); +} + +#include "customotherconfigwidget.moc" +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/custommakefiles/customotherconfigwidget.h b/buildtools/custommakefiles/customotherconfigwidget.h new file mode 100644 index 00000000..755df98b --- /dev/null +++ b/buildtools/custommakefiles/customotherconfigwidget.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005 by Achim Herwig * + * achim.herwig@wodca.de * + * * + * 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. * + * * + ***************************************************************************/ +#ifndef CUSTOMOTHERCONFIGWIDGET_H +#define CUSTOMOTHERCONFIGWIDGET_H + +#include "domutil.h" + +#include + +class CustomProjectPart; +class EnvironmentVariablesWidget; + +/** +@author KDevelop Authors +*/ +class CustomOtherConfigWidget : public CustomOtherConfigWidgetBase +{ + Q_OBJECT + +public: + CustomOtherConfigWidget(CustomProjectPart* part, const QString& configGroup, QWidget* parent); + + ~CustomOtherConfigWidget(); + +public slots: + void accept(); + +protected: + CustomProjectPart* m_part; + QString m_configGroup; + QDomDocument& m_dom; + + QStringList m_allEnvironments; + QString m_currentEnvironment; + + EnvironmentVariablesWidget* m_envWidget; + + virtual void envNameChanged(const QString& envName); + virtual void envChanged(const QString& envName); + virtual void envAdded(); + virtual void envRemoved(); + virtual void envCopied(); + +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/custommakefiles/customotherconfigwidgetbase.ui b/buildtools/custommakefiles/customotherconfigwidgetbase.ui new file mode 100644 index 00000000..174391ae --- /dev/null +++ b/buildtools/custommakefiles/customotherconfigwidgetbase.ui @@ -0,0 +1,288 @@ + +CustomOtherConfigWidgetBase + + + CustomOtherConfigWidgetBase + + + + 0 + 0 + 659 + 600 + + + + Make Options + + + + unnamed + + + + layout3 + + + + unnamed + + + + defaultTarget_edit + + + + + makebin_edit + + + + + makeoptions_label + + + Add&itional options: + + + makeoptions_edit + + + + + makeoptions_edit + + + + + makebin_label + + + Name of build &script + + + makebin_edit + + + + + defTarget_label + + + Default &target: + + + defaultTarget_edit + + + + + + + layout2 + + + + unnamed + + + + prio_label + + + Run with priority: + + + jobs_box + + + + + prio_box + + + + 0 + 0 + 0 + 0 + + + + 19 + + + -20 + + + 0 + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + + + layout3 + + + + unnamed + + + + envs_label + + + + 1 + 5 + 0 + 0 + + + + E&nvironment: + + + envs_combo + + + + + envs_combo + + + + 3 + 0 + 0 + 0 + + + + true + + + + + addenvs_button + + + &Add + + + false + + + + + copyenvs_button + + + &Copy + + + false + + + + + removeenvs_button + + + Re&move + + + false + + + + + + + env_var_group + + + + 5 + 3 + 0 + 0 + + + + Environment &Variables + + + + + + + envs_combo + textChanged(const QString&) + CustomOtherConfigWidgetBase + envNameChanged(const QString&) + + + envs_combo + activated(const QString&) + CustomOtherConfigWidgetBase + envChanged(const QString&) + + + copyenvs_button + clicked() + CustomOtherConfigWidgetBase + envCopied() + + + addenvs_button + clicked() + CustomOtherConfigWidgetBase + envAdded() + + + removeenvs_button + clicked() + CustomOtherConfigWidgetBase + envRemoved() + + + + makebin_edit + makeoptions_edit + envs_combo + addenvs_button + copyenvs_button + removeenvs_button + + + kdialog.h + + + envNameChanged(const QString &) + envChanged(const QString&) + envAdded() + envRemoved() + envCopied() + + + + diff --git a/buildtools/custommakefiles/customprojectpart.cpp b/buildtools/custommakefiles/customprojectpart.cpp new file mode 100644 index 00000000..f061dadc --- /dev/null +++ b/buildtools/custommakefiles/customprojectpart.cpp @@ -0,0 +1,1669 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 "customprojectpart.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "runoptionswidget.h" +#include "makeoptionswidget.h" +#include "custombuildoptionswidget.h" +#include "custommakeconfigwidget.h" +#include "customotherconfigwidget.h" +#include "custommanagerwidget.h" +#include "config.h" +#include "envvartools.h" +#include "urlutil.h" + +#include "selectnewfilesdialog.h" + +#include + +typedef KDevGenericFactory CustomProjectFactory; +static const KDevPluginInfo data( "kdevcustomproject" ); +K_EXPORT_COMPONENT_FACTORY( libkdevcustomproject, CustomProjectFactory( data ) ) + +CustomProjectPart::CustomProjectPart( QObject *parent, const char *name, const QStringList & ) + : KDevBuildTool( &data, parent, name ? name : "CustomProjectPart" ) + , m_lastCompilationFailed( false ), m_recursive( false ), m_first_recursive( false ) +{ + setInstance( CustomProjectFactory::instance() ); + setXMLFile( "kdevcustomproject.rc" ); + + m_executeAfterBuild = false; + + KAction *action; + + action = new KAction( i18n( "Re-Populate Project" ), 0, this, SLOT( populateProject() ), actionCollection(), "repopulate_project" ); + action->setToolTip( i18n( "Re-Populate Project" ) ); + action->setWhatsThis( i18n( "Re-Populate Project

Re-Populates the project, searching through the project directory and adding all files that match one of the wildcards set in the custom manager options of the project filelist." ) ); + + action = new KAction( i18n( "&Build Project" ), "make_kdevelop", Key_F8, + this, SLOT( slotBuild() ), + actionCollection(), "build_build" ); + action->setToolTip( i18n( "Build project" ) ); + action->setWhatsThis( i18n( "Build project

Runs make from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Build Options tab." ) ); + + action = new KAction( i18n( "&Build Active Directory" ), "make_kdevelop", Key_F7, + this, SLOT( slotBuildActiveDir() ), + actionCollection(), "build_buildactivetarget" ); + action->setToolTip( i18n( "Build active directory" ) ); + action->setWhatsThis( i18n( "Build active directory

Constructs a series of make commands to build the active directory. " + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + action = new KAction( i18n( "Compile &File" ), "make_kdevelop", + this, SLOT( slotCompileFile() ), + actionCollection(), "build_compilefile" ); + action->setToolTip( i18n( "Compile file" ) ); + action->setWhatsThis( i18n( "Compile file

Runs make filename.o command from the directory where 'filename' is the name of currently opened file.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Build Options tab." ) ); + + action = new KAction( i18n( "Install" ), 0, + this, SLOT( slotInstall() ), + actionCollection(), "build_install" ); + action->setToolTip( i18n( "Install" ) ); + action->setWhatsThis( i18n( "Install

Runs make install command from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + action = new KAction( i18n( "Install Active Directory" ), 0, + this, SLOT( slotInstallActiveDir() ), + actionCollection(), "build_installactivetarget" ); + action->setToolTip( i18n( "Install active directory" ) ); + action->setWhatsThis( i18n( "Install active directory

Runs make install command from the active directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + action = new KAction( i18n( "Install (as root user)" ), 0, + this, SLOT( slotInstallWithKdesu() ), + actionCollection(), "build_install_kdesu" ); + action->setToolTip( i18n( "Install as root user" ) ); + action->setWhatsThis( i18n( "Install

Runs make install command from the project directory with root privileges.
" + "It is executed via kdesu command.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + action = new KAction( i18n( "&Clean Project" ), 0, + this, SLOT( slotClean() ), + actionCollection(), "build_clean" ); + action->setToolTip( i18n( "Clean project" ) ); + action->setWhatsThis( i18n( "Clean project

Runs make clean command from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Build Options tab." ) ); + + action = new KAction( i18n( "Execute Program" ), "exec", 0, + this, SLOT( slotExecute() ), + actionCollection(), "build_execute" ); + action->setToolTip( i18n( "Execute program" ) ); + action->setWhatsThis( i18n( "Execute program

Executes the main program specified in project settings, Run Options tab. " + "If it is not specified then the active target is used to determine the application to run." ) ); + + KActionMenu *menu = new KActionMenu( i18n( "Build &Target" ), + actionCollection(), "build_target" ); + m_targetMenu = menu->popupMenu(); + menu->setToolTip( i18n( "Build target" ) ); + menu->setWhatsThis( i18n( "Build target

Runs make targetname from the project directory (targetname is the name of the target selected).
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Build Options tab." ) ); + + m_targetObjectFilesMenu = new QPopupMenu(); + m_targetOtherFilesMenu = new QPopupMenu(); + + m_makeEnvironmentsSelector = new KSelectAction( i18n( "Make &Environment" ), 0, + actionCollection(), "build_make_environment" ); + m_makeEnvironmentsSelector->setToolTip( i18n( "Make environment" ) ); + m_makeEnvironmentsSelector->setWhatsThis( i18n( "Make Environment

Choose the set of environment variables to be passed on to make.
" + "Environment variables can be specified in the project " + "settings dialog, Build Options tab." ) ); + + connect( m_targetMenu, SIGNAL( aboutToShow() ), + this, SLOT( updateTargetMenu() ) ); + connect( m_targetMenu, SIGNAL( activated( int ) ), + this, SLOT( targetMenuActivated( int ) ) ); + connect( m_targetObjectFilesMenu, SIGNAL( activated( int ) ), + this, SLOT( targetObjectFilesMenuActivated( int ) ) ); + connect( m_targetOtherFilesMenu, SIGNAL( activated( int ) ), + this, SLOT( targetOtherFilesMenuActivated( int ) ) ); + connect( m_makeEnvironmentsSelector->popupMenu(), SIGNAL( aboutToShow() ), + this, SLOT( updateMakeEnvironmentsMenu() ) ); + connect( m_makeEnvironmentsSelector->popupMenu(), SIGNAL( activated( int ) ), + this, SLOT( makeEnvironmentsMenuActivated( int ) ) ); + connect( core(), SIGNAL( projectConfigWidget( KDialogBase* ) ), + this, SLOT( projectConfigWidget( KDialogBase* ) ) ); + connect( core(), SIGNAL( contextMenu( QPopupMenu *, const Context * ) ), + this, SLOT( contextMenu( QPopupMenu *, const Context * ) ) ); + + connect( makeFrontend(), SIGNAL( commandFinished( const QString& ) ), + this, SLOT( slotCommandFinished( const QString& ) ) ); + connect( makeFrontend(), SIGNAL( commandFailed( const QString& ) ), + this, SLOT( slotCommandFailed( const QString& ) ) ); +} + + +CustomProjectPart::~CustomProjectPart() +{} + + +void CustomProjectPart::projectConfigWidget( KDialogBase *dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage( i18n( "Custom Manager" ), i18n( "Custom Manager" ), BarIcon( "make", KIcon::SizeMedium ) ); + CustomManagerWidget *w0 = new CustomManagerWidget( this, vbox ); + connect( dlg, SIGNAL( okClicked() ), w0, SLOT( accept() ) ); + + vbox = dlg->addVBoxPage( i18n( "Run Options" ), i18n( "Run Options" ), BarIcon( "make", KIcon::SizeMedium ) ); + RunOptionsWidget *w1 = new RunOptionsWidget( *projectDom(), "/kdevcustomproject", buildDirectory(), vbox ); + connect( dlg, SIGNAL( okClicked() ), w1, SLOT( accept() ) ); + vbox = dlg->addVBoxPage( i18n( "Build Options" ), i18n( "Build Options" ), BarIcon( "make", KIcon::SizeMedium ) ); + QTabWidget *buildtab = new QTabWidget( vbox ); + + CustomBuildOptionsWidget *w2 = new CustomBuildOptionsWidget( *projectDom(), buildtab ); + connect( dlg, SIGNAL( okClicked() ), w2, SLOT( accept() ) ); + buildtab->addTab( w2, i18n( "&Build" ) ); + + CustomOtherConfigWidget *w4 = new CustomOtherConfigWidget( this, "/kdevcustomproject", buildtab ); + connect( dlg, SIGNAL( okClicked() ), w4, SLOT( accept() ) ); + buildtab->addTab( w4, i18n( "&Other" ) ); + + CustomMakeConfigWidget *w3 = new CustomMakeConfigWidget( this, "/kdevcustomproject", buildtab ); + buildtab->addTab( w3, i18n( "Ma&ke" ) ); + w2->setMakeOptionsWidget( buildtab, w3, w4 ); + connect( dlg, SIGNAL( okClicked() ), w3, SLOT( accept() ) ); + +} + + +void CustomProjectPart::contextMenu( QPopupMenu *popup, const Context *context ) +{ + if ( !context->hasType( Context::FileContext ) ) + return; + + const FileContext *fcontext = static_cast( context ); + + m_contextAddFiles.clear(); + m_contextRemoveFiles.clear(); + + QString popupstr = fcontext->urls().first().fileName(); + + if ( popupstr == QString::null ) + popupstr = "."; + + if ( fcontext->urls().size() == 1 && URLUtil::isDirectory( fcontext->urls().first() ) && !isInBlacklist( fcontext->urls().first().path() ) ) + { + popup->insertSeparator(); + // remember the name of the directory + m_contextDirName = fcontext->urls().first().path(); + m_contextDirName = m_contextDirName.mid( project()->projectDirectory().length() + 1 ); + int id = popup->insertItem( i18n( "Make Active Directory" ), + this, SLOT( slotChooseActiveDirectory() ) ); + popup->setWhatsThis( id, i18n( "Make active directory

" + "Chooses this directory as the destination for new files created using wizards " + "like the New Class wizard." ) ); + } + + kdDebug( 9025 ) << "context urls: " << fcontext->urls() << endl; + if ( fcontext->urls().size() == 1 && ( isProjectFileType( fcontext->urls().first().path() ) || URLUtil::isDirectory( fcontext->urls().first() ) ) ) + { + popup->insertSeparator(); + m_contextDirName = fcontext->urls().first().path(); + m_contextDirName = m_contextDirName.mid( project()->projectDirectory().length() + 1 ); + int id; + if ( isInBlacklist( m_contextDirName ) ) + { + id = popup->insertItem( i18n( "Remove from blacklist" ), + this, SLOT( slotChangeBlacklist() ) ); + popup->setWhatsThis( id, i18n( "Remove from blacklist

" + "Removes the given file or directory from the " + "blacklist if it is already in it.
The blacklist contains files and" + " directories that should be ignored even if they match a project filetype " + "pattern" ) ); + } + else + { + id = popup->insertItem( i18n( "Add to blacklist" ), + this, SLOT( slotChangeBlacklist() ) ); + popup->setWhatsThis( id, i18n( "Add to blacklist

" + "Adds the given file or directory to the blacklist.
The blacklist contains files and" + " directories that should be ignored even if they match a project filetype " + "pattern" ) ); + } + } + + const KURL::List urls = fcontext->urls(); + + bool dirAddRecursive = false; + bool dirDelRecursive = false; + + for ( KURL::List::ConstIterator it = urls.begin(); it != urls.end(); ++it ) + { + kdDebug( 9025 ) << "Checking URL: " << *it << endl; + QString canPath( URLUtil::canonicalPath(( *it ).path() ) ); + QString relPath = relativeToProject( canPath ); + kdDebug( 9025 ) << "relpath: " << relPath << "|canpath: " << canPath << endl; + if ( isInBlacklist( relPath ) ) + continue; + if ((( *it ).isLocalFile() && isProjectFileType(( *it ).fileName() ) ) ) + { + if ( project()->isProjectFile( canPath ) ) + m_contextRemoveFiles << relPath; + if ( !project()->isProjectFile( canPath ) ) + m_contextAddFiles << relPath; + } + if ( QFileInfo(( *it ).path() ).isDir() ) + { + if ( containsProjectFiles( canPath ) || project()->isProjectFile( canPath ) ) + { + if ( containsProjectFiles( canPath ) ) + dirDelRecursive = true; + m_contextRemoveFiles << relPath; + } + if ( containsNonProjectFiles( canPath ) || !project()->isProjectFile( canPath ) ) + { + if ( containsNonProjectFiles( canPath ) ) + dirAddRecursive = true; + m_contextAddFiles << relPath; + } + } + } + + if ( m_contextAddFiles.size() > 0 || m_contextRemoveFiles.size() > 0 ) + popup->insertSeparator(); + if ( m_contextAddFiles.size() > 0 ) + { + int id = popup->insertItem( i18n( "Add Selected File/Dir(s) to Project" ), + this, SLOT( slotAddToProject() ) ); + popup->setWhatsThis( id, i18n( "Add to project

Adds selected file/dir(s) to the list of files in the project. " + "Note that the files should be manually added to the corresponding makefile or build.xml." ) ); + if ( dirAddRecursive ) + { + int id = popup->insertItem( i18n( "Add Selected Dir(s) to Project (recursive)" ), + this, SLOT( slotAddToProjectRecursive() ) ); + popup->setWhatsThis( id, i18n( "Add to project

Recursively adds selected dir(s) to the list of files in the project. " + "Note that the files should be manually added to the corresponding makefile or build.xml." ) ); + } + } + + if ( m_contextRemoveFiles.size() > 0 ) + { + int id = popup->insertItem( i18n( "Remove Selected File/Dir(s) From Project" ), + this, SLOT( slotRemoveFromProject() ) ); + popup->setWhatsThis( id, i18n( "Remove from project

Removes selected file/dir(s) from the list of files in the project. " + "Note that the files should be manually excluded from the corresponding makefile or build.xml." ) ); + + if ( dirDelRecursive ) + { + int id = popup->insertItem( i18n( "Remove Selected Dir(s) From Project (recursive)" ), + this, SLOT( slotRemoveFromProjectRecursive() ) ); + popup->setWhatsThis( id, i18n( "Remove from project

Recursively removes selected dir(s) from the list of files in the project. " + "Note that the files should be manually excluded from the corresponding makefile or build.xml." ) ); + } + } +} + + +void CustomProjectPart::slotAddToProject() +{ + m_recursive = false; + m_first_recursive = true; + addFiles( m_contextAddFiles ); +} + + +void CustomProjectPart::slotRemoveFromProject() +{ + m_recursive = false; + m_first_recursive = true; + removeFiles( m_contextRemoveFiles ); +} + + +void CustomProjectPart::slotAddToProjectRecursive() +{ + m_recursive = true; + addFiles( m_contextAddFiles ); + m_recursive = false; +} + + +void CustomProjectPart::slotRemoveFromProjectRecursive() +{ + m_recursive = true; + removeFiles( m_contextRemoveFiles ); + m_recursive = false; +} + +void CustomProjectPart::slotChangeBlacklist() +{ + switchBlacklistEntry( m_contextDirName ); +} + +void CustomProjectPart::slotChooseActiveDirectory() +{ + QString olddir = activeDirectory(); + QDomDocument &dom = *projectDom(); + DomUtil::writeEntry( dom, "/kdevcustomproject/general/activedir", m_contextDirName ); + emit activeDirectoryChanged( olddir, activeDirectory() ); +} + + +void CustomProjectPart::openProject( const QString &dirName, const QString &projectName ) +{ + m_projectDirectory = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if ( DomUtil::readEntry( dom, "/kdevcustomproject/run/directoryradio" ) == "" ) + { + DomUtil::writeEntry( dom, "/kdevcustomproject/run/directoryradio", "executable" ); + } + + if ( filetypes().isEmpty() ) + { + QStringList types; + types << "*.java" << "*.h" << "*.H" << "*.hh" << "*.hxx" << "*.hpp" << "*.c" << "*.C" + << "*.cc" << "*.cpp" << "*.c++" << "*.cxx" << "Makefile" << "CMakeLists.txt"; + DomUtil::writeListEntry( dom, "/kdevcustomproject/filetypes", "filetype", types ); + } + + /*this entry is currently only created by the cmake kdevelop3 project generator + in order to support completely-out-of-source builds, where nothing, not + even the kdevelop project files are created in the source directory, Alex + */ + m_filelistDir = DomUtil::readEntry( dom, "/kdevcustomproject/filelistdirectory" ); + if ( m_filelistDir.isEmpty() ) + m_filelistDir = dirName; + + if ( QFileInfo( m_filelistDir + "/" + projectName.lower() + + ".kdevelop.filelist" ).exists() ) + { + QDir( m_filelistDir ).rename( + projectName.lower() + ".kdevelop.filelist", + projectName + ".kdevelop.filelist" ); + } + + QFile f( m_filelistDir + "/" + projectName + ".kdevelop.filelist" ); + if ( f.open( IO_ReadOnly ) ) + { + QTextStream stream( &f ); + while ( !stream.atEnd() ) + { + QString s = stream.readLine(); + // Skip comments. + if ( s.isEmpty() || s.startsWith( "#" ) ) + continue; + // Skip non-existent files. + if ( ! QFileInfo( projectDirectory() + "/" + s ).exists() ) + continue; + // Do not bother with files already in project or on blacklist. + if ( isInProject( s ) || isInBlacklist( s ) ) + continue; + addToProject( s ); + } + QStringList newfiles; + findNewFiles( dirName, newfiles ); + + if ( newfiles.count() > 0 ) + { + addNewFilesToProject( newfiles ); + } + + } + else + { + int r = KMessageBox::questionYesNo( mainWindow()->main(), + i18n( "This project does not contain any files yet.\n" + "Populate it with all C/C++/Java files below " + "the project directory?" ), QString::null, i18n( "Populate" ), i18n( "Do Not Populate" ) ); + if ( r == KMessageBox::Yes ) + populateProject(); + } + + + // check if there is an old envvars entry (from old project file with single make environment) + QString buildtool = DomUtil::readEntry( dom , "/kdevcustomproject/build/buildtool" ); + QDomElement el = + DomUtil::elementByPath( dom , "/kdevcustomproject/" + buildtool + "/envvars" ); + if ( !el.isNull() ) + { + QDomElement envs = DomUtil::createElementByPath( dom , "/kdevcustomproject/" + buildtool + "/environments" ); + DomUtil::makeEmpty( envs ); + el.setTagName( "default" ); + envs.appendChild( el ); + } + KDevProject::openProject( dirName, projectName ); +} + + +/** + * @brief Recursively search given directory searching for files which may be part of this project. + * + * The files found not in a black list, + * and not being already part of our project are gathered. + * + * @param dir directory to scan (and recurse) for potential project files. + * @param[out] fileList the list of files found. + */ +void CustomProjectPart::findNewFiles( const QString& dir, QStringList& filelist ) const +{ + if ( dir.isEmpty() ) + return; + QStringList fileentries = QDir( dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( dir ).entryList( QDir::Dirs ); + QStringList entries = fileentries + dirs; + QString relpath = relativeToProject( dir ); + if ( !relpath.isEmpty() ) + relpath += "/"; + for ( QStringList::const_iterator it = entries.begin(); it != entries.end(); ++it ) + { + // Only process genuine entries - files and directories. + if (( *it == "." ) || ( *it == ".." ) ) + continue; + // If the entry (be it a file or a directory) is already part of this project, proceed to next one. + const QString relativeEntry( relpath + *it ); + if ( isInProject( relativeEntry ) ) + continue; + // If the entry is blacklisted, proceed to next one. + // Note that by using generic isInBlacklist(), + // we are actually wasting resources, + // because it also tests whether any parent directory of relativeEntry is blacklisted. + // But by the order we are traversing and processing the directories, + // we know it is not the case, ever. + if ( isInBlacklist( relativeEntry ) ) + continue; + // We have a new, non-blacklisted entry. + // Recurse into it (a directory) or add it to the potential list of new project files. + const QString absoluteEntry( dir + "/" + *it ); + if ( QFileInfo( absoluteEntry ).isFile() ) + { + filelist << relativeEntry; + } + else if ( QFileInfo( absoluteEntry ).isDir() ) + { + bool searchRecursive = true; + QFileInfo fi( absoluteEntry ); + if( fi.isSymLink() ) + { + QString realDir = fi.readLink(); + if( QFileInfo( realDir ).exists() ) + { + for( QStringList::const_iterator it = filelist.constBegin(); it != filelist.constEnd(); ++it ) + { + + if( QFileInfo(projectDirectory()+"/"+*it).absFilePath().startsWith( realDir ) ) + { + searchRecursive = false; + } + } + } else { + searchRecursive = false; + } + } + if( searchRecursive ) + { + findNewFiles( absoluteEntry, filelist ); + } + } + } +} + + +void CustomProjectPart::populateProject() +{ + + KDialogBase* dlg = new KDialogBase( mainWindow()->main(), "typeselector", true, + "Select filetypes of project", KDialogBase::Ok | KDialogBase::Cancel ); + QVBox* box = dlg->makeVBoxMainWidget(); + KEditListBox* lb = new KEditListBox( "Filetypes in the project", box, "selecttypes", + false, KEditListBox::Add | KEditListBox::Remove ); + lb->setItems( filetypes() ); + if ( dlg->exec() == QDialog::Accepted ) + { + setFiletypes( lb->items() ); + } + + QApplication::setOverrideCursor( Qt::waitCursor ); + removeFiles( allFiles() ); + updateBlacklist( QStringList() ); + + QStringList newlist; + + findNewFiles( projectDirectory(), newlist ); + + QApplication::restoreOverrideCursor(); + addNewFilesToProject( newlist ); +} + + +void CustomProjectPart::closeProject() +{ + saveProject(); +} + +void CustomProjectPart::saveProject() +{ + QFile f( m_filelistDir + "/" + m_projectName + ".kdevelop.filelist" ); + if ( !f.open( IO_WriteOnly ) ) + return; + + QTextStream stream( &f ); + stream << "# KDevelop Custom Project File List" << endl; + + ProjectFilesSet::ConstIterator it; + for ( it = m_sourceFilesSet.constBegin(); it != m_sourceFilesSet.constEnd(); ++it ) + stream << it.key() << endl; + f.close(); +} + + +QString CustomProjectPart::projectDirectory() const +{ + return m_projectDirectory; +} + + +QString CustomProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList CustomProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry( *projectDom(), "/kdevcustomproject/run/envvars", "envvar", "name", "value" ); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString CustomProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory( "kdevcustomproject" ); + if ( cwd.isEmpty() ) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString CustomProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevcustomproject/run/mainprogram" ); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith( "/" ) ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the debug command line arguments */ +QString CustomProjectPart::debugArguments() const +{ + return DomUtil::readEntry( *projectDom(), "/kdevcustomproject/run/globaldebugarguments" ); +} + + +/** Retuns a QString with the run command line arguments */ +QString CustomProjectPart::runArguments() const +{ + return DomUtil::readEntry( *projectDom(), "/kdevcustomproject/run/programargs" ); +} + +QString CustomProjectPart::activeDirectory() const +{ + QDomDocument &dom = *projectDom(); + return DomUtil::readEntry( dom, "/kdevcustomproject/general/activedir", "." ); +} + + +QStringList CustomProjectPart::allFiles() const +{ + return m_sourceFilesSet.keys(); +} + + +void CustomProjectPart::addFile( const QString &fileName ) +{ + QStringList fileList; + fileList.append( fileName ); + + this->addFiles( fileList ); +} + +void CustomProjectPart::addFiles( const QStringList& fileList ) +{ + QStringList::ConstIterator it; + QStringList addedFiles; + QStringList myfileList = fileList; + kdDebug( 9025 ) << "Adding files: " << myfileList << endl; + myfileList.remove( "." ); + myfileList.remove( "" ); + myfileList.remove( ".." ); + for ( it = myfileList.begin(); it != myfileList.end(); ++it ) + { + if ( isInBlacklist( *it ) ) + continue; + QString relpath; + kdDebug( 9025 ) << "Checking path: " << *it << endl; + if ( QDir::isRelativePath( *it ) ) + { + kdDebug( 9025 ) << *it << " is relative" << endl; + relpath = *it; + } + else + { + kdDebug( 9025 ) << *it << " is not relative" << endl; + relpath = relativeToProject( *it ); + } + + if ( !QFileInfo( projectDirectory() + "/" + relpath ).exists() ) + continue; + + if ( QFileInfo( projectDirectory() + "/" + relpath ).isDir() && ( m_recursive || m_first_recursive ) ) + { + kdDebug( 9025 ) << "is a dir and " << m_recursive << "|" << m_first_recursive << endl; + m_first_recursive = false; + QStringList fileentries = QDir( projectDirectory() + "/" + relpath ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( projectDirectory() + "/" + relpath ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + for ( QStringList::iterator subit = subentries.begin(); subit != subentries.end(); ++subit ) + { + if ( *subit != "." && *subit != ".." ) + *subit = relpath + "/" + ( *subit ); + if (( *subit ).startsWith( "/" ) ) + *subit = ( *subit ).mid( 1, ( *subit ).length() ); + } + addFiles( subentries ); + addedFiles << relpath; + addToProject( relpath ); + m_first_recursive = true; + } + else if ( isProjectFileType( QFileInfo( relpath ).fileName() ) && ( ! isInProject( relpath ) ) ) + { + QStringList paths = QStringList::split( "/", relpath ); + paths.pop_back(); + QString path; + for ( QStringList::const_iterator it = paths.begin(); it != paths.end(); ++it ) + { + path += *it; + if ( ! isInProject( path ) ) + { + addedFiles << path; + addToProject( path ); + } + path += "/"; + } + addedFiles << relpath; + addToProject( relpath ); + } + else + { + kdDebug( 9025 ) << "not adding " << relpath << endl; + } + } + m_first_recursive = false; + saveProject(); + + kdDebug( 9025 ) << "Emitting addedFilesToProject" << addedFiles << endl; + emit addedFilesToProject( addedFiles ); +} + +void CustomProjectPart::removeFile( const QString &fileName ) +{ + QStringList fileList; + fileList.append( fileName ); + + this->removeFiles( fileList ); +} + +void CustomProjectPart::removeFiles( const QStringList& fileList ) +{ + kdDebug( 9025 ) << "Emitting removedFilesFromProject" << fileList << endl; + QStringList removedFiles; + QStringList myfileList = fileList; + QStringList::ConstIterator it; + myfileList.remove( "." ); + myfileList.remove( ".." ); + myfileList.remove( "" ); + + for ( it = myfileList.begin(); it != myfileList.end(); ++it ) + { + QString relpath; + if ( QDir::isRelativePath( *it ) ) + relpath = *it; + else + relpath = relativeToProject( *it ); + + if ( QFileInfo( projectDirectory() + "/" + relpath ).isDir() && ( m_recursive || m_first_recursive ) ) + { + m_first_recursive = false; + QStringList fileentries = QDir( projectDirectory() + "/" + relpath ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( projectDirectory() + "/" + relpath ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + for ( QStringList::iterator subit = subentries.begin(); subit != subentries.end(); ++subit ) + if ( *subit != "." && *subit != ".." ) + *subit = relpath + "/" + ( *subit ); + removeFiles( subentries ); + if ( !containsProjectFiles( relpath ) ) + { + removedFiles << relpath; + removeFromProject( relpath ); + } + m_first_recursive = true; + } + else if ( isInProject( relpath ) ) + { + removedFiles << relpath; + removeFromProject( relpath ); + QStringList paths = QStringList::split( "/", relpath ); + QString lastsubentry = paths[paths.size()-1]; + paths.pop_back(); + while ( paths.size() > 0 ) + { + QString dir = paths.join( "/" ); + QStringList projectentries = projectFilesInDir( dir ); + if ( projectentries.size() == 0 ) + { + removedFiles << dir; + removeFromProject( dir ); + } + else + break; + lastsubentry = paths[paths.size()-1]; + paths.pop_back(); + } + } + } + + saveProject(); + emit removedFilesFromProject( removedFiles ); +} + +QString CustomProjectPart::buildDirectory() const +{ + QString dir = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/builddir" ); + if ( dir.isEmpty() ) + return projectDirectory(); + if ( QFileInfo( dir ).isRelative() ) + return QDir::cleanDirPath( projectDirectory() + "/" + dir ); + return dir; +} + + +QString CustomProjectPart::makeEnvironment() const +{ + // Get the make environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + DomUtil::PairList envvars = + DomUtil::readPairListEntry( *projectDom(), "/kdevcustomproject/" + buildtool + "/environments/" + currentMakeEnvironment(), "envvar", "name", "value" ); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for ( it = envvars.begin(); it != envvars.end(); ++it ) + { + environstr += ( *it ).first; + environstr += "="; + environstr += EnvVarTools::quote(( *it ).second ); + environstr += " "; + } + + KConfigGroup grp( kapp->config(), "MakeOutputView" ); + if( grp.readBoolEntry( "ForceCLocale", true ) ) + environstr += "LC_MESSAGES=" + EnvVarTools::quote( "C" )+" "+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" "; + + return environstr; +} + + +void CustomProjectPart::startMakeCommand( const QString &dir, const QString &target, bool withKdesu ) +{ + if ( partController()->saveAllFiles() == false ) + return; //user cancelled + + QDomDocument &dom = *projectDom(); + QString buildtool = DomUtil::readEntry( dom, "/kdevcustomproject/build/buildtool" ); + + QString cmdline; + if ( buildtool == "ant" ) + { + cmdline = "ant"; + } + else if ( buildtool == "other" ) + { + cmdline = DomUtil::readEntry( dom, "/kdevcustomproject/other/otherbin" ); + if ( cmdline.isEmpty() ) + cmdline = "echo"; + else if ( cmdline.find( "/" ) == -1 ) + cmdline = "./" + cmdline; + cmdline += " " + DomUtil::readEntry( dom, "/kdevcustomproject/other/otheroptions" ); + } + else + { + cmdline = DomUtil::readEntry( dom, "/kdevcustomproject/make/makebin" ); + if ( cmdline.isEmpty() ) + cmdline = MAKE_COMMAND; + if ( !DomUtil::readBoolEntry( dom, "/kdevcustomproject/make/abortonerror" ) ) + cmdline += " -k"; + int jobs = DomUtil::readIntEntry( dom, "/kdevcustomproject/make/numberofjobs" ); + if ( jobs != 0 ) + { + cmdline += " -j"; + cmdline += QString::number( jobs ); + } + if ( DomUtil::readBoolEntry( dom, "/kdevcustomproject/make/dontact" ) ) + cmdline += " -n"; + cmdline += " " + DomUtil::readEntry( dom, "/kdevcustomproject/make/makeoptions" ); + } + + cmdline += " "; + if ( !target.isEmpty() ) + cmdline += KProcess::quote( target ); + + QString dircmd = "cd "; + dircmd += KProcess::quote( dir ); + dircmd += " && "; + + int prio = DomUtil::readIntEntry( dom, "/kdevcustomproject/" + buildtool + "/prio" ); + QString nice; + if ( prio != 0 ) + { + nice = QString( "nice -n%1 " ).arg( prio ); + } + + cmdline.prepend( nice ); + cmdline.prepend( makeEnvironment() ); + + if ( withKdesu ) + cmdline = "kdesu -t -c '" + cmdline + "'"; + + m_buildCommand = dircmd + cmdline; + + + makeFrontend()->queueCommand( dir, dircmd + cmdline ); +} + + +void CustomProjectPart::slotBuild() +{ + m_lastCompilationFailed = false; + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + startMakeCommand( buildDirectory(), DomUtil::readEntry( *projectDom(), + "/kdevcustomproject/" + buildtool + "/defaulttarget" ) ); +} + +void CustomProjectPart::slotBuildActiveDir() +{ + m_lastCompilationFailed = false; + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + startMakeCommand( buildDirectory() + "/" + activeDirectory(), DomUtil::readEntry( *projectDom(), + "/kdevcustomproject/" + buildtool + "/defaulttarget" ) ); +} + + +void CustomProjectPart::slotCompileFile() +{ + KParts::ReadWritePart *part = dynamic_cast( partController()->activePart() ); + if ( !part || !part->url().isLocalFile() ) + return; + + QString fileName = part->url().path(); + QFileInfo fi( fileName ); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName( true ); + kdDebug( 9025 ) << "Compiling " << fileName + << "in dir " << sourceDir + << " with baseName " << baseName << endl; + + // What would be nice: In case of non-recursive build system, climb up from + // the source dir until a Makefile is found + + QString buildDir = sourceDir; + QString target = baseName + ".o"; + + QString buildtool = DomUtil::readEntry( *projectDom(), "/kdevcustomproject/build/buildtool" ); + + //if there is no Makefile in the directory of the source file + //try to build it from the main build dir + //this works e.g. for non-recursive cmake Makefiles, Alex + if ( buildtool == "make" && ( QFile::exists( sourceDir + "/Makefile" ) == false ) + && ( QFile::exists( sourceDir + "/makefile" ) == false ) ) + { + buildDir = buildDirectory(); + } + + startMakeCommand( buildDir, target ); +} + +void CustomProjectPart::slotInstallActiveDir() +{ + startMakeCommand( buildDirectory() + "/" + activeDirectory(), QString::fromLatin1( "install" ) ); +} + +void CustomProjectPart::slotInstall() +{ + startMakeCommand( buildDirectory(), QString::fromLatin1( "install" ) ); +} + + +void CustomProjectPart::slotInstallWithKdesu() +{ + // First issue "make" to build the entire project with the current user + // This way we make sure all files are up to date before we do the "make install" + slotBuild(); + + // After that issue "make install" with the root user + startMakeCommand( buildDirectory(), QString::fromLatin1( "install" ), true ); +} + +void CustomProjectPart::slotClean() +{ + startMakeCommand( buildDirectory(), QString::fromLatin1( "clean" ) ); +} + + +void CustomProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + + bool _auto = false; + if ( DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/autocompile", true ) && ( isDirty() || !QFileInfo( mainProgram() ).exists() ) ) + { + m_executeAfterBuild = true; + slotBuild(); + _auto = true; + } + + if ( DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/autoinstall", false ) && ( isDirty() || !QFileInfo( mainProgram() ).exists() ) ) + { + m_executeAfterBuild = true; + // Use kdesu?? + if ( DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/autokdesu", false ) ) + //slotInstallWithKdesu assumes that it hasn't just been build... + _auto ? slotInstallWithKdesu() : startMakeCommand( buildDirectory(), QString::fromLatin1( "install" ), true ); + else + slotInstall(); + _auto = true; + } + + if ( _auto ) + return; + + // Get the run environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = runEnvironmentVars(); + QString environstr; + DomUtil::PairList::ConstIterator it; + for ( it = envvars.begin(); it != envvars.end(); ++it ) + { + environstr += ( *it ).first; + environstr += "="; + environstr += EnvVarTools::quote(( *it ).second ); + environstr += " "; + } + + if ( mainProgram().isEmpty() ) + // Do not execute non executable targets + return; + + QString program = environstr; + program += mainProgram(); + program += " " + runArguments(); + + bool inTerminal = DomUtil::readBoolEntry( *projectDom(), "/kdevcustomproject/run/terminal" ); + + kdDebug( 9025 ) << "runDirectory: <" << runDirectory() << ">" << endl; + kdDebug( 9025 ) << "environstr : <" << environstr << ">" << endl; + kdDebug( 9025 ) << "mainProgram : <" << mainProgram() << ">" << endl; + kdDebug( 9025 ) << "runArguments: <" << runArguments() << ">" << endl; + + appFrontend()->startAppCommand( runDirectory(), program, inTerminal ); +} + +void CustomProjectPart::updateTargetMenu() +{ + m_targets.clear(); + m_targetsObjectFiles.clear(); + m_targetsOtherFiles.clear(); + m_targetMenu->clear(); + m_targetObjectFilesMenu->clear(); + m_targetOtherFilesMenu->clear(); + + QDomDocument &dom = *projectDom(); + bool ant = DomUtil::readEntry( dom, "/kdevcustomproject/build/buildtool" ) == "ant"; + + if ( ant ) + { + QFile f( buildDirectory() + "/build.xml" ); + if ( !f.open( IO_ReadOnly ) ) + { + kdDebug( 9025 ) << "No build file" << endl; + return; + } + QDomDocument dom; + if ( !dom.setContent( &f ) ) + { + kdDebug( 9025 ) << "Build script not valid xml" << endl; + f.close(); + return; + } + f.close(); + + QDomNode node = dom.documentElement().firstChild(); + while ( !node.isNull() ) + { + if ( node.toElement().tagName() == "target" ) + m_targets.append( node.toElement().attribute( "name" ) ); + node = node.nextSibling(); + } + } + else + { + kdDebug( 9025 ) << "Trying to load a makefile... " << endl; + + m_makefileVars.clear(); + m_parsedMakefiles.clear(); + m_makefilesToParse.clear(); + m_makefilesToParse.push( "Makefile" ); + m_makefilesToParse.push( "makefile" ); + putEnvVarsInVarMap(); + while ( !m_makefilesToParse.isEmpty() ) + parseMakefile( m_makefilesToParse.pop() ); + + //free the memory again + m_makefileVars.clear(); + m_parsedMakefiles.clear(); + + m_targets.sort(); + m_targetsObjectFiles.sort(); + m_targetsOtherFiles.sort(); + + } + + m_targetMenu->insertItem( i18n( "Object Files" ), m_targetObjectFilesMenu ); + m_targetMenu->insertItem( i18n( "Other Files" ), m_targetOtherFilesMenu ); + + int id = 0; + QStringList::ConstIterator it; + for ( it = m_targets.begin(); it != m_targets.end(); ++it ) + m_targetMenu->insertItem( *it, id++ ); + + id = 0; + for ( it = m_targetsObjectFiles.begin(); it != m_targetsObjectFiles.end(); ++it ) + m_targetObjectFilesMenu->insertItem( *it, id++ ); + + id = 0; + for ( it = m_targetsOtherFiles.begin(); it != m_targetsOtherFiles.end(); ++it ) + m_targetOtherFilesMenu->insertItem( *it, id++ ); +} + +void CustomProjectPart::putEnvVarsInVarMap() +{ + DomUtil::PairList envvars = + DomUtil::readPairListEntry( *projectDom(), "/kdevcustomproject/make/environments/" + currentMakeEnvironment(), "envvar", "name", "value" ); + + for ( DomUtil::PairList::ConstIterator it = envvars.begin(); it != envvars.end(); ++it ) + m_makefileVars[( *it ).first] = ( *it ).second; //is qouting here required as in makeEnvironment() ?? +} + +void CustomProjectPart::parseMakefile( const QString& filename ) +{ + if ( m_parsedMakefiles.contains( filename ) ) + return; + + m_parsedMakefiles.insert( filename, 1 ); + + QString absFilename = filename; + if ( !filename.startsWith( "/" ) ) + absFilename = buildDirectory() + "/" + filename; + + QFile f( absFilename ); + if ( !f.open( IO_ReadOnly ) ) + { + kdDebug( 9025 ) << "could not open " << absFilename << endl; + return; + } + QRegExp targetRe( "^ *([^\\t$.#]\\S+) *:.*$" ); + targetRe.setMinimal( true ); + + QRegExp variablesRe( "\\$\\(\\s*([^\\)\\s]+)\\s*\\)" ); + QRegExp assignmentRe( "^\\s*(\\S+)\\s*[:\\?]?=\\s*(\\S+)\\s*(#.*)?$" ); + + QRegExp includedMakefilesRe( "^include\\s+(\\S+)" ); + QString str = ""; + while ( !f.atEnd() ) + { + f.readLine( str, 200 ); + + // Replace any variables in the current line + int offset = -1; + while (( offset = variablesRe.search( str, offset + 1 ) ) != -1 ) + { + QString variableName = variablesRe.cap( 1 ).simplifyWhiteSpace(); + if ( m_makefileVars.contains( variableName ) ) + { + str.replace( variablesRe.cap( 0 ), m_makefileVars[variableName] ); + } + } + + // Read all continuation lines + // kdDebug(9025) << "Trying: " << str.simplifyWhiteSpace() << endl; + //while (str.right(1) == "\\" && !stream.atEnd()) { + // str.remove(str.length()-1, 1); + // str += stream.readLine(); + //} + // Find any variables + if ( assignmentRe.search( str ) != -1 ) + { + m_makefileVars[assignmentRe.cap( 1 ).simplifyWhiteSpace()] = assignmentRe.cap( 2 ).simplifyWhiteSpace(); + } + else if ( includedMakefilesRe.search( str ) != -1 ) + { + QString includedMakefile = includedMakefilesRe.cap( 1 ).simplifyWhiteSpace(); + m_makefilesToParse.push( includedMakefile ); + } + else if ( targetRe.search( str ) != -1 ) + { + QString tmpTarget = targetRe.cap( 1 ).simplifyWhiteSpace(); + if ( tmpTarget.endsWith( ".o" ) ) + { + if ( m_targetsObjectFiles.find( tmpTarget ) == m_targetsObjectFiles.end() ) + m_targetsObjectFiles += tmpTarget; + } + else if ( tmpTarget.contains( '.' ) ) + { + if ( m_targetsOtherFiles.find( tmpTarget ) == m_targetsOtherFiles.end() ) + m_targetsOtherFiles += tmpTarget; + } + else + { + if ( m_targets.find( tmpTarget ) == m_targets.end() ) + m_targets += tmpTarget; + } + } + } + f.close(); +} + +void CustomProjectPart::targetMenuActivated( int id ) +{ + QString target = m_targets[id]; + startMakeCommand( buildDirectory(), target ); +} + +void CustomProjectPart::targetObjectFilesMenuActivated( int id ) +{ + QString target = m_targetsObjectFiles[id]; + startMakeCommand( buildDirectory(), target ); +} + +void CustomProjectPart::targetOtherFilesMenuActivated( int id ) +{ + QString target = m_targetsOtherFiles[id]; + startMakeCommand( buildDirectory(), target ); +} + +void CustomProjectPart::updateMakeEnvironmentsMenu() +{ + QDomDocument &dom = *projectDom(); + bool makeUsed = ( DomUtil::readEntry( dom, "/kdevcustomproject/build/buildtool" ) == "make" ); + if ( makeUsed ) + { + QStringList l = allMakeEnvironments(); + m_makeEnvironmentsSelector->setItems( l ); + m_makeEnvironmentsSelector->setCurrentItem( l.findIndex( currentMakeEnvironment() ) ); + } + else + { + m_makeEnvironmentsSelector->clear(); + } + /* + m_makeEnvironmentsMenu->clear(); + QDomDocument &dom = *projectDom(); + + QStringList environments = allMakeEnvironments(); + QStringList::ConstIterator it; + int id = 0; + for (it = environments.begin(); it != environments.end(); ++it) + m_makeEnvironmentsMenu->insertItem(*it, id++); + } + */ +} + +void CustomProjectPart::makeEnvironmentsMenuActivated( int id ) +{ + QDomDocument &dom = *projectDom(); + QString environment = allMakeEnvironments()[id]; + DomUtil::writeEntry( dom, "/kdevcustomproject/make/selectedenvironment", environment ); +} + +void CustomProjectPart::slotCommandFinished( const QString& command ) +{ + kdDebug( 9025 ) << "CustomProjectPart::slotProcessFinished()" << endl; + + if ( m_buildCommand != command ) + return; + + m_buildCommand = QString::null; + + m_timestamp.clear(); + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while ( it != fileList.end() ) + { + QString fileName = *it; + ++it; + + m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified(); + } + + emit projectCompiled(); + + if ( m_executeAfterBuild ) + { + slotExecute(); + m_executeAfterBuild = false; + } +} + +void CustomProjectPart::slotCommandFailed( const QString& /*command*/ ) +{ + m_lastCompilationFailed = true; + m_executeAfterBuild = false; +} + +bool CustomProjectPart::isDirty() +{ + if ( m_lastCompilationFailed ) return true; + + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while ( it != fileList.end() ) + { + QString fileName = *it; + ++it; + + QMap::Iterator it = m_timestamp.find( fileName ); + QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified(); + if ( it == m_timestamp.end() || *it != t ) + { + return true; + } + } + + return false; +} + + +QStringList CustomProjectPart::allMakeEnvironments() const +{ + QDomDocument &dom = *projectDom(); + + QStringList allConfigs; + + QDomNode node = + DomUtil::elementByPath( dom , "/kdevcustomproject/make/environments" ); + // extract the names of the different make environments + QDomElement childEl = node.firstChild().toElement(); + while ( !childEl.isNull() ) + { + QString config = childEl.tagName(); + allConfigs.append( config ); + childEl = childEl.nextSibling().toElement(); + } + if ( allConfigs.isEmpty() ) + allConfigs.append( "default" ); + + return allConfigs; +} + + +QString CustomProjectPart::currentMakeEnvironment() const +{ + QStringList allEnvs = allMakeEnvironments(); + QDomDocument &dom = *projectDom(); + QString environment = DomUtil::readEntry( dom, "/kdevcustomproject/make/selectedenvironment" ); + if ( environment.isEmpty() || !allEnvs.contains( environment ) ) + environment = allEnvs[0]; + return environment; +} + +/*! + \fn CustomProjectPart::distFiles() const + */ +QStringList CustomProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir( projectDir ); + QStringList files = dir.entryList( "*README*" ); + return sourceList + files; +} + +bool CustomProjectPart::containsNonProjectFiles( const QString& dir ) +{ + if ( isInBlacklist( dir ) ) + return false; + QStringList fileentries = QDir( dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( dir ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + subentries.remove( "." ); + subentries.remove( ".." ); + for ( QStringList::const_iterator it = subentries.begin(); it != subentries.end(); ++it ) + { + if ( isInBlacklist( *it ) ) + continue; + if ( QFileInfo( dir + "/" + *it ).isDir() && !isInBlacklist( *it ) ) + { + if ( containsNonProjectFiles( dir + "/" + *it ) ) + { + return true; + } + } + else if ( !project()->isProjectFile( URLUtil::canonicalPath( dir + "/" + *it ) ) + && !isInBlacklist( *it ) ) + { + return true; + } + } + return false; +} + +bool CustomProjectPart::containsProjectFiles( const QString& dir ) +{ + if ( isInBlacklist( dir ) ) + return false; + + QStringList fileentries = QDir( dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( dir ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + subentries.remove( "." ); + subentries.remove( ".." ); + for ( QStringList::const_iterator it = subentries.begin(); it != subentries.end(); ++it ) + { + if ( isInBlacklist( *it ) ) + continue; + + if ( QFileInfo( dir + "/" + *it ).isDir() && !isInBlacklist( *it ) ) + { + if ( containsProjectFiles( dir + "/" + *it ) ) + { + return true; + } + } + else if ( project()->isProjectFile( URLUtil::canonicalPath( dir + "/" + *it ) ) && !isInBlacklist( *it ) ) + { + return true; + } + } + return false; +} + +QStringList CustomProjectPart::projectFilesInDir( const QString& dir ) +{ + QStringList result; + QStringList fileentries = QDir( projectDirectory() + "/" + dir ).entryList( filetypes().join( ";" ) ); + QStringList dirs = QDir( projectDirectory() + "/" + dir ).entryList( QDir::Dirs ); + QStringList subentries = fileentries + dirs; + subentries.remove( "." ); + subentries.remove( ".." ); + for ( QStringList::const_iterator it = subentries.begin(); it != subentries.end(); ++it ) + { + if ( isInProject( dir + "/" + *it ) ) + { + result << ( *it ); + } + } + return result; +} + +QStringList CustomProjectPart::filetypes( ) const +{ + return DomUtil::readListEntry( *projectDom(), "/kdevcustomproject/filetypes", "filetype" ); +} + +bool CustomProjectPart::isProjectFileType( const QString& filename ) const +{ + QStringList types = filetypes(); + QRegExp re( "", true, true ); + for ( QStringList::const_iterator it = types.begin(); it != types.end(); ++it ) + { + re.setPattern( *it ); + int pos = re.search( filename ); + uint len = re.matchedLength(); + if ((( *it ).find( "*" ) != -1 || ( *it ).find( "?" ) != -1 ) && pos + len == filename.length() ) + return true; + else if ( filename.find( "/" ) != -1 && filename.find( *it ) != -1 ) + return true; + else if ( filename.find( "/" ) == -1 && filename == *it ) + return true; + } + return false; +} + +void CustomProjectPart::switchBlacklistEntry( const QString& path ) +{ + QStringList blacklist = this->blacklist(); + kdDebug( 9025 ) << "Switching path " << path << endl; + if ( !isInBlacklist( path ) ) + { + blacklist << path; + m_recursive = true; + removeFile( path ); + m_recursive = false; + } + else + { + blacklist.remove( path ); + } + updateBlacklist( blacklist ); +} + +QString CustomProjectPart::relativeToProject( const QString& abspath ) const +{ + QString path = abspath.mid( projectDirectory().length() + 1 ); + kdDebug( 9025 ) << "abspath: " << "|project dir: " << projectDirectory() << "|path: " << path << endl; + if ( path.endsWith( "/" ) ) + path = path.mid( 0, path.length() - 1 ); + if ( path.startsWith( "/" ) ) + path = path.mid( 1, path.length() ); + return path; +} + +bool CustomProjectPart::isInBlacklist( const QString& path ) const +{ + QString relpath = path; + QStringList blacklist = this->blacklist(); + if ( !QFileInfo( relpath ).isRelative() ) + relpath = relativeToProject( path ); + if ( blacklist.find( relpath ) != blacklist.end() ) + return true; + QStringList paths = QStringList::split( "/", relpath ); + QString parentpath; + for ( QStringList::const_iterator it = paths.begin(); it != paths.end(); ++it ) + { + parentpath += *it; + if ( blacklist.find( parentpath ) != blacklist.end() ) + return true; + parentpath = parentpath + "/"; + } + return false; +} + +void CustomProjectPart::updateBlacklist( const QStringList& l ) +{ + DomUtil::writeListEntry( *projectDom(), "kdevcustomproject/blacklist", "path", l ); +} + +QStringList CustomProjectPart::blacklist() const +{ + return DomUtil::readListEntry( *projectDom(), "kdevcustomproject/blacklist", "path" ); +} + +void CustomProjectPart::addNewFilesToProject( const QStringList& filelist ) +{ + QStringList addfiles; + for ( QStringList::const_iterator it = filelist.begin(); it != filelist.end(); ++it ) + { + if (( ! isInProject( *it ) ) && ( isProjectFileType( *it ) || QFileInfo( projectDirectory() + "/" + *it ).isDir() ) && !isInBlacklist( *it ) ) + { + addfiles << *it; + } + } + + if ( addfiles.isEmpty() ) + return; + + SelectNewFilesDialog *dlg = new SelectNewFilesDialog( addfiles, mainWindow()->main() ); + if ( dlg->exec() == KDialog::Accepted ) + { + m_first_recursive = false; + m_recursive = false; + QStringList blacklist = this->blacklist(); + QStringList excludelist = dlg->excludedPaths(); + QStringList removeFromExcludes; + for ( QStringList::const_iterator it = excludelist.begin(); it != excludelist.end(); ++it ) + { + if ( QFileInfo( projectDirectory() + "/" + *it ).isDir() ) + { + for ( ProjectFilesSet::ConstIterator it2 = m_sourceFilesSet.constBegin(); it2 != m_sourceFilesSet.constEnd(); ++it2 ) + { + if ( it2.key().find( *it ) != -1 ) + { + removeFromExcludes << *it; + } + } + } + } + for ( QStringList::const_iterator it = removeFromExcludes.begin(); it != removeFromExcludes.end(); ++it ) + { + excludelist.remove( *it ); + } + blacklist += excludelist; + updateBlacklist( blacklist ); + addFiles( dlg->includedPaths() ); + } +} + +void CustomProjectPart::setFiletypes( const QStringList& l ) +{ + DomUtil::writeListEntry( *projectDom(), "kdevcustomproject/filetypes", "filetype", l ); +} + + +/** + * @brief Is a given file (or a directory) part of this project? + * + * @param fileName + */ +bool CustomProjectPart::isInProject( const QString& fileName ) const +{ + return m_sourceFilesSet.contains( fileName ); +} + + +/** + * @brief Add a file (or a directory) to this project. + * + * @param fileName + * + * @see removeFromProject() + */ +void CustomProjectPart::addToProject( const QString& fileName ) +{ + m_sourceFilesSet.insert( fileName, false ); +} + + +/** + * @brief Remove a file (or a directory) from this project. + * + * @param fileName + */ +void CustomProjectPart::removeFromProject( const QString& fileName ) +{ + m_sourceFilesSet.remove( fileName ); +} + + +#include "customprojectpart.moc" + diff --git a/buildtools/custommakefiles/customprojectpart.h b/buildtools/custommakefiles/customprojectpart.h new file mode 100644 index 00000000..f3fb9ec4 --- /dev/null +++ b/buildtools/custommakefiles/customprojectpart.h @@ -0,0 +1,158 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _CUSTOMPROJECTPART_H_ +#define _CUSTOMPROJECTPART_H_ + +#include +#include +#include +#include +#include + +#include + +class QListViewItem; +class QPopupMenu; +class QStringList; +class KDialogBase; +class CustomProjectWidget; +class Context; +class KSelectAction; + +class CustomProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + CustomProjectPart( QObject *parent, const char *name, const QStringList & ); + ~CustomProjectPart(); + + QStringList allMakeEnvironments() const; + QString currentMakeEnvironment() const; + + bool isDirty(); + QStringList distFiles() const; + + virtual void openProject( const QString &dirName, const QString &projectName ); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile( const QString &fileName ); + virtual void addFiles( const QStringList& fileList ); + virtual void removeFile( const QString &fileName ); + virtual void removeFiles( const QStringList &fileList ); + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + QString relativeToProject( const QString& ) const; + + +private slots: + void populateProject(); + void projectConfigWidget( KDialogBase *dlg ); + void contextMenu( QPopupMenu *popup, const Context *context ); + void slotAddToProject(); + void slotRemoveFromProject(); + void slotAddToProjectRecursive(); + void slotRemoveFromProjectRecursive(); + void addNewFilesToProject( const QStringList& ); + void slotChangeBlacklist(); + void slotChooseActiveDirectory(); + void slotBuild(); + void slotBuildActiveDir(); + void slotCompileFile(); + void slotInstall(); + void slotInstallActiveDir(); + void slotInstallWithKdesu(); + void slotClean(); + void slotExecute(); + void updateTargetMenu(); + void targetMenuActivated( int id ); + void targetObjectFilesMenuActivated( int id ); + void targetOtherFilesMenuActivated( int id ); + void updateMakeEnvironmentsMenu(); + void makeEnvironmentsMenuActivated( int id ); + void slotCommandFinished( const QString& command ); + void slotCommandFailed( const QString& command ); + +private: + bool containsNonProjectFiles( const QString& url ); + QStringList projectFilesInDir( const QString& dir ); + bool containsProjectFiles( const QString& url ); + bool isProjectFileType( const QString& absFile ) const; + bool isInBlacklist( const QString& ) const; + void cleanFileList(); + void setFiletypes( const QStringList& ); + void findNewFiles( const QString& dir, QStringList& list) const; + + QStringList filetypes() const; + QStringList blacklist() const; + void updateBlacklist( const QStringList& ); + void saveProject(); + void startMakeCommand( const QString &dir, const QString &target, bool withKdesu = false ); + void parseMakefile( const QString& file ); + QString makeEnvironment() const; + void putEnvVarsInVarMap(); + void switchBlacklistEntry(const QString& ); + + bool isInProject( const QString& fileName ) const; + void addToProject( const QString& fileName ); + void removeFromProject( const QString& fileName ); + + /** + * @brief Set of all the project's files. + * + * @bug + * Due to deficiency in QT3, + * we have to use a map with next-to-useless element value, + * keyed by the file name, + * as a set-container replacement. + */ + typedef QMap ProjectFilesSet; + + QString m_projectDirectory; + QString m_projectName; + QString m_filelistDir; + /** All the sources (files and directories) of this project. */ + ProjectFilesSet m_sourceFilesSet; + QPopupMenu *m_targetMenu; + QPopupMenu *m_targetObjectFilesMenu; + QPopupMenu *m_targetOtherFilesMenu; + KSelectAction *m_makeEnvironmentsSelector; + QStringList m_targets; + QStringList m_targetsObjectFiles; + QStringList m_targetsOtherFiles; + QStringList m_contextAddFiles; + QStringList m_contextRemoveFiles; + QString m_contextDirName; + + QMap m_timestamp; + bool m_executeAfterBuild; + QString m_buildCommand; + bool m_lastCompilationFailed; + QMap m_parsedMakefiles; + QValueStack m_makefilesToParse; + QMap m_makefileVars; + bool m_recursive; + bool m_first_recursive; +}; + +#endif +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/kdevcustomproject.desktop b/buildtools/custommakefiles/kdevcustomproject.desktop new file mode 100644 index 00000000..276f4c1a --- /dev/null +++ b/buildtools/custommakefiles/kdevcustomproject.desktop @@ -0,0 +1,91 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Custom Project +Comment[br]=Raktres diouzhoc'h +Comment[ca]=Projecte a mida +Comment[cs]=Vlastní projekt +Comment[da]=Brugerdefineret projekt +Comment[de]=Benutzerdefiniertes Projekt für KDevelop +Comment[el]=Προσαρμοσμένo έργο +Comment[es]=Proyecto personalizado +Comment[et]=Kohandatav projekt +Comment[eu]=Proiektu pertsonalizatua +Comment[fa]=پروژۀ سفارشی +Comment[fr]=Projet personnalisé +Comment[ga]=Tionscadal Saincheaptha +Comment[gl]=Proxecto persoalizado +Comment[hi]=कस्टम परियोजना +Comment[hu]=Egyedi projekt +Comment[is]=Sérsniðið verkefni +Comment[it]=Progetto personalizzato +Comment[ja]=カスタムプロジェクト +Comment[ms]=Projek Tersendiri +Comment[nds]=Egen Projekt +Comment[ne]=अनुकूल परियोजना +Comment[nl]=Aangepast project +Comment[pl]=Własny projekt +Comment[pt]=Projecto Personalizado +Comment[pt_BR]=Projeto Personalizado +Comment[ru]=Особый проект +Comment[sk]=Vlastný projekt +Comment[sl]=Poljuben projekt +Comment[sr]=Произвољан пројекат +Comment[sr@Latn]=Proizvoljan projekat +Comment[sv]=Eget projekt +Comment[ta]=தனிப்பயன் பிராஜக்ட் +Comment[tg]=Лоиҳаи оддӣ +Comment[tr]=Özel Proje +Comment[zh_CN]=自定义工程 +Comment[zh_TW]=自訂專案 +Name=KDevCustomProject +Name[da]=KDevelop brugerdefineret projekt +Name[de]=Benutzerdefiniertes Projekt (KDevelop) +Name[hi]=के-डेव-कस्टम-परियोजना +Name[nds]=Egen Projekt (KDevelop) +Name[ne]=केडीई विकास अनुकूल परियोजना +Name[pl]=KDevWłasnyProjekt +Name[sk]=KDevVlastnýProjekt +Name[sv]=KDevelop eget projekt +Name[ta]=கெடெவ் தனிப்பயன் பிராஜக்ட் +Name[tg]=Лоиҳаи оддӣKDev +Name[zh_TW]=KDevelop 自訂專案 +GenericName=Custom Project +GenericName[br]=Raktres diouzhoc'h +GenericName[ca]=Projecte a mida +GenericName[da]=Brugerdefineret projekt +GenericName[de]=Benutzerdefiniertes Projekt +GenericName[el]=Προσαρμοσμένο έργο +GenericName[es]=Proyecto personalizado +GenericName[et]=Kohandatav projekt +GenericName[eu]=Proiektu pertsonalizatua +GenericName[fa]=پروژۀ سفارشی +GenericName[fr]=Projet personnalisé +GenericName[ga]=Tionscadal Saincheaptha +GenericName[gl]=Proxecto persoalizado +GenericName[hi]=कस्टम परियोजना +GenericName[hu]=Egyedi projekt +GenericName[it]=Progetto personalizzato +GenericName[ja]=カスタムプロジェクト +GenericName[ms]=Projek Tersendiri +GenericName[nds]=Egen Projekt +GenericName[ne]=अनुकूल परियोजना +GenericName[nl]=Aangepast project +GenericName[pl]=Projekt: własny +GenericName[pt]=Projecto Personalizado +GenericName[pt_BR]=Projeto Personalizado +GenericName[ru]=Особый проект +GenericName[sk]=Vlastný projekt +GenericName[sl]=Poljuben projekt +GenericName[sr]=Произвољан пројекат +GenericName[sr@Latn]=Proizvoljan projekat +GenericName[sv]=Eget projekt +GenericName[ta]=தனிப்பயன் பிராஜக்ட் +GenericName[tg]=Лоиҳаи оддӣ +GenericName[tr]=Özel Proje +GenericName[zh_CN]=自定义工程 +GenericName[zh_TW]=自訂專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevcustomproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/custommakefiles/kdevcustomproject.rc b/buildtools/custommakefiles/kdevcustomproject.rc new file mode 100644 index 00000000..c744b4be --- /dev/null +++ b/buildtools/custommakefiles/kdevcustomproject.rc @@ -0,0 +1,30 @@ + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/buildtools/custommakefiles/selectnewfilesdialog.cpp b/buildtools/custommakefiles/selectnewfilesdialog.cpp new file mode 100644 index 00000000..cfcb84e6 --- /dev/null +++ b/buildtools/custommakefiles/selectnewfilesdialog.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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 "selectnewfilesdialog.h" + +#include +#include +#include +#include +#include +#include +#include "selectnewfilesdialogbase.h" + +SelectNewFilesDialog::SelectNewFilesDialog( QStringList paths, QWidget* parent, const char* name ) + : KDialogBase( parent, name, true, i18n("Add newly created files to project"), KDialogBase::Ok|KDialogBase::Cancel ) +{ + m_widget = new SelectNewFilesDialogBase(this); + m_widget->fileView->header()->hide(); + m_widget->fileView->addColumn(i18n("Path") ); + for( QStringList::const_iterator it = paths.begin(); it != paths.end(); ++it) + { + addPath(0, *it); + } + setMainWidget( m_widget ); + resize( 300,400 ); +} + +SelectNewFilesDialog::~SelectNewFilesDialog() +{} + +void SelectNewFilesDialog::slotCancel() +{ + excludePaths.clear(); + includePaths.clear(); + KDialogBase::slotCancel(); +} + +void SelectNewFilesDialog::checkItem( QCheckListItem* item, const QString& curpath ) +{ + if( !item ) + return; + + QString path = curpath + item->text(); + if( item->state() != QCheckListItem::Off ) + includePaths << path; + else + excludePaths << path; + if( item->firstChild() ) + { + checkItem( static_cast(item->firstChild()), path+"/" ); + } + if( item->nextSibling() ) + { + checkItem( static_cast(item->nextSibling()), curpath ); + } +} + +void SelectNewFilesDialog::slotOk() +{ + QCheckListItem* item = static_cast (m_widget->fileView->firstChild()); + checkItem( item, "" ); + kdDebug(9025) << "Inc List:" << includePaths << endl; + kdDebug(9025) << "Exc List:" << excludePaths << endl; + KDialogBase::slotOk(); +} + +void SelectNewFilesDialog::addPath( QCheckListItem* item, const QString& path ) +{ + if( path.isEmpty() ) + return; + + QStringList parts = QStringList::split("/", path ); + QString name = parts.first(); + parts.pop_front(); + QCheckListItem* i = createItem( item, name, parts.size() ); + i->setState( QCheckListItem::On ); + i->setTristate( true ); + addPath(i, parts.join("/") ); +} + +QCheckListItem* SelectNewFilesDialog::createItem( QCheckListItem* parent, const QString& name, int count ) +{ + QCheckListItem::Type t = QCheckListItem::CheckBox; + if( count > 0 ) + t = QCheckListItem::CheckBoxController; + + if( parent == 0 ) + { + QListViewItem* item = m_widget->fileView->firstChild(); + while( item ) + { + if( item->text( 0 ) == name ) + return static_cast(item); + item = item->nextSibling(); + } + return new QCheckListItem( m_widget->fileView, name, t ); + }else + { + QListViewItem* item = parent->firstChild(); + while( item ) + { + if( item->text( 0 ) == name ) + return static_cast(item); + item = item->nextSibling(); + } + return new QCheckListItem( parent, name, t ); + } +} + +QStringList SelectNewFilesDialog::excludedPaths() const +{ + return excludePaths; +} + +QStringList SelectNewFilesDialog::includedPaths() const +{ + return includePaths; +} + +#include "selectnewfilesdialog.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/selectnewfilesdialog.h b/buildtools/custommakefiles/selectnewfilesdialog.h new file mode 100644 index 00000000..b970dc7d --- /dev/null +++ b/buildtools/custommakefiles/selectnewfilesdialog.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2007 by Andreas Pakulat * + * apaku@gmx.de * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef SELECTNEWFILESDIALOG_H +#define SELECTNEWFILESDIALOG_H + +#include "kdialogbase.h" + +class QCheckListItem; +class QStringList; +class SelectNewFilesDialogBase; + +class SelectNewFilesDialog : public KDialogBase +{ +Q_OBJECT + +public: + SelectNewFilesDialog( QStringList paths, QWidget* parent = 0, const char* name = 0 ); + ~SelectNewFilesDialog(); + + QStringList excludedPaths() const; + QStringList includedPaths() const; + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void slotCancel(); + virtual void slotOk(); +private: + void addPath( QCheckListItem* , const QString& ); + void checkItem( QCheckListItem* item, const QString& curpath ); + QCheckListItem* createItem( QCheckListItem*, const QString&, int ); + SelectNewFilesDialogBase* m_widget; + QStringList excludePaths; + QStringList includePaths; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/custommakefiles/selectnewfilesdialogbase.ui b/buildtools/custommakefiles/selectnewfilesdialogbase.ui new file mode 100644 index 00000000..fbd5b5ec --- /dev/null +++ b/buildtools/custommakefiles/selectnewfilesdialogbase.ui @@ -0,0 +1,50 @@ + +SelectNewFilesDialogBase + + + SelectNewFilesDialogBase + + + + 0 + 0 + 532 + 324 + + + + + unnamed + + + + textLabel1 + + + Files to add to the Project: + + + + + fileView + + + true + + + false + + + Select the files to add to the project + + + Select the files and directories that should be added to the list of project files. All other files and directories will be put into the blacklist. + + + + + + + klistview.h + + diff --git a/buildtools/lib/Makefile.am b/buildtools/lib/Makefile.am new file mode 100644 index 00000000..c772e395 --- /dev/null +++ b/buildtools/lib/Makefile.am @@ -0,0 +1,8 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +SUBDIRS = parsers widgets base + +DOXYGEN_EMPTY = YES +include ../../Doxyfile.am diff --git a/buildtools/lib/base/Mainpage.dox b/buildtools/lib/base/Mainpage.dox new file mode 100644 index 00000000..dbf199a5 --- /dev/null +++ b/buildtools/lib/base/Mainpage.dox @@ -0,0 +1,19 @@ +/** +@mainpage The KDevelop Buildtool Base Library + +This library contains base classes for KDevelop builtool support plugins. + +Link with: -lkdevbuildbase + +Include path: -I\$(kde_includes)/kdevelop/buildtools/base + +\section btbaseoverview Overview +This library is created to provide KDevBuildTool compat class which can be used +as drop-in replacement of KDevProject class for buildtool support plugins +written for old KDevelop architecture (before version 3.2). + +Nevertheless, it can be useful for new buildtool plugins as well because it provides +useful methods to get application and make frontend extensions. + +*/ + diff --git a/buildtools/lib/base/Makefile.am b/buildtools/lib/base/Makefile.am new file mode 100644 index 00000000..6c9f6df6 --- /dev/null +++ b/buildtools/lib/base/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + $(all_includes) +METASOURCES = AUTO +lib_LTLIBRARIES = libkdevbuildbase.la +libkdevbuildbase_la_LDFLAGS = $(all_libraries) +libkdevbuildbase_la_LIBADD = $(top_builddir)/lib/interfaces/libkdevinterfaces.la $(LIB_QT) $(LIB_KDEUI) +libkdevbuildbase_la_SOURCES = kdevbuildtool.cpp +kdevelopbuildtoolsincludedir = $(includedir)/kdevelop/buildtools/base +kdevelopbuildtoolsinclude_HEADERS = kdevbuildtool.h + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils kdevutil kdevinterfaces kdevextensions +DOXYGEN_PROJECTNAME = KDevelop Buildtool Base Library +DOXYGEN_DOCDIRPREFIX = kdevbt +include ../../../Doxyfile.am diff --git a/buildtools/lib/base/kdevbuildtool.cpp b/buildtools/lib/base/kdevbuildtool.cpp new file mode 100644 index 00000000..a8b7de3a --- /dev/null +++ b/buildtools/lib/base/kdevbuildtool.cpp @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "kdevbuildtool.h" + +#include +#include + +KDevBuildTool::KDevBuildTool(const KDevPluginInfo* info, QObject* parent, const char* name) + :KDevProject(info, parent, name) +{ +} + +KDevMakeFrontend * KDevBuildTool::makeFrontend() +{ + return extension("KDevelop/MakeFrontend"); +} + +KDevAppFrontend * KDevBuildTool::appFrontend() +{ + return extension("KDevelop/AppFrontend"); +} + diff --git a/buildtools/lib/base/kdevbuildtool.h b/buildtools/lib/base/kdevbuildtool.h new file mode 100644 index 00000000..95ed8d37 --- /dev/null +++ b/buildtools/lib/base/kdevbuildtool.h @@ -0,0 +1,41 @@ +/* This file is part of the KDE project + Copyright (C) 1999-2001 Bernd Gehrmann + Copyright (C) 2004 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef KDEVBUILDTOOL_H +#define KDEVBUILDTOOL_H + +#include + +class KDevMakeFrontend; +class KDevAppFrontend; + +/**Base class for KDevelop build tool support plugins.*/ +class KDevBuildTool: public KDevProject +{ +public: + KDevBuildTool(const KDevPluginInfo* info, QObject* parent, const char* name); + + /**@return The make frontend.*/ + KDevMakeFrontend *makeFrontend(); + /**@return The application frontend.*/ + KDevAppFrontend *appFrontend(); + +}; + +#endif diff --git a/buildtools/lib/parsers/Makefile.am b/buildtools/lib/parsers/Makefile.am new file mode 100644 index 00000000..a1c9f256 --- /dev/null +++ b/buildtools/lib/parsers/Makefile.am @@ -0,0 +1,8 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +SUBDIRS = qmake autotools + +DOXYGEN_EMPTY = YES +include ../../../Doxyfile.am diff --git a/buildtools/lib/parsers/autotools/Mainpage.dox b/buildtools/lib/parsers/autotools/Mainpage.dox new file mode 100644 index 00000000..99d200d9 --- /dev/null +++ b/buildtools/lib/parsers/autotools/Mainpage.dox @@ -0,0 +1,11 @@ +/** +@mainpage The KDevelop Makefile.am Parser + +This library contains a parser that handles Makefile.am. + +Link with: -lkdevautotoolsparser + +Include path: -I\$(kde_includes)/kdevelop/buildtools/parsers/autotools + +*/ + diff --git a/buildtools/lib/parsers/autotools/Makefile.am b/buildtools/lib/parsers/autotools/Makefile.am new file mode 100644 index 00000000..c0776c2f --- /dev/null +++ b/buildtools/lib/parsers/autotools/Makefile.am @@ -0,0 +1,24 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. +SUBDIRS = . tests +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + $(all_includes) +METASOURCES = AUTO +noinst_LTLIBRARIES = libkdevautotoolsparser.la +libkdevautotoolsparser_la_LDFLAGS = $(all_libraries) $(LIB_KIO) +libkdevautotoolsparser_la_SOURCES = autotoolsast.cpp autotoolsdriver.cpp autotools_yacc.cpp + +parser: + cd $(srcdir) ; \ + bison -d autotools.yy -o autotools_yacc.cpp ; \ + mv -f autotools_yacc.hpp autotools_yacc.h ; \ + flex -oautotools_lex.cpp autotools.ll + +EXTRA_DIST = autotools.yy autotools.ll + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils +DOXYGEN_PROJECTNAME = KDevelop AutoTools Parser +DOXYGEN_DOCDIRPREFIX = kdevparser +include ../../../../Doxyfile.am diff --git a/buildtools/lib/parsers/autotools/autotools.ll b/buildtools/lib/parsers/autotools/autotools.ll new file mode 100644 index 00000000..ae646edb --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools.ll @@ -0,0 +1,136 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +/** +@file autotools.ll +Autotools Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ +%} +%option noyywrap + +%x list +%x funcargs +%x conditional + +delim [ \t] +ws {delim}+ +letter [A-Za-z] +digit [0-9] +id_simple ({digit}|{letter}|\!|-|_|\*|\$|@)({letter}|{digit}|\||\!|-|_|\*|\$|\(|\.|\+|\-|\)|\/)* +id_list [^\n]*\\{ws}* +id_args [^\n]*\) +number {digit}+ +comment #.* +comment_cont {ws}*#.*\n +id_list_single [^\n]* +cont \\{ws}*\n +keywords (if|else|endif|include) +rule [\t]+[^\n]* + +%% + +{ws} {} +{cont} { BEGIN(list); return CONT; } +{keywords} { + yylval.value = yytext; + if ( yylval.value == "if" ) + return IF_KEYWORD; + + if ( yylval.value == "else" ) + return ELSE_KEYWORD; + + if ( yylval.value == "endif" ) + return ENDIF_KEYWORD; + + return KEYWORD; +} + + +{id_simple} { yylval.value = yytext; return (ID_SIMPLE); } + +{rule} { + yylval.value = yytext; + return RULE; +} + +{id_list} { + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.findRev("\\")); + unput('\\'); + BEGIN(INITIAL); + return (ID_LIST); + } + +{comment_cont} { + yylval.value = yytext; + BEGIN(list); + return (LIST_COMMENT); + } + +{id_list_single} { + yylval.value = yytext; + BEGIN(INITIAL); + return (ID_LIST_SINGLE); + } + +{id_args} { + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (ID_ARGS); + } + +"=" { BEGIN(list); yylval.value = yytext; return EQ; } +"+=" { BEGIN(list); yylval.value = yytext; return PLUSEQ; } +"{" { return LCURLY; } +"}" { return RCURLY; } +":" { BEGIN(list); yylval.value = yytext; return COLON; } +"\n" { BEGIN(INITIAL); return NEWLINE; } +{comment} { yylval.value = yytext; return (COMMENT); } + +%% + diff --git a/buildtools/lib/parsers/autotools/autotools.yy b/buildtools/lib/parsers/autotools/autotools.yy new file mode 100644 index 00000000..e124ee85 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools.yy @@ -0,0 +1,323 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +Autotools Parser + +Simple LALR parser which builds the syntax tree (see @ref Autotools::AST). + +@todo Recognize comments after statements like: +noinst_HEADERS = foo.h #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include +#include "autotoolsast.h" + +#define YYSTYPE_IS_DECLARED + +using namespace AutoTools; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in Makefile.am file: + @code + foo_SOURCES = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: +
+    foo1.cpp
+    foo2.cpp
+    foo3.cpp foo4.cpp
+    
+ */ + QStringList values; +}; + +typedef Result YYSTYPE; + +void yyerror(const char *str) { + printf("bison error: %s\n", str); +} + +int yylex(); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +QValueStack projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ +%} + +%token ID_SIMPLE +%token ID_LIST +%token LBRACE +%token EQ +%token PLUSEQ +%token MINUSQE +%token STAREQ +%token TILDEEQ +%token LBRACE +%token RBRACE +%token COLON +%token NUMSIGN +%token NEWLINE +%token NUMBER +%token COMMENT +%token CONT +%token DOT +%token RCURLY +%token LCURLY +%token ID_ARGS +%token LIST_COMMENT +%token ID_LIST_SINGLE +%token IF_KEYWORD +%token ELSE_KEYWORD +%token ENDIF_KEYWORD +%token KEYWORD +%token RULE + +%% + +project : +{ + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); +} +statements +; + +statements : statements statement +{ + projects.top()->addChildAST($2); + + if ( $2->nodeType() == AST::ProjectAST && + static_cast( $2 )->scopedID == "if" ) + { + $2->setDepth(depth); + depth++; + } + else if ( $2->nodeType() == AST::ProjectAST && + static_cast( $2 )->scopedID == "else" ) + { + --depth; + $2->setDepth(depth); + ++depth; + } + else if ( $2->nodeType() == AST::ProjectAST && + static_cast( $2 )->scopedID == "endif" ) + { + --depth; + $2->setDepth(depth); + } + else + $2->setDepth(depth); +} +| +; + +statement : variable_assignment +{ + $$ = $1; +} +| automake_if +{ + $$ = $1; +} +| else_statement +{ + $$ = $1; +} +| endif_statement +{ + $$ = $1; +} +| target +{ + $$ = $1; +} +| am_rule +{ + $$ = $1; +} +| include_directive +{ + $$ = $1; +} +| comment +{ + $$ = $1; +} +| emptyline +{ + $$ = new NewLineAST(); +} +; + +automake_if: IF_KEYWORD scoped_identifier +{ + ConditionAST* projectAST = new ConditionAST(); + projectAST->type = "if"; + projectAST->conditionName = $2; + $$ = projectAST; +}; + +endif_statement: ENDIF_KEYWORD +{ + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + $$ = past; +} +| ENDIF_KEYWORD scoped_identifier +{ + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + past->conditionName = $2; + $$ = past; +} +; + +else_statement: ELSE_KEYWORD +{ + ConditionAST* past = new ConditionAST(); + past->type = "else"; + $$ = past; +} +| ELSE_KEYWORD scoped_identifier +{ + ConditionAST* past = new ConditionAST(); + past->type = "else"; + past->conditionName = $2; + $$ = past; +} +; + +variable_assignment : scoped_identifier operator multiline_values +{ + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values = $3; + $$ = node; +} +; + +scoped_identifier : ID_SIMPLE scoped_identifier +{ $$ = $1 + $2; } +| ID_SIMPLE +; + +multiline_values : multiline_values line_body +{ + $$.append($2); +} +| { $$.clear(); } + ; + +line_body : ID_LIST CONT { $$ = $1 + " \\\n"; } + | ID_LIST_SINGLE NEWLINE { $$ = $1 + "\n"; } + | CONT { $$ = "\\\n"; } + | LIST_COMMENT + ; + +target: scoped_identifier COLON multiline_values +{ + AutomakeTargetAST *node = new AutomakeTargetAST(); + node->target = $1; + node->deps = $3; + $$ = node; +} +; + +am_rule: RULE +{ + ProjectAST* node = new ProjectAST(ProjectAST::Rule); + node->scopedID = $1; + $$ = node; +} +; + +include_directive: KEYWORD scoped_identifier +{ + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->values = QStringList($2); + $$ = node; +} +; + +operator : EQ | PLUSEQ +; + +comment : COMMENT NEWLINE +{ + CommentAST *node = new CommentAST(); + node->comment = $1 + "\n"; + $$ = node; +} +; + +emptyline : NEWLINE +; +%% + +#include "autotools_lex.cpp" diff --git a/buildtools/lib/parsers/autotools/autotools_lex.cpp b/buildtools/lib/parsers/autotools/autotools_lex.cpp new file mode 100644 index 00000000..ac307240 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools_lex.cpp @@ -0,0 +1,1894 @@ +#line 2 "autotools_lex.cpp" + +#line 4 "autotools_lex.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 31 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include +#include +#include +#include + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart(yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +extern int yyleng; + +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* Stack of input buffers. */ +static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ +static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ +static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; +static int yy_n_chars; /* number of characters read into yy_ch_buf */ +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart (FILE *input_file ); +void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); +YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); +void yy_delete_buffer (YY_BUFFER_STATE b ); +void yy_flush_buffer (YY_BUFFER_STATE b ); +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); +void yypop_buffer_state (void ); + +static void yyensure_buffer_stack (void ); +static void yy_load_buffer_state (void ); +static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); + +#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) + +YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); +YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); +YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer(yyin,YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define yywrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; + +typedef int yy_state_type; + +extern int yylineno; + +int yylineno = 1; + +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state (void ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); +static int yy_get_next_buffer (void ); +static void yy_fatal_error (yyconst char msg[] ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ + (yy_c_buf_p) = yy_cp; + +#define YY_NUM_RULES 17 +#define YY_END_OF_BUFFER 18 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[64] = + { 0, + 0, 0, 8, 8, 0, 0, 0, 0, 18, 17, + 1, 15, 1, 4, 16, 17, 14, 10, 17, 4, + 4, 12, 13, 8, 1, 8, 6, 17, 9, 5, + 1, 1, 1, 4, 4, 16, 11, 0, 2, 4, + 4, 3, 4, 8, 6, 1, 8, 8, 7, 6, + 6, 0, 9, 4, 4, 4, 6, 6, 4, 4, + 4, 4, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 5, 1, 6, 7, 1, 1, 1, 8, + 9, 10, 11, 1, 12, 13, 14, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 1, 1, + 17, 1, 1, 18, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 1, 20, 1, 1, 21, 1, 19, 19, 22, 23, + + 24, 25, 19, 19, 26, 19, 19, 27, 19, 28, + 19, 19, 19, 19, 29, 19, 30, 19, 19, 19, + 19, 19, 31, 32, 33, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[34] = + { 0, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[72] = + { 0, + 0, 0, 32, 51, 34, 36, 0, 0, 155, 156, + 38, 156, 42, 67, 0, 137, 156, 156, 45, 23, + 31, 156, 156, 133, 63, 38, 98, 134, 133, 0, + 58, 59, 62, 0, 0, 0, 156, 101, 156, 112, + 117, 0, 117, 118, 104, 105, 65, 67, 156, 110, + 113, 127, 126, 110, 106, 104, 117, 124, 104, 93, + 99, 96, 156, 144, 146, 148, 109, 97, 83, 150, + 72 + } ; + +static yyconst flex_int16_t yy_def[72] = + { 0, + 63, 1, 64, 64, 65, 65, 66, 66, 63, 63, + 67, 63, 63, 63, 68, 63, 63, 63, 63, 14, + 14, 63, 63, 69, 69, 70, 69, 71, 71, 67, + 67, 67, 63, 14, 14, 68, 63, 63, 63, 14, + 14, 14, 14, 69, 69, 69, 70, 70, 63, 70, + 69, 71, 71, 14, 14, 14, 69, 70, 14, 14, + 14, 14, 0, 63, 63, 63, 63, 63, 63, 63, + 63 + } ; + +static yyconst flex_int16_t yy_nxt[190] = + { 0, + 10, 11, 12, 13, 14, 15, 14, 10, 10, 14, + 16, 14, 10, 10, 14, 17, 18, 14, 14, 19, + 14, 14, 14, 20, 14, 21, 14, 14, 14, 14, + 22, 10, 23, 25, 12, 25, 10, 26, 10, 31, + 49, 32, 29, 33, 29, 33, 38, 39, 38, 40, + 41, 27, 25, 12, 25, 42, 26, 50, 43, 31, + 32, 32, 32, 33, 46, 33, 46, 49, 47, 49, + 27, 34, 52, 34, 34, 34, 34, 34, 35, 34, + 34, 34, 45, 44, 50, 34, 50, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 36, 34, 51, + + 39, 51, 38, 39, 38, 57, 46, 57, 46, 30, + 47, 58, 49, 58, 51, 39, 51, 45, 57, 42, + 57, 62, 61, 45, 45, 58, 49, 58, 42, 50, + 60, 59, 45, 42, 53, 53, 45, 45, 56, 55, + 54, 53, 53, 50, 24, 24, 28, 28, 10, 10, + 48, 48, 45, 37, 63, 9, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63 + } ; + +static yyconst flex_int16_t yy_chk[190] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 3, 3, 5, 3, 6, 11, + 26, 11, 5, 13, 6, 13, 19, 19, 19, 20, + 20, 3, 4, 4, 4, 21, 4, 26, 21, 31, + 32, 31, 32, 33, 25, 33, 25, 47, 25, 48, + 4, 14, 71, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 25, 69, 47, 14, 48, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 68, 14, 27, + + 27, 27, 38, 38, 38, 45, 46, 45, 46, 67, + 46, 50, 50, 50, 51, 51, 51, 27, 57, 62, + 57, 61, 60, 45, 46, 58, 58, 58, 59, 50, + 56, 55, 51, 54, 53, 52, 57, 44, 43, 41, + 40, 29, 28, 58, 64, 64, 65, 65, 66, 66, + 70, 70, 24, 16, 9, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63, 63, 63 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +extern int yy_flex_debug; +int yy_flex_debug = 0; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "autotools.ll" +#line 2 "autotools.ll" +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include + +/** +@file autotools.ll +Autotools Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ + + + +#line 559 "autotools_lex.cpp" + +#define INITIAL 0 +#define list 1 +#define funcargs 2 +#define conditional 3 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#include +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap (void ); +#else +extern int yywrap (void ); +#endif +#endif + + static void yyunput (int c,char *buf_ptr ); + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (void ); +#else +static int input (void ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + size_t n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int yylex (void); + +#define YY_DECL int yylex (void) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 73 "autotools.ll" + + +#line 716 "autotools_lex.cpp" + + if ( (yy_init) ) + { + (yy_init) = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 64 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 156 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 75 "autotools.ll" +{} + YY_BREAK +case 2: +/* rule 2 can match eol */ +YY_RULE_SETUP +#line 76 "autotools.ll" +{ BEGIN(list); return CONT; } + YY_BREAK +case 3: +YY_RULE_SETUP +#line 77 "autotools.ll" +{ + yylval.value = yytext; + if ( yylval.value == "if" ) + return IF_KEYWORD; + + if ( yylval.value == "else" ) + return ELSE_KEYWORD; + + if ( yylval.value == "endif" ) + return ENDIF_KEYWORD; + + return KEYWORD; +} + YY_BREAK +case 4: +YY_RULE_SETUP +#line 92 "autotools.ll" +{ yylval.value = yytext; return (ID_SIMPLE); } + YY_BREAK +case 5: +YY_RULE_SETUP +#line 94 "autotools.ll" +{ + yylval.value = yytext; + return RULE; +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 99 "autotools.ll" +{ + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.findRev("\\")); + unput('\\'); + BEGIN(INITIAL); + return (ID_LIST); + } + YY_BREAK +case 7: +/* rule 7 can match eol */ +YY_RULE_SETUP +#line 107 "autotools.ll" +{ + yylval.value = yytext; + BEGIN(list); + return (LIST_COMMENT); + } + YY_BREAK +case 8: +YY_RULE_SETUP +#line 113 "autotools.ll" +{ + yylval.value = yytext; + BEGIN(INITIAL); + return (ID_LIST_SINGLE); + } + YY_BREAK +case 9: +YY_RULE_SETUP +#line 119 "autotools.ll" +{ + yylval.value = yytext; + yylval.value = yylval.value.mid(0, yylval.value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (ID_ARGS); + } + YY_BREAK +case 10: +YY_RULE_SETUP +#line 127 "autotools.ll" +{ BEGIN(list); yylval.value = yytext; return EQ; } + YY_BREAK +case 11: +YY_RULE_SETUP +#line 128 "autotools.ll" +{ BEGIN(list); yylval.value = yytext; return PLUSEQ; } + YY_BREAK +case 12: +YY_RULE_SETUP +#line 129 "autotools.ll" +{ return LCURLY; } + YY_BREAK +case 13: +YY_RULE_SETUP +#line 130 "autotools.ll" +{ return RCURLY; } + YY_BREAK +case 14: +YY_RULE_SETUP +#line 131 "autotools.ll" +{ BEGIN(list); yylval.value = yytext; return COLON; } + YY_BREAK +case 15: +/* rule 15 can match eol */ +YY_RULE_SETUP +#line 132 "autotools.ll" +{ BEGIN(INITIAL); return NEWLINE; } + YY_BREAK +case 16: +YY_RULE_SETUP +#line 133 "autotools.ll" +{ yylval.value = yytext; return (COMMENT); } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 135 "autotools.ll" +ECHO; + YY_BREAK +#line 922 "autotools_lex.cpp" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(list): +case YY_STATE_EOF(funcargs): +case YY_STATE_EOF(conditional): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (void) +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + size_t num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart(yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (void) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 64 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) +{ + register int yy_is_jam; + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 64 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 63); + + return yy_is_jam ? 0 : yy_current_state; +} + + static void yyunput (int c, register char * yy_bp ) +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (void) +#else + static int input (void) +#endif + +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart(yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ + void yyrestart (FILE * input_file ) +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer(yyin,YY_BUF_SIZE ); + } + + yy_init_buffer(YY_CURRENT_BUFFER,input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ + void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +static void yy_load_buffer_state (void) +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ + YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer(b,file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ + void yy_delete_buffer (YY_BUFFER_STATE b ) +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +#ifndef __cplusplus +extern int isatty (int ); +#endif /* __cplusplus */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ + static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) + +{ + int oerrno = errno; + + yy_flush_buffer(b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ + void yy_flush_buffer (YY_BUFFER_STATE b ) +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +void yypop_buffer_state (void) +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void yyensure_buffer_stack (void) +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer(b ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to yylex() will + * scan from a @e copy of @a str. + * @param str a NUL-terminated string to scan + * + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * yy_scan_bytes() instead. + */ +YY_BUFFER_STATE yy_scan_string (yyconst char * yy_str ) +{ + + return yy_scan_bytes(yy_str,strlen(yy_str) ); +} + +/** Setup the input buffer state to scan the given bytes. The next call to yylex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE yy_scan_bytes (yyconst char * bytes, int len ) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yyalloc(n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer(buf,n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg ) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the current line number. + * + */ +int yyget_lineno (void) +{ + + return yylineno; +} + +/** Get the input stream. + * + */ +FILE *yyget_in (void) +{ + return yyin; +} + +/** Get the output stream. + * + */ +FILE *yyget_out (void) +{ + return yyout; +} + +/** Get the length of the current token. + * + */ +int yyget_leng (void) +{ + return yyleng; +} + +/** Get the current token. + * + */ + +char *yyget_text (void) +{ + return yytext; +} + +/** Set the current line number. + * @param line_number + * + */ +void yyset_lineno (int line_number ) +{ + + yylineno = line_number; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * + * @see yy_switch_to_buffer + */ +void yyset_in (FILE * in_str ) +{ + yyin = in_str ; +} + +void yyset_out (FILE * out_str ) +{ + yyout = out_str ; +} + +int yyget_debug (void) +{ + return yy_flex_debug; +} + +void yyset_debug (int bdebug ) +{ + yy_flex_debug = bdebug ; +} + +/* yylex_destroy is for both reentrant and non-reentrant scanners. */ +int yylex_destroy (void) +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +#undef YY_NEW_FILE +#undef YY_FLUSH_BUFFER +#undef yy_set_bol +#undef yy_new_buffer +#undef yy_set_interactive +#undef yytext_ptr +#undef YY_DO_BEFORE_ACTION + +#ifdef YY_DECL_IS_OURS +#undef YY_DECL_IS_OURS +#undef YY_DECL +#endif +#line 135 "autotools.ll" + + + + diff --git a/buildtools/lib/parsers/autotools/autotools_yacc.cpp b/buildtools/lib/parsers/autotools/autotools_yacc.cpp new file mode 100644 index 00000000..f4a3892c --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools_yacc.cpp @@ -0,0 +1,1631 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Written by Richard Stallman by simplifying the original so called + ``semantic'' parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ID_SIMPLE = 258, + ID_LIST = 259, + LBRACE = 260, + EQ = 261, + PLUSEQ = 262, + MINUSQE = 263, + STAREQ = 264, + TILDEEQ = 265, + RBRACE = 266, + COLON = 267, + NUMSIGN = 268, + NEWLINE = 269, + NUMBER = 270, + COMMENT = 271, + CONT = 272, + DOT = 273, + RCURLY = 274, + LCURLY = 275, + ID_ARGS = 276, + LIST_COMMENT = 277, + ID_LIST_SINGLE = 278, + IF_KEYWORD = 279, + ELSE_KEYWORD = 280, + ENDIF_KEYWORD = 281, + KEYWORD = 282, + RULE = 283 + }; +#endif +#define ID_SIMPLE 258 +#define ID_LIST 259 +#define LBRACE 260 +#define EQ 261 +#define PLUSEQ 262 +#define MINUSQE 263 +#define STAREQ 264 +#define TILDEEQ 265 +#define RBRACE 266 +#define COLON 267 +#define NUMSIGN 268 +#define NEWLINE 269 +#define NUMBER 270 +#define COMMENT 271 +#define CONT 272 +#define DOT 273 +#define RCURLY 274 +#define LCURLY 275 +#define ID_ARGS 276 +#define LIST_COMMENT 277 +#define ID_LIST_SINGLE 278 +#define IF_KEYWORD 279 +#define ELSE_KEYWORD 280 +#define ENDIF_KEYWORD 281 +#define KEYWORD 282 +#define RULE 283 + + + + +/* Copy the first part of user declarations. */ +#line 1 "autotools.yy" + +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +Autotools Parser + +Simple LALR parser which builds the syntax tree (see @ref Autotools::AST). + +@todo Recognize comments after statements like: +noinst_HEADERS = foo.h #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include +#include "autotoolsast.h" + +#define YYSTYPE_IS_DECLARED + +using namespace AutoTools; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in Makefile.am file: + @code + foo_SOURCES = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: +
+    foo1.cpp
+    foo2.cpp
+    foo3.cpp foo4.cpp
+    
+ */ + QStringList values; +}; + +typedef Result YYSTYPE; + +void yyerror(const char *str) { + printf("bison error: %s\n", str); +} + +int yylex(); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +QValueStack projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +typedef int YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + + + +/* Copy the second part of user declarations. */ + + +/* Line 214 of yacc.c. */ +#line 253 "autotools_yacc.cpp" + +#if ! defined (yyoverflow) || YYERROR_VERBOSE + +# ifndef YYFREE +# define YYFREE free +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# endif + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# endif +# else +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# endif +#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short int yyss; + YYSTYPE yyvs; + }; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined (__GNUC__) && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined (__STDC__) || defined (__cplusplus) + typedef signed char yysigned_char; +#else + typedef short int yysigned_char; +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 3 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 33 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 29 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 18 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 35 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 43 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 283 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const unsigned char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const unsigned char yyprhs[] = +{ + 0, 0, 3, 4, 7, 10, 11, 13, 15, 17, + 19, 21, 23, 25, 27, 29, 32, 34, 37, 39, + 42, 46, 49, 51, 54, 55, 58, 61, 63, 65, + 69, 71, 74, 76, 78, 81 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yysigned_char yyrhs[] = +{ + 30, 0, -1, -1, 31, 32, -1, 32, 33, -1, + -1, 37, -1, 34, -1, 36, -1, 35, -1, 41, + -1, 42, -1, 43, -1, 45, -1, 46, -1, 24, + 38, -1, 26, -1, 26, 38, -1, 25, -1, 25, + 38, -1, 38, 44, 39, -1, 3, 38, -1, 3, + -1, 39, 40, -1, -1, 4, 17, -1, 23, 14, + -1, 17, -1, 22, -1, 38, 12, 39, -1, 28, + -1, 27, 38, -1, 6, -1, 7, -1, 16, 14, + -1, 14, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const unsigned short int yyrline[] = +{ + 0, 142, 142, 142, 149, 175, 178, 182, 186, 190, + 194, 198, 202, 206, 210, 216, 224, 230, 239, 245, + 254, 264, 266, 269, 273, 276, 277, 278, 279, 282, + 291, 299, 308, 308, 311, 319 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE +/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "ID_SIMPLE", "ID_LIST", "LBRACE", "EQ", + "PLUSEQ", "MINUSQE", "STAREQ", "TILDEEQ", "RBRACE", "COLON", "NUMSIGN", + "NEWLINE", "NUMBER", "COMMENT", "CONT", "DOT", "RCURLY", "LCURLY", + "ID_ARGS", "LIST_COMMENT", "ID_LIST_SINGLE", "IF_KEYWORD", + "ELSE_KEYWORD", "ENDIF_KEYWORD", "KEYWORD", "RULE", "$accept", "project", + "@1", "statements", "statement", "automake_if", "endif_statement", + "else_statement", "variable_assignment", "scoped_identifier", + "multiline_values", "line_body", "target", "am_rule", + "include_directive", "operator", "comment", "emptyline", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const unsigned short int yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const unsigned char yyr1[] = +{ + 0, 29, 31, 30, 32, 32, 33, 33, 33, 33, + 33, 33, 33, 33, 33, 34, 35, 35, 36, 36, + 37, 38, 38, 39, 39, 40, 40, 40, 40, 41, + 42, 43, 44, 44, 45, 46 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const unsigned char yyr2[] = +{ + 0, 2, 0, 2, 2, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, + 3, 2, 1, 2, 0, 2, 2, 1, 1, 3, + 1, 2, 1, 1, 2, 1 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const unsigned char yydefact[] = +{ + 2, 0, 5, 1, 3, 22, 35, 0, 0, 18, + 16, 0, 30, 4, 7, 9, 8, 6, 0, 10, + 11, 12, 13, 14, 21, 34, 15, 19, 17, 31, + 32, 33, 24, 24, 29, 20, 0, 27, 28, 0, + 23, 25, 26 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yysigned_char yydefgoto[] = +{ + -1, 1, 2, 4, 13, 14, 15, 16, 17, 18, + 34, 40, 19, 20, 21, 33, 22, 23 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -18 +static const yysigned_char yypact[] = +{ + -18, 2, -18, -18, -3, 0, -18, -6, 0, 0, + 0, 0, -18, -18, -18, -18, -18, -18, 3, -18, + -18, -18, -18, -18, -18, -18, -18, -18, -18, -18, + -18, -18, -18, -18, 10, 10, -5, -18, -18, 4, + -18, -18, -18 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yysigned_char yypgoto[] = +{ + -18, -18, -18, -18, -18, -18, -18, -18, -18, -4, + -17, -18, -18, -18, -18, -18, -18, -18 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const unsigned char yytable[] = +{ + 5, 24, 3, 5, 26, 27, 28, 29, 25, 30, + 31, 6, 41, 7, 36, 32, 35, 0, 42, 0, + 0, 8, 9, 10, 11, 12, 0, 37, 0, 0, + 0, 0, 38, 39 +}; + +static const yysigned_char yycheck[] = +{ + 3, 5, 0, 3, 8, 9, 10, 11, 14, 6, + 7, 14, 17, 16, 4, 12, 33, -1, 14, -1, + -1, 24, 25, 26, 27, 28, -1, 17, -1, -1, + -1, -1, 22, 23 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const unsigned char yystos[] = +{ + 0, 30, 31, 0, 32, 3, 14, 16, 24, 25, + 26, 27, 28, 33, 34, 35, 36, 37, 38, 41, + 42, 43, 45, 46, 38, 14, 38, 38, 38, 38, + 6, 7, 12, 44, 39, 39, 4, 17, 22, 23, + 40, 17, 14 +}; + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ +#endif +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int +#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. */ + +#define YYFAIL goto yyerrlab + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror ("syntax error: cannot back up");\ + YYERROR; \ + } \ +while (0) + +#define YYTERROR 1 +#define YYERRCODE 256 + +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + ((Current).first_line = (Rhs)[1].first_line, \ + (Current).first_column = (Rhs)[1].first_column, \ + (Current).last_line = (Rhs)[N].last_line, \ + (Current).last_column = (Rhs)[N].last_column) +#endif + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (YYLEX_PARAM) +#else +# define YYLEX yylex () +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +# define YYDSYMPRINT(Args) \ +do { \ + if (yydebug) \ + yysymprint Args; \ +} while (0) + +# define YYDSYMPRINTF(Title, Token, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yysymprint (stderr, \ + Token, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_stack_print (short int *bottom, short int *top) +#else +static void +yy_stack_print (bottom, top) + short int *bottom; + short int *top; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (/* Nothing. */; bottom <= top; ++bottom) + YYFPRINTF (stderr, " %d", *bottom); + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yy_reduce_print (int yyrule) +#else +static void +yy_reduce_print (yyrule) + int yyrule; +#endif +{ + int yyi; + unsigned int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", + yyrule - 1, yylno); + /* Print the symbols being reduced, and their result. */ + for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) + YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); + YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YYDSYMPRINT(Args) +# define YYDSYMPRINTF(Title, Token, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 +# undef YYMAXDEPTH +#endif + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; + + while (*yys++ != '\0') + continue; + + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif +{ + register char *yyd = yydest; + register const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +#endif /* !YYERROR_VERBOSE */ + + + +#if YYDEBUG +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) +#else +static void +yysymprint (yyoutput, yytype, yyvaluep) + FILE *yyoutput; + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + if (yytype < YYNTOKENS) + { + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); +# ifdef YYPRINT + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + } + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + switch (yytype) + { + default: + break; + } + YYFPRINTF (yyoutput, ")"); +} + +#endif /* ! YYDEBUG */ +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +#if defined (__STDC__) || defined (__cplusplus) +static void +yydestruct (int yytype, YYSTYPE *yyvaluep) +#else +static void +yydestruct (yytype, yyvaluep) + int yytype; + YYSTYPE *yyvaluep; +#endif +{ + /* Pacify ``unused variable'' warnings. */ + (void) yyvaluep; + + switch (yytype) + { + + default: + break; + } +} + + +/* Prevent warnings from -Wmissing-prototypes. */ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM); +# else +int yyparse (); +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int yyparse (void); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + +/* Number of syntax errors so far. */ +int yynerrs; + + + +/*----------. +| yyparse. | +`----------*/ + +#ifdef YYPARSE_PARAM +# if defined (__STDC__) || defined (__cplusplus) +int yyparse (void *YYPARSE_PARAM) +# else +int yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +# endif +#else /* ! YYPARSE_PARAM */ +#if defined (__STDC__) || defined (__cplusplus) +int +yyparse (void) +#else +int +yyparse () + +#endif +#endif +{ + + register int yystate; + register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short int yyssa[YYINITDEPTH]; + short int *yyss = yyssa; + register short int *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; + + + +#define YYPOPSTACK (yyvsp--, yyssp--) + + YYSIZE_T yystacksize = YYINITDEPTH; + + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + + + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ + int yylen; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + + yyssp = yyss; + yyvsp = yyvs; + + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short int *yyss1 = yyss; + + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyoverflowlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + short int *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); + +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +/* yyresume: */ + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + yystate = yyn; + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 142 "autotools.yy" + { + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); +;} + break; + + case 4: +#line 150 "autotools.yy" + { + projects.top()->addChildAST(yyvsp[0].node); + + if ( yyvsp[0].node->nodeType() == AST::ProjectAST && + static_cast( yyvsp[0].node )->scopedID == "if" ) + { + yyvsp[0].node->setDepth(depth); + depth++; + } + else if ( yyvsp[0].node->nodeType() == AST::ProjectAST && + static_cast( yyvsp[0].node )->scopedID == "else" ) + { + --depth; + yyvsp[0].node->setDepth(depth); + ++depth; + } + else if ( yyvsp[0].node->nodeType() == AST::ProjectAST && + static_cast( yyvsp[0].node )->scopedID == "endif" ) + { + --depth; + yyvsp[0].node->setDepth(depth); + } + else + yyvsp[0].node->setDepth(depth); +;} + break; + + case 6: +#line 179 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 7: +#line 183 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 8: +#line 187 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 9: +#line 191 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 10: +#line 195 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 11: +#line 199 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 12: +#line 203 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 13: +#line 207 "autotools.yy" + { + yyval.node = yyvsp[0].node; +;} + break; + + case 14: +#line 211 "autotools.yy" + { + yyval.node = new NewLineAST(); +;} + break; + + case 15: +#line 217 "autotools.yy" + { + ConditionAST* projectAST = new ConditionAST(); + projectAST->type = "if"; + projectAST->conditionName = yyvsp[0].value; + yyval.node = projectAST; +;} + break; + + case 16: +#line 225 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + yyval.node = past; +;} + break; + + case 17: +#line 231 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type= "endif"; + past->conditionName = yyvsp[0].value; + yyval.node = past; +;} + break; + + case 18: +#line 240 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type = "else"; + yyval.node = past; +;} + break; + + case 19: +#line 246 "autotools.yy" + { + ConditionAST* past = new ConditionAST(); + past->type = "else"; + past->conditionName = yyvsp[0].value; + yyval.node = past; +;} + break; + + case 20: +#line 255 "autotools.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = yyvsp[-2].value; + node->op = yyvsp[-1].value; + node->values = yyvsp[0].values; + yyval.node = node; +;} + break; + + case 21: +#line 265 "autotools.yy" + { yyval.value = yyvsp[-1].value + yyvsp[0].value; ;} + break; + + case 23: +#line 270 "autotools.yy" + { + yyval.values.append(yyvsp[0].value); +;} + break; + + case 24: +#line 273 "autotools.yy" + { yyval.values.clear(); ;} + break; + + case 25: +#line 276 "autotools.yy" + { yyval.value = yyvsp[-1].value + " \\\n"; ;} + break; + + case 26: +#line 277 "autotools.yy" + { yyval.value = yyvsp[-1].value + "\n"; ;} + break; + + case 27: +#line 278 "autotools.yy" + { yyval.value = "\\\n"; ;} + break; + + case 29: +#line 283 "autotools.yy" + { + AutomakeTargetAST *node = new AutomakeTargetAST(); + node->target = yyvsp[-2].value; + node->deps = yyvsp[0].values; + yyval.node = node; +;} + break; + + case 30: +#line 292 "autotools.yy" + { + ProjectAST* node = new ProjectAST(ProjectAST::Rule); + node->scopedID = yyvsp[0].value; + yyval.node = node; +;} + break; + + case 31: +#line 300 "autotools.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = yyvsp[-1].value; + node->values = QStringList(yyvsp[0].value); + yyval.node = node; +;} + break; + + case 34: +#line 312 "autotools.yy" + { + CommentAST *node = new CommentAST(); + node->comment = yyvsp[-1].value + "\n"; + yyval.node = node; +;} + break; + + + } + +/* Line 1010 of yacc.c. */ +#line 1403 "autotools_yacc.cpp" + + yyvsp -= yylen; + yyssp -= yylen; + + + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if YYERROR_VERBOSE + yyn = yypact[yystate]; + + if (YYPACT_NINF < yyn && yyn < YYLAST) + { + YYSIZE_T yysize = 0; + int yytype = YYTRANSLATE (yychar); + const char* yyprefix; + char *yymsg; + int yyx; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 0; + + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); + yycount += 1; + if (yycount == 5) + { + yysize = 0; + break; + } + } + yysize += (sizeof ("syntax error, unexpected ") + + yystrlen (yytname[yytype])); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) + { + char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); + yyp = yystpcpy (yyp, yytname[yytype]); + + if (yycount < 5) + { + yyprefix = ", expecting "; + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + yyp = yystpcpy (yyp, yyprefix); + yyp = yystpcpy (yyp, yytname[yyx]); + yyprefix = " or "; + } + } + yyerror (yymsg); + YYSTACK_FREE (yymsg); + } + else + yyerror ("syntax error; also virtual memory exhausted"); + } + else +#endif /* YYERROR_VERBOSE */ + yyerror ("syntax error"); + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* If at end of input, pop the error token, + then the rest of the stack, then return failure. */ + if (yychar == YYEOF) + for (;;) + { + YYPOPSTACK; + if (yyssp == yyss) + YYABORT; + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[*yyssp], yyvsp); + } + } + else + { + YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); + yydestruct (yytoken, &yylval); + yychar = YYEMPTY; + + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + +#ifdef __GNUC__ + /* Pacify GCC when the user code never invokes YYERROR and the label + yyerrorlab therefore never appears in user code. */ + if (0) + goto yyerrorlab; +#endif + + yyvsp -= yylen; + yyssp -= yylen; + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); + yydestruct (yystos[yystate], yyvsp); + YYPOPSTACK; + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + if (yyn == YYFINAL) + YYACCEPT; + + YYDPRINTF ((stderr, "Shifting error token, ")); + + *++yyvsp = yylval; + + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#ifndef yyoverflow +/*----------------------------------------------. +| yyoverflowlab -- parser overflow comes here. | +`----------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif + return yyresult; +} + + +#line 321 "autotools.yy" + + +#include "autotools_lex.cpp" + diff --git a/buildtools/lib/parsers/autotools/autotools_yacc.h b/buildtools/lib/parsers/autotools/autotools_yacc.h new file mode 100644 index 00000000..b8becb4a --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotools_yacc.h @@ -0,0 +1,100 @@ +/* A Bison parser, made by GNU Bison 1.875d. */ + +/* Skeleton parser for Yacc-like parsing with Bison, + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* As a special exception, when this file is copied by Bison into a + Bison output file, you may use that output file without restriction. + This special exception was added by the Free Software Foundation + in version 1.24 of Bison. */ + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + ID_SIMPLE = 258, + ID_LIST = 259, + LBRACE = 260, + EQ = 261, + PLUSEQ = 262, + MINUSQE = 263, + STAREQ = 264, + TILDEEQ = 265, + RBRACE = 266, + COLON = 267, + NUMSIGN = 268, + NEWLINE = 269, + NUMBER = 270, + COMMENT = 271, + CONT = 272, + DOT = 273, + RCURLY = 274, + LCURLY = 275, + ID_ARGS = 276, + LIST_COMMENT = 277, + ID_LIST_SINGLE = 278, + IF_KEYWORD = 279, + ELSE_KEYWORD = 280, + ENDIF_KEYWORD = 281, + KEYWORD = 282, + RULE = 283 + }; +#endif +#define ID_SIMPLE 258 +#define ID_LIST 259 +#define LBRACE 260 +#define EQ 261 +#define PLUSEQ 262 +#define MINUSQE 263 +#define STAREQ 264 +#define TILDEEQ 265 +#define RBRACE 266 +#define COLON 267 +#define NUMSIGN 268 +#define NEWLINE 269 +#define NUMBER 270 +#define COMMENT 271 +#define CONT 272 +#define DOT 273 +#define RCURLY 274 +#define LCURLY 275 +#define ID_ARGS 276 +#define LIST_COMMENT 277 +#define ID_LIST_SINGLE 278 +#define IF_KEYWORD 279 +#define ELSE_KEYWORD 280 +#define ENDIF_KEYWORD 281 +#define KEYWORD 282 +#define RULE 283 + + + + +#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) +typedef int YYSTYPE; +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +# define YYSTYPE_IS_TRIVIAL 1 +#endif + +extern YYSTYPE yylval; + + + diff --git a/buildtools/lib/parsers/autotools/autotoolsast.cpp b/buildtools/lib/parsers/autotools/autotoolsast.cpp new file mode 100644 index 00000000..71596e3d --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsast.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "autotoolsast.h" + +namespace AutoTools { + +//AST + +AST::~AST() +{ + for (QValueList::iterator it = m_children.begin(); it != m_children.end(); ++it) + { + AST *node = *it; + delete node; + } +} + +void AST::addChildAST(AST *node) +{ + m_children.append(node); +} + +void AST::writeBack(QString &buffer) +{ + for (QValueList::const_iterator it = m_children.constBegin(); + it != m_children.constEnd(); ++it) + { + if (*it) + (*it)->writeBack(buffer); + } +} + +QString AST::indentation() +{ + QString result; + for (int i = 0; i < depth(); i++) + result += '\t'; + return result; +} + +bool AST::hasChildren() const +{ + return !m_children.isEmpty(); +} + +QValueList AST::children() const +{ + return m_children; +} + +//ProjectAST + +void ProjectAST::writeBack(QString &buffer) +{ + if ( isRule() ) + buffer += scopedID; + else + buffer += indentation(); + + AST::writeBack(buffer); + +} + +void ProjectAST::addChildAST(AST *node) +{ + statements.append(node); + AST::addChildAST(node); +} + +void AssignmentAST::writeBack(QString &buffer) +{ + buffer += indentation() + scopedID + " " + op + values.join(""); +} + +void AutomakeTargetAST::writeBack( QString& buffer ) +{ + buffer += target + ":" + deps.join(""); +} + +void ConditionAST::writeBack( QString& buffer ) +{ + buffer += indentation() + type + " " + conditionName; +} + +void NewLineAST::writeBack(QString &buffer) +{ + buffer += "\n"; +} + +void CommentAST::writeBack(QString &buffer) +{ + buffer += indentation() + comment; +} + +} + +// kate: indent-mode csands; tab-width 4; space-indent off; diff --git a/buildtools/lib/parsers/autotools/autotoolsast.h b/buildtools/lib/parsers/autotools/autotoolsast.h new file mode 100644 index 00000000..c92c17c7 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsast.h @@ -0,0 +1,269 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef AUTOTOOLSAST_H +#define AUTOTOOLSAST_H + +#include + +/** +@file autotools.h +Abstract Syntax Tree (AST) class declarations. +*/ + +namespace AutoTools +{ + +/** + * AST node. + * This is the base class. Objects of this type are not created by the parser. + * + * Each AST node holds the list of its children which are always deleted in the + * destructor. This way, it's possible call delete for only root AST node and + * others will be deleted automatically. + * + * Each AST node also knows how to write the information back into .pro file. + */ +class AST +{ +public: + /**Type of AST node.*/ + enum NodeType { + ProjectAST, ///< Project, scope or function scope. + AssignmentAST, ///< Variable assignment. + TargetAST, ///< Automake target + MakefileConditionalAST, ///< Makefile.am conditional + NewLineAST, ///< Line feed. + CommentAST ///< Comment. + }; + + /** Constructs AST with given node type.*/ + AST(NodeType nodeType): m_nodeType(nodeType), m_depth(0) {} + virtual ~AST(); + + /** + * Adds child AST node to this node. Despite this function is virtual, + * reimplementations should call it to make automatic destruction of + * AST tree possible.*/ + virtual void addChildAST(AST *node); + + /** + * Writes information stored in the AST into the @p buffer. + * This is a default implementation which iterates over child nodes + * and calls writeBack for each child node. + */ + virtual void writeBack(QString &buffer); + + /** @return The type of the node.*/ + virtual NodeType nodeType() const { return m_nodeType; } + + /** Sets the depth of the node in AST.*/ + void setDepth(int depth) { m_depth = depth; } + + /** @return The depth of the node in AST.*/ + int depth() const { return m_depth; } + + /** @return The indentation string based on node depth.*/ + virtual QString indentation(); + + //! \return true if this AST has children + bool hasChildren() const; + + /** + * Get the children of this ast + * \return the list of this ast's childre + */ + QValueList children() const; + + + +protected: + NodeType m_nodeType; + QValueList m_children; + +private: + int m_depth; + +}; + + +/** + * Project AST node. + * Represents complete projects, scopes and function scopes. + * Examples: + * @code + * scopename{ + * var=value + * } + * function(args){ + * var=value + * } + * @endcode + */ +class ProjectAST: public AST +{ +public: + /**The kind of a project node.*/ + enum Kind + { + Project, ///< Project + Target, ///< Custom Automake Target + ConditionalScope, ///< Automake Conditional + Rule, ///< Automake Rule + Empty ///< Project does not exist. the AST is empty + }; + + /** Constructs a project node of given @p kind. */ + ProjectAST(Kind kind = Project): AST(AST::ProjectAST), m_kind(kind) {} + + virtual void writeBack(QString &buffer); + virtual void addChildAST(AST *node); + + /** @return true if this node is a project.*/ + bool isProject() const { return m_kind == Project; } + + bool isRule() const { return m_kind == Rule; } + + /** @return true if this node is an automake conditional */ + bool isConditionalScope() const { return m_kind == ConditionalScope; } + + /** @return true if this node is empty.*/ + bool isEmpty() const { return m_kind == Empty; } + + /**Scoped identifier (scope name or rule).*/ + QString scopedID; + + /**Function arguments. Empty for other kinds of projects.*/ + QString args; + + /** The automake conditional has an else attached */ + bool hasElse; + + /**List of statements.*/ + QValueList statements; + +private: + Kind m_kind; + +}; + + +/** + * Assignment AST node. + * Represents assignments, for example: + * \code + * var=value + * \endcode + * + * Values can be specified on several lines and + * each line is stored as a string in the list of values.@n + * For example, if we have in .pro: + * \code + * SOURCES=a.cpp \ + * b.cpp c.cpp + * \endcode + * then values will be stored as a two elements list: + * \code + * a.cpp + * b.cpp c.cpp + * \endcode + */ +class AssignmentAST: public AST +{ +public: + AssignmentAST(): AST(AST::AssignmentAST) {} + + virtual void writeBack(QString &buffer); + + /**Scoped name of the variable.*/ + QString scopedID; + + /**Operator.*/ + QString op; + + /**List of values.*/ + QStringList values; +}; + +class AutomakeTargetAST : public AST +{ +public: + AutomakeTargetAST() : AST(AST::TargetAST) {} + + virtual void writeBack( QString& buffer ); + + /// The name of the target + QString target; + + /// The dependencies for the target, if any + QStringList deps; +}; + +class ConditionAST : public AST +{ +public: + ConditionAST() : AST( AST::MakefileConditionalAST ) {} + + virtual void writeBack( QString& buffer ); + + /// The keyword for the condition (if, else, endif) + QString type; + + /// The name of the condition + QString conditionName; +}; + +/** + * New line AST node. + * Represents line feeds in files. + */ +class NewLineAST: public AST +{ +public: + NewLineAST(): AST(AST::NewLineAST) {} + + virtual void writeBack(QString &buffer); + +}; + + +/** + * Comment AST node. + * Represents comments. + */ +class CommentAST: public AST +{ +public: + CommentAST(): AST(AST::CommentAST) {} + + virtual void writeBack(QString &buffer); + + /**Comment text.*/ + QString comment; + +}; + +} + +#endif + +// kate: indent-mode csands; space-indent off; tab-width 4; auto-insert-doxygen on; diff --git a/buildtools/lib/parsers/autotools/autotoolsdriver.cpp b/buildtools/lib/parsers/autotools/autotoolsdriver.cpp new file mode 100644 index 00000000..8ec643ab --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsdriver.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "autotoolsdriver.h" +#include "autotoolsast.h" + +#include +#include +#include + +extern FILE *yyin, *yyout; +extern int yyparse(); +//extern int yydebug; +extern QValueStack projects; + +namespace AutoTools { + +int Driver::parseFile(const char *fileName, ProjectAST **ast) +{ + //yydebug = 1; + yyin = fopen(fileName, "r"); + if (yyin == 0) + { + ast = 0; + return 1; + } + int ret = yyparse(); + *ast = projects.top(); + fclose(yyin); + return ret; +} + +int Driver::parseFile(QString fileName, ProjectAST **ast) +{ + return parseFile(fileName.ascii(), ast); +} + +int Driver::parseFile(KURL fileName, ProjectAST **ast) +{ + QString tmpFile; + int ret = 0; + if (KIO::NetAccess::download(fileName, tmpFile, 0)) + ret = parseFile(tmpFile, ast); + KIO::NetAccess::removeTempFile(tmpFile); + return ret; +} + +} + +//kate: indent-mode csands; space-indent off; tab-width 4; + diff --git a/buildtools/lib/parsers/autotools/autotoolsdriver.h b/buildtools/lib/parsers/autotools/autotoolsdriver.h new file mode 100644 index 00000000..eba0a823 --- /dev/null +++ b/buildtools/lib/parsers/autotools/autotoolsdriver.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * Copyright (c) 2005 by Matt Rogers * + * mattr@kde.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEDRIVER_H +#define QMAKEQMAKEDRIVER_H + +#include +#include + +namespace AutoTools { + +/** +@file autotoolsdriver.h +Driver for a qmake parser. +*/ + +class ProjectAST; + +/** + * Driver. + * Use methods of this class to lauch parsing and build the AST. + */ +class Driver +{ +public: + /** + * Parses the file @p fileName and stores the resulting ProjectAST root + * into @p ast. @p ast should not be initialized before. Driver will + * initialize it on its own. + * @return The result of parsing. Result is 0 on success and <> 0 on failure. + */ + static int parseFile(const char *fileName, ProjectAST **ast); + static int parseFile(QString fileName, ProjectAST **ast); + static int parseFile(KURL fileName, ProjectAST **ast); + +/* template + static void walkAST(Op &op, const ProjectAST *ast) + { +// op(ast); + for (QValueList::const_iterator it = ast->statements.constBegin(); + it != ast->statements.constEnd(); ++it) + { + const AST *child = *it; + if (child->nodeType() == AST::ProjectAST) + walkAST(op, static_cast(child)); + else + op(child); + } + } +*/ +}; + +} + +#endif + +// kate: indent-mode csands; tab-width 4; space-indent off; auto-insert-doxygen on; diff --git a/buildtools/lib/parsers/autotools/tests/Makefile.am b/buildtools/lib/parsers/autotools/tests/Makefile.am new file mode 100644 index 00000000..222a0482 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/Makefile.am @@ -0,0 +1,21 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + -I$(top_srcdir)/buildtools/lib/parsers/autotools \ + -I$(top_builddir)/buildtools/lib/parsers/autotools/tests \ + $(all_includes) + +METASOURCES = AUTO + +check_PROGRAMS = runner viewer + +runner_LDFLAGS = $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +runner_LDADD = $(top_builddir)/buildtools/lib/parsers/autotools/libkdevautotoolsparser.la +runner_SOURCES = runner.cpp + +viewer_LDFLAGS = $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +viewer_LDADD = $(top_builddir)/buildtools/lib/parsers/autotools/libkdevautotoolsparser.la +viewer_SOURCES = viewer.cpp viewer_main.cpp viewerbase.ui diff --git a/buildtools/lib/parsers/autotools/tests/runner.cpp b/buildtools/lib/parsers/autotools/tests/runner.cpp new file mode 100644 index 00000000..cf9f68d1 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/runner.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include + +using namespace AutoTools; + +int main(int argc, char *argv[]) +{ + ProjectAST *projectAST; + if (argc > 1) + return Driver::parseFile(argv[1], &projectAST); + else + return 0; +} + diff --git a/buildtools/lib/parsers/autotools/tests/viewer.cpp b/buildtools/lib/parsers/autotools/tests/viewer.cpp new file mode 100644 index 00000000..047e6b28 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewer.cpp @@ -0,0 +1,162 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "viewer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace AutoTools; + +Viewer::Viewer(QWidget *parent, const char *name) + :ViewerBase(parent, name) +{ + if (QFile::exists(QDir::currentDirPath() + "/" + "qtlist")) + { + QFile f(QDir::currentDirPath() + "/" + "qtlist"); + f.open(IO_ReadOnly); + QTextStream str(&f); + while (!str.eof()) + files->insertItem(str.readLine()); + } + ast->setSorting(-1); + parentProject.push((QListViewItem*)0); +} + +void Viewer::addAll_clicked() +{ + if (allLocation->text().isEmpty()) + return; + QDir d(allLocation->text()); + QStringList l = d.entryList("*.am"); + for (QStringList::iterator it = l.begin(); it != l.end(); ++it) + (*it) = QDir::cleanDirPath(allLocation->text() + "/" + (*it)); + files->insertStringList(l); +} + +void Viewer::choose_clicked() +{ + QString fileName = QFileDialog::getOpenFileName(QDir::currentDirPath(), "*.am", this); + if (!fileName.isEmpty()) + files->insertItem(fileName); +} + +void Viewer::files_currentChanged(QListBoxItem* item) +{ + ast->clear(); + + QFile f(item->text()); + f.open(IO_ReadOnly); + QTextStream str(&f); + source->setText(str.read()); + f.close(); + + int result = Driver::parseFile(item->text().ascii(), &projectAST); + if (projectAST && (result == 0)) + { + processAST(projectAST); + } + if (tabWidget2->currentPageIndex() == 1) + tabWidget2_selected("Source to be written back"); +} + +void Viewer::tabWidget2_selected(const QString& text) +{ + if ((text == "Source to be written back") && projectAST) + { + QString buffer; + projectAST->writeBack(buffer); + writeBack->setText(buffer); + } +} + +void Viewer::processAST(ProjectAST *projectAST, QListViewItem *globAfter) +{ + QListViewItem *projectIt; + if (!parentProject.top()) + projectIt = new QListViewItem(ast, "Project"); + else + { + if ( projectAST->isConditionalScope() || projectAST->isRule() ) + projectIt = new QListViewItem(parentProject.top(), globAfter, projectAST->scopedID); + } + projectIt->setOpen(true); + + QListViewItem *after = 0; + for (QValueList::const_iterator it = projectAST->statements.constBegin(); + it != projectAST->statements.constEnd(); ++it) + { + AST *ast = *it; + if (ast == 0) + continue; + switch (ast->nodeType()) { + case AST::AssignmentAST: { + AssignmentAST *assignmentAST = static_cast(ast); + QListViewItem *item = new QListViewItem(projectIt, after, + assignmentAST->scopedID, assignmentAST->op, assignmentAST->values.join("")); + item->setMultiLinesEnabled(true); + after = item; } + break; + + case AST::TargetAST: + { + AutomakeTargetAST* ata = static_cast(ast); + QListViewItem* item = new QListViewItem(projectIt, after, + ata->target, QString::null, ata->deps.join("")); + after = item; + } + break; + + case AST::NewLineAST: +// after = new QListViewItem(projectIt, after, ""); + break; + + case AST::CommentAST: +// after = new QListViewItem(projectIt, after, ""); + break; + + case AST::MakefileConditionalAST: + { + ConditionAST* ata = static_cast(ast); + QListViewItem* item = new QListViewItem(projectIt, after, + ata->type, ata->conditionName, QString::null ); + after = item; + } + case AST::ProjectAST: { + ProjectAST *projectAST = static_cast(ast); + parentProject.push(projectIt); + processAST(projectAST, after); + parentProject.pop(); } + break; + } + } +} + +#include "viewer.moc" + diff --git a/buildtools/lib/parsers/autotools/tests/viewer.h b/buildtools/lib/parsers/autotools/tests/viewer.h new file mode 100644 index 00000000..46698483 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewer.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef VIEWER_H +#define VIEWER_H + +#include + +#include "viewerbase.h" + +namespace AutoTools { class ProjectAST; } + +class QListViewItem; + +class Viewer: public ViewerBase { +Q_OBJECT +public: + Viewer(QWidget *parent = 0, const char *name = 0); + void processAST(AutoTools::ProjectAST *projectAST, QListViewItem *globAfter = 0); +public slots: + virtual void tabWidget2_selected(const QString&); + virtual void files_currentChanged(QListBoxItem*); + virtual void choose_clicked(); + virtual void addAll_clicked(); +private: + AutoTools::ProjectAST *projectAST; + QValueStack parentProject; +}; + +#endif diff --git a/buildtools/lib/parsers/autotools/tests/viewer_main.cpp b/buildtools/lib/parsers/autotools/tests/viewer_main.cpp new file mode 100644 index 00000000..32641eff --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewer_main.cpp @@ -0,0 +1,34 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include "viewer.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + Viewer viewer; + app.setMainWidget(&viewer); + viewer.show(); + viewer.resize(800, 600); + //viewer.setWindowState(viewer.windowState() | Qt::WindowMaximized); + + return app.exec(); +} diff --git a/buildtools/lib/parsers/autotools/tests/viewerbase.ui b/buildtools/lib/parsers/autotools/tests/viewerbase.ui new file mode 100644 index 00000000..7c228299 --- /dev/null +++ b/buildtools/lib/parsers/autotools/tests/viewerbase.ui @@ -0,0 +1,220 @@ + +ViewerBase + + + ViewerBase + + + + 0 + 0 + 600 + 480 + + + + Viewer + + + + unnamed + + + + layout2 + + + + unnamed + + + + source + + + + 7 + 7 + 0 + 1 + + + + + + tabWidget2 + + + + 7 + 7 + 0 + 2 + + + + + tab + + + Parse Tree + + + + unnamed + + + + + Name + + + true + + + true + + + + + Value 1 + + + true + + + true + + + + + Value 2 + + + true + + + true + + + + ast + + + + + + + tab + + + Source to Be Written Back + + + + unnamed + + + + writeBack + + + + + + + + + + allLocation + + + + 150 + 32767 + + + + + + addAll + + + + 150 + 32767 + + + + Add All From Directory + + + + + choose + + + + 150 + 32767 + + + + Choose File to Add... + + + + + files + + + + 7 + 7 + 0 + 0 + + + + + 150 + 32767 + + + + + + + + addAll + clicked() + ViewerBase + addAll_clicked() + + + choose + clicked() + ViewerBase + choose_clicked() + + + files + currentChanged(QListBoxItem*) + ViewerBase + files_currentChanged(QListBoxItem*) + + + tabWidget2 + selected(const QString&) + ViewerBase + tabWidget2_selected(const QString&) + + + + addAll_clicked() + choose_clicked() + files_currentChanged(QListBoxItem*) + tabWidget2_selected(const QString&) + + + diff --git a/buildtools/lib/parsers/qmake/FlexLexer.h b/buildtools/lib/parsers/qmake/FlexLexer.h new file mode 100644 index 00000000..1db844da --- /dev/null +++ b/buildtools/lib/parsers/qmake/FlexLexer.h @@ -0,0 +1,205 @@ + +// -*-C++-*- +// FlexLexer.h -- define interfaces for lexical analyzer classes generated +// by flex + +// Copyright (c) 1993 The Regents of the University of California. +// All rights reserved. +// +// This code is derived from software contributed to Berkeley by +// Kent Williams and Tom Epperly. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: + +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. + +// Neither the name of the University nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. + +// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR +// IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE. + +// This file defines FlexLexer, an abstract class which specifies the +// external interface provided to flex C++ lexer objects, and yyFlexLexer, +// which defines a particular lexer class. +// +// If you want to create multiple lexer classes, you use the -P flag +// to rename each yyFlexLexer to some other xxFlexLexer. You then +// include in your other sources once per lexer class: +// +// #undef yyFlexLexer +// #define yyFlexLexer xxFlexLexer +// #include +// +// #undef yyFlexLexer +// #define yyFlexLexer zzFlexLexer +// #include +// ... + +#ifndef __FLEX_LEXER_H +// Never included before - need to define base class. +#define __FLEX_LEXER_H + +#include +# ifndef FLEX_STD +# define FLEX_STD std:: +# endif + +extern "C++" { + +struct yy_buffer_state; +typedef int yy_state_type; + +class FlexLexer { +public: + virtual ~FlexLexer() { } + + const char* YYText() const { return yytext; } + int YYLeng() const { return yyleng; } + + virtual void + yy_switch_to_buffer( struct yy_buffer_state* new_buffer ) = 0; + virtual struct yy_buffer_state* + yy_create_buffer( FLEX_STD istream* s, int size ) = 0; + virtual void yy_delete_buffer( struct yy_buffer_state* b ) = 0; + virtual void yyrestart( FLEX_STD istream* s ) = 0; + + virtual int yylex() = 0; + + // Call yylex with new input/output sources. + int yylex( FLEX_STD istream* new_in, FLEX_STD ostream* new_out = 0 ) + { + switch_streams( new_in, new_out ); + return yylex(); + } + + // Switch to new input/output streams. A nil stream pointer + // indicates "keep the current one". + virtual void switch_streams( FLEX_STD istream* new_in = 0, + FLEX_STD ostream* new_out = 0 ) = 0; + + int lineno() const { return yylineno; } + + int debug() const { return yy_flex_debug; } + void set_debug( int flag ) { yy_flex_debug = flag; } + +protected: + char* yytext; + int yyleng; + int yylineno; // only maintained if you use %option yylineno + int yy_flex_debug; // only has effect with -d or "%option debug" +}; + +} +#endif + +#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce) +// Either this is the first time through (yyFlexLexerOnce not defined), +// or this is a repeated include to define a different flavor of +// yyFlexLexer, as discussed in the flex man page. +#define yyFlexLexerOnce + +extern "C++" { + +class yyFlexLexer : public FlexLexer { +public: + // arg_yyin and arg_yyout default to the cin and cout, but we + // only make that assignment when initializing in yylex(). + yyFlexLexer( FLEX_STD istream* arg_yyin = 0, FLEX_STD ostream* arg_yyout = 0 ); + + virtual ~yyFlexLexer(); + + void yy_switch_to_buffer( struct yy_buffer_state* new_buffer ); + struct yy_buffer_state* yy_create_buffer( FLEX_STD istream* s, int size ); + void yy_delete_buffer( struct yy_buffer_state* b ); + void yyrestart( FLEX_STD istream* s ); + + void yypush_buffer_state( struct yy_buffer_state* new_buffer ); + void yypop_buffer_state(void); + + virtual int yylex(); + virtual void switch_streams( FLEX_STD istream* new_in, FLEX_STD ostream* new_out ); + +protected: + virtual int LexerInput( char* buf, int max_size ); + virtual void LexerOutput( const char* buf, int size ); + virtual void LexerError( const char* msg ); + + void yyunput( int c, char* buf_ptr ); + int yyinput(); + + void yy_load_buffer_state(); + void yy_init_buffer( struct yy_buffer_state* b, FLEX_STD istream* s ); + void yy_flush_buffer( struct yy_buffer_state* b ); + + int yy_start_stack_ptr; + int yy_start_stack_depth; + int* yy_start_stack; + + void yy_push_state( int new_state ); + void yy_pop_state(); + int yy_top_state(); + + yy_state_type yy_get_previous_state(); + yy_state_type yy_try_NUL_trans( yy_state_type current_state ); + int yy_get_next_buffer(); + + FLEX_STD istream* yyin; // input source for default LexerInput + FLEX_STD ostream* yyout; // output sink for default LexerOutput + + // yy_hold_char holds the character lost when yytext is formed. + char yy_hold_char; + + // Number of characters read into yy_ch_buf. + int yy_n_chars; + + // Points to current character in buffer. + char* yy_c_buf_p; + + int yy_init; // whether we need to initialize + int yy_start; // start state number + + // Flag which is used to allow yywrap()'s to do buffer switches + // instead of setting up a fresh yyin. A bit of a hack ... + int yy_did_buffer_switch_on_eof; + + + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + struct yy_buffer_state ** yy_buffer_stack; /**< Stack as an array. */ + void yyensure_buffer_stack(void); + + // The following are not always needed, but may be depending + // on use of certain flex features (like REJECT or yymore()). + + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + yy_state_type* yy_state_buf; + yy_state_type* yy_state_ptr; + + char* yy_full_match; + int* yy_full_state; + int yy_full_lp; + + int yy_lp; + int yy_looking_for_trail_begin; + + int yy_more_flag; + int yy_more_len; + int yy_more_offset; + int yy_prev_more_offset; +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/Mainpage.dox b/buildtools/lib/parsers/qmake/Mainpage.dox new file mode 100644 index 00000000..7b2e2682 --- /dev/null +++ b/buildtools/lib/parsers/qmake/Mainpage.dox @@ -0,0 +1,16 @@ +/** +@mainpage The KDevelop QMake Parser + +This library contains qmake parser. + +Link with: -lkdevqmakeparser + +Include path: -I\$(kde_includes)/kdevelop/buildtools/parsers/qmake + +\section qmakeparseroverview Overview +Here resides a parser for qmake .pro (.pri) files. This parser +reads project files, builds an AST which then can be written +back to the project file. + +*/ + diff --git a/buildtools/lib/parsers/qmake/Makefile.am b/buildtools/lib/parsers/qmake/Makefile.am new file mode 100644 index 00000000..fd80170c --- /dev/null +++ b/buildtools/lib/parsers/qmake/Makefile.am @@ -0,0 +1,31 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +#SUBDIRS = tests + +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + $(all_includes) +METASOURCES = AUTO +lib_LTLIBRARIES = libkdevqmakeparser.la +libkdevqmakeparser_la_LDFLAGS = -no-undefined $(all_libraries) $(LIB_KIO) +libkdevqmakeparser_la_SOURCES = qmake_lex.cpp qmake_yacc.cpp qmakeast.cpp \ + qmakeastvisitor.cpp qmakedriver.cpp + +kdevelopbuildtoolsincludedir = $(includedir)/kdevelop/buildtools/parsers/qmake +kdevelopbuildtoolsinclude_HEADERS = qmakeast.h qmakedriver.h qmakeastvisitor.h + +parser: + cd $(srcdir) ; \ + bison -d qmake.yy -r all -k -t -oqmake_yacc.cpp ; \ + flex -d -oqmake_lex.cpp qmake.ll + +EXTRA_DIST = qmake.yy qmake.ll + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils +DOXYGEN_PROJECTNAME = KDevelop QMake parser +DOXYGEN_DOCDIRPREFIX = kdevparser +include ../../../../Doxyfile.am + +noinst_HEADERS = qmake.ll qmake.yy qmake_lex.h diff --git a/buildtools/lib/parsers/qmake/location.hh b/buildtools/lib/parsers/qmake/location.hh new file mode 100644 index 00000000..4da36b8a --- /dev/null +++ b/buildtools/lib/parsers/qmake/location.hh @@ -0,0 +1,145 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Locations for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file location.hh + ** Define the QMake::location class. + */ + +#ifndef BISON_LOCATION_HH +# define BISON_LOCATION_HH + +# include +# include +# include "position.hh" + +namespace QMake +{ + + /// Abstract a location. + class location + { + public: + + /// Construct a location. + location () + : begin (), end () + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + begin.initialize (fn); + end = begin; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// Reset initial location to final location. + inline void step () + { + begin = end; + } + + /// Extend the current location to the COUNT next columns. + inline void columns (unsigned int count = 1) + { + end += count; + } + + /// Extend the current location to the COUNT next lines. + inline void lines (unsigned int count = 1) + { + end.lines (count); + } + /** \} */ + + + public: + /// Beginning of the located region. + position begin; + /// End of the located region. + position end; + }; + + /// Join two location objects to create a location. + inline const location operator+ (const location& begin, const location& end) + { + location res = begin; + res.end = end.end; + return res; + } + + /// Add two location objects. + inline const location operator+ (const location& begin, unsigned int width) + { + location res = begin; + res.columns (width); + return res; + } + + /// Add and assign a location. + inline location& operator+= (location& res, unsigned int width) + { + res.columns (width); + return res; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param loc a reference to the location to redirect + ** + ** Avoid duplicate information. + */ + inline std::ostream& operator<< (std::ostream& ostr, const location& loc) + { + position last = loc.end - 1; + ostr << loc.begin; + if (last.filename + && (!loc.begin.filename + || *loc.begin.filename != *last.filename)) + ostr << '-' << last; + else if (loc.begin.line != last.line) + ostr << '-' << last.line << '.' << last.column; + else if (loc.begin.column != last.column) + ostr << '-' << last.column; + return ostr; + } + +} + +#endif // not BISON_LOCATION_HH diff --git a/buildtools/lib/parsers/qmake/position.hh b/buildtools/lib/parsers/qmake/position.hh new file mode 100644 index 00000000..704f0df4 --- /dev/null +++ b/buildtools/lib/parsers/qmake/position.hh @@ -0,0 +1,142 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Positions for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/** + ** \file position.hh + ** Define the QMake::position class. + */ + +#ifndef BISON_POSITION_HH +# define BISON_POSITION_HH + +# include +# include + +namespace QMake +{ + /// Abstract a position. + class position + { + public: + + /// Construct a position. + position () + : filename (0), line (1), column (0) + { + } + + + /// Initialization. + inline void initialize (std::string* fn) + { + filename = fn; + line = 1; + column = 0; + } + + /** \name Line and Column related manipulators + ** \{ */ + public: + /// (line related) Advance to the COUNT next lines. + inline void lines (int count = 1) + { + column = 0; + line += count; + } + + /// (column related) Advance to the COUNT next columns. + inline void columns (int count = 1) + { + int leftmost = 0; + int current = column; + if (leftmost <= current + count) + column += count; + else + column = 0; + } + /** \} */ + + public: + /// File name to which this position refers. + std::string* filename; + /// Current line number. + unsigned int line; + /// Current column number. + unsigned int column; + }; + + /// Add and assign a position. + inline const position& + operator+= (position& res, const int width) + { + res.columns (width); + return res; + } + + /// Add two position objects. + inline const position + operator+ (const position& begin, const int width) + { + position res = begin; + return res += width; + } + + /// Add and assign a position. + inline const position& + operator-= (position& res, const int width) + { + return res += -width; + } + + /// Add two position objects. + inline const position + operator- (const position& begin, const int width) + { + return begin + -width; + } + + /** \brief Intercept output stream redirection. + ** \param ostr the destination output stream + ** \param pos a reference to the position to redirect + */ + inline std::ostream& + operator<< (std::ostream& ostr, const position& pos) + { + if (pos.filename) + ostr << *pos.filename << ':'; + return ostr << pos.line << '.' << pos.column; + } + +} +#endif // not BISON_POSITION_HH diff --git a/buildtools/lib/parsers/qmake/qmake.ll b/buildtools/lib/parsers/qmake/qmake.ll new file mode 100644 index 00000000..715d60b3 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake.ll @@ -0,0 +1,237 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#define DONT_INCLUDE_FLEXLEXER + +#include "qmake_lex.h" + +/** +@file qmake.ll +QMake Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ +%} + +%option noyywrap +%option yylineno +%option c++ +%option yyclass="QMake::Lexer" + +%x vallist +%x funcargs + +delim [ \t] +ws {delim}+ +newline (\n|\r|\r\n) +quote "\"" +var_value [^#\r\n\t ]*[^\r\n\t \\] +quoted_var_value {quote}({var_value}|[\t ])({var_value}|[\t ])*{quote} +letter [A-Za-z] +digit [0-9] +id_simple ({digit}|{letter}|\!|-|_|\*|\$)({letter}|{digit}|\||\!|-|_|\*|\$|\.|\+)* +id_args [^\r\n]*\) +number {digit}+ +comment #[^\r\n]*{newline} +comment_cont (\\{ws}*#[^\r\n]*{newline}|#[^\r\n]*\\{newline}) +cont \\{ws}*{newline} + +%% +<> { + BEGIN(INITIAL); + return Parser::token::token::ENDOFFILE; +} +{ws} {} + +{ws} { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::LIST_WS; +} + +{cont} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::CONT; +} + +{comment_cont} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COMMENT_CONT; +} + +{id_simple} { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::ID_SIMPLE); +} + +{id_args} { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + mylval->value = mylval->value.mid(0, mylval->value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (Parser::token::token::ID_ARGS); + } + +{var_value} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::VARIABLE_VALUE; +} + +{quoted_var_value} { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::QUOTED_VARIABLE_VALUE; +} + +"=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::EQ; +} + +"+=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::PLUSEQ; +} + +"-=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::MINUSEQ; +} + +"*=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::STAREQ; +} + +"~=" { + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::TILDEEQ; +} + +"{" { + return Parser::token::token::LCURLY; +} + +":"{delim}*"{" { + return Parser::token::token::LCURLY; +} + +"}" { + return Parser::token::token::RCURLY; +} + +"(" { + BEGIN(funcargs); + return Parser::token::token::LBRACE; +} + +")" { + BEGIN(INITIAL); + return Parser::token::token::RBRACE; +} + +":" { + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COLON; +} + + +{ws}{newline} { + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + +{newline} { + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + +{comment} { + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::COMMENT); +} + +%% +namespace QMake +{ + Lexer::Lexer( std::istream* argin, std::ostream* argout ) + : yyFlexLexer(argin, argout), mylval(0), m_lineEnding(None) + { + } + + int Lexer::yylex( QMake::Parser::semantic_type* yylval ) + { + mylval = yylval; + return yylex(); + } + + void Lexer::setLineEndingFromString( const QString& str ) + { + if( str.endsWith("\r\n") && m_lineEnding == None ) + m_lineEnding = Windows; + else if ( str.endsWith("\r") && m_lineEnding == None ) + m_lineEnding = MacOS; + else if ( m_lineEnding == None ) + m_lineEnding = Unix; + } + + Lexer::LineEnding Lexer::lineending() + { + return m_lineEnding; + } +} + +int QMakelex( QMake::Parser::semantic_type* yylval, QMake::Lexer* lexer) +{ + return lexer->yylex( yylval ); +} + diff --git a/buildtools/lib/parsers/qmake/qmake.yy b/buildtools/lib/parsers/qmake/qmake.yy new file mode 100644 index 00000000..9e6d378a --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake.yy @@ -0,0 +1,430 @@ +%{ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * Copyright (C) 2006 by Andreas Pakulat * + * apaku@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +QMake Parser + +Simple LALR parser which builds the syntax tree (see @ref QMake::AST). + +@todo Recognize comments after statements like: +SOURCES = foo #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include +#include "qmakeast.h" +#include + +#define YYSTYPE_IS_DECLARED + +namespace QMake +{ + class Lexer; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in .pro file: + @code + SOURCE = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: +
+    foo1.cpp
+    foo2.cpp
+    foo3.cpp foo4.cpp
+    
+ */ + QStringList values; + QString indent; +}; + +#define YYSTYPE Result +typedef Result YYSTYPE; +} + +extern int QMakelex( QMake::Result* yylval, QMake::Lexer* lexer ); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +//QValueStack projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +// int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ +%} + +%skeleton "lalr1.cc" +%define "parser_class_name" "Parser" +%name-prefix="QMake" +%parse-param { QMake::Lexer* lexer } +%parse-param { QValueStack& projects } +%parse-param { int depth } +%lex-param { QMake::Lexer* lexer } +%start project + +%token ID_SIMPLE +%token EQ +%token PLUSEQ +%token MINUSEQ +%token STAREQ +%token TILDEEQ +%token LBRACE +%token RBRACE +%token COLON +%token NEWLINE +%token COMMENT +%token CONT +%token COMMENT_CONT +%token RCURLY +%token LCURLY +%token ID_ARGS +%token QUOTED_VARIABLE_VALUE +%token VARIABLE_VALUE +%token LIST_WS +%token ENDOFFILE +%% + +project : + { + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); + } + statements + ; + +statements : statements statement + { + projects.top()->addChildAST($2); + $2->setDepth(depth); + } + | + ; + +statement : variable_assignment + { + $$ = $1; + } + | scope + { + $$ = $1; + } + | function_call + { + $$ = $1; + } + | comment + { + $$ = $1; + } + | emptyline + { + $$ = new NewLineAST(); + } + ; + +variable_assignment : ID_SIMPLE operator multiline_values listws NEWLINE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values = $3 ; + node->values.append( $4 ); + node->values.append( $5 ); + node->indent = $3; + $$ = node; + } + | ID_SIMPLE operator multiline_values listws ENDOFFILE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values = $3 ; + node->values.append( $4 ); + node->indent = $3; + $$ = node; + } + | ID_SIMPLE operator multiline_values listws CONT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values = $3 ; + node->values.append( $4 ); + node->values.append( $5 ); + node->indent = $3; + $$ = node; + } + | ID_SIMPLE operator multiline_values listws COMMENT_CONT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values = $3 ; + node->values.append( $4 ); + node->values.append( $5 ); + node->indent = $3; + $$ = node; + } + | ID_SIMPLE operator listws NEWLINE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values.append( $3 ); + node->values.append( $4 ); + $$ = node; + } + | ID_SIMPLE operator listws ENDOFFILE + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values.append( $3 ); + $$ = node; + } + | ID_SIMPLE operator listws COMMENT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values.append( $3 ); + node->values.append( $4 ); + $$ = node; + } + | ID_SIMPLE operator multiline_values listws COMMENT + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = $1; + node->op = $2; + node->values = $3; + node->values.append( $4 ); + node->values.append( $5 ); + node->indent = $3; + $$ = node; + } + ; + +possible_value : variable_value | COMMENT_CONT | CONT + +multiline_values : multiline_values LIST_WS possible_value + { + $$.append( $2 ); + $$.append( $3 ); + } + | multiline_values variable_value + { + $$.append( $2 ); + } + | multiline_values listws CONT listws possible_value + { + $$.append( $2 ); + $$.append( $3 ); + $$.append( $4 ); + $$.append( $5 ); + if( $4 != "" && $$ == "" ) + $$ = $4; + } + | multiline_values listws COMMENT_CONT listws possible_value + { + $$.append( $2 ); + $$.append( $3 ); + $$.append( $4 ); + $$.append( $5 ); + if( $4 != "" && $$ == "" ) + $$ = $4; + } + | listws possible_value + { + $$ = QStringList(); + $$.append( $1 ); + $$.append( $2 ); + } + ; + + +variable_value : VARIABLE_VALUE { $$ = $1; } + | QUOTED_VARIABLE_VALUE { $$ = $1; } + ; + + +listws: LIST_WS + { + $$ = $1; + $$ = $1; + } + | + { + $$ = QString(); + $$ = QString(); + } + ; +operator : EQ + { + $$ = $1; + } + | PLUSEQ + { + $$ = $1; + } + | MINUSEQ + { + $$ = $1; + } + | STAREQ + { + $$ = $1; + } + | TILDEEQ + { + $$ = $1; + } + ; + +scope : ID_SIMPLE + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::Scope); + projects.push(projectAST); + projects.top()->scopedID = $1; + depth++; + } + scope_body + { + $$ = projects.pop(); + depth--; + } + ; + +function_call : ID_SIMPLE LBRACE function_args RBRACE + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = $1; + projects.top()->args = $3; + depth++; + + //qWarning("%s", $1.ascii()); + if ($1.contains("include")) + { + IncludeAST *includeAST = new IncludeAST(); + includeAST->projectName = $3; + projects.top()->addChildAST(includeAST); + includeAST->setDepth(depth); + } + } + scope_body + else_statement + { + $$ = projects.pop(); + depth--; + } + ; + +function_args : ID_ARGS { $$ = $1; } + | { $$ = ""; } + ; + +scope_body : LCURLY statements RCURLY + | COLON statement + { + projects.top()->addChildAST($2); + $2->setDepth(depth); + } + | + ; + +else_statement : "else" LCURLY + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = "else"; + projects.top()->args = ""; + depth++; + } + scope_body RCURLY + { + $$ = projects.pop(); + depth--; + } + | + { + $$ = new ProjectAST(); + } + ; + +comment : COMMENT + { + CommentAST *node = new CommentAST(); + node->comment = $1; + $$ = node; + } + ; + +emptyline : NEWLINE + ; + +%% + + +namespace QMake +{ + void Parser::error(const location_type& /*l*/, const std::string& m) + { + std::cerr << m << std::endl; + } +} diff --git a/buildtools/lib/parsers/qmake/qmake_lex.cpp b/buildtools/lib/parsers/qmake/qmake_lex.cpp new file mode 100644 index 00000000..b49677fe --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_lex.cpp @@ -0,0 +1,2239 @@ +#line 2 "qmake_lex.cpp" + +#line 4 "qmake_lex.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 33 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* %if-c++-only */ + /* The c++ scanner is a mess. The FlexLexer.h header file relies on the + * following macro. This is required in order to pass the c++-multiple-scanners + * test in the regression suite. We get reports that it breaks inheritance. + * We will address this in a future release of flex, or omit the C++ scanner + * altogether. + */ + #define yyFlexLexer yyFlexLexer +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +/* %if-c-only */ +/* %endif */ + +/* %if-tables-serialization */ +/* %endif */ +/* end standard C headers. */ + +/* %if-c-or-c++ */ +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have . Non-C99 systems may or may not. */ + +#if __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +/* %endif */ + +/* %if-c++-only */ +/* begin standard C++ headers. */ +#include +#include +#include +#include +/* end standard C++ headers. */ +/* %endif */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* %not-for-header */ + +/* Returned upon end-of-file. */ +#define YY_NULL 0 +/* %ok-for-header */ + +/* %not-for-header */ + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) +/* %ok-for-header */ + +/* %if-reentrant */ +/* %endif */ + +/* %if-not-reentrant */ + +/* %endif */ + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN (yy_start) = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START (((yy_start) - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +/* %if-not-reentrant */ +extern int yyleng; +/* %endif */ + +/* %if-c-only */ +/* %if-not-reentrant */ +/* %endif */ +/* %endif */ + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires + * access to the local variable yy_act. Since yyless() is a macro, it would break + * existing scanners that call yyless() from OUTSIDE yylex. + * One obvious solution it to make yy_act a global. I tried that, and saw + * a 5% performance hit in a non-yylineno scanner, because yy_act is + * normally declared as a register variable-- so it is not worth it. + */ + #define YY_LESS_LINENO(n) \ + do { \ + int yyl;\ + for ( yyl = n; yyl < yyleng; ++yyl )\ + if ( yytext[yyl] == '\n' )\ + --yylineno;\ + }while(0) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = (yy_hold_char); \ + YY_RESTORE_YY_MORE_OFFSET \ + (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, (yytext_ptr) ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { +/* %if-c-only */ +/* %endif */ + +/* %if-c++-only */ + std::istream* yy_input_file; +/* %endif */ + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +/* %if-not-reentrant */ +/* %endif */ +/* %ok-for-header */ + +/* %endif */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ + ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] + +/* %if-c-only Standard (non-C++) definition */ +/* %if-not-reentrant */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ +/* %endif */ + +void *yyalloc (yy_size_t ); +void *yyrealloc (void *,yy_size_t ); +void yyfree (void * ); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + yyensure_buffer_stack (); \ + YY_CURRENT_BUFFER_LVALUE = \ + yy_create_buffer( yyin, YY_BUF_SIZE ); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */ +/* Begin user sect3 */ + +#define yywrap() 1 +#define YY_SKIP_YYWRAP + +#define FLEX_DEBUG + +typedef unsigned char YY_CHAR; + +#define yytext_ptr yytext +#define YY_INTERACTIVE + +#include +int yyFlexLexer::yylex() + { + LexerError( "yyFlexLexer::yylex invoked but %option yyclass used" ); + return 0; + } + +#define YY_DECL int QMake::Lexer::yylex() + +/* %if-c-only Standard (non-C++) definition */ +/* %endif */ + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + (yytext_ptr) = yy_bp; \ +/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\ + yyleng = (size_t) (yy_cp - yy_bp); \ + (yy_hold_char) = *yy_cp; \ + *yy_cp = '\0'; \ +/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\ + (yy_c_buf_p) = yy_cp; + +/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ +#define YY_NUM_RULES 23 +#define YY_END_OF_BUFFER 24 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[76] = + { 0, + 0, 0, 0, 0, 0, 0, 24, 23, 1, 21, + 21, 5, 23, 17, 18, 5, 23, 5, 19, 9, + 23, 14, 16, 23, 7, 2, 7, 7, 23, 23, + 6, 1, 21, 5, 0, 22, 22, 0, 12, 10, + 11, 0, 15, 0, 3, 3, 0, 13, 7, 7, + 0, 2, 20, 20, 7, 0, 7, 0, 7, 0, + 6, 4, 4, 0, 4, 4, 7, 0, 7, 7, + 0, 0, 8, 0, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 6, 7, 8, 1, 1, 1, 9, + 10, 11, 12, 1, 13, 14, 1, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 16, 1, 1, + 17, 1, 1, 1, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 1, 19, 1, 1, 20, 1, 18, 18, 18, 18, + + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, + 18, 18, 21, 22, 23, 24, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[25] = + { 0, + 1, 2, 3, 3, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[85] = + { 0, + 0, 0, 23, 41, 28, 30, 132, 289, 126, 289, + 123, 56, 32, 289, 289, 106, 105, 104, 35, 289, + 77, 289, 289, 103, 34, 55, 47, 69, 87, 108, + 106, 111, 289, 0, 79, 289, 96, 82, 289, 289, + 289, 44, 289, 0, 289, 90, 59, 289, 68, 289, + 85, 93, 289, 74, 105, 123, 141, 98, 99, 45, + 42, 289, 47, 105, 289, 36, 159, 177, 195, 213, + 108, 231, 249, 112, 289, 268, 271, 274, 27, 277, + 279, 281, 284, 286 + } ; + +static yyconst flex_int16_t yy_def[85] = + { 0, + 75, 1, 76, 76, 77, 77, 75, 75, 75, 75, + 75, 75, 78, 75, 75, 12, 75, 12, 75, 75, + 75, 75, 75, 75, 79, 75, 80, 78, 79, 81, + 81, 75, 75, 12, 78, 75, 75, 78, 75, 75, + 75, 75, 75, 21, 75, 75, 82, 75, 79, 75, + 79, 75, 75, 75, 83, 84, 84, 80, 82, 81, + 81, 75, 75, 82, 75, 75, 83, 84, 83, 84, + 83, 84, 84, 84, 0, 75, 75, 75, 75, 75, + 75, 75, 75, 75 + } ; + +static yyconst flex_int16_t yy_nxt[314] = + { 0, + 8, 9, 10, 11, 12, 8, 13, 12, 14, 15, + 16, 17, 18, 8, 12, 19, 20, 12, 21, 12, + 22, 8, 23, 24, 26, 10, 11, 49, 27, 28, + 8, 8, 8, 8, 36, 37, 42, 31, 65, 31, + 50, 29, 26, 10, 11, 42, 27, 28, 56, 62, + 38, 61, 51, 57, 61, 43, 52, 53, 54, 29, + 34, 65, 66, 34, 43, 58, 34, 34, 34, 34, + 34, 36, 37, 34, 50, 34, 53, 34, 44, 45, + 46, 36, 37, 47, 62, 63, 51, 38, 44, 45, + 46, 50, 45, 59, 52, 53, 54, 38, 36, 75, + + 38, 65, 66, 51, 57, 51, 68, 65, 66, 75, + 69, 70, 32, 75, 70, 61, 58, 61, 68, 48, + 41, 40, 39, 71, 68, 33, 71, 32, 73, 68, + 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 74, 68, 75, 75, 75, 73, 68, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 74, + 68, 75, 75, 75, 69, 70, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 71, 68, 75, + 75, 75, 73, 68, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 74, 68, 75, 75, 75, + + 69, 70, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75, 71, 68, 75, 75, 75, 73, 68, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 74, 68, 75, 75, 75, 73, 68, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 74, + 68, 75, 75, 75, 73, 68, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 74, 25, 25, + 25, 30, 30, 30, 35, 35, 35, 55, 55, 60, + 60, 64, 64, 64, 67, 67, 72, 72, 7, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75 + } ; + +static yyconst flex_int16_t yy_chk[314] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 3, 3, 79, 3, 3, + 5, 5, 6, 6, 13, 13, 19, 5, 66, 6, + 25, 3, 4, 4, 4, 42, 4, 4, 27, 63, + 13, 61, 25, 27, 60, 19, 26, 26, 26, 4, + 12, 47, 47, 12, 42, 27, 12, 12, 12, 12, + 12, 28, 28, 12, 49, 12, 54, 12, 21, 21, + 21, 35, 35, 21, 38, 38, 49, 28, 29, 29, + 29, 51, 46, 29, 52, 52, 52, 35, 37, 58, + + 38, 59, 59, 51, 58, 29, 55, 64, 64, 71, + 55, 55, 32, 74, 71, 31, 58, 30, 74, 24, + 18, 17, 16, 55, 56, 11, 71, 9, 56, 56, + 74, 7, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 56, 57, 0, 0, 0, 57, 57, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 57, + 67, 0, 0, 0, 67, 67, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 67, 68, 0, + 0, 0, 68, 68, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 68, 69, 0, 0, 0, + + 69, 69, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 69, 70, 0, 0, 0, 70, 70, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 70, 72, 0, 0, 0, 72, 72, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 72, + 73, 0, 0, 0, 73, 73, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 73, 76, 76, + 76, 77, 77, 77, 78, 78, 78, 80, 80, 81, + 81, 82, 82, 82, 83, 83, 84, 84, 75, 75, + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + + 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, + 75, 75, 75 + } ; + +/* Table of booleans, true if rule could match eol. */ +static yyconst flex_int32_t yy_rule_can_match_eol[24] = + { 0, +0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 0, }; + +static yyconst flex_int16_t yy_rule_linenum[23] = + { 0, + 81, 83, 88, 94, 100, 105, 113, 119, 125, 131, + 137, 143, 149, 155, 159, 163, 167, 172, 177, 183, + 190, 197 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +#line 1 "qmake.ll" +#line 2 "qmake.ll" +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include + +#define DONT_INCLUDE_FLEXLEXER + +#include "qmake_lex.h" + +/** +@file qmake.ll +QMake Lexer + +There are 3 types of identifiers recognized by this lexer: +-id_simple: examples of such identifiers are qmake variables and scoped variables +at the left of the operator in assignments (like "SOURCES" in "SOURCES+=foo.cpp goo.cpp"); +-id_list: those are "value list identifiers" at the right side in assignments +(like "foo.cpp goo.cpp" in "SOURCES+=foo.cpp goo.cpp"); +-id_args: function arguments recognized as one identifier +(example: ""${QMAKE_FILE} is intended only for Windows!"" +in "!win32-*:!wince-*:error("${QMAKE_FILE} is intended only for Windows!")" statements). +. + +To recognize those identifiers two additional start conditions are used: list and funcargs. + +@note "Not" operator (!) is recognized as a part of an identifier. Linefeeds passed to +the parser as NEWLINE tokens to preserve file structure but whitespaces are stripped +so no indentation is preserved by this lexer (and parser). + +To debug this lexer, put the line below into the next flex file section. +%option debug +*/ + + +#line 657 "qmake_lex.cpp" + +#define INITIAL 0 +#define vallist 1 +#define funcargs 2 + +#ifndef YY_NO_UNISTD_H +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +#include +/* %endif */ +#endif + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* %if-c-only Reentrant structure and macros (non-C++). */ +/* %if-reentrant */ +/* %if-c-only */ +/* %endif */ +/* %if-reentrant */ +/* %endif */ +/* %if-bison-bridge */ +/* %endif */ +/* %endif End reentrant structures and macros. */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ); +#endif + +#ifndef YY_NO_INPUT +/* %if-c-only Standard (non-C++) definition */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %endif */ +#endif + +/* %if-c-only */ +/* %endif */ + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* %if-c-only Standard (non-C++) definition */ +/* %endif */ +/* %if-c++-only C++ definition */ +#define ECHO LexerOutput( yytext, yyleng ) +/* %endif */ +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ +/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\ +\ +/* %if-c++-only C++ definition \ */\ + if ( (result = LexerInput( (char *) buf, max_size )) < 0 ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +/* %endif */ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +#define YY_FATAL_ERROR(msg) LexerError( msg ) +/* %endif */ +#endif + +/* %if-tables-serialization structures and prototypes */ +/* %not-for-header */ + +/* %ok-for-header */ + +/* %not-for-header */ + +/* %tables-yydmap generated elements */ +/* %endif */ +/* end tables serialization structures and prototypes */ + +/* %ok-for-header */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 +/* %if-c-only Standard (non-C++) definition */ +/* %endif */ +/* %if-c++-only C++ definition */ +#define YY_DECL int yyFlexLexer::yylex() +/* %endif */ +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +/* %% [6.0] YY_RULE_SETUP definition goes here */ +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/* %not-for-header */ + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +/* %% [7.0] user's declarations go here */ +#line 76 "qmake.ll" + +#line 818 "qmake_lex.cpp" + + if ( !(yy_init) ) + { + (yy_init) = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! (yy_start) ) + (yy_start) = 1; /* first start state */ + + if ( ! yyin ) +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + yyin = & std::cin; +/* %endif */ + + if ( ! yyout ) +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + yyout = & std::cout; +/* %endif */ + + if ( ! YY_CURRENT_BUFFER ) { + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_load_buffer_state( ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { +/* %% [8.0] yymore()-related code goes here */ + yy_cp = (yy_c_buf_p); + + /* Support of yytext. */ + *yy_cp = (yy_hold_char); + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + +/* %% [9.0] code to set up and find next match goes here */ + yy_current_state = (yy_start); +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 289 ); + +yy_find_action: +/* %% [10.0] code to find the action number goes here */ + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + +/* %% [11.0] code for yylineno update goes here */ + + if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] ) + { + int yyl; + for ( yyl = 0; yyl < yyleng; ++yyl ) + if ( yytext[yyl] == '\n' ) + + yylineno++; +; + } + +do_action: /* This label is used only to access EOF actions. */ + +/* %% [12.0] debug code goes here */ + if ( yy_flex_debug ) + { + if ( yy_act == 0 ) + std::cerr << "--scanner backing up\n"; + else if ( yy_act < 23 ) + std::cerr << "--accepting rule at line " << yy_rule_linenum[yy_act] << + "(\"" << yytext << "\")\n"; + else if ( yy_act == 23 ) + std::cerr << "--accepting default rule (\"" << yytext << "\")\n"; + else if ( yy_act == 24 ) + std::cerr << "--(end of buffer or a NUL)\n"; + else + std::cerr << "--EOF (start condition " << YY_START << ")\n"; + } + + switch ( yy_act ) + { /* beginning of action switch */ +/* %% [13.0] actions go here */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = (yy_hold_char); + yy_cp = (yy_last_accepting_cpos); + yy_current_state = (yy_last_accepting_state); + goto yy_find_action; + +case YY_STATE_EOF(vallist): +#line 77 "qmake.ll" +{ + BEGIN(INITIAL); + return Parser::token::token::ENDOFFILE; +} + YY_BREAK +case 1: +YY_RULE_SETUP +#line 81 "qmake.ll" +{} + YY_BREAK +case 2: +YY_RULE_SETUP +#line 83 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::LIST_WS; +} + YY_BREAK +case 3: +/* rule 3 can match eol */ +YY_RULE_SETUP +#line 88 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::CONT; +} + YY_BREAK +case 4: +/* rule 4 can match eol */ +YY_RULE_SETUP +#line 94 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COMMENT_CONT; +} + YY_BREAK +case 5: +YY_RULE_SETUP +#line 100 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::ID_SIMPLE); +} + YY_BREAK +case 6: +YY_RULE_SETUP +#line 105 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + mylval->value = mylval->value.mid(0, mylval->value.length()-1); + unput(')'); + BEGIN(INITIAL); + return (Parser::token::token::ID_ARGS); + } + YY_BREAK +case 7: +YY_RULE_SETUP +#line 113 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::VARIABLE_VALUE; +} + YY_BREAK +case 8: +YY_RULE_SETUP +#line 119 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::QUOTED_VARIABLE_VALUE; +} + YY_BREAK +case 9: +YY_RULE_SETUP +#line 125 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::EQ; +} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 131 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::PLUSEQ; +} + YY_BREAK +case 11: +YY_RULE_SETUP +#line 137 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::MINUSEQ; +} + YY_BREAK +case 12: +YY_RULE_SETUP +#line 143 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::STAREQ; +} + YY_BREAK +case 13: +YY_RULE_SETUP +#line 149 "qmake.ll" +{ + BEGIN(vallist); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::TILDEEQ; +} + YY_BREAK +case 14: +YY_RULE_SETUP +#line 155 "qmake.ll" +{ + return Parser::token::token::LCURLY; +} + YY_BREAK +case 15: +YY_RULE_SETUP +#line 159 "qmake.ll" +{ + return Parser::token::token::LCURLY; +} + YY_BREAK +case 16: +YY_RULE_SETUP +#line 163 "qmake.ll" +{ + return Parser::token::token::RCURLY; +} + YY_BREAK +case 17: +YY_RULE_SETUP +#line 167 "qmake.ll" +{ + BEGIN(funcargs); + return Parser::token::token::LBRACE; +} + YY_BREAK +case 18: +YY_RULE_SETUP +#line 172 "qmake.ll" +{ + BEGIN(INITIAL); + return Parser::token::token::RBRACE; +} + YY_BREAK +case 19: +YY_RULE_SETUP +#line 177 "qmake.ll" +{ + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return Parser::token::token::COLON; +} + YY_BREAK +case 20: +/* rule 20 can match eol */ +YY_RULE_SETUP +#line 183 "qmake.ll" +{ + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + YY_BREAK +case 21: +/* rule 21 can match eol */ +YY_RULE_SETUP +#line 190 "qmake.ll" +{ + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + setLineEndingFromString( mylval->value ); + return Parser::token::token::NEWLINE; +} + YY_BREAK +case 22: +/* rule 22 can match eol */ +YY_RULE_SETUP +#line 197 "qmake.ll" +{ + BEGIN(INITIAL); + mylval->value = QString::fromLocal8Bit( YYText(), YYLeng() ); + return (Parser::token::token::COMMENT); +} + YY_BREAK +case 23: +YY_RULE_SETUP +#line 203 "qmake.ll" +ECHO; + YY_BREAK +#line 1145 "qmake_lex.cpp" +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(funcargs): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = (yy_hold_char); + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++(yy_c_buf_p); + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { +/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */ + yy_cp = (yy_c_buf_p); + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_END_OF_FILE: + { + (yy_did_buffer_switch_on_eof) = 0; + + if ( yywrap( ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = + (yytext_ptr) + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + (yy_c_buf_p) = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; + + yy_current_state = yy_get_previous_state( ); + + yy_cp = (yy_c_buf_p); + yy_bp = (yytext_ptr) + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of yylex */ +/* %ok-for-header */ + +/* %if-c++-only */ +/* %not-for-header */ + +yyFlexLexer::yyFlexLexer( std::istream* arg_yyin, std::ostream* arg_yyout ) +{ + yyin = arg_yyin; + yyout = arg_yyout; + yy_c_buf_p = 0; + yy_init = 0; + yy_start = 0; + yy_flex_debug = 0; + yylineno = 1; // this will only get updated if %option yylineno + + yy_did_buffer_switch_on_eof = 0; + + yy_looking_for_trail_begin = 0; + yy_more_flag = 0; + yy_more_len = 0; + yy_more_offset = yy_prev_more_offset = 0; + + yy_start_stack_ptr = yy_start_stack_depth = 0; + yy_start_stack = NULL; + + (yy_buffer_stack) = 0; + (yy_buffer_stack_top) = 0; + (yy_buffer_stack_max) = 0; + + yy_state_buf = 0; + +} + +void yyFlexLexer::switch_streams( std::istream* new_in, std::ostream* new_out ) +{ + if ( new_in ) + { + yy_delete_buffer( YY_CURRENT_BUFFER ); + yy_switch_to_buffer( yy_create_buffer( new_in, YY_BUF_SIZE ) ); + } + + if ( new_out ) + yyout = new_out; +} + +#ifdef YY_INTERACTIVE +int yyFlexLexer::LexerInput( char* buf, int /* max_size */ ) +#else +int yyFlexLexer::LexerInput( char* buf, int max_size ) +#endif +{ + if ( yyin->eof() || yyin->fail() ) + return 0; + +#ifdef YY_INTERACTIVE + yyin->get( buf[0] ); + + if ( yyin->eof() ) + return 0; + + if ( yyin->bad() ) + return -1; + + return 1; + +#else + (void) yyin->read( buf, max_size ); + + if ( yyin->bad() ) + return -1; + else + return yyin->gcount(); +#endif +} + +void yyFlexLexer::LexerOutput( const char* buf, int size ) +{ + (void) yyout->write( buf, size ); +} +/* %ok-for-header */ + +/* %endif */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +int yyFlexLexer::yy_get_next_buffer() +/* %endif */ +{ + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = (yytext_ptr); + register int number_to_move, i; + int ret_val; + + if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) ((yy_c_buf_p) - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + (yy_n_chars), (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + if ( (yy_n_chars) == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + (yy_n_chars) += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; + + (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +/* %if-c-only */ +/* %not-for-header */ + +/* %endif */ +/* %if-c++-only */ + yy_state_type yyFlexLexer::yy_get_previous_state() +/* %endif */ +{ + register yy_state_type yy_current_state; + register char *yy_cp; + +/* %% [15.0] code to get the start state into yy_current_state goes here */ + yy_current_state = (yy_start); + + for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) + { +/* %% [16.0] code to find the next state goes here */ + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + yy_state_type yyFlexLexer::yy_try_NUL_trans( yy_state_type yy_current_state ) +/* %endif */ +{ + register int yy_is_jam; + /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */ + register char *yy_cp = (yy_c_buf_p); + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + (yy_last_accepting_state) = yy_current_state; + (yy_last_accepting_cpos) = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 76 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 75); + + return yy_is_jam ? 0 : yy_current_state; +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yyunput( int c, register char* yy_bp) +/* %endif */ +{ + register char *yy_cp; + + yy_cp = (yy_c_buf_p); + + /* undo effects of setting up yytext */ + *yy_cp = (yy_hold_char); + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = (yy_n_chars) + 2; + register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ + YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; + register char *source = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; + + while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; + + if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + +/* %% [18.0] update yylineno here */ + + if ( c == '\n' ){ + --yylineno; + } + + (yytext_ptr) = yy_bp; + (yy_hold_char) = *yy_cp; + (yy_c_buf_p) = yy_cp; +} +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + int yyFlexLexer::yyinput() +/* %endif */ +{ + int c; + + *(yy_c_buf_p) = (yy_hold_char); + + if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) + /* This was really a NUL. */ + *(yy_c_buf_p) = '\0'; + + else + { /* need more input */ + int offset = (yy_c_buf_p) - (yytext_ptr); + ++(yy_c_buf_p); + + switch ( yy_get_next_buffer( ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap( ) ) + return EOF; + + if ( ! (yy_did_buffer_switch_on_eof) ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + (yy_c_buf_p) = (yytext_ptr) + offset; + break; + } + } + } + + c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ + *(yy_c_buf_p) = '\0'; /* preserve yytext */ + (yy_hold_char) = *++(yy_c_buf_p); + +/* %% [19.0] update BOL and yylineno */ + if ( c == '\n' ) + + yylineno++; +; + + return c; +} +/* %if-c-only */ +/* %endif */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * + * @note This function does not reset the start condition to @c INITIAL . + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yyrestart( std::istream* input_file ) +/* %endif */ +{ + + if ( ! YY_CURRENT_BUFFER ){ + yyensure_buffer_stack (); + YY_CURRENT_BUFFER_LVALUE = + yy_create_buffer( yyin, YY_BUF_SIZE ); + } + + yy_init_buffer( YY_CURRENT_BUFFER, input_file ); + yy_load_buffer_state( ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +/* %endif */ +{ + + /* TODO. We should be able to replace this entire function body + * with + * yypop_buffer_state(); + * yypush_buffer_state(new_buffer); + */ + yyensure_buffer_stack (); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + yy_load_buffer_state( ); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + (yy_did_buffer_switch_on_eof) = 1; +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_load_buffer_state() +/* %endif */ +{ + (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + (yy_hold_char) = *(yy_c_buf_p); +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * + * @return the allocated buffer state. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + YY_BUFFER_STATE yyFlexLexer::yy_create_buffer( std::istream* file, int size ) +/* %endif */ +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with yy_create_buffer() + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_delete_buffer( YY_BUFFER_STATE b ) +/* %endif */ +{ + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yyfree((void *) b->yy_ch_buf ); + + yyfree((void *) b ); +} + +/* %if-c-only */ +/* %endif */ + +/* %if-c++-only */ + +extern "C" int isatty (int ); + +/* %endif */ + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a yyrestart() or at EOF. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_init_buffer( YY_BUFFER_STATE b, std::istream* file ) +/* %endif */ + +{ + int oerrno = errno; + + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then yy_init_buffer was _probably_ + * called from yyrestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + b->yy_is_interactive = 0; +/* %endif */ + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_flush_buffer( YY_BUFFER_STATE b ) +/* %endif */ +{ + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + yy_load_buffer_state( ); +} + +/* %if-c-or-c++ */ +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::yypush_buffer_state (YY_BUFFER_STATE new_buffer) +/* %endif */ +{ + if (new_buffer == NULL) + return; + + yyensure_buffer_stack(); + + /* This block is copied from yy_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *(yy_c_buf_p) = (yy_hold_char); + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + (yy_buffer_stack_top)++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from yy_switch_to_buffer. */ + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; +} +/* %endif */ + +/* %if-c-or-c++ */ +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::yypop_buffer_state (void) +/* %endif */ +{ + if (!YY_CURRENT_BUFFER) + return; + + yy_delete_buffer(YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + if ((yy_buffer_stack_top) > 0) + --(yy_buffer_stack_top); + + if (YY_CURRENT_BUFFER) { + yy_load_buffer_state( ); + (yy_did_buffer_switch_on_eof) = 1; + } +} +/* %endif */ + +/* %if-c-or-c++ */ +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::yyensure_buffer_stack(void) +/* %endif */ +{ + int num_to_alloc; + + if (!(yy_buffer_stack)) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + (yy_buffer_stack_max) = num_to_alloc; + (yy_buffer_stack_top) = 0; + return; + } + + if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = (yy_buffer_stack_max) + grow_size; + (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc + ((yy_buffer_stack), + num_to_alloc * sizeof(struct yy_buffer_state*) + ); + + /* zero only the new slots.*/ + memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); + (yy_buffer_stack_max) = num_to_alloc; + } +} +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_push_state( int new_state ) +/* %endif */ +{ + if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) ) + { + yy_size_t new_size; + + (yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = (yy_start_stack_depth) * sizeof( int ); + + if ( ! (yy_start_stack) ) + (yy_start_stack) = (int *) yyalloc(new_size ); + + else + (yy_start_stack) = (int *) yyrealloc((void *) (yy_start_stack),new_size ); + + if ( ! (yy_start_stack) ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START; + + BEGIN(new_state); +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + void yyFlexLexer::yy_pop_state() +/* %endif */ +{ + if ( --(yy_start_stack_ptr) < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN((yy_start_stack)[(yy_start_stack_ptr)]); +} + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ + int yyFlexLexer::yy_top_state() +/* %endif */ +{ + return (yy_start_stack)[(yy_start_stack_ptr) - 1]; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +void yyFlexLexer::LexerError( yyconst char msg[] ) +{ + std::cerr << msg << std::endl; + exit( YY_EXIT_FAILURE ); +} +/* %endif */ + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = (yy_hold_char); \ + (yy_c_buf_p) = yytext + yyless_macro_arg; \ + (yy_hold_char) = *(yy_c_buf_p); \ + *(yy_c_buf_p) = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/* %if-c-only */ +/* %if-reentrant */ +/* %endif */ +/* %if-reentrant */ +/* %endif */ +/* %endif */ + +/* %if-reentrant */ +/* %if-bison-bridge */ +/* %endif */ +/* %endif */ + +/* %if-c-only */ +/* %endif */ + +/* %if-c-or-c++ */ +/* %if-c-only */ +/* %endif */ +/* %if-c++-only */ +yyFlexLexer::~yyFlexLexer() +/* %endif */ +{ + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + yy_delete_buffer( YY_CURRENT_BUFFER ); + YY_CURRENT_BUFFER_LVALUE = NULL; + yypop_buffer_state(); + } + + /* Destroy the stack itself. */ + yyfree((yy_buffer_stack) ); + (yy_buffer_stack) = NULL; + +/* %if-c++-only */ + delete [] (yy_state_buf); + yyfree((yy_start_stack) ); +/* %endif */ + +/* %if-c-only */ +/* %if-reentrant */ +/* %endif */ +/* %endif */ +} +/* %endif */ + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s ) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *yyalloc (yy_size_t size ) +{ + return (void *) malloc( size ); +} + +void *yyrealloc (void * ptr, yy_size_t size ) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void yyfree (void * ptr ) +{ + free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ +} + +/* %if-tables-serialization definitions */ +/* %define-yytables The name for this specific scanner's tables. */ +#define YYTABLES_NAME "yytables" +/* %endif */ + +/* %ok-for-header */ + +#line 203 "qmake.ll" + + +namespace QMake +{ + Lexer::Lexer( std::istream* argin, std::ostream* argout ) + : yyFlexLexer(argin, argout), mylval(0), m_lineEnding(None) + { + } + + int Lexer::yylex( QMake::Parser::semantic_type* yylval ) + { + mylval = yylval; + return yylex(); + } + + void Lexer::setLineEndingFromString( const QString& str ) + { + if( str.endsWith("\r\n") && m_lineEnding == None ) + m_lineEnding = Windows; + else if ( str.endsWith("\r") && m_lineEnding == None ) + m_lineEnding = MacOS; + else if ( m_lineEnding == None ) + m_lineEnding = Unix; + } + + Lexer::LineEnding Lexer::lineending() + { + return m_lineEnding; + } +} + +int QMakelex( QMake::Parser::semantic_type* yylval, QMake::Lexer* lexer) +{ + return lexer->yylex( yylval ); +} + + diff --git a/buildtools/lib/parsers/qmake/qmake_lex.h b/buildtools/lib/parsers/qmake/qmake_lex.h new file mode 100644 index 00000000..1b91e747 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_lex.h @@ -0,0 +1,49 @@ +/* KDevelop QMake Support + * + * Copyright 2007 Andreas Pakulat + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ +#ifndef QMAKE_LEX_H +#define QMAKE_LEX_H + +#include "qmake_yacc.hpp" +#include + +#ifndef DONT_INCLUDE_FLEXLEXER +#include "FlexLexer.h" +#endif + +namespace QMake +{ + class Lexer : public yyFlexLexer + { + public: + enum LineEnding{ None, Unix, MacOS, Windows }; + Lexer( std::istream* argin = 0, std::ostream* argout = 0 ); + int yylex( QMake::Parser::semantic_type* yylval ); + int yylex(); + void setLineEndingFromString( const QString& ); + LineEnding lineending(); + private: + QMake::Parser::semantic_type* mylval; + LineEnding m_lineEnding; + }; +} + +#endif + +// kate: space-indent on; indent-width 4; tab-width: 4; replace-tabs on; auto-insert-doxygen on diff --git a/buildtools/lib/parsers/qmake/qmake_yacc.cpp b/buildtools/lib/parsers/qmake/qmake_yacc.cpp new file mode 100644 index 00000000..9cd09ebe --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_yacc.cpp @@ -0,0 +1,1243 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton implementation for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +// Take the name prefix into account. +#define yylex QMakelex + +#include "qmake_yacc.hpp" + +/* User implementation prologue. */ + + +/* Line 317 of lalr1.cc. */ +#line 45 "qmake_yacc.cpp" + +#ifndef YY_ +# if YYENABLE_NLS +# if ENABLE_NLS +# include /* FIXME: INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#define YYUSE(e) ((void) (e)) + +/* A pseudo ostream that takes yydebug_ into account. */ +# define YYCDEBUG \ + for (bool yydebugcond_ = yydebug_; yydebugcond_; yydebugcond_ = false) \ + (*yycdebug_) + +/* Enable debugging if requested. */ +#if YYDEBUG + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug_) \ + { \ + *yycdebug_ << Title << ' '; \ + yy_symbol_print_ ((Type), (Value), (Location)); \ + *yycdebug_ << std::endl; \ + } \ +} while (false) + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug_) \ + yy_reduce_print_ (Rule); \ +} while (false) + +# define YY_STACK_PRINT() \ +do { \ + if (yydebug_) \ + yystack_print_ (); \ +} while (false) + +#else /* !YYDEBUG */ + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_REDUCE_PRINT(Rule) +# define YY_STACK_PRINT() + +#endif /* !YYDEBUG */ + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + +namespace QMake +{ +#if YYERROR_VERBOSE + + /* Return YYSTR after stripping away unnecessary quotes and + backslashes, so that it's suitable for yyerror. The heuristic is + that double-quoting is unnecessary unless the string contains an + apostrophe, a comma, or backslash (other than backslash-backslash). + YYSTR is taken from yytname. */ + std::string + Parser::yytnamerr_ (const char *yystr) + { + if (*yystr == '"') + { + std::string yyr = ""; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + yyr += *yyp; + break; + + case '"': + return yyr; + } + do_not_strip_quotes: ; + } + + return yystr; + } + +#endif + + /// Build a parser object. + Parser::Parser (QMake::Lexer* lexer_yyarg, QValueStack& projects_yyarg, int depth_yyarg) + : yydebug_ (false), + yycdebug_ (&std::cerr), + lexer (lexer_yyarg), + projects (projects_yyarg), + depth (depth_yyarg) + { + } + + Parser::~Parser () + { + } + +#if YYDEBUG + /*--------------------------------. + | Print this symbol on YYOUTPUT. | + `--------------------------------*/ + + inline void + Parser::yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yyvaluep); + switch (yytype) + { + default: + break; + } + } + + + void + Parser::yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, const location_type* yylocationp) + { + *yycdebug_ << (yytype < yyntokens_ ? "token" : "nterm") + << ' ' << yytname_[yytype] << " (" + << *yylocationp << ": "; + yy_symbol_value_print_ (yytype, yyvaluep, yylocationp); + *yycdebug_ << ')'; + } +#endif /* ! YYDEBUG */ + + void + Parser::yydestruct_ (const char* yymsg, + int yytype, semantic_type* yyvaluep, location_type* yylocationp) + { + YYUSE (yylocationp); + YYUSE (yymsg); + YYUSE (yyvaluep); + + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } + } + + void + Parser::yypop_ (unsigned int n) + { + yystate_stack_.pop (n); + yysemantic_stack_.pop (n); + yylocation_stack_.pop (n); + } + + std::ostream& + Parser::debug_stream () const + { + return *yycdebug_; + } + + void + Parser::set_debug_stream (std::ostream& o) + { + yycdebug_ = &o; + } + + + Parser::debug_level_type + Parser::debug_level () const + { + return yydebug_; + } + + void + Parser::set_debug_level (debug_level_type l) + { + yydebug_ = l; + } + + + int + Parser::parse () + { + /// Look-ahead and look-ahead in internal form. + int yychar = yyempty_; + int yytoken = 0; + + /* State. */ + int yyn; + int yylen = 0; + int yystate = 0; + + /* Error handling. */ + int yynerrs_ = 0; + int yyerrstatus_ = 0; + + /// Semantic value of the look-ahead. + semantic_type yylval; + /// Location of the look-ahead. + location_type yylloc; + /// The locations where the error started and ended. + location yyerror_range[2]; + + /// $$. + semantic_type yyval; + /// @$. + location_type yyloc; + + int yyresult; + + YYCDEBUG << "Starting parse" << std::endl; + + + /* Initialize the stacks. The initial state will be pushed in + yynewstate, since the latter expects the semantical and the + location values to have been already stored, initialize these + stacks with a primary value. */ + yystate_stack_ = state_stack_type (0); + yysemantic_stack_ = semantic_stack_type (0); + yylocation_stack_ = location_stack_type (0); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* New state. */ + yynewstate: + yystate_stack_.push (yystate); + YYCDEBUG << "Entering state " << yystate << std::endl; + goto yybackup; + + /* Backup. */ + yybackup: + + /* Try to take a decision without look-ahead. */ + yyn = yypact_[yystate]; + if (yyn == yypact_ninf_) + goto yydefault; + + /* Read a look-ahead token. */ + if (yychar == yyempty_) + { + YYCDEBUG << "Reading a token: "; + yychar = yylex (&yylval, lexer); + } + + + /* Convert token to internal form. */ + if (yychar <= yyeof_) + { + yychar = yytoken = yyeof_; + YYCDEBUG << "Now at end of input." << std::endl; + } + else + { + yytoken = yytranslate_ (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yytoken) + goto yydefault; + + /* Reduce or error. */ + yyn = yytable_[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == yytable_ninf_) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Accept? */ + if (yyn == yyfinal_) + goto yyacceptlab; + + /* Shift the look-ahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != yyeof_) + yychar = yyempty_; + + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yylloc); + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus_) + --yyerrstatus_; + + yystate = yyn; + goto yynewstate; + + /*-----------------------------------------------------------. + | yydefault -- do the default action for the current state. | + `-----------------------------------------------------------*/ + yydefault: + yyn = yydefact_[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + /*-----------------------------. + | yyreduce -- Do a reduction. | + `-----------------------------*/ + yyreduce: + yylen = yyr2_[yyn]; + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. Otherwise, use the top of the stack. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. */ + if (yylen) + yyval = yysemantic_stack_[yylen - 1]; + else + yyval = yysemantic_stack_[0]; + + { + slice slice (yylocation_stack_, yylen); + YYLLOC_DEFAULT (yyloc, slice, yylen); + } + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 144 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(); + projects.push(projectAST); + ;} + break; + + case 4: +#line 152 "qmake.yy" + { + projects.top()->addChildAST((yysemantic_stack_[(2) - (2)].node)); + (yysemantic_stack_[(2) - (2)].node)->setDepth(depth); + ;} + break; + + case 6: +#line 160 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 7: +#line 164 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 8: +#line 168 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 9: +#line 172 "qmake.yy" + { + (yyval.node) = (yysemantic_stack_[(1) - (1)].node); + ;} + break; + + case 10: +#line 176 "qmake.yy" + { + (yyval.node) = new NewLineAST(); + ;} + break; + + case 11: +#line 182 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 12: +#line 193 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 13: +#line 203 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 14: +#line 214 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values) ; + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 15: +#line 225 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(4) - (1)].value); + node->op = (yysemantic_stack_[(4) - (2)].value); + node->values.append( (yysemantic_stack_[(4) - (3)].value) ); + node->values.append( (yysemantic_stack_[(4) - (4)].value) ); + (yyval.node) = node; + ;} + break; + + case 16: +#line 234 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(4) - (1)].value); + node->op = (yysemantic_stack_[(4) - (2)].value); + node->values.append( (yysemantic_stack_[(4) - (3)].value) ); + (yyval.node) = node; + ;} + break; + + case 17: +#line 242 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(4) - (1)].value); + node->op = (yysemantic_stack_[(4) - (2)].value); + node->values.append( (yysemantic_stack_[(4) - (3)].value) ); + node->values.append( (yysemantic_stack_[(4) - (4)].value) ); + (yyval.node) = node; + ;} + break; + + case 18: +#line 251 "qmake.yy" + { + AssignmentAST *node = new AssignmentAST(); + node->scopedID = (yysemantic_stack_[(5) - (1)].value); + node->op = (yysemantic_stack_[(5) - (2)].value); + node->values = (yysemantic_stack_[(5) - (3)].values); + node->values.append( (yysemantic_stack_[(5) - (4)].value) ); + node->values.append( (yysemantic_stack_[(5) - (5)].value) ); + node->indent = (yysemantic_stack_[(5) - (3)].indent); + (yyval.node) = node; + ;} + break; + + case 22: +#line 266 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(3) - (2)].value) ); + (yyval.values).append( (yysemantic_stack_[(3) - (3)].value) ); + ;} + break; + + case 23: +#line 271 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(2) - (2)].value) ); + ;} + break; + + case 24: +#line 275 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(5) - (2)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (3)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (4)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (5)].value) ); + if( (yysemantic_stack_[(5) - (4)].indent) != "" && (yyval.indent) == "" ) + (yyval.indent) = (yysemantic_stack_[(5) - (4)].indent); + ;} + break; + + case 25: +#line 284 "qmake.yy" + { + (yyval.values).append( (yysemantic_stack_[(5) - (2)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (3)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (4)].value) ); + (yyval.values).append( (yysemantic_stack_[(5) - (5)].value) ); + if( (yysemantic_stack_[(5) - (4)].indent) != "" && (yyval.indent) == "" ) + (yyval.indent) = (yysemantic_stack_[(5) - (4)].indent); + ;} + break; + + case 26: +#line 293 "qmake.yy" + { + (yyval.values) = QStringList(); + (yyval.values).append( (yysemantic_stack_[(2) - (1)].value) ); + (yyval.values).append( (yysemantic_stack_[(2) - (2)].value) ); + ;} + break; + + case 27: +#line 301 "qmake.yy" + { (yyval.value) = (yysemantic_stack_[(1) - (1)].value); ;} + break; + + case 28: +#line 302 "qmake.yy" + { (yyval.value) = (yysemantic_stack_[(1) - (1)].value); ;} + break; + + case 29: +#line 307 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + (yyval.indent) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 30: +#line 312 "qmake.yy" + { + (yyval.value) = QString(); + (yyval.indent) = QString(); + ;} + break; + + case 31: +#line 318 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 32: +#line 322 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 33: +#line 326 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 34: +#line 330 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 35: +#line 334 "qmake.yy" + { + (yyval.value) = (yysemantic_stack_[(1) - (1)].value); + ;} + break; + + case 36: +#line 340 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::Scope); + projects.push(projectAST); + projects.top()->scopedID = (yysemantic_stack_[(1) - (1)].value); + depth++; + ;} + break; + + case 37: +#line 347 "qmake.yy" + { + (yyval.node) = projects.pop(); + depth--; + ;} + break; + + case 38: +#line 354 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = (yysemantic_stack_[(4) - (1)].value); + projects.top()->args = (yysemantic_stack_[(4) - (3)].value); + depth++; + + //qWarning("%s", $1.ascii()); + if ((yysemantic_stack_[(4) - (1)].value).contains("include")) + { + IncludeAST *includeAST = new IncludeAST(); + includeAST->projectName = (yysemantic_stack_[(4) - (3)].value); + projects.top()->addChildAST(includeAST); + includeAST->setDepth(depth); + } + ;} + break; + + case 39: +#line 372 "qmake.yy" + { + (yyval.node) = projects.pop(); + depth--; + ;} + break; + + case 40: +#line 378 "qmake.yy" + { (yyval.value) = (yysemantic_stack_[(1) - (1)].value); ;} + break; + + case 41: +#line 379 "qmake.yy" + { (yyval.value) = ""; ;} + break; + + case 43: +#line 384 "qmake.yy" + { + projects.top()->addChildAST((yysemantic_stack_[(2) - (2)].node)); + (yysemantic_stack_[(2) - (2)].node)->setDepth(depth); + ;} + break; + + case 45: +#line 392 "qmake.yy" + { + ProjectAST *projectAST = new ProjectAST(ProjectAST::FunctionScope); + projects.push(projectAST); + projects.top()->scopedID = "else"; + projects.top()->args = ""; + depth++; + ;} + break; + + case 46: +#line 400 "qmake.yy" + { + (yyval.node) = projects.pop(); + depth--; + ;} + break; + + case 47: +#line 405 "qmake.yy" + { + (yyval.node) = new ProjectAST(); + ;} + break; + + case 48: +#line 411 "qmake.yy" + { + CommentAST *node = new CommentAST(); + node->comment = (yysemantic_stack_[(1) - (1)].value); + (yyval.node) = node; + ;} + break; + + + /* Line 675 of lalr1.cc. */ +#line 756 "qmake_yacc.cpp" + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1_[yyn], &yyval, &yyloc); + + yypop_ (yylen); + yylen = 0; + YY_STACK_PRINT (); + + yysemantic_stack_.push (yyval); + yylocation_stack_.push (yyloc); + + /* Shift the result of the reduction. */ + yyn = yyr1_[yyn]; + yystate = yypgoto_[yyn - yyntokens_] + yystate_stack_[0]; + if (0 <= yystate && yystate <= yylast_ + && yycheck_[yystate] == yystate_stack_[0]) + yystate = yytable_[yystate]; + else + yystate = yydefgoto_[yyn - yyntokens_]; + goto yynewstate; + + /*------------------------------------. + | yyerrlab -- here on detecting error | + `------------------------------------*/ + yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus_) + { + ++yynerrs_; + error (yylloc, yysyntax_error_ (yystate)); + } + + yyerror_range[0] = yylloc; + if (yyerrstatus_ == 3) + { + /* If just tried and failed to reuse look-ahead token after an + error, discard it. */ + + if (yychar <= yyeof_) + { + /* Return failure if at end of input. */ + if (yychar == yyeof_) + YYABORT; + } + else + { + yydestruct_ ("Error: discarding", yytoken, &yylval, &yylloc); + yychar = yyempty_; + } + } + + /* Else will try to reuse look-ahead token after shifting the error + token. */ + goto yyerrlab1; + + + /*---------------------------------------------------. + | yyerrorlab -- error raised explicitly by YYERROR. | + `---------------------------------------------------*/ + yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (false) + goto yyerrorlab; + + yyerror_range[0] = yylocation_stack_[yylen - 1]; + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + yypop_ (yylen); + yylen = 0; + yystate = yystate_stack_[0]; + goto yyerrlab1; + + /*-------------------------------------------------------------. + | yyerrlab1 -- common code for both syntax error and YYERROR. | + `-------------------------------------------------------------*/ + yyerrlab1: + yyerrstatus_ = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact_[yystate]; + if (yyn != yypact_ninf_) + { + yyn += yyterror_; + if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yyterror_) + { + yyn = yytable_[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yystate_stack_.height () == 1) + YYABORT; + + yyerror_range[0] = yylocation_stack_[0]; + yydestruct_ ("Error: popping", + yystos_[yystate], + &yysemantic_stack_[0], &yylocation_stack_[0]); + yypop_ (); + yystate = yystate_stack_[0]; + YY_STACK_PRINT (); + } + + if (yyn == yyfinal_) + goto yyacceptlab; + + yyerror_range[1] = yylloc; + // Using YYLLOC is tempting, but would change the location of + // the look-ahead. YYLOC is available though. + YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2); + yysemantic_stack_.push (yylval); + yylocation_stack_.push (yyloc); + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos_[yyn], + &yysemantic_stack_[0], &yylocation_stack_[0]); + + yystate = yyn; + goto yynewstate; + + /* Accept. */ + yyacceptlab: + yyresult = 0; + goto yyreturn; + + /* Abort. */ + yyabortlab: + yyresult = 1; + goto yyreturn; + + yyreturn: + if (yychar != yyeof_ && yychar != yyempty_) + yydestruct_ ("Cleanup: discarding lookahead", yytoken, &yylval, &yylloc); + + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + yypop_ (yylen); + while (yystate_stack_.height () != 1) + { + yydestruct_ ("Cleanup: popping", + yystos_[yystate_stack_[0]], + &yysemantic_stack_[0], + &yylocation_stack_[0]); + yypop_ (); + } + + return yyresult; + } + + // Generate an error message. + std::string + Parser::yysyntax_error_ (int yystate) + { + std::string res; + YYUSE (yystate); +#if YYERROR_VERBOSE + int yyn = yypact_[yystate]; + if (yypact_ninf_ < yyn && yyn <= yylast_) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = yylast_ - yyn + 1; + int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_; + int count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + ++count; + + // FIXME: This method of building the message is not compatible + // with internationalization. It should work like yacc.c does it. + // That is, first build a string that looks like this: + // "syntax error, unexpected %s or %s or %s" + // Then, invoke YY_ on this string. + // Finally, use the string as a format to output + // yytname_[tok], etc. + // Until this gets fixed, this message appears in English only. + res = "syntax error, unexpected "; + res += yytnamerr_ (yytname_[tok]); + if (count < 5) + { + count = 0; + for (int x = yyxbegin; x < yyxend; ++x) + if (yycheck_[x + yyn] == x && x != yyterror_) + { + res += (!count++) ? ", expecting " : " or "; + res += yytnamerr_ (yytname_[x]); + } + } + } + else +#endif + res = YY_("syntax error"); + return res; + } + + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ + const signed char Parser::yypact_ninf_ = -44; + const signed char + Parser::yypact_[] = + { + -44, 19, -44, -44, 8, 45, -44, -44, -44, -44, + -44, -44, -44, -44, -44, -44, -44, -44, -44, 12, + 10, 31, -44, 24, -44, -15, -5, 8, -44, -44, + -44, -44, -44, 26, -44, 14, -44, -44, -44, -44, + -44, -44, -44, -44, 0, 31, -44, -44, -44, 18, + 18, -44, -44, 20, 26, 26, 27, -44, -44, -44, + -44, 31, 39, -44 + }; + + /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE + doesn't specify something else to do. Zero means the default is an + error. */ + const unsigned char + Parser::yydefact_[] = + { + 2, 0, 5, 1, 3, 36, 49, 48, 4, 6, + 7, 8, 9, 10, 31, 32, 33, 34, 35, 41, + 30, 44, 40, 0, 29, 30, 0, 0, 5, 37, + 38, 28, 27, 29, 23, 0, 15, 17, 21, 20, + 16, 26, 19, 43, 0, 44, 22, 11, 18, 13, + 14, 12, 42, 47, 0, 0, 0, 39, 24, 25, + 45, 44, 0, 46 + }; + + /* YYPGOTO[NTERM-NUM]. */ + const signed char + Parser::yypgoto_[] = + { + -44, -44, -44, 7, 29, -44, -32, -44, 22, -25, + -44, -44, -44, -44, -44, -44, -43, -44, -44, -44, + -44 + }; + + /* YYDEFGOTO[NTERM-NUM]. */ + const signed char + Parser::yydefgoto_[] = + { + -1, 1, 2, 4, 8, 9, 41, 25, 42, 26, + 20, 10, 21, 11, 45, 23, 29, 57, 61, 12, + 13 + }; + + /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. */ + const signed char Parser::yytable_ninf_ = -31; + const signed char + Parser::yytable_[] = + { + 35, 46, 53, 5, 31, 32, 33, 36, 37, 38, + 39, 5, 6, 7, 31, 32, 52, 40, 62, 3, + 6, 7, 58, 59, 54, 55, 47, 48, 49, 50, + 22, 24, -30, -30, 30, 44, 51, -30, -30, 24, + 38, 39, 27, 56, 60, 31, 32, 34, 28, 14, + 15, 16, 17, 18, 19, 63, 43 + }; + + /* YYCHECK. */ + const unsigned char + Parser::yycheck_[] = + { + 25, 33, 45, 3, 19, 20, 21, 12, 13, 14, + 15, 3, 12, 13, 19, 20, 16, 22, 61, 0, + 12, 13, 54, 55, 49, 50, 12, 13, 14, 15, + 18, 21, 14, 15, 10, 28, 22, 19, 20, 21, + 14, 15, 11, 23, 17, 19, 20, 25, 17, 4, + 5, 6, 7, 8, 9, 16, 27 + }; + + /* STOS_[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ + const unsigned char + Parser::yystos_[] = + { + 0, 25, 26, 0, 27, 3, 12, 13, 28, 29, + 35, 37, 43, 44, 4, 5, 6, 7, 8, 9, + 34, 36, 18, 39, 21, 31, 33, 11, 17, 40, + 10, 19, 20, 21, 32, 33, 12, 13, 14, 15, + 22, 30, 32, 28, 27, 38, 30, 12, 13, 14, + 15, 22, 16, 40, 33, 33, 23, 41, 30, 30, + 17, 42, 40, 16 + }; + +#if YYDEBUG + /* TOKEN_NUMBER_[YYLEX-NUM] -- Internal symbol number corresponding + to YYLEX-NUM. */ + const unsigned short int + Parser::yytoken_number_[] = + { + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278 + }; +#endif + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ + const unsigned char + Parser::yyr1_[] = + { + 0, 24, 26, 25, 27, 27, 28, 28, 28, 28, + 28, 29, 29, 29, 29, 29, 29, 29, 29, 30, + 30, 30, 31, 31, 31, 31, 31, 32, 32, 33, + 33, 34, 34, 34, 34, 34, 36, 35, 38, 37, + 39, 39, 40, 40, 40, 42, 41, 41, 43, 44 + }; + + /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ + const unsigned char + Parser::yyr2_[] = + { + 0, 2, 0, 2, 2, 0, 1, 1, 1, 1, + 1, 5, 5, 5, 5, 4, 4, 4, 5, 1, + 1, 1, 3, 2, 5, 5, 2, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 0, 3, 0, 7, + 1, 0, 3, 2, 0, 0, 5, 0, 1, 1 + }; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at \a yyntokens_, nonterminals. */ + const char* + const Parser::yytname_[] = + { + "$end", "error", "$undefined", "ID_SIMPLE", "EQ", "PLUSEQ", "MINUSEQ", + "STAREQ", "TILDEEQ", "LBRACE", "RBRACE", "COLON", "NEWLINE", "COMMENT", + "CONT", "COMMENT_CONT", "RCURLY", "LCURLY", "ID_ARGS", + "QUOTED_VARIABLE_VALUE", "VARIABLE_VALUE", "LIST_WS", "ENDOFFILE", + "\"else\"", "$accept", "project", "@1", "statements", "statement", + "variable_assignment", "possible_value", "multiline_values", + "variable_value", "listws", "operator", "scope", "@2", "function_call", + "@3", "function_args", "scope_body", "else_statement", "@4", "comment", + "emptyline", 0 + }; +#endif + +#if YYDEBUG + /* YYRHS -- A `-1'-separated list of the rules' RHS. */ + const Parser::rhs_number_type + Parser::yyrhs_[] = + { + 25, 0, -1, -1, 26, 27, -1, 27, 28, -1, + -1, 29, -1, 35, -1, 37, -1, 43, -1, 44, + -1, 3, 34, 31, 33, 12, -1, 3, 34, 31, + 33, 22, -1, 3, 34, 31, 33, 14, -1, 3, + 34, 31, 33, 15, -1, 3, 34, 33, 12, -1, + 3, 34, 33, 22, -1, 3, 34, 33, 13, -1, + 3, 34, 31, 33, 13, -1, 32, -1, 15, -1, + 14, -1, 31, 21, 30, -1, 31, 32, -1, 31, + 33, 14, 33, 30, -1, 31, 33, 15, 33, 30, + -1, 33, 30, -1, 20, -1, 19, -1, 21, -1, + -1, 4, -1, 5, -1, 6, -1, 7, -1, 8, + -1, -1, 3, 36, 40, -1, -1, 3, 9, 39, + 10, 38, 40, 41, -1, 18, -1, -1, 17, 27, + 16, -1, 11, 28, -1, -1, -1, 23, 17, 42, + 40, 16, -1, -1, 13, -1, 12, -1 + }; + + /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ + const unsigned char + Parser::yyprhs_[] = + { + 0, 0, 3, 4, 7, 10, 11, 13, 15, 17, + 19, 21, 27, 33, 39, 45, 50, 55, 60, 66, + 68, 70, 72, 76, 79, 85, 91, 94, 96, 98, + 100, 101, 103, 105, 107, 109, 111, 112, 116, 117, + 125, 127, 128, 132, 135, 136, 137, 143, 144, 146 + }; + + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ + const unsigned short int + Parser::yyrline_[] = + { + 0, 144, 144, 144, 151, 156, 159, 163, 167, 171, + 175, 181, 192, 202, 213, 224, 233, 241, 250, 263, + 263, 263, 265, 270, 274, 283, 292, 301, 302, 306, + 312, 317, 321, 325, 329, 333, 340, 339, 354, 353, + 378, 379, 382, 383, 388, 392, 391, 405, 410, 418 + }; + + // Print the state stack on the debug stream. + void + Parser::yystack_print_ () + { + *yycdebug_ << "Stack now"; + for (state_stack_type::const_iterator i = yystate_stack_.begin (); + i != yystate_stack_.end (); ++i) + *yycdebug_ << ' ' << *i; + *yycdebug_ << std::endl; + } + + // Report on the debug stream that the rule \a yyrule is going to be reduced. + void + Parser::yy_reduce_print_ (int yyrule) + { + unsigned int yylno = yyrline_[yyrule]; + int yynrhs = yyr2_[yyrule]; + /* Print the symbols being reduced, and their result. */ + *yycdebug_ << "Reducing stack by rule " << yyrule - 1 + << " (line " << yylno << "), "; + /* The symbols being reduced. */ + for (int yyi = 0; yyi < yynrhs; yyi++) + YY_SYMBOL_PRINT (" $" << yyi + 1 << " =", + yyrhs_[yyprhs_[yyrule] + yyi], + &(yysemantic_stack_[(yynrhs) - (yyi + 1)]), + &(yylocation_stack_[(yynrhs) - (yyi + 1)])); + } +#endif // YYDEBUG + + /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ + Parser::token_number_type + Parser::yytranslate_ (int t) + { + static + const token_number_type + translate_table[] = + { + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23 + }; + if ((unsigned int) t <= yyuser_token_number_max_) + return translate_table[t]; + else + return yyundef_token_; + } + + const int Parser::yyeof_ = 0; + const int Parser::yylast_ = 56; + const int Parser::yynnts_ = 21; + const int Parser::yyempty_ = -2; + const int Parser::yyfinal_ = 3; + const int Parser::yyterror_ = 1; + const int Parser::yyerrcode_ = 256; + const int Parser::yyntokens_ = 24; + + const unsigned int Parser::yyuser_token_number_max_ = 278; + const Parser::token_number_type Parser::yyundef_token_ = 2; + +} // namespace QMake + +#line 421 "qmake.yy" + + + +namespace QMake +{ + void Parser::error(const location_type& /*l*/, const std::string& m) + { + std::cerr << m << std::endl; + } +} + diff --git a/buildtools/lib/parsers/qmake/qmake_yacc.hpp b/buildtools/lib/parsers/qmake/qmake_yacc.hpp new file mode 100644 index 00000000..69b8a035 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmake_yacc.hpp @@ -0,0 +1,418 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Skeleton interface for Bison LALR(1) parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C++ LALR(1) parser skeleton written by Akim Demaille. */ + +#ifndef PARSER_HEADER_H +# define PARSER_HEADER_H + +#include +#include +#include "stack.hh" + +namespace QMake +{ + class position; + class location; +} + +/* First part of user declarations. */ +#line 1 "qmake.yy" + +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * Copyright (C) 2006 by Andreas Pakulat * + * apaku@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +/** +@file qmake.yy +QMake Parser + +Simple LALR parser which builds the syntax tree (see @ref QMake::AST). + +@todo Recognize comments after statements like: +SOURCES = foo #regognize me + +@fixme Parser fails on files that do not end with a newline +@fixme 1 shift/reduce conflict in "line_body" rule +*/ + +#include +#include "qmakeast.h" +#include + +#define YYSTYPE_IS_DECLARED + +namespace QMake +{ + class Lexer; + +/** +The yylval type. +*/ +struct Result { + Result(): node(0) {} + + /**Type of semantic value for simple grammar rules.*/ + QString value; + /**Type of semantic value for grammar rules which are parts of AST.*/ + AST *node; + /**Type of semantic value for "multiline_values" grammar rule. + Each line of multiline value is stored as a string in the list. + + For example we have in .pro file: + @code + SOURCE = foo1.cpp \ + foo2.cpp \ + foo3.cpp foo4.cpp + @endcode + The string list will be populated with three strings: +
+    foo1.cpp
+    foo2.cpp
+    foo3.cpp foo4.cpp
+    
+ */ + QStringList values; + QString indent; +}; + +#define YYSTYPE Result +typedef Result YYSTYPE; +} + +extern int QMakelex( QMake::Result* yylval, QMake::Lexer* lexer ); + +/** +The stack to store ProjectAST pointers when a new child +ProjectAST is created and filled with statements. + +Parser creates root ProjectAST for a .pro file, pushes it onto the stack and starts +adding statements. Each statement is added as a child StatementAST to the ProjectAST +currently on the top in the stack. + +When a scope or function scope statement is parsed, the child ProjectAST is created +and pushed onto the stack. Therefore all statements which belong to the scope +or function scope are added as childs to their direct parent (scope or function scope). +*/ +//QValueStack projects; + +/** +The current depth of AST node is stored here. +AST depth is important to know because automatic indentation can +be easily implemented (the parser itself looses all information +about indentation). +*/ +// int depth = 0; + +/* +To debug this parser, put the line below into the next bison file section. +Don't forget to uncomment "yydebug = 1" line in qmakedriver.cpp. +%debug +*/ + + +/* Line 35 of lalr1.cc. */ +#line 165 "qmake_yacc.hpp" + +#include "location.hh" + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 1 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 1 +#endif + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ +do { \ + if (N) \ + { \ + (Current).begin = (Rhs)[1].begin; \ + (Current).end = (Rhs)[N].end; \ + } \ + else \ + { \ + (Current).begin = (Current).end = (Rhs)[0].end; \ + } \ +} while (false) +#endif + +namespace QMake +{ + + /// A Bison parser. + class Parser + { + public: + /// Symbol semantic values. +#ifndef YYSTYPE + typedef int semantic_type; +#else + typedef YYSTYPE semantic_type; +#endif + /// Symbol locations. + typedef location location_type; + /// Tokens. + struct token + { + /* Tokens. */ + enum yytokentype { + ID_SIMPLE = 258, + EQ = 259, + PLUSEQ = 260, + MINUSEQ = 261, + STAREQ = 262, + TILDEEQ = 263, + LBRACE = 264, + RBRACE = 265, + COLON = 266, + NEWLINE = 267, + COMMENT = 268, + CONT = 269, + COMMENT_CONT = 270, + RCURLY = 271, + LCURLY = 272, + ID_ARGS = 273, + QUOTED_VARIABLE_VALUE = 274, + VARIABLE_VALUE = 275, + LIST_WS = 276, + ENDOFFILE = 277 + }; + + }; + /// Token type. + typedef token::yytokentype token_type; + + /// Build a parser object. + Parser (QMake::Lexer* lexer_yyarg, QValueStack& projects_yyarg, int depth_yyarg); + virtual ~Parser (); + + /// Parse. + /// \returns 0 iff parsing succeeded. + virtual int parse (); + + /// The current debugging stream. + std::ostream& debug_stream () const; + /// Set the current debugging stream. + void set_debug_stream (std::ostream &); + + /// Type for debugging levels. + typedef int debug_level_type; + /// The current debugging level. + debug_level_type debug_level () const; + /// Set the current debugging level. + void set_debug_level (debug_level_type l); + + private: + /// Report a syntax error. + /// \param loc where the syntax error is found. + /// \param msg a description of the syntax error. + virtual void error (const location_type& loc, const std::string& msg); + + /// Generate an error message. + /// \param state the state where the error occurred. + /// \param tok the look-ahead token. + virtual std::string yysyntax_error_ (int yystate); + +#if YYDEBUG + /// \brief Report a symbol value on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_value_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); + /// \brief Report a symbol on the debug stream. + /// \param yytype The token type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + virtual void yy_symbol_print_ (int yytype, + const semantic_type* yyvaluep, + const location_type* yylocationp); +#endif /* ! YYDEBUG */ + + + /// State numbers. + typedef int state_type; + /// State stack type. + typedef stack state_stack_type; + /// Semantic value stack type. + typedef stack semantic_stack_type; + /// location stack type. + typedef stack location_stack_type; + + /// The state stack. + state_stack_type yystate_stack_; + /// The semantic value stack. + semantic_stack_type yysemantic_stack_; + /// The location stack. + location_stack_type yylocation_stack_; + + /// Internal symbol numbers. + typedef unsigned char token_number_type; + /* Tables. */ + /// For a state, the index in \a yytable_ of its portion. + static const signed char yypact_[]; + static const signed char yypact_ninf_; + + /// For a state, default rule to reduce. + /// Unless\a yytable_ specifies something else to do. + /// Zero means the default is an error. + static const unsigned char yydefact_[]; + + static const signed char yypgoto_[]; + static const signed char yydefgoto_[]; + + /// What to do in a state. + /// \a yytable_[yypact_[s]]: what to do in state \a s. + /// - if positive, shift that token. + /// - if negative, reduce the rule which number is the opposite. + /// - if zero, do what YYDEFACT says. + static const signed char yytable_[]; + static const signed char yytable_ninf_; + + static const unsigned char yycheck_[]; + + /// For a state, its accessing symbol. + static const unsigned char yystos_[]; + + /// For a rule, its LHS. + static const unsigned char yyr1_[]; + /// For a rule, its RHS length. + static const unsigned char yyr2_[]; + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE + /// For a symbol, its name in clear. + static const char* const yytname_[]; +#endif + +#if YYERROR_VERBOSE + /// Convert the symbol name \a n to a form suitable for a diagnostic. + virtual std::string yytnamerr_ (const char *n); +#endif + +#if YYDEBUG + /// A type to store symbol numbers and -1. + typedef signed char rhs_number_type; + /// A `-1'-separated list of the rules' RHS. + static const rhs_number_type yyrhs_[]; + /// For each rule, the index of the first RHS symbol in \a yyrhs_. + static const unsigned char yyprhs_[]; + /// For each rule, its source line number. + static const unsigned short int yyrline_[]; + /// For each scanner token number, its symbol number. + static const unsigned short int yytoken_number_[]; + /// Report on the debug stream that the rule \a r is going to be reduced. + virtual void yy_reduce_print_ (int r); + /// Print the state stack on the debug stream. + virtual void yystack_print_ (); +#endif + + /// Convert a scanner token number \a t to a symbol number. + token_number_type yytranslate_ (int t); + + /// \brief Reclaim the memory associated to a symbol. + /// \param yymsg Why this token is reclaimed. + /// \param yytype The symbol type. + /// \param yyvaluep Its semantic value. + /// \param yylocationp Its location. + inline void yydestruct_ (const char* yymsg, + int yytype, + semantic_type* yyvaluep, + location_type* yylocationp); + + /// Pop \a n symbols the three stacks. + inline void yypop_ (unsigned int n = 1); + + /* Constants. */ + static const int yyeof_; + /* LAST_ -- Last index in TABLE_. */ + static const int yylast_; + static const int yynnts_; + static const int yyempty_; + static const int yyfinal_; + static const int yyterror_; + static const int yyerrcode_; + static const int yyntokens_; + static const unsigned int yyuser_token_number_max_; + static const token_number_type yyundef_token_; + + /* Debugging. */ + int yydebug_; + std::ostream* yycdebug_; + + + /* User arguments. */ + QMake::Lexer* lexer; + QValueStack& projects; + int depth; + }; +} + + +#endif /* ! defined PARSER_HEADER_H */ diff --git a/buildtools/lib/parsers/qmake/qmakeast.cpp b/buildtools/lib/parsers/qmake/qmakeast.cpp new file mode 100644 index 00000000..e6283e28 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeast.cpp @@ -0,0 +1,170 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qmakeast.h" + +#include + +namespace QMake { + +//AST + +AST::~AST() +{ + for (QValueList::iterator it = m_children.begin(); it != m_children.end(); ++it) + { + AST *node = *it; + delete node; + } + m_children.clear(); +} + +void AST::addChildAST(AST *node) +{ + m_children.append(node); +} + +void AST::removeChildAST(AST *node) +{ + m_children.remove(node); +} + +void AST::writeBack(QString &buffer) +{ + for (QValueList::const_iterator it = m_children.constBegin(); + it != m_children.constEnd(); ++it) + { + if (*it) + { + (*it)->writeBack(buffer); + } + } +} + +QString AST::indentation() +{ + QString result; + for (int i = 0; i < depth(); i++) + result += " "; + return result; +} + +//ProjectAST + +void ProjectAST::writeBack(QString &buffer) +{ + bool hasActualStatements = false; + for (QValueList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) + { + if ((*it)->nodeType() != AST::IncludeAST) + { + hasActualStatements = true; + break; + } + } + + if (isScope()) + { + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += scopedID; + if( m_children.count() == 1 ) + buffer += " : "; + else + buffer += " {"; + } + else if (isFunctionScope()) + { + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += scopedID + "(" + args + ")"; + if( m_children.count() == 1 && hasActualStatements ) + buffer += ": "; + else if( (m_children.count() > 0 && hasActualStatements) ) + buffer += "{"; + else + buffer += ""; + } + else if( !buffer.endsWith(": ") ) + buffer += indentation(); + AST::writeBack(buffer); + if (isScope() && m_children.count() > 1 ) + buffer += indentation() + "}"; + + if (isFunctionScope() && (hasActualStatements) && m_children.count() > 1) + buffer += indentation() + "}"; +} + + +void ProjectAST::setLineEnding( ProjectAST::LineEnding l ) +{ + m_lineEnding = l; +} + +ProjectAST::LineEnding ProjectAST::lineEnding() +{ + return m_lineEnding; +} + +//AssignmentAST + +AssignmentAST::~AssignmentAST() +{ +} + +void AssignmentAST::writeBack(QString &buffer) +{ + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += scopedID + " " + op; + if( values.first().stripWhiteSpace() != "" ) + buffer += " "; + buffer += values.join(""); +} + + +//NewLineAST + +void NewLineAST::writeBack(QString &buffer) +{ + buffer += "\n"; +} + + +//CommentAST + +void CommentAST::writeBack(QString &buffer) +{ + if( !buffer.endsWith(": ") ) + buffer += indentation(); + buffer += comment; +} + + +//IncludeAST + +void IncludeAST::writeBack(QString &/*buffer*/) +{ +} + +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + + diff --git a/buildtools/lib/parsers/qmake/qmakeast.h b/buildtools/lib/parsers/qmake/qmakeast.h new file mode 100644 index 00000000..b8486433 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeast.h @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEAST_H +#define QMAKEQMAKEAST_H + +#include + +/** +@file qmakeast.h +Abstract Syntax Tree (AST) class declarations. +*/ + +namespace QMake { + +/** +AST node. +This is the base class. Objects of this type are not created by the parser. + +Each AST node holds the list of its children which are always deleted in the +destructor. This way, it's possible call delete for only root AST node and +others will be deleted automatically. + +Each AST node also knows how to write the information back into .pro file. +*/ +class AST { +public: + /**Type of AST node.*/ + enum NodeType { + ProjectAST /** m_children; + +protected: + NodeType m_nodeType; + +private: + int m_depth; + +}; + + +/** +Project AST node. +Represents complete projects, scopes and function scopes. +Examples: +@code +scopename{ +var=value +} +function(args){ +var=value +} +@endcode +*/ +class ProjectAST: public AST { +public: + /**The kind of a project node.*/ + enum Kind { + Project /** +var=value + + +Values can be specified on several lines and +each line is stored as a string in the list of values.@n +For example, if we have in .pro: +
+SOURCES=a.cpp \
+    b.cpp c.cpp
+
+then values will be stored as a two elements list: +
+a.cpp
+    b.cpp c.cpp
+
+*/ +class AssignmentAST: public AST { +public: + AssignmentAST(): AST(AST::AssignmentAST){} + ~AssignmentAST(); + + virtual void writeBack(QString &buffer); + + /**Scoped name of the variable.*/ + QString scopedID; + /**Operator.*/ + QString op; + /**List of values.*/ + QStringList values; + /**Indentation of multiline values*/ + QString indent; +}; + + +/** +New line AST node. +Represents line feeds in files. +*/ +class NewLineAST: public AST { +public: + NewLineAST(): AST(AST::NewLineAST) {} + + virtual void writeBack(QString &buffer); + +}; + + +/** +Comment AST node. +Represents comments. +*/ +class CommentAST: public AST { +public: + CommentAST(): AST(AST::CommentAST) {} + + virtual void writeBack(QString &buffer); + + /**Comment text.*/ + QString comment; + +}; + + +/** +Include AST node. +Represents pri include. + */ +class IncludeAST: public AST { +public: + IncludeAST(): AST(AST::IncludeAST) {} + + virtual void writeBack(QString &buffer); + + QString projectName; +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/qmakeastvisitor.cpp b/buildtools/lib/parsers/qmake/qmakeastvisitor.cpp new file mode 100644 index 00000000..d8dd7751 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeastvisitor.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qmakeastvisitor.h" + +namespace QMake { + +void ASTVisitor::processProject(ProjectAST *project) +{ + if (project->isProject()) + enterRealProject(project); + else if (project->isScope()) + enterScope(project); + else if (project->isFunctionScope()) + enterFunctionScope(project); + for (QValueList::const_iterator it = project->m_children.constBegin(); + it != project->m_children.constEnd(); ++it) + { + AST *ast = *it; + if (ast == 0) + continue; + switch (ast->nodeType()) { + case AST::AssignmentAST: + processAssignment(static_cast(ast)); + break; + + case AST::NewLineAST: + processNewLine(static_cast(ast)); + break; + + case AST::CommentAST: + processComment(static_cast(ast)); + break; + + case AST::ProjectAST: + processProject(static_cast(ast)); + break; + + case AST::IncludeAST: + processInclude(static_cast(ast)); + break; + } + } + if (project->isProject()) + leaveRealProject(project); + else if (project->isScope()) + leaveScope(project); + else if (project->isFunctionScope()) + leaveFunctionScope(project); +} + +} diff --git a/buildtools/lib/parsers/qmake/qmakeastvisitor.h b/buildtools/lib/parsers/qmake/qmakeastvisitor.h new file mode 100644 index 00000000..006d1de3 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakeastvisitor.h @@ -0,0 +1,46 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEASTVISITOR_H +#define QMAKEQMAKEASTVISITOR_H + +#include "qmakeast.h" + +namespace QMake { + +class ASTVisitor{ +public: + ASTVisitor() {} + + virtual void processProject(ProjectAST *); + virtual void enterRealProject(ProjectAST *) {} + virtual void leaveRealProject(ProjectAST *) {} + virtual void enterScope(ProjectAST *) {} + virtual void leaveScope(ProjectAST *) {} + virtual void enterFunctionScope(ProjectAST *) {} + virtual void leaveFunctionScope(ProjectAST *) {} + virtual void processAssignment(AssignmentAST *) {} + virtual void processNewLine(NewLineAST *) {} + virtual void processComment(CommentAST *) {} + virtual void processInclude(IncludeAST *) {} +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/qmakedriver.cpp b/buildtools/lib/parsers/qmake/qmakedriver.cpp new file mode 100644 index 00000000..3e385c7a --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakedriver.cpp @@ -0,0 +1,113 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qmakedriver.h" +#include "qmakeast.h" + +#include +#include + +#include +#include +#include + +#include "qmake_lex.h" +#include "qmake_yacc.hpp" + +namespace QMake { + +int Driver::parseFile(const char *fileName, ProjectAST **ast, int debug) +{ + std::ifstream inf( fileName, std::ios::in ); + if ( !inf.is_open() ) + { + *ast = 0; + return 1; + } +// yydebug = 1; + Lexer l(&inf); + l.set_debug(debug); + int depth = 0; + QValueStack stack; + Parser p(&l, stack, depth); + p.set_debug_level(debug); + int ret = p.parse(); + *ast = stack.top(); + (*ast)->setFileName(fileName); + switch( l.lineending() ) + { + case QMake::Lexer::Windows: + (*ast)->setLineEnding(QMake::ProjectAST::Windows); + break; + case QMake::Lexer::MacOS: + (*ast)->setLineEnding(QMake::ProjectAST::MacOS); + break; + case QMake::Lexer::Unix: + default: + (*ast)->setLineEnding(QMake::ProjectAST::Unix); + break; + } + return ret; +} + +int Driver::parseFile(QString fileName, ProjectAST **ast, int debug) +{ + return parseFile(fileName.ascii(), ast, debug); +} + +int Driver::parseFile(KURL fileName, ProjectAST **ast, int debug) +{ + QString tmpFile; + int ret = 0; + if (KIO::NetAccess::download(fileName, tmpFile, 0)) + ret = parseFile(tmpFile, ast, debug); + KIO::NetAccess::removeTempFile(tmpFile); + return ret; +} + +int Driver::parseString( const char* string, ProjectAST **ast, int debug ) +{ + std::istringstream ins; + ins.str(string); + Lexer l(&ins); + l.set_debug(debug); + int depth = 0; + QValueStack stack; + Parser p(&l, stack, depth); + p.set_debug_level(debug); + int ret = p.parse(); + *ast = stack.top(); + (*ast)->setFileName(""); + switch( l.lineending() ) + { + case QMake::Lexer::Windows: + (*ast)->setLineEnding(QMake::ProjectAST::Windows); + break; + case QMake::Lexer::MacOS: + (*ast)->setLineEnding(QMake::ProjectAST::MacOS); + break; + case QMake::Lexer::Unix: + default: + (*ast)->setLineEnding(QMake::ProjectAST::Unix); + break; + } + return ret; +} + +} diff --git a/buildtools/lib/parsers/qmake/qmakedriver.h b/buildtools/lib/parsers/qmake/qmakedriver.h new file mode 100644 index 00000000..a1cdc9d9 --- /dev/null +++ b/buildtools/lib/parsers/qmake/qmakedriver.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QMAKEQMAKEDRIVER_H +#define QMAKEQMAKEDRIVER_H + +class QString; +class KURL; + +namespace QMake { + +/** +@file qmakedriver.h +Driver for a qmake parser. +*/ + +class ProjectAST; + +/** +Driver. +Use methods of this class to lauch parsing and build the AST. +*/ +class Driver{ +public: + /**Parses the file @p fileName and stores the resulting ProjectAST root + into @p ast. @p ast should not be initialized before. Driver will + initialize it on its own. + @return The result of parsing. Result is 0 on success and <> 0 on failure. + */ + static int parseFile(const char *fileName, ProjectAST **ast, int debug); + static int parseFile(QString fileName, ProjectAST **ast, int debug); + static int parseFile(KURL fileName, ProjectAST **ast, int debug); + static int parseString(const char* string, ProjectAST **ast, int debug); + +}; + +} + +#endif diff --git a/buildtools/lib/parsers/qmake/stack.hh b/buildtools/lib/parsers/qmake/stack.hh new file mode 100644 index 00000000..b81e4a28 --- /dev/null +++ b/buildtools/lib/parsers/qmake/stack.hh @@ -0,0 +1,129 @@ +/* A Bison parser, made by GNU Bison 2.3. */ + +/* Stack handling for Bison parsers in C++ + + Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + + 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, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef BISON_STACK_HH +# define BISON_STACK_HH + +#include + +namespace QMake +{ + template > + class stack + { + public: + + // Hide our reversed order. + typedef typename S::reverse_iterator iterator; + typedef typename S::const_reverse_iterator const_iterator; + + stack () : seq_ () + { + } + + stack (unsigned int n) : seq_ (n) + { + } + + inline + T& + operator [] (unsigned int i) + { + return seq_[i]; + } + + inline + const T& + operator [] (unsigned int i) const + { + return seq_[i]; + } + + inline + void + push (const T& t) + { + seq_.push_front (t); + } + + inline + void + pop (unsigned int n = 1) + { + for (; n; --n) + seq_.pop_front (); + } + + inline + unsigned int + height () const + { + return seq_.size (); + } + + inline const_iterator begin () const { return seq_.rbegin (); } + inline const_iterator end () const { return seq_.rend (); } + + private: + + S seq_; + }; + + /// Present a slice of the top of a stack. + template > + class slice + { + public: + + slice (const S& stack, + unsigned int range) : stack_ (stack), + range_ (range) + { + } + + inline + const T& + operator [] (unsigned int i) const + { + return stack_[range_ - i]; + } + + private: + + const S& stack_; + unsigned int range_; + }; +} + +#endif // not BISON_STACK_HH diff --git a/buildtools/lib/parsers/qmake/tests/Makefile.am b/buildtools/lib/parsers/qmake/tests/Makefile.am new file mode 100644 index 00000000..a73f8f4e --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/Makefile.am @@ -0,0 +1,21 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +INCLUDES = -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/util -I$(top_srcdir)/lib/widgets/propeditor \ + -I$(top_srcdir)/buildtools/lib/parsers/qmake \ + -I$(top_builddir)/buildtools/lib/parsers/qmake/tests \ + $(all_includes) + +METASOURCES = AUTO + +noinst_PROGRAMS = runner viewer + +runner_LDFLAGS = $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +runner_LDADD = $(top_builddir)/buildtools/lib/parsers/qmake/libkdevqmakeparser.la +runner_SOURCES = runner.cpp + +viewer_LDFLAGS = --no-undefined $(all_libraries) $(LIB_KDECORE) $(KDE_RPATH) +viewer_LDADD = $(top_builddir)/buildtools/lib/parsers/qmake/libkdevqmakeparser.la +viewer_SOURCES = viewer.cpp viewer_main.cpp viewerbase.ui diff --git a/buildtools/lib/parsers/qmake/tests/runner.cpp b/buildtools/lib/parsers/qmake/tests/runner.cpp new file mode 100644 index 00000000..b01284f1 --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/runner.cpp @@ -0,0 +1,169 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include +#include "qmakedriver.h" +#include "qmakeastvisitor.h" + +#include + +#include +#include +#include + +static const KCmdLineOptions options[] = +{ + {"silent", "Enable Parser debug output", 0}, + {"!debug", "Disable output of the generated AST", 0}, + {"!+files", "QMake project files", 0} +}; + + +class PrintAST : QMake::ASTVisitor +{ +public: + PrintAST() : QMake::ASTVisitor() + { + indent = 0; + } + + virtual void processProject( QMake::ProjectAST* p ) + { + QMake::ASTVisitor::processProject(p); + } +private: + virtual void enterRealProject( QMake::ProjectAST* p ) + { + kdDebug(9024) << getIndent() << "--------- Entering Project: " << replaceWs(p->fileName()) << "| LineEnding:" << p->lineEnding() << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterRealProject(p); + } + + virtual void leaveRealProject( QMake::ProjectAST* p ) + { + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Project: " << replaceWs(p->fileName()) << " --------------" << endl; + QMake::ASTVisitor::leaveRealProject(p); + } + + virtual void enterScope( QMake::ProjectAST* p ) + { + kdDebug(9024) << getIndent() << "--------- Entering Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterScope(p); + } + + virtual void leaveScope( QMake::ProjectAST* p ) + { + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + QMake::ASTVisitor::leaveScope(p); + } + + virtual void enterFunctionScope( QMake::ProjectAST* p ) + { + kdDebug(9024) << getIndent() << "--------- Entering FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterFunctionScope(p); + } + + virtual void leaveFunctionScope( QMake::ProjectAST* p ) + { + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + QMake::ASTVisitor::leaveFunctionScope(p); + } + + QString replaceWs(QString s) + { + return s.replace("\n", "%nl").replace("\t", "%tab").replace(" ", "%spc"); + } + + virtual void processAssignment( QMake::AssignmentAST* a) + { + kdDebug(9024) << getIndent() << "Assignment(" << replaceWs(a->indent) << "):" << replaceWs(a->scopedID) << " " << replaceWs(a->op) << " " << replaceWs(a->values.join("|")) << endl; + QMake::ASTVisitor::processAssignment(a); + } + + virtual void processNewLine( QMake::NewLineAST* n) + { + kdDebug(9024) << getIndent() << "Newline " << endl; + QMake::ASTVisitor::processNewLine(n); + } + + virtual void processComment( QMake::CommentAST* a) + { + kdDebug(9024) << getIndent() << "Comment: " << replaceWs(a->comment) << endl; + QMake::ASTVisitor::processComment(a); + } + + virtual void processInclude( QMake::IncludeAST* a) + { + kdDebug(9024) << getIndent() << "Include: " << replaceWs(a->projectName) << endl; + QMake::ASTVisitor::processInclude(a); + } + + QString getIndent() + { + QString ind; + for( int i = 0 ; i < indent ; i++) + ind += " "; + return ind; + } + int indent; +}; +int main(int argc, char *argv[]) +{ + KCmdLineArgs::init( argc, argv, "QMake Parser", "qmake-parser", "Parse QMake project files", "1.0.0"); + KCmdLineArgs::addCmdLineOptions(options); + + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + if( args->count() < 1 ) + { + KCmdLineArgs::usage(0); + } + + int debug = 0; + bool silent = false; + + if( args->isSet("silent") ) + silent = true; + if( args->isSet("debug") ) + debug = 1; + for( int i = 0 ; i < args->count() ; i++ ) + { + QMake::ProjectAST *projectAST; + int ret = QMake::Driver::parseFile(args->url(i).path(), &projectAST, debug); + PrintAST pa; + if ( ret == 0 ) + if ( !silent ) + { + pa.processProject(projectAST); + QString profile; + projectAST->writeBack(profile); + kdDebug(9024) << "QMake file written back:\n" << profile << endl; + } + return ret; + } + return 0; +} diff --git a/buildtools/lib/parsers/qmake/tests/viewer.cpp b/buildtools/lib/parsers/qmake/tests/viewer.cpp new file mode 100644 index 00000000..dba2b7fb --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewer.cpp @@ -0,0 +1,182 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "viewer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace QMake; + +Viewer::Viewer(QWidget *parent, const char *name) + :ViewerBase(parent, name), projectAST(0) +{ + if (QFile::exists(QDir::currentDirPath() + "/" + "qtlist")) + { + QFile f(QDir::currentDirPath() + "/" + "qtlist"); + f.open(IO_ReadOnly); + QTextStream str(&f); + while (!str.eof()) + files->insertItem(str.readLine()); + } + ast->setSorting(-1); +// parentProject.push((QListViewItem*)0); +} + +void Viewer::addAll_clicked() +{ + if (allLocation->text().isEmpty()) + return; + QDir d(allLocation->text()); + QStringList l = d.entryList("*.pro *.pri"); + for (QStringList::iterator it = l.begin(); it != l.end(); ++it) + (*it) = QDir::cleanDirPath(allLocation->text() + "/" + (*it)); + files->insertStringList(l); +} + +void Viewer::choose_clicked() +{ + QString fileName = QFileDialog::getOpenFileName(QDir::currentDirPath(), "*.pro *.pri", this); + if (!fileName.isEmpty()) + files->insertItem(fileName); +} + +void Viewer::files_currentChanged(QListBoxItem* item) +{ + ast->clear(); + + QFile f(item->text()); + f.open(IO_ReadOnly); + QTextStream str(&f); + source->setText(str.read()); + f.close(); + + int result = QMake::Driver::parseFile(item->text().ascii(), &projectAST, 0); + if (projectAST && (result == 0)) + { + processAST(projectAST); + } + if (tabWidget2->currentPageIndex() == 1) + tabWidget2_selected("Source to be written back"); +} + +void Viewer::tabWidget2_selected(const QString& text) +{ + if ((text == "Source to Be Written Back") && projectAST) + { + QString buffer; + projectAST->writeBack(buffer); + writeBack->setText(buffer); + } +} + +class ViewerVisitor: public ASTVisitor { +public: + ViewerVisitor(Viewer *v): ASTVisitor() + { + this->v = v; + parentProject.push((QListViewItem*)0); + } + + virtual void processProject(ProjectAST *project) + { + ASTVisitor::processProject(project); + } + + virtual void enterRealProject(ProjectAST *project) + { + QListViewItem *projectIt; + if (!parentProject.top()) + { + projectIt = new QListViewItem(v->ast, "Project"); + projectIt->setOpen(true); + parentProject.push(projectIt); + } + + ASTVisitor::enterRealProject(project); + } + virtual void enterScope(ProjectAST *scope) + { + QListViewItem *projectIt = new QListViewItem(parentProject.top(), scope->scopedID, "scope"); + parentProject.push(projectIt); + ASTVisitor::enterScope(scope); + } + virtual void leaveScope(ProjectAST *scope) + { + parentProject.pop(); + } + virtual void enterFunctionScope(ProjectAST *fscope) + { + QListViewItem *projectIt = new QListViewItem(parentProject.top(), + fscope->scopedID + "(" + fscope->args + ")", "function scope"); + parentProject.push(projectIt); + ASTVisitor::enterFunctionScope(fscope); + } + virtual void leaveFunctionScope(ProjectAST *fscope) + { + parentProject.pop(); + } + virtual void processAssignment(AssignmentAST *assignment) + { + QListViewItem *item = new QListViewItem(parentProject.top(), + assignment->scopedID, assignment->op, assignment->values.join("|"), + "assignment"); + item->setMultiLinesEnabled(true); + + ASTVisitor::processAssignment(assignment); + } + virtual void processNewLine(NewLineAST *newline) + { + new QListViewItem(parentProject.top(), ""); + ASTVisitor::processNewLine(newline); + } + virtual void processComment(CommentAST *comment) + { + new QListViewItem(parentProject.top(), ""); + ASTVisitor::processComment(comment); + } + virtual void processInclude(IncludeAST *include) + { + new QListViewItem(parentProject.top(), "", include->projectName); + QMake::ASTVisitor::processInclude(include); + } + + Viewer *v; + QValueStack parentProject; +}; + + +void Viewer::processAST(QMake::ProjectAST *projectAST, QListViewItem *globAfter) +{ + ViewerVisitor visitor(this); + visitor.processProject(projectAST); +} + +#include "viewer.moc" diff --git a/buildtools/lib/parsers/qmake/tests/viewer.h b/buildtools/lib/parsers/qmake/tests/viewer.h new file mode 100644 index 00000000..8d0da49f --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewer.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef VIEWER_H +#define VIEWER_H + +#include + +#include "viewerbase.h" + +namespace QMake { +class ProjectAST; +} + +class QListViewItem; + +class Viewer: public ViewerBase { +Q_OBJECT +public: + Viewer(QWidget *parent = 0, const char *name = 0); + void processAST(QMake::ProjectAST *projectAST, QListViewItem *globAfter = 0); +public slots: + virtual void tabWidget2_selected(const QString&); + virtual void files_currentChanged(QListBoxItem*); + virtual void choose_clicked(); + virtual void addAll_clicked(); +private: + QMake::ProjectAST *projectAST; + friend class ViewerVisitor; +}; + +#endif diff --git a/buildtools/lib/parsers/qmake/tests/viewer_main.cpp b/buildtools/lib/parsers/qmake/tests/viewer_main.cpp new file mode 100644 index 00000000..8fdbc910 --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewer_main.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005 by Alexander Dymo * + * adymo@kdevelop.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU Library General Public License as * + * published by the Free Software Foundation; either version 2 of the * + * License, or (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include +#include "viewer.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + Viewer viewer; + app.setMainWidget(&viewer); + viewer.show(); + viewer.setWindowState(viewer.windowState() | Qt::WindowMaximized); + + return app.exec(); +} diff --git a/buildtools/lib/parsers/qmake/tests/viewerbase.ui b/buildtools/lib/parsers/qmake/tests/viewerbase.ui new file mode 100644 index 00000000..976d4d0f --- /dev/null +++ b/buildtools/lib/parsers/qmake/tests/viewerbase.ui @@ -0,0 +1,250 @@ + +ViewerBase + + + ViewerBase + + + + 0 + 0 + 600 + 480 + + + + Viewer + + + + unnamed + + + + splitter5 + + + Horizontal + + + + layout4 + + + + unnamed + + + + allLocation + + + + 32767 + 32767 + + + + + + addAll + + + + 32767 + 32767 + + + + Add All From Directory + + + + + choose + + + + 32767 + 32767 + + + + Choose File to Add... + + + + + files + + + + 7 + 7 + 0 + 0 + + + + + 32767 + 32767 + + + + Auto + + + + + + + splitter2 + + + Vertical + + + + source + + + + 7 + 7 + 0 + 1 + + + + + + tabWidget2 + + + + 7 + 7 + 0 + 2 + + + + + tab + + + Parse Tree + + + + unnamed + + + + + Name + + + true + + + true + + + + + Value 1 + + + true + + + true + + + + + Value 2 + + + true + + + true + + + + + Value 3 + + + true + + + true + + + + ast + + + + + + + tab + + + Source to Be Written Back + + + + unnamed + + + + writeBack + + + + + + + + + + + + addAll + clicked() + ViewerBase + addAll_clicked() + + + choose + clicked() + ViewerBase + choose_clicked() + + + files + currentChanged(QListBoxItem*) + ViewerBase + files_currentChanged(QListBoxItem*) + + + tabWidget2 + selected(const QString&) + ViewerBase + tabWidget2_selected(const QString&) + + + + addAll_clicked() + choose_clicked() + files_currentChanged( QListBoxItem * ) + tabWidget2_selected( const QString & ) + + + diff --git a/buildtools/lib/widgets/Mainpage.dox b/buildtools/lib/widgets/Mainpage.dox new file mode 100644 index 00000000..56884c97 --- /dev/null +++ b/buildtools/lib/widgets/Mainpage.dox @@ -0,0 +1,10 @@ +/** +@mainpage The KDevelop Buildtool Widgets Library + +This library contains widgets commonly used in buildtool support plugins. + +Link with: -lkdevbuildtoolswidgets + +Include path: -I\$(kde_includes)/kdevelop/buildtools/widgets +*/ + diff --git a/buildtools/lib/widgets/Makefile.am b/buildtools/lib/widgets/Makefile.am new file mode 100644 index 00000000..2277d9d0 --- /dev/null +++ b/buildtools/lib/widgets/Makefile.am @@ -0,0 +1,30 @@ +# This directory collects some classes related to +# project management for the sole purpose that they +# can be shared between parts. + +INCLUDES = -I$(top_srcdir)/lib/interfaces -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/lib/widgets/propeditor $(all_includes) + +lib_LTLIBRARIES = libkdevbuildtoolswidgets.la +libkdevbuildtoolswidgets_la_LDFLAGS = $(all_libraries) +libkdevbuildtoolswidgets_la_LIBADD = $(top_builddir)/lib/interfaces/libkdevinterfaces.la \ + $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) $(LIB_KIO) -lktexteditor +libkdevbuildtoolswidgets_la_SOURCES = addenvvardlg.cpp addfilesdialog.cpp \ + environmentdisplaydialog.cpp environmentdisplaydialogbase.ui environmentvariableswidget.cpp \ + environmentvariableswidgetbase.ui envvartools.cpp makeoptionswidget.cpp makeoptionswidgetbase.ui \ + removesubprojectdialog.cpp removesubprojectdlgbase.ui runoptionswidget.cpp runoptionswidgetbase.ui \ + subclassesdlg.cpp subclassesdlgbase.ui + +METASOURCES = AUTO + +kdevelopbuildtoolsincludedir = $(includedir)/kdevelop/buildtools/widgets +kdevelopbuildtoolsinclude_HEADERS = addenvvardlg.h addfilesdialog.h \ + environmentvariableswidget.h environmentvariableswidgetbase.h envvartools.h makeoptionswidget.h \ + makeoptionswidgetbase.h removesubprojectdialog.h removesubprojectdlgbase.h runoptionswidget.h \ + runoptionswidgetbase.h subclassesdlg.h subclassesdlgbase.h + +DOXYGEN_REFERENCES = dcop interfaces kdecore kdefx kdeui khtml kmdi kio kjs kparts kutils kdevutil kdevinterfaces kdevutil +DOXYGEN_PROJECTNAME = KDevelop Buildtool Widgets Library +DOXYGEN_DOCDIRPREFIX = kdevbt +include ../../../Doxyfile.am +noinst_HEADERS = environmentdisplaydialog.h diff --git a/buildtools/lib/widgets/addenvvardlg.cpp b/buildtools/lib/widgets/addenvvardlg.cpp new file mode 100644 index 00000000..aaf82774 --- /dev/null +++ b/buildtools/lib/widgets/addenvvardlg.cpp @@ -0,0 +1,84 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Bernd Gehrmann + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "addenvvardlg.h" + + +AddEnvvarDialog::AddEnvvarDialog(QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("Add Environment Variable")); + + QLabel *varname_label = new QLabel(i18n("&Name:"), this); + varname_edit = new KLineEdit(this); + varname_edit->setFocus(); + varname_label->setBuddy(varname_edit); + + connect( varname_edit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotTextChanged() ) ); + QLabel *value_label = new QLabel(i18n("&Value:"), this); + value_edit = new KLineEdit(this); + value_label->setBuddy(value_edit); + QFontMetrics fm(value_edit->fontMetrics()); + value_edit->setMinimumWidth(fm.width('X')*35); + connect( value_edit, SIGNAL( textChanged ( const QString & ) ), this, SLOT( slotTextChanged() ) ); + + + QVBoxLayout *layout = new QVBoxLayout(this, 10); + + QGridLayout *grid = new QGridLayout(2, 2); + layout->addLayout(grid); + grid->addWidget(varname_label, 0, 0); + grid->addWidget(varname_edit, 0, 1); + grid->addWidget(value_label, 1, 0); + grid->addWidget(value_edit, 1, 1); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + layout->addWidget(frame, 0); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + m_pOk = buttonbox->addButton( KStdGuiItem::ok()); + QPushButton *cancel = buttonbox->addButton(KStdGuiItem::cancel()); + m_pOk->setDefault(true); + connect( m_pOk, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + layout->addWidget(buttonbox, 0); + slotTextChanged(); +} + + +AddEnvvarDialog::~AddEnvvarDialog() +{} + +void AddEnvvarDialog::slotTextChanged() +{ + m_pOk->setEnabled( !varname_edit->text().isEmpty() && !value_edit->text().isEmpty() ); +} + +#include "addenvvardlg.moc" diff --git a/buildtools/lib/widgets/addenvvardlg.h b/buildtools/lib/widgets/addenvvardlg.h new file mode 100644 index 00000000..0ffdbde1 --- /dev/null +++ b/buildtools/lib/widgets/addenvvardlg.h @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Bernd Gehrmann + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _ADDENVVARDLG_H_ +#define _ADDENVVARDLG_H_ + +#include +#include +class QPushButton; + +/** +Dialog to add environment variables. +*/ +class AddEnvvarDialog : public QDialog +{ + Q_OBJECT + +public: + AddEnvvarDialog( QWidget *parent=0, const char *name=0 ); + ~AddEnvvarDialog(); + + QString varname() const + { return varname_edit->text(); } + QString value() const + { return value_edit->text(); } + void setvarname(const QString name) const + { varname_edit->setText(name); } + void setvalue(const QString value) const + { value_edit->setText(value); } + private slots: + void slotTextChanged(); +private: + KLineEdit *varname_edit; + KLineEdit *value_edit; + QPushButton *m_pOk; +}; + +#endif diff --git a/buildtools/lib/widgets/addfilesdialog.cpp b/buildtools/lib/widgets/addfilesdialog.cpp new file mode 100644 index 00000000..8ba14539 --- /dev/null +++ b/buildtools/lib/widgets/addfilesdialog.cpp @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include +#include + +#include + +#include "addfilesdialog.h" +#include "addfilesdialog.moc" + +AddFilesDialog::AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal): + KFileDialog(startDir, filter, parent, name, modal) +{ + KConfig *config = kapp->config(); + config->setGroup("Add Files Dialog"); + + m_extraWidget = new QComboBox(false, this); + m_extraWidget->insertItem(i18n("Copy File(s)"), 0); + m_extraWidget->insertItem(i18n("Create Symbolic Link(s)"), 1); + m_extraWidget->insertItem(i18n("Add Relative Path(s)"), 2); + m_extraWidget->setCurrentItem(config->readNumEntry("Mode")); + connect(m_extraWidget, SIGNAL(activated(int)), this, SLOT(storePreferred(int))); + + setPreviewWidget(m_extraWidget); + + setOperationMode(Opening); +} + + +AddFilesDialog::AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal, QComboBox *extraWidget): + KFileDialog(startDir, filter, parent, name, modal, extraWidget), m_extraWidget(extraWidget) +{ + KConfig *config = kapp->config(); + config->setGroup("Add Files Dialog"); + + m_extraWidget->insertItem(i18n("Copy File(s)"), 0); + m_extraWidget->insertItem(i18n("Create Symbolic Link(s)"), 1); + m_extraWidget->insertItem(i18n("Add Relative Path(s)"), 2); + m_extraWidget->setCurrentItem(config->readNumEntry("Mode")); + connect(m_extraWidget, SIGNAL(activated(int)), this, SLOT(storePreferred(int))); + + setOperationMode(Opening); +} + + +AddFilesDialog::~AddFilesDialog() +{ +} + +AddFilesDialog::Mode AddFilesDialog::mode( ) +{ + return (AddFilesDialog::Mode)m_extraWidget->currentItem(); +} + +void AddFilesDialog::storePreferred( int index ) +{ + KConfig *config = kapp->config(); + config->setGroup("Add Files Dialog"); + config->writeEntry("Mode", index); +} diff --git a/buildtools/lib/widgets/addfilesdialog.h b/buildtools/lib/widgets/addfilesdialog.h new file mode 100644 index 00000000..00b238a7 --- /dev/null +++ b/buildtools/lib/widgets/addfilesdialog.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#ifndef ADDFILESDIALOG_H +#define ADDFILESDIALOG_H + +#include +#include + +class QComboBox; + +/** +This class allows you to choose additional modes when adding +files to the project. +Currently available modes are Copy, Link and Relative. +Relative means that file should be not copied but added +with the relative path (e.g. ../../dir/filename) +*/ +class AddFilesDialog : public KFileDialog +{ + Q_OBJECT +public: + enum Mode { Copy, Link, Relative }; + + AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal); + + AddFilesDialog(const QString& startDir, const QString& filter, + QWidget *parent, const char *name, bool modal, QComboBox *extraWidget); + + virtual ~AddFilesDialog(); + + virtual AddFilesDialog::Mode mode(); + +private: + QComboBox * m_extraWidget; + +private slots: + void storePreferred(int index); +}; + +#endif diff --git a/buildtools/lib/widgets/environmentdisplaydialog.cpp b/buildtools/lib/widgets/environmentdisplaydialog.cpp new file mode 100644 index 00000000..7d01b031 --- /dev/null +++ b/buildtools/lib/widgets/environmentdisplaydialog.cpp @@ -0,0 +1,54 @@ +/* This file is part of the KDE project + Copyright (C) 2007 Jens Dagerbo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include +#include +#include + +#include "environmentdisplaydialog.h" + +extern char **environ; + +EnvironmentDisplayDialog::EnvironmentDisplayDialog(QWidget* parent, const char* name, bool modal, WFlags fl) +: EnvironmentDisplayDialogBase(parent,name, modal,fl) +{ + QStringList environment; + char ** e = ::environ; + + while ( *e ) + { + environment << *e; + e++; + } + + QStringList::ConstIterator it = environment.begin(); + while( it !=environment.end() ) + { + QStringList pair = QStringList::split( QChar('='), *it ); + if ( pair.count() == 2 ) + { + new QListViewItem( environmentListView, pair.first(), pair.last() ); + } + ++it; + } +} + + +#include "environmentdisplaydialog.moc" + diff --git a/buildtools/lib/widgets/environmentdisplaydialog.h b/buildtools/lib/widgets/environmentdisplaydialog.h new file mode 100644 index 00000000..af284a3b --- /dev/null +++ b/buildtools/lib/widgets/environmentdisplaydialog.h @@ -0,0 +1,35 @@ +/* This file is part of the KDE project + Copyright (C) 2007 Jens Dagerbo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef ENVIRONMENTDISPLAYDIALOG_H +#define ENVIRONMENTDISPLAYDIALOG_H + + +#include "environmentdisplaydialogbase.h" + +class EnvironmentDisplayDialog : public EnvironmentDisplayDialogBase +{ +Q_OBJECT + +public: + EnvironmentDisplayDialog(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); +}; + +#endif + diff --git a/buildtools/lib/widgets/environmentdisplaydialogbase.ui b/buildtools/lib/widgets/environmentdisplaydialogbase.ui new file mode 100644 index 00000000..8b41862f --- /dev/null +++ b/buildtools/lib/widgets/environmentdisplaydialogbase.ui @@ -0,0 +1,111 @@ + +EnvironmentDisplayDialogBase + + + EnvironmentDisplayDialogBase + + + + 0 + 0 + 583 + 523 + + + + Environment + + + + unnamed + + + + groupBox1 + + + Current Environment + + + + unnamed + + + + + Variable + + + true + + + true + + + + + Value + + + true + + + true + + + + environmentListView + + + + + + + layout1 + + + + unnamed + + + + spacer1 + + + Horizontal + + + Expanding + + + + 321 + 21 + + + + + + closeButton + + + &Close + + + + + + + + + closeButton + clicked() + EnvironmentDisplayDialogBase + accept() + + + + + klistview.h + + diff --git a/buildtools/lib/widgets/environmentvariableswidget.cpp b/buildtools/lib/widgets/environmentvariableswidget.cpp new file mode 100644 index 00000000..7ba08427 --- /dev/null +++ b/buildtools/lib/widgets/environmentvariableswidget.cpp @@ -0,0 +1,126 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann + Copyright (C) 2003 John Firebaugh + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "environmentvariableswidget.h" +#include "environmentdisplaydialog.h" + +#include +#include +#include +#include +#include "domutil.h" +#include "addenvvardlg.h" + + +void EnvironmentVariablesWidget::addVarClicked() +{ + AddEnvvarDialog dlg( this, "add env dialog" ) ; + if (QListViewItem *Item = listview->selectedItem()) + { + dlg.setvarname(Item->text(0)); + dlg.setvalue(Item->text(1)); + } + if (!dlg.exec()) + return; + + (void) new QListViewItem(listview, dlg.varname(), dlg.value()); +} + + +void EnvironmentVariablesWidget::editVarClicked() +{ + AddEnvvarDialog dlg( this, "edit env dialog" ); + QListViewItem *item = listview->selectedItem(); + if ( !item ) + return; + dlg.setvarname(item->text(0)); + dlg.setvalue(item->text(1)); + if (!dlg.exec()) + return; + + item->setText(0,dlg.varname()); + item->setText(1,dlg.value()); +} + + +void EnvironmentVariablesWidget::removeVarClicked() +{ + delete listview->selectedItem(); +} + + +EnvironmentVariablesWidget::EnvironmentVariablesWidget(QDomDocument &dom, const QString &configGroup, + QWidget *parent, const char *name) + : EnvironmentVariablesWidgetBase(parent, name), + m_dom(dom), m_configGroup(configGroup) +{ + readEnvironment(dom, configGroup); + connect( listview, SIGNAL( doubleClicked ( QListViewItem *, const QPoint &, int ) ), this, SLOT( editVarClicked() ) ); +} + + +EnvironmentVariablesWidget::~EnvironmentVariablesWidget() +{} + +void EnvironmentVariablesWidget::readEnvironment(QDomDocument &dom, const QString &configGroup) +{ + m_dom = dom; + m_configGroup = configGroup; + + listview->clear(); + + DomUtil::PairList list = + DomUtil::readPairListEntry(dom, m_configGroup, "envvar", "name", "value"); + + QListViewItem *lastItem = 0; + + DomUtil::PairList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + QListViewItem *newItem = new QListViewItem(listview, (*it).first, (*it).second); + if (lastItem) + newItem->moveItem(lastItem); + lastItem = newItem; + } +} + +void EnvironmentVariablesWidget::changeConfigGroup( const QString &configGroup) +{ + m_configGroup = configGroup; +} + +void EnvironmentVariablesWidget::accept() +{ + DomUtil::PairList list; + QListViewItem *item = listview->firstChild(); + while (item) { + list << DomUtil::Pair(item->text(0), item->text(1)); + item = item->nextSibling(); + } + + DomUtil::writePairListEntry(m_dom, m_configGroup, "envvar", "name", "value", list); +} + +void EnvironmentVariablesWidget::environmentClicked() +{ + EnvironmentDisplayDialog dlg; + dlg.exec(); +} + +#include "environmentvariableswidget.moc" diff --git a/buildtools/lib/widgets/environmentvariableswidget.h b/buildtools/lib/widgets/environmentvariableswidget.h new file mode 100644 index 00000000..9f2d472e --- /dev/null +++ b/buildtools/lib/widgets/environmentvariableswidget.h @@ -0,0 +1,59 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann + Copyright (C) 2003 John Firebaugh + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _ENVIRONMENTVARIABLESWIDGET_H_ +#define _ENVIRONMENTVARIABLESWIDGET_H_ + +#include "environmentvariableswidgetbase.h" + +#include + +/** +Environment variables widget. +*/ +class EnvironmentVariablesWidget : public EnvironmentVariablesWidgetBase +{ + Q_OBJECT + +public: + EnvironmentVariablesWidget( QDomDocument &dom, const QString &configGroup, + QWidget *parent=0, const char *name=0 ); + ~EnvironmentVariablesWidget(); + + /// read in a set of environment variables from the DOM document + void readEnvironment(QDomDocument &dom, const QString &configGroup); + + /// changes the path in the DOM structure where the environment variables are stored + void changeConfigGroup( const QString &configGroup); + +public slots: + void accept(); + +private: + virtual void addVarClicked(); + virtual void removeVarClicked(); + virtual void editVarClicked(); + virtual void environmentClicked(); + + QDomDocument &m_dom; + QString m_configGroup; +}; + +#endif diff --git a/buildtools/lib/widgets/environmentvariableswidgetbase.ui b/buildtools/lib/widgets/environmentvariableswidgetbase.ui new file mode 100644 index 00000000..d16cc613 --- /dev/null +++ b/buildtools/lib/widgets/environmentvariableswidgetbase.ui @@ -0,0 +1,200 @@ + +EnvironmentVariablesWidgetBase + + + EnvironmentVariablesWidgetBase + + + + 0 + 0 + 566 + 451 + + + + Environment Variables + + + + unnamed + + + 0 + + + + + Name + + + true + + + true + + + + + Value + + + true + + + true + + + + listview + + + + 7 + 7 + 0 + 0 + + + + true + + + AllColumns + + + + + removevar_button + + + + 5 + 0 + 0 + 0 + + + + &Remove + + + + + editvar_button + + + + 1 + 0 + 0 + 0 + + + + &Edit + + + + + addvar_button + + + + 1 + 0 + 0 + 0 + + + + A&dd / Copy + + + + + Spacer12 + + + Vertical + + + Expanding + + + + 20 + 60 + + + + + + environmentButton + + + E&nvironment + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 171 + + + + + + + + addvar_button + clicked() + EnvironmentVariablesWidgetBase + addVarClicked() + + + removevar_button + clicked() + EnvironmentVariablesWidgetBase + removeVarClicked() + + + editvar_button + clicked() + EnvironmentVariablesWidgetBase + editVarClicked() + + + environmentButton + clicked() + EnvironmentVariablesWidgetBase + environmentClicked() + + + + listview + addvar_button + removevar_button + + + kdialog.h + + + addVarClicked() + removeVarClicked() + editVarClicked() + environmentClicked() + + + + diff --git a/buildtools/lib/widgets/envvartools.cpp b/buildtools/lib/widgets/envvartools.cpp new file mode 100644 index 00000000..bc8eaf51 --- /dev/null +++ b/buildtools/lib/widgets/envvartools.cpp @@ -0,0 +1,31 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include "envvartools.h" + +#include + +QString EnvVarTools::quote( const QString & arg ) +{ + QString res = arg; + res.replace(QRegExp(QString::fromLatin1("'")), QString::fromLatin1("'\\''")); + res.prepend("\""); + res.append("\""); + return res; +} + diff --git a/buildtools/lib/widgets/envvartools.h b/buildtools/lib/widgets/envvartools.h new file mode 100644 index 00000000..65db1b8d --- /dev/null +++ b/buildtools/lib/widgets/envvartools.h @@ -0,0 +1,28 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include + +/**Environment support functions.*/ +namespace EnvVarTools{ + + /**Quotes the argument using double quotes ("). Created as a replacement + for KShellProcess::quote.*/ + QString quote(const QString &arg); + +} diff --git a/buildtools/lib/widgets/makeoptionswidget.cpp b/buildtools/lib/widgets/makeoptionswidget.cpp new file mode 100644 index 00000000..c720de8b --- /dev/null +++ b/buildtools/lib/widgets/makeoptionswidget.cpp @@ -0,0 +1,64 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "makeoptionswidget.h" + +#include +#include +#include +#include +#include + +#include "domutil.h" +#include "environmentvariableswidget.h" + +MakeOptionsWidget::MakeOptionsWidget(QDomDocument &dom, const QString &configGroup, + QWidget *parent, const char *name) + : MakeOptionsWidgetBase(parent, name), + m_dom(dom), m_configGroup(configGroup) +{ + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_environmentVariablesWidget = new EnvironmentVariablesWidget( dom, configGroup + "/make/envvars", env_var_group ); + + abort_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/make/abortonerror", true )); + jobs_box->setValue(DomUtil::readIntEntry(dom, configGroup + "/make/numberofjobs")); + runMultiJobs->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/make/runmultiplejobs")); + dontact_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/make/dontact")); + makebin_edit->setText(DomUtil::readEntry(dom, configGroup + "/make/makebin")); + prio_box->setValue(DomUtil::readIntEntry(dom, configGroup + "/make/prio")); +} + + +MakeOptionsWidget::~MakeOptionsWidget() +{} + + +void MakeOptionsWidget::accept() +{ + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/abortonerror", abort_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/runmultiplejobs", runMultiJobs->isChecked()); + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/numberofjobs", jobs_box->value()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/make/dontact", dontact_box->isChecked()); + DomUtil::writeEntry(m_dom, m_configGroup + "/make/makebin", makebin_edit->text()); + DomUtil::writeIntEntry(m_dom, m_configGroup + "/make/prio", prio_box->value()); + + m_environmentVariablesWidget->accept(); +} + +#include "makeoptionswidget.moc" diff --git a/buildtools/lib/widgets/makeoptionswidget.h b/buildtools/lib/widgets/makeoptionswidget.h new file mode 100644 index 00000000..b6deeb05 --- /dev/null +++ b/buildtools/lib/widgets/makeoptionswidget.h @@ -0,0 +1,50 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _MAKEOPTIONSWIDGET_H_ +#define _MAKEOPTIONSWIDGET_H_ + +#include "makeoptionswidgetbase.h" + +#include + +class EnvironmentVariablesWidget; + +/** +Make options widget. +*/ +class MakeOptionsWidget : public MakeOptionsWidgetBase +{ + Q_OBJECT + +public: + MakeOptionsWidget( QDomDocument &dom, const QString &configGroup, + QWidget *parent=0, const char *name=0 ); + ~MakeOptionsWidget(); + +public slots: + void accept(); + +private: + QDomDocument &m_dom; + QString m_configGroup; + EnvironmentVariablesWidget* m_environmentVariablesWidget; +}; + +#endif diff --git a/buildtools/lib/widgets/makeoptionswidgetbase.ui b/buildtools/lib/widgets/makeoptionswidgetbase.ui new file mode 100644 index 00000000..4bddebd1 --- /dev/null +++ b/buildtools/lib/widgets/makeoptionswidgetbase.ui @@ -0,0 +1,194 @@ + +MakeOptionsWidgetBase + + + make_options_widget + + + + 0 + 0 + 507 + 366 + + + + Make Options + + + + unnamed + + + + abort_box + + + &Abort on first error + + + + + dontact_box + + + Onl&y display commands without actually executing them + + + + + env_var_group + + + Environment &Variables + + + + + makebin_label + + + &Name of make executable: + + + makebin_edit + + + + + makebin_edit + + + + + jobs_box + + + false + + + + 0 + 0 + 0 + 0 + + + + 30 + + + 1 + + + + + textLabel1 + + + false + + + Num&ber of jobs to run simultaneously: + + + jobs_box + + + + + spacer33 + + + Horizontal + + + Expanding + + + + 121 + 20 + + + + + + spacer2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + runMultiJobs + + + Run more than one &job at a time + + + + + prio_label + + + Make priority: + + + + + prio_box + + + + 0 + 0 + 0 + 0 + + + + 19 + + + -20 + + + + + + + runMultiJobs + toggled(bool) + textLabel1 + setEnabled(bool) + + + runMultiJobs + toggled(bool) + jobs_box + setEnabled(bool) + + + + abort_box + dontact_box + makebin_edit + jobs_box + + + kdialog.h + + + + diff --git a/buildtools/lib/widgets/removesubprojectdialog.cpp b/buildtools/lib/widgets/removesubprojectdialog.cpp new file mode 100644 index 00000000..37f9aaf8 --- /dev/null +++ b/buildtools/lib/widgets/removesubprojectdialog.cpp @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include +#include +#include "removesubprojectdialog.h" + +RemoveSubprojectDialog::RemoveSubprojectDialog(QString caption, QString question, QWidget* parent, const char* name, bool modal, WFlags fl) + : RemoveSubprojectDlgBase(parent,name, modal,fl) +{ + setCaption(caption); + removeLabel->setText(question); +} + +RemoveSubprojectDialog::~RemoveSubprojectDialog() +{ +} + +/*$SPECIALIZATION$*/ +void RemoveSubprojectDialog::reject() +{ + QDialog::reject(); +} + +void RemoveSubprojectDialog::accept() +{ + QDialog::accept(); +} + +bool RemoveSubprojectDialog::removeFromDisk( ) +{ + return removeCheckBox->isChecked(); +} + + +#include "removesubprojectdialog.moc" + diff --git a/buildtools/lib/widgets/removesubprojectdialog.h b/buildtools/lib/widgets/removesubprojectdialog.h new file mode 100644 index 00000000..89487511 --- /dev/null +++ b/buildtools/lib/widgets/removesubprojectdialog.h @@ -0,0 +1,52 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef REMOVESUBPROJECTDIALOG_H +#define REMOVESUBPROJECTDIALOG_H + +#include "removesubprojectdlgbase.h" + +/** +Subproject removal dialog. +*/ +class RemoveSubprojectDialog : public RemoveSubprojectDlgBase +{ + Q_OBJECT + +public: + RemoveSubprojectDialog(QString caption, QString question, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~RemoveSubprojectDialog(); + /*$PUBLIC_FUNCTIONS$*/ + bool removeFromDisk(); + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void reject(); + virtual void accept(); + +}; + +#endif + diff --git a/buildtools/lib/widgets/removesubprojectdlgbase.ui b/buildtools/lib/widgets/removesubprojectdlgbase.ui new file mode 100644 index 00000000..cd36b6ff --- /dev/null +++ b/buildtools/lib/widgets/removesubprojectdlgbase.ui @@ -0,0 +1,154 @@ + +RemoveSubprojectDlgBase + + + RemoveSubprojectDlgBase + + + + 0 + 0 + 378 + 147 + + + + [REMOVE SUBPROJECT] + + + + unnamed + + + + fileGroupBox + + + + 0 + 0 + + + + + 32767 + 140 + + + + Sunken + + + &Information + + + + unnamed + + + + removeLabel + + + [REMOVE QUESTION] + + + + + removeCheckBox + + + Also &remove it from disk + + + + + noticeLabel + + + + 200 + 0 + + + + <b>Note:</b> You will not be able to undo this operation. + + + + + + + buttonLayout + + + + unnamed + + + 0 + + + + buttonSpacer + + + Horizontal + + + Expanding + + + + 30 + 20 + + + + + + removeButton + + + &OK + + + true + + + + + cancelButton + + + &Cancel + + + + + + + + + removeButton + clicked() + RemoveSubprojectDlgBase + accept() + + + cancelButton + clicked() + RemoveSubprojectDlgBase + reject() + + + + kdialog.h + + + accept() + reject() + + + + diff --git a/buildtools/lib/widgets/runoptionswidget.cpp b/buildtools/lib/widgets/runoptionswidget.cpp new file mode 100644 index 00000000..95fe4529 --- /dev/null +++ b/buildtools/lib/widgets/runoptionswidget.cpp @@ -0,0 +1,138 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#include "runoptionswidget.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "domutil.h" +#include "environmentvariableswidget.h" + + +RunOptionsWidget::RunOptionsWidget(QDomDocument &dom, const QString &configGroup, + const QString &buildDirectory, QWidget *parent, const char *name) + : RunOptionsWidgetBase(parent, name), + m_dom(dom), m_configGroup(configGroup) +{ + // Create the "Environment Variables" GUI + env_var_group->setColumnLayout( 1, Qt::Vertical ); + m_environmentVariablesWidget = new EnvironmentVariablesWidget( dom, configGroup + "/run/envvars", env_var_group ); + + mainprogram_edit->completionObject()->setMode(KURLCompletion::FileCompletion); + mainprogram_edit->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + if( DomUtil::readEntry(dom, configGroup + "/run/mainprogram").isEmpty() && QFileInfo( buildDirectory ).exists() ) + { + mainprogram_edit->setURL( buildDirectory ); + mainprogram_edit->fileDialog()->setURL( KURL::fromPathOrURL(buildDirectory) ); + }else if ( QFileInfo( DomUtil::readEntry(dom, configGroup + "/run/mainprogram") ).exists() ) + { + QString program = DomUtil::readEntry(dom, configGroup + "/run/mainprogram"); + if( QDir::isRelativePath(program) ) + program = buildDirectory + "/" + program; + mainprogram_edit->setURL(program); + mainprogram_edit->fileDialog()->setURL( program ); + }else + { + mainprogram_edit->setURL(QString()); + mainprogram_edit->fileDialog()->setURL(QString()); + } + + cwd_edit->completionObject()->setMode(KURLCompletion::DirCompletion); + cwd_edit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + if( DomUtil::readEntry(dom, configGroup + "/run/globalcwd").isEmpty() && QFileInfo( buildDirectory ).exists() ) + { + cwd_edit->setURL( buildDirectory ); + cwd_edit->fileDialog()->setURL( KURL::fromPathOrURL(buildDirectory) ); + }else if( QFileInfo( DomUtil::readEntry(dom, configGroup + "/run/globalcwd") ).exists() ) + { + cwd_edit->setURL(DomUtil::readEntry(dom, configGroup + "/run/globalcwd")); + cwd_edit->fileDialog()->setURL( KURL::fromPathOrURL( DomUtil::readEntry(dom, configGroup + "/run/globalcwd") ) ); + }else + { + cwd_edit->setURL(QString()); + cwd_edit->fileDialog()->setURL(QString()); + } + + if( configGroup == "/kdevautoproject" || configGroup == "/kdevtrollproject" ) + { + mainProgramGroupBox->setCheckable(true); + mainProgramGroupBox->setChecked( DomUtil::readBoolEntry(dom, configGroup+"/run/useglobalprogram", false ) ); + }else + { + delete notelabel; + } + + // Read the main program command line arguments and store them in the edit box + + runargs_edit->setText(DomUtil::readEntry(dom, configGroup + "/run/programargs")); + debugargs_edit->setText(DomUtil::readEntry(dom, configGroup + "/run/globaldebugarguments")); + + startinterminal_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/terminal")); + autocompile_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/autocompile", false)); + autoinstall_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/autoinstall", false)); + autokdesu_box->setChecked(DomUtil::readBoolEntry(dom, configGroup + "/run/autokdesu", false)); +} + + +RunOptionsWidget::~RunOptionsWidget() +{} + + +void RunOptionsWidget::accept() +{ + DomUtil::writeEntry(m_dom, m_configGroup + "/run/mainprogram", mainprogram_edit->url()); + DomUtil::writeEntry(m_dom, m_configGroup + "/run/programargs", runargs_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/run/globaldebugarguments", debugargs_edit->text()); + DomUtil::writeEntry(m_dom, m_configGroup + "/run/globalcwd", cwd_edit->url()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/useglobalprogram", mainProgramGroupBox->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/terminal", startinterminal_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/autocompile", autocompile_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/autoinstall", autoinstall_box->isChecked()); + DomUtil::writeBoolEntry(m_dom, m_configGroup + "/run/autokdesu", autokdesu_box->isChecked()); + + m_environmentVariablesWidget->accept(); +} + +void RunOptionsWidget::mainProgramChanged( ) +{ + + if( mainProgramGroupBox->isChecked() && mainprogram_edit->url().isEmpty() ) + { + mainprogram_label->setPaletteForegroundColor(QColor("#ff0000")); + } + else + { + mainprogram_label->unsetPalette(); + } +} + +#include "runoptionswidget.moc" diff --git a/buildtools/lib/widgets/runoptionswidget.h b/buildtools/lib/widgets/runoptionswidget.h new file mode 100644 index 00000000..758ef4b1 --- /dev/null +++ b/buildtools/lib/widgets/runoptionswidget.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (C) 2001-2002 Bernd Gehrmann + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef _RUNOPTIONSWIDGET_H_ +#define _RUNOPTIONSWIDGET_H_ + +#include "runoptionswidgetbase.h" + +#include +#include + +class EnvironmentVariablesWidget; + +/** +Run options widget. +*/ +class RunOptionsWidget : public RunOptionsWidgetBase +{ + Q_OBJECT + +public: + RunOptionsWidget( QDomDocument &dom, //!< document DOM + const QString &configGroup, //!< configuration group + const QString &buildDirectory, //!< project build directory + QWidget *parent=0, //!< parent widget + const char *name=0 //!< widget's name + ); + ~RunOptionsWidget(); + +public slots: + void accept(); + +private: + virtual void mainProgramChanged( ); + + QDomDocument &m_dom; + QString m_configGroup; + EnvironmentVariablesWidget* m_environmentVariablesWidget; +}; + +#endif diff --git a/buildtools/lib/widgets/runoptionswidgetbase.ui b/buildtools/lib/widgets/runoptionswidgetbase.ui new file mode 100644 index 00000000..1163484c --- /dev/null +++ b/buildtools/lib/widgets/runoptionswidgetbase.ui @@ -0,0 +1,257 @@ + +RunOptionsWidgetBase + + + run_options_widget + + + + 0 + 0 + 500 + 506 + + + + Run Options + + + + unnamed + + + + mainProgramGroupBox + + + + 5 + 0 + 0 + 0 + + + + Main Program + + + false + + + false + + + + unnamed + + + + notelabel + + + Note: These options override target specific settings. + + + AlignVCenter + + + For Automake and QMake type projects, the proper way to set these options are per target in the <b>Automake Manager</b> and <b>QMake Manager</b>, respectively. + + + + + runargs_edit + + + The command line arguments passed to the main program when run + + + + + mainprogram_label_2 + + + Run Arg&uments: + + + mainprogram_edit + + + + + mainprogram_label + + + Executa&ble: + + + mainprogram_edit + + + + + mainprogram_edit + + + Full path to the executable + + + + + mainprogram_label_3 + + + Debug Ar&guments: + + + mainprogram_edit + + + + + debugargs_edit + + + The command line arguments passed to the main program when debugged + + + + + mainprogram_label_3_2 + + + Working &Directory: + + + mainprogram_edit + + + + + cwd_edit + + + Sets the current working directory for the launched process + + + + + + + groupBox2 + + + + 5 + 0 + 0 + 0 + + + + Options + + + + unnamed + + + + autocompile_box + + + Automaticall&y compile before execution + + + If the program is not up-to-date with the source code, compile it before starting its execution + + + + + autoinstall_box + + + &Automatically install before execution + + + + + + + + autokdesu_box + + + Use &kdesu when installing + + + + + + + + startinterminal_box + + + Start in e&xternal terminal + + + Start the main program in an external terminal + + + + + + + env_var_group + + + Environment &Variables + + + + + + + mainprogram_edit + textChanged(const QString&) + run_options_widget + mainProgramChanged() + + + mainprogram_edit + urlSelected(const QString&) + run_options_widget + mainProgramChanged() + + + mainProgramGroupBox + toggled(bool) + run_options_widget + mainProgramChanged() + + + + startinterminal_box + autocompile_box + + + kdialog.h + ksqueezedtextlabel.h + + + mainProgramChanged() + + + + + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/lib/widgets/subclassesdlg.cpp b/buildtools/lib/widgets/subclassesdlg.cpp new file mode 100644 index 00000000..5c3a0fef --- /dev/null +++ b/buildtools/lib/widgets/subclassesdlg.cpp @@ -0,0 +1,122 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ +#include +#include + +#include "subclassesdlg.h" +#include "subclassesdlg.moc" +SubclassesDlg::SubclassesDlg(QString form, DomUtil::PairList &config, QString projectDir, QWidget* parent, const char* name, bool modal, WFlags fl) +: SubclassesDlgBase(parent,name, modal,fl), m_form(form), m_config(config), m_projectDir(projectDir) +{ + subclass_url->setEnabled(false); + + DomUtil::PairList::iterator it; + for ( it = config.begin(); it != config.end(); ++it ) + { + if ((*it).second == form) + subclasses_box->insertItem(projectDir + (*it).first); + } +} + +SubclassesDlg::~SubclassesDlg() +{ +} + +/*$SPECIALIZATION$*/ +void SubclassesDlg::accept() +{ + QPtrList pairsToRemove; + + DomUtil::PairList::iterator it; + for ( it = m_config.begin(); it != m_config.end(); ++it ) + { + if ((*it).second == m_form) + { + pairsToRemove.append(&(*it)); + } + } + + DomUtil::Pair *pair; + for ( pair = pairsToRemove.first(); pair; pair = pairsToRemove.next() ) + { + m_config.remove(*pair); + } + + for (int i = 0; i < (int)subclasses_box->count(); ++i) + { + m_config << DomUtil::Pair(subclasses_box->text(i).remove(0,m_projectDir.length()), m_form); + } + + SubclassesDlgBase::accept(); +} + + +void SubclassesDlg::newRelation() +{ + subclasses_box->setFocus(); + subclasses_box->insertItem(""); + subclasses_box->setCurrentItem(subclasses_box->count()-1); + subclass_url->setEnabled(true); + subclass_url->setURL(""); + subclass_url->setFocus(); +} + +void SubclassesDlg::removeRelation() +{ + if (subclasses_box->currentItem() > -1) + { + QListBoxItem *item = subclasses_box->item(subclasses_box->currentItem()); + int itemIdx = subclasses_box->currentItem(); + + if (item->prev()) + { + subclasses_box->setCurrentItem(item->prev()); + subclass_url->setURL(item->prev()->text()); + } + else if (item->next()) + { + subclasses_box->setCurrentItem(item->next()); + subclass_url->setURL(item->next()->text()); + } + else + { + subclass_url->setEnabled(false); + subclass_url->setURL(""); + } + subclasses_box->removeItem(itemIdx); + } +} + +void SubclassesDlg::changeCurrentURL(const QString &str) +{ + if ( subclasses_box->currentItem() > -1 ) + { + subclasses_box->changeItem(str, subclasses_box->currentItem()); + } +} + +void SubclassesDlg::currentRelationChanged( QListBoxItem * item ) +{ + if (item) + { + subclass_url->setEnabled(true); + subclass_url->setURL(item->text()); + } +} + diff --git a/buildtools/lib/widgets/subclassesdlg.h b/buildtools/lib/widgets/subclassesdlg.h new file mode 100644 index 00000000..46b07b31 --- /dev/null +++ b/buildtools/lib/widgets/subclassesdlg.h @@ -0,0 +1,58 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Alexander Dymo + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. +*/ + +#ifndef SUBCLASSESDLG_H +#define SUBCLASSESDLG_H +#include "domutil.h" +#include "subclassesdlgbase.h" + +/** +Subclass creation dialog. +*/ +class SubclassesDlg : public SubclassesDlgBase +{ + Q_OBJECT + +public: + SubclassesDlg(QString form, DomUtil::PairList &config, QString projectDir, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~SubclassesDlg(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + virtual void accept(); + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void newRelation(); + virtual void removeRelation(); + virtual void changeCurrentURL(const QString &str); + virtual void currentRelationChanged(QListBoxItem *item); + +private: + QString m_form; + DomUtil::PairList &m_config; + QString m_projectDir; +}; + +#endif + diff --git a/buildtools/lib/widgets/subclassesdlgbase.ui b/buildtools/lib/widgets/subclassesdlgbase.ui new file mode 100644 index 00000000..026ab2ca --- /dev/null +++ b/buildtools/lib/widgets/subclassesdlgbase.ui @@ -0,0 +1,224 @@ + +SubclassesDlgBase + + + SubclassesDlgBase + + + + 0 + 0 + 514 + 278 + + + + Related Subclasses + + + true + + + + unnamed + + + + add_button + + + &Add Relation + + + false + + + + + remove_button + + + &Remove Relation + + + false + + + + + subclasses_box + + + + + subclass_url + + + + 0 + 24 + + + + WheelFocus + + + + + spacer2 + + + Vertical + + + Expanding + + + + 20 + 90 + + + + + + textLabel2 + + + + 5 + 5 + 0 + 0 + + + + Related subclass &location: + + + WordBreak|AlignVCenter + + + subclass_url + + + + + layout3 + + + + unnamed + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 310 + 20 + + + + + + buttonOk + + + &OK + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + true + + + false + + + + + + + + + buttonOk + clicked() + SubclassesDlgBase + accept() + + + subclass_url + textChanged(const QString&) + SubclassesDlgBase + changeCurrentURL(const QString&) + + + remove_button + clicked() + SubclassesDlgBase + removeRelation() + + + buttonCancel + clicked() + SubclassesDlgBase + reject() + + + add_button + clicked() + SubclassesDlgBase + newRelation() + + + subclasses_box + clicked(QListBoxItem*) + SubclassesDlgBase + currentRelationChanged(QListBoxItem*) + + + + subclasses_box + add_button + subclass_url + remove_button + buttonOk + buttonCancel + + + kdialog.h + + + changeCurrentURL(const QString &str) + removeRelation() + newRelation() + currentRelationChanged(QListBoxItem *item) + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/pascal/Makefile.am b/buildtools/pascal/Makefile.am new file mode 100644 index 00000000..d975575a --- /dev/null +++ b/buildtools/pascal/Makefile.am @@ -0,0 +1,24 @@ +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external \ + -I$(top_srcdir)/lib/interfaces/extras -I$(top_srcdir)/lib/util -I$(top_builddir)/buildtools/lib/widgets \ + $(all_includes) + +kde_module_LTLIBRARIES = libkdevpascalproject.la +libkdevpascalproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevpascalproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevpascalproject_la_SOURCES = pascalproject_part.cpp pascalproject_widget.cpp pascalproject_optionsdlgbase.ui pascalprojectoptionsdlg.cpp pascalglobaloptionsdlg.cpp service.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevpascalproject.desktop + +rcdir = $(kde_datadir)/kdevpascalproject +rc_DATA = kdevpascalproject.rc + + + + diff --git a/buildtools/pascal/README.dox b/buildtools/pascal/README.dox new file mode 100644 index 00000000..4f3b9897 --- /dev/null +++ b/buildtools/pascal/README.dox @@ -0,0 +1,13 @@ +/** \class PascalProjectPart +This is the Pascal build tool part. + +Common build tool part part for all available pascal compilers (gpc, fpc, dcc). +It holds no project file list and tries to abstract from their specifics. + +\authors Alexander Dymo + +\maintainer Alexander Dymo + +\deprecated This class is deprecated, use GenericProjectPart (buildtools/generic) instead. + +*/ diff --git a/buildtools/pascal/kdevpascalproject.desktop b/buildtools/pascal/kdevpascalproject.desktop new file mode 100644 index 00000000..05b7e507 --- /dev/null +++ b/buildtools/pascal/kdevpascalproject.desktop @@ -0,0 +1,93 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Pascal Project +Comment[br]=Raktres Pascal +Comment[ca]=Projecte Pascal +Comment[da]=Pascal projekt +Comment[de]=Pascal-Projekt für KDevelop +Comment[el]=Έργο Pascal +Comment[es]=Proyecto de Pascal +Comment[et]=Pascali projekt +Comment[eu]=Pascal proiektua +Comment[fa]=پروژۀ پاسکال +Comment[fr]=Projet en langage PASCAL +Comment[ga]=Tionscadal Pascal +Comment[gl]=Proxecto Pascal +Comment[hi]=पास्कल परियोजना +Comment[hu]=Pascal-projekt +Comment[is]=Pascal verkefni +Comment[it]=Progetto per Pascal +Comment[ja]=Pascal プロジェクト +Comment[ms]=Projek Pascal +Comment[nds]=Pascal-Projekt +Comment[ne]=पास्कल परियोजना +Comment[nl]=Pascal-project +Comment[pa]=ਪਾਸਕਲ ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: Pascal +Comment[pt]=Projecto de Pascal +Comment[pt_BR]=Projeto Pascal +Comment[ru]=Проект Pascal +Comment[sk]=Pascal projekt +Comment[sl]=Projekt Pascal +Comment[sr]=Pascal пројекат +Comment[sr@Latn]=Pascal projekat +Comment[sv]=Pascal-projekt +Comment[ta]=பாஸ்கல் பிராஜக்ட் +Comment[tg]=Лоиҳаи Pascal +Comment[tr]=Pascal Projesi +Comment[uz]=Pascal loyihasi +Comment[uz@cyrillic]=Pascal лойиҳаси +Comment[zh_CN]=Pascal 工程 +Comment[zh_TW]=Pascal 專案 +Name=KDevPascalProject +Name[da]=KDevelop Pascal-projekt +Name[de]=Pascal-Projekt (KDevelop) +Name[hi]=के-डेव-पास्कल-परियोजना +Name[nds]=Pascal-Projekt (KDevelop) +Name[ne]=केडीई विकास पास्कल परियोजना +Name[pl]=KDevProjektPascal +Name[sk]=KDevPascalProjekt +Name[sv]=KDevelop Pascal-projekt +Name[ta]=கெடெவ் பாஸ்கல் பிராஜக்ட் +Name[tg]=Лоиҳаи ПаскалKDev +Name[zh_TW]=KDevelop Pascal 專案 +GenericName=Pascal Project +GenericName[br]=Raktres Pascal +GenericName[ca]=Projecte Pascal +GenericName[da]=Pascal projekt +GenericName[de]=Pascal-Projekt +GenericName[el]=Έργο Pascal +GenericName[es]=Proyecto de Pascal +GenericName[et]=Pascali projekt +GenericName[eu]=Pascal proiektua +GenericName[fa]=پروژۀ پاسکال +GenericName[fr]=Projet en langage PASCAL +GenericName[ga]=Tionscadal Pascal +GenericName[gl]=Proxecto Pascal +GenericName[hi]=पास्कल परियोजना +GenericName[hu]=Pascal-projekt +GenericName[it]=Progetto in Pascal +GenericName[ja]=Pascal プロジェクト +GenericName[ms]=Projek Pascal +GenericName[nds]=Pascal-Projekt +GenericName[ne]=पास्कल परियोजना +GenericName[nl]=Pascal-project +GenericName[pl]=Projekt: Pascal +GenericName[pt]=Projecto de Pascal +GenericName[pt_BR]=Projeto Pascal +GenericName[ru]=Проект Pascal +GenericName[sk]=Pascal projekt +GenericName[sl]=Projekt Pascal +GenericName[sr]=Pascal пројекат +GenericName[sr@Latn]=Pascal projekat +GenericName[sv]=Pascal-projekt +GenericName[ta]=பாஸ்கல் பிராஜக்ட் +GenericName[tr]=Pascal Projesi +GenericName[uz]=Pascal loyihasi +GenericName[uz@cyrillic]=Pascal лойиҳаси +GenericName[zh_CN]=Pascal 工程 +GenericName[zh_TW]=Pascal 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevpascalproject +X-KDevelop-Version=5 diff --git a/buildtools/pascal/kdevpascalproject.rc b/buildtools/pascal/kdevpascalproject.rc new file mode 100644 index 00000000..9e7f46fd --- /dev/null +++ b/buildtools/pascal/kdevpascalproject.rc @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/buildtools/pascal/pascalglobaloptionsdlg.cpp b/buildtools/pascal/pascalglobaloptionsdlg.cpp new file mode 100644 index 00000000..a710db19 --- /dev/null +++ b/buildtools/pascal/pascalglobaloptionsdlg.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 +#include +#include +#include + +#include +#include +#include + +#include "kdevcompileroptions.h" + +#include "service.h" +#include "pascalproject_part.h" +#include "pascalglobaloptionsdlg.h" + +PascalGlobalOptionsDlg::PascalGlobalOptionsDlg(PascalProjectPart *part, QWidget* parent, const char* name, WFlags fl) + :PascalProjectOptionsDlgBase(parent,name,fl), m_part(part) +{ + delete config_label; + delete config_combo; + delete addconfig_button; + delete removeconfig_button; + delete compiler_label; + delete configuration_layout; + delete configuration_line; + delete exec_label; + delete exec_edit; + delete mainSourceLabel; + delete mainSourceUrl; + delete defaultopts_button; + + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + currentCompiler = QString::null; + + /*kdDebug() << ServiceComboBox::defaultCompiler() << endl; + kdDebug() << ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names) << endl; + kdDebug() << compiler_box->text(ServiceComboBox::itemForText(ServiceComboBox::defaultCompiler(), service_names)) << endl; +*/ + ServiceComboBox::setCurrentText(compiler_box, ServiceComboBox::defaultCompiler(), service_names); + compiler_box_activated(compiler_box->currentText()); +} + +PascalGlobalOptionsDlg::~PascalGlobalOptionsDlg() +{ +} + +void PascalGlobalOptionsDlg::optionsButtonClicked() +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void PascalGlobalOptionsDlg::compiler_box_activated(const QString& text) +{ + kdDebug() << "text changed from " << currentCompiler << " to " << text << endl; + if (currentCompiler == text) + return; + if (!currentCompiler.isEmpty()) + saveCompilerOpts(currentCompiler); + currentCompiler = text; + readCompilerOpts(currentCompiler); +} + +void PascalGlobalOptionsDlg::accept() +{ + saveCompilerOpts(currentCompiler); + + saveConfigCache(); +} + +void PascalGlobalOptionsDlg::saveCompilerOpts( QString compiler ) +{ + configCache[compiler] = options_edit->text(); +} + +void PascalGlobalOptionsDlg::readCompilerOpts( QString compiler ) +{ + QString settings = configCache[compiler]; + if (settings.isEmpty()) + { + KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + settings = config->readPathEntry(compiler); + } + + options_edit->setText(settings); +} + +void PascalGlobalOptionsDlg::readConfigCache( ) +{ +/* KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + + QMap settings = config->entryMap("Pascal Compiler"); +*/ +} + +void PascalGlobalOptionsDlg::saveConfigCache( ) +{ + KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + + for (QMap::iterator it = configCache.begin(); it != configCache.end(); ++it) + { + config->writeEntry(it.key(), it.data()); + } +} + +#include "pascalglobaloptionsdlg.moc" diff --git a/buildtools/pascal/pascalglobaloptionsdlg.h b/buildtools/pascal/pascalglobaloptionsdlg.h new file mode 100644 index 00000000..14da2221 --- /dev/null +++ b/buildtools/pascal/pascalglobaloptionsdlg.h @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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. * + * * + ***************************************************************************/ +#ifndef PASCALGLOBALOPTIONSDLG_H +#define PASCALGLOBALOPTIONSDLG_H + +#include + +#include + +#include "pascalproject_optionsdlgbase.h" + +class PascalProjectPart; + +class PascalGlobalOptionsDlg : public PascalProjectOptionsDlgBase +{ + Q_OBJECT + +public: + PascalGlobalOptionsDlg(PascalProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~PascalGlobalOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void optionsButtonClicked(); + virtual void compiler_box_activated(const QString& text); + +private: + PascalProjectPart *m_part; + KTrader::OfferList offers; + QString currentCompiler; + QStringList service_names; + QStringList service_execs; + QMap configCache; + + void saveCompilerOpts(QString compiler); + void readCompilerOpts(QString compiler); + + void readConfigCache(); + void saveConfigCache(); +}; + +#endif diff --git a/buildtools/pascal/pascalproject_optionsdlgbase.ui b/buildtools/pascal/pascalproject_optionsdlgbase.ui new file mode 100644 index 00000000..0f0b2324 --- /dev/null +++ b/buildtools/pascal/pascalproject_optionsdlgbase.ui @@ -0,0 +1,474 @@ + +PascalProjectOptionsDlgBase + + + PascalProjectOptionsDlgBase + + + true + + + + 0 + 0 + 600 + 480 + + + + Pascal Compiler + + + + unnamed + + + + configuration_layout + + + + unnamed + + + + config_label + + + + 1 + 5 + 0 + 0 + + + + Con&figuration: + + + config_combo + + + + + config_combo + + + + 3 + 0 + 0 + 0 + + + + true + + + + + Spacer17_2 + + + Horizontal + + + Fixed + + + + 20 + 8 + + + + + + addconfig_button + + + &Add + + + + + removeconfig_button + + + &Remove + + + + + Spacer18_2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + + + options_button + + + + 0 + 0 + 0 + 0 + + + + + 30 + 32767 + + + + ... + + + + + options_label + + + + 4 + 5 + 0 + 0 + + + + Compiler op&tions: + + + compiler_box + + + + + compiler_label + + + + 4 + 5 + 0 + 0 + + + + &Pascal compiler: + + + compiler_box + + + + + exec_edit + + + + + options_edit + + + + + compiler_box + + + + + exec_label + + + + 4 + 5 + 0 + 0 + + + + Compiler co&mmand: + + + compiler_box + + + + + configuration_line + + + HLine + + + Sunken + + + Horizontal + + + + + spacer11 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + spacer12 + + + Vertical + + + Fixed + + + + 20 + 16 + + + + + + spacer13 + + + Vertical + + + Fixed + + + + 20 + 30 + + + + + + spacer7 + + + Horizontal + + + Expanding + + + + 400 + 20 + + + + + + defaultopts_button + + + Load &Default Compiler Options + + + + + mainSourceUrl + + + + 0 + 26 + + + + WheelFocus + + + + + mainSourceLabel + + + + 4 + 5 + 0 + 0 + + + + Main &source file: + + + compiler_box + + + + + spacer1 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + compiler_box + activated(const QString&) + PascalProjectOptionsDlgBase + compiler_box_activated(const QString&) + + + removeconfig_button + clicked() + PascalProjectOptionsDlgBase + configRemoved() + + + config_combo + textChanged(const QString&) + PascalProjectOptionsDlgBase + configComboTextChanged(const QString&) + + + config_combo + activated(const QString&) + PascalProjectOptionsDlgBase + configChanged(const QString&) + + + addconfig_button + clicked() + PascalProjectOptionsDlgBase + configAdded() + + + options_button + clicked() + PascalProjectOptionsDlgBase + optionsButtonClicked() + + + exec_edit + textChanged(const QString&) + PascalProjectOptionsDlgBase + setDirty() + + + options_edit + textChanged(const QString&) + PascalProjectOptionsDlgBase + setDirty() + + + mainSourceUrl + textChanged(const QString&) + PascalProjectOptionsDlgBase + setDirty() + + + mainSourceUrl + urlSelected(const QString&) + PascalProjectOptionsDlgBase + setDirty() + + + compiler_box + activated(const QString&) + PascalProjectOptionsDlgBase + setDirty() + + + compiler_box + textChanged(const QString&) + PascalProjectOptionsDlgBase + setDirty() + + + defaultopts_button + clicked() + PascalProjectOptionsDlgBase + setDefaultOptions() + + + defaultopts_button + clicked() + PascalProjectOptionsDlgBase + setDirty() + + + + compiler_box + exec_edit + options_edit + options_button + defaultopts_button + mainSourceUrl + config_combo + addconfig_button + removeconfig_button + + + kdialog.h + + + compiler_box_activated(const QString&) + addconfig_button_clicked() + configRemoved() + configComboTextChanged(const QString&) + configChanged(const QString&) + optionsButtonClicked() + configAdded() + setDirty() + setDefaultOptions() + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/pascal/pascalproject_part.cpp b/buildtools/pascal/pascalproject_part.cpp new file mode 100644 index 00000000..3fe09420 --- /dev/null +++ b/buildtools/pascal/pascalproject_part.cpp @@ -0,0 +1,493 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 "pascalproject_part.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "kdevlanguagesupport.h" +#include "kdevcompileroptions.h" +#include "runoptionswidget.h" +#include "envvartools.h" + +#include "pascalproject_widget.h" +#include "pascalprojectoptionsdlg.h" +#include "pascalglobaloptionsdlg.h" + +#include + +typedef KDevGenericFactory PascalProjectFactory; +static const KDevPluginInfo data("kdevpascalproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevpascalproject, PascalProjectFactory( data ) ) + +PascalProjectPart::PascalProjectPart(QObject *parent, const char *name, const QStringList& ) + :KDevBuildTool(&data, parent, name ? name : "PascalProjectPart" ) +{ + setInstance(PascalProjectFactory::instance()); + setXMLFile("kdevpascalproject.rc"); + + KAction *action; + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + this, SLOT(slotBuild()), + actionCollection(), "build_build" ); + action->setToolTip(i18n("Build project")); + action->setWhatsThis(i18n("Build project

Runs the compiler on a main source file of the project. " + "The compiler and the main source file can be set in project settings, Pascal Compiler tab.")); + action = new KAction( i18n("Execute Program"), "exec", 0, + this, SLOT(slotExecute()), + actionCollection(), "build_execute" ); + action->setToolTip(i18n("Execute program")); + action->setWhatsThis(i18n("Execute program

Executes the main program specified in project settings, Run options tab. " + "If nothing is set, the binary file with the same name as the main source file name is executed.")); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); + + connect( core(), SIGNAL(configWidget(KDialogBase*)), + this, SLOT(configWidget(KDialogBase*)) ); + +// m_widget = new PascalProjectWidget(this); + +// QWhatsThis::add(m_widget, i18n("WHAT DOES THIS PART DO?")); + + // now you decide what should happen to the widget. Take a look at kdevcore.h + // or at other plugins how to embed it. + + // if you want to embed your widget as an outputview, simply uncomment + // the following line. + + // mainWindow()->embedOutputView( m_widget, "name that should appear", "enter a tooltip" ); + +} + +PascalProjectPart::~PascalProjectPart() +{ +// delete m_widget; +} + +/** + * @todo This should really be merged with FileTreeWidget::matchesHidePattern() + * and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp + */ +static bool matchesPattern(const QString &fileName, const QStringList &patternList) +{ + QStringList::ConstIterator it; + for (it = patternList.begin(); it != patternList.end(); ++it) { + QRegExp re(*it, true, true); + if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length()) + return true; + } + + return false; +} + +void PascalProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + m_buildDir = dirName; + m_projectDir = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevpascalproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevpascalproject/run/directoryradio", "executable"); + } + + loadProjectConfig(); + + // Put all files from all subdirectories into file list + QValueStack s; + int prefixlen = m_projectDir.length()+1; + s.push(m_projectDir); + + QStringList includepatternList; + if ( languageSupport() ) + { + KMimeType::List list = languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + } + QString excludepatterns = "*~"; + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug(9033) << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + QPtrListIterator it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + kdDebug(9033) << "Pushing: " << path << endl; + s.push(path); + } + else { + if (matchesPattern(path, includepatternList) + && !matchesPattern(path, excludepatternList)) { + kdDebug(9033) << "Adding: " << path << endl; + m_sourceFiles.append(path.mid(prefixlen)); + } else { + kdDebug(9033) << "Ignoring: " << path << endl; + } + } + } + } while (!s.isEmpty()); + + KDevProject::openProject( dirName, projectName ); +} + +void PascalProjectPart::closeProject() +{ +} + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList PascalProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevpascalproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString PascalProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory("kdevpascalproject"); + if (cwd.isEmpty()) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString PascalProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevpascalproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the debug command line arguments */ +QString PascalProjectPart::debugArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/globaldebugarguments"); +} + + +/** Retuns a QString with the run command line arguments */ +QString PascalProjectPart::runArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/programargs"); +} + +QString PascalProjectPart::mainSource() const +{ + return projectDirectory() + "/" + m_mainSource; +} + +void PascalProjectPart::setMainSource(QString fullPath) +{ + QString olddir = activeDirectory(); + m_mainSource = fullPath.replace(QRegExp(QString(projectDirectory() + QString("/"))),""); + emit activeDirectoryChanged( olddir, activeDirectory() ); +} + +QString PascalProjectPart::projectDirectory() const +{ + return m_projectDir; +} + +QString PascalProjectPart::projectName() const +{ + return m_projectName; +} + +QString PascalProjectPart::activeDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true).replace(QRegExp(projectDirectory()),""); +} + +QString PascalProjectPart::buildDirectory() const +{ + QFileInfo fi(mainSource()); + return fi.dirPath(true); +} + +void PascalProjectPart::listOfFiles(QStringList &result, QString path) const +{ + QDir d(path); + if (!d.exists()) + return; + QFileInfoList *entries = const_cast(d.entryInfoList(QDir::Dirs | QDir::Files | QDir::Hidden)); + for (QFileInfo *it = entries->first(); it; it = entries->next()) + { + if ((it->isDir()) && (it->filePath() != path)) + { +// qWarning("entering dir %s", it->dirPath().latin1()); + listOfFiles(result, it->dirPath()); + } + else + { +// qWarning("adding to result: %s", it->filePath().latin1()); + result << it->filePath(); + } + } +} + +QStringList PascalProjectPart::allFiles() const +{ +// QStringList files; + +// listOfFiles(files, projectDirectory()); + +// return files; + return m_sourceFiles; +} + +void PascalProjectPart::addFile(const QString& /*fileName*/) +{ +} + +void PascalProjectPart::addFiles(const QStringList& /*fileList*/) +{ +} + +void PascalProjectPart::removeFile(const QString& /*fileName*/) +{ +} + +void PascalProjectPart::removeFiles(const QStringList& /*fileList*/) +{ +} + +void PascalProjectPart::slotBuild() +{ + if (partController()->saveAllFiles()==false) + return; //user cancelled + + QString cmdline = m_compilerExec + " " + m_compilerOpts + " "; + + if (cmdline.isEmpty()) + { + KMessageBox::sorry(0, i18n("Could not find pascal compiler.\nCheck if your compiler settings are correct.")); + return; + } + + QFileInfo fi(mainSource()); + cmdline += fi.fileName(); + + QString dircmd = "cd "; + dircmd += KProcess::quote(buildDirectory()); + dircmd += " && "; + + makeFrontend()->queueCommand(buildDirectory(), dircmd + cmdline); +} + +void PascalProjectPart::slotExecute() +{ + partController()->saveAllFiles(); + + QDomDocument &dom = *(projectDom()); + bool runInTerminal = DomUtil::readBoolEntry(dom, "/kdevpascalproject/run/terminal", true); + + // Get the run environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), "/kdevpascalproject/run/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + for (it = envvars.begin(); it != envvars.end(); ++it) { + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + + QString program = mainProgram(); + program.prepend(environstr); + program += " " + DomUtil::readEntry(*projectDom(), "/kdevpascalproject/run/programargs"); + + appFrontend()->startAppCommand(buildDirectory(), program, runInTerminal); +} + +void PascalProjectPart::changedFiles( const QStringList & fileList ) +{ + KDevProject::changedFiles(fileList); +} + +void PascalProjectPart::changedFile( const QString & fileName ) +{ + KDevProject::changedFile(fileName); +} + +void PascalProjectPart::projectConfigWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Pascal Compiler")); + PascalProjectOptionsDlg *w = new PascalProjectOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), this, SLOT(loadProjectConfig()) ); + + vbox = dlg->addVBoxPage(i18n("Run Options"), i18n("Run Options"), BarIcon( "make", KIcon::SizeMedium )); + RunOptionsWidget *w3 = new RunOptionsWidget(*projectDom(), "/kdevpascalproject", buildDirectory(), vbox); + connect( dlg, SIGNAL(okClicked()), w3, SLOT(accept()) ); + +} + +void PascalProjectPart::loadProjectConfig( ) +{ + QDomDocument &dom = *(projectDom()); + + QString config = DomUtil::readEntry(dom, "/kdevpascalproject/general/useconfiguration", "default"); + m_mainSource = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/mainsource") ); + m_compilerOpts = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/compileroptions")); + m_compilerExec = DomUtil::readEntry(dom, QString("/kdevpascalproject/configurations/") + config + QString("/compilerexec")); + + if (m_compilerExec.isEmpty()) + { + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + QValueList::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + m_compilerExec = (*it)->exec(); + break; + } + } + } +} + +void PascalProjectPart::configWidget( KDialogBase * dlg ) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Pascal Compiler")); + PascalGlobalOptionsDlg *w = new PascalGlobalOptionsDlg(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); +} + +KDevCompilerOptions *PascalProjectPart::createCompilerOptions(const QString &name) +{ + KService::Ptr service = KService::serviceByDesktopName(name); + if (!service) { + kdDebug() << "Can't find service " << name; + return 0; + } + + KLibFactory *factory = KLibLoader::self()->factory(QFile::encodeName(service->library())); + if (!factory) { + QString errorMessage = KLibLoader::self()->lastErrorMessage(); + KMessageBox::error(0, i18n("There was an error loading the module %1.\n" + "The diagnostics is:\n%2").arg(service->name()).arg(errorMessage)); + exit(1); + } + + QStringList args; + QVariant prop = service->property("X-KDevelop-Args"); + if (prop.isValid()) + args = QStringList::split(" ", prop.toString()); + + QObject *obj = factory->create(this, service->name().latin1(), + "KDevCompilerOptions", args); + + if (!obj->inherits("KDevCompilerOptions")) { + kdDebug() << "Component does not inherit KDevCompilerOptions" << endl; + return 0; + } + KDevCompilerOptions *dlg = (KDevCompilerOptions*) obj; + + return dlg; +} + +QString PascalProjectPart::defaultOptions( const QString compiler ) const +{ + KConfig *config = KGlobal::config(); + config->setGroup("Pascal Compiler"); + return config->readPathEntry(compiler); +} + +#include "pascalproject_part.moc" + + +/*! + \fn PascalProjectPart::distFiles() const + */ +QStringList PascalProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "Makefile"); + return sourceList + files; +} diff --git a/buildtools/pascal/pascalproject_part.h b/buildtools/pascal/pascalproject_part.h new file mode 100644 index 00000000..3273011d --- /dev/null +++ b/buildtools/pascal/pascalproject_part.h @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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. * + * * + ***************************************************************************/ +#ifndef __KDEVPART_PASCALPROJECT_H__ +#define __KDEVPART_PASCALPROJECT_H__ + +#include + +#include "kdevbuildtool.h" + +class PascalProjectWidget; +class KDialogBase; +class KDevCompilerOptions; + +class PascalProjectPart : public KDevBuildTool +{ + Q_OBJECT +public: + PascalProjectPart(QObject *parent, const char *name, const QStringList &); + ~PascalProjectPart(); + + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + /**Returns the name of the main source file without extension. + All pascal compilers call the binary by that way*/ + virtual QString mainProgram() const; + /**Main source file (like src/main.pp)*/ + virtual QString mainSource() const; + virtual void setMainSource(QString fullPath); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString activeDirectory() const; + /**The location of the main source file*/ + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + /**Returns everything in the project directory*/ + virtual QStringList allFiles() const; + /**This does absolutelly nothing*/ + virtual void addFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void addFiles(const QStringList &fileList); + /**This does absolutelly nothing*/ + virtual void removeFile(const QString &fileName); + /**This does absolutelly nothing*/ + virtual void removeFiles(const QStringList &fileList); + + virtual void changedFiles( const QStringList & fileList ); + virtual void changedFile( const QString & fileName ); + + KDevCompilerOptions *createCompilerOptions(const QString &name); + + virtual QString defaultOptions(const QString compiler) const; + QStringList distFiles() const; + +public slots: + /**loads config from project file*/ + void loadProjectConfig(); + +private slots: + void slotBuild(); + void slotExecute(); + void projectConfigWidget(KDialogBase *dlg); + void configWidget(KDialogBase *dlg); + +private: + QGuardedPtr m_widget; + + void listOfFiles(QStringList &result, QString path) const; + + QString m_buildDir; + QString m_projectDir; + QString m_projectName; + + QString m_mainProg; + QString m_mainSource; + QString m_compilerExec; + QString m_compilerOpts; + + QStringList m_sourceFiles; +}; + +#endif diff --git a/buildtools/pascal/pascalproject_widget.cpp b/buildtools/pascal/pascalproject_widget.cpp new file mode 100644 index 00000000..039c97e6 --- /dev/null +++ b/buildtools/pascal/pascalproject_widget.cpp @@ -0,0 +1,26 @@ +#include +#include +#include +#include + + +#include + + +#include "pascalproject_part.h" +#include "pascalproject_widget.h" + + +PascalProjectWidget::PascalProjectWidget(PascalProjectPart *part) + : QWidget(0, "PascalProject widget") +{ + Q_UNUSED( part ); +} + + +PascalProjectWidget::~PascalProjectWidget() +{ +} + + +#include "pascalproject_widget.moc" diff --git a/buildtools/pascal/pascalproject_widget.h b/buildtools/pascal/pascalproject_widget.h new file mode 100644 index 00000000..198cf794 --- /dev/null +++ b/buildtools/pascal/pascalproject_widget.h @@ -0,0 +1,25 @@ +#ifndef __PASCALPROJECT_WIDGET_H__ +#define __PASCALPROJECT_WIDGET_H__ + + +#include +#include + + +class KDevProject; +class PascalProjectPart; + + +class PascalProjectWidget : public QWidget +{ + Q_OBJECT + +public: + + PascalProjectWidget(PascalProjectPart *part); + ~PascalProjectWidget(); + +}; + + +#endif diff --git a/buildtools/pascal/pascalprojectoptionsdlg.cpp b/buildtools/pascal/pascalprojectoptionsdlg.cpp new file mode 100644 index 00000000..7a97cea3 --- /dev/null +++ b/buildtools/pascal/pascalprojectoptionsdlg.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "domutil.h" +#include "kdevcompileroptions.h" + +#include "service.h" +#include "pascalproject_part.h" +#include "pascalprojectoptionsdlg.h" + +PascalProjectOptionsDlg::PascalProjectOptionsDlg(PascalProjectPart *part, QWidget* parent, const char* name, WFlags fl) + : PascalProjectOptionsDlgBase(parent,name, fl), m_part(part) +{ + config_combo->setValidator(new QRegExpValidator(QRegExp("^\\D.*"), this)); + + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + + ServiceComboBox::insertStringList(compiler_box, offers, &service_names, &service_execs); + + if (offers.isEmpty()) + options_button->setEnabled(false); + + allConfigs = allBuildConfigs(); + config_combo->insertStringList(allConfigs); + + dirty = false; + + QDomDocument &dom = *(m_part->projectDom()); + currentConfig = QString::null; + configChanged(DomUtil::readEntry(dom, "/kdevpascalproject/general/useconfiguration", "default")); +} + +PascalProjectOptionsDlg::~PascalProjectOptionsDlg() +{ +} + +QStringList PascalProjectOptionsDlg::allBuildConfigs() +{ + QDomDocument &dom = *(m_part->projectDom()); + + QStringList allConfigs; + allConfigs.append("default"); + + QDomNode node = dom.documentElement().namedItem("kdevpascalproject").namedItem("configurations"); + QDomElement childEl = node.firstChild().toElement(); + while (!childEl.isNull()) { + QString config = childEl.tagName(); + kdDebug() << "Found config " << config << endl; + if (config != "default") + allConfigs.append(config); + childEl = childEl.nextSibling().toElement(); + } + + return allConfigs; +} + +void PascalProjectOptionsDlg::accept() +{ + DomUtil::writeEntry(*m_part->projectDom(), "/kdevpascalproject/general/useconfiguration", currentConfig); + if (dirty) + { + saveConfig(currentConfig); + } +} + +void PascalProjectOptionsDlg::compiler_box_activated( const QString& /*s*/ ) +{ + QString exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); +} + +void PascalProjectOptionsDlg::saveConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevpascalproject/configurations/" + config + "/"; + + DomUtil::writeEntry(dom, prefix + "compiler", + ServiceComboBox::currentText(compiler_box, service_names)); + DomUtil::writeEntry(dom, prefix + "compileroptions", options_edit->text()); + DomUtil::writeEntry(dom, prefix + "compilerexec", exec_edit->text()); + DomUtil::writeEntry(dom, prefix + "mainsource", mainSourceUrl->url().replace(QRegExp(m_part->projectDirectory() + QString("/")),"")); +} + +void PascalProjectOptionsDlg::readConfig( QString config ) +{ + QDomDocument dom = *m_part->projectDom(); + QString prefix = "/kdevpascalproject/configurations/" + config + "/"; + + QString compiler = DomUtil::readEntry(dom, prefix + "compiler", ""); + + if (compiler.isEmpty()) + { + offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + QValueList::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + compiler = (*it)->name(); + kdDebug() << "compiler is " << compiler << endl; + break; + } + } + } + ServiceComboBox::setCurrentText(compiler_box, compiler, service_names); + + QString exec = DomUtil::readEntry(dom, prefix + "compilerexec", ""); + if (exec.isEmpty()) + exec = ServiceComboBox::currentText(compiler_box, service_execs); + exec_edit->setText(exec); + options_edit->setText(DomUtil::readEntry(dom, prefix + "compileroptions")); + mainSourceUrl->setURL(m_part->projectDirectory() + "/" + DomUtil::readEntry(dom, prefix + "mainsource")); +} + +void PascalProjectOptionsDlg::configComboTextChanged(const QString &config) +{ + bool canAdd = !allConfigs.contains(config) && !config.contains("/") && !config.isEmpty(); + bool canRemove = allConfigs.contains(config) && config != "default"; + addconfig_button->setEnabled(canAdd); + removeconfig_button->setEnabled(canRemove); +} + + +void PascalProjectOptionsDlg::configChanged(const QString &config) +{ + if (config == currentConfig || !allConfigs.contains(config)) + return; + + if (!currentConfig.isNull() && dirty) + saveConfig(currentConfig); + + currentConfig = config; + readConfig(config); + dirty = false; + + config_combo->blockSignals(true); + config_combo->setEditText(config); + config_combo->blockSignals(false); +} + + +void PascalProjectOptionsDlg::configAdded() +{ + QString config = config_combo->currentText(); + + allConfigs.append(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + configChanged(config); + setDirty(); // force saving +} + + +void PascalProjectOptionsDlg::configRemoved() +{ + QString config = config_combo->currentText(); + + QDomDocument dom = *m_part->projectDom(); + QDomNode node = dom.documentElement().namedItem("kdevpascalproject").namedItem("configurations"); + node.removeChild(node.namedItem(config)); + allConfigs.remove(config); + + config_combo->clear(); + config_combo->insertStringList(allConfigs); + + currentConfig = QString::null; + configChanged("default"); +} + +void PascalProjectOptionsDlg::optionsButtonClicked( ) +{ + QString name = ServiceComboBox::currentText(compiler_box, service_names); + KDevCompilerOptions *plugin = m_part->createCompilerOptions(name); + + if (plugin) { + QString flags = plugin->exec(this, options_edit->text()); + options_edit->setText(flags); + delete plugin; + } +} + +void PascalProjectOptionsDlg::setDirty( ) +{ + dirty = true; +} + +void PascalProjectOptionsDlg::setDefaultOptions( ) +{ + if (!compiler_box->currentText().isEmpty()) + options_edit->setText(m_part->defaultOptions(compiler_box->currentText())); +} + +#include "pascalprojectoptionsdlg.moc" diff --git a/buildtools/pascal/pascalprojectoptionsdlg.h b/buildtools/pascal/pascalprojectoptionsdlg.h new file mode 100644 index 00000000..70e911de --- /dev/null +++ b/buildtools/pascal/pascalprojectoptionsdlg.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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. * + * * + ***************************************************************************/ +#ifndef PASCALPROJECTOPTIONSDLG_H +#define PASCALPROJECTOPTIONSDLG_H + +#include + +#include "pascalproject_optionsdlgbase.h" + +class PascalProjectPart; +class KDevCompilerOptions; + +class PascalProjectOptionsDlg : public PascalProjectOptionsDlgBase +{ + Q_OBJECT + +public: + PascalProjectOptionsDlg(PascalProjectPart *part, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~PascalProjectOptionsDlg(); + +public slots: + virtual void accept(); + +protected slots: + virtual void compiler_box_activated(const QString &s); + void configComboTextChanged(const QString &config); + void configChanged(const QString &config); + void configAdded(); + void configRemoved(); + void optionsButtonClicked(); + void setDirty(); + void setDefaultOptions(); + +private: + QStringList allConfigs; + QString currentConfig; + bool dirty; + + KTrader::OfferList offers; + QStringList service_names; + QStringList service_execs; + + PascalProjectPart *m_part; + + void saveConfig(QString config); + void readConfig(QString config); + QStringList allBuildConfigs(); +}; + +#endif + diff --git a/buildtools/pascal/service.cpp b/buildtools/pascal/service.cpp new file mode 100644 index 00000000..c678f916 --- /dev/null +++ b/buildtools/pascal/service.cpp @@ -0,0 +1,77 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 +#include + +#include +#include + +#include "service.h" + + +void ServiceComboBox::insertStringList(QComboBox *combo, const QValueList &list, + QStringList *names, QStringList *execs) +{ + QValueList::ConstIterator it; + for (it = list.begin(); it != list.end(); ++it) { + combo->insertItem((*it)->comment()); + (*names) << (*it)->desktopEntryName(); + (*execs) << (*it)->exec(); + kdDebug() << "insertStringList item " << (*it)->name() << "," << (*it)->exec() << endl; + } +} + +QString ServiceComboBox::currentText(QComboBox *combo, const QStringList &names) +{ + if (combo->currentItem() == -1) + return QString::null; + return names[combo->currentItem()]; +} + +void ServiceComboBox::setCurrentText(QComboBox *combo, const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + combo->setCurrentItem(i); + break; + } + ++i; + } +} + +int ServiceComboBox::itemForText(const QString &str, const QStringList &names) +{ + QStringList::ConstIterator it; + int i = 0; + for (it = names.begin(); it != names.end(); ++it) { + if (*it == str) { + return i; + } + ++i; + } + return 0; +} + +QString ServiceComboBox::defaultCompiler() +{ + KTrader::OfferList offers = KTrader::self()->query("KDevelop/CompilerOptions", "[X-KDevelop-Language] == 'Pascal'"); + QValueList::ConstIterator it; + for (it = offers.begin(); it != offers.end(); ++it) { + if ((*it)->property("X-KDevelop-Default").toBool()) { + return (*it)->name();; + } + } + return ""; +} diff --git a/buildtools/pascal/service.h b/buildtools/pascal/service.h new file mode 100644 index 00000000..30bb142b --- /dev/null +++ b/buildtools/pascal/service.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2003 Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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. * + * * + ***************************************************************************/ +#ifndef SERVICE_H +#define SERVICE_H + +#include + +class ServiceComboBox +{ +public: + static void insertStringList(QComboBox *combo, const QValueList &list, + QStringList *names, QStringList *execs); + static QString currentText(QComboBox *combo, const QStringList &names); + static void setCurrentText(QComboBox *combo, const QString &str, const QStringList &names); + static int itemForText(const QString &str, const QStringList &names); + static QString defaultCompiler(); +}; + +#endif diff --git a/buildtools/qmake/Makefile.am b/buildtools/qmake/Makefile.am new file mode 100644 index 00000000..6b65901a --- /dev/null +++ b/buildtools/qmake/Makefile.am @@ -0,0 +1,34 @@ +# Here resides the troll project part for tmake or qmake + + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/buildtools/lib/parsers/qmake \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external -I$(top_srcdir)/lib/util \ + -I$(top_builddir)/buildtools/lib/widgets $(all_includes) + + +kde_module_LTLIBRARIES = libkdevtrollproject.la +libkdevtrollproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevtrollproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/lib/util/libkdevutil.la $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la \ + $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la \ + $(top_builddir)/buildtools/lib/parsers/qmake/libkdevqmakeparser.la + +libkdevtrollproject_la_SOURCES = choosesubprojectdlg.cpp \ + choosesubprojectdlgbase.ui createscopedlg.cpp createscopedlgbase.ui disablesubprojectdlg.cpp \ + disablesubprojectdlgbase.ui newwidgetdlg.cpp newwidgetdlgbase.ui \ + projectconfigurationdlg.cpp projectconfigurationdlgbase.ui qmakedefaultopts.cpp \ + qmakeoptionswidget.cpp qmakeoptionswidgetbase.ui qmakescopeitem.cpp scope.cpp \ + trolllistview.cpp trollprojectpart.cpp trollprojectwidget.cpp + + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevtrollproject.desktop kdevtmakeproject.desktop + +rcdir = $(kde_datadir)/kdevtrollproject +rc_DATA = kdevtrollproject.rc +noinst_HEADERS = createscopedlg.h disablesubprojectdlg.h qmakedefaultopts.h \ + qmakeoptionswidget.h qmakescopeitem.h trolllistview.h diff --git a/buildtools/qmake/README b/buildtools/qmake/README new file mode 100644 index 00000000..0146b60f --- /dev/null +++ b/buildtools/qmake/README @@ -0,0 +1 @@ +Please read the README.dox file. \ No newline at end of file diff --git a/buildtools/qmake/README.dox b/buildtools/qmake/README.dox new file mode 100644 index 00000000..6f0a4027 --- /dev/null +++ b/buildtools/qmake/README.dox @@ -0,0 +1,39 @@ +/** \class TrollProjectPart +A projectmanager for qmake based projects. + +Loads and maintains .pro files (qmake project files). The trollprojectpart +supports subprojects and qmake scopes. Qmake projects can be configured on +project, subproject and file level. +It will regenerate a projects .pro files dynamically as you add,remove or +reconfigure (sub)projects. Unsupported qmake features will be left unchanged +(hopefully) no major testing has been run yet. + +\authors Bernd Gehrmann +\authors Thomas Hasart + +\maintainer Jakob Simon-Gaarde + +\feature Loads and maintains .pro files (qmake project files). +\feature Supports subprojects and qmake scopes. +\feature Qmake projects can be configured on project, subproject and file level. +\feature Regenerates a projects .pro files dynamically as you add, +remove or reconfigure (sub)projects. +\feature Unsupported qmake features will be left unchanged (hopefully) + no major testing has been run yet. + +\bug bugs in trollproject component at Bugzilla database + +\requirement QMake >= 3.0.3 + +\todo Relative directories (priority 1) + By default a qmake projects created with kdevelop must be distributable, + therefore all directory-selections must be relative the subproject where + it is used (user can override this ofcourse). So when a select-directory + dialog is opened getRelativeDirectory() (#include pathutil.h) should be + called. +\todo Ignore shell-expressions and qmake-functions (priority 2-3) + FileBuffer should recognize and ignore shell-expressions and qmake-functions. + (Jakob Simon-Gaarde says: I'm on this one) + + +*/ diff --git a/buildtools/qmake/choosesubprojectdlg.cpp b/buildtools/qmake/choosesubprojectdlg.cpp new file mode 100644 index 00000000..20264144 --- /dev/null +++ b/buildtools/qmake/choosesubprojectdlg.cpp @@ -0,0 +1,114 @@ +/*************************************************************************** + * Copyright (C) 2003 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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 + +#include "trollprojectwidget.h" + +#include "choosesubprojectdlg.h" +#include "scope.h" + +ChooseSubprojectDlg::ChooseSubprojectDlg(TrollProjectWidget *widget, QWidget* parent, const char* name, bool modal, WFlags fl) + : ChooseSubprojectDlgBase(parent,name, modal,fl), m_widget(widget) +{ + connect(subprojects_view, SIGNAL(selectionChanged(QListViewItem*)), this, SLOT(itemSelected(QListViewItem *))); + if( m_widget->m_rootSubproject) + { + ChooseItem *it = new ChooseItem(m_widget->m_rootSubproject, subprojects_view, m_widget->m_rootSubproject->text(0)); + it->setPixmap(0, *(m_widget->m_rootSubproject->pixmap(0))); + it->setOpen(true); + fillSubprojectsView(it); + subprojects_view->setSelected(it, true); + } +} + +ChooseSubprojectDlg::~ChooseSubprojectDlg() +{ +} + +/*$SPECIALIZATION$*/ +void ChooseSubprojectDlg::accept() +{ + if (!subprojects_view->currentItem()) + return; + ChooseItem *item = dynamic_cast(subprojects_view->currentItem()); + if (!item) + return; + if ( item->subproject()->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + return; + + QDialog::accept(); +} + +ChooseItem::ChooseItem( QMakeScopeItem * spitem, QListViewItem * parent, QString text ) + :KListViewItem(parent, text), m_spitem(spitem) +{ +} + +ChooseItem::ChooseItem( QMakeScopeItem * spitem, QListView * parent, QString text ) + :KListViewItem(parent, text), m_spitem(spitem) +{ +} + +QMakeScopeItem * ChooseItem::subproject( ) +{ + return m_spitem; +} + +void ChooseSubprojectDlg::fillSubprojectsView( ChooseItem *item ) +{ + if (!item->subproject()) + return; + + QListViewItem * sub_spitem = item->subproject()->firstChild(); + while( sub_spitem ) { + QMakeScopeItem *spitem = dynamic_cast(sub_spitem); + if ( spitem && spitem->scope->scopeType() == Scope::ProjectScope ) + { + ChooseItem *child_item = new ChooseItem(spitem, item, spitem->text(0)); + child_item->setPixmap(0, *(spitem->pixmap(0))); + child_item->setOpen(true); + fillSubprojectsView(child_item); + } + + sub_spitem = sub_spitem->nextSibling(); + } +} + +void ChooseSubprojectDlg::itemSelected( QListViewItem * it ) +{ + if (!it) + return; + ChooseItem *item = dynamic_cast(it); + if (!item) + return; + if ( item->subproject()->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + buttonOk->setEnabled(false); + else + buttonOk->setEnabled(true); +} + +QMakeScopeItem * ChooseSubprojectDlg::selectedSubproject( ) +{ + if (subprojects_view->currentItem()) + { + ChooseItem *item = dynamic_cast(subprojects_view->currentItem()); + if (item) + return item->subproject(); + } + + return 0; +} + + +#include "choosesubprojectdlg.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/choosesubprojectdlg.h b/buildtools/qmake/choosesubprojectdlg.h new file mode 100644 index 00000000..689fe8b3 --- /dev/null +++ b/buildtools/qmake/choosesubprojectdlg.h @@ -0,0 +1,64 @@ +/*************************************************************************** + * Copyright (C) 2003 by Alexander Dymo * + * cloudtemple@mksat.net * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef CHOOSESUBPROJECTDLG_H +#define CHOOSESUBPROJECTDLG_H + +#include + +#include "choosesubprojectdlgbase.h" + +class QMakeScopeItem; +class TrollProjectWidget; + +class ChooseItem: public KListViewItem +{ +public: + ChooseItem(QMakeScopeItem *spitem, QListViewItem *parent, QString text); + ChooseItem(QMakeScopeItem *spitem, QListView *parent, QString text); + + QMakeScopeItem *subproject(); + +private: + QMakeScopeItem *m_spitem; +}; + +class ChooseSubprojectDlg : public ChooseSubprojectDlgBase +{ + Q_OBJECT + +public: + ChooseSubprojectDlg(TrollProjectWidget *widget, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~ChooseSubprojectDlg(); + /*$PUBLIC_FUNCTIONS$*/ + + QMakeScopeItem *selectedSubproject(); + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + TrollProjectWidget *m_widget; + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void accept(); + virtual void itemSelected(QListViewItem *it); + +private: + void fillSubprojectsView(ChooseItem *item); + +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/choosesubprojectdlgbase.ui b/buildtools/qmake/choosesubprojectdlgbase.ui new file mode 100644 index 00000000..12db29e2 --- /dev/null +++ b/buildtools/qmake/choosesubprojectdlgbase.ui @@ -0,0 +1,134 @@ + +ChooseSubprojectDlgBase + + + ChooseSubprojectDlgBase + + + + 0 + 0 + 511 + 282 + + + + Select Subproject + + + true + + + + unnamed + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + &OK + + + + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + + Subprojects + + + true + + + true + + + + subprojects_view + + + LastColumn + + + + + + + buttonOk + clicked() + ChooseSubprojectDlgBase + accept() + + + buttonCancel + clicked() + ChooseSubprojectDlgBase + reject() + + + + subprojects_view + buttonOk + buttonCancel + + + + klistview.h + kpushbutton.h + + diff --git a/buildtools/qmake/createscopedlg.cpp b/buildtools/qmake/createscopedlg.cpp new file mode 100644 index 00000000..439ddd70 --- /dev/null +++ b/buildtools/qmake/createscopedlg.cpp @@ -0,0 +1,100 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "createscopedlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "urlutil.h" +#include "qmakescopeitem.h" +#include "scope.h" +#include "trollprojectwidget.h" + +CreateScopeDlg::CreateScopeDlg( QMakeScopeItem* item, QWidget* parent, const char* name, bool modal, WFlags fl ) + : CreateScopeDlgBase( parent, name, modal, fl ), m_item( item ) +{ + incUrl->setMode( KFile::File | KFile::LocalOnly ); + incUrl->setCaption( i18n( "Choose existing .pri file or give a new filename for creation" ) ); + incUrl->setURL( QString("") ); + incUrl->completionObject() ->setDir( item->scope->projectDir() ); + incUrl->fileDialog()->setURL( KURL::fromPathOrURL( item->scope->projectDir() ) ); +} + +CreateScopeDlg::~CreateScopeDlg() +{} + +void CreateScopeDlg::accept() +{ + Scope * s = 0; + switch ( comboScopeType->currentItem() ) + { + case 0: + if ( !editScopeName->text().isEmpty() ) + s = m_item->scope->createSimpleScope( editScopeName->text() ); + break; + case 1: + if ( !editFunction->text().isEmpty() && !editArguments->text().isEmpty() ) + s = m_item->scope->createFunctionScope( editFunction->text(), editArguments->text() ); + break; + case 2: + if ( !incUrl->url().isEmpty() ) + { + QString file = incUrl->url(); + if ( !incUrl->url().endsWith( ".pri" ) ) + file += ".pri"; + if( file.find("/") == -1 ) + file = m_item->scope->projectDir()+"/"+file; + // We need to create the file, because getRelativePath checks for existent paths + if( !QFile::exists(file) ) + { + QFile temp(file); + if( temp.open(IO_WriteOnly) ) + temp.close(); + } + file = URLUtil::getRelativePath( m_item->scope->projectDir(), file ); + s = m_item->scope->createIncludeScope( file ); + } + break; + } + if ( s ) + { + if ( !m_item->firstChild() ) + new QMakeScopeItem( m_item, s->scopeName(), s ); + else + { + QListViewItem* item = m_item->firstChild(); + while( item->nextSibling() ) + item = item->nextSibling(); + QMakeScopeItem* newitem = new QMakeScopeItem( m_item, s->scopeName(), s ); + newitem->moveItem( item ); + } + QDialog::accept(); + } + else + { + if ( KMessageBox::warningYesNo( this, i18n( "You did not specify all needed information. " + "The scope will not be created.
Do you want to abort the scope creation?" ), + i18n( "Missing information" ) ) == KMessageBox:: Yes ) + QDialog::reject(); + } +} + +#include "createscopedlg.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/createscopedlg.h b/buildtools/qmake/createscopedlg.h new file mode 100644 index 00000000..c8ed86ef --- /dev/null +++ b/buildtools/qmake/createscopedlg.h @@ -0,0 +1,45 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef CREATESCOPEDLG_H +#define CREATESCOPEDLG_H + +#include "createscopedlgbase.h" + +class QMakeScopeItem; +class TrollProjectWigdet; + +class CreateScopeDlg : public CreateScopeDlgBase +{ + Q_OBJECT + +public: + CreateScopeDlg( QMakeScopeItem* item, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CreateScopeDlg(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void accept(); +private: + QMakeScopeItem* m_item; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/createscopedlgbase.ui b/buildtools/qmake/createscopedlgbase.ui new file mode 100644 index 00000000..244589cd --- /dev/null +++ b/buildtools/qmake/createscopedlgbase.ui @@ -0,0 +1,329 @@ + +CreateScopeDlgBase + + + CreateScopeDlgBase + + + + 0 + 0 + 348 + 208 + + + + Create Scope + + + + unnamed + + + + layout4 + + + + unnamed + + + + textLabel1 + + + Scopetype: + + + + + + Simple Scope + + + + + Function Scope + + + + + Include File + + + + comboScopeType + + + Choose between the different types of new scopes + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 95 + 20 + + + + + + + + groupBox1 + + + Scope Settings + + + + unnamed + + + + widgetStack1 + + + + simplePage + + + 0 + + + + unnamed + + + + editScopeName + + + Specify the new scope name + + + + + textLabel2 + + + Scopename: + + + editScopeName + + + + + + + funcPage + + + 1 + + + + unnamed + + + + editFunction + + + + + textLabel3 + + + Function: + + + editFunction + + + Specify the function name + + + + + textLabel4 + + + Arguments: + + + editArguments + + + Specify the list of function arguments, delimited by a comma + + + + + editArguments + + + + + + + incPage + + + 2 + + + + unnamed + + + + incUrl + + + StrongFocus + + + *.pri + + + 25 + + + Choose the .pri file to include + + + + + textLabel5 + + + Include File: + + + incUrl + + + + + checkNotInc + + + &use !include instead of include + + + Use !include instead of include for the function scope + + + + + + + + + + layout3 + + + + unnamed + + + + spacer2 + + + Horizontal + + + Expanding + + + + 150 + 20 + + + + + + buttonOk + + + O&K + + + true + + + true + + + + + buttonCancel + + + Ca&ncel + + + true + + + + + + + + + + + comboScopeType + activated(int) + widgetStack1 + raiseWidget(int) + + + buttonOk + clicked() + CreateScopeDlgBase + accept() + + + buttonCancel + clicked() + CreateScopeDlgBase + reject() + + + + editFunction + editArguments + comboScopeType + buttonOk + buttonCancel + editScopeName + incUrl + checkNotInc + + + + kcombobox.h + klineedit.h + klineedit.h + klineedit.h + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/qmake/disablesubprojectdlg.cpp b/buildtools/qmake/disablesubprojectdlg.cpp new file mode 100644 index 00000000..335bf33f --- /dev/null +++ b/buildtools/qmake/disablesubprojectdlg.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "disablesubprojectdlg.h" +#include +#include +#include "scope.h" +#include "qmakescopeitem.h" + +DisableSubprojectDlg::DisableSubprojectDlg( const QStringList& projects, QWidget* parent, const char* name, WFlags fl ) + : DisableSubprojectDlgBase( parent, name, fl ) +{ + for( QStringList::const_iterator it = projects.begin(); it != projects.end(); ++it ) + { + new QCheckListItem(subprojects_view, *it, QCheckListItem::CheckBox); + } +} + +DisableSubprojectDlg::~DisableSubprojectDlg() +{ +} + +QStringList DisableSubprojectDlg::selectedProjects() +{ + QStringList result; + QListViewItem* item = subprojects_view->firstChild(); + while( item ) + { + QCheckListItem* ci = dynamic_cast(item); + if( ci && ci->isOn() ) + { + result << ci->text(0); + } + item = item->nextSibling(); + } + return result; +} + +#include "disablesubprojectdlg.moc" + + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/disablesubprojectdlg.h b/buildtools/qmake/disablesubprojectdlg.h new file mode 100644 index 00000000..13a27468 --- /dev/null +++ b/buildtools/qmake/disablesubprojectdlg.h @@ -0,0 +1,42 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef DISABLESUBPROJECTDLG_H +#define DISABLESUBPROJECTDLG_H + +#include "disablesubprojectdlgbase.h" + +class DisableSubprojectDlg : public DisableSubprojectDlgBase +{ + Q_OBJECT + +public: + DisableSubprojectDlg( const QStringList& projects, QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~DisableSubprojectDlg(); + /*$PUBLIC_FUNCTIONS$*/ + + QStringList selectedProjects(); + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +}; + +#endif + + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/disablesubprojectdlgbase.ui b/buildtools/qmake/disablesubprojectdlgbase.ui new file mode 100644 index 00000000..ffcc1d32 --- /dev/null +++ b/buildtools/qmake/disablesubprojectdlgbase.ui @@ -0,0 +1,126 @@ + +DisableSubprojectDlgBase + + + DisableSubprojectDlgBase + + + + 0 + 0 + 512 + 282 + + + + Select Subprojects to disable + + + + unnamed + + + + + Subprojects + + + true + + + true + + + + subprojects_view + + + LastColumn + + + + + Layout1 + + + + unnamed + + + 0 + + + 6 + + + + Horizontal Spacing2 + + + Horizontal + + + Expanding + + + + 20 + 20 + + + + + + buttonOk + + + O&K + + + true + + + true + + + + + buttonCancel + + + &Cancel + + + + + + true + + + + + + + + + + + buttonOk + clicked() + DisableSubprojectDlgBase + accept() + + + buttonCancel + clicked() + DisableSubprojectDlgBase + accept() + + + + + klistview.h + kpushbutton.h + kpushbutton.h + + diff --git a/buildtools/qmake/kdevtmakeproject.desktop b/buildtools/qmake/kdevtmakeproject.desktop new file mode 100644 index 00000000..f1921523 --- /dev/null +++ b/buildtools/qmake/kdevtmakeproject.desktop @@ -0,0 +1,91 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=TMake Project +Comment[br]=Rektras TMake +Comment[ca]=Projecte TMake +Comment[da]=TMake-projekt +Comment[de]=TMake-Projekt für KDevelop +Comment[el]=Έργο TMake +Comment[es]=Proyecto TMake +Comment[et]=TMake projekt +Comment[eu]=TMake proiektua +Comment[fa]=پروژۀ TMake +Comment[fr]=Projet avec TMake +Comment[ga]=Comhad tionscadail TMake +Comment[gl]=Proxecto TMake +Comment[hi]=टी-मेक परियोजना +Comment[hu]=TMake-projekt +Comment[is]=TMake verkefni +Comment[it]=Progetto per TMake +Comment[ja]=TMake プロジェクト +Comment[ms]=Projek TMake +Comment[nds]=TMake-Projekt +Comment[ne]=TMake परियोजना +Comment[nl]=TMake-project +Comment[pl]=Projekt: TMake +Comment[pt]=Projecto TMake +Comment[pt_BR]=Projeto TMake +Comment[ru]=Проект TMake +Comment[sk]=TMake projekt +Comment[sl]=Projekt TMake +Comment[sr]=TMake пројекат +Comment[sr@Latn]=TMake projekat +Comment[sv]=Tmake-projekt +Comment[ta]=டிமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи TMake +Comment[tr]=TMake Projesi +Comment[zh_CN]=TMake 工程 +Comment[zh_TW]=TMake 專案 +Name=KDevTMakeProject +Name[da]=KDevelop TMake-projekt +Name[de]=TMake-Projekt (KDevelop) +Name[hi]=के-डेव-टी-मेक-परियोजना +Name[nds]=TMake-Projekt (KDevelop) +Name[ne]=KDevTMake परियोजना +Name[pl]=KDevProjektTMake +Name[sk]=KDevTMakeProjekt +Name[sv]=KDevelop Tmake-projekt +Name[ta]=கெடெவ் டிமேக் பிராஜக்ட் +Name[tg]=KDevTСохтани лоиҳа +Name[zh_TW]=KDevelop TMake 專案 +GenericName=TMake Project +GenericName[br]=Raktres TMake +GenericName[ca]=Projecte TMake +GenericName[da]=TMake-projekt +GenericName[de]=TMake-Projekt +GenericName[el]=Έργο TMake +GenericName[es]=Proyecto TMake +GenericName[et]=TMake projekt +GenericName[eu]=TMake proiektua +GenericName[fa]=پروژۀ TMake +GenericName[fr]=Projet avec TMake +GenericName[ga]=Tionscadal TMake +GenericName[gl]=Proxecto TMake +GenericName[hi]=टी-मेक परियोजना +GenericName[hu]=TMake-projekt +GenericName[it]=Progetto per TMake +GenericName[ja]=TMake プロジェクト +GenericName[ms]=Projek TMake +GenericName[nds]=TMake-Projekt +GenericName[ne]=TMake परियोजना +GenericName[nl]=TMake-project +GenericName[pl]=Projekt: TMake +GenericName[pt]=Projecto TMake +GenericName[pt_BR]=Projeto TMake +GenericName[ru]=Проект TMake +GenericName[sk]=TMake projekt +GenericName[sl]=Projekt TMake +GenericName[sr]=TMake пројекат +GenericName[sr@Latn]=TMake projekat +GenericName[sv]=Tmake-projekt +GenericName[ta]=டிமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи TMake +GenericName[tr]=TMake Projesi +GenericName[zh_CN]=TMake 工程 +GenericName[zh_TW]=TMake 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevtrollproject +X-KDevelop-Version=5 +X-KDevelop-Args=TMake + diff --git a/buildtools/qmake/kdevtrollproject.desktop b/buildtools/qmake/kdevtrollproject.desktop new file mode 100644 index 00000000..5debaf34 --- /dev/null +++ b/buildtools/qmake/kdevtrollproject.desktop @@ -0,0 +1,95 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=QMake Project +Comment[br]=Raktres QMake +Comment[ca]=Projecte QMake +Comment[da]=QMake-projekt +Comment[de]=QMake-Projekt für KDevelop +Comment[el]=Έργο QMake +Comment[es]=Proyecto QMake +Comment[et]=QMake projekt +Comment[eu]=QMake proiektua +Comment[fa]=پروژۀ QMake +Comment[fr]=Projet avec QMake +Comment[ga]=Tionscadal QMake +Comment[gl]=Proxecto QMake +Comment[hi]=क्यू-मेक परियोजना +Comment[hu]=QMake-projekt +Comment[is]=QMake verkefni +Comment[it]=Progetto per QMake +Comment[ja]=QMake プロジェクト +Comment[ms]=Projek QMake +Comment[nds]=QMake-Projekt +Comment[ne]=QMake परियोजना +Comment[nl]=QMake-project +Comment[pa]=QMake ਪ੍ਰੋਜੈਕਟ +Comment[pl]=Projekt: QMake +Comment[pt]=Projecto QMake +Comment[pt_BR]=Projeto QMake +Comment[ru]=Проект QMake +Comment[sk]=QMake projekt +Comment[sl]=Projekt QMake +Comment[sr]=QMake пројекат +Comment[sr@Latn]=QMake projekat +Comment[sv]=Qmake-projekt +Comment[ta]=க்யுமேக் பிராஜக்ட் +Comment[tg]=Лоиҳаи QMake +Comment[tr]=QMake Projesi +Comment[uz]=QMake loyihasi +Comment[uz@cyrillic]=QMake лойиҳаси +Comment[zh_CN]=QMake 工程 +Comment[zh_TW]=QMake 專案 +Name=KDevTrollProject +Name[da]=KDevelop Troll-projekt +Name[de]=QMake-Projekt (KDevelop) +Name[hi]=के-डेव-ट्रॉल-परियोजना +Name[nds]=QMake-Projekt (KDevelop) +Name[ne]=KDevTroll परियोजना +Name[pl]=KDevProjektTroll +Name[sk]=KDevTrollProjekt +Name[sv]=KDevelop Troll-projekt +Name[ta]=கெடெவ் டிரால் பிராஜக்ட் +Name[zh_TW]=KDevelop Troll 專案 +GenericName=QMake Project +GenericName[br]=Raktres QMake +GenericName[ca]=Projecte QMake +GenericName[da]=QMake-projekt +GenericName[de]=QMake-Projekt +GenericName[el]=Έργο QMake +GenericName[es]=Proyecto QMake +GenericName[et]=QMake projekt +GenericName[eu]=QMake proiektua +GenericName[fa]=پروژۀ QMake +GenericName[fr]=Projet avec QMake +GenericName[ga]=Tionscadal QMake +GenericName[gl]=Proxecto QMake +GenericName[hi]=क्यू-मेक परियोजना +GenericName[hu]=QMake-projekt +GenericName[it]=Progetto per QMake +GenericName[ja]=QMake プロジェクト +GenericName[ms]=Projek QMake +GenericName[nds]=QMake-Projekt +GenericName[ne]=QMake परियोजना +GenericName[nl]=QMake-project +GenericName[pa]=QMake ਪ੍ਰੋਜੈਕਟ +GenericName[pl]=Projekt: QMake +GenericName[pt]=Projecto QMake +GenericName[pt_BR]=Projeto QMake +GenericName[ru]=Проект QMake +GenericName[sk]=QMake projekt +GenericName[sl]=Projekt QMake +GenericName[sr]=QMake пројекат +GenericName[sr@Latn]=QMake projekat +GenericName[sv]=Qmake-projekt +GenericName[ta]=க்யுமேக் பிராஜக்ட் +GenericName[tg]=Лоиҳаи QMake +GenericName[tr]=QMake Projesi +GenericName[uz]=QMake loyihasi +GenericName[uz@cyrillic]=QMake лойиҳаси +GenericName[zh_CN]=QMake 工程 +GenericName[zh_TW]=QMake 專案 +ServiceTypes=KDevelop/Project +X-KDE-Library=libkdevtrollproject +X-KDevelop-Version=5 +X-KDevelop-Args= diff --git a/buildtools/qmake/kdevtrollproject.rc b/buildtools/qmake/kdevtrollproject.rc new file mode 100644 index 00000000..8f6e0048 --- /dev/null +++ b/buildtools/qmake/kdevtrollproject.rc @@ -0,0 +1,33 @@ + + + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/buildtools/qmake/newwidgetdlg.cpp b/buildtools/qmake/newwidgetdlg.cpp new file mode 100644 index 00000000..7be62acd --- /dev/null +++ b/buildtools/qmake/newwidgetdlg.cpp @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright (C) 2002 by Jakob Simon-Gaarde * + * jsgaarde@tdcspace.dk * + * * + * 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 "newwidgetdlg.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define WIDGET_CAPTION_NAME "widget/property|name=caption/string" +#define WIDGET_CLASS_NAME "class" +#define WIDGET_SLOTS "slots" + +NewWidgetDlg::NewWidgetDlg(QStringList &newFileNames,QWidget* parent, const char* name, bool modal, WFlags fl) +: NewWidgetDlgBase(parent,name,modal,fl), +m_newFileNames(newFileNames) +//================================================= +{ +// Remove in kde 3.4 support + okayButton->setGuiItem(KStdGuiItem::ok()); + cancelButton->setGuiItem(KStdGuiItem::cancel()); +} + + +NewWidgetDlg::~NewWidgetDlg() +//============================================== +{ +} + + +void NewWidgetDlg::subclassingPressed() +//===================================== +{ + QMessageBox::information(0,"subclassing",""); +} + + +void NewWidgetDlg::templateSelChanged() +//===================================== +{ + QMessageBox::information(0,"template",""); +} + +void NewWidgetDlg::accept() +//========================= +{ + QDomDocument doc; + DomUtil::openDOMFile(doc,"/home/jsgaarde/programming/kdevelop/domapp/clean_dialog.ui"); + DomUtil::replaceText(doc,WIDGET_CLASS_NAME,"TestClass"); + DomUtil::replaceText(doc,WIDGET_CAPTION_NAME,"Test Dialog"); + QDomElement slotsElem = DomUtil::elementByPathExt(doc,WIDGET_SLOTS); + QDomNodeList slotnodes = slotsElem.childNodes(); + for (unsigned int i=0; i +NewWidgetDlgBase + + + NewWidgetDlgBase + + + + 0 + 0 + 650 + 474 + + + + + 5 + 7 + 0 + 0 + + + + New Widget + + + + unnamed + + + + cancelButton + + + &Cancel + + + + + GroupBox2 + + + Widget Properties + + + + unnamed + + + + subclassingCb + + + Subclassing + + + + + Layout5 + + + + unnamed + + + 0 + + + + captionLb + + + Caption: + + + + + subclassnameEd + + + + + TextLabel4 + + + Subclass name: + + + + + captionEd + + + + + ui_classnameEd + + + + 120 + 0 + + + + + + classnameLb + + + Class name: + + + + + + + previewLb + + + + 2 + 2 + 0 + 0 + + + + + 0 + 160 + + + + image0 + + + true + + + + + + New Item + + + + templateList + + + + + + + Spacer2 + + + Horizontal + + + Expanding + + + + 310 + 0 + + + + + + okayButton + + + &OK + + + + + + + 789cdd5c577362cb767e3fbf62eaf6db2d571ba148b9fc80028a244584cb0f9d480221b22497ffbb57afd06c103aa399a3721dfb72f7814f9bdddd2b876ee65ffff9a3512bfff8e7bffe31999a69d7fd701d33fef14f3f1b0cdefee33ffffdbffef8c7562ef7235e3b3bdb3ff2fff8973ffea1fc0ff743e5f07f88e7091f20ae09dec2fba69530dd778c77f8f959c274ff40303f7f9730ddb78c0fe879f39e30de770bc1fc7c89b1a3efbb7dc25bbc7ef7ca98d7632e111f24fa7209d3fc8f8279fce384e9fe94b1d0d74c98ee5705f3f36f09d3fd0963a64fd513a6fb05c1f4bced254cf49f09ced3f8278c997e7396307edf68c1349e3b4f18ef7b599fa3f15485b0f0cfdb84697d5b8c857ec398e9f13cdf16afc7aa88b792fcfc8031dff71709d37a5f05d37a7d8fb0ac271405337fde13a6e7f705333d0dc6bcde6004f3f3e78c451e0bc6c2cf36e13ccf6f4e190bfd63c4895e1308cbf77583317f5f3f30e6f9f43d637e3ee0f7f369fc304f98f897eeb37e2d18f378e13061d297316359df3de16dd1ffc098e7f3c78c793c37445c90efeb47c6f2fd66c2a41f79c662bf3dc6629ffcfd1d9127fa8bed2d19cf6e3116fedc3196f5ef254cf21e1296f1743361bc6feb8c793c8bf6b55d90e75d8fb03cefa709e3fdd0144cfc56fb8c65bdc58489fe9160febe622cf39f254ceb97fbc29f838469fd4f11ef6cc9f7435e30db8762cccfabd78489bea260d6774d7857f8759b307e5fe704f3fa5b8c77993faf82e97ea8332e307d57888d3c6f04f3f36e37615a9f15ccfee892318fa7b712267ed404f3fccf09d3fd05e1bd2d9e1fe5b79bdff5ccbf53c1ccbf47c1f902dedf26bcb7c5f33505f37c0f09d3fd57c1e46f429931f3c7dd33e6f92deaf36e5a5f7817bcbd85f79f19f3f3ea21615aff93609acf0e19337f5459303daf6f12a6f90f04f37a2d63e1cf96605eff7bc224afb9607ade05c2fbcc2f7f2698d77f9d30e9fbae607ade9f3016f923fd7bf9bdc236cac37518f3fcbe2d989f2f0ba6efab6dc269be5bc1fcfdd384697ccf98f96dca09d3f345c1fcfc3861d2971a63d6573f17ccfc7a13ccfc427ddb03fa49defe29615a4f9d31cfe74e13a6fb53c1ac2f8631cfa7af05f3f38384f179db15ccf3df244cfc6b3366f99bf384899e1dc1cc8f56c2f8bc1f09e6f12b840f581e6120989f47feed6fcbfabc134ccf872a6399af9330f1e34a30cf774758e6332f82e9799d4f98e84df7e979374a18ef9b29639647d009d3fc15c1f4bc318c999e702298e9a1f1ac3caf3463be6f1e1833bd6a2f6192df9b601eef967081e9f58782e9fbe646308f8ff67fb09dee3f0b667dba60ccf4eaba60e6cf56c2f4fc2363a6576f0be6f9761226f91e1136ec1f2c7fdfb0fd595cff8195f94c25617ade08dea1fb5dc6a2cfa58489ff82995fba9030c9ef52308d175a848df0e74930d37f9c303d9f632cfa712598e5f39830c90ff5adb023e3bb13c6c25f9d30cd5f154cebf3216183fad1616c985fdb09d3f81782e979f79c303e1f468c03eb575e30ebc37ec234dead601acf5608db3cc7f707c1cc8f90303d9f17ccf2d863bcc7cf1f254cfe662698e3a560c3f9ce5dc2a4ffbb82397ea1fc0a4ef8158e19337fc2a560a6679e307edf5e33667ea8ab84493e1dc1fc7c59f02ed6d3a14d38d1bb9330d94b4d30ebf375c224df73c6c28f8260e6877c7f8ffde34c30cf779a30f99b1bc1349fea33667e9a79c2c44f998ff9a95f13a67ce25230fb8b9260e6cf11e3c0f9dc4bc214af268279fc69c2e4bf9d60ce777612267dcd1176ac7fba97308d3f13ccf9c861c2c4cf3bc6ac7ff621618a571dc1fc3cf3d3317f1cd263923d98026191a71a264cfad4174cfae1cf198bfc1e0433ff6a82d97e0f13c6f15c5b308d675b8c595ebe9830c96b2c98f3839b84491f4f04b37e9e0966faea09937ebe09667af619b3bc552f61e29711ccfcdc4998d61704f3faaa09d37a8e05337f6682993f9384717d8671d28f61c2a41f5dc1ac7f8384e9fe5830eb773161f2670dc1ec2f4f13a678f52298d7779d30ae4f5718b3fee99030cdaf04f3fa5cc2747f2498ede32461b28f92608e47321edbbb6e254ce379c13c5f3f61aa2f647cd61f9f672cf23e4a98ec47e86779dbbd8449de587f1827faecbb8c59ffecbd60bedf17ccfa564f98eeef31667d315b8299fe8b84697c2798e4a30f1226fdc90966fb9a12167db1ed84899e8960d697fd84495fb605b37fde4d98d63b12ccf6964f98ec2d7d9fe3cb59c214dfee188b3fab264ceb3b16ccf2b50993fc851ed627bd4898d63716cceb3f4c98ecf34830f3f33c61f27f8f8279fd3b8c25fe0c12a6f518c1b4defa3461badf11ccf9727a9efd455930e7478d84291ebe0be6f55e244cfc147a257ebd254cf3cf05b33f3b4b98ee3f09667ebe274cf9475f30e717c584e93eebbf677fa58e05f37ca58449be0dc15c4fa13ddbe46ffc4430f1df29c62c4feb1326fb1809e6fca693308db710ccf6789030c5a71a6396573817ccfe232798f35f9730e99bac87e5a39e13267d9a09e6f9ab09d3fab6184b3e712198e5514d98e81d0866fdbe4a98f4e55630d70b9384c93e9f088b7cec4dc2a40fcf8239be9513267afb82591ebb09d3fc5dc15c0fdc274cf4ee30667bf55782391e61fcb3deeded917edf3066fe865ec2743f2798edb59230cd772d787f1bf16dc216d77fc458fcef2261a2e75e30fbdb43c1ac9f7b09d37aba82f768bf8ae4e9855fae9430f9dbbe60e6d776c2147f2f05337daf0993fef27c9efda1b18239ff6a0966fd7b4f98d6eb190b7fd17fb85d170e905fe188b08ca72e05f37a860993bedf326679d4a75a69a3d5efbe6bab1d5cebef3fbbe8d9ccf557d781b250dffe725fb8e2cbeb00d737cd4a71eb2ff32464aef477bc677f22d36f92497cff16b904dd42fe662ffafbf74bfc2772f90e9e2439988f57f63ecb6a69376dedbe63fe6fb417a757ed407d90d167df779967be412e7f992719dff4996cf8fa60577f3b7bd9eca33ef29be4d45ab3af6f92cab7d98b179f559fc2a70e6a4e37da027eb6681378c5bfc37b37ce4deff8c4dfc95e94eec1baba280b79efc01c4fbacf36d1d503b82ce027f8348814216dddbf99bd3cc30a15ad0e71570fd10e228543fd827fa35547bf35826ba0c748d184a8fa5bd98b42ad899ae6d1b2e96f434d31e625ca0aa530d05378454a46ac8933d2b7ef92cb5fcec786b0e239fade177c714e86abb7ac631d58fd026818eb57944b9449179f7bfb2e5ff62d7269c18a5ab8a2b8ea77586f115e87f03ad2c7fa4497e03ad567f03ad717fa12fe7ea5cb2897397ab46ff265df622f735dc1f53ce92aacf210565cd3757dad6ff4adbed3f7fa4137e07ad08fbaa9737a4be7f5b6ded1bbf0dd77a067ef7f35be50ec96f8ed327f979831048dd9072a0e74016e28fda88cb2cae1e594cf5cf16f16ee06d5526dd5d147aa8bd633c071b373b8b555ace3dfb21798a105974ffe9572a8aeea69a39e541f3e0dd4b31aaa1735526358ed04d7ecd494df676a0e97c76b4951bc16ea555fab37f5ae8aea500fd5913ad6bd7af40e237502144eb453a54c5da4b2b9c56fd80bc66a758a3c136ac06ed5997e51e7f07ea12ed5952a832c2ab07aafaab0f21a5c73f89cbd3cbed3ab0674d5912aa047dfab6b75a36e61ed33f0e271960efa3c075aabd49dfe4a4ef1557b11b91035f4a4c1d870a5ee754d3de83bd56019444a1ee16ac24aa749361ea98cef39a4845ed524a32d9557604340cf15f839a00238a550fa1d9827238fbf682f3e632f74b540ee4a81f5aa5db5a7f6515f68e5f58c1cdc868b6473c0b4cc819aa62ac0522245c6c4ffdf186b1c7aeb18a7ba20abea4fedf957eca59fb90c7ad117bd301e2ce4c104584513d65480ff3679b5510659b988bd084573a48234112ed382ff16a27c4c5bdf980e8c3c80b9233506e4d2f92cf7fecdf8229ae5c1fbb6c0daabfac874f52de846e428ad26aeb09ef15bcbd52fed67796f96b19d1a3e7f007f07eb313df3a4774d1f5608be0566ec26ddf8495efd257b8916cf323103786f0325cf60eb16f95e4f3cf688a34ce6c96eaa19fba8a17ce691dd20078fa8c074d5f01dbd81199a17333231631b9a81996caa797ed35ec47f88ddb4f5a199ea06f2b7ce16d084753493ad08bfe76bafa52dcdf8bdc0eb772b76e654de1833839cc7821e543ef412c287f57ddd5e3af8fd9656660ee31fe96bb3483e09a831af448179636da921752ef9ae498a9ae01dcc3b0cb9a46f66ded3f78803e4a9c7a6680ed5c01c61be36446d33baa7fa7fd15e623c8959e00bdac9543fe0cc05d40db2802893a8f7c7a0f5d5f4576b4e4c4955c0a21be61424b98008e4e465ced86666186b2cda5a93e509583f9a73b09b0ba026ad247a6af4d6bf6f2f1db0bfa8e451bb9e99921c4ac59b4bd2fb2893a585030d01d67265caa662aaa6069eb66eaee1d38dce9b5b88250b96d3ccdcb1dd57d97eaa38ce0ca9bd370f10bfc65cd57563bc9118b3eedbbe6c2f2fe622d685a6611ec1e21dc77689e59ef9db645dafc01a9ae6d9e44047ee81b35b90332fe055d665d3006ee4cdb6d931bb660f640663997d8c3873b623d2bc038aa1face1ca84ba0c6a5573753ef848f72f999bd809540fe67c6a600c1d7a24c222dde2ab08418556aaa091a833aa5e03fd65a67bddeb7c1b66cbb3e351758c9c42aba873ce9ab5bdb3155db85fc6d413edbf630428907885a3781d1ac7db27dc859c758c175b026edacf7a27fc95ebc99db813eb7cf104f7c8aed31168a078655989259d8a17db1233bb690dfd8b6eeda295a2de5d301fb2f2dc403e38cb7333bb70b8cb61ec79de1b8758eb41e680129db5733b2548f8e309f7ecaf8ae95fedb57ec45c50cefd9bee1ac53f24b682739b217fb1ee7b5457b08741c45dbb2c7f569bc8083167522d4a75c41f771051e32ae437b624bf6d474ec993d477a482ef5943fd4316b58d80b5db6037b895569ac0f36f4e13eb117b782806e73a42e4c07f2aee82b27c94a3cdbc80429b9b265a037d88aad9a23886f437b8cba1d3b16432db943acef6325ed319ebfe8be3a01ddedd81ada8e63bbab27df1865ee6cdd5eeb2b1b50cf62b5bdb63eb19bacbde085392970f5065710b32f63dbf6d6de61e6b8cc5222d7c06ea24c40f3b6ed3dc49d05ca213b16d51d31cf7e025feae0d3dc3ec46aa13ee5ee6bd736ccd83e4234016ae0a1038e4d8e3d74f435d63675940a4818a59d1ddf6fb017d23b8ef178778833e7e0d3425dd92dcce76b1cd5a6999aa4a2ae6d5e455f35415e0f3ff898168cd243b94ce0d55103bb6d77ec2ef0b96ff7e089992eda7d7b80d167b692b771be600b40b882da2f44fdd5215e5a313756ec654d2e0e31d002fc9beba133ea5e95a13e89d1718e71708a7491079e386beaaa68636745adea70b2b73398fd06fe0b3ecc393373def45cd067e09f5ec9c3aa43d7726d18a994ea50d1308cbcf6dc75c01681578e7b6ff529cba5bfc15e967ae770fc1e7e07b206e0770da3ca947936656e45adb6aee79eec295684d421f2cc896c8f1fb20f5582bf4f5ddfe4dc007b010b5384eaa7ab5fcd857d80e7c6fadc3ddbb3186739cecc967251ce0ddd0b649bedfa34c517d6a13f970b522b18aa093742e94f52fd4eb92fe8b11bebbaedb07605f6bea2bfcbdc760e79c80b54f0b76ee2a61851a21731a66867ceb959e401e459afaea5eb6e8c5c9bb3ddd01575a1a25e6ccc36bba05fd9fd9bfea7f642f4ced07b7a908983ec2e0f114d6ac6097b9b98cd3bd08832483ea0a70afa0dac62c8fd61b7d6cf1feaa9eaaa5d37c78a07b2140714b957f7a6cf80db90ed458b5210c3dc3b663712ff4536e0715cd11d02e547988f59b615b936ca85fd4bbf4e7de10e3c7d8cdebf4039125a7d0db2afc8ab7d77e24a9015185809d59b5d8864129703d43a1419a3b4ae6025a75126e6dd9d012de7902958fde006e0c3c6ea10b40c9eb6bbeec2f4909a6ab219cf9e6dec2e21beb6d0fa891aaa799de4672bf145ecc5215fa3d779b7a74ae3c833b5eca550d7a1628d812801f16480eb35dc4319f058ad5883f298637de6aec04e809254db78d6b45b88ff25eca70757d627aec2fd03a973a4d6713aaf9ed5ce8a0f53eb72f910473ba8fd91f6a23e5731ebaaa5de8a64e5608d9076555d6d59f7896fc15a7daedfa25c30aa94ad737594ee2ce5f9527581a69aa2bbb6bb205f18c1dda837f43413c964f81df233b56f3b9019058cc24eabac5c32f6e256628cc34c307e2eba5b1c59b2f959e2a9354dc82027c8a5a5cfa2712287ef7485ec07e27accf31729bf2e485586b137f2bbe1eedd036827f0cf9e981964012798c32efb3971e65803d420cfab6204eb7e2e17d171de59205db4aea1ebe841973279441979a8fb9eadb76d57dbb00719fbcb6ff08a9ea06c46ee1129b1189fb836e14c32c60f882aaee9727680dcacea63b765dae899e7ecc3880b1efcf8237832ca5497e706d6ed45e4d2c2cfb1c3463a79e8de507b853f73aeb840c34c4eef6b6b8f5132ab7b906f6829b11b78a58fcd0b7af45449732e2c7950acdcdacebb3ce8738c155db76deadc1759e6169eba346ec78cd1b2b2f6dd5f938b9c4f21deb6317f0bb1dfa26f60d4a9f229bb8f72c9c1a8bb6e0fbc31ed3d9a9578425e00bc30d46e79b7c3da2575499573e13952073c77fb3aaf4b9003d09eda8b5ec0c89a39982a3ea86f7ccccb20da19b67ee911adc797a55c025acb13e87afc74e40e567af52417c88bc102ee5dc192e7cec679b29b2ec8f6ca4dd4b6a75535590acb6a8b2cda99606ecdcc34ec896ec7c8015135f6fab6d7e432a728e09519a99db59d34af3fb117b81cd6d74394cbb1becb7458a72c97b939f1062aa4367ccbe28e6ad259b4b70e585c19f2ae9d4889b7cc893a6b19ad0ef32c13bc53bb503d2bee21473f02551a58e916e7c9443dd16255de7b1b2be6e8cb643ebfa17e71593f06fcf130fe09772a66ab7251151fa08e076b513de45236fe3a3d76db6ee25bd16b002533b68dd57e7ff44b25df062dbc01bbf290cf4d584307ae01d592e1e82fcf92958e4ddd62ee9ff1639bea4a976229f9ee21c8e5047b7a32a678e48969aba12e9a0bb63ec87780a78677ec604ac856a6c8598b598fc4a41c5b402d5a8a3df71ddf059b8b73cf40effb3cce047cd519cc40f34e1217d17bdb7b4b3eac8d6b0d1fea1791c720c9867cc408c63c5dd55bf29240e10dcc083516e4b8f1bb3daa3fd1c38cad4bf1a4c97ce52e385102763cf73dffe4fbd6c72e2b6618919a58c9f8a8a160416db6fda5adc24b3720c2ecc78a2cee3669c5be73935c9856cedae3b98953d0319f6a71910bd062eae01da98e8f7ade5367aa046b993807d94a9dfb11d2eb9fb34ca2a6e648f7fdc03ffb2154d52dacf97a2897aeba437e2efc4b461fa48e454f01fab0bf2e97157b913c4ce412efcfa2de03171ed2484bb9007fa0a629933470155023c49d39756b6a7e04d98a8508a839ffc8fa2ea9150be065cfcd2de49b55f0b10fee0e2ae7125bcd087c1ae918d9a97468638c825a0a79a878adad757b497d40b297c05d4e17f516339855eb8fef0b53055a869c27807d41a93e55b76ad78f31efaa638ccfc17f0b240b5e158d95c34eba530d73eba3249dcd410c883b54313fef40d6b38d3a3a632d937c3946e83acbc57e622fe27f5cb2178be7572093d2cd157ba1cfb13779631aa0539427f8b8df672c545a735a037ad079eafdcf33cf4b4f7f869da910a95183a8a52ce5ae1e012d076e1f75f380b9d8241efa29d2a230eb77595b59938b4bb4aad8b7859834864a2ec7d5572ee3cbea31ff8648dd055aa29697f42cfa2edb454f1af763a8435e55d2bb8fcf7b257bcbe4639be8e3c6beed67fa1d32cbd8f5807c01e63df473ec95d7388f957cc1aa57bf203f96d9b3db54bf2ce5d283911d8c39d597fe1533d65477630c7e0769cf416633ac5c14f8b227338378829516f7ed675c7bc8cab3fb6213b5dc9d9840ce3f056acae89762ded086d85ec6fe127d676975d6d6a0d619a7b82f76bea9aeb4c98f7571cf6504b9658533a31af590e30c71af543f9a0e64b65849838694637a01df3bf0a45d13f663a4a1d10b8b9cbc92be175dd3989199b27f37635fc4a8d6f11eabfe264b257579210bac9811d475d9b3b59beb7d95b117dec5370d7fc815fa9c77e864d7c5e80258cc007939f347fe1869a69dbc3ad252672df7ecd10a5c8165f7cea4ba5c78a85b629f052365b47c9faa64e9ca38b5e54bd82757985d66fa79abf165ad37d68fbd4b90cec274cc3dcc55e5fdf819f7c8c0e7fa53fb0879ba43af5cf4d18b5ab770e7e47ba09aaf2baa4fd063f91ef277861ca11a556a22f2070bc843176029e7766421073497ac9753e482f717e8c56a2eeabecde8d1267bc9d6d0333c21721673567bea2f15755f97fb8f3eee50983d53852c30d23ef390139b629420dcc18cd8bcb32c3cf2f3c997d5183fcf9092b5fd7fcc3f17a6acdeec0c62ce38555fcd94c94d807f2d88ad7472216b2b7f2e173af91575b7afaf7c85b3f60c35d1fa4dc9767d15e25a0fabb743fbe8c76e1f4fee5074e1fa04f2d09aaffb6b778a6733ea6acedae3d2fe3ff9280bdfbcf1b7306a0f635153e5403a3945f5ce1434e1cef5d50eee1e28aeb33ef6c7a4672972910aab027173e04ed28e025123bbd94e8ddcb32d61efdee9577f6f67a608b907f5b7a4660cfed43f580f1cbd872c6dbc127165af9fb516e4d3f08fbe99bc9dec20e25826b8139f3373bf855c0f18fb47ebf125d593cb33c60ebf1d6bdd01d4eb45b665ca3eb0978275dec22eec29ea63ec09bd9a0664fa1df4159eec4437dc95c9c7fa13f2ae7d3f416a265ca72e7725a29c9b98a7d18eed257cbe54d48bcbb10c27ae683bd8513219b98c3ef493b3bde4e5157c5e57dc91dfc61e9d679b218ecfd4818d7ad68ef991df8138d7d3cf1eaa2afb087562097d53ec16c5ac660faac581df77c6397fe0db2b75aaf4bf3c7a851a72c82305cb1c90bc4705c6b5be907691e39a1dca65a3bd6cdaa385cf45df076bb460d51287a38c649f64df5c9b317ab3987fcf6c09a939053a4e2137385303b641f2a06575032a20fb46b27b2e14496e3157d96c36f62d9c3d33dbfa8af2dfd87f3383a0b006b61ffa637ff61ad911d4df9518f34c4bc9ee1b65215e356c0d328078926dae8e22352e6ada996bfa337d6a77b587ac2066bf3d7c3d417c3f058f07194230187bce56f270c9da9aca67fe6e4d2958882cf184739f7bfbcb9ee807b9fcc97ea573ce1442e464016879645bacb24638a8fddb66dbb5f448f56186b9ee061f426885b67a072f17f78efba1837add03aade4d2374d53558955dd1b666e6dd73dca12bd60f3d7762fa7a6873d807b52b7af32bfbfb56ed849eebe06e528deb7df169b4021b9e5c5b9feb29f66e8399eb4ee81bdac7a65346b1fa2d01277b71efc296628726c656eee8adcb6599937b1e7f003986d395a0300288bffd8dfd7d48f316eec53ee1e892472d3d74ecdb6d8567f71c86601d5d9b8b7d0fdc05838ad3de70b61ac20b5013772fe229bab25fb837f47805ecb77d944d73498b5761e4ca3617c6d80b5dd62ebfb1bf6f0620994998a6ae9d64f39c5721b925b0ce1b90cd15eebf2bac46e26cb1e3d3b20f61861d6a1f6bae1819c0aa0edd34cc39be6f7a516fd341fd59c55c89f60dfccafece87fae567fbfb71d7322cfc83bee13d2d393122d56f3c6b143b9063a804aafac46dc7332c51abc182700737bc207506e51269ecba6a780d6fe11d7de2267bf1d83b77a1180e5ddb35a422c8d84bf8757bb1c7e6c81e83648ec2b1ca533ce6bd07c731146b4d3c256155de55dca18995da3e584bcc32bafa055780792078b436bc16fa085638f5cd0d5e4c2ca5c99fc7e1c4e4819a57aca0973dcb0fbf79fada79fefad419b5e35c28b95e92cc9ce79af0994ad2711b4fe4d82664e707e61032971148097f07a3069081348c371ee27f379cbab18f63e592947dfaafc85cec06e26438d347317fc02cd1a6b812b01a345fb7173d08e71a7b4ce1c2bcd8ad14e99aa2d3c98e6a8c2aba0114695336cfe152efc433fd1025afd49e3f0b6588bc8bf48cf8c58f92c99c35376dd0de9cba05afd1036f223d23957ee7f4e5f8a2db76e26a16f2533bb00e1ea29caac95926adbea9e8ac6e15abcae86d21c241846fd873a0ab611670058c2a48059fa799731ebcecb5f81599905c22c716fe1434f72ae58bcbdfff855f892f404bc0bd6890ae19c77cd70d71451395faf56ad9095cefb92cdfe97301655a4b75e33473afce1ab62a971966070b3f3723dc7fa475498cd9b8bfffd97bb4563c41751cadc6fa5009d598a1a909cc5150cb7d78b9aadcb958e2033eed963d554a19249ddb5ada4a7d835ca0c28b72d60fa16643e63c8c59cd1fbf622fbea0abdac63d1c1bfbfa166c7864e2b9f7e52f0f64cf57e423a73f2406656a5296256a156ada261ff6e1cc39686bcccaeae17a997fadc8e78bf1054f3a44c9c41dbdaaaea8beb90837e600328106dacd2347cfa95a9e4f4ebb79c0d333aa4fb07eab738f46f6da72fc3dde6d0ac58ced64fb01b182e8855bc84d2799fdea5f8e2f7ecbcce17501686826e12edcfb7d888697e63a3c70cd99958bec98644fc4bb957bcb6e77532dbb802ec6f8d0c05f9dacf93188fd25736f20fbd0639685cbd8cb86f3639fdacbeac57b9aaeaa77adb317b68eddc0cc09a9150f2bbb0e2233cab267a95e21ff57c7ce8e3255d78645d1ce4d3afd0bf50664cae1112829c61c2fb3ae95fdeb2f9ee75f3bb31d3bd8e011c67637f4f5692887a69273e475ae1357f6053299bd74a57cc68791fe0cc248175dd5e4cd2e7640cf3cd1037edc28f3a48ff0345c2fed0f7df8bdf3577f2fb67275b1af3982ace215f4f730e440e01d88a10d96411dfbbf55dbb33d3cb79cdd89aae2abee2fc06e2698f954ec59d882faa4e1cab1ea750d7fe0e65177e33da2d31d87219eefefc73317ebb5ef2fc497e52b5b2fe0af0ce31948b8dad1b3854b370879888713deadcdca65dd57f1efc6ccc215a1a2ded6875069c53dd29843bfaa779373733c2361ddbeb977c7fa08aba1e5997197f55f59b9fc3c1f5bf5e37cde78807a06f117a24e0fdeafcca1effb921b28981f4f867ffcf51bfdf22dfef62def2fcd7968d98ebdc53a7e0895d638e0ef4d6d50b790cd9debfb28135d473b19f3391b857d9895dfa4ff4a7cf9c003fa55ee047f6535897591adaa1ee44a4520cb9b43db3135f3e876c2b65790378f3187092083b19faa575bd3795f32b53051b73ea776207ab958c105e5f331b7c21ed54e3c7b126a104f6ea3ef021c6532e49330ebbf25fc157bc9fc1b23743682cf823fc51e22f5055dd75cd8b63ab72d88a9f177ad0b33365e1f796fef21eba9411d5030757de01776663bfad06d836ec62a349e4119d4a7bc52ac47f1f30034f8125e033c011fcf1078f63a935f389fbc49266b1756c05ddd8ffa1b730acbfbfc985f809784881aebad98f18ce115a096d9078ddfc773f121ee52c15ab903c17b5c74ce93cf7ae289e22e563df48bc13ef646e3aed984bbf7abbeecebf165eddf7ff9d4c7595a199f5791735eddcc6f2357ff7d98ecef2557ffeed6f462e5b9cfd6f90bf6b27e65e20ef256f1ea48a387994ba8fbf09e7af6ab7b29ab7d96e59ccbb37c1bedf8977e8fbc41362bbd10e19d4bab240da2dfec679fcbc66b3997b9cc29f8df27d9a013cbded81afe727c59fa8a55b9acc6dde5bdd57f2bc1613f7ef0e1391977d9835cf65696673eb3e76c5c668c0d31e68bf9585897cd8a5c3ef9379236c5e71519b613ffc3fa3cebb12d53e367f1cab85f944b6b03ffb3325bb7a3d51c61f5dcdf92c724afd1da5c9ffd8e72b34c7eadde8fef2dfd718f66c913f99d325db28718dfe9372fd95f00f3fd956bdd6fd17cab72cdcc9be402df0b3be157ed6595a7eb79c0f2f7ca2ef1dcf1af76567fcfbc49861ffd53d66e3eca7e2927f85e50ab72f96a8efc2b79dbbace7ff5fe67f36db4a1aceffb7a7cf93ff1faa67f7fec6ff1feff4a2efffd6f7ffc0f54dd11fd + + + + + okayButton + pressed() + NewWidgetDlgBase + accept() + + + cancelButton + pressed() + NewWidgetDlgBase + reject() + + + templateList + selectionChanged() + NewWidgetDlgBase + templateSelChanged() + + + subclassingCb + pressed() + NewWidgetDlgBase + subclassingPressed() + + + + templateList + subclassingCb + ui_classnameEd + captionEd + subclassnameEd + okayButton + cancelButton + + + kdialog.h + kpushbutton.h + + + subclassingPressed() + templateSelChanged() + + + + diff --git a/buildtools/qmake/projectconfigurationdlg.cpp b/buildtools/qmake/projectconfigurationdlg.cpp new file mode 100644 index 00000000..b76fc3a5 --- /dev/null +++ b/buildtools/qmake/projectconfigurationdlg.cpp @@ -0,0 +1,2174 @@ +/*************************************************************************** +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jsgaarde@tdcspace.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "projectconfigurationdlg.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "trollprojectwidget.h" +#include "trollprojectpart.h" +#include "qmakescopeitem.h" +#include "scope.h" +#include "urlutil.h" + +InsideCheckListItem::InsideCheckListItem( QListView *parent, QMakeScopeItem *item, ProjectConfigurationDlg *config ) : + QCheckListItem( parent, item->relativePath().endsWith("/") ? item->relativePath().right( item->relativePath().length() - 1 ) : item->relativePath(), QCheckListItem::CheckBox ) +{ + prjItem = item; + m_config = config; +} + +InsideCheckListItem::InsideCheckListItem( QListView *parent, QListViewItem *after, QMakeScopeItem *item, ProjectConfigurationDlg *config ) : + QCheckListItem( parent, + after, + item->relativePath(), QCheckListItem::CheckBox ) +{ + prjItem = item; + m_config = config; +} + +//check or uncheck dependency to currently checked or unchecked library +void InsideCheckListItem::stateChange( bool state ) +{ + if ( listView() == m_config->insidelib_listview ) + { + QListViewItemIterator it( m_config->intDeps_view ); + while ( it.current() ) + { + InsideCheckListItem * chi = dynamic_cast( it.current() ); + if ( chi ) + if ( chi->prjItem == prjItem ) + chi->setOn( state ); + ++it; + } + } +} + +CustomVarListItem::CustomVarListItem(QListView* parent, unsigned int id, QMap var) + : KListViewItem(parent), m_key(id) +{ + setText(0, var["var"]); + setText(1, var["op"]); + setText(2, var["values"]); +} + +QString CustomVarListItem::key(int column, bool ascending) const +{ + if( column == 0) + return QString::number(m_key); + return KListViewItem::key(column, ascending); +} + +ProjectConfigurationDlg::ProjectConfigurationDlg( QListView *_prjList, TrollProjectWidget* _prjWidget, QWidget* parent, const char* name, bool modal, WFlags fl ) + : ProjectConfigurationDlgBase( parent, name, modal, fl | Qt::WStyle_Tool ), myProjectItem(0) +{ + prjList = _prjList; + prjWidget = _prjWidget; + // m_projectConfiguration = conf; + m_targetLibraryVersion->setValidator( new QRegExpValidator( + QRegExp( "\\d+(\\.\\d+)?(\\.\\d+)" ), this ) ); + customVariables->setSortColumn(0); + customVariables->setSortOrder(Qt::Ascending); + mocdir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + mocdir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + objdir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + objdir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + rccdir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + rccdir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + uidir_url->completionObject()->setMode(KURLCompletion::DirCompletion); + uidir_url->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + m_CWDEdit->completionObject()->setMode(KURLCompletion::DirCompletion); + m_CWDEdit->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); + m_targetPath->completionObject()->setMode(KURLCompletion::DirCompletion); + m_targetPath->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly ); +} + +void ProjectConfigurationDlg::updateSubproject( QMakeScopeItem* _item ) +{ + if ( myProjectItem && myProjectItem->scope ) + { + switch ( prjWidget->dialogSaveBehaviour() ) + { + case TrollProjectWidget::AlwaysSave: + apply(); + break; + case TrollProjectWidget::NeverSave: + break; + case TrollProjectWidget::Ask: + if ( !buttonApply->isEnabled() ) + break; + if ( KMessageBox::questionYesNo( 0, i18n( "Save the current subproject's configuration?" ), + i18n( "Save Configuration?" ) ) == KMessageBox::Yes ) + apply(); + break; + } + } + myProjectItem = _item; + updateControls(); + buttonApply->setEnabled( false ); +} + +ProjectConfigurationDlg::~ProjectConfigurationDlg() +{} + +void ProjectConfigurationDlg::updateProjectConfiguration() +{ + // Template + if ( myProjectItem->scope->scopeType() == Scope::ProjectScope ) + { + if ( radioApplication->isChecked() ) + { + if( myProjectItem->scope->variableValues("TEMPLATE").findIndex("app") == -1 ) + { + addAppDeps(); + removeSharedLibDeps(); + removeStaticLibDeps(); + } + myProjectItem->scope->setEqualOp( "TEMPLATE", "app" ); + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "staticlib" ); + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "dll" ); + myProjectItem->setPixmap( 0, SmallIcon( "qmake_app" ) ); + QString targetname = prjWidget->getCurrentOutputFilename(); + if( targetname.findRev("/") != -1 ) + targetname = targetname.right( targetname.length() - targetname.findRev("/") - 1 ); + DomUtil::writeEntry( *prjWidget->m_part->projectDom(), + "/kdevtrollproject/run/runarguments/"+targetname, m_editRunArguments->text() ); + DomUtil::writeEntry( *prjWidget->m_part->projectDom(), + "/kdevtrollproject/run/cwd/"+targetname, m_CWDEdit->url() ); + DomUtil::writeEntry( *prjWidget->m_part->projectDom(), + "/kdevtrollproject/run/debugarguments/"+targetname, m_editDebugArguments->text() ); + + } + else if ( radioLibrary->isChecked() ) + { + myProjectItem->scope->setEqualOp( "TEMPLATE", "lib" ); + if ( staticRadio->isOn() ) + { + if( myProjectItem->scope->variableValues("CONFIG").findIndex("dll") != -1 ) + { + addStaticLibDeps(); + removeSharedLibDeps(); + } + myProjectItem->addValue( "CONFIG", "staticlib" ); + myProjectItem->removeValue( "CONFIG", "dll" ); + if ( !myProjectItem->scope->listIsEmpty( myProjectItem->scope->variableValues( "VERSION" ) ) ) + { + myProjectItem->scope->removeVariable( "VERSION", "=" ); + myProjectItem->scope->removeVariable( "VERSION", "+=" ); + myProjectItem->scope->removeVariable( "VERSION", "-=" ); + } + } + if ( sharedRadio->isOn() ) + { + kdDebug(9024) << "Activating debug lib:" << myProjectItem->scope->variableValues("CONFIG") << endl; + if( myProjectItem->scope->variableValues("CONFIG").findIndex("dll") == -1 ) + { + addSharedLibDeps(); + removeStaticLibDeps(); + } + myProjectItem->addValue( "CONFIG", "dll" ); + myProjectItem->scope->setEqualOp( "VERSION", m_targetLibraryVersion->text() ); + if ( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 ) + myProjectItem->removeValue( "CONFIG", "staticlib" ); + } + if ( checkPlugin->isOn() ) + myProjectItem->addValue( "CONFIG", "plugin" ); + else + myProjectItem->removeValue( "CONFIG", "plugin" ); + if ( checkDesigner->isChecked() ) + myProjectItem->addValue( "CONFIG", "designer" ); + else + myProjectItem->removeValue( "CONFIG", "designer" ); + + myProjectItem->setPixmap( 0, SmallIcon( "qmake_lib" ) ); + removeAppDeps(); + } + else if ( radioSubdirs->isChecked() ) + { + if( myProjectItem->scope->variableValues("TEMPLATE").findIndex("subdirs") == -1 ) + { + removeSharedLibDeps(); + removeStaticLibDeps(); + removeAppDeps(); + } + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "dll" ); + if( myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 ) + myProjectItem->scope->removeFromPlusOp( "CONFIG", "staticlib" ); + myProjectItem->scope->setEqualOp( "TEMPLATE", "subdirs" ); + myProjectItem->setPixmap( 0, SmallIcon( "folder" ) ); + } + } + + // Buildmode + int releaseidx = myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "release" ); + int debugidx = myProjectItem->scope->variableValues( "CONFIG" ).findIndex( "debug" ); + if ( radioReleaseMode->isChecked() ) + { + if( releaseidx != -1 && releaseidx < debugidx ) + myProjectItem->removeValue( "CONFIG", "debug" ); + else if( debugidx != -1 ) + myProjectItem->removeValue( "CONFIG", "debug" ); + myProjectItem->addValue( "CONFIG", "release" ); + }else if( !checkDebugReleaseMode->isChecked() ) + myProjectItem->removeValue( "CONFIG", "release" ); + + if ( radioDebugMode->isChecked() ) + { + if( debugidx != -1 && debugidx < releaseidx ) + myProjectItem->removeValue( "CONFIG", "release" ); + else if( releaseidx != -1 ) + myProjectItem->removeValue( "CONFIG", "release" ); + myProjectItem->addValue( "CONFIG", "debug" ); + }else if( !checkDebugReleaseMode->isChecked() ) + myProjectItem->removeValue( "CONFIG", "debug" ); + + // requirements + if ( exceptionCheck->isChecked() ) + myProjectItem->addValue( "CONFIG", "exceptions" ); + else + myProjectItem->removeValue( "CONFIG", "exceptions" ); + if ( stlCheck->isChecked() ) + myProjectItem->addValue( "CONFIG", "stl" ); + else + myProjectItem->removeValue( "CONFIG", "stl" ); + if ( rttiCheck->isChecked() ) + myProjectItem->addValue( "CONFIG", "rtti" ); + else + myProjectItem->removeValue( "CONFIG", "rtti" ); + if ( checkQt->isChecked() ) + myProjectItem->addValue( "CONFIG", "qt" ); + else + myProjectItem->removeValue( "CONFIG", "qt" ); + if ( checkOpenGL->isChecked() ) + myProjectItem->addValue( "CONFIG", "opengl" ); + else + myProjectItem->removeValue( "CONFIG", "opengl" ); + if ( checkThread->isChecked() ) + myProjectItem->addValue( "CONFIG", "thread" ); + else + myProjectItem->removeValue( "CONFIG", "thread" ); + if ( checkX11->isChecked() ) + myProjectItem->addValue( "CONFIG", "x11" ); + else + myProjectItem->removeValue( "CONFIG", "x11" ); + if ( checkOrdered->isChecked() ) + myProjectItem->addValue( "CONFIG", "ordered" ); + else + myProjectItem->removeValue( "CONFIG", "ordered" ); + if ( checkLibtool->isChecked() ) + myProjectItem->addValue( "CONFIG", "compile_libtool" ); + else + myProjectItem->removeValue( "CONFIG", "compile_libtool" ); + + if ( checkConsole->isChecked() ) + myProjectItem->addValue( "CONFIG", "console" ); + else + myProjectItem->removeValue( "CONFIG", "console" ); + if ( checkPCH->isChecked() ) + myProjectItem->addValue( "CONFIG", "precompile_header" ); + else + myProjectItem->removeValue( "CONFIG", "precompile_header" ); + // Warnings + if ( checkWarning->isChecked() ) + { + myProjectItem->addValue( "CONFIG", "warn_on" ); + myProjectItem->removeValue( "CONFIG", "warn_off" ); + } + else + { + myProjectItem->addValue( "CONFIG", "warn_off" ); + myProjectItem->removeValue( "CONFIG", "warn_on" ); + } + if ( checkWindows->isChecked() ) + myProjectItem->addValue( "CONFIG", "windows" ); + else + myProjectItem->removeValue( "CONFIG", "windows" ); + + //Qt4 libs + if ( prjWidget->m_part->isQt4Project() ) + { + if ( checkDebugReleaseMode->isChecked() ) + myProjectItem->addValue( "CONFIG", "debug_and_release" ); + else + myProjectItem->removeValue( "CONFIG", "debug_and_release" ); + + if ( checkTestlib->isChecked() ) + myProjectItem->addValue( "CONFIG", "qtestlib" ); + else + myProjectItem->removeValue( "CONFIG", "qtestlib" ); + if ( checkAssistant->isChecked() ) + myProjectItem->addValue( "CONFIG", "assistant" ); + else + myProjectItem->removeValue( "CONFIG", "assistant" ); + if ( checkUiTools->isChecked() ) + myProjectItem->addValue( "CONFIG", "uitools" ); + else + myProjectItem->removeValue( "CONFIG", "uitools" ); + if ( checkQDBus->isChecked() ) + myProjectItem->addValue( "CONFIG", "dbus" ); + else + myProjectItem->removeValue( "CONFIG", "dbus" ); + if ( checkBuildAll->isChecked() ) + myProjectItem->addValue( "CONFIG", "build_all" ); + else + myProjectItem->removeValue( "CONFIG", "build_all" ); + if ( checkQtHelp->isChecked() ) + myProjectItem->addValue( "CONFIG", "help" ); + else + myProjectItem->removeValue( "CONFIG", "help" ); + + if ( checkQt4Core->isChecked() ) + myProjectItem->addValue( "QT", "core" ); + else + myProjectItem->removeValue( "QT", "core" ); + if ( checkQt4Gui->isChecked() ) + myProjectItem->addValue( "QT", "gui" ); + else + myProjectItem->removeValue( "QT", "gui" ); + if ( checkQt4SQL->isChecked() ) + myProjectItem->addValue( "QT", "sql" ); + else + myProjectItem->removeValue( "QT", "sql" ); + if ( checkQt4SVG->isChecked() ) + myProjectItem->addValue( "QT", "svg" ); + else + myProjectItem->removeValue( "QT", "svg" ); + if ( checkQt4XML->isChecked() ) + myProjectItem->addValue( "QT", "xml" ); + else + myProjectItem->removeValue( "QT", "xml" ); + if ( checkQt4Network->isChecked() ) + myProjectItem->addValue( "QT", "network" ); + else + myProjectItem->removeValue( "QT", "network" ); + if ( checkQt3Support->isChecked() ) + myProjectItem->addValue( "QT", "qt3support" ); + else + myProjectItem->removeValue( "QT", "qt3support" ); + if ( checkQt4OpenGL->isChecked() ) + myProjectItem->addValue( "QT", "opengl" ); + else + myProjectItem->removeValue( "QT", "opengl" ); + if ( checkQtScript->isChecked() ) + myProjectItem->addValue( "QT", "script" ); + else + myProjectItem->removeValue( "QT", "script" ); + if ( checkQtWebKit->isChecked() ) + myProjectItem->addValue( "QT", "webkit" ); + else + myProjectItem->removeValue( "QT", "webkit" ); + if ( checkQtXmlPatterns->isChecked() ) + myProjectItem->addValue( "QT", "xmlpatterns" ); + else + myProjectItem->removeValue( "QT", "xmlpatterns" ); + if ( checkPhonon->isChecked() ) + myProjectItem->addValue( "QT", "phonon" ); + else + myProjectItem->removeValue( "QT", "phonon" ); + } + + QStringList confValues = myProjectItem->scope->variableValues( "CONFIG" ); + QStringList extraValues = QStringList::split( " ", editConfigExtra->text() ); + for ( QStringList::iterator it = confValues.begin() ; it != confValues.end() ; ++it ) + { + if ( Scope::KnownConfigValues.findIndex( *it ) == -1 && extraValues.findIndex( *it ) == -1 ) + { + myProjectItem->scope->removeFromPlusOp( "CONFIG", *it ); + } + } + + for ( QStringList::iterator it = extraValues.begin() ; it != extraValues.end() ; ++it ) + { + if ( confValues.findIndex( *it ) == -1 ) + myProjectItem->scope->addToPlusOp( "CONFIG", *it ); + } + + QString targetpath = m_targetPath->url(); +// if( !QFileInfo( targetpath ).isRelative() ) +// targetpath = URLUtil::getRelativePath( myProjectItem->scope->projectDir(), targetpath ); + if( myProjectItem->scope->scopeType() == Scope::FunctionScope || myProjectItem->scope->scopeType() == Scope::SimpleScope ) + { + if( myProjectItem->scope->variableValues("TARGET").findIndex( m_targetOutputFile->text() ) == -1 ) + myProjectItem->scope->setEqualOp( "TARGET", QStringList( m_targetOutputFile->text() ) ); + if( myProjectItem->scope->variableValues("DESTDIR").findIndex( targetpath ) == -1 ) + myProjectItem->scope->setEqualOp( "DESTDIR", QStringList( targetpath ) ); + }else + { + myProjectItem->scope->setEqualOp( "TARGET", QStringList( m_targetOutputFile->text() ) ); + myProjectItem->scope->setEqualOp( "DESTDIR", QStringList( targetpath ) ); + } + + myProjectItem->updateValues( "DEFINES", QStringList::split( " ", m_defines->text() ) ); + myProjectItem->updateValues( "QMAKE_CXXFLAGS_DEBUG", QStringList::split( " ", m_debugFlags->text() ) ); + myProjectItem->updateValues( "QMAKE_CXXFLAGS_RELEASE", QStringList::split( " ", m_releaseFlags->text() ) ); + + //add selected includes + QStringList values; + InsideCheckListItem *insideItem = ( InsideCheckListItem * ) insideinc_listview->firstChild(); + while ( insideItem ) + { + if ( insideItem->isOn() ) + { + QString tmpInc = insideItem->prjItem->getIncAddPath( myProjectItem->scope->projectDir() ); + tmpInc = QDir::cleanDirPath( tmpInc ); + values << tmpInc; + + } + insideItem = ( InsideCheckListItem* ) insideItem->itemBelow(); + } + + QCheckListItem *outsideItem = ( QCheckListItem * ) outsideinc_listview->firstChild(); + while ( outsideItem ) + { + values << outsideItem->text( 0 ); + outsideItem = ( QCheckListItem* ) outsideItem->itemBelow(); + } +// myProjectItem->removeValues( "INCLUDEPATH", values ); + myProjectItem->updateValues( "INCLUDEPATH", values ); + + //target.install + if ( checkInstallTarget->isChecked() == true ) + { + myProjectItem->addValue( "INSTALLS", "target" ); + myProjectItem->scope->setEqualOp( "target.path", QStringList( m_InstallTargetPath->text() ) ); + } + else + { + myProjectItem->removeValue( "INSTALLS", "target" ); + myProjectItem->scope->removeVariable( "target.path", "=" ); + } + + //makefile + myProjectItem->scope->setEqualOp( "MAKEFILE", QStringList( makefile_url->url() ) ); + + //add libs to link + + values.clear(); + QStringList libPaths; + + //inside libs to link + insideItem = ( InsideCheckListItem * ) insidelib_listview->firstChild(); + while ( insideItem ) + { + if ( insideItem->isOn() ) + { + + QString tmpLib = insideItem->prjItem->getLibAddObject( myProjectItem->scope->projectDir() ); + if ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + //add path if shared lib is linked + QString tmpPath = insideItem->prjItem->getLibAddPath( + myProjectItem->scope->projectDir() ); + if ( tmpPath != "" ) + { + values << ("-L"+tmpPath) ; + } + } + values << tmpLib ; + + } + insideItem = ( InsideCheckListItem* ) insideItem->itemBelow(); + } + + //extra lib paths + QListViewItem *lvItem = outsidelibdir_listview->firstChild(); + while ( lvItem ) + { + values << ( "-L"+lvItem->text( 0 ) ); + lvItem = lvItem->itemBelow(); + } + + + //outside libs to link + outsideItem = ( QCheckListItem * ) outsidelib_listview->firstChild(); + while ( outsideItem ) + { + values << outsideItem->text( 0 ); + outsideItem = ( QCheckListItem* ) outsideItem->itemBelow(); + } + + +// myProjectItem->removeValues( "LIBS", values ); + myProjectItem->updateValues( "LIBS", values ); + + values.clear(); + + //external project dependencies + QListViewItem *depItem = extDeps_view->firstChild(); + while ( depItem ) + { + values << depItem->text( 0 ); + depItem = depItem->itemBelow(); + } + + //internal project dependencies + insideItem = dynamic_cast( intDeps_view->firstChild() ); + while ( insideItem ) + { + if ( insideItem->isOn() ) + { + if ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 + || ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex("dll") == -1 + && insideItem->prjItem->scope->variableValues( "TEMPLATE" ).findIndex("lib") != -1 ) ) + { + values << insideItem->prjItem->getLibAddObject( + myProjectItem->scope->projectDir() ); + } + else if ( insideItem->prjItem->scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + values << insideItem->prjItem->getSharedLibAddObject( + myProjectItem->scope->projectDir() ); + } + else + { + values << insideItem->prjItem->getApplicationObject( + myProjectItem->scope->projectDir() ); + } + } + insideItem = dynamic_cast( insideItem->itemBelow() ); + } +// myProjectItem->removeValues( "TARGETDEPS", values ); + myProjectItem->updateValues( "TARGETDEPS", values ); + + values.clear(); + //change build order + lvItem = buildorder_listview->firstChild(); + if ( lvItem && lvItem->itemBelow() && myProjectItem->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + { + + while ( lvItem ) + { + values << lvItem->text( 0 ); + lvItem = lvItem->itemBelow(); + } + + if( values != myProjectItem->scope->variableValues("SUBDIRS") ) + { + if ( myProjectItem->scope->isVariableReset( "SUBDIRS" ) ) + { + myProjectItem->scope->removeVariable( "SUBDIRS", "=" ); + myProjectItem->scope->setEqualOp( "SUBDIRS", values ); + } + else + { + myProjectItem->scope->removeVariable( "SUBDIRS", "+=" ); + myProjectItem->scope->setPlusOp( "SUBDIRS", values ); + } + } + } + + // intermediate locations + myProjectItem->scope->setEqualOp( "OBJECTS_DIR", QStringList( objdir_url->url() ) ); + myProjectItem->scope->setEqualOp( "UI_DIR", QStringList( uidir_url->url() ) ); + myProjectItem->scope->setEqualOp( "MOC_DIR", QStringList( mocdir_url->url() ) ); + myProjectItem->scope->setEqualOp( "RCC_DIR", QStringList( rccdir_url->url() ) ); + + //CORBA + myProjectItem->scope->setEqualOp( "IDL_COMPILER", QStringList( idlCmdEdit->url() ) ); + myProjectItem->updateValues( "IDL_OPTIONS", QStringList::split( " ", idlCmdOptionsEdit->text() ) ); + + QListViewItemIterator iter(customVariables); + for( ; iter.current() ; iter++ ) + { + QListViewItem* item = iter.current(); + myProjectItem->scope->updateCustomVariable( item->key(0, true).toUInt(), item->text(0), item->text(1), item->text(2) ); + } +} + +void ProjectConfigurationDlg::accept() +{ + if( buttonApply->isEnabled() ) + apply(); + myProjectItem = 0; + QDialog::accept(); +} + +void ProjectConfigurationDlg::reject() +{ + myProjectItem = 0; + QDialog::reject(); +} + + + +void ProjectConfigurationDlg::updateControls() +{ + // Project template + groupLibraries->setEnabled( false ); + if( myProjectItem->scope->scopeType() != Scope::ProjectScope ) + groupTemplate->setEnabled( false ); + else + groupTemplate->setEnabled( true ); + + //cache the value of the some variables + QStringList configValues = myProjectItem->scope->variableValues( "CONFIG" ); + QStringList templateValues = myProjectItem->scope->variableValues( "TEMPLATE" ); + //if( !myProjectItem->isScope ) + //{ + if ( templateValues.findIndex( "lib" ) != -1 ) + { + groupLibraries->setEnabled( true ); + + radioLibrary->setChecked( true ); + staticRadio->setChecked( true ); //default + + if ( configValues.findIndex( "staticlib" ) != -1 ) + { + staticRadio->setChecked( true ); + checkPlugin->setEnabled( false ); + checkDesigner->setEnabled( false ); + } + else + staticRadio->setChecked( false ); + if ( configValues.findIndex( "dll" ) != -1 ) + { + sharedRadio->setChecked( true ); + checkPlugin->setEnabled( true ); + if( prjWidget->m_part->isQt4Project() ) + checkDesigner->setEnabled( true ); + m_targetLibraryVersion->setText( myProjectItem->scope->variableValues( "VERSION" ).front() ); + } + else + { + sharedRadio->setChecked( false ); + m_targetLibraryVersion->setText( "" ); + } + + if( !staticRadio->isChecked() && !sharedRadio->isChecked() ) + { + staticRadio->setChecked( true ); + checkPlugin->setEnabled( false ); + checkDesigner->setEnabled( false ); + } + + if ( configValues.findIndex( "plugin" ) != -1 ) + checkPlugin->setChecked( true ); + else + checkPlugin->setChecked( false ); + if ( configValues.findIndex( "designer" ) != -1 ) + checkDesigner->setChecked( true ); + else + checkDesigner->setChecked( false ); + if ( configValues.findIndex( "compile_libtool" ) != -1 ) + checkLibtool->setChecked( true ); + else + checkLibtool->setChecked( false ); + } + else if ( templateValues.findIndex( "subdirs" ) != -1 ) + { + radioSubdirs->setChecked( true ); + }else + { + //Default is app mode + radioApplication->setChecked( true ); + if ( configValues.findIndex( "console" ) != -1 ) + { + checkConsole->setChecked( true ); + } + QString targetname = prjWidget->getCurrentOutputFilename(); + if( targetname.findRev("/") != -1 ) + targetname = targetname.right( targetname.length() - targetname.findRev("/") - 1 ); + m_editRunArguments->setText( DomUtil::readEntry( *prjWidget->m_part->projectDom(), "/kdevtrollproject/run/runarguments/"+targetname, "" ) ); + + QString dir = DomUtil::readEntry( *prjWidget->m_part->projectDom(), "/kdevtrollproject/run/cwd/"+targetname, "" ); + if( QFileInfo(dir).isRelative() ) + { + m_CWDEdit->completionObject()->setDir( myProjectItem->scope->projectDir() ); + m_CWDEdit->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + + m_CWDEdit->completionObject()->setDir( dir); + m_CWDEdit->fileDialog()->setURL( KURL( dir ) ); + } + m_CWDEdit->setURL( dir ); + + if( m_CWDEdit->url().isEmpty() ) + { + QString destdir = myProjectItem->m_widget->getCurrentDestDir(); + if( !destdir.startsWith( "/" ) ) + destdir = myProjectItem->m_widget->projectDirectory()+"/"+destdir; + m_CWDEdit->setURL( destdir.left( destdir.findRev("/") ) ); + m_CWDEdit->fileDialog()->setURL( KURL::fromPathOrURL( destdir.left( destdir.findRev("/") ) ) ); + } + m_editDebugArguments->setText( DomUtil::readEntry( *prjWidget->m_part->projectDom(), "/kdevtrollproject/run/debugarguments/"+targetname, "" ) ); + } + + // Buildmode + int debugidx = configValues.findIndex( "debug" ); + int releaseidx = configValues.findIndex( "release" ); + if ( debugidx != -1 && debugidx > releaseidx ) + { + radioDebugMode->setChecked( true ); + } + if ( releaseidx != -1 && releaseidx > debugidx ) + { + radioReleaseMode->setChecked( true ); + } + if ( configValues.findIndex( "debug_and_release" ) != -1 ) + { + checkDebugReleaseMode->setChecked( true ); + } + + // Requirements + if ( configValues.findIndex( "qt" ) != -1 ) + checkQt->setChecked( true ); + else + checkQt->setChecked( false ); + if ( configValues.findIndex( "opengl" ) != -1 ) + checkOpenGL->setChecked( true ); + else + checkOpenGL->setChecked( false ); + if ( configValues.findIndex( "thread" ) != -1 ) + checkThread->setChecked( true ); + else + checkThread->setChecked( false ); + if ( configValues.findIndex( "x11" ) != -1 ) + checkX11->setChecked( true ); + else + checkX11->setChecked( false ); + if ( configValues.findIndex( "ordered" ) != -1 ) + checkOrdered->setChecked( true ); + else + checkOrdered->setChecked( false ); + if ( configValues.findIndex( "exceptions" ) != -1 ) + exceptionCheck->setChecked( true ); + else + exceptionCheck->setChecked( false ); + if ( configValues.findIndex( "stl" ) != -1 ) + stlCheck->setChecked( true ); + else + stlCheck->setChecked( false ); + if ( configValues.findIndex( "rtti" ) != -1 ) + rttiCheck->setChecked( true ); + else + rttiCheck->setChecked( false ); + if ( configValues.findIndex( "precompile_header" ) != -1 ) + checkPCH->setChecked( true ); + else + checkPCH->setChecked( false ); + // Warnings + if ( configValues.findIndex( "warn_on" ) != -1 ) + { + checkWarning->setChecked( true ); + } + if ( configValues.findIndex( "warn_off" ) != -1 ) + { + checkWarning->setChecked( false ); + } + + if ( configValues.findIndex( "windows" ) != -1 ) + checkWindows->setChecked( true ); + else + checkWindows->setChecked( false ); + + //Qt4 libs + if ( prjWidget->m_part->isQt4Project() ) + { + + if ( configValues.findIndex( "assistant" ) != -1 ) + checkAssistant->setChecked( true ); + else + checkAssistant->setChecked( false ); + if ( configValues.findIndex( "qtestlib" ) != -1 ) + checkTestlib->setChecked( true ); + else + checkTestlib->setChecked( false ); + if ( configValues.findIndex( "uitools" ) != -1 ) + checkUiTools->setChecked( true ); + else + checkUiTools->setChecked( false ); + if ( configValues.findIndex( "dbus" ) != -1 ) + checkQDBus->setChecked( true ); + else + checkQDBus->setChecked( false ); + if ( configValues.findIndex( "build_all" ) != -1 ) + checkBuildAll->setChecked( true ); + else + checkBuildAll->setChecked( false ); + if ( configValues.findIndex( "help" ) != -1 ) + checkQtHelp->setChecked( true ); + else + checkQtHelp->setChecked( false ); + + QStringList qtLibs = myProjectItem->scope->variableValues( "QT" ); + if ( qtLibs.findIndex( "core" ) != -1 ) + checkQt4Core->setChecked( true ); + else + checkQt4Core->setChecked( false ); + if ( qtLibs.findIndex( "gui" ) != -1 ) + checkQt4Gui->setChecked( true ); + else + checkQt4Gui->setChecked( false ); + if ( qtLibs.findIndex( "sql" ) != -1 ) + checkQt4SQL->setChecked( true ); + else + checkQt4SQL->setChecked( false ); + if ( qtLibs.findIndex( "xml" ) != -1 ) + checkQt4XML->setChecked( true ); + else + checkQt4XML->setChecked( false ); + if ( qtLibs.findIndex( "network" ) != -1 ) + checkQt4Network->setChecked( true ); + else + checkQt4Network->setChecked( false ); + if ( qtLibs.findIndex( "svg" ) != -1 ) + checkQt4SVG->setChecked( true ); + else + checkQt4SVG->setChecked( false ); + if ( qtLibs.findIndex( "opengl" ) != -1 ) + checkQt4OpenGL->setChecked( true ); + else + checkQt4OpenGL->setChecked( false ); + if ( qtLibs.findIndex( "qt3support" ) != -1 ) + checkQt3Support->setChecked( true ); + else + checkQt3Support->setChecked( false ); + if ( qtLibs.findIndex( "script" ) != -1 ) + checkQtScript->setChecked( true ); + else + checkQtScript->setChecked( false ); + if ( qtLibs.findIndex( "phonon" ) != -1 ) + checkPhonon->setChecked( true ); + else + checkPhonon->setChecked( false ); + if ( qtLibs.findIndex( "webkit" ) != -1 ) + checkQtWebKit->setChecked( true ); + else + checkQtWebKit->setChecked( false ); + if ( qtLibs.findIndex( "xmlpatterns" ) != -1 ) + checkQtXmlPatterns->setChecked( true ); + else + checkQtXmlPatterns->setChecked( false ); + + checkDebugReleaseMode->setEnabled( true ); + checkBuildAll->setEnabled( true ); + groupQt4Libs->setEnabled( checkQt->isChecked() ); + rccdir_url->setEnabled( true ); + rccdir_label->setEnabled( true ); + } + + //fill the custom config edit + QStringList extraValues; + for ( QStringList::const_iterator it = configValues.begin() ; it != configValues.end() ; ++it ) + { + if ( Scope::KnownConfigValues.findIndex( *it ) == -1 ) + { + extraValues << *it; + } + } + editConfigExtra->setText( extraValues.join( " " ) ); + + QString dir = myProjectItem->scope->variableValues( "MAKEFILE" ).front(); + if( QFileInfo(dir).isRelative() ) + { + makefile_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + makefile_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + makefile_url->completionObject()->setDir( dir ); + makefile_url->fileDialog()->setURL( KURL( dir ) ); + } + makefile_url->setURL( dir ); + + if ( myProjectItem->scope->variableValues( "INSTALLS" ).findIndex( "target" ) != -1 ) + { + checkInstallTarget->setChecked( true ); + m_InstallTargetPath->setEnabled( true ); + } + else + { + checkInstallTarget->setChecked( false ); + m_InstallTargetPath->setEnabled( false ); + } + m_InstallTargetPath->setText( myProjectItem->scope->variableValues( "target.path" ).front() ); + + m_targetOutputFile->setText( myProjectItem->scope->variableValues( "TARGET" ).front() ); + + dir = myProjectItem->scope->variableValues( "DESTDIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + m_targetPath->completionObject()->setDir( myProjectItem->scope->projectDir() ); + m_targetPath->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + m_targetPath->completionObject()->setDir( dir ); + m_targetPath->fileDialog()->setURL( KURL( dir ) ); + } + m_targetPath->setURL( dir ); + + m_defines->setText( myProjectItem->scope->variableValues( "DEFINES" ).join( " " ) ); + m_debugFlags->setText( myProjectItem->scope->variableValues( "QMAKE_CXXFLAGS_DEBUG" ).join( " " ) ); + m_releaseFlags->setText( myProjectItem->scope->variableValues( "QMAKE_CXXFLAGS_RELEASE" ).join( " " ) ); + + updateIncludeControl(); + updateLibControls(); + updateBuildOrderControl(); + updateDependenciesControl(); + + dir = myProjectItem->scope->variableValues( "OBJECTS_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + objdir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + objdir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + objdir_url->completionObject()->setDir( dir ); + objdir_url->fileDialog()->setURL( KURL( dir ) ); + } + objdir_url->setURL( dir ); + dir = myProjectItem->scope->variableValues( "UI_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + uidir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + uidir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + uidir_url->completionObject()->setDir( dir ); + uidir_url->fileDialog()->setURL( KURL( dir ) ); + } + uidir_url->setURL( dir ); + dir = myProjectItem->scope->variableValues( "MOC_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + mocdir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + mocdir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + mocdir_url->completionObject()->setDir( dir ); + mocdir_url->fileDialog()->setURL( KURL( dir ) ); + } + mocdir_url->setURL( dir ); + dir = myProjectItem->scope->variableValues( "RC_DIR" ).front(); + if( QFileInfo(dir).isRelative() ) + { + rccdir_url->completionObject()->setDir( myProjectItem->scope->projectDir() ); + rccdir_url->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + rccdir_url->completionObject()->setDir( dir ); + rccdir_url->fileDialog()->setURL( KURL( dir ) ); + } + rccdir_url->setURL( dir ); + + + dir = myProjectItem->scope->variableValues( "IDL_COMPILER" ).front(); + if( QFileInfo(dir).isRelative() ) + { + idlCmdEdit->completionObject()->setDir( myProjectItem->scope->projectDir() ); + idlCmdEdit->fileDialog()->setURL( KURL( myProjectItem->scope->projectDir()+"/"+dir ) ); + }else + { + idlCmdEdit->completionObject()->setDir( dir ); + idlCmdEdit->fileDialog()->setURL( KURL( dir ) ); + } + idlCmdEdit->setURL( dir ); + idlCmdOptionsEdit->setText( myProjectItem->scope->variableValues( "IDL_OPTIONS" ).join( " " ) ); + + customVariables->clear(); + customVariableName->setText(""); + customVariableData->setText(""); + customVariableOp->setCurrentItem( 0 ); + QMap > customvars = myProjectItem->scope->customVariables(); + QMap >::iterator idx = customvars.begin(); + for ( ; idx != customvars.end(); ++idx ) + { + CustomVarListItem* item = new CustomVarListItem( customVariables, idx.key(), idx.data() ); + item->setMultiLinesEnabled(true); + } + + groupTemplateChanged(0); +} + +QPtrList ProjectConfigurationDlg::getAllProjects() +{ + QPtrList tmpPrjList; + QMakeScopeItem *item = static_cast( prjList->firstChild() ); + while ( item ) + { + if ( item->scope->scopeType() == Scope::ProjectScope ) + { + if( item != myProjectItem ) + tmpPrjList.append( item ); + getAllSubProjects( item, &tmpPrjList ); + } + item = static_cast( item->nextSibling() ); + } + return ( tmpPrjList ); +} + +void ProjectConfigurationDlg::getAllSubProjects( QMakeScopeItem *item, QPtrList *itemList ) +{ + + QMakeScopeItem * subItem = static_cast( item->firstChild() ); + while ( subItem ) + { + if ( subItem->scope->scopeType() == Scope::ProjectScope ) + { + if ( subItem != myProjectItem ) + itemList->append( subItem ); + getAllSubProjects( subItem, itemList ); + } + subItem = static_cast( subItem->nextSibling() ); + } +} + +void ProjectConfigurationDlg::updateIncludeControl() +{ + insideinc_listview->setSorting( -1, false ); + outsideinc_listview->setSorting( -1, false ); + insideinc_listview->clear(); + outsideinc_listview->clear(); + + QStringList incList = myProjectItem->scope->variableValues( "INCLUDEPATH" ); + QStringList intIncList = incList; + QMap items; + QPtrList itemList = getAllProjects(); + QMakeScopeItem *item = itemList.first(); + while ( item ) + { + if ( item->scope->variableValues( "TEMPLATE" ).findIndex( "lib" ) != -1 || + item->scope->variableValues( "TEMPLATE" ).findIndex( "app" ) != -1 ) + { + QString tmpInc = item->getIncAddPath( myProjectItem->scope->projectDir() ); + tmpInc = QDir::cleanDirPath( tmpInc ); + InsideCheckListItem *newItem = new InsideCheckListItem( insideinc_listview, + insideinc_listview->lastItem(), item, this ); + + items[tmpInc] = newItem; + if ( incList.findIndex( tmpInc ) != -1 ) + { + incList.remove( tmpInc ); + newItem->setOn( true ); + } + } + // item=(ProjectItem*)item->itemBelow(); + item = itemList.next(); + } + + + //all other in incList are outside incs + outsideinc_listview->clear(); + QStringList::Iterator it1 = incList.begin(); + for ( ;it1 != incList.end();++it1 ) + { + intIncList.remove(*it1); + new QListViewItem( outsideinc_listview, outsideinc_listview->lastItem(), ( *it1 ) ); + } + for( QStringList::const_iterator it = intIncList.begin(); it != intIncList.end(); ++it ) + { + insideinc_listview->insertItem( items[*it] ); + items.remove(*it); + } + for( QMap::ConstIterator it3 = items.begin(); it3 != items.end(); it3++ ) + { + insideinc_listview->insertItem( it3.data() ); + } +} + +void ProjectConfigurationDlg::updateLibControls() +{ + + QPtrList itemList = getAllProjects(); + + insidelib_listview->setSorting( -1, false ); + outsidelib_listview->setSorting( -1, false ); + outsidelibdir_listview->setSorting( -1, false ); + insidelib_listview->clear(); + outsidelib_listview->clear(); + outsidelibdir_listview->clear(); + //update librarys + //temp strlist + QStringList libList = myProjectItem->scope->variableValues( "LIBS" ); + QStringList intLibList = libList; + QMap items; + QMakeScopeItem* item = itemList.first(); + while ( item ) + { + if ( item->scope->variableValues( "TEMPLATE" ).findIndex( "lib" ) != -1 ) + { + if ( item != myProjectItem ) + { + // create lib string + QString tmpLib = item->getLibAddObject( myProjectItem->scope->projectDir() ); + + InsideCheckListItem * newItem = new InsideCheckListItem( insidelib_listview, + insidelib_listview->lastItem(), item, this ); + insidelib_listview->takeItem( newItem ); + items[tmpLib] = newItem; + QString tmpLibDir = item->getLibAddPath( myProjectItem->scope->projectDir() ); + kdDebug(9024) << "lib:" << tmpLib << " dir:" << tmpLibDir << "|" << libList << endl; + if ( libList.findIndex( "-L" + tmpLibDir ) != -1 ) + { + libList.remove( "-L" + tmpLibDir ); + } + if ( libList.findIndex( tmpLib ) != -1 ) + { + libList.remove( tmpLib ); + newItem->setOn( true ); + } + } + } + item = itemList.next(); + } + + //all other in libList are outside libs + QStringList::Iterator it1 = libList.begin(); + for ( ;it1 != libList.end();++it1 ) + { + intLibList.remove( *it1 ); + if ( ( *it1 ).startsWith( "-L" ) ) + new QListViewItem( outsidelibdir_listview, outsidelibdir_listview->lastItem(), ( *it1 ).mid( 2 ) ); + else + { + new QListViewItem( outsidelib_listview, outsidelib_listview->lastItem(), ( *it1 ) ); + } + } + + for( QStringList::const_iterator it = intLibList.begin(); it != intLibList.end(); ++it ) + { + QString lib = *it; + if( !lib.startsWith( "-L" ) ) + { + insidelib_listview->insertItem( items[lib] ); + items.remove(lib); + } + } + for( QMap::ConstIterator it3 = items.begin(); it3 != items.end(); it3++ ) + { + insidelib_listview->insertItem( it3.data() ); + } +} + +void ProjectConfigurationDlg::updateDependenciesControl( ) +{ + QPtrList itemList = getAllProjects(); + + intDeps_view->setSorting( -1, false ); + extDeps_view->setSorting( -1, false ); + intDeps_view->clear(); + extDeps_view->clear(); + + QStringList depsList = myProjectItem->scope->variableValues( "TARGETDEPS" ); + QStringList intDepList = depsList; + QMap items; + QMakeScopeItem *item = itemList.first(); + while ( item ) + { + QStringList templateval = item->scope->variableValues( "TEMPLATE" ); + if ( templateval.findIndex( "lib" ) != -1 + || templateval.findIndex( "app" ) != -1 ) + { + QString tmpLib; + QStringList values = item->scope->variableValues( "CONFIG" ); + if ( templateval.findIndex( "lib" ) != -1 && values.findIndex( "dll" ) != -1 ) + tmpLib = item->getSharedLibAddObject( myProjectItem->scope->projectDir() ); + else if ( templateval.findIndex( "lib" ) != -1 ) + tmpLib = item->getLibAddObject( myProjectItem->scope->projectDir() ); + else + tmpLib = item->getApplicationObject( myProjectItem->scope->projectDir() ); + InsideCheckListItem * newItem = new InsideCheckListItem( intDeps_view, intDeps_view->lastItem(), item, this ); + items[tmpLib] = newItem; + if ( depsList.findIndex( tmpLib ) != -1 ) + { + depsList.remove( tmpLib ); + newItem->setOn( true ); + } + + } + item = itemList.next(); + } + + //add all other prj in itemList unchecked + + extDeps_view->clear(); + for ( QStringList::Iterator it1 = depsList.begin();it1 != depsList.end();++it1 ) + { + intDepList << *it1; + new QListViewItem( extDeps_view, extDeps_view->lastItem(), ( *it1 ) ); + } + + + for( QStringList::const_iterator it = intDepList.begin(); it != intDepList.end(); ++it ) + { + intDeps_view->insertItem( items[*it] ); + items.remove(*it); + } + + for( QMap::ConstIterator it2 = items.begin(); it2 != items.end(); it2++ ) + { + intDeps_view->insertItem( it2.data() ); + } +} + + +void ProjectConfigurationDlg::updateBuildOrderControl() +{ + //sort build order only if subdirs + if ( myProjectItem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) != -1 ) + { + + QPtrList itemList; + + QMakeScopeItem *item = static_cast( myProjectItem->firstChild() ); + while ( item ) + { + itemList.append( item ); + item = static_cast( item->nextSibling() ); + } + + incaddTab->setEnabled( false ); + buildorder_listview->setSorting( -1, false ); + buildorder_listview->clear(); + QStringList buildList = myProjectItem->scope->variableValues( "SUBDIRS" ); + QStringList::Iterator it1 = buildList.begin(); + for ( ;it1 != buildList.end();++it1 ) + { + item = itemList.first(); + while ( item ) + { + if ( item->scope->scopeType() == Scope::ProjectScope ) + { + if ( item->text( 0 ) == ( *it1 ) ) + { + new QListViewItem( buildorder_listview, buildorder_listview->lastItem(), item->text( 0 ) ); + itemList.take(); + break; + } + } + item = itemList.next();; + } + } + }else + buildorder_listview->clear(); +} + +//build order buttons +void ProjectConfigurationDlg::buildorderMoveUpClicked() +{ + if ( buildorder_listview->currentItem() == buildorder_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = buildorder_listview->firstChild(); + while ( item->nextSibling() != buildorder_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( buildorder_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::buildorderMoveDownClicked() +{ + if ( buildorder_listview->currentItem() == 0 || buildorder_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + buildorder_listview->currentItem() ->moveItem( buildorder_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +//Include dir buttons +void ProjectConfigurationDlg::insideIncMoveUpClicked() +{ + if ( insideinc_listview->currentItem() == insideinc_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = insideinc_listview->firstChild(); + while ( item->nextSibling() != insideinc_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( insideinc_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::insideIncMoveDownClicked() +{ + if ( insideinc_listview->currentItem() == 0 || insideinc_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + insideinc_listview->currentItem() ->moveItem( insideinc_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideIncMoveUpClicked() +{ + if ( outsideinc_listview->currentItem() == outsideinc_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = outsideinc_listview->firstChild(); + while ( item->nextSibling() != outsideinc_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( outsideinc_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideIncMoveDownClicked() +{ + if ( outsideinc_listview->currentItem() == 0 || outsideinc_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + outsideinc_listview->currentItem() ->moveItem( outsideinc_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideIncAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add include directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + new QListViewItem( outsideinc_listview, dir ); + activateApply( 0 ); + } +} + + +void ProjectConfigurationDlg::outsideIncRemoveClicked() +{ + delete outsideinc_listview->currentItem(); + activateApply( 0 ); +} + +//libadd buttons +void ProjectConfigurationDlg::insideLibMoveUpClicked() +{ + if ( insidelib_listview->currentItem() == insidelib_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = insidelib_listview->firstChild(); + while ( item->nextSibling() != insidelib_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( insidelib_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::insideLibMoveDownClicked() +{ + if ( insidelib_listview->currentItem() == 0 || insidelib_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + insidelib_listview->currentItem() ->moveItem( insidelib_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibMoveUpClicked() +{ + if ( outsidelib_listview->currentItem() == outsidelib_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = outsidelib_listview->firstChild(); + while ( item->nextSibling() != outsidelib_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( outsidelib_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibMoveDownClicked() +{ + if ( outsidelib_listview->currentItem() == 0 || outsidelib_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + outsidelib_listview->currentItem() ->moveItem( outsidelib_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add Library: Either choose the .a/.so file or give -l" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + dialog.urlRequester() ->setFilter( "*.so|"+i18n("Shared Library (*.so)")+"\n*.a|"+i18n("Static Library (*.a)") ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if( file.startsWith("-l") ) + { + new QListViewItem( outsidelib_listview, file ); + activateApply( 0 ); + } + else + { + QFileInfo fi(file); + if( !fi.exists() ) + { + new QListViewItem( outsidelib_listview, file );; + activateApply( 0 ); + } + if( fi.extension(false) == "a" ) + { + new QListViewItem( outsidelib_listview, file ); + activateApply( 0 ); + }else if ( fi.extension(false) == "so" ) + { + QString path = fi.dirPath( true ); + QString name = fi.fileName(); + if( name.startsWith( "lib" ) ) + name = name.mid(3); + name = "-l"+name.left( name.length() - 3 ); + new QListViewItem( outsidelib_listview, name ); + new QListViewItem( outsidelibdir_listview, path ); + activateApply( 0 ); + }else + return; + } + + } +} + + +void ProjectConfigurationDlg::outsideLibRemoveClicked() +{ + delete outsidelib_listview->currentItem(); + activateApply( 0 ); +} + +//lib paths buttons +void ProjectConfigurationDlg::outsideLibDirMoveUpClicked() +{ + if ( outsidelibdir_listview->currentItem() == outsidelibdir_listview->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = outsidelibdir_listview->firstChild(); + while ( item->nextSibling() != outsidelibdir_listview->currentItem() ) + item = item->nextSibling(); + item->moveItem( outsidelibdir_listview->currentItem() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibDirMoveDownClicked() +{ + if ( outsidelibdir_listview->currentItem() == 0 || outsidelibdir_listview->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + outsidelibdir_listview->currentItem() ->moveItem( outsidelibdir_listview->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + + +void ProjectConfigurationDlg::outsideLibDirAddClicked() +{ + KURLRequesterDlg dialog( "", i18n( "Add library directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + new QListViewItem( outsidelibdir_listview, dir ); + activateApply( 0 ); + } +} + + +void ProjectConfigurationDlg::outsideLibDirRemoveClicked() +{ + delete outsidelibdir_listview->currentItem(); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::outsideIncEditClicked() +{ + QListViewItem * item = outsideinc_listview->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change include directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + } + else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + item->setText( 0, dir ); + activateApply( 0 ); + } +} + +void ProjectConfigurationDlg::outsideLibEditClicked() +{ + QListViewItem *item = outsidelib_listview->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change Library:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + }else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString file = dialog.urlRequester() ->url(); + if ( !file.isEmpty() ) + { + if( file.startsWith("-l") ) + { + item->setText( 0, file ); + activateApply( 0 ); + } + else + { + QFileInfo fi(file); + if( !fi.exists() ) + { + item->setText( 0, file ); + activateApply( 0 ); + } + if( fi.extension(false) == "a" ) + { + item->setText( 0, file ); + activateApply( 0 ); + }else if ( fi.extension(false) == "so" ) + { + QString path = fi.dirPath( true ); + QString name = fi.fileName(); + if( name.startsWith( "lib" ) ) + name = name.mid(3); + name = "-l"+name.left( name.length() - 3 ); + item->setText( 0, name ); + new QListViewItem( outsidelibdir_listview, path ); + activateApply( 0 ); + }else + return; + } + } +} + +void ProjectConfigurationDlg::outsideLibDirEditClicked() +{ + QListViewItem * item = outsidelibdir_listview->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change library directory:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + } + else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString dir = dialog.urlRequester() ->url(); + if ( !dir.isEmpty() ) + { + item->setText( 0, dir ); + activateApply( 0 ); + } +} + + +void ProjectConfigurationDlg::extAdd_button_clicked( ) +{ + KURLRequesterDlg dialog( "", i18n( "Add target:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::LocalOnly ); + dialog.urlRequester() ->setURL( QString::null ); + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir() ) ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString path = dialog.urlRequester() ->url(); + if ( !path.isEmpty() ) + { + new QListViewItem( extDeps_view, path ); + activateApply( 0 ); + } +} + +void ProjectConfigurationDlg::extEdit_button_clicked( ) +{ + QListViewItem * item = extDeps_view->currentItem(); + if ( item == NULL ) return ; + QString text = item->text( 0 ); + + KURLRequesterDlg dialog( text, i18n( "Change target:" ), 0, 0 ); + dialog.urlRequester() ->setMode( KFile::File | KFile::LocalOnly ); + if( QFileInfo(text).isRelative() ) + { + dialog.urlRequester() ->completionObject() ->setDir( myProjectItem->scope->projectDir() ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( myProjectItem->scope->projectDir()+"/"+text ) ); + } + else + { + dialog.urlRequester() ->completionObject() ->setDir( text ); + dialog.urlRequester() ->fileDialog() ->setURL( KURL( text ) ); + } + dialog.urlRequester() ->setURL( text ); + if ( dialog.exec() != QDialog::Accepted ) + return ; + QString path = dialog.urlRequester() ->url(); + if ( !path.isEmpty() ) + { + item->setText( 0, path ); + activateApply( 0 ); + } +} + +void ProjectConfigurationDlg::extMoveDown_button_clicked( ) +{ + if ( extDeps_view->currentItem() == 0 || extDeps_view->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + extDeps_view->currentItem() ->moveItem( extDeps_view->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::extMoveUp_button_clicked( ) +{ + if ( extDeps_view->currentItem() == extDeps_view->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = extDeps_view->firstChild(); + while ( item->nextSibling() != extDeps_view->currentItem() ) + item = item->nextSibling(); + item->moveItem( extDeps_view->currentItem() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::extRemove_button_clicked( ) +{ + delete extDeps_view->currentItem(); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::intMoveDown_button_clicked( ) +{ + if ( intDeps_view->currentItem() == 0 || intDeps_view->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + + intDeps_view->currentItem() ->moveItem( intDeps_view->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::intMoveUp_button_clicked( ) +{ + if ( intDeps_view->currentItem() == intDeps_view->firstChild() ) + { + KNotifyClient::beep(); + return ; + } + + QListViewItem *item = intDeps_view->firstChild(); + while ( item->nextSibling() != intDeps_view->currentItem() ) + item = item->nextSibling(); + item->moveItem( intDeps_view->currentItem() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::addCustomValueClicked() +{ + QMap customvar; + customvar["var"] = i18n("Name"); + customvar["op"] = "="; + customvar["values"] = i18n("Value"); + unsigned int key = myProjectItem->scope->addCustomVariable( customvar["var"], customvar["op"], customvar["values"] ); + CustomVarListItem* item = new CustomVarListItem( customVariables, key, customvar ); + item->setMultiLinesEnabled(true); + customVariables->setSelected( item, true ); + newCustomVariableActive(); + customVariables->sort(); + activateApply( 0 ); +} +void ProjectConfigurationDlg::removeCustomValueClicked() +{ + QListViewItem * item = customVariables->currentItem(); + if ( item ) + { + myProjectItem->scope->removeCustomVariable( item->key(0, true).toUInt() ); + delete item; + } + if( customVariables->firstChild() ) + { + customVariables->setSelected( customVariables->firstChild(), true ); + newCustomVariableActive(); + }else + { + customVariableName->setText( "" ); + customVariableData->setText( "" ); + customVariableOp->setCurrentItem( 0 ); + customVariableName->setFocus(); + } + customVariables->sort(); + + activateApply( 0 ); +} + +void ProjectConfigurationDlg::upCustomValueClicked() +{ + // custom vars + QListViewItem * item = customVariables->firstChild(); + if ( customVariables->currentItem() == item ) + { + KNotifyClient::beep(); + return ; + } + while ( item->nextSibling() != customVariables->currentItem() ) + item = item->nextSibling(); + item->moveItem( customVariables->currentItem() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::downCustomValueClicked() +{ + if ( customVariables->currentItem() == 0 || customVariables->currentItem() ->nextSibling() == 0 ) + { + KNotifyClient::beep(); + return ; + } + customVariables->currentItem() ->moveItem( customVariables->currentItem() ->nextSibling() ); + activateApply( 0 ); +} + +void ProjectConfigurationDlg::newCustomVariableActive( ) +{ + customVariableOp->blockSignals(true); + customVariableName->blockSignals(true); + customVariableData->blockSignals(true); + QListViewItem * item = customVariables->currentItem(); + if ( item ) + { + customVariableName->setText( item->text( 0 ) ); + customVariableData->setText( item->text( 2 ) ); + customVariableOp->setCurrentText( item->text( 1 ) ); + customVariableName->setFocus(); + } + customVariableOp->blockSignals(false); + customVariableName->blockSignals(false); + customVariableData->blockSignals(false); +} + +void ProjectConfigurationDlg::groupLibrariesChanged( int ) +{ + if ( staticRadio->isChecked() ) + { + checkPlugin->setEnabled( false ); + checkDesigner->setEnabled( false ); + } + else if ( sharedRadio->isChecked() ) + { + checkPlugin->setEnabled( true ); + checkDesigner->setEnabled( checkPlugin->isChecked() ); + } + else if ( checkPlugin->isChecked() && prjWidget->m_part->isQt4Project() ) + { + checkDesigner->setEnabled( true ); + } + else + { + checkDesigner->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::groupTemplateChanged( int ) +{ + + if ( radioSubdirs->isChecked() ) + { + TabBuild->setTabEnabled( custVarsTab, true ); + TabBuild->setTabEnabled( libAddTab, false ); + TabBuild->setTabEnabled( incaddTab, false ); + TabBuild->setTabEnabled( buildOptsTab, false ); + TabBuild->setTabEnabled( configTab, false ); + TabBuild->setTabEnabled( depTab, true ); + intDeps_view->setEnabled( false ); + intMoveUp_button->setEnabled( false ); + intMoveDown_button->setEnabled( false ); + extAdd_button->setEnabled( false ); + extRemove_button->setEnabled( false ); + extEdit_button->setEnabled( false ); + extMoveUp_button->setEnabled( false ); + extMoveDown_button->setEnabled( false ); + extDeps_view->setEnabled( false ); + buildorder_listview->setEnabled( checkOrdered->isOn() ); + buildmoveup_button->setEnabled( checkOrdered->isOn() ); + buildmovedown_button->setEnabled( checkOrdered->isOn() ); + targetGroupbox->setEnabled( false ); + targetInstGroupbox->setEnabled( false ); + checkOrdered->setEnabled( true ); + } + else if ( radioLibrary->isChecked() ) + { + // staticRadio->setChecked(true); + TabBuild->setTabEnabled( custVarsTab, true ); + TabBuild->setTabEnabled( depTab, true ); + TabBuild->setTabEnabled( libAddTab, true ); + TabBuild->setTabEnabled( incaddTab, true ); + TabBuild->setTabEnabled( buildOptsTab, true ); + TabBuild->setTabEnabled( configTab, true ); + intDeps_view->setEnabled( true ); + intMoveUp_button->setEnabled( true ); + intMoveDown_button->setEnabled( true ); + extAdd_button->setEnabled( true ); + extRemove_button->setEnabled( true ); + extEdit_button->setEnabled( true ); + extMoveUp_button->setEnabled( true ); + extMoveDown_button->setEnabled( true ); + extDeps_view->setEnabled( true ); + buildorder_listview->setEnabled( false ); + buildmoveup_button->setEnabled( false ); + buildmovedown_button->setEnabled( false ); + groupLibraries->setEnabled( true ); + targetGroupbox->setEnabled( true ); + targetInstGroupbox->setEnabled( true ); + checkOrdered->setEnabled( false ); + } + else if ( radioApplication->isChecked() ) + { + TabBuild->setTabEnabled( custVarsTab, true ); + TabBuild->setTabEnabled( depTab, true ); + TabBuild->setTabEnabled( libAddTab, true ); + TabBuild->setTabEnabled( incaddTab, true ); + TabBuild->setTabEnabled( buildOptsTab, true ); + TabBuild->setTabEnabled( configTab, true ); + intDeps_view->setEnabled( true ); + intMoveUp_button->setEnabled( true ); + intMoveDown_button->setEnabled( true ); + extAdd_button->setEnabled( true ); + extRemove_button->setEnabled( true ); + extEdit_button->setEnabled( true ); + extMoveUp_button->setEnabled( true ); + extMoveDown_button->setEnabled( true ); + extDeps_view->setEnabled( true ); + buildorder_listview->setEnabled( false ); + buildmoveup_button->setEnabled( false ); + buildmovedown_button->setEnabled( false ); + groupLibraries->setEnabled( false ); + targetGroupbox->setEnabled( true ); + targetInstGroupbox->setEnabled( true ); + checkConsole->setEnabled( true ); + checkWindows->setEnabled( true ); + checkOrdered->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::groupRequirementsChanged( int ) +{ + if ( checkQt->isChecked() && prjWidget->m_part->isQt4Project() ) + { + groupQt4Libs->setEnabled( true ); + } + else + { + groupQt4Libs->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::targetInstallChanged( bool checked ) +{ + if ( checked ) + { + m_InstallTargetPath->setEnabled( true ); + } + else + { + m_InstallTargetPath->setEnabled( false ); + } + activateApply( 0 ); +} + +void ProjectConfigurationDlg::apply() +{ +// if( buttonApply->isEnabled() ) + if( !myProjectItem || !myProjectItem->scope ) + { + buttonApply->setEnabled( false ); + return; + } + updateProjectConfiguration(); + myProjectItem->scope->saveToFile(); + // prjWidget->updateProjectConfiguration( myProjectItem ); + prjWidget->setupContext(); + buttonApply->setEnabled( false ); +} + +void ProjectConfigurationDlg::activateApply( int ) +{ + buttonApply->setEnabled( true ); +} +void ProjectConfigurationDlg::activateApply( const QString& ) +{ + buttonApply->setEnabled( true ); +} + +void ProjectConfigurationDlg::activateApply( QListViewItem* ) +{ + buttonApply->setEnabled( true ); +} + +void ProjectConfigurationDlg::removeSharedLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("LIBS").findIndex(infos["shared_lib"]) != -1 ) + prjItem->scope->removeFromPlusOp("LIBS", infos["shared_lib"]); + if( prjItem->scope->variableValues("LIBS").findIndex(infos["shared_libdir"]) != -1 ) + prjItem->scope->removeFromPlusOp("LIBS", infos["shared_libdir"]); + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["shared_depend"]) != -1 ) + { + prjItem->scope->removeFromPlusOp("TARGETDEPS", infos["shared_depend"]); + + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::addStaticLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["app_depend"]) != -1 + || prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["shared_depend"]) != -1 ) + { + prjItem->scope->addToPlusOp("LIBS", infos["static_lib"]); + prjItem->scope->addToPlusOp("TARGETDEPS", infos["static_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::removeStaticLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + + QMap infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("LIBS").findIndex(infos["static_lib"]) != -1 ) + prjItem->scope->removeFromPlusOp("LIBS", infos["static_lib"]); + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["static_depend"]) != -1 ) + { + prjItem->scope->removeFromPlusOp("TARGETDEPS", infos["static_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::addSharedLibDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["app_depend"]) != -1 + || prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["static_depend"]) != -1 ) + { + prjItem->scope->addToPlusOp("LIBS", infos["shared_lib"]); + prjItem->scope->addToPlusOp("LIBS", infos["shared_libdir"]); + prjItem->scope->addToPlusOp("TARGETDEPS", infos["shared_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::removeAppDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["app_depend"]) != -1 ) + { + prjItem->scope->removeFromPlusOp("TARGETDEPS", infos["app_depend"]); + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::addAppDeps() +{ + QListViewItemIterator it(myProjectItem->listView()); + for( ; it.current() ; ++it ) + { + QMakeScopeItem* prjItem = static_cast( it.current() ); + if( prjItem == myProjectItem || !prjItem->isEnabled() ) + continue; + + QMap infos = myProjectItem->getLibInfos(prjItem->scope->projectDir()); + + if( prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["shared_depend"]) != -1 + || prjItem->scope->variableValues("TARGETDEPS").findIndex(infos["static_depend"]) != -1 ) + { + prjItem->scope->addToPlusOp("TARGETDEPS", infos["app_depend"]); + + prjItem->scope->saveToFile(); + } + } +} + +void ProjectConfigurationDlg::customVarChanged() +{ + QListViewItem * item = customVariables->currentItem(); + if ( item ) + { + item->setText( 0, customVariableName->text() ); + item->setText( 1, customVariableOp->currentText() ); + item->setText( 2, customVariableData->text() ); + } + activateApply( 0 ); +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/projectconfigurationdlg.h b/buildtools/qmake/projectconfigurationdlg.h new file mode 100644 index 00000000..246fb388 --- /dev/null +++ b/buildtools/qmake/projectconfigurationdlg.h @@ -0,0 +1,145 @@ +/*************************************************************************** +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jsgaarde@tdcspace.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef PROJECTCONFIGURATIONDLG_H +#define PROJECTCONFIGURATIONDLG_H + +#include "projectconfigurationdlgbase.h" +//#include "trollprojectwidget.h" +#include +#include +#include +#include + +class QMakeScopeItem; +class KListViewItem; +class qProjectItem; +class ProjectConfigurationDlg; +class TrollProjectWidget; + +class InsideCheckListItem : public QCheckListItem +{ +public: + InsideCheckListItem( QListView *parent, QMakeScopeItem *item, ProjectConfigurationDlg *config ); + + InsideCheckListItem( QListView *parent, QListViewItem *after, QMakeScopeItem *item, ProjectConfigurationDlg *config ); + QMakeScopeItem *prjItem; + ProjectConfigurationDlg *m_config; + +protected: + virtual void stateChange ( bool state ); +}; + +class CustomVarListItem : public KListViewItem +{ + public: + CustomVarListItem( QListView*, unsigned int, QMap ); + QString key(int column, bool ascending) const; + private: + unsigned int m_key; +}; + +class ProjectConfigurationDlg : public ProjectConfigurationDlgBase +{ +public: + ProjectConfigurationDlg( QListView *_prjList, TrollProjectWidget* _prjWidget, QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~ProjectConfigurationDlg(); + void updateControls(); + void updateSubproject( QMakeScopeItem* _item ); + QMakeScopeItem* currentProjectItem() { return myProjectItem; } + +public slots: + // virtual void radioLibrarytoggled(bool); + virtual void updateProjectConfiguration(); + + virtual void buildorderMoveUpClicked(); + virtual void buildorderMoveDownClicked(); + + virtual void insideIncMoveUpClicked(); + virtual void insideIncMoveDownClicked(); + virtual void outsideIncMoveUpClicked(); + virtual void outsideIncMoveDownClicked(); + virtual void outsideIncAddClicked(); + virtual void outsideIncRemoveClicked(); + virtual void outsideIncEditClicked(); + + virtual void insideLibMoveUpClicked(); + virtual void insideLibMoveDownClicked(); + virtual void outsideLibMoveUpClicked(); + virtual void outsideLibMoveDownClicked(); + virtual void outsideLibAddClicked(); + virtual void outsideLibRemoveClicked(); + virtual void outsideLibEditClicked(); + + virtual void outsideLibDirMoveUpClicked(); + virtual void outsideLibDirMoveDownClicked(); + virtual void outsideLibDirAddClicked(); + virtual void outsideLibDirRemoveClicked(); + virtual void outsideLibDirEditClicked(); + + virtual void extAdd_button_clicked(); + virtual void extEdit_button_clicked(); + virtual void extMoveDown_button_clicked(); + virtual void extMoveUp_button_clicked(); + virtual void extRemove_button_clicked(); + virtual void intMoveDown_button_clicked(); + virtual void intMoveUp_button_clicked(); + + virtual void addCustomValueClicked(); + virtual void removeCustomValueClicked(); + virtual void upCustomValueClicked(); + virtual void downCustomValueClicked(); + + virtual void newCustomVariableActive(); + + virtual void groupLibrariesChanged( int ); + virtual void groupRequirementsChanged( int ); + virtual void groupTemplateChanged( int ); + virtual void targetInstallChanged( bool ); + virtual void accept(); + virtual void reject(); + virtual void apply(); + virtual void activateApply( int ); + virtual void activateApply( const QString& ); + + + void updateIncludeControl(); + void updateLibControls(); + void updateBuildOrderControl(); + void updateDependenciesControl(); + virtual void activateApply(QListViewItem*); + virtual void customVarChanged(); + +protected: + QListView *prjList; + QMakeScopeItem *myProjectItem; + QPtrList getAllProjects(); + TrollProjectWidget* prjWidget; + void getAllSubProjects( QMakeScopeItem *item, QPtrList *itemList ); + +private: + void removeSharedLibDeps(); + void removeStaticLibDeps(); + void addSharedLibDeps(); + void addStaticLibDeps(); + void removeAppDeps(); + void addAppDeps(); +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/projectconfigurationdlgbase.ui b/buildtools/qmake/projectconfigurationdlgbase.ui new file mode 100644 index 00000000..d447210d --- /dev/null +++ b/buildtools/qmake/projectconfigurationdlgbase.ui @@ -0,0 +1,2897 @@ + +ProjectConfigurationDlgBase +Jakob Simon-Gaarde + + + ProjectConfigurationDlgBase + + + + 0 + 0 + 746 + 694 + + + + + 5 + 5 + 0 + 0 + + + + QMake Subproject Configuration + + + + unnamed + + + + buttonCancel + + + &Cancel + + + + + buttonOk + + + &OK + + + true + + + + + Spacer1_2 + + + Horizontal + + + Expanding + + + + 260 + 16 + + + + + + buttonApply + + + &Apply + + + + + TabBuild + + + true + + + 0 + + + + buildTab + + + Basics + + + + unnamed + + + + groupTemplate + + + Template + + + + unnamed + + + + radioLibrary + + + Librar&y + + + Create a library + + + + + radioSubdirs + + + &Subdirectories + + + This project holds subdirectories + + + + + checkOrdered + + + false + + + Ordered + + + Build the subprojects in the order they are listed in the .pro file + + + + + spacer15 + + + Horizontal + + + Expanding + + + + 101 + 20 + + + + + + radioApplication + + + WidgetOrigin + + + A&pplication + + + Create an application + + + + + + + targetGroupbox + + + Target + + + + unnamed + + + + TextLabel1_2 + + + Path: + + + m_targetPath + + + + + TextLabel2 + + + Output file: + + + m_targetOutputFile + + + + + m_targetOutputFile + + + + + m_targetPath + + + + + + + targetInstGroupbox + + + Target Installation + + + + unnamed + + + + m_InstallTargetPath + + + + + checkInstallTarget + + + I&nstall + + + + + textLabel1_2 + + + Installation path: + + + m_InstallTargetPath + + + + + + + groupBox6 + + + Makefile + + + + unnamed + + + + makefile_url + + + + + + + argumentsGroupBox + + + false + + + Arguments + + + + unnamed + + + + textLabel1_6 + + + Run arguments: + + + + + m_editRunArguments + + + + + m_editDebugArguments + + + + + textLabel2_2 + + + Debug Arguments: + + + + + textLabel2_2_2 + + + Working Directory: + + + + + m_CWDEdit + + + + + + + Spacer3 + + + Vertical + + + Expanding + + + + 20 + 120 + + + + + + + + configTab + + + Configuration + + + + unnamed + + + + groupBuildMode + + + Build Mode + + + -1 + + + Set project to be built in release mode + + + + unnamed + + + + layout147 + + + + unnamed + + + + radioDebugMode + + + Debug + + + Set project to be built in debug mode + + + + + radioReleaseMode + + + Release + + + Set project to be built in release mode + + + + + checkDebugReleaseMode + + + false + + + Debug && Release + + + + + + Set project to be built in debug_and_release mode + + + + + + + layout30 + + + + unnamed + + + + checkWarning + + + Enable warnings + + + Show compiler warnings + + + + + checkBuildAll + + + false + + + Build All + + + Builds Debug and Release version if Debug&Release is configured + + + + + + + + + groupRequirements + + + Requirements + + + + unnamed + + + + checkOpenGL + + + OpenGL + + + Requires the OpenGL (or Mesa) headers/libraries + + + + + stlCheck + + + STL + + + + + checkThread + + + Thread + + + Requires support for multi-threaded application or library. + + + + + checkQt + + + Qt + + + Requires the Qt header files/library + + + + + checkX11 + + + X11 + + + Support required for X11 application or library + + + + + checkPCH + + + Precompiled headers + + + + + rttiCheck + + + RTTI + + + + + checkWindows + + + Windows + + + + + textLabel1_4 + + + Custom Configuration + + + + + exceptionCheck + + + Exceptions + + + + + editConfigExtra + + + + + checkConsole + + + true + + + Console + + + + + + Check to build a win32 console app + + + + + + + groupQt4Libs + + + false + + + Qt4 Libraries + + + + unnamed + + + + checkQt4Gui + + + Gui + + + true + + + + + checkQt4XML + + + XML + + + + + checkQt4Network + + + Network + + + + + checkQt4Core + + + Core + + + true + + + + + checkQt4OpenGL + + + OpenGL + + + + + checkUiTools + + + QtUiTools + + + + + checkQt4SQL + + + SQL + + + + + checkQt4SVG + + + SVG + + + + + checkTestlib + + + QtTest + + + + + checkQt3Support + + + Qt3 Support + + + + + checkQDBus + + + QDBus (Qt4.2) + + + + + checkAssistant + + + QtAssistant + + + + + checkQtScript + + + QtScript (Qt4.3) + + + + + checkQtWebKit + + + QtWebKit (Qt4.4) + + + + + checkQtXmlPatterns + + + QtXmlPatterns (Qt4.4) + + + + + checkPhonon + + + Phonon (Qt4.4) + + + + + checkQtHelp + + + QtHelp (Qt4.4) + + + + + + + groupLibraries + + + Library Options + + + false + + + + unnamed + + + + layout69 + + + + unnamed + + + + staticRadio + + + Build as static library + + + true + + + + + checkPlugin + + + false + + + Plugin + + + + + checkLibtool + + + true + + + Make libtool archive + + + Support required for X11 application or library + + + + + + + spacer34 + + + Horizontal + + + Expanding + + + + 41 + 20 + + + + + + layout68 + + + + unnamed + + + + sharedRadio + + + Build as shared library + + + + + checkDesigner + + + false + + + Designer Plugin + + + + + + + + layout67 + + + + unnamed + + + + textLabel1 + + + Library version: + + + m_targetLibraryVersion + + + + + m_targetLibraryVersion + + + + + + + + + + + Spacer2 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + incaddTab + + + Includes + + + + unnamed + + + + Layout9 + + + + unnamed + + + 0 + + + + insideIncMoveUpBtn + + + Move Up + + + + + insideIncMoveDownBtn + + + Move Down + + + + + Spacer3_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + Directories Outside Project + + + true + + + true + + + + outsideinc_listview + + + LastColumn + + + + + + Directories Inside Project + + + true + + + true + + + + insideinc_listview + + + LastColumn + + + + + layout8 + + + + unnamed + + + + outsideIncAddBtn + + + Add... + + + + + outsideIncRemoveBtn + + + Remove + + + + + outsideIncEditBtn + + + Edit + + + + + outsideIncMoveUpBtn + + + Move Up + + + + + outsideIncMoveDownBtn + + + Move Down + + + + + Spacer2_2 + + + Vertical + + + Expanding + + + + 20 + 70 + + + + + + + + + + libAddTab + + + Libraries + + + + unnamed + + + + layout12 + + + + unnamed + + + + + External Library Dirs + + + true + + + true + + + + outsidelibdir_listview + + + LastColumn + + + + + layout10 + + + + unnamed + + + + outsideLibDirAddBtn + + + Add... + + + + + outsideLibDirRemoveBtn + + + Remove + + + + + outsideLibDirEditBtn + + + Edit + + + + + outsideLibDirMoveUpBtn + + + Move Up + + + + + outsideLibDirMoveDownBtn + + + Move Down + + + + + Spacer2_2_2 + + + Vertical + + + Expanding + + + + 20 + 70 + + + + + + + + + + layout11 + + + + unnamed + + + + + External Libraries + + + true + + + true + + + + outsidelib_listview + + + LastColumn + + + + + layout9 + + + + unnamed + + + + outsideLibAddBtn + + + Add... + + + + + outsideLibRemoveBtn + + + Remove + + + + + outsideLibEditBtn + + + Edit + + + + + outsideLibMoveUpBtn + + + Move Up + + + + + outsideLibMoveDownBtn + + + Move Down + + + + + Spacer8_2 + + + Vertical + + + Expanding + + + + 20 + 64 + + + + + + + + + + layout10 + + + + unnamed + + + + + Link Convenience Libraries Inside Project + + + true + + + true + + + + insidelib_listview + + + LastColumn + + + + + Layout9_3 + + + + unnamed + + + + insideLibMoveUpBtn + + + Move Up + + + + + insideLibMoveDownBtn + + + Move Down + + + + + Spacer6_2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + depTab + + + Dependencies + + + + unnamed + + + + layout26 + + + + unnamed + + + + + Targets in Project + + + true + + + true + + + + intDeps_view + + + LastColumn + + + + + Layout9_3_2 + + + + unnamed + + + 0 + + + + intMoveUp_button + + + Move Up + + + + + intMoveDown_button + + + Move Down + + + + + Spacer6_2_2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + layout27 + + + + unnamed + + + + + Miscellaneous Targets + + + true + + + true + + + + extDeps_view + + + LastColumn + + + + + layout9_2 + + + + unnamed + + + + extAdd_button + + + Add... + + + + + extRemove_button + + + Remove + + + + + extEdit_button + + + Edit + + + + + extMoveUp_button + + + Move Up + + + + + extMoveDown_button + + + Move Down + + + + + Spacer8_2_2 + + + Vertical + + + Expanding + + + + 20 + 64 + + + + + + + + + + layout28_2 + + + + unnamed + + + + + Order in Which Sub Projects Are Built + + + true + + + true + + + + buildorder_listview + + + LastColumn + + + + + Layout9_2 + + + + unnamed + + + 0 + + + + buildmoveup_button + + + Move Up + + + + + buildmovedown_button + + + Move Down + + + + + Spacer3_2_2 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + + + + + + buildOptsTab + + + Build Options + + + + unnamed + + + + GroupBox2 + + + + 1 + 1 + 0 + 0 + + + + Compiler Options + + + + unnamed + + + + layout26 + + + + unnamed + + + + layout23 + + + + unnamed + + + + TextLabel2_2 + + + Debug flags: + + + m_debugFlags + + + + + TextLabel2_2_2 + + + Release flags: + + + m_releaseFlags + + + + + TextLabel1 + + + Defines: + + + + + + + layout24 + + + + unnamed + + + + m_debugFlags + + + + + m_releaseFlags + + + + + m_defines + + + + + + + + + + + groupBox8 + + + Intermediate File Directories + + + + unnamed + + + + layout84 + + + + unnamed + + + + mocdir_label + + + MOC files: + + + mocdir_url + + + + + uidir_label + + + UI files: + + + uidir_url + + + + + objdir_label + + + Object files: + + + objdir_url + + + + + rccdir_label + + + false + + + RCC files: + + + + + + + layout85 + + + + unnamed + + + + mocdir_url + + + + + uidir_url + + + + + objdir_url + + + + + rccdir_url + + + false + + + + + + + + + idlGroup + + + Corba + + + + unnamed + + + 11 + + + + TextLabel2_3 + + + Compiler options: + + + idlCmdOptionsEdit + + + + + idlCmdOptionsEdit + + + + + idlCmdEdit + + + + + TextLabel1_2_2 + + + IDL compiler: + + + idlCmdEdit + + + + + + + spacer29 + + + Vertical + + + Expanding + + + + 20 + 21 + + + + + + + + custVarsTab + + + Custom Variables + + + + unnamed + + + + layout24 + + + + unnamed + + + + + Name + + + true + + + true + + + + + Operator + + + true + + + true + + + + + Value + + + true + + + true + + + + customVariables + + + + 7 + 7 + 0 + 6 + + + + true + + + Accept + + + true + + + + + layout23 + + + + unnamed + + + + layout22 + + + + unnamed + + + + varAdd_button + + + New + + + + + varRemove_button + + + Remove + + + + + varMoveUp_button + + + Move Up + + + + + varMoveDown_button + + + Move Down + + + + + + + Spacer8_2_2_2 + + + Vertical + + + Expanding + + + + 20 + 106 + + + + + + + + + + layout33 + + + + unnamed + + + + textLabel1_3 + + + + 5 + 5 + 0 + 0 + + + + Name: + + + + + customVariableName + + + + 7 + 0 + 3 + 0 + + + + + + + + layout32 + + + + unnamed + + + + textLabel1_5 + + + Operator + + + + + + += + + + + + -= + + + + + = + + + + + *= + + + + + ~= + + + + customVariableOp + + + + 1 + 0 + 0 + 0 + + + + 0 + + + false + + + + + spacer17 + + + Horizontal + + + Expanding + + + + 250 + 20 + + + + + + + + layout34 + + + + unnamed + + + + textLabel2 + + + + 5 + 5 + 0 + 0 + + + + Value: + + + AlignTop + + + + + customVariableData + + + + 7 + 7 + 0 + 2 + + + + + + + + + + + + + buttonOk + clicked() + ProjectConfigurationDlgBase + accept() + + + idlCmdEdit + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + idlCmdEdit + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + idlCmdOptionsEdit + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + makefile_url + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + makefile_url + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_debugFlags + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_defines + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_InstallTargetPath + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + mocdir_url + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + mocdir_url + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_releaseFlags + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_targetLibraryVersion + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_targetOutputFile + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + objdir_url + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + objdir_url + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + rccdir_url + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + rccdir_url + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + uidir_url + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + editConfigExtra + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_editRunArguments + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_editDebugArguments + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + groupBuildMode + clicked(int) + ProjectConfigurationDlgBase + activateApply(int) + + + groupQt4Libs + clicked(int) + ProjectConfigurationDlgBase + activateApply(int) + + + insideinc_listview + clicked(QListViewItem*) + ProjectConfigurationDlgBase + activateApply(QListViewItem*) + + + insideinc_listview + spacePressed(QListViewItem*) + ProjectConfigurationDlgBase + activateApply(QListViewItem*) + + + insidelib_listview + clicked(QListViewItem*) + ProjectConfigurationDlgBase + activateApply(QListViewItem*) + + + insidelib_listview + spacePressed(QListViewItem*) + ProjectConfigurationDlgBase + activateApply(QListViewItem*) + + + intDeps_view + clicked(QListViewItem*) + ProjectConfigurationDlgBase + activateApply(QListViewItem*) + + + intDeps_view + spacePressed(QListViewItem*) + ProjectConfigurationDlgBase + activateApply(QListViewItem*) + + + varAdd_button + clicked() + ProjectConfigurationDlgBase + addCustomValueClicked() + + + buttonApply + clicked() + ProjectConfigurationDlgBase + apply() + + + buildmovedown_button + clicked() + ProjectConfigurationDlgBase + buildorderMoveDownClicked() + + + buildmoveup_button + clicked() + ProjectConfigurationDlgBase + buildorderMoveUpClicked() + + + customVariableName + textChanged(const QString&) + ProjectConfigurationDlgBase + customVarChanged() + + + customVariableOp + activated(const QString&) + ProjectConfigurationDlgBase + customVarChanged() + + + customVariableData + textChanged() + ProjectConfigurationDlgBase + customVarChanged() + + + varMoveUp_button + clicked() + ProjectConfigurationDlgBase + downCustomValueClicked() + + + extAdd_button + clicked() + ProjectConfigurationDlgBase + extAdd_button_clicked() + + + extEdit_button + clicked() + ProjectConfigurationDlgBase + extEdit_button_clicked() + + + extMoveDown_button + clicked() + ProjectConfigurationDlgBase + extMoveDown_button_clicked() + + + extMoveUp_button + clicked() + ProjectConfigurationDlgBase + extMoveUp_button_clicked() + + + extRemove_button + clicked() + ProjectConfigurationDlgBase + extRemove_button_clicked() + + + groupLibraries + clicked(int) + ProjectConfigurationDlgBase + groupLibrariesChanged(int) + + + groupRequirements + clicked(int) + ProjectConfigurationDlgBase + groupRequirementsChanged(int) + + + groupTemplate + clicked(int) + ProjectConfigurationDlgBase + groupTemplateChanged(int) + + + insideIncMoveDownBtn + clicked() + ProjectConfigurationDlgBase + insideIncMoveDownClicked() + + + insideIncMoveUpBtn + clicked() + ProjectConfigurationDlgBase + insideIncMoveUpClicked() + + + insideLibMoveDownBtn + clicked() + ProjectConfigurationDlgBase + insideLibMoveDownClicked() + + + insideLibMoveUpBtn + clicked() + ProjectConfigurationDlgBase + insideLibMoveUpClicked() + + + intMoveDown_button + clicked() + ProjectConfigurationDlgBase + intMoveDown_button_clicked() + + + intMoveUp_button + clicked() + ProjectConfigurationDlgBase + intMoveUp_button_clicked() + + + customVariables + selectionChanged() + ProjectConfigurationDlgBase + newCustomVariableActive() + + + outsideIncAddBtn + clicked() + ProjectConfigurationDlgBase + outsideIncAddClicked() + + + outsideIncEditBtn + clicked() + ProjectConfigurationDlgBase + outsideIncEditClicked() + + + outsideIncMoveDownBtn + clicked() + ProjectConfigurationDlgBase + outsideIncMoveDownClicked() + + + outsideIncMoveUpBtn + clicked() + ProjectConfigurationDlgBase + outsideIncMoveUpClicked() + + + outsideIncRemoveBtn + clicked() + ProjectConfigurationDlgBase + outsideIncRemoveClicked() + + + outsideLibAddBtn + clicked() + ProjectConfigurationDlgBase + outsideLibAddClicked() + + + outsideLibDirAddBtn + clicked() + ProjectConfigurationDlgBase + outsideLibDirAddClicked() + + + outsideLibDirEditBtn + clicked() + ProjectConfigurationDlgBase + outsideLibDirEditClicked() + + + outsideLibDirMoveDownBtn + clicked() + ProjectConfigurationDlgBase + outsideLibDirMoveDownClicked() + + + outsideLibDirMoveUpBtn + clicked() + ProjectConfigurationDlgBase + outsideLibDirMoveUpClicked() + + + outsideLibDirRemoveBtn + clicked() + ProjectConfigurationDlgBase + outsideLibDirRemoveClicked() + + + outsideLibEditBtn + clicked() + ProjectConfigurationDlgBase + outsideLibEditClicked() + + + outsideLibMoveDownBtn + clicked() + ProjectConfigurationDlgBase + outsideLibMoveDownClicked() + + + outsideLibMoveUpBtn + clicked() + ProjectConfigurationDlgBase + outsideLibMoveUpClicked() + + + outsideLibRemoveBtn + clicked() + ProjectConfigurationDlgBase + outsideLibRemoveClicked() + + + buttonCancel + clicked() + ProjectConfigurationDlgBase + reject() + + + varRemove_button + clicked() + ProjectConfigurationDlgBase + removeCustomValueClicked() + + + checkOrdered + toggled(bool) + buildmovedown_button + setDisabled(bool) + + + checkOrdered + toggled(bool) + buildmoveup_button + setDisabled(bool) + + + checkOrdered + toggled(bool) + buildorder_listview + setDisabled(bool) + + + radioApplication + toggled(bool) + argumentsGroupBox + setEnabled(bool) + + + checkInstallTarget + toggled(bool) + ProjectConfigurationDlgBase + targetInstallChanged(bool) + + + varMoveDown_button + clicked() + ProjectConfigurationDlgBase + upCustomValueClicked() + + + m_targetPath + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_targetPath + returnPressed(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_targetPath + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + uidir_url + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_CWDEdit + textChanged(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + m_CWDEdit + urlSelected(const QString&) + ProjectConfigurationDlgBase + activateApply(const QString&) + + + + TabBuild + radioApplication + radioLibrary + radioSubdirs + checkOrdered + m_targetOutputFile + checkInstallTarget + m_InstallTargetPath + makefile_url + radioDebugMode + radioReleaseMode + checkDebugReleaseMode + checkWarning + checkBuildAll + checkQt + checkOpenGL + stlCheck + checkWindows + checkThread + checkX11 + rttiCheck + exceptionCheck + checkConsole + checkPCH + editConfigExtra + checkQt4Core + checkQt4Gui + checkQt4XML + checkQt4Network + checkQt4OpenGL + checkUiTools + checkQt4SQL + checkQt4SVG + checkTestlib + checkQt3Support + checkQDBus + checkAssistant + checkQtScript + checkQtWebKit + checkQtXmlPatterns + checkPhonon + checkQtHelp + staticRadio + checkPlugin + checkLibtool + sharedRadio + checkDesigner + m_targetLibraryVersion + insideinc_listview + insideIncMoveUpBtn + insideIncMoveDownBtn + outsideinc_listview + outsideIncAddBtn + outsideIncRemoveBtn + outsideIncEditBtn + outsideIncMoveUpBtn + outsideIncMoveDownBtn + insidelib_listview + insideLibMoveUpBtn + insideLibMoveDownBtn + outsidelibdir_listview + outsideLibDirAddBtn + outsideLibDirRemoveBtn + outsideLibDirEditBtn + outsideLibDirMoveUpBtn + outsideLibDirMoveDownBtn + outsidelib_listview + outsideLibAddBtn + outsideLibRemoveBtn + outsideLibEditBtn + outsideLibMoveUpBtn + outsideLibMoveDownBtn + intDeps_view + intMoveUp_button + intMoveDown_button + extDeps_view + extAdd_button + extRemove_button + extEdit_button + extMoveUp_button + extMoveDown_button + buildorder_listview + buildmoveup_button + buildmovedown_button + m_debugFlags + m_releaseFlags + m_defines + mocdir_url + uidir_url + objdir_url + rccdir_url + idlCmdEdit + idlCmdOptionsEdit + customVariables + varAdd_button + varRemove_button + varMoveUp_button + varMoveDown_button + customVariableName + customVariableOp + customVariableData + buttonOk + buttonApply + buttonCancel + + + klineedit.h + kdialog.h + kpushbutton.h + + + updateProjectConfiguration() + buildorderMoveUpClicked() + buildorderMoveDownClicked() + outsideIncMoveUpClicked() + outsideIncMoveDownClicked() + insideIncMoveUpClicked() + insideIncMoveDownClicked() + outsideLibMoveUpClicked() + outsideLibMoveDownClicked() + insideLibMoveUpClicked() + insideLibMoveDownClicked() + outsideIncAddClicked() + outsideIncRemoveClicked() + outsideLibAddClicked() + outsideLibRemoveClicked() + outsideLibDirMoveDownClicked() + outsideLibDirMoveUpClicked() + outsideLibDirAddClicked() + outsideLibDirRemoveClicked() + outsideLibDirEditClicked() + outsideLibEditClicked() + outsideIncEditClicked() + intMoveUp_button_clicked() + intMoveDown_button_clicked() + extAdd_button_clicked() + extRemove_button_clicked() + extEdit_button_clicked() + extMoveUp_button_clicked() + extMoveDown_button_clicked() + removeCustomValueClicked() + upCustomValueClicked() + downCustomValueClicked() + newCustomVariableActive() + addCustomValueClicked() + groupRequirementsChanged( int ) + groupLibrariesChanged( int ) + groupTemplateChanged( int ) + targetInstallChanged( bool ) + apply() + activateApply( int ) + activateApply( const QString & ) + activateApply( QListViewItem * ) + customVarChanged() + + + + + kpushbutton.h + kpushbutton.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + kurlrequester.h + kpushbutton.h + klistview.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kpushbutton.h + kcombobox.h + ktextedit.h + + diff --git a/buildtools/qmake/qmakedefaultopts.cpp b/buildtools/qmake/qmakedefaultopts.cpp new file mode 100644 index 00000000..14ca7aa0 --- /dev/null +++ b/buildtools/qmake/qmakedefaultopts.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "qmakedefaultopts.h" + +#include +#include +#include +#include + +#include + +QMakeDefaultOpts::QMakeDefaultOpts() +{ + +} + +void QMakeDefaultOpts::readVariables( const QString& qmake, const QString& projdir ) +{ + KTempFile makefile (projdir+"/", ".mf"); + KTempFile qmakefile(projdir+"/", ".pro"); + if ( makefile.status() == 0 && qmakefile.status() == 0 ) + { + makefile.close(); + qmakefile.close(); + + BlockingKProcess proc; + kdDebug(9024) << "KProc Working dir:" << projdir << endl; + proc.setWorkingDirectory( projdir ); + proc << qmake; + proc << "-d"; + proc << "-o"; + proc << makefile.name(); + proc << qmakefile.name(); + kdDebug(9024) << "Executing:" << proc.args() << endl; + proc.start( KProcess::NotifyOnExit, KProcess::Stderr ); + if( !proc.isRunning() && !proc.normalExit() ) + { + kdDebug(9024) << "Couldn't execute qmake: " << proc.args() << endl; + makefile.unlink(); + qmakefile.unlink(); + m_variables.clear(); + m_keys.clear(); + }else + { + makefile.unlink(); + qmakefile.unlink(); + QStringList lines = QStringList::split( "\n", proc.stdErr() ); + kdDebug(9024) << "Got " << lines.count() << " lines" << endl; + for ( QStringList::const_iterator it = lines.begin(); it != lines.end(); ++it) + { + QString line = *it; + QRegExp re( "DEBUG 1: ([^ =:]+) === (.*)" ); + if ( re.exactMatch( line ) ) + { + QString var = re.cap( 1 ); + QStringList values = QStringList::split( " :: ", re.cap( 2 ) ); + m_variables[var] = values; + m_keys.append( var ); + } + } + } + } +} + +QMakeDefaultOpts::~QMakeDefaultOpts() +{ +} + +const QStringList QMakeDefaultOpts::variableValues( const QString& var ) const +{ +// QStringList result; + if ( m_variables.contains(var) ) + return m_variables[var]; + return QStringList(); +} + +const QStringList& QMakeDefaultOpts::variables() const +{ + return m_keys; +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakedefaultopts.h b/buildtools/qmake/qmakedefaultopts.h new file mode 100644 index 00000000..63bab54b --- /dev/null +++ b/buildtools/qmake/qmakedefaultopts.h @@ -0,0 +1,49 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef QMAKEDEFAULTOPTS_H +#define QMAKEDEFAULTOPTS_H + +#include +#include +// #include + +// class KTempFile; +// class BlockingKProcess; + +class QMakeDefaultOpts +{ +public: + QMakeDefaultOpts( ); + + ~QMakeDefaultOpts(); + + void readVariables( const QString& qtdir, const QString& projdir ); + + const QStringList variableValues( const QString& ) const; + const QStringList& variables() const; + +// signals: +// void variablesRead(); + +// private slots: +// void slotReadStderr( KProcess*, char*, int ); +// void slotFinished( KProcess* ); + +private: + QMap m_variables; + QStringList m_keys; +}; + +#endif + + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakeoptionswidget.cpp b/buildtools/qmake/qmakeoptionswidget.cpp new file mode 100644 index 00000000..89f63c1e --- /dev/null +++ b/buildtools/qmake/qmakeoptionswidget.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "qmakeoptionswidget.h" + +#include +#include +#include +#include + +#include +#include + +QMakeOptionsWidget::QMakeOptionsWidget( const QString& projectdir, QDomDocument &dom, const QString &configGroup, + QWidget *parent, const char *name ) + : QMakeOptionsWidgetBase( parent, name ), + m_dom( dom ), m_configGroup( configGroup ), m_projectDir( projectdir ) +{ + groupBehaviour->setButton( DomUtil::readIntEntry( dom, configGroup+"/qmake/savebehaviour", 2) ); + checkReplacePaths->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/replacePaths", false ) ); + checkDisableDefaultOpts->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/disableDefaultOpts", true ) ); + checkFilenamesOnly->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/enableFilenamesOnly", false ) ); + showVariablesInTree->setChecked( DomUtil::readBoolEntry( dom, configGroup+"/qmake/showVariablesInTree", true ) ); + checkShowParseErrors->setChecked( DomUtil::readBoolEntry( dom, + configGroup+"/qmake/showParseErrors", true ) ); + qmakeProjectFile->setURL( DomUtil::readEntry( dom, configGroup+"/qmake/projectfile", "" ) ); + qmakeProjectFile->setMode( KFile::File | KFile::ExistingOnly | KFile::LocalOnly ); + qmakeProjectFile->setFilter( "*.pro *.pri" ); + if( qmakeProjectFile->url().isEmpty() ) + { + qmakeProjectFile->setURL( projectdir ); + } +} + + +QMakeOptionsWidget::~QMakeOptionsWidget() +{} + + +void QMakeOptionsWidget::accept() +{ + DomUtil::writeIntEntry( m_dom, m_configGroup + "/qmake/savebehaviour", groupBehaviour->selectedId() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/replacePaths", checkReplacePaths->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/disableDefaultOpts", checkDisableDefaultOpts->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/enableFilenamesOnly", checkFilenamesOnly->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/showVariablesInTree", showVariablesInTree->isChecked() ); + DomUtil::writeBoolEntry( m_dom, m_configGroup + "/qmake/showParseErrors", checkShowParseErrors->isChecked() ); + QString projfile = qmakeProjectFile->url(); + if( projfile != m_projectDir && QFileInfo( projfile ).isFile() && ( projfile.endsWith( ".pro" ) || projfile.endsWith( ".pri" ) ) ) + DomUtil::writeEntry( m_dom, m_configGroup + "/qmake/projectfile", projfile ); +} + +#include "qmakeoptionswidget.moc" + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakeoptionswidget.h b/buildtools/qmake/qmakeoptionswidget.h new file mode 100644 index 00000000..c50e4b44 --- /dev/null +++ b/buildtools/qmake/qmakeoptionswidget.h @@ -0,0 +1,39 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef QMAKEOPTIONSWIDGET_H +#define QMAKEOPTIONSWIDGET_H + +#include "qmakeoptionswidgetbase.h" + +#include + +class QMakeOptionsWidget : public QMakeOptionsWidgetBase +{ + Q_OBJECT +public: + QMakeOptionsWidget( const QString& projectdir, QDomDocument &dom, const QString &configGroup, + QWidget *parent = 0, const char *name = 0 ); + ~QMakeOptionsWidget(); + +public slots: + void accept(); +private: + QDomDocument &m_dom; + QString m_configGroup; + QString m_projectDir; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + + diff --git a/buildtools/qmake/qmakeoptionswidgetbase.ui b/buildtools/qmake/qmakeoptionswidgetbase.ui new file mode 100644 index 00000000..0ad833d1 --- /dev/null +++ b/buildtools/qmake/qmakeoptionswidgetbase.ui @@ -0,0 +1,217 @@ + +QMakeOptionsWidgetBase + + + QMakeOptionsWidgetBase + + + + 0 + 0 + 738 + 523 + + + + QMake Manager Options + + + + unnamed + + + + textLabel1_2 + + + - Also look into C++/Qt to define the QMake, Qt and Designer paths. +- Environment variables that should be resolved during parsing can be set on the Make Options page. +- For changes on this page to take effect the project needs to be reloaded. + + + + + layout1 + + + + unnamed + + + + textLabel1_3 + + + QMake Project File: + + + qmakeProjectFile + + + + + qmakeProjectFile + + + This is the top level qmake project file, from which the project manager will be populated. +Leave this empty to automatically search for a .pro file in the project directory. + + + + + + + groupBehaviour + + + true + + + Behaviour on Subproject Change + + + + unnamed + + + + textLabel1 + + + The following settings determine what the project configuration dialog should do when another subproject is selected while the dialog is still open. + + + WordBreak|AlignVCenter + + + + + radioAlwaysSave + + + &Always Save + + + Always save the configuration when changing the project. + + + Always save the project configuration when selecting a another sub project. + + + + + radioNeverSave + + + &Never Save (Warning: This can lead to loss of setting changes) + + + Never save the configuration when changing the project. + + + Never save the project configuration when selecting a another sub project. + + + + + radioAsk + + + As&k + + + true + + + Ask whether the configuration should be saved when switching the project. + + + Always ask whether the configuration should be saved when selecting another subproject. + + + + + + + checkReplacePaths + + + + 5 + 5 + 0 + 0 + + + + Repla&ce File Paths with matching Variables when adding files + + + false + + + This replaces the relative paths of added files with existing custom variables if the value assigned to it is the same as the path. + + + + + showVariablesInTree + + + Show variables in filenames in the QMake projectmanager view. + + + + + checkFilenamesOnly + + + Display only filenames in the QMake Manager (Project reload is needed after changing this setting) + + + + + checkDisableDefaultOpts + + + Do not use the QMake Default Options +This disables the reading of any .qmake.cache files or mkspecs. + + + + + checkShowParseErrors + + + Show parse error in message box + + + true + + + + + spacer1 + + + Vertical + + + Expanding + + + + 20 + 50 + + + + + + + + kurlrequester.h + klineedit.h + kpushbutton.h + + diff --git a/buildtools/qmake/qmakescopeitem.cpp b/buildtools/qmake/qmakescopeitem.cpp new file mode 100644 index 00000000..66fa3c3f --- /dev/null +++ b/buildtools/qmake/qmakescopeitem.cpp @@ -0,0 +1,928 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* Part of this file is taken from Qt Designer. * +* * +* 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 "qmakescopeitem.h" + +#include +#include + +#include +#include +#include +#include + +#include "scope.h" +#include "urlutil.h" +#include "trollprojectwidget.h" +/* + * Class qProjectItem + */ + +qProjectItem::qProjectItem( Type type, QListView *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{} + + +qProjectItem::qProjectItem( Type type, qProjectItem *parent, const QString &text ) + : QListViewItem( parent, text ), typ( type ) +{} + + + +/* + * Class GroupItem + */ + +GroupItem::GroupItem( QListView *lv, GroupType type, const QString &text, QMakeScopeItem* spitem ) + : qProjectItem( Group, lv, text ) +{ + this->owner = spitem; + groupType = type; +// files.setAutoDelete( true ); + setPixmap( 0, SmallIcon( "tar" ) ); +} + +GroupItem::GroupType GroupItem::groupTypeForExtension( const QString &ext ) +{ + if ( ext == "cpp" || ext == "cc" || ext == "c" || ext == "C" || ext == "c++" || ext == "cxx" || ext == "ocl" ) + return Sources; + else if ( ext == "hpp" || ext == "h" || ext == "hxx" || ext == "hh" || ext == "h++" || ext == "H" ) + return Headers; + else if ( ext == "ui" ) + return Forms; + else if ( ext == "jpg" || ext == "jpeg" || ext == "png" || ext == "xpm" || ext == "gif" || ext == "bmp" ) + return Images; + else if ( ext == "idl" ) + return IDLs; + else if ( ext == "l" || ext == "ll" || ext == "lxx" || ext == "l++" ) + return Lexsources; + else if ( ext == "y" || ext == "yy" || ext == "yxx" || ext == "y++" ) + return Yaccsources; + else if ( ext == "ts" ) + return Translations; + else if ( ext == "qrc" ) + return Resources; + else + return Distfiles; +} + +void GroupItem::groupTypeMeanings( GroupItem::GroupType type, QString& title, QString& ext ) +{ + switch ( type ) + { + case GroupItem::Sources: + title = i18n( "Sources" ); + ext = "*.cpp *.c"; + break; + case GroupItem::Headers: + title = i18n( "Headers" ); + ext = "*.h *.hpp"; + break; + case GroupItem::Forms: + title = i18n( "Forms" ); + ext = "*.ui"; + break; + case GroupItem::IDLs: + title = i18n( "Corba IDLs" ); + ext = "*.idl *.kidl"; + break; + case GroupItem::Lexsources: + title = i18n( "Lexsources" ); + ext = "*.l *.ll *.lxx *.l++"; + break; + case GroupItem::Yaccsources: + title = i18n( "Yaccsources" ); + ext = "*.y *.yy *.yxx *.y++"; + break; + case GroupItem::Images: + title = i18n( "Images" ); + ext = "*.jpg *.jpeg *.png *.xpm *.gif *.bmp"; + break; + case GroupItem::Resources: + title = i18n( "Resources" ); + ext = "*.qrc"; + break; + case GroupItem::Distfiles: + title = i18n( "Distfiles" ); + ext = "*"; + break; + case GroupItem::Translations: + title = i18n( "Translations" ); + ext = "*.ts"; + break; + case GroupItem::InstallRoot: + title = i18n( "Installs" ); + ext = "*"; + break; + case GroupItem::InstallObject: + title = i18n( "Install object" ); + ext = "*"; + break; + + default: // just give back source files, et all + title = i18n( "Source Files" ); + ext = "*.cpp *.cc *.ocl *.c *.hpp *.h *.ui"; + } +} + +void GroupItem::paintCell( QPainter* p, const QColorGroup& c, int column, int width, int align ) +{ + QColorGroup cg( c ); + if ( !firstChild() ) + { + cg.setColor( QColorGroup::Text, cg.mid() ); + } + + qProjectItem::paintCell( p, cg, column, width, align ); +} + +void GroupItem::addFileToScope( const QString& filename ) +{ + QString file = filename; + + QPtrListIterator it( files ); + while ( it.current() != 0 ) + { + if ( it.current() ->text( 0 ) == file ) //File already exists in this subproject + return ; + ++it; + } + + FileItem *fitem = owner->createFileItem( file ); + + fitem->uiFileLink = owner->m_widget->getUiFileLink( owner->relativePath() + QString( QChar( QDir::separator() ) ), owner->scope->resolveVariables( filename ) ); + files.append( fitem ); + switch ( groupType ) + { + case GroupItem::Sources: + owner->addValue( "SOURCES", file ); + break; + case GroupItem::Headers: + owner->addValue( "HEADERS", file ); + break; + case GroupItem::Forms: + if( owner->m_widget->isTMakeProject() ) + owner->addValue( "INTERFACES", file ); + else + owner->addValue( "FORMS", file ); + break; + case GroupItem::IDLs: + owner->addValue( "IDLS", file ); + break; + case GroupItem::Lexsources: + owner->addValue( "LEXSOURCES", file ); + break; + case GroupItem::Yaccsources: + owner->addValue( "YACCSOURCES", file ); + break; + case GroupItem::Images: + owner->addValue( "IMAGES", file ); + break; + case GroupItem::Resources: + owner->addValue( "RESOURCES", file ); + break; + case GroupItem::Distfiles: + owner->addValue( "DISTFILES", file ); + break; + case GroupItem::Translations: + owner->addValue( "TRANSLATIONS", file ); + break; + case GroupItem::InstallObject: + owner->addValue( text( 0 ) + ".files", file ); + break; + default: + break; + } + owner->scope->saveToFile(); +} + +void GroupItem::removeFileFromScope( const QString& filename ) +{ + QString filePath; + + QPtrListIterator it( files ); + while ( it.current() != 0 ) + { + if ( it.current() ->text( 0 ) == filename ) //File already exists in this subproject + { + FileItem * fitem = it.current(); + filePath = fitem->localFilePath; + files.remove( it ); + delete fitem; + break; + } + ++it; + } + + if ( groupType == GroupItem::Sources ) + { + owner->removeValue( "SOURCES", filePath ); + } + else if ( groupType == GroupItem::Headers ) + { + owner->removeValue( "HEADERS", filePath ); + } + else if ( groupType == GroupItem::Forms ) + { + owner->removeValue( "FORMS", filePath ); + } + else if ( groupType == GroupItem::Images ) + { + owner->removeValue( "IMAGES", filePath ); + } + else if ( groupType == GroupItem::Resources ) + { + owner->removeValue( "RESOURCES", filePath ); + } + else if ( groupType == GroupItem::Lexsources ) + { + owner->removeValue( "LEXSOURCES", filePath ); + } + else if ( groupType == GroupItem::Yaccsources ) + { + owner->removeValue( "YACCSOURCES", filePath ); + } + else if ( groupType == GroupItem::Translations ) + { + owner->removeValue( "TRANSLATIONS", filePath ); + } + else if ( groupType == GroupItem::IDLs ) + { + owner->removeValue( "IDL", filePath ); + } + else if ( groupType == GroupItem::Distfiles ) + { + owner->removeValue( "DISTFILES", filePath ); + } + else if ( groupType == GroupItem::InstallObject ) + { + owner->removeValue( text( 0 ) + ".files", filePath ); + } + owner->scope->saveToFile(); +} + +void GroupItem::addInstallObject( const QString& objectname ) +{ + GroupItem * objitem = owner->createGroupItem( GroupItem::InstallObject, objectname, owner ); + owner->addValue( "INSTALLS", objectname ); + owner->scope->saveToFile(); + installs.append( objitem ); +} + +void GroupItem::removeInstallObject( GroupItem* item ) +{ + owner->removeValue( "INSTALLS", item->text(0) ); + owner->scope->saveToFile(); + installs.remove( item ); + delete item; +} + +/* + * Class FileItem + */ + +FileItem::FileItem( QListView *lv, const QString &text ) + : qProjectItem( File, lv, text ), uiFileLink( "" ) +{ + // if excluded is set the file is excluded in the subproject/project. + // by default excluded is set to false, thus file is included + // excluded = exclude; + setPixmap( 0, SmallIcon( "document" ) ); +} + + +/* + * Class QMakeScopeItem + */ + +QMakeScopeItem::QMakeScopeItem( QListView *parent, const QString &text, Scope* s, TrollProjectWidget* widget ) + : qProjectItem( Subproject, parent, text ), scope( s ), m_widget( widget ) +{ + // configuration.m_template = QTMP_APPLICATION; + init(); +} + + +QMakeScopeItem::QMakeScopeItem( QMakeScopeItem *parent, const QString &text, Scope* s ) + : qProjectItem( Subproject, parent, text ), scope( s ), m_widget( parent->m_widget ) +{ + init(); +} + +QMakeScopeItem::~QMakeScopeItem() +{ + QMap::iterator it; + for ( it = groups.begin() ; it != groups.end() ; ++it ) + { + GroupItem* s = it.data(); + delete s; + } + groups.clear(); + +} + +QString QMakeScopeItem::relativePath() +{ + if( !scope || !scope->parent() ) + return ""; + if( scope->scopeType() == Scope::ProjectScope ) + { + if( scope->parent() && scope->parent()->variableValues("SUBDIRS").contains( URLUtil::relativePathToFile( scope->parent()->projectDir(), scope->projectDir()+"/"+scope->fileName() ) ) ) + { + return URLUtil::relativePathToFile( scope->parent()->projectDir(), scope->projectDir()+"/"+scope->fileName() ); + }else + { + return URLUtil::getRelativePath( m_widget->projectDirectory(), scope->projectDir() ); + } + }else + return static_cast( parent() ) ->relativePath(); +// if( !scope->parent() ) +// return ""; +// else if ( !scope->parent()->parent() || scope->scopeType() != Scope::ProjectScope ) +// return scope->scopeName(); +// else if ( scope->scopeType() == Scope::ProjectScope ) +// return ( static_cast( parent() ) ->relativePath() +// + QString( QChar( QDir::separator() ) ) + scope->scopeName() ); +// else +// return ( static_cast( parent() ) ->relativePath() ); +} + +QString QMakeScopeItem::getSharedLibAddObject( QString basePath ) +{ + if ( scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + if ( !scope->variableValues( "DESTDIR" ).front().isEmpty() ) + { + if ( QDir::isRelativePath( scope->variableValues( "DESTDIR" ).front() ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + scope->variableValues( "DESTDIR" ).front(); + else + tmpPath = scope->variableValues( "DESTDIR" ).front(); + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + QString libString; + if ( !scope->variableValues( "TARGET" ).front().isEmpty() ) + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + scope->variableValues( "TARGET" ).front() + ".so"; + + } + else + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + scope->projectName() + ".so"; + + } + return ( libString ); + } + return ""; +} + +QString QMakeScopeItem::getApplicationObject( QString basePath ) +{ + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + QString destdir = scope->resolveVariables( scope->variableValues( "DESTDIR" ).front() ); + + if ( !destdir.isEmpty() ) + { + if ( QDir::isRelativePath( destdir ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + destdir; + else + tmpPath = destdir; + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + QString target = scope->resolveVariables( scope->variableValues( "TARGET" ).front() ); + + if ( target.isEmpty() ) + return tmpPath + QString( QChar( QDir::separator() ) ) + scope->projectName(); + else + return tmpPath + QString( QChar( QDir::separator() ) ) + target; +} + +QString QMakeScopeItem::getLibAddObject( QString basePath ) +{ + if ( scope->variableValues( "CONFIG" ).findIndex( "dll" ) != -1 ) + { + QString target = scope->resolveVariables( scope->variableValues( "TARGET" ).front() ); + if ( !target.isEmpty() ) + { + return ( "-l" + target ); + } + else + { + return ( "-l" + scope->projectName() ); + } + } + else if ( scope->variableValues( "CONFIG" ).findIndex( "staticlib" ) != -1 + || scope->variableValues("TEMPLATE").findIndex("lib") != -1 ) + { + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + QString destdir = scope->resolveVariables( scope->variableValues( "DESTDIR" ).front() ); + if ( !destdir.isEmpty() ) + { + if ( QDir::isRelativePath( destdir ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + destdir; + else + tmpPath = destdir; + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + QString libString; + QString target = scope->resolveVariables( scope->variableValues( "TARGET" ).front() ); + if ( !target.isEmpty() ) + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + target + ".a"; + + } + else + { + libString = tmpPath + QString( QChar( QDir::separator() ) ) + "lib" + scope->projectName() + ".a"; + + } + return ( libString ); + } + + return ( "" ); +} +QString QMakeScopeItem::getLibAddPath( QString basePath ) +{ + + //PATH only add if shared lib + if ( scope->variableValues( "CONFIG" ).findIndex( "dll" ) == -1 ) return ( "" ); + + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + QString destdir = scope->resolveVariables( scope->variableValues( "DESTDIR" ).front() ); + if ( !destdir.isEmpty() ) + { + if ( QDir::isRelativePath( destdir ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + destdir; + else + tmpPath = destdir; + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + return ( tmpPath ); + +} + +QString QMakeScopeItem::getIncAddPath( QString basePath ) +{ + QString tmpPath = URLUtil::getRelativePath( basePath, scope->projectDir() ); + tmpPath = QDir::cleanDirPath( tmpPath ); + + return ( tmpPath ); +} + +void QMakeScopeItem::buildSubTree() +{ + QValueList::const_iterator it; + + sortChildItems( 0, false ); + + QValueList scopes = scope->scopesInOrder(); + + for ( it = scopes.begin(); it != scopes.end(); ++it ) + { + if( (*it)->scopeType() != Scope::InvalidScope ) + new QMakeScopeItem( this, ( *it )->scopeName(), ( *it ) ); + else + kdDebug( 9024 ) << "No QMakeScopeItem created" << endl; + } +} + + +void QMakeScopeItem::init() +{ + if ( scope->scopeType() == Scope::SimpleScope ) + { + setPixmap( 0, SmallIcon( "qmake_scope" ) ); + } + else if ( scope->scopeType() == Scope::FunctionScope ) + { + setPixmap( 0, SmallIcon( "qmake_func_scope" ) ); + } + else if ( scope->scopeType() == Scope::IncludeScope ) + { + setPixmap( 0, SmallIcon( "qmake_inc_scope" ) ); + } + else + { + QStringList tmp = scope->variableValues( "TEMPLATE" ); + if( scope->isEnabled() ) + { + if ( tmp.findIndex( "subdirs" ) != -1 ) + setPixmap( 0, SmallIcon( "folder" ) ); + else if ( tmp.findIndex( "lib" ) != -1 ) + setPixmap( 0, SmallIcon( "qmake_lib" ) ); + else + setPixmap( 0, SmallIcon( "qmake_app" ) ); + }else + { + if ( tmp.findIndex( "subdirs" ) != -1 ) + setPixmap( 0, SmallIcon( "folder_grey" ) ); + else if ( tmp.findIndex( "lib" ) != -1 ) + setPixmap( 0, SmallIcon( "qmake_lib_disabled" ) ); + else + setPixmap( 0, SmallIcon( "qmake_app_disabled" ) ); + } + } + + setEnabled( scope->isEnabled() ); + if( scope->isEnabled() ) + { + buildGroups(); + buildSubTree(); + } +} + +GroupItem* QMakeScopeItem::createGroupItem( GroupItem::GroupType type, const QString& label, QMakeScopeItem* scopeitem ) +{ + GroupItem * item = new GroupItem( scopeitem->listView(), type, label, scopeitem ); + scopeitem->listView() ->takeItem( item ); + return item; +} + +FileItem* QMakeScopeItem::createFileItem( const QString& name ) +{ + QString display = name; + if( m_widget->showFilenamesOnly() ) + { + int dirSepPos = name.findRev( QChar( QDir::separator() ) ); + if ( dirSepPos != - 1 ) + display = name.mid( dirSepPos + 1 ); + } + if( !m_widget->showVariablesInTree() ) + { + display = scope->resolveVariables( display ); + } + FileItem * fitem = new FileItem( listView(), display ); + listView() ->takeItem( fitem ); + + fitem->localFilePath = name; + + return fitem; +} + +void QMakeScopeItem::buildGroups() +{ + if( scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + return; + QStringList values; + + GroupItem* item; + QStringList::iterator it; + + values = scope->variableValues( "INSTALLS" ); + item = createGroupItem( GroupItem::InstallRoot, "INSTALLS", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + if ( ( *it ) == "target" ) + continue; + + QString path = scope->variableValues( *it + ".path" ).front(); + GroupItem* installitem = createGroupItem( GroupItem::InstallObject, *it, this ); + item->installs.append( installitem ); + QStringList files = scope -> variableValues( *it + ".files" ); + if ( !files.isEmpty() ) + { + QStringList::iterator filesit = files.begin(); + for ( ;filesit != files.end(); ++filesit ) + { + installitem->files.append( createFileItem( *filesit ) ); + } + } + } + + values = scope->variableValues( "LEXSOURCES" ); + item = createGroupItem( GroupItem::Lexsources, "LEXSOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "YACCSOURCES" ); + item = createGroupItem( GroupItem::Yaccsources, "YACCSOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "DISTFILES" ); + item = createGroupItem( GroupItem::Distfiles, "DISTFILES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + if ( scope->isQt4Project() ) + { + values = scope->variableValues( "RESOURCES" ); + item = createGroupItem( GroupItem::Resources, "RESOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + } + values = scope->variableValues( "IMAGES" ); + item = createGroupItem( GroupItem::Images, "IMAGES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "TRANSLATIONS" ); + item = createGroupItem( GroupItem::Translations, "TRANSLATIONS", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "IDLS" ); + item = createGroupItem( GroupItem::IDLs, "Corba IDL", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + if ( m_widget->isTMakeProject() ) + { + values = scope->variableValues( "INTERFACES" ); + item = createGroupItem( GroupItem::Forms, "INTERFACES", this ); + } + else + { + values = scope->variableValues( "FORMS" ); + item = createGroupItem( GroupItem::Forms, "FORMS", this ); + } + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + item->files.append( createFileItem( *it ) ); + } + + values = scope->variableValues( "SOURCES" ); + item = createGroupItem( GroupItem::Sources, "SOURCES", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + FileItem* fitem = createFileItem( *it ); + fitem->uiFileLink = m_widget->getUiFileLink( relativePath() + QString( QChar( QDir::separator() ) ), scope->resolveVariables( *it ) ); + item->files.append( fitem ); + } + + values = scope->variableValues( "HEADERS" ); + item = createGroupItem( GroupItem::Headers, "HEADERS", this ); + groups.insert( item->groupType, item ); + for ( it = values.begin(); it != values.end(); ++it ) + { + FileItem* fitem = createFileItem( *it ); + fitem->uiFileLink = m_widget->getUiFileLink( relativePath() + QString( QChar( QDir::separator() ) ), scope->resolveVariables( *it ) ); + item->files.append( fitem ); + } + +} + +void QMakeScopeItem::removeValues( const QString& var, const QStringList& values ) +{ + for( QStringList::const_iterator it = values.begin() ; it != values.end(); ++it ) + { + removeValue( var, *it ); + } +} + +void QMakeScopeItem::addValues( const QString& var, const QStringList& values ) +{ + for( QStringList::const_iterator it = values.begin() ; it != values.end(); ++it ) + { + addValue( var, *it ); + } +} + +void QMakeScopeItem::removeValue( const QString& var, const QString& value ) +{ + if( scope->scopeType() != Scope::IncludeScope && scope->variableValues( var ).findIndex( value ) != -1 ) + { + if( scope->variableValuesForOp( var, "+=" ).findIndex(value) != -1 ) + { + scope->removeFromPlusOp( var, QStringList( value ) ); + if( scope->variableValues( var ).findIndex( value ) != -1 ) + { + scope->addToMinusOp( var, QStringList( value ) ); + } + }else + scope->addToMinusOp( var, QStringList( value ) ); + }else if( scope->scopeType() == Scope::IncludeScope ) + { + scope->addToMinusOp( var, QStringList( value ) ); + } +} + +void QMakeScopeItem::addValue( const QString& var, const QString& value ) +{ + if( scope->scopeType() != Scope::IncludeScope && scope->variableValues( var ).findIndex( value ) == -1 ) + { + if( scope->variableValuesForOp( var, "-=" ).findIndex(value) != -1 ) + scope->removeFromMinusOp( var, QStringList( value ) ); + else + scope->addToPlusOp( var, QStringList( value ) ); + }else if( scope->scopeType() == Scope::IncludeScope ) + { + scope->addToPlusOp( var, QStringList( value ) ); + } +} + +void QMakeScopeItem::updateValues( const QString& var, const QStringList& values ) +{ + QStringList curValues = scope->variableValues( var, (scope->scopeType() != Scope::IncludeScope) ); + QStringList scopeValues = scope->variableValuesForOp( var, "+=" ); + for( QStringList::const_iterator it = curValues.begin(); it != curValues.end(); ++it ) + { + if ( values.findIndex( *it ) == -1 ) + { + if( scopeValues.findIndex( *it ) != -1 ) + { + scope->removeFromPlusOp( var, QStringList( *it ) ); + scopeValues.remove( *it ); + }else + scope->addToMinusOp( var, QStringList( *it ) ); + } + } + for( QStringList::const_iterator it = values.begin(); it != values.end(); ++it ) + { + if ( scopeValues.findIndex( *it ) != -1 ) + { + scopeValues.remove(*it); + } + } +// kdDebug(9024) << "--------------" << var << "------------------" << endl; +// kdDebug(9024) << "values: " << values << "| scope:" << scopeValues << endl; + scopeValues += values; +// kdDebug(9024) << "values: " << values << "| scope:" << scopeValues << endl; + scope->setPlusOp( var, scopeValues ); +// QStringList tmp = scope->variableValuesForOp( var, "+=" ); +// kdDebug(9024) << "result:" << tmp << endl; +// kdDebug(9024) << "---------------------------------------" << endl; +} + +QMakeScopeItem* QMakeScopeItem::projectFileItem() +{ + if( scope->scopeType() != Scope::ProjectScope ) + { + QMakeScopeItem* parentitem = dynamic_cast(parent()); + if( parentitem ) + return parentitem->projectFileItem(); + } + return this; +} + +void QMakeScopeItem::reloadProject() +{ + kdDebug(9024) << "Reloading Project" << endl; + QListViewItem* item = firstChild(); + while( item ) + { + QListViewItem* olditem = item; + item = olditem->nextSibling(); + delete olditem; + } + QMap::iterator it; + for ( it = groups.begin() ; it != groups.end() ; ++it ) + { + GroupItem* s = it.data(); + QListView* l = s->listView(); + if(l) + l->removeItem(s); + delete s; + } + groups.clear(); + scope->reloadProject(); + init(); +} + +void QMakeScopeItem::disableSubprojects( const QStringList& dirs ) +{ + QStringList::const_iterator it = dirs.begin(); + for( ; it != dirs.end() ; ++it) + { + if( scope->variableValues("SUBDIRS").findIndex(*it) != -1 ) + { + Scope* s = scope->disableSubproject(*it); + if( !s ) + return; + else + { + QMakeScopeItem* newitem = new QMakeScopeItem( this, s->scopeName(), s ); + QListViewItem* lastitem = firstChild(); + while( lastitem && lastitem->nextSibling() ) + lastitem = lastitem->nextSibling(); + if( lastitem ) + newitem->moveItem(lastitem); + } + } + } + +} + +int QMakeScopeItem::compare( QListViewItem* i, int , bool ) const +{ + QMakeScopeItem* other = dynamic_cast(i); + if( !i ) + return -1; + if( other->scope->getNum() < scope->getNum() ) + return 1; + else if ( other->scope->getNum() > scope->getNum() ) + return -1; + else + return 0; +} + +QMap QMakeScopeItem::getLibInfos( QString basePath ) +{ + + QMap result; + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["shared_lib"] = "-l"+scope->projectName(); + else + result["shared_lib"] = "-l"+scope->variableValues( "TARGET" ).front(); + + QString tmpPath = URLUtil::getRelativePath(basePath, scope->projectDir() ); + if ( !scope->variableValues( "DESTDIR" ).front().isEmpty() ) + { + if ( QDir::isRelativePath( scope->variableValues( "DESTDIR" ).front() ) ) + tmpPath += QString( QChar( QDir::separator() ) ) + scope->variableValues( "DESTDIR" ).front(); + else + tmpPath = scope->variableValues( "DESTDIR" ).front(); + } + else + { + tmpPath += QString( QChar( QDir::separator() ) ); + } + + tmpPath = QDir::cleanDirPath( tmpPath ); + + result["shared_libdir"] = "-L"+tmpPath; + + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["shared_depend"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->projectName()+".so"; + else + result["shared_depend"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->variableValues( "TARGET" ).front()+".so"; + + + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["static_lib"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->projectName()+".a"; + else + result["static_lib"] = tmpPath+QString(QChar(QDir::separator()))+"lib"+scope->variableValues( "TARGET" ).front()+".a"; + + result["static_depend"] = result["static_lib"]; + + if ( scope->variableValues( "TARGET" ).front().isEmpty() ) + result["app_depend"] = tmpPath + QString( QChar( QDir::separator() ) ) + scope->projectName(); + else + result["app_depend"] = tmpPath + QString( QChar( QDir::separator() ) ) + scope->variableValues( "TARGET" ).front(); + + QString map; + for( QMap::const_iterator it = result.begin(); it != result.end(); ++it ) + map += "["+it.key() + "=>" +it.data() + "],"; + kdDebug(9024) << "Running getLibInfo for" << scope->projectName() << "|" << map << endl; + return result; +} + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/qmakescopeitem.h b/buildtools/qmake/qmakescopeitem.h new file mode 100644 index 00000000..b2c84345 --- /dev/null +++ b/buildtools/qmake/qmakescopeitem.h @@ -0,0 +1,128 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _QMAKESCOPEITEM_H_ +#define _QMAKESCOPEITEM_H_ + +#include +#include + +class Scope; +class QMakeScopeItem; +class FileItem; +class TrollProjectWidget; + +/** + * Base class for all items appearing in ProjectOverview and ProjectDetails. + */ +class qProjectItem : public QListViewItem +{ +public: + enum Type { Subproject, Group, File }; + + qProjectItem( Type type, QListView *parent, const QString &text ); + qProjectItem( Type type, qProjectItem *parent, const QString &text ); + + QString scopeString; + Type type() + { return typ; } + +private: + Type typ; + void init(); + +}; + + +class GroupItem : public qProjectItem +{ +public: + enum GroupType {NoType, Sources, Headers, Forms, Distfiles, Images, Resources, Lexsources, Yaccsources, Translations, IDLs, InstallRoot, InstallObject, MaxTypeEnum }; + + static GroupType groupTypeForExtension( const QString &ext ); + static void groupTypeMeanings( GroupItem::GroupType type, QString& title, QString& ext ); + + GroupItem( QListView *lv, GroupType type, const QString &text, QMakeScopeItem* spitem ); + + void removeFileFromScope( const QString& filename); + void addFileToScope( const QString& filename); + void addInstallObject( const QString& objectname); + void removeInstallObject( GroupItem* item ); + + // qmake INSTALLS support + QPtrList installs; + QPtrList files; + +// QStringList str_files; +// QStringList str_files_exclude; + // end qmake INSTALLS support + GroupType groupType; + QMakeScopeItem* owner; + +protected: + void paintCell( QPainter* p, const QColorGroup& cg, int column, int width, int align ); +}; + + +// Not sure if this complexity is really necessary... +class FileItem : public qProjectItem +{ +public: + FileItem( QListView *lv, const QString &text ); + + QString uiFileLink; + QString localFilePath; +}; + +/** + * Stores one Scope + */ +class QMakeScopeItem : public qProjectItem +{ +public: + QMakeScopeItem( QListView *parent, const QString &text, Scope *s, TrollProjectWidget* widget ); + QMakeScopeItem( QMakeScopeItem *parent, const QString &text, Scope* ); + void updateValues( const QString& var, const QStringList& values ); + void addValue( const QString& var, const QString& value ); + void removeValue( const QString& var, const QString& value ); + void addValues( const QString& var, const QStringList& values ); + void removeValues( const QString& var, const QStringList& values ); + void disableSubprojects( const QStringList& ); + void reloadProject(); + int compare( QListViewItem* i, int col, bool ascending ) const; + ~QMakeScopeItem(); + + QMap groups; + + Scope* scope; + QString relativePath(); + QString getLibAddPath( QString ); + QString getLibAddObject( QString ); + QString getSharedLibAddObject( QString ); + QString getApplicationObject( QString ); + QString getIncAddPath( QString downDirs ); + FileItem* createFileItem(const QString& file); + GroupItem* createGroupItem(GroupItem::GroupType type, const QString& name, QMakeScopeItem* scopeitem); + QMap getLibInfos( QString ); + + QMakeScopeItem* projectFileItem(); + + TrollProjectWidget* m_widget; +private: + void init(); + void buildSubTree(); + void buildGroups(); +}; + + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/scope.cpp b/buildtools/qmake/scope.cpp new file mode 100644 index 00000000..c090861b --- /dev/null +++ b/buildtools/qmake/scope.cpp @@ -0,0 +1,1710 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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 "scope.h" + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "urlutil.h" +#include "trollprojectpart.h" +#include "qmakedefaultopts.h" + +const QStringList Scope::KnownVariables = QStringList() << "QT" << "CONFIG" << "TEMPLATE" << "SUBDIRS" << "VERSION" << "LIBS" << "target.path" << "INSTALLS" << "MAKEFILE" << "TARGETDEPS" << "INCLUDEPATH" << "TARGET" << "DESTDIR" << "DEFINES" << "QMAKE_CXXFLAGS_DEBUG" << "QMAKE_CXXFLAGS_RELEASE" << "OBJECTS_DIR" << "UI_DIR" << "MOC_DIR" << "IDL_COMPILER" << "IDL_OPTIONS" << "RCC_DIR" << "IDLS" << "RESOURCES" << "IMAGES" << "LEXSOURCES" << "DISTFILES" << "YACCSOURCES" << "TRANSLATIONS" << "HEADERS" << "SOURCES" << "INTERFACES" << "FORMS" ; + +const QStringList Scope::KnownConfigValues = QStringList() << "debug" << "release" << "debug_and_release" << "warn_on" << "warn_off" << "staticlib" << "dll" << "plugin" << "designer" << "create_pkgconf" << "create_libtool" << "qt" << "console" << "windows" << "x11" << "thread" << "exceptions" << "stl" << "rtti" << "opengl" << "thread" << "ordered" << "precompile_header" << "qtestlib" << "uitools" << "dbus" << "assistant" << "build_all" << "help"; + +Scope::Scope( const QMap& env, const QString &filename, TrollProjectPart* part ) + : m_root( 0 ), m_incast( 0 ), m_parent( 0 ), m_num(0), m_isEnabled( true ), m_part(part), m_defaultopts(0), m_environment( env ) +{ + if ( !loadFromFile( filename ) ) + { + if( !QFileInfo( filename ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( filename ); + }else + { + delete m_root; + m_root = 0; + } + } + loadDefaultOpts(); + if( m_root ) + { + m_part->dirWatch()->addFile(filename); + } + init(); +} + +Scope::~Scope() +{ + QMap::iterator it; + for ( it = m_scopes.begin() ; it != m_scopes.end() ; ++it ) + { + Scope* s = it.data(); + delete s; + } + m_scopes.clear(); + + m_customVariables.clear(); + if ( m_root && m_root->isProject() && !m_incast ) + { + delete m_root; + m_root = 0; + delete m_defaultopts; + m_defaultopts = 0; + } + +} + +// Simple/Function Scopes +Scope::Scope( const QMap& env, unsigned int num, Scope* parent, QMake::ProjectAST* scope, + QMakeDefaultOpts* defaultopts, TrollProjectPart* part ) + : m_root( scope ), m_incast( 0 ), m_parent( parent ), m_num(num), m_isEnabled( true ), + m_part(part), m_defaultopts(defaultopts), m_environment( env ) +{ + init(); +} + +//Subdirs +Scope::Scope( const QMap& env, unsigned int num, Scope* parent, const QString& filename, + TrollProjectPart* part, bool isEnabled ) + : m_root( 0 ), m_incast( 0 ), m_parent( parent ), m_num(num), m_isEnabled( isEnabled ), + m_part(part), m_defaultopts(0), m_environment( env ) +{ + if ( !loadFromFile( filename ) ) + { + if( !QFileInfo( filename ).exists() && QFileInfo( QFileInfo( filename ).dirPath( true ) ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( filename ); + }else + { + delete m_root; + m_root = 0; + m_isEnabled = false; + } + } + loadDefaultOpts(); + if( m_root ) + m_part->dirWatch()->addFile(filename); + init(); +} + +//Include Scope +Scope::Scope( const QMap& env, unsigned int num, Scope* parent, QMake::IncludeAST* incast, const QString& path, + const QString& incfile, QMakeDefaultOpts* defaultopts, TrollProjectPart* part ) + : m_root( 0 ), m_incast( incast ), m_parent( parent ), m_num(num), m_isEnabled( true ), + m_part(part), m_defaultopts(defaultopts), m_environment( env ) +{ + QString absfilename; + QString tmp = incfile.stripWhiteSpace(); + if( tmp.contains(")" ) ) + tmp = tmp.mid(0, tmp.find(")") ); + + if( tmp.startsWith( "\"" ) ) + tmp = tmp.mid( 1, tmp.length()-2 ); + + if( QFileInfo(tmp).isRelative() ) + { + absfilename = QDir::cleanDirPath( path + QString( QChar( QDir::separator() ) ) + tmp ); + }else + absfilename = QDir::cleanDirPath( tmp ); + if ( !loadFromFile( absfilename ) ) + { + if( !QFileInfo( absfilename ).exists() && QFileInfo( QFileInfo( absfilename ).dirPath( true ) ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( absfilename ); + }else + { + delete m_root; + m_root = 0; + m_isEnabled = false; + } + } + if( m_root ) + m_part->dirWatch()->addFile( m_root->fileName() ); + init(); +} + +bool Scope::loadFromFile( const QString& filename ) +{ + if ( !QFileInfo(filename).exists() || QMake::Driver::parseFile( filename, &m_root, 0 ) != 0 ) + { + kdDebug( 9024 ) << "Couldn't parse project: " << filename << endl; + if( DomUtil::readBoolEntry( *m_part->projectDom(), + "/kdevtrollproject/qmake/showParseErrors", true ) ) + { + KMessageBox::error( 0, i18n( "Could not parse project file: %1" ).arg( filename ), + i18n( "Could not parse project file" ) ); + } + m_root = 0; + return false; + } +// init(); + return true; +} + +void Scope::saveToFile() const +{ + if ( !m_root ) + return ; + + if ( scopeType() != ProjectScope && scopeType() != IncludeScope ) + { + m_parent->saveToFile(); + return; + } + + QString filename; + if ( scopeType() == ProjectScope ) + filename = m_root->fileName() ; + else if ( scopeType() == IncludeScope ) + filename = m_parent->projectDir() + QString( QChar( QDir::separator() ) ) + m_incast->projectName; + if ( filename.isEmpty() ) + return ; + m_part->dirWatch()->stopScan(); + QFile file( filename ); + if ( file.open( IO_WriteOnly ) ) + { + + QTextStream out( &file ); + QString astbuffer; + m_root->writeBack( astbuffer ); + out << astbuffer; + file.close(); + }else + { + KMessageBox::error( 0, i18n( "Could not write project file: %1" ).arg( filename ), + i18n( "Could not write project file" ) ); + } +#ifdef DEBUG + Scope::PrintAST pa; + pa.processProject(m_root); +#endif + m_part->dirWatch()->startScan(); +} + +void Scope::addToPlusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "+=", values, false ); +} + +void Scope::removeFromPlusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "+=", values, true ); +} + + +void Scope::addToMinusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "-=", values, false ); +} + +void Scope::removeFromMinusOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "-=", values, true ); +} + +void Scope::addToEqualOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "=", values, false ); +} + +void Scope::removeFromEqualOp( const QString& variable, const QStringList& values ) +{ + if ( !m_root ) + return ; + + updateVariable( variable, "=", values, true ); +} + +void Scope::setPlusOp( const QString& variable, const QStringList& values ) +{ + if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "+=") ) ) + return; + + updateVariable( variable, "+=", variableValuesForOp( variable, "+=" ), true ); + updateVariable( variable, "+=", values, false ); +} + +void Scope::setEqualOp( const QString& variable, const QStringList& values ) +{ + if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "=") ) ) + return; + + updateVariable( variable, "=", variableValuesForOp( variable, "=" ), true ); + updateVariable( variable, "=", values, false ); +} + +void Scope::setMinusOp( const QString& variable, const QStringList& values ) +{ + if( !m_root || Scope::listsEqual(values, variableValuesForOp(variable, "-=") ) ) + return; + + updateVariable( variable, "-=", variableValuesForOp( variable, "-=" ), true ); + updateVariable( variable, "-=", values, false ); +} + +QStringList Scope::variableValuesForOp( const QString& variable , const QString& op ) const +{ + QStringList result; + + if( !m_root ) + return result; + + QValueList::const_iterator it; + for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it ) + { + QMake::AST* ast = *it; + if ( ast->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assign = static_cast( ast ); + if ( assign->scopedID == variable && assign->op == op ) + { + result += assign->values; + } + } + } + result = cleanStringList(result); + return result; +} + +QStringList Scope::variableValues( const QString& variable, bool checkIncParent, bool fetchFromParent, bool evaluateSubScopes ) +{ + QStringList result; + + if ( !m_root ) + return result; + + if( m_varCache.contains( variable ) && fetchFromParent && ( checkIncParent || scopeType() != Scope::IncludeScope ) ) + { + return m_varCache[variable]; + } + + calcValuesFromStatements( variable, result, checkIncParent, 0, fetchFromParent, true, evaluateSubScopes ); + result = cleanStringList(result); + if( ( scopeType() != Scope::IncludeScope || checkIncParent ) && fetchFromParent ) + { + m_varCache[ variable ] = result; + } + return result; +} + +void Scope::calcValuesFromStatements( const QString& variable, QStringList& result, bool checkIncParent, QMake::AST* stopHere, bool fetchFromParent, bool setDefault, bool evaluateSubScopes ) const +{ + if( !m_root ) + return; + + /* For variables that we don't know and which are not QT/CONFIG find the default value */ + if( setDefault && m_defaultopts + && m_defaultopts->variables().findIndex(variable) != -1 + && ( variable == "TEMPLATE" || variable == "QT" || KnownVariables.findIndex(variable) == -1 || variable == "CONFIG" ) ) + { + result = m_defaultopts->variableValues(variable); + } + + if ( ( scopeType() == FunctionScope || scopeType() == SimpleScope ) && fetchFromParent ) + { + m_parent->calcValuesFromStatements( variable, result, checkIncParent, this->m_root, fetchFromParent, setDefault, evaluateSubScopes ); + } + else if ( scopeType() == IncludeScope && checkIncParent && fetchFromParent ) + { + m_parent->calcValuesFromStatements( variable, result, true, this->m_incast, fetchFromParent, setDefault, evaluateSubScopes ); + } + + QValueList::const_iterator it; + for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it ) + { + if ( stopHere && *it == stopHere ) + return ; + QMake::AST* ast = *it; + if ( ast->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assign = static_cast( ast ); + if ( assign->scopedID == variable ) + { + if ( assign->op == "=" ) + { + result = assign->values; + } + else if ( assign->op == "+=" ) + { + for ( QStringList::const_iterator sit = assign->values.begin(); sit != assign->values.end() ; ++sit ) + { + if ( result.findIndex( *sit ) == -1 ) + result.append( *sit ); + } + } + else if ( assign->op == "-=" ) + { + for ( QStringList::const_iterator sit = assign->values.begin(); sit != assign->values.end() ; ++sit ) + { + if ( result.findIndex( *sit ) != -1 ) + result.remove( *sit ); + } + } + } + }else if( evaluateSubScopes ) + { + if( ast->nodeType() == QMake::AST::IncludeAST ) + { + QMake::IncludeAST* iast = static_cast(ast); + QValueList l = m_scopes.keys(); + for( unsigned int i = 0; i < l.count(); ++i ) + { + int num = l[ i ]; + if( m_scopes.contains( num ) ) + { + Scope* s = m_scopes[num]; + if( s && s->scopeType() == IncludeScope && s->m_incast == iast ) + { + s->calcValuesFromStatements( variable, result, false, 0, false, false, evaluateSubScopes ); + } + } + } + + } + else if( ast->nodeType() == QMake::AST::ProjectAST ) + { + QMake::ProjectAST* past = static_cast(ast); + if( past->isFunctionScope() || past->isScope() ) + { + QValueList l = m_scopes.keys(); + for( unsigned int i = 0; i < l.count(); ++i ) + { + int num = l[ i ]; + if( m_scopes.contains( num ) ) + { + Scope* s = m_scopes[num]; + if( s && s->m_root == past && s->m_root->scopedID == past->scopedID ) + { + s->calcValuesFromStatements( variable, result, false, 0, false, false, evaluateSubScopes ); + } + } + } + } + } + } + } + + result = cleanStringList( result ); + return ; +} + +Scope::ScopeType Scope::scopeType() const +{ + if ( !m_root ) + return InvalidScope; + else if ( m_incast ) + return IncludeScope; + else if ( m_root->isProject() ) + return ProjectScope; + else if ( m_root->isScope() ) + return SimpleScope; + else if ( m_root->isFunctionScope() ) + return FunctionScope; + return InvalidScope; +} + +QString Scope::scopeName() const +{ + if ( !m_root ) + return ""; + if ( m_incast ) + return "include<" + m_incast->projectName + ">"; + else if ( m_root->isFunctionScope() ) + return funcScopeKey( m_root ); + else if ( m_root->isScope() ) + return m_root->scopedID; + else if ( m_root->isProject() ) + { + if( m_parent && QDir::cleanDirPath( m_parent->projectDir() ) != QDir::cleanDirPath( projectDir() ) ) + { + return URLUtil::getRelativePath( m_parent->projectDir(), projectDir() ); + }else if ( m_parent && QDir::cleanDirPath( m_parent->projectDir() ) == QDir::cleanDirPath( projectDir() ) ) + { + return fileName(); + }else + return QFileInfo( projectDir() ).fileName() ; + } + return QString(); +} + +QString Scope::fileName() const +{ + if( !m_root ) + return ""; + if ( m_incast ) + return m_incast->projectName; + else if ( m_root->isProject() ) + return QFileInfo( m_root->fileName() ).fileName(); + else + return m_parent->fileName(); +} + +Scope* Scope::createFunctionScope( const QString& funcName, const QString& args ) +{ + if ( !m_root ) + return 0; + + QMake::ProjectAST* ast = new QMake::ProjectAST( QMake::ProjectAST::FunctionScope ); + ast->scopedID = funcName; + ast->args = args; + ast->setDepth( m_root->depth() ); + ast->addChildAST( new QMake::NewLineAST() ); + m_root->addChildAST( ast ); + m_root->addChildAST( new QMake::NewLineAST() ); + Scope* funcScope = new Scope( m_environment, getNextScopeNum(), this, ast, m_defaultopts, m_part ); + if( funcScope->scopeType() != Scope::InvalidScope ) + { + m_scopes.insert( getNextScopeNum(), funcScope ); + return funcScope; + }else + delete funcScope; + return 0; +} + +Scope* Scope::createSimpleScope( const QString& scopename ) +{ + if ( !m_root ) + return 0; + + QMake::ProjectAST* ast = new QMake::ProjectAST( QMake::ProjectAST::Scope ); + ast->scopedID = scopename; + ast->addChildAST( new QMake::NewLineAST() ); + ast->setDepth( m_root->depth() ); + m_root->addChildAST( ast ); + m_root->addChildAST( new QMake::NewLineAST() ); + /* We can't unconditionally add the scope name to CONFIG, scope might be win32 which may only be in CONFIG under windows. + if ( m_part->isQt4Project() ) + addToPlusOp( "CONFIG", QStringList( scopename ) ); + */ + Scope* simpleScope = new Scope( m_environment, getNextScopeNum(), this, ast, m_defaultopts, m_part ); + + if( simpleScope->scopeType() != Scope::InvalidScope ) + { + m_scopes.insert( getNextScopeNum(), simpleScope ); + return simpleScope; + }else + delete simpleScope; + return 0; + +} + +Scope* Scope::createIncludeScope( const QString& includeFile, bool negate ) +{ + if ( !m_root ) + return 0; + + Scope* funcScope; + if ( negate ) + { + funcScope = createFunctionScope( "!include", includeFile ); + } + else + { + funcScope = createFunctionScope( "include", includeFile ); + } + if( funcScope == 0 ) + return 0; + + QMake::IncludeAST* ast = new QMake::IncludeAST(); + ast->setDepth( m_root->depth() ); + ast->projectName = includeFile; + Scope* incScope = new Scope( m_environment, funcScope->getNextScopeNum(), funcScope, ast, projectDir(), resolveVariables( ast->projectName ), m_defaultopts, m_part ); + if ( incScope->scopeType() != InvalidScope ) + { + funcScope->m_root->addChildAST( ast ); + funcScope->m_scopes.insert( funcScope->getNextScopeNum(), incScope ); + return funcScope; + } + else + { + deleteFunctionScope( m_scopes.keys().last() ); + delete incScope; + } + return 0; + +} + +Scope* Scope::createSubProject( const QString& projname ) +{ + if( !m_root ) + return 0; + + if( variableValuesForOp( "SUBDIRS", "-=").findIndex( projname ) != -1 ) + removeFromMinusOp( "SUBDIRS", projname ); + + QString realprojname = resolveVariables(projname); + + if( variableValuesForOp( "SUBDIRS", "-=").findIndex( realprojname ) != -1 ) + removeFromMinusOp( "SUBDIRS", realprojname ); + + QDir curdir( projectDir() ); + + if ( variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 ) + { + QString filename; + if( !realprojname.endsWith(".pro") ) + { + if ( !curdir.exists( realprojname ) ) + if ( !curdir.mkdir( realprojname ) ) + return 0; + curdir.cd( realprojname ); + QStringList entries = curdir.entryList("*.pro", QDir::Files); + + if ( !entries.isEmpty() && entries.findIndex( curdir.dirName()+".pro" ) == -1 ) + filename = curdir.absPath() + QString(QChar(QDir::separator()))+entries.first(); + else + filename = curdir.absPath() + QString(QChar(QDir::separator()))+curdir.dirName()+".pro"; + }else + filename = curdir.absPath() + QString(QChar(QDir::separator())) + realprojname; + + kdDebug( 9024 ) << "Creating subproject with filename:" << filename << endl; + + Scope* s = new Scope( m_environment, getNextScopeNum(), this, filename, m_part ); + s->loadDefaultOpts(); + if ( s->scopeType() != InvalidScope ) + { + if( s->variableValues("TEMPLATE").isEmpty() ) + s->setEqualOp("TEMPLATE", QStringList("app")); + s->saveToFile(); + addToPlusOp( "SUBDIRS", QStringList( realprojname ) ); + m_scopes.insert( getNextScopeNum(), s ); + return s; + } else + { + delete s; + } + } + + return 0; +} + +bool Scope::deleteFunctionScope( unsigned int num ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + Scope* funcScope = m_scopes[ num ]; + if ( funcScope ) + { + QMake::AST* ast = m_root->m_children[ m_root->m_children.findIndex( funcScope->m_root ) ]; + if( !ast ) + return false; + m_scopes.remove( num ); + m_root->removeChildAST( funcScope->m_root ); + delete funcScope; + delete ast; + return true; + } + return false; +} + +bool Scope::deleteSimpleScope( unsigned int num ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + Scope* simpleScope = m_scopes[ num ]; + if ( simpleScope ) + { + QMake::AST* ast = m_root->m_children[ m_root->m_children.findIndex( simpleScope->m_root ) ]; + if( !ast ) + return false; + m_scopes.remove( num ); + removeFromPlusOp( "CONFIG", simpleScope->m_root->scopedID ); + m_root->removeChildAST( simpleScope->m_root ); + delete simpleScope; + delete ast; + return true; + } + return false; +} + +bool Scope::deleteIncludeScope( unsigned int num ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + Scope * incScope = m_scopes[ num ]; + if( !incScope ) + return false; + QMake::AST* ast = incScope->m_incast; + if( !ast ) + return false; + m_scopes.remove( num ); + m_root->removeChildAST( incScope->m_incast); + delete incScope; + delete ast; + + return m_parent->deleteFunctionScope( getNum() ); +} + +bool Scope::deleteSubProject( unsigned int num, bool deleteSubdir ) +{ + if ( !m_root || !m_scopes.contains( num ) ) + return false; + + QValueList::iterator it = findExistingVariable( "TEMPLATE" ); + if ( it != m_root->m_children.end() ) + { + QMake::AssignmentAST * tempast = static_cast( *it ); + if ( tempast->values.findIndex( "subdirs" ) != -1 || findExistingVariable( "TEMPLATE" ) != m_root->m_children.end() ) + { + Scope* project = m_scopes[ num ]; + if( !project ) + return false; + + QString projdir = project->scopeName(); + if ( deleteSubdir ) + { + QDir projdir = QDir( projectDir() ); + QString dir = project->scopeName(); + if( !dir.endsWith(".pro") ) + { + QDir subdir = QDir( projectDir() + QString( QChar( QDir::separator() ) ) + dir ); + if ( subdir.exists() ) + { + QStringList entries = subdir.entryList(); + for ( QStringList::iterator eit = entries.begin() ; eit != entries.end() ; ++eit ) + { + if( *eit == "." || *eit == ".." ) + continue; + if( !subdir.remove( *eit ) ) + kdDebug( 9024 ) << "Couldn't delete " << *eit << " from " << subdir.absPath() << endl; + } + if( !projdir.rmdir( dir ) ) + kdDebug( 9024 ) << "Couldn't delete " << dir << " from " << projdir.absPath() << endl; + } + }else + { + QDir d( project->projectDir() ); + kdDebug(9024) << "removed subproject?:" << d.remove( dir ) << endl; + } + } + QValueList::iterator foundit = findExistingVariable( "SUBDIRS" ); + if ( foundit != m_root->m_children.end() ) + { + QMake::AssignmentAST * ast = static_cast( *foundit ); + updateValues( ast->values, QStringList( projdir ), true, ast->indent ); + if( m_varCache.contains( "SUBDIRS" ) ) + m_varCache.erase( "SUBDIRS" ); + }else + return false; + m_scopes.remove( num ); + delete project; + return true; + } + } + return false; +} + +void Scope::updateValues( QStringList& origValues, const QStringList& newValues, bool remove, QString indent ) +{ + if( !m_root ) + return; + + for ( QStringList::const_iterator it = newValues.begin(); it != newValues.end() ; ++it ) + { + if ( origValues.findIndex( *it ) == -1 && !remove ) + { + while ( !origValues.isEmpty() && origValues.last() == getLineEndingString() ) + origValues.pop_back(); + if ( origValues.count() > 0 && !containsContinue( origValues.last() ) && !isComment( origValues.last() ) ) + { + origValues.append( " " ); + origValues.append( "\\"+getLineEndingString() ); + if( indent != "" ) + origValues.append( indent ); + }else if ( !origValues.isEmpty() && containsContinue( origValues.last() ) && !isComment( origValues.last() ) ) + { + if( indent != "" ) + origValues.append( indent ); + }else if ( !origValues.isEmpty() && isComment( origValues.last() ) ) + { + origValues[origValues.count()-1] = "\\ "+origValues[origValues.count()-1]; + if( indent != "" ) + origValues.append( indent ); + }else if ( origValues.isEmpty() ) + origValues.append(" "); + QString newval = *it; + QRegExp re("([^$])\\$([^$\\(\\)\\{\\} /]*)( |\\)|/)"); + newval.replace(re, "\\1$(\\2)\\3"); + if( (newval).contains(" ") || (newval).contains("\t") || (newval).contains( getLineEndingString() ) || (newval).contains("#") ) + origValues.append( "\""+newval+"\"" ); + else + origValues.append( newval ); + origValues.append( getLineEndingString() ); + } else if ( origValues.findIndex( *it ) != -1 && remove ) + { + QStringList::iterator posit = origValues.find( *it ); + posit = origValues.remove( posit ); + while( posit != origValues.end() && ( (*posit).find( QRegExp("\\\\[\\s]*"+getLineEndingString() ) ) != -1 + || (*posit).stripWhiteSpace() == "" ) ) + { + posit = origValues.remove( posit ); + } + } + } + while( !origValues.isEmpty() && (origValues.last() == "\\"+getLineEndingString() + || origValues.last() == getLineEndingString() + || origValues.last().stripWhiteSpace() == "" ) && !origValues.isEmpty() ) + origValues.pop_back(); + if( !origValues.isEmpty() && origValues.last().find( QRegExp("\\\\[ \t]*#") ) != -1 ) + origValues[origValues.count()-1] = origValues[origValues.count()-1].mid(origValues[origValues.count()-1].find( "#") ); + if( !origValues.isEmpty() && origValues.last().find( getLineEndingString() ) == -1 ) + origValues.append(getLineEndingString()); +} + +void Scope::updateVariable( const QString& variable, const QString& op, const QStringList& values, bool removeFromOp ) +{ + if ( !m_root || listIsEmpty( values ) ) + return ; + + if( m_varCache.contains( variable ) ) + m_varCache.erase( variable ); + + for ( int i = m_root->m_children.count() - 1; i >= 0; --i ) + { + if ( m_root->m_children[ i ] ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assignment = static_cast( m_root->m_children[ i ] ); + if ( assignment->scopedID == variable && Scope::isCompatible( assignment->op, op ) ) + { + updateValues( assignment->values, values, removeFromOp, assignment->indent ); + if ( removeFromOp && listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + } + return ; + } + else if ( assignment->scopedID == variable && !Scope::isCompatible( assignment->op, op ) ) + { + for ( QStringList::const_iterator it = values.begin() ; it != values.end() ; ++it ) + { + if ( op == "+=" && !removeFromOp && assignment->values.findIndex( *it ) != -1 ) + { + if ( assignment->op == "=" ) + { + updateValues( assignment->values, values, false, assignment->indent ); + return ; + } + else if ( assignment->op == "-=" ) + { + updateValues( assignment->values, QStringList( *it ), true, assignment->indent ); + if ( listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + break; + } + } + } + else if ( op == "-=" && !removeFromOp && assignment->values.findIndex( *it ) != -1 ) + { + updateValues( assignment->values, QStringList( *it ), true, assignment->indent ); + if ( listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + break; + } + } + else if ( op == "=" ) + { + if ( !removeFromOp ) + { + m_root->removeChildAST( assignment ); + delete assignment; + } + else if ( assignment->op == "+=" && assignment->values.findIndex( *it ) != -1 ) + { + updateValues( assignment->values, QStringList( *it ), true, assignment->indent ); + if ( listIsEmpty( assignment->values ) ) + { + m_root->removeChildAST( assignment ); + delete assignment; + break; + } + } + } + } + } + } + } + + if ( !removeFromOp ) + { + QMake::AssignmentAST * ast = new QMake::AssignmentAST(); + ast->scopedID = variable; + ast->op = op; + updateValues( ast->values, values ); + if( scopeType() == ProjectScope ) + ast->setDepth( m_root->depth() ); + else + ast->setDepth( m_root->depth()+1 ); + m_root->addChildAST( ast ); + if ( values.findIndex( getLineEndingString() ) == -1 ) + { + ast->values.append( getLineEndingString() ); + } + } +} + +QValueList::iterator Scope::findExistingVariable( const QString& variable ) +{ + QValueList::iterator it; + QStringList ops; + ops << "=" << "+="; + + for ( it = m_root->m_children.begin(); it != m_root->m_children.end() ; ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * assignment = static_cast( *it ); + if ( assignment->scopedID == variable && ops.findIndex( assignment->op ) != -1 ) + { + return it; + } + } + } + return m_root->m_children.end(); +} + +void Scope::init() +{ + if( !m_root ) + return; + + kdDebug(9024) << "Initializing Scope: " << scopeName() << this << endl; + m_maxCustomVarNum = 1; + + QValueList::const_iterator it; + for ( it = m_root->m_children.begin(); it != m_root->m_children.end(); ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::ProjectAST ) + { + QMake::ProjectAST * p = static_cast( *it ); + m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, p, m_defaultopts, m_part ) ); + } + else if ( ( *it ) ->nodeType() == QMake::AST::IncludeAST ) + { + QMake::IncludeAST * i = static_cast( *it ); + QString filename = i->projectName; + if( i->projectName.stripWhiteSpace().startsWith("$") ) + { + filename = resolveVariables(i->projectName, *it); + } + m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, i, projectDir(), filename, m_defaultopts, m_part ) ); + } + else if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * m = static_cast( *it ); + // Check wether TEMPLATE==subdirs here too! + if ( m->scopedID == "SUBDIRS" && variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + { + for ( QStringList::const_iterator sit = m->values.begin() ; sit != m->values.end(); ++sit ) + { + QString str = *sit; + if ( containsContinue( str ) || isComment( str ) || str == getLineEndingString() || str == "." || str == "./" || (str).stripWhiteSpace() == "" ) + continue; + QDir subproject; + QString projectfile; + kdDebug(9024) << "reading subproject: " << str << endl; + if( str.startsWith("$") ) + str = resolveVariables(str, *it); + if( str.endsWith(".pro") ) + { + subproject = QDir( projectDir(), "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files ); + projectfile = str; + }else + { + QString dir = str; + if( QFileInfo( dir ).isRelative() ) + dir = projectDir() + QString( QChar( QDir::separator() ) ) + dir; + subproject = QDir( dir, + "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files ); + if( !subproject.exists() ) + { + kdDebug(9024) << "Project Dir doesn't exist, trying to find name.subdir variable:" << str << endl; + if( !variableValues(str+".subdir").isEmpty() ) + { + kdDebug(9024) << "Found name.subdir variable for " << str << endl; + subproject = QDir( projectDir() + QString( QChar( QDir::separator() ) ) + + variableValues(str+".subdir").first(), + "*.pro", QDir::Name | QDir::IgnoreCase, QDir::Files ); + }else + continue; + } + if ( subproject.entryList().isEmpty() || subproject.entryList().findIndex( str + ".pro" ) != -1 ) + projectfile = (str) + ".pro"; + else + projectfile = subproject.entryList().first(); + + } + kdDebug( 9024 ) << "Parsing subproject: " << projectfile << endl; + m_scopes.insert( getNextScopeNum(), new Scope( m_environment, getNextScopeNum(), this, + subproject.absFilePath( projectfile ), + m_part, ( m->op != "-=" )) ); + } + } + else + { + if ( !( + KnownVariables.findIndex( m->scopedID ) != -1 + && ( m->op == "=" || m->op == "+=" || m->op == "-=") + ) + && !( + ( m->scopedID.contains( ".files" ) || m->scopedID.contains( ".path" ) ) + && variableValues("INSTALLS").findIndex(m->scopedID.left( m->scopedID.findRev(".") != -1 ) ) + ) + && !( + ( m->scopedID.contains( ".subdir" ) ) + && variableValues("SUBDIRS").findIndex(m->scopedID.left( m->scopedID.findRev(".") != -1 ) ) + ) + ) + { + m_customVariables[ m_maxCustomVarNum++ ] = m; + } + } + } + } +} + +QString Scope::projectName() const +{ + if( !m_root ) + return ""; + + return QFileInfo( projectDir() ).fileName(); +} + +QString Scope::projectDir() const +{ + if( !m_root ) + return ""; + if ( m_root->isProject() ) + { + return QFileInfo( m_root->fileName() ).dirPath( true ); + } + else + { + return m_parent->projectDir(); + } +} + +const QMap > Scope::customVariables() const +{ + QMap > result; + if( !m_root ) + return result; + + QMap::const_iterator it = m_customVariables.begin(); + for ( ; it != m_customVariables.end(); ++it ) + { + QMap temp; + temp[ "var" ] = it.data()->scopedID; + temp[ "op" ] = it.data()->op; + temp[ "values" ] = it.data()->values.join("").stripWhiteSpace(); + result[ it.key() ] = temp; + } + return result; +} + +void Scope::updateCustomVariable( unsigned int id, const QString& name, const QString& newop, const QString& newvalues ) +{ + if( !m_root ) + return; + if ( id > 0 && m_customVariables.contains( id ) ) + { + m_customVariables[ id ] ->values.clear(); + updateValues( m_customVariables[ id ] ->values, newvalues.stripWhiteSpace() ); + if( m_varCache.contains( m_customVariables[ id ]->scopedID ) ) + m_varCache.erase( m_customVariables[ id ]->scopedID ); + m_customVariables[ id ] ->op = newop; + m_customVariables[ id ] ->scopedID = name; + } +} + +unsigned int Scope::addCustomVariable( const QString& var, const QString& op, const QString& values ) +{ + QMake::AssignmentAST* newast = new QMake::AssignmentAST(); + newast->scopedID = var; + newast->op = op; + newast->values.append(values.stripWhiteSpace()); + if( scopeType() == ProjectScope ) + newast->setDepth( m_root->depth() ); + else + newast->setDepth( m_root->depth()+1 ); + m_root->addChildAST( newast ); + m_customVariables[ m_maxCustomVarNum++ ] = newast; + return (m_maxCustomVarNum-1); +} + +void Scope::removeCustomVariable( unsigned int id ) +{ + if( m_customVariables.contains(id) ) + { + QMake::AssignmentAST* m = m_customVariables[id]; + m_customVariables.remove(id); + m_root->m_children.remove( m ); + } +} + +bool Scope::isVariableReset( const QString& var ) +{ + bool result = false; + if( !m_root ) + return result; + QValueList::const_iterator it = m_root->m_children.begin(); + for ( ; it != m_root->m_children.end(); ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + QMake::AssignmentAST * ast = static_cast( *it ); + if ( ast->scopedID == var && ast->op == "=" ) + { + result = true; + break; + } + } + } + return result; +} + +void Scope::removeVariable( const QString& var, const QString& op ) +{ + if ( !m_root ) + return ; + + QMake::AssignmentAST* ast = 0; + + QValueList::iterator it = m_root->m_children.begin(); + for ( ; it != m_root->m_children.end(); ++it ) + { + if ( ( *it ) ->nodeType() == QMake::AST::AssignmentAST ) + { + ast = static_cast( *it ); + if ( ast->scopedID == var && ast->op == op ) + { + m_root->m_children.remove( ast ); + it = m_root->m_children.begin(); + } + } + } +} + +bool Scope::listIsEmpty( const QStringList& values ) +{ + if ( values.size() < 1 ) + return true; + for ( QStringList::const_iterator it = values.begin(); it != values.end(); ++it ) + { + if ( ( *it ).stripWhiteSpace() != "" && ( *it ).stripWhiteSpace() != "\\" ) + return false; + } + return true; +} + +bool Scope::isCompatible( const QString& op1, const QString& op2) +{ + if( op1 == "+=" ) + return ( op2 == "+=" || op2 == "=" ); + else if ( op1 == "-=" ) + return ( op2 == "-=" ); + else if ( op1 == "=" ) + return ( op2 == "=" || op2 == "+=" ); + return false; +} + +bool Scope::listsEqual(const QStringList& l1, const QStringList& l2) +{ + QStringList left = l1; + QStringList right = l2; +// left.sort(); +// right.sort(); + return (left == right); +} + +QStringList Scope::cleanStringList(const QStringList& list) const +{ + QStringList result; + for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it ) + { + QString s = *it; + if( s.stripWhiteSpace() != "" + && !containsContinue(s) + && s.stripWhiteSpace() != getLineEndingString() + && !isComment(s) ) + result.append(s); + } + return result; +} + +bool Scope::isQt4Project() const +{ + return m_part->isQt4Project(); +} + +void Scope::reloadProject() +{ + if ( !m_root || !m_root->isProject() ) + return; + + QString filename = m_root->fileName(); + QMap::iterator it; + for ( it = m_scopes.begin() ; it != m_scopes.end() ; ++it ) + { + Scope* s = it.data(); + delete s; + } + m_scopes.clear(); + + m_customVariables.clear(); + + m_varCache.clear(); + + if ( m_root->isProject() ) + delete m_root; + if ( !loadFromFile( filename ) && !QFileInfo( filename ).exists() ) + { + m_root = new QMake::ProjectAST(); + m_root->setFileName( filename ); + } + init(); +} + +Scope* Scope::disableSubproject( const QString& dir) +{ + if( !m_root || ( m_root->isProject() && !m_incast ) ) + return 0; + + if( scopeType() != Scope::IncludeScope && variableValuesForOp( "SUBDIRS", "+=").findIndex( dir ) != -1 ) + removeFromPlusOp( "SUBDIRS", dir ); + else if( scopeType() != Scope::IncludeScope ) + removeFromPlusOp( "SUBDIRS", dir ); + + QDir curdir( projectDir() ); + + if ( variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 ) + { + curdir.cd(dir); + QString filename; + QStringList entries = curdir.entryList("*.pro", QDir::Files); + + if ( !entries.isEmpty() && entries.findIndex( curdir.dirName()+".pro" ) != -1 ) + filename = curdir.absPath() + QString(QChar(QDir::separator()))+entries.first(); + else + filename = curdir.absPath() + QString(QChar(QDir::separator()))+curdir.dirName()+".pro"; + + kdDebug( 9024 ) << "Disabling subproject with filename:" << filename << endl; + + Scope* s = new Scope( m_environment, getNextScopeNum(), this, filename, m_part, false ); + addToMinusOp( "SUBDIRS", QStringList( dir ) ); + m_scopes.insert( getNextScopeNum(), s ); + return s; + } + + return 0; +} + +QString Scope::resolveVariables( const QString& value ) const +{ + return resolveVariables(QStringList(value), 0).front(); +} + + +QString Scope::resolveVariables( const QString& value, QMake::AST* stopHere ) const +{ + return resolveVariables(QStringList(value), stopHere).front(); +} + +QStringList Scope::variableValues( const QString& variable, QMake::AST* stopHere, bool fetchFromParent ) const +{ + QStringList result; + + if ( !m_root ) + return result; + + calcValuesFromStatements( variable, result, true, stopHere, fetchFromParent ); + result = cleanStringList(result); + return result; +} + +QStringList Scope::resolveVariables( const QStringList& values, QMake::AST* stopHere ) const +{ + QStringList result = values; + QMap variables; + for( QStringList::iterator it = result.begin(); it != result.end(); ++it ) + { + QRegExp re("\\$\\$([^{}\\) /]*)( |\\)|/|$)"); + int pos = 0; + while( pos >= 0 ) + { + pos = re.search( (*it), pos ); + if( pos > -1 ) + { + if( !variables.contains( re.cap(1) ) ) + { + variables[re.cap(1)] = resolveVariables( variableValues( re.cap(1), stopHere ) ); + if( variables[re.cap(1)].isEmpty() && re.cap(1) == "TARGET" ) + { + variables[re.cap(1)] = QFileInfo( fileName() ).baseName(); + } + } + pos += re.matchedLength(); + } + } + re = QRegExp("\\$\\$\\{([^\\)\\}]*)\\}"); + pos = 0; + while( pos >= 0 ) + { + pos = re.search( (*it), pos ); + if( pos > -1 ) + { + if( !variables.contains( re.cap(1) ) ) + { + variables[re.cap(1)] = resolveVariables( variableValues( re.cap(1), stopHere ) ); + if( variables[re.cap(1)].isEmpty() && re.cap(1) == "TARGET" ) + { + variables[re.cap(1)] = QFileInfo( fileName() ).baseName(); + } + } + pos += re.matchedLength(); + } + } + re = QRegExp("\\$\\$\\(([^\\)\\}]*)\\)"); + pos = 0; + QMap envvars; + while( pos >= 0 ) + { + pos = re.search( (*it), pos ); + if( pos > -1 ) + { + if( !envvars.contains( re.cap(1) ) ) + if( m_environment.contains( re.cap(1) ) != -1 ) + envvars[re.cap(1)] = m_environment[ re.cap(1) ]; + else if ( ::getenv( re.cap(1).local8Bit() ) != 0 ) + envvars[re.cap(1)] = QString::fromLocal8Bit( ::getenv( re.cap(1).local8Bit() ) ); + pos += re.matchedLength(); + } + } + for( QMap::const_iterator it2 = envvars.begin(); it2 != envvars.end(); ++it2 ) + { + (*it).replace("$$("+it2.key()+")", it2.data() ); + } + for( QMap::const_iterator it2 = variables.begin(); it2 != variables.end(); ++it2 ) + { + for( QStringList::const_iterator it3 = it2.data().begin(); it3 != it2.data().end(); ++it3 ) + { + (*it).replace("$$"+it2.key(), *it3 ); + (*it).replace("$${"+it2.key()+"}", *it3 ); + } + } + } + return result; +} + +void Scope::allFiles( const QString& projectDirectory, std::set& res ) +{ + + QString myRelPath = URLUtil::getRelativePath( projectDirectory, projectDir() ); + QString file; + QStringList values; + QString header = ""; + if( variableValues("TEMPLATE",false ).findIndex("subdirs") == -1 ) + { + values = variableValues( "INSTALLS" ,false, false ); + QStringList::const_iterator it; + for ( it = values.begin(); it != values.end(); ++it ) + { + if ( ( *it ) == "target" ) + continue; + + QStringList files = variableValues( *it + ".files" ,false, false ); + QStringList::iterator filesit = files.begin(); + for ( ;filesit != files.end(); ++filesit ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *filesit; + file = resolveVariables( file ); + if( file.contains("*") ) + { + QFileInfo fi( projectDirectory + QString( QChar( QDir::separator() ) ) + file ); + QDir absDir = fi.dir( true ); + absDir.setNameFilter( fi.fileName() ); + absDir.setFilter( QDir::Files | QDir::Readable | QDir::NoSymLinks ); + QStringList list = absDir.entryList(); + for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it ) + { + res.insert( QDir::cleanDirPath( URLUtil::getRelativePath( projectDirectory, absDir.path()+QString( QChar( QDir::separator() ) )+*it ) ) ); + } + } + else + { + res.insert( QDir::cleanDirPath( file ) ); + } + } + } + + values = variableValues( "LEXSOURCES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "YACCSOURCES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "DISTFILES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + if( file.contains("*") ) + { + QFileInfo fi( projectDirectory + QString( QChar( QDir::separator() ) ) + file ); + QDir absDir = fi.dir( true ); + absDir.setNameFilter( fi.fileName() ); + absDir.setFilter( QDir::Files | QDir::Readable | QDir::NoSymLinks ); + QStringList list = absDir.entryList(); + for( QStringList::const_iterator it = list.begin(); it != list.end(); ++it ) + { + res.insert( QDir::cleanDirPath( URLUtil::getRelativePath( projectDirectory, absDir.path()+QString( QChar( QDir::separator() ) )+*it ) ) ); + } + } + else + { + res.insert( QDir::cleanDirPath( file ) ); + } + } + + if ( isQt4Project() ) + { + values = variableValues( "RESOURCES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + } + values = variableValues( "IMAGES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "TRANSLATIONS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "IDLS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + if ( m_part->isTMakeProject() ) + { + values = variableValues( "INTERFACES" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + if( QFileInfo(projectDir()+QString(QChar(QDir::separator())) + *it+".h").exists() ) + res.insert( QDir::cleanDirPath( file+".h" ) ); + } + } + else + { + values = variableValues( "FORMS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + + if( !m_part->isQt4Project()) + { + header = projectDir()+QString(QChar(QDir::separator())) + *it+".h"; + if( QFileInfo(header).exists() ) + res.insert( QDir::cleanDirPath( header ) ); + header = projectDir()+QString(QChar(QDir::separator())) + *it+".cpp"; + if( QFileInfo(header).exists() ) + res.insert( QDir::cleanDirPath( header ) ); + } + else + { + header = projectDir()+QString(QChar(QDir::separator())) + "ui_" +*it; + header.replace(QRegExp("\\.ui$"),".h"); + if( QFileInfo(header).exists() ) + res.insert( QDir::cleanDirPath( header ) ); + } + } + } + + values = variableValues( "SOURCES" ,false, false ); + kdDebug(9024) << "scope:" << scopeType() << " found values: " << values << endl; + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + + values = variableValues( "HEADERS" ,false, false ); + for ( it = values.begin(); it != values.end(); ++it ) + { + file = myRelPath + QString(QChar(QDir::separator())) + *it; + file = resolveVariables( file ); + res.insert( QDir::cleanDirPath( file ) ); + } + } + QMap::const_iterator it = m_scopes.begin(); + for( ; it != m_scopes.end(); ++it ) + { + it.data()->allFiles( projectDirectory, res ); + } +} + +QStringList Scope::allFiles( const QString& projectDir ) +{ + QStringList result; + std::set files; + allFiles( projectDir, files ); + for( std::set::const_iterator it = files.begin(); it != files.end() ; ++it ) + result.append( *it ); + kdDebug(9024) << "all files: " << result << endl; + return result; +} + +QString Scope::findCustomVarForPath( const QString& path ) +{ + QString result; + if( !m_root ) + return result; + + QMap::const_iterator it = m_customVariables.begin(); + for( ; it != m_customVariables.end(); ++it ) + { + kdDebug(9024) << "Checking " << path << " against " << cleanStringList(it.data()->values) << endl; + if( !it.data()->values.isEmpty() && cleanStringList(it.data()->values).front() == path ) + { + return it.data()->scopedID; + } + } + if( scopeType() != ProjectScope ) + { + return parent()->findCustomVarForPath( path ); + } + return result; +} + +void Scope::loadDefaultOpts() +{ + if( !m_defaultopts && m_root ) + { + m_defaultopts = new QMakeDefaultOpts(); + if( DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/disableDefaultOpts", true ) ) + { + m_defaultopts->readVariables( m_part->qmakePath(), QFileInfo( m_root->fileName() ).dirPath( true ) ); + } + } +} + +QString Scope::getLineEndingString() const +{ + + if( scopeType() == ProjectScope ) + { + switch( m_root->lineEnding() ) + { + case QMake::ProjectAST::Windows: + return QString("\r\n"); + break; + case QMake::ProjectAST::MacOS: + return QString("\r"); + break; + case QMake::ProjectAST::Unix: + return QString("\n"); + break; + } + }else if( m_parent ) + { + return m_parent->getLineEndingString(); + } + return "\n"; +} + +QString Scope::replaceWs(QString s) +{ + return s.replace( getLineEndingString(), "%nl").replace("\t", "%tab").replace(" ", "%spc"); +} + +bool Scope::containsContinue(const QString& s ) const +{ + return( s.find( QRegExp( "\\\\\\s*"+getLineEndingString() ) ) != -1 + || s.find( QRegExp( "\\\\\\s*#" ) ) != -1 ); +} + +bool Scope::isComment( const QString& s) const +{ + return s.startsWith("#"); +} + +#ifdef DEBUG +void Scope::printTree() +{ + PrintAST p; + p.processProject(m_root); +} + +Scope::PrintAST::PrintAST() : QMake::ASTVisitor() +{ + indent = 0; +} + +void Scope::PrintAST::processProject( QMake::ProjectAST* p ) +{ + QMake::ASTVisitor::processProject(p); +} + +void Scope::PrintAST::enterRealProject( QMake::ProjectAST* p ) +{ + kdDebug(9024) << getIndent() << "--------- Entering Project: " << replaceWs(p->fileName()) << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterRealProject(p); +} + +void Scope::PrintAST::leaveRealProject( QMake::ProjectAST* p ) +{ + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Project: " << replaceWs(p->fileName()) << " --------------" << endl; + QMake::ASTVisitor::leaveRealProject(p); +} + +void Scope::PrintAST::enterScope( QMake::ProjectAST* p ) +{ + kdDebug(9024) << getIndent() << "--------- Entering Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterScope(p); +} + +void Scope::PrintAST::leaveScope( QMake::ProjectAST* p ) +{ + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving Scope: " << replaceWs(p->scopedID) << " --------------" << endl; + QMake::ASTVisitor::leaveScope(p); +} + +void Scope::PrintAST::enterFunctionScope( QMake::ProjectAST* p ) +{ + kdDebug(9024) << getIndent() << "--------- Entering FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + indent += 4; + QMake::ASTVisitor::enterFunctionScope(p); +} + +void Scope::PrintAST::leaveFunctionScope( QMake::ProjectAST* p ) +{ + indent -= 4; + kdDebug(9024) << getIndent() << "--------- Leaving FunctionScope: " << replaceWs(p->scopedID) << "(" << replaceWs(p->args) << ")"<< " --------------" << endl; + QMake::ASTVisitor::leaveFunctionScope(p); +} + +QString Scope::PrintAST::replaceWs(QString s) +{ + return s.replace("\n", "%nl").replace("\t", "%tab").replace(" ", "%spc"); +} + +void Scope::PrintAST::processAssignment( QMake::AssignmentAST* a) +{ + kdDebug(9024) << getIndent() << "Assignment: " << replaceWs(a->scopedID) << " " << replaceWs(a->op) << " " + << replaceWs(a->values.join("|"))<< endl; + QMake::ASTVisitor::processAssignment(a); +} + +void Scope::PrintAST::processNewLine( QMake::NewLineAST* n) +{ + kdDebug(9024) << getIndent() << "Newline " << endl; + QMake::ASTVisitor::processNewLine(n); +} + +void Scope::PrintAST::processComment( QMake::CommentAST* a) +{ + kdDebug(9024) << getIndent() << "Comment: " << replaceWs(a->comment) << endl; + QMake::ASTVisitor::processComment(a); +} + +void Scope::PrintAST::processInclude( QMake::IncludeAST* a) +{ + kdDebug(9024) << getIndent() << "Include: " << replaceWs(a->projectName) << endl; + QMake::ASTVisitor::processInclude(a); +} + +QString Scope::PrintAST::getIndent() +{ + QString ind; + for( int i = 0 ; i < indent ; i++) + ind += " "; + return ind; +} +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/qmake/scope.h b/buildtools/qmake/scope.h new file mode 100644 index 00000000..e8f40eb9 --- /dev/null +++ b/buildtools/qmake/scope.h @@ -0,0 +1,308 @@ +/*************************************************************************** +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _SCOPE_H_ +#define _SCOPE_H_ + +#include +#include +#include +#include + +#include "qmakeast.h" +#include "qmakedefaultopts.h" + +#ifdef DEBUG +#include "qmakeastvisitor.h" +#endif + +class Scope; +class TrollProjectPart; + +class Scope +{ +public: + + enum ScopeType { + ProjectScope, + FunctionScope, + SimpleScope, + IncludeScope, + InvalidScope + }; + static const QStringList KnownVariables; + static const QStringList KnownConfigValues; + + Scope( const QMap& env, const QString &filename, TrollProjectPart* part ); + ~Scope(); + + void saveToFile() const; + + // Changing variable values + void addToPlusOp( const QString& variable, const QStringList& values ); + void removeFromPlusOp( const QString& variable, const QStringList& values ); + void addToMinusOp( const QString& variable, const QStringList& values ); + void removeFromMinusOp( const QString& variable, const QStringList& values ); + void addToEqualOp( const QString& variable, const QStringList& values ); + void removeFromEqualOp( const QString& variable, const QStringList& values ); + void setPlusOp( const QString& variable, const QStringList& values ); + void setEqualOp( const QString& variable, const QStringList& values ); + void setMinusOp( const QString& variable, const QStringList& values ); + + // Checks wether a line like VAR = exists in this subscope + bool isVariableReset( const QString& var ); + + // Fetch the valuelist for the variable op combination inside this scope + QStringList variableValuesForOp( const QString& variable, const QString& op ) const; + + // Fetch the variable values by running over the statements and adding/removing/setting + // as the encountered op's say, begin with the parent projects variableValues list + QStringList variableValues( const QString& variable, bool checkIncParent = true, bool fetchFromParent = true, bool evaluateSubScopes = false ); + + // Remove a variable+Op combination from the scope, if existant + void removeVariable( const QString& var, const QString& op ); + + // Getting to know what type of scope this is + ScopeType scopeType() const; + + // This returns the function+args, the scopename or the pro/pri file + // depending on the type of scope + QString scopeName() const; + + // Returns the projectName for this scope, this is equal to the last part of the projectDir() + QString projectName() const; + + // Returns just the filename of this project's .pro file + QString fileName() const; + + // Returns the absolute path of the dir containing the .pro file + QString projectDir() const; + + // get the parent Scope + Scope* parent() const { return m_parent; } + + // Fetching sub-scopes + const QValueList scopesInOrder() const { return m_scopes.values(); } + // Working on SubScopes + /* + * creates a new function scope at the end of this (Sub-)AST and returns the Scope wrapping it + */ + Scope* createFunctionScope( const QString& funcName, const QString& args ); + /* + * creates a new simple scope at the end of this (Sub-)AST and returns the Scope wrapping it + */ + Scope* createSimpleScope( const QString& scopename ); + + /* + * creates a new function scope at the end of this (Sub-)AST + * and a new include scope inside the new function scope. + * It returns the Scope wrapping the include-AST, the function scope AST + * can be accessed easily using the parent() method. + */ + Scope* createIncludeScope( const QString& includeFile, bool negate = false ); + + /* + * creates a new subproject in dir (create's dir if necessary) + * If this scope is not a project scope the subproject will be added to this + * Scope only, i.e. it is not seen in the project-files list of subdirs + */ + Scope* createSubProject( const QString& dir ); + + /* delete the given function scope */ + bool deleteFunctionScope( unsigned int ); + /* delete the given simple scope */ + bool deleteSimpleScope( unsigned int ); + /* delete the given include scope */ + bool deleteIncludeScope( unsigned int ); + /* deletes the subproject (including the subdir if deleteSubdir is true) */ + bool deleteSubProject( unsigned int, bool deleteSubdir ); + + /* find out wether the project is Qt4 or Qt3 */ + bool isQt4Project() const ; + + /* Provide a Map of Custom variables */ + const QMap > customVariables() const; + + unsigned int addCustomVariable( const QString& var, const QString& op, const QString& values ); + + /* Removes the variable with the given id if it exists */ + void removeCustomVariable( unsigned int ); + + /* Update the values of the variable/operation combo var+op to values */ + void updateCustomVariable( unsigned int, const QString&, const QString& , const QString& ); + + // Checks wether a QStringList contains any values that are not whitespace or \\n + static bool listIsEmpty( const QStringList& values ); + + /* returns wether this is an enabled subproject or a disabled one */ + bool isEnabled() { return m_isEnabled; } + + QStringList cleanStringList(const QStringList& list) const; + + /* Reload a project scope */ + void reloadProject(); + + /* creates a new disabled Scope child and add SUBDIRS -= dir to this scope */ + Scope* disableSubproject( const QString& ); + + /* return the "position" of this scope in the list of scopes */ + unsigned int getNum() { return m_num; } + + QStringList allFiles( const QString& ); + + QString resolveVariables( const QString& ) const; + + QString findCustomVarForPath( const QString& ); + +#ifdef DEBUG + void printTree(); +#endif + +private: + + // Builds the scope-lists and the customVariables list + void init(); + + /* + * Updates the given Variable+op with the values, if removeFromOp is true it removes the values, else it adds them + * this works it's way back through the current scope and changes the last occurence of op to + * include all new values. + * + * Depending on "op" it might end the search earlier (if op is += it also stops at =) + * + * This also removes the values from other assignments if the operation is not op, i.e. + * if op is += removes values from any occurence of -= + * if op is -= removes values from any occurence of = and += + * if op is = removes values frmo any occurence of -= + */ + void updateVariable( const QString& variable, const QString& op, const QStringList& values, bool removeFromOp ); + + /* + * Helper Function to change the origValues list with the values from newValues + * depending on the state of "remove" either adds or removes all entries from newValues + * to origValues if they didn't exist there yet + */ + void updateValues( QStringList& origValues, const QStringList& newValues, bool remove = false, QString indent = " " ); + + /* + * Finds an existing variable, returns the end() of the statemenst if it is not found + */ + QValueList::iterator findExistingVariable( const QString& variable ); + + // Private constructors for easier subscope creation + /* + * just initializes the lists from the scope + */ + Scope( const QMap& env, unsigned int num, Scope* parent, QMake::ProjectAST* root, QMakeDefaultOpts*, TrollProjectPart* part ); + /* + * reads the given filename and parses it. If it doesn't exist creates an empty + * ProjectAST with the given filename + */ + Scope( const QMap& env, unsigned int num, Scope* parent, const QString& filename, TrollProjectPart* part, bool isEnabled = true ); + /* + * Creates a scope for an include statement, parses the file and initializes the Scope + * Create an empty ProjectAST if the file cannot be found or parsed. + */ + Scope( const QMap& env, unsigned int num, Scope* parent, QMake::IncludeAST* incast, const QString& path, const QString& incfile, QMakeDefaultOpts*, TrollProjectPart* part ); + + + // runs through the statements until stopHere is found (or the end is reached, if stopHere is 0), + // using the given list as startvalue + // Changes the list using the +=, -=, = operations accordingly + void calcValuesFromStatements( const QString& variable, QStringList& result, bool, QMake::AST* stopHere = 0, bool fetchFromParent = true, bool setDefault = true, bool evaluateSubScopes = false ) const; + + // Check wether the two operators are compatible + static bool isCompatible( const QString& op1, const QString& op2); + + // Check wether the 2 lists are equal, regardless of element order. + static bool listsEqual(const QStringList& , const QStringList& ); + + // Load and Save project files, these only work on ProjectScope's + bool loadFromFile( const QString& filename ); + + QString funcScopeKey( QMake::ProjectAST* funcast ) const { return funcast->scopedID + "(" + funcast->args + ")"; } + + unsigned int getNextScopeNum() { if( m_scopes.isEmpty() ) return 0; else return (m_scopes.keys().last()+1); } + + QStringList lookupVariable( const QString& var ); + + QStringList resolveVariables( const QStringList&, QMake::AST* = 0 ) const; + QStringList variableValues( const QString& variable, QMake::AST*, bool fetchFromParent = true ) const; + QString resolveVariables( const QString& , QMake::AST* ) const; + + // This function determines the currently used String for fileending, it can be \n, \r or \r\n + QString getLineEndingString() const; + bool isComment( const QString& ) const; + bool containsContinue( const QString& ) const; + void allFiles( const QString&, std::set& ); + + void loadDefaultOpts(); + + QMake::ProjectAST* m_root; + QMake::IncludeAST* m_incast; + QMap m_customVariables; + QMap m_scopes; + Scope* m_parent; + unsigned int m_maxCustomVarNum; + + QString replaceWs(QString); + + + // The "position" inside the parent scope that this scope starts at + unsigned int m_num; + bool m_isEnabled; + TrollProjectPart* m_part; + QMakeDefaultOpts* m_defaultopts; + QMap m_varCache; + QMap m_environment; + +#ifdef DEBUG + class PrintAST : QMake::ASTVisitor + { + + public: + PrintAST(); + virtual void processProject( QMake::ProjectAST* p ); + virtual void enterRealProject( QMake::ProjectAST* p ); + + virtual void leaveRealProject( QMake::ProjectAST* p ); + + virtual void enterScope( QMake::ProjectAST* p ); + + virtual void leaveScope( QMake::ProjectAST* p ); + + virtual void enterFunctionScope( QMake::ProjectAST* p ); + + virtual void leaveFunctionScope( QMake::ProjectAST* p ); + + virtual void processAssignment( QMake::AssignmentAST* a); + + virtual void processNewLine( QMake::NewLineAST* n); + + virtual void processComment( QMake::CommentAST* a); + + virtual void processInclude( QMake::IncludeAST* a); + + QString replaceWs(QString); + + private: + QString getIndent(); + int indent; + + }; +#endif + +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/trolllistview.cpp b/buildtools/qmake/trolllistview.cpp new file mode 100644 index 00000000..531bb3e8 --- /dev/null +++ b/buildtools/qmake/trolllistview.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "trolllistview.h" + + +TrollListView::TrollListView(TrollProjectWidget *widget, QWidget *parent, + TrollProjectWidget::TrollProjectView view, const char *name) + :KListView(parent, name), m_widget(widget), m_view(view) +{ +} + +TrollListView::~TrollListView() +{ +} + +void TrollListView::focusOutEvent( QFocusEvent */* e*/ ) +{ + m_widget->setLastFocusedView(m_view); +} + +#include "trolllistview.moc" diff --git a/buildtools/qmake/trolllistview.h b/buildtools/qmake/trolllistview.h new file mode 100644 index 00000000..0ee86abb --- /dev/null +++ b/buildtools/qmake/trolllistview.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2004 by Alexander Dymo * + * adymo@mksat.net * + * * + * 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. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef TROLLLISTVIEW_H +#define TROLLLISTVIEW_H + +#include + +#include "trollprojectwidget.h" + +class TrollListView : public KListView +{ +Q_OBJECT +public: + TrollListView(TrollProjectWidget *widget, QWidget *parent, TrollProjectWidget::TrollProjectView view, const char *name = 0); + ~TrollListView(); +protected: + virtual void focusOutEvent(QFocusEvent *e); + +private: + TrollProjectWidget *m_widget; + TrollProjectWidget::TrollProjectView m_view; +}; + +#endif diff --git a/buildtools/qmake/trollprojectpart.cpp b/buildtools/qmake/trollprojectpart.cpp new file mode 100644 index 00000000..6d2f5b3a --- /dev/null +++ b/buildtools/qmake/trollprojectpart.cpp @@ -0,0 +1,931 @@ +/*************************************************************************** + * Copyright (C) 2003 by Thomas Hasart * + * thasart@gmx.de * + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2002 by Jakob Simon-Gaarde * + * jakob@jsg.dk * + * * + * 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 "trollprojectpart.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevmakefrontend.h" +#include "kdevappfrontend.h" +#include "kdevpartcontroller.h" +#include "trollprojectwidget.h" +#include "runoptionswidget.h" +#include "config.h" +#include "envvartools.h" +#include "qmakeoptionswidget.h" +#include "scope.h" + +#include +#include + +typedef KDevGenericFactory TrollProjectFactory; +static const KDevPluginInfo data("kdevtrollproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevtrollproject, TrollProjectFactory( data ) ) + +TrollProjectPart::TrollProjectPart(QObject *parent, const char *name, const QStringList& args ) + : KDevBuildTool(&data, parent, name ? name : "TrollProjectPart") +{ + setInstance(TrollProjectFactory::instance()); + + if ( args.count() == 1 && args[0] == "TMake" ) + m_tmakeProject = true; + else + m_tmakeProject = false; + + setXMLFile("kdevtrollproject.rc"); + + m_executeProjectAfterBuild = false; + m_executeTargetAfterBuild = false; + + m_dirWatch = new KDirWatch(this); + + m_widget = new TrollProjectWidget(this); + m_widget->setIcon(SmallIcon("qmakerun")); + m_widget->setCaption(i18n("QMake Manager")); + QWhatsThis::add(m_widget, i18n("QMake manager

" + "The QMake manager project tree consists of two parts. The 'overview' " + "in the upper half shows the subprojects, each one having a " + ".pro file. The 'details' view in the lower half shows the " + "list of files for the active subproject selected in the overview.")); + + mainWindow()->embedSelectViewRight(m_widget, i18n("QMake Manager"), i18n("QMake manager")); + + KAction *action; + + const QIconSet icon(SmallIcon("compfile")); + action = new KAction( i18n("Compile &File"), "compfile", 0, + m_widget, SLOT(slotBuildOpenFile()), + actionCollection(),"build_compilefile" ); + action->setToolTip(i18n("Compile file")); + action->setWhatsThis(i18n("Compile file

Runs make filename.o command from the directory where 'filename' is the name of currently opened file.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + + action = new KAction( i18n("&Build Project"), "make_kdevelop", Key_F8, + m_widget, SLOT(slotBuildProject()), + actionCollection(), "build_build_project" ); + action->setToolTip(i18n("Build project")); + action->setWhatsThis(i18n("Build project

Runs make from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Rebuild Project"),"rebuild" , 0, + m_widget, SLOT(slotRebuildProject()), + actionCollection(),"build_rebuild_project" ); + action->setToolTip(i18n("Rebuild project")); + action->setWhatsThis(i18n("Rebuild project

Runs make clean and then make from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Install Project"),"install" , 0, + m_widget, SLOT(slotInstallProject()), + actionCollection(),"build_install_project" ); + action->setToolTip(i18n("Install project")); + action->setWhatsThis(i18n("Install project

Runs make install from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Clean Project"), 0, + m_widget, SLOT(slotCleanProject()), + actionCollection(), "build_clean_project" ); + action->setToolTip(i18n("Clean project")); + action->setWhatsThis(i18n("Clean project

Runs make clean command from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Dist-Clean Project"), 0, + m_widget, SLOT(slotDistCleanProject()), + actionCollection(), "build_distclean_project" ); + action->setToolTip(i18n("Dist-Clean project")); + action->setWhatsThis(i18n("Dist-Clean project

Runs make distclean command from the " + "project directory.
Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("Execute Main Program"), "exec", SHIFT+Key_F9, + this, SLOT(slotBuildAndExecuteProject()), + actionCollection(), "build_execute_project" ); + action->setToolTip(i18n("Execute main program")); + action->setWhatsThis(i18n("Execute program

Executes the currently selected subproject if it is an application or the program specified in project settings, Run Options tab.")); + + action = new KAction( i18n("&Build Subproject"), "make_kdevelop", Key_F7, + m_widget, SLOT(slotBuildTarget()), + actionCollection(), "build_build_target" ); + action->setToolTip(i18n("Build subproject")); + action->setWhatsThis(i18n("Build subproject

Runs make from the current subproject directory. " + "Current subproject is a subproject selected in QMake manager 'overview' window.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Rebuild Subproject"), "rebuild", 0, + m_widget, SLOT(slotRebuildTarget()), + actionCollection(),"build_rebuild_target" ); + action->setToolTip(i18n("Rebuild subproject")); + action->setWhatsThis(i18n("Rebuild subproject

Runs make clean and then make from the current subproject directory. " + "Current subproject is a subproject selected in QMake manager 'overview' window.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Install Subproject"), "install", 0, + m_widget, SLOT(slotInstallTarget()), + actionCollection(),"build_install_target" ); + action->setToolTip(i18n("Install subproject")); + action->setWhatsThis(i18n("Install subproject

Runs make install from the current subproject directory. " + "The current subproject is the subproject selected in the QMake manager 'overview' window.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Clean Subproject"), 0, + m_widget, SLOT(slotCleanTarget()), + actionCollection(), "build_clean_target" ); + action->setToolTip(i18n("Clean subproject")); + action->setWhatsThis(i18n("Clean subproject

Runs make clean from the current subproject directory. " + "The current subproject is the subproject selected in the QMake manager 'overview' window.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("&Dist-Clean Subproject"), 0, + m_widget, SLOT(slotDistCleanTarget()), + actionCollection(), "build_distclean_target" ); + action->setToolTip(i18n("Dist-Clean subproject")); + action->setWhatsThis(i18n("Dist-Clean subproject

Runs make distclean from the current" + " subproject directory. The current subproject is the subproject selected in the QMake manager 'overview' window.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab.")); + + action = new KAction( i18n("Execute Subproject"), "exec", 0, + this, SLOT(slotBuildAndExecuteTarget()), + actionCollection(), "build_execute_target" ); + action->setToolTip(i18n("Execute subproject")); + action->setWhatsThis(i18n("Execute subproject

Executes the target program for the currently selected subproject. " + "This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be " + "defined in Subproject Settings dialog (open it from the subproject context menu).")); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); + + connect( makeFrontend(), SIGNAL(commandFinished(const QString&)), + this, SLOT(slotCommandFinished(const QString&)) ); + + QString m_defaultQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); + QString m_qmakePath = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", ""); + QString qtversion = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/version", "3"); + + if( m_defaultQtDir.isEmpty() || !isValidQtDir( m_defaultQtDir ) ) + { + m_defaultQtDir = findQtDir(); + kdDebug(9024) << "Setting default dir to: " << m_defaultQtDir << endl; + DomUtil::writeEntry(*projectDom(), "/kdevcppsupport/qt/root", m_defaultQtDir ); + } + if( m_qmakePath.isEmpty() || !isExecutable( m_qmakePath ) ) + { + m_qmakePath = findExecutable( "qmake-qt"+qtversion ); + if( m_qmakePath.isEmpty() || !isExecutable( m_qmakePath ) ) + m_qmakePath = findExecutable( "qmake" ); + kdDebug(9024) << "Setting qmake binary to: " << m_qmakePath << endl; + DomUtil::writeEntry(*projectDom(), "/kdevcppsupport/qt/qmake", m_qmakePath ); + } +} + + +TrollProjectPart::~TrollProjectPart() +{ + if (m_widget) + mainWindow()->removeView(m_widget); + delete m_widget; +} + +QString TrollProjectPart::makeEnvironment() +{ + // Get the make environment variables pairs into the environstr string + // in the form of: "ENV_VARIABLE=ENV_VALUE" + // Note that we quote the variable value due to the possibility of + // embedded spaces + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*projectDom(), "/kdevtrollproject/make/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + bool hasQtDir = false; + for (it = envvars.begin(); it != envvars.end(); ++it) { + if( (*it).first == "QTDIR" ) + hasQtDir = true; + + environstr += (*it).first; + environstr += "="; + environstr += EnvVarTools::quote((*it).second); + environstr += " "; + } + + if( !hasQtDir && !isQt4Project() && !DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", "").isEmpty() ) + { + environstr += QString( "QTDIR=" ) + EnvVarTools::quote( DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", "") ) + QString( " PATH=$QTDIR/bin:$PATH " ); + } + + KConfigGroup grp( kapp->config(), "MakeOutputView" ); + if( grp.readBoolEntry( "ForceCLocale", true ) ) + environstr += "LC_MESSAGES="+EnvVarTools::quote("C")+" "+" "+"LC_CTYPE="+EnvVarTools::quote("C")+" "; + + return environstr; +} + +void TrollProjectPart::projectConfigWidget(KDialogBase *dlg) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Run Options"), i18n("Run Options"), BarIcon( "make", KIcon::SizeMedium )); + RunOptionsWidget *optdlg = new RunOptionsWidget(*projectDom(), "/kdevtrollproject", buildDirectory(), vbox); + + vbox = dlg->addVBoxPage(i18n("Make Options"), i18n("Make Options"), BarIcon( "make", KIcon::SizeMedium )); + MakeOptionsWidget *w4 = new MakeOptionsWidget(*projectDom(), "/kdevtrollproject", vbox); + + vbox = dlg->addVBoxPage(i18n("QMake Manager"), i18n("QMake Manager"), BarIcon( "make", KIcon::SizeMedium )); + QMakeOptionsWidget *qm = new QMakeOptionsWidget( projectDirectory(), *projectDom(), "/kdevtrollproject", vbox); + + + connect( dlg, SIGNAL(okClicked()), w4, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), qm, SLOT(accept()) ); + connect( dlg, SIGNAL(okClicked()), optdlg, SLOT(accept()) ); +} + + +void TrollProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + mainWindow()->statusBar()->message( i18n("Loading Project...") ); + + QString defaultQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); + if( !isQt4Project() && ( defaultQtDir.isEmpty() || !isValidQtDir( defaultQtDir ) ) ) + { + bool doask = true; + while( doask ) + { + KURLRequesterDlg dlg( i18n("Choose Qt3 directory"), + i18n("Choose the Qt3 directory to use. This directory needs to have an include directory containing qt.h.") + , m_widget, 0); + dlg.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dlg.urlRequester() ->setURL( QString::null ); + dlg.urlRequester() ->completionObject() ->setDir( "/" ); + + if ( dlg.exec() == QDialog::Accepted && !dlg.urlRequester() ->url().isEmpty() ) + { + QString qtdir = dlg.urlRequester()->url(); + if( !isValidQtDir( qtdir ) ) + { + if( KMessageBox::warningYesNo( m_widget, + i18n("The directory you gave is not a proper Qt directory, the " + "project might not work properly without one.\nPlease make " + "sure you give a directory that contains a bin with the " + "qmake binary in it and for Qt3 project also contains an " + "include directory with qt.h in it.\nDo you want to try " + "setting a Qt directory again?"), + i18n("Wrong Qt directory given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + }else + { + defaultQtDir = qtdir; + doask = false; + } + + }else + { + if( KMessageBox::warningYesNo( m_widget, + i18n("You did not specify a Qt directory, and the project might not " + "work properly without one.\nDo you want to try setting a Qt" + " directory again?"), + i18n("No Qt directory given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + } + } + } + QString qmakePath = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", ""); + if( qmakePath.isEmpty() || !isExecutable( qmakePath ) ) + { + bool doask = true; + while( doask ) + { + KURLRequesterDlg dlg( i18n("Choose QMake executable"), + i18n("Choose the QMake binary to use. QMake is used to generate Makefiles from the project files."), m_widget, 0); + dlg.urlRequester() ->setMode( KFile::Directory | KFile::LocalOnly ); + dlg.urlRequester() ->setURL( QString::null ); + dlg.urlRequester() ->completionObject() ->setDir( "/" ); + + if ( dlg.exec() == QDialog::Accepted && !dlg.urlRequester() ->url().isEmpty() ) + { + QString qmake = dlg.urlRequester()->url(); + if( !isExecutable( qmake ) ) + { + if( KMessageBox::warningYesNo( m_widget, + i18n("The binary you gave is not executable, the " + "project might not work properly.\nPlease make " + "sure you give a qmake binary that is executable.\nDo you want to try " + "setting the QMake binary again?"), + i18n("Wrong QMake binary given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + }else + { + qmakePath = qmake; + doask = false; + } + + }else + { + if( KMessageBox::warningYesNo( m_widget, + i18n("You did not specify a QMake binary, and the project might not " + "work properly without one.\nDo you want to try setting a QMake" + " binary again?"), + i18n("No QMake binary given")) + == KMessageBox::Yes + ) + doask = true; + else + doask = false; + } + } + } + DomUtil::writeEntry( *projectDom(), "/kdevcppsupport/qt/root", defaultQtDir ); + DomUtil::writeEntry( *projectDom(), "/kdevcppsupport/qt/qmake", qmakePath ); + + m_projectName = projectName; + + m_widget->openProject(dirName); + + + QDomDocument &dom = *projectDom(); + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevtrollproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevtrollproject/run/directoryradio", "executable"); + } + + KDevProject::openProject( dirName, projectName ); +} + + +void TrollProjectPart::closeProject() +{ + m_widget->closeProject(); +} + + +QString TrollProjectPart::projectDirectory() const +{ + return m_widget->projectDirectory(); +} + + +QString TrollProjectPart::buildDirectory() const +{ + return m_widget->projectDirectory(); +} + +QString TrollProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList TrollProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevtrollproject/run/envvars", "envvar", "name", "value"); +} + +void TrollProjectPart::slotBuildAndExecuteProject() +{ + partController()->saveAllFiles(); + if (isDirty()) { + m_executeProjectAfterBuild = true; + m_widget->slotBuildProject(); + } else + m_widget->slotExecuteProject(); +} + +void TrollProjectPart::slotBuildAndExecuteTarget() +{ + partController()->saveAllFiles(); + if (isDirty()) { + m_executeTargetAfterBuild = true; + m_widget->slotBuildTarget(); + } else + m_widget->slotExecuteTarget(); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString TrollProjectPart::runDirectory() const +{ + QDomDocument &dom = *projectDom(); + + QString cwd; + if( DomUtil::readBoolEntry(dom, "/kdevtrollproject/run/useglobalprogram", true) ) + { + cwd = defaultRunDirectory("kdevtrollproject"); + }else + { + QString name = m_widget->getCurrentOutputFilename(); + if( name.findRev("/") != -1 ) + name = name.right( name.length()-name.findRev("/")-1 ); + cwd = DomUtil::readEntry( dom, "/kdevtrollproject/run/cwd/" + name ); + } + if( cwd.isEmpty() ) + { + QString destpath = m_widget->getCurrentTarget(); + if( QDir::isRelativePath( destpath ) ) + { + destpath = m_widget->subprojectDirectory() + QString( QChar( QDir::separator() ) ) + destpath; + } + destpath = destpath.left( destpath.findRev("/") ); + cwd = destpath; + } + + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ + + +QString TrollProjectPart::mainProgram() const +{ + + QDomDocument &dom = *projectDom(); + + if( DomUtil::readBoolEntry(dom, "/kdevtrollproject/run/useglobalprogram", false) ) + { + QString DomMainProgram = DomUtil::readEntry(dom, "/kdevtrollproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + }else + { + if( !m_widget->currentSubproject()) + { + KMessageBox::error( m_widget, "There's no selected subproject!\n" + "Unable to determine the main program", "No selected subproject found" ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : There's no active target! -> Unable to determine the main program in TrollProjectPart::mainProgram()" << endl; + return QString::null; + } + + if ( m_widget->currentSubproject()->scope->variableValues("TEMPLATE").findIndex("app") == -1 ) + { + KMessageBox::error( m_widget, "Selected Subproject \""+m_widget->currentSubproject()->scope->projectName()+"\"isn't binary ( " + m_widget->currentSubproject()->scope->variableValues("TEMPLATE").join(" ") + " ) !\n" + "Unable to determine the main program. If you want this\n" + "to be the selected subproject, set a main program under\n" + "Project -> Project Options -> Run Options", "Selected subproject is not a library" ); + kdDebug ( 9020 ) << k_funcinfo << "Error! : Active target isn't binary (" << m_widget->currentSubproject()->scope->variableValues("TEMPLATE").join(" ") << ") ! -> Unable to determine the main program in TrollProjectPart::mainProgram()" << endl; + return QString::null; + } + + QString destpath = m_widget->getCurrentTarget(); + if( QDir::isRelativePath( destpath ) ) + { + destpath = m_widget->subprojectDirectory() + QString( QChar( QDir::separator() ) ) + destpath; + } + return destpath; + } +} + +QString TrollProjectPart::debugArguments() const +{ + if( DomUtil::readBoolEntry(*projectDom(), "/kdevtrollproject/run/useglobalprogram", true ) ) + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/globaldebugarguments"); + }else + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/debugarguments/"+m_widget->getCurrentOutputFilename() ); + } +} + +/** Retuns a QString with the run command line arguments */ +QString TrollProjectPart::runArguments() const +{ + if( DomUtil::readBoolEntry(*projectDom(), "/kdevtrollproject/run/useglobalprogram", true) ) + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/programargs"); + }else + { + return DomUtil::readEntry(*projectDom(), "/kdevtrollproject/run/runarguments/"+m_widget->getCurrentOutputFilename() ); + } +} + + +QString TrollProjectPart::activeDirectory() const +{ + QDomDocument &dom = *projectDom(); + + return DomUtil::readEntry(dom, "/kdevtrollproject/general/activedir"); +} + + +QStringList TrollProjectPart::allFiles() const +{ + return m_widget->allFiles(); +} + + +void TrollProjectPart::addFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( QStringList( fileName ) ); +} + +void TrollProjectPart::addFiles ( const QStringList &fileList ) +{ + QStringList files = fileList; + for (QStringList::iterator it = files.begin(); it != files.end(); ++it) + { + if( !QFileInfo( *it ).isRelative() ) + { + *it = URLUtil::relativePathToFile( projectDirectory(), *it ); + } + } + m_widget->addFiles(files); + +} + +void TrollProjectPart::removeFile(const QString & /* fileName */) +{ + /// \FIXME +/* QStringList fileList; + fileList.append ( fileName ); + + this->removeFiles ( fileList );*/ +} + +void TrollProjectPart::removeFiles ( const QStringList& fileList ) +{ +/// \FIXME missing remove files functionality +// QStringList::ConstIterator it; +// +// it = fileList.begin(); +// +// for ( ; it != fileList.end(); ++it ) +// { +// FIXME +// } + + emit removedFilesFromProject ( fileList ); +} +/* +void TrollProjectPart::startMakeCommand(const QString &dir, const QString &target) +{ + partController()->saveAllFiles(); + + QFileInfo fi(dir + "/Makefile"); + if (!fi.exists()) { + int r = KMessageBox::questionYesNo(m_widget, i18n("There is no Makefile in this directory. Run qmake first?"), QString::null, i18n("Run qmake"), i18n("Do Not Run")); + if (r == KMessageBox::No) + return; + startQMakeCommand(dir); + } + QDomDocument &dom = *projectDom(); + + if (target=="clean") + { + QString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); + if (cmdline.isEmpty()) + cmdline = MAKE_COMMAND; + cmdline += " clean"; + QString dircmd = "cd "; + dircmd += dir; + dircmd += " && "; + cmdline.prepend(makeEnvironment()); + makeFrontend()->queueCommand(dir, dircmd + cmdline); + } + + QString cmdline = DomUtil::readEntry(dom, "/kdevtrollproject/make/makebin"); + if (cmdline.isEmpty()) + cmdline = MAKE_COMMAND; + if (!DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/abortonerror")) + cmdline += " -k"; + int jobs = DomUtil::readIntEntry(dom, "/kdevtrollproject/make/numberofjobs"); + if (jobs != 0) { + cmdline += " -j"; + cmdline += QString::number(jobs); + } + if (DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/dontact")) + cmdline += " -n"; + + cmdline += " "; + cmdline += target; + + QString dircmd = "cd "; + dircmd += dir; + dircmd += " && "; + + cmdline.prepend(makeEnvironment()); + makeFrontend()->queueCommand(dir, dircmd + cmdline); +} +*/ + +void TrollProjectPart::startQMakeCommand(const QString &dir, bool recursive) +{ + QFileInfo fi(dir); + QString cmdline; + + if ( isTMakeProject() ) + { + cmdline = "tmake "; + }else + { + cmdline = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", "")+" "; + } + + if(isQt4Project() && recursive) + { + cmdline += " -recursive "; + } + + //QString cmdline = QString::fromLatin1( isTMakeProject() ? "tmake " : "qmake " ); +// cmdline += fi.baseName() + ".pro"; + QDir d(dir); + QStringList l = d.entryList("*.pro"); + + if( l.isEmpty() || ( l.count() && l.findIndex( projectName() + ".pro" ) != -1 ) ) + cmdline += projectName()+".pro"; + else if( l.isEmpty() || (l.count() && l.findIndex( fi.baseName() + ".pro" ) != -1 ) ) + cmdline += fi.baseName() + ".pro"; + else + cmdline += l[0]; + +// cmdline += QString::fromLatin1( " -o Makefile" ); + + QString dircmd = "cd "; + dircmd += KProcess::quote(dir); + dircmd += " && "; + + cmdline.prepend(makeEnvironment()); + makeFrontend()->queueCommand(dir, dircmd + cmdline); +} + +void TrollProjectPart::queueCmd(const QString &dir, const QString &cmd) +{ + makeFrontend()->queueCommand(dir, cmd); +} + +void TrollProjectPart::slotCommandFinished( const QString& command ) +{ + Q_UNUSED( command ); + +// if( m_buildCommand != command ) +// return; +// +// m_buildCommand = QString::null; + + m_timestamp.clear(); + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + m_timestamp[ fileName ] = QFileInfo( projectDirectory(), fileName ).lastModified(); + } + + emit projectCompiled(); + + if( m_executeProjectAfterBuild ) + { + m_widget->slotExecuteProject(); + m_executeProjectAfterBuild = false; + }else if( m_executeTargetAfterBuild ) + { + m_widget->slotExecuteTarget(); + m_executeTargetAfterBuild = false; + } + +} + +bool TrollProjectPart::isDirty() +{ + QStringList fileList = allFiles(); + QStringList::Iterator it = fileList.begin(); + while( it != fileList.end() ){ + QString fileName = *it; + ++it; + + QMap::Iterator it = m_timestamp.find( fileName ); + QDateTime t = QFileInfo( projectDirectory(), fileName ).lastModified(); + if( it == m_timestamp.end() || *it != t ){ + return true; + } + } + + return false; +} + +KDevProject::Options TrollProjectPart::options( ) const +{ + return UsesQMakeBuildSystem; +} + +bool TrollProjectPart::isValidQtDir( const QString& path ) const +{ + QFileInfo inc( path + QString( QChar( QDir::separator() ) )+ + "include"+QString( QChar( QDir::separator() ) )+ + "qt.h" ); + return ( isQt4Project() || ( !isQt4Project() && inc.exists() ) ); +} + +void TrollProjectPart::buildBinDirs( QStringList & dirs ) const +{ + if( !isQt4Project() ) + { + QString m_defaultQtDir = DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/root", ""); + if( !m_defaultQtDir.isEmpty() ) + dirs << (m_defaultQtDir + QString( QChar( QDir::separator() ) ) + "bin" ); + dirs << ( ::getenv("QTDIR") + QString( QChar( QDir::separator() ) ) + "bin" ); + } + QStringList paths = QStringList::split(":",::getenv("PATH")); + dirs += paths; + QString binpath = QDir::rootDirPath() + "bin"; + if( dirs.findIndex( binpath ) != -1 ) + dirs << binpath; + + binpath = QDir::rootDirPath() + "usr" + QString( QChar( QDir::separator() ) ) + "bin"; + if( dirs.findIndex( binpath ) != -1 ) + dirs << binpath; + binpath = QDir::rootDirPath() + "usr" + QString( QChar( QDir::separator() ) ) + "local" + QString( QChar( QDir::separator() ) ) + "bin"; + if( dirs.findIndex( binpath ) != -1 ) + dirs << binpath; +} + + +QString TrollProjectPart::findExecutable( const QString& execname ) const +{ + QStringList dirs; + buildBinDirs( dirs ); + + for( QStringList::Iterator it=dirs.begin(); it!=dirs.end(); ++it ) + { + QString designer = *it + QString( QChar( QDir::separator() ) ) + execname; + if( !designer.isEmpty() && isExecutable( designer ) ) + { + return designer; + } + } + return ""; +} + +bool TrollProjectPart::isExecutable( const QString& path ) const +{ + QFileInfo fi(path); + return( fi.exists() && fi.isExecutable() ); +} + +QString TrollProjectPart::findQtDir() +{ + QStringList qtdirs; + if( !isQt4Project() ) + qtdirs.push_back( ::getenv("QTDIR") ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"lib"+QString( QChar( QDir::separator() ) )+"qt"+QString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"lib"+QString( QChar( QDir::separator() ) )+"qt"+QString( QChar( QDir::separator() ) )+QString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"share"+QString( QChar( QDir::separator() ) )+"qt"+QString("%1").arg( DomUtil::readEntry( *projectDom(), "/kdevcppsupport/qt/version", "3") ) ); + qtdirs.push_back( QDir::rootDirPath()+"usr" ); + qtdirs.push_back( QDir::rootDirPath()+"usr"+QString( QChar( QDir::separator() ) )+"lib"+QString( QChar( QDir::separator() ) )+"qt" ); + + for( QStringList::Iterator it=qtdirs.begin(); it!=qtdirs.end(); ++it ) + { + QString qtdir = *it; + if( !qtdir.isEmpty() && isValidQtDir(qtdir) ) + { + return qtdir; + } + } + return ""; +} + + +QStringList recursiveProFind( const QString &currDir, const QString &baseDir ) +{ + QStringList fileList; + + if( !currDir.contains( QString( QChar ( QDir::separator() ) ) +".." ) + && !currDir.contains( QString( QChar( QDir::separator() ) )+".") ) + { + QDir dir(currDir); + QStringList dirList = dir.entryList(QDir::Dirs ); + QStringList::Iterator idx = dirList.begin(); + for( ; idx != dirList.end(); ++idx ) + { + fileList += recursiveProFind( currDir + QString( QChar( QDir::separator() ) ) + (*idx),baseDir ); + } + QStringList newFiles = dir.entryList("*.pro *.PRO"); + idx = newFiles.begin(); + for( ; idx != newFiles.end(); ++idx ) + { + QString file = currDir + QString( QChar( QDir::separator() ) ) + (*idx); + fileList.append( file.remove( baseDir ) ); + } + } + + + return fileList; +} + +/*! + \fn TrollProjectPart::distFiles() const + */ +QStringList TrollProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QStringList files = recursiveProFind( projectDir, projectDir + QString( QChar( QDir::separator() ) ) ); + return sourceList + files; +} + +bool TrollProjectPart::isQt4Project() const +{ + return ( DomUtil::readIntEntry( *projectDom(), "kdevcppsupport/qt/version", 3 ) == 4 ); +} + +KDirWatch* TrollProjectPart::dirWatch() +{ + return m_dirWatch; +} + +void TrollProjectPart::slotBuild() +{ + m_widget->slotBuildProject(); +} + +#include "trollprojectpart.moc" + +//kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + + diff --git a/buildtools/qmake/trollprojectpart.h b/buildtools/qmake/trollprojectpart.h new file mode 100644 index 00000000..3e571e85 --- /dev/null +++ b/buildtools/qmake/trollprojectpart.h @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2003 by Thomas Hasart * + * thasart@gmx.de * + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * Copyright (C) 2002 by Jakob Simon-Gaarde * + * jakob@jsg.dk * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _TROLLPROJECTPART_H_ +#define _TROLLPROJECTPART_H_ + +#include +#include +#include +#include + +#include "kdevbuildtool.h" + +class KDialogBase; +class TrollProjectWidget; +class KDirWatch; +class QMakeDefaultOpts; + +class TrollProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + TrollProjectPart( QObject *parent, const char *name, const QStringList &args ); + ~TrollProjectPart(); + + bool isTMakeProject() const { return m_tmakeProject; } + bool isQt4Project() const; + bool isDirty(); + KDirWatch* dirWatch(); + virtual Options options() const; + QStringList distFiles() const; + inline QString qmakePath() const { return DomUtil::readEntry(*projectDom(), "/kdevcppsupport/qt/qmake", "");; } + +protected: + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile(const QString &fileName); + virtual void addFiles ( const QStringList &fileList ); + virtual void removeFile(const QString &fileName); + virtual void removeFiles ( const QStringList &fileList ); + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + +private slots: + void projectConfigWidget(KDialogBase *dlg); + void slotBuild(); +// void slotClean(); +// void slotExecute(); + void slotCommandFinished( const QString& command ); + void slotBuildAndExecuteProject(); + void slotBuildAndExecuteTarget(); + +private: +// void startMakeCommand(const QString &dir, const QString &target); + void startQMakeCommand(const QString &dir, bool recursive = false ); +// void execute(const QString &directory, const QString &command); + void queueCmd(const QString &dir, const QString &cmd); + QString makeEnvironment(); + + QString findQtDir(); + QString findExecutable( const QString& path ) const; + void buildBinDirs( QStringList& ) const; + bool isValidQtDir( const QString& path ) const; + bool isExecutable( const QString& path ) const; + + QGuardedPtr m_widget; + QString m_projectName; + bool m_tmakeProject; + + QMap m_timestamp; + bool m_executeProjectAfterBuild; + bool m_executeTargetAfterBuild; + QString m_buildCommand; + + KDirWatch* m_dirWatch; + + friend class TrollProjectWidget; + friend class ProjectRunOptionsDlg; + friend class QMakeDefaultOpts; +}; + +#endif + diff --git a/buildtools/qmake/trollprojectwidget.cpp b/buildtools/qmake/trollprojectwidget.cpp new file mode 100644 index 00000000..7668dbd7 --- /dev/null +++ b/buildtools/qmake/trollprojectwidget.cpp @@ -0,0 +1,2547 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* Copyright (C) 2000-2001 by Trolltech AS. * +* info@trolltech.com * +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jakob@jsg.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* Part of this file is taken from Qt Designer. * +* * +* 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 "trollprojectwidget.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kdevcore.h" +#include "kdevpartcontroller.h" +#include "kdevmainwindow.h" +#include "trollprojectpart.h" +#include "kdevappfrontend.h" +#include "kdevmakefrontend.h" +#include "kdevlanguagesupport.h" +#include "kdevcreatefile.h" +#include "subclassesdlg.h" +#include "addfilesdialog.h" +#include "urlutil.h" +#include "trolllistview.h" +#include "projectconfigurationdlg.h" +#include "qmakescopeitem.h" +#include "scope.h" +#include "createscopedlg.h" +#include "disablesubprojectdlg.h" +#include + +TrollProjectWidget::TrollProjectWidget( TrollProjectPart *part ) + : QVBox( 0, "troll project widget" ), m_shownSubproject( 0 ), m_rootSubproject( 0 ), + m_rootScope ( 0 ), m_part ( part ), m_configDlg( 0 ), m_filesCached(false) +{ + + QSplitter * splitter = new QSplitter( Vertical, this ); + + ////////////////// + // PROJECT VIEW // + ////////////////// + + overviewContainer = new QVBox( splitter, "Projects" ); + overviewContainer->setMargin ( 2 ); + overviewContainer->setSpacing ( 2 ); + // overviewContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); + // splitter->setResizeMode(overviewContainer, QSplitter::FollowSizeHint); + + projectTools = new QHBox( overviewContainer, "Project buttons" ); + projectTools->setMargin ( 2 ); + projectTools->setSpacing ( 2 ); + // Add subdir + addSubdirButton = new QToolButton ( projectTools, "Add subproject button" ); + addSubdirButton->setPixmap ( SmallIcon ( "folder_new" ) ); + addSubdirButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, addSubdirButton->sizePolicy().hasHeightForWidth() ) ); + addSubdirButton->setEnabled ( true ); + QToolTip::add( addSubdirButton, i18n( "Add subproject" ) ); + QWhatsThis::add( addSubdirButton, i18n( "Add subproject

Creates a new or adds an existing subproject to a currently selected subproject. " + "This action is allowed only if a type of the subproject is 'subdirectories'. The type of the subproject can be " + "defined in Subproject Settings dialog (open it from the subproject context menu)." ) ); + // Create scope + createScopeButton = new QToolButton ( projectTools, "Create scope button" ); + createScopeButton->setPixmap ( SmallIcon ( "qmake_scopenew" ) ); + createScopeButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, createScopeButton->sizePolicy().hasHeightForWidth() ) ); + createScopeButton->setEnabled ( true ); + QToolTip::add( createScopeButton, i18n( "Create scope" ) ); + QWhatsThis::add( createScopeButton, i18n( "Create scope

Creates QMake scope in the project file in case the subproject is selected or creates nested scope in case the scope is selected." ) ); + + // build + buildProjectButton = new QToolButton ( projectTools, "Make button" ); + buildProjectButton->setPixmap ( SmallIcon ( "make_kdevelop" ) ); + buildProjectButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, buildProjectButton->sizePolicy().hasHeightForWidth() ) ); + buildProjectButton->setEnabled ( true ); + QToolTip::add( buildProjectButton, i18n( "Build project" ) ); + QWhatsThis::add( buildProjectButton, i18n( "Build project

Runs make from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + // rebuild + rebuildProjectButton = new QToolButton ( projectTools, "Rebuild button" ); + rebuildProjectButton->setPixmap ( SmallIcon ( "rebuild" ) ); + rebuildProjectButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, rebuildProjectButton->sizePolicy().hasHeightForWidth() ) ); + rebuildProjectButton->setEnabled ( true ); + QToolTip::add( rebuildProjectButton, i18n( "Rebuild project" ) ); + QWhatsThis::add( rebuildProjectButton, i18n( "Rebuild project

Runs make clean and then make from the project directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + // run + executeProjectButton = new QToolButton ( projectTools, "Run button" ); + executeProjectButton->setPixmap ( SmallIcon ( "exec" ) ); + executeProjectButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, executeProjectButton->sizePolicy().hasHeightForWidth() ) ); + executeProjectButton->setEnabled ( true ); + QToolTip::add( executeProjectButton, i18n( "Execute main program" ) ); + QWhatsThis::add( executeProjectButton, i18n( "Execute main program

Executes the main program specified in project settings, Run Options tab." ) ); + // spacer + QWidget *spacer = new QWidget( projectTools ); + projectTools->setStretchFactor( spacer, 1 ); + // Project configuration + projectconfButton = new QToolButton ( projectTools, "Project configuration button" ); + projectconfButton->setPixmap ( SmallIcon ( "configure" ) ); + projectconfButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, projectconfButton->sizePolicy().hasHeightForWidth() ) ); + projectconfButton->setEnabled ( true ); + QToolTip::add( projectconfButton, i18n( "Subproject settings" ) ); + QWhatsThis::add( projectconfButton, i18n( "Subproject settings

Opens QMake Subproject Configuration dialog for the currently selected subproject. " + "It provides settings for:
subproject type and configuration,
include and library paths,
lists of dependencies and " + "external libraries,
build order,
intermediate files locations,
compiler options." ) ); + + // Project button connections + connect ( addSubdirButton, SIGNAL ( clicked () ), this, SLOT ( slotAddSubproject () ) ); + connect ( createScopeButton, SIGNAL ( clicked () ), this, SLOT ( slotCreateScope () ) ); + + + connect ( buildProjectButton, SIGNAL ( clicked () ), this, SLOT ( slotBuildProject () ) ); + connect ( rebuildProjectButton, SIGNAL ( clicked () ), this, SLOT ( slotRebuildProject () ) ); + connect ( executeProjectButton, SIGNAL ( clicked () ), m_part, SLOT ( slotBuildAndExecuteProject () ) ); + + + connect ( projectconfButton, SIGNAL ( clicked () ), this, SLOT ( slotConfigureProject () ) ); + + // Project tree + overview = new TrollListView( this, overviewContainer, SubprojectView, "project overview widget" ); +// overview->setResizeMode( QListView::LastColumn ); + overview->setSorting( -1 ); + overview->header() ->hide(); + overview->addColumn( QString::null ); + + // Project tree connections + connect( overview, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotOverviewSelectionChanged( QListViewItem* ) ) ); + connect( overview, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotOverviewContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); + + + ///////////////// + // DETAIL VIEW // + ///////////////// + + // Details tree + detailContainer = new QVBox( splitter, "Details" ); + detailContainer->setMargin ( 2 ); + detailContainer->setSpacing ( 2 ); + // detailContainer->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); + + // Details Toolbar + fileTools = new QHBox( detailContainer, "Detail buttons" ); + fileTools->setMargin ( 2 ); + fileTools->setSpacing ( 2 ); + + // Add new file button + newfileButton = new QToolButton ( fileTools, "Create new file" ); + newfileButton->setPixmap ( SmallIcon ( "filenew" ) ); + newfileButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, newfileButton->sizePolicy().hasHeightForWidth() ) ); + newfileButton->setEnabled ( true ); + QToolTip::add( newfileButton, i18n( "Create new file" ) ); + QWhatsThis::add( newfileButton, i18n( "Create new file

Creates a new file and adds it to a currently selected group." ) ); + + // Add existing files button + addfilesButton = new QToolButton ( fileTools, "Add existing files" ); + addfilesButton->setPixmap ( SmallIcon ( "fileimport" ) ); + addfilesButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, addfilesButton->sizePolicy().hasHeightForWidth() ) ); + addfilesButton->setEnabled ( true ); + QToolTip::add( addfilesButton, i18n( "Add existing files" ) ); + QWhatsThis::add( addfilesButton, i18n( "Add existing files

Adds existing files to a currently selected group. It is " + "possible to copy files to a current subproject directory, create symbolic links or " + "add them with the relative path." ) ); + + // remove file button + removefileButton = new QToolButton ( fileTools, "Remove file" ); + removefileButton->setPixmap ( SmallIcon ( "button_cancel" ) ); + removefileButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, removefileButton->sizePolicy().hasHeightForWidth() ) ); + removefileButton->setEnabled ( true ); + QToolTip::add( removefileButton, i18n( "Remove file" ) ); + QWhatsThis::add( removefileButton, i18n( "Remove file

Removes file from a current group. Does not remove file from disk." ) ); + + // build selected file + buildFileButton = new QToolButton ( fileTools, "Make file button" ); + buildFileButton->setPixmap ( SmallIcon ( "compfile" ) ); + buildFileButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, buildFileButton->sizePolicy().hasHeightForWidth() ) ); + buildFileButton->setEnabled ( true ); + QToolTip::add( buildFileButton, i18n( "Compile file" ) ); + QWhatsThis::add( buildFileButton, i18n( "Compile file

Runs make filename.o command from the directory where 'filename' is the name of currently opened file.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + // build + buildTargetButton = new QToolButton ( fileTools, "Make sp button" ); + buildTargetButton->setPixmap ( SmallIcon ( "make_kdevelop" ) ); + buildTargetButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, buildTargetButton->sizePolicy().hasHeightForWidth() ) ); + buildTargetButton->setEnabled ( true ); + QToolTip::add( buildTargetButton, i18n( "Build subproject" ) ); + QWhatsThis::add( buildTargetButton, i18n( "Build subproject

Runs make from the current subproject directory. " + "Current subproject is a subproject selected in QMake manager 'overview' window.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + // rebuild + rebuildTargetButton = new QToolButton ( fileTools, "Rebuild sp button" ); + rebuildTargetButton->setPixmap ( SmallIcon ( "rebuild" ) ); + rebuildTargetButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, rebuildTargetButton->sizePolicy().hasHeightForWidth() ) ); + rebuildTargetButton->setEnabled ( true ); + QToolTip::add( rebuildTargetButton, i18n( "Rebuild subproject" ) ); + QWhatsThis::add( rebuildTargetButton, i18n( "Rebuild subproject

Runs make clean and then make from the current subproject directory. " + "Current subproject is a subproject selected in QMake manager 'overview' window.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + // run + executeTargetButton = new QToolButton ( fileTools, "Run sp button" ); + executeTargetButton->setPixmap ( SmallIcon ( "exec" ) ); + executeTargetButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, executeTargetButton->sizePolicy().hasHeightForWidth() ) ); + executeTargetButton->setEnabled ( true ); + QToolTip::add( executeTargetButton, i18n( "Execute subproject" ) ); + QWhatsThis::add( executeTargetButton, i18n( "Execute subproject

Executes the target program for the currently selected subproject. " + "This action is allowed only if a type of the subproject is 'application'. The type of the subproject can be " + "defined in Subproject Settings dialog (open it from the subproject context menu)." ) ); + + + // spacer + spacer = new QWidget( fileTools ); + projectTools->setStretchFactor( spacer, 1 ); + + // Configure file button + excludeFileFromScopeButton = new QToolButton ( fileTools, "Exclude file" ); + excludeFileFromScopeButton->setPixmap ( SmallIcon ( "configure_file" ) ); + excludeFileFromScopeButton->setSizePolicy ( QSizePolicy ( ( QSizePolicy::SizeType ) 0, ( QSizePolicy::SizeType ) 0, 0, 0, excludeFileFromScopeButton->sizePolicy().hasHeightForWidth() ) ); + excludeFileFromScopeButton->setEnabled ( true ); + QToolTip::add( excludeFileFromScopeButton , i18n( "Exclude file" ) ); + QWhatsThis::add( excludeFileFromScopeButton , i18n( "Exclude file

Exclude the selected file from this scope." ) ); + + // detail tree + details = new TrollListView( this, detailContainer, DetailsView, "details widget" ); + details->setRootIsDecorated( true ); + details->setResizeMode( QListView::LastColumn ); + details->setSorting( -1 ); + details->header() ->hide(); + details->addColumn( QString::null ); + // Detail button connections + connect ( addfilesButton, SIGNAL ( clicked () ), this, SLOT ( slotAddFiles () ) ); + connect ( newfileButton, SIGNAL ( clicked () ), this, SLOT ( slotNewFile () ) ); + connect ( removefileButton, SIGNAL ( clicked () ), this, SLOT ( slotRemoveFile () ) ); + connect ( buildFileButton, SIGNAL ( clicked () ), this, SLOT ( slotBuildSelectedFile () ) ); + connect ( excludeFileFromScopeButton, SIGNAL ( clicked () ), this, SLOT ( slotExcludeFileFromScopeButton() ) ); + + // Detail tree connections + connect( details, SIGNAL( selectionChanged( QListViewItem* ) ), + this, SLOT( slotDetailsSelectionChanged( QListViewItem* ) ) ); + connect( details, SIGNAL( executed( QListViewItem* ) ), + this, SLOT( slotDetailsExecuted( QListViewItem* ) ) ); + connect( details, SIGNAL( contextMenu( KListView*, QListViewItem*, const QPoint& ) ), + this, SLOT( slotDetailsContextMenu( KListView*, QListViewItem*, const QPoint& ) ) ); + + connect ( buildTargetButton, SIGNAL ( clicked () ), this, SLOT ( slotBuildTarget () ) ); + connect ( rebuildTargetButton, SIGNAL ( clicked () ), this, SLOT ( slotRebuildTarget () ) ); + connect ( executeTargetButton, SIGNAL ( clicked () ), m_part, SLOT ( slotBuildAndExecuteTarget () ) ); + buildTargetButton->setEnabled( false ); + rebuildTargetButton->setEnabled( false ); + executeTargetButton->setEnabled( false ); + + m_configDlg = new ProjectConfigurationDlg( overview, this, this ); + + connect( m_part->dirWatch(), SIGNAL( dirty(const QString&) ), this, SLOT( slotProjectDirty(const QString&) ) ); +} + + +TrollProjectWidget::~TrollProjectWidget() +{ + delete m_configDlg; +} + + +void TrollProjectWidget::openProject( const QString &dirName ) +{ + QDomDocument & dom = *( m_part->projectDom() ); + m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + + QString projectfile = DomUtil::readEntry( dom, "/kdevtrollproject/qmake/projectfile", "" ); + + m_showFilenamesOnly = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/enableFilenamesOnly", false ); + m_showVariablesInTree = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/showVariablesInTree", true ); + + QString proname; + + if( projectfile.isEmpty() ) + { + QFileInfo fi( dirName ); + QDir dir( dirName ); + // QString proname = item->path + "/" + fi.baseName() + ".pro"; + + QStringList l = dir.entryList( "*.pro" ); + + QString profile; + if( l.count() && l.findIndex( m_part->projectName() + ".pro") != -1 ) + profile = m_part->projectName()+".pro"; + else if( l.isEmpty() || ( l.count() && l.findIndex( fi.baseName() + ".pro") != -1 ) ) + profile = fi.baseName()+".pro"; + else + profile = l[0]; + + proname = dirName + QString( QChar( QDir::separator() ) ) + profile; + } else + { + proname = projectfile; + } + + kdDebug( 9024 ) << "Parsing " << proname << endl; + + m_rootScope = new Scope( qmakeEnvironment(), proname, m_part ); + if( m_rootScope->scopeType() != Scope::InvalidScope ) + { + + m_rootSubproject = new QMakeScopeItem( overview, m_rootScope->scopeName(), m_rootScope, this ); + + + m_rootSubproject->setOpen( true ); + if ( m_rootSubproject->firstChild() && m_rootSubproject->scope->variableValues( "TEMPLATE" ).findIndex("subdirs") != -1 ) + { + overview->setSelected( m_rootSubproject->firstChild(), true ); + } + else + { + overview->setSelected( m_rootSubproject, true ); + } + }else + { + delete m_rootScope; + m_rootScope = 0; + } +// kdDebug(9024) << "Adding " << allFiles().count() << " Files" << endl; +// kdDebug(9024) << allFiles() << endl; + +} + +void TrollProjectWidget::createQMakeScopeItems() +{ + +} + +void TrollProjectWidget::closeProject() +{ + m_rootSubproject = 0; + overview->clear(); + details->clear(); + delete m_rootScope; +} + +QStringList TrollProjectWidget::allFiles() +{ + if( !m_rootScope ) + return QStringList(); + if( m_filesCached ) + return m_allFilesCache; + m_allFilesCache = m_rootScope->allFiles( m_rootScope->projectDir() ); + m_filesCached = true; + return m_allFilesCache; +} + +QString TrollProjectWidget::projectDirectory() +{ + if ( !m_rootScope ) + return QString::null; //confused + + return m_rootScope->projectDir(); +} + + +QString TrollProjectWidget::subprojectDirectory() +{ + if ( !m_shownSubproject ) + return QString::null; + + return m_shownSubproject->scope->projectDir(); +} + +void TrollProjectWidget::setupContext() +{ + if ( !m_shownSubproject ) + return ; + bool buildable = true; + bool runable = true; + bool fileconfigurable = true; + bool hasSourceFiles = true; + bool hasSubdirs = false; + + QStringList tmpl = m_shownSubproject->scope->variableValues( "TEMPLATE" ); + + if ( tmpl.findIndex( "lib" ) != -1 ) + { + runable = false; + } + else if ( tmpl.findIndex( "subdirs" ) != -1 ) + { + hasSubdirs = true; + runable = false; + hasSourceFiles = false; + fileconfigurable = false; + } + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + { + runable = false; + buildable = false; + } + + + // Setup toolbars according to context + addSubdirButton->setEnabled( hasSubdirs ); + buildTargetButton->setEnabled( buildable ); + m_part->actionCollection() ->action( "build_build_target" ) ->setEnabled( buildable ); + + rebuildTargetButton->setEnabled( buildable ); + m_part->actionCollection() ->action( "build_rebuild_target" ) ->setEnabled( buildable ); + + executeTargetButton->setEnabled( runable ); + m_part->actionCollection() ->action( "build_execute_target" ) ->setEnabled( runable ); + + excludeFileFromScopeButton->setEnabled( !hasSubdirs ); + newfileButton->setEnabled( !hasSubdirs ); + removefileButton->setEnabled( !hasSubdirs ); + addfilesButton->setEnabled( !hasSubdirs ); + buildFileButton->setEnabled( !hasSubdirs ); + + details->setEnabled( hasSourceFiles ); +} + +void TrollProjectWidget::slotOverviewSelectionChanged( QListViewItem *item ) +{ + QString olddir = m_part->activeDirectory(); + if ( !item ) + { + kdDebug(9024) << "Trying to select a non-existing item" << endl; + return ; + } + cleanDetailView( m_shownSubproject ); + m_shownSubproject = static_cast( item ); + setupContext(); + buildProjectDetailTree( m_shownSubproject, details ); + + QDomDocument &dom = *( m_part->projectDom() ); + DomUtil::writeEntry( dom, "/kdevtrollproject/general/activedir", m_shownSubproject->relativePath() ); + if ( m_configDlg && m_configDlg->isShown() ) + { + m_configDlg->updateSubproject( m_shownSubproject ); + } + emit m_part->activeDirectoryChanged( olddir, m_part->activeDirectory() ); +} + +QString TrollProjectWidget::getCurrentTarget() +{ + if ( !m_shownSubproject ) + return ""; + QString destdir = getCurrentDestDir(); + if ( destdir.isEmpty() ) + return getCurrentOutputFilename(); + else + return destdir + QString( QChar( QDir::separator() ) ) + getCurrentOutputFilename(); +} + +QString TrollProjectWidget::getCurrentDestDir() +{ + if ( !m_shownSubproject ) + return ""; + QStringList destdir = m_shownSubproject->scope->variableValues( "DESTDIR", true, true, true ); + return m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->variableValues( "DESTDIR", true, true, true ).front()); +} + +QString TrollProjectWidget::getCurrentOutputFilename() +{ + if ( !m_shownSubproject ) + return ""; + if ( m_shownSubproject->scope->variableValues( "TARGET", true, true, true ).isEmpty() ) + { + QString exe = m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->fileName()); + return exe.replace( QRegExp( "\\.pro$" ), "" ); + } + else + { + return m_shownSubproject->scope->resolveVariables(m_shownSubproject->scope->variableValues( "TARGET", true, true, true ).front()); + } +} + +void TrollProjectWidget::cleanDetailView( QMakeScopeItem *item ) +{ + // If no children in detailview + // it is a subdir template + if ( item && details->childCount() ) + { + QListViewItem* i = details->firstChild(); + while( i ) + { + QListViewItem* old = i; + i = i->nextSibling(); + details->takeItem(old); + } +// QMapIterator it1 = item->groups.begin() ; +// for ( ; it1 != item->groups.end(); ++it1 ) +// { +// // After AddTargetDialog, it can happen that an +// // item is not yet in the list view, so better check... +// if ( it1.data() ->parent() ) +// while ( it1.data() ->firstChild() ) +// it1.data() ->takeItem( it1.data() ->firstChild() ); +// details->takeItem( it1.data() ); +// } + } +} + +void TrollProjectWidget::buildProjectDetailTree( QMakeScopeItem *item, KListView *listviewControl ) +{ + + // Insert all GroupItems and all of their children into the view + if ( !listviewControl || item->scope->variableValues( "TEMPLATE" ).findIndex("subdirs") != -1 ) + return ; + + QMapIterator it2 = item->groups.begin(); + QListViewItem* lastItem = 0; + for ( ; it2 != item->groups.end(); ++it2 ) + { + listviewControl->insertItem( it2.data() ); + if(lastItem) + it2.data()->moveItem(lastItem); + lastItem = it2.data(); + if ( it2.key() == GroupItem::InstallRoot ) + { + QListViewItem* lastinstallitem = 0; + QPtrListIterator it3( it2.data() ->installs ); + for ( ; it3.current(); ++it3 ) + { + it2.data() ->insertItem( *it3 ); + if ( lastinstallitem ) + it3.current()->moveItem(lastinstallitem); + lastinstallitem = it3.current(); + QPtrListIterator it4( ( *it3 ) ->files ); + QListViewItem* lastfileitem = 0; + for ( ; it4.current(); ++it4 ) + { + ( *it3 ) ->insertItem( *it4 ); + if ( lastfileitem ) + it4.current()->moveItem(lastfileitem); + lastfileitem = it4.current(); + } + ( *it3 ) ->setOpen( true ); + ( *it3 ) ->sortChildItems( 0, true ); + } + it2.data() ->setOpen( true ); + it2.data() ->sortChildItems( 0, true ); + } + else + { + QPtrListIterator it3( it2.data() ->files ); + QListViewItem* lastfileitem = 0; + for ( ; it3.current(); ++it3 ) + { + it2.data() ->insertItem( *it3 ); + if ( lastfileitem ) + it3.current()->moveItem(lastfileitem); + lastfileitem = it3.current(); + } + it2.data() ->setOpen( true ); + it2.data() ->sortChildItems( 0, true ); + } + } + listviewControl->setSelected( listviewControl->selectedItem(), false ); + listviewControl->setCurrentItem( 0 ); +} + +void TrollProjectWidget::slotDetailsExecuted( QListViewItem *item ) +{ + if ( !item ) + return ; + + // We assume here that ALL items in both list views + // are qProjectItem's + qProjectItem *pvitem = static_cast( item ); + if ( pvitem->type() != qProjectItem::File ) + return ; + + FileItem *fitem = static_cast( pvitem ); + + QString filePath; + if( m_shownSubproject->scope->scopeType() == Scope::IncludeScope ) + { + filePath = m_shownSubproject->scope->parent()->projectDir(); + }else + { + filePath = m_shownSubproject->scope->projectDir(); + } + filePath += QChar( QDir::separator() ) + m_shownSubproject->scope->resolveVariables( fitem->localFilePath ); + + bool isUiFile = QFileInfo( fitem->text( 0 ) ).extension() == "ui"; + kdDebug(9024) << "Opening file: " << filePath << endl; + if ( isTMakeProject() && isUiFile ) + { + // start designer in your PATH + KShellProcess proc; + proc << "designer" << filePath; + proc.start( KProcess::DontCare, KProcess::NoCommunication ); + } + else + m_part->partController() ->editDocument( KURL( filePath ) ); +} + + +void TrollProjectWidget::slotConfigureProject() +{ + m_configDlg->updateSubproject( m_shownSubproject ); + m_configDlg->show(); +} + +void TrollProjectWidget::slotExecuteTarget() +{ + //m_part->slotExecute(); + // no subproject selected + if ( !m_shownSubproject ) + return ; + + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + + + + // Only run application projects + if ( !m_shownSubproject->scope->variableValues( "TEMPLATE" ).isEmpty() && m_shownSubproject->scope->variableValues( "TEMPLATE" ).findIndex( "app" ) == -1 ) + return ; + + //only run once + if (m_part->appFrontend()->isRunning()) + { + if (KMessageBox::questionYesNo(this, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) + return; + m_part->appFrontend()->stopApplication(); + while(m_part->appFrontend()->isRunning()) + { + KApplication::kApplication()->processEvents(); + usleep(100); + } + } + + + QString program = KProcess::quote( "." + QString( QChar( QDir::separator() ) ) + getCurrentOutputFilename() ); + + // Build environment variables to prepend to the executable path + QString runEnvVars = QString::null; + DomUtil::PairList list = + DomUtil::readPairListEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/envvars", "envvar", "name", "value" ); + + DomUtil::PairList::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) + { + const DomUtil::Pair &pair = ( *it ); + if ( ( !pair.first.isEmpty() ) && ( !pair.second.isEmpty() ) ) + runEnvVars += pair.first + "=" + pair.second + " "; + } + program.prepend( runEnvVars ); + + program.append( " " + m_part->runArguments() + " " ); + // std::cerr<execute(dircmd + "./"+program); + // m_part->appFrontend()->startAppCommand(dircmd +"./"+program,true); + + bool inTerminal = DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/run/terminal" ); + + m_part->appFrontend() ->startAppCommand( subprojectDirectory() + QString( QChar( QDir::separator() ) ) + getCurrentDestDir(), program, inTerminal ); + +} + +void TrollProjectWidget::slotBuildProject() +{ + if ( m_part->partController() ->saveAllFiles() == false ) + return ; //user cancelled + + QString dir = projectDirectory(); + + if ( !m_rootSubproject ) + return ; + + createMakefileIfMissing( dir, m_rootSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_rootSubproject->scope ); + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotInstallProject() +{ + if ( m_part->partController() ->saveAllFiles() == false ) + return ; //user cancelled + + QString dir = projectDirectory(); + + if ( !m_rootSubproject ) + return ; + + createMakefileIfMissing( dir, m_rootSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_rootSubproject->scope ) + " install"; + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotBuildTarget() +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !m_shownSubproject ) + return ; + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + QString dir = subprojectDirectory(); + createMakefileIfMissing( dir, m_shownSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_shownSubproject->scope ); + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotInstallTarget() +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !m_shownSubproject ) + return ; + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + QString dir = subprojectDirectory(); + createMakefileIfMissing( dir, m_shownSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString buildcmd = constructMakeCommandLine( m_shownSubproject->scope ) + " install"; + m_part->queueCmd( dir, dircmd + buildcmd ); +} + +void TrollProjectWidget::slotRebuildProject() +{ + m_part->partController() ->saveAllFiles(); + QString dir = this-> projectDirectory(); + + if ( !m_rootSubproject ) + return ; + + createMakefileIfMissing( dir, m_rootSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString rebuildcmd = constructMakeCommandLine( m_rootSubproject->scope ) + " clean && " + constructMakeCommandLine( m_rootSubproject->scope ); + m_part->queueCmd( dir, dircmd + rebuildcmd ); +} + +void TrollProjectWidget::slotRebuildTarget() +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !m_shownSubproject ) + return ; + // can't build from scope + if ( m_shownSubproject->scope->scopeType() != Scope::ProjectScope ) + return ; + + QString dir = subprojectDirectory(); + createMakefileIfMissing( dir, m_shownSubproject ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString rebuildcmd = constructMakeCommandLine( m_shownSubproject->scope ) + " clean && " + constructMakeCommandLine( m_shownSubproject->scope ); + m_part->queueCmd( dir, dircmd + rebuildcmd ); +} + +void TrollProjectWidget::slotCreateScope( QMakeScopeItem *spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else + spitem = m_shownSubproject; + CreateScopeDlg dlg( spitem, this ); + if ( dlg.exec() == QDialog::Accepted ) + { + spitem->scope->saveToFile( ); + spitem->sortChildItems( 0, true ); + } + return ; +} + +void TrollProjectWidget::slotAddSubproject( QMakeScopeItem *spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else + spitem = m_shownSubproject; + + m_filesCached = false; + m_allFilesCache.clear(); + + QString projectdir = spitem->scope->projectDir(); + + KURLRequesterDlg dialog( i18n( "Add Subproject" ), i18n( "Please enter a name for the subproject: " ), this, 0 ); + KURLRequester* req = dialog.urlRequester(); + req->setMode( KFile::Directory | KFile::File | KFile::LocalOnly ); + req->setFilter( "*.pro|QMake Project Files (*.pro)" ); + req->setURL( QString() ); + req->fileDialog()->setURL( KURL::fromPathOrURL( projectdir ) ); + req->completionObject() ->setDir( projectdir ); + + if ( dialog.exec() == QDialog::Accepted && !dialog.urlRequester() ->url().isEmpty() ) + { + QString subdirname; + if ( !QDir::isRelativePath( dialog.urlRequester() ->url() ) ) + subdirname = URLUtil::getRelativePath( projectdir, dialog.urlRequester()->url() ); + else + subdirname = dialog.urlRequester()->url(); + + while( subdirname.endsWith( QString(QChar(QDir::separator())) ) ) + subdirname = subdirname.left(subdirname.length()-1); + if( !subdirname.endsWith(".pro") ) + { + kdDebug(9024) << "Cleaned subdirname: " << subdirname << endl; + QDir dir( projectdir ); + QString realdir = spitem->scope->resolveVariables( subdirname ); + if ( !dir.exists( realdir ) ) + { + if ( !dir.mkdir( realdir ) ) + { + KMessageBox::error( this, i18n( "Failed to create subdirectory. " + "Do you have write permission " + "in the project folder?" ) ); + return ; + }else + { + QFile f( dir.absPath()+"/"+realdir+"/"+realdir+".pro" ); + f.open( IO_WriteOnly ); + f.close(); + } + } + }else + { + QString realdir = spitem->scope->resolveVariables( subdirname ); + QFile f( projectdir+"/"+realdir ); + f.open( IO_WriteOnly ); + f.close(); + } + + addSubprojectToItem( spitem, subdirname ); + + } +} + +void TrollProjectWidget::addSubprojectToItem( QMakeScopeItem* spitem, const QString& subdirname ) +{ + QListViewItem* item = spitem->firstChild(); + while( item ) + { + QMakeScopeItem* sitem = static_cast(item); + if( sitem->scope->scopeName() == subdirname ) + { + if( sitem->scope->isEnabled() ) + { + return; + }else + { + spitem->scope->removeFromMinusOp( "SUBDIRS", subdirname ); + delete item; + if( spitem->scope->variableValues( "SUBDIRS" ).findIndex( subdirname ) != -1 ) + return; + } + } + item = item->nextSibling(); + } + + Scope* subproject = spitem->scope->createSubProject( subdirname ); + if( subproject ) + { + new QMakeScopeItem( spitem, subproject->scopeName(), subproject ); +// QListViewItem* lastitem = spitem->firstChild(); +// while( lastitem->nextSibling() != 0 ) +// lastitem = lastitem->nextSibling(); +// newitem->moveItem( lastitem ); + }else + { + KMessageBox::error(this, i18n("Could not create subproject. This means that either the project you wanted" + " to add a subproject to is not parsed correctly, or it is not a" + " subdirs-project."), i18n("Subproject creation failed") ); + } + spitem->scope->saveToFile(); + spitem->sortChildItems( 0, true ); +} + +void TrollProjectWidget::slotRemoveSubproject( QMakeScopeItem *spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else if ( ( spitem = dynamic_cast( m_shownSubproject->parent() ) ) != NULL ) + { + + m_filesCached = false; + m_allFilesCache.clear(); + + bool delsubdir = false; + if ( KMessageBox::warningYesNo( this, i18n( "Delete the file/directory of the subproject from disk?" ), i18n( "Delete subdir?" ) ) == KMessageBox::Yes ) + delsubdir = true; + if( !spitem->scope->deleteSubProject( m_shownSubproject->scope->getNum(), delsubdir ) ) + { + KMessageBox::error(this, i18n("Could not delete subproject.\nThis is an internal error, please write a" + " bug report to bugs.kde.org and include the output of kdevelop when run" + "from a shell."),i18n("Subproject Deletion failed")); + return; + } + delete m_shownSubproject; + m_shownSubproject = spitem; + spitem->scope->saveToFile( ); + overview->setCurrentItem( m_shownSubproject ); + overview->setSelected( m_shownSubproject, true ); + } +} + +void TrollProjectWidget::slotOverviewContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return ; + + QMakeScopeItem *spitem = static_cast( item ); + + KPopupMenu popup( this ); + popup.insertTitle( i18n( "Subproject %1" ).arg( item->text( 0 ) ) ); + + int idBuild = -2; + int idRebuild = -2; + int idClean = -2; + int idInstall = -2; + int idDistClean = -2; + int idQmake = -2; + int idQmakeRecursive = -2; + int idProjectConfiguration = -2; + int idAddSubproject = -2; + int idRemoveSubproject = -2; + int idDisableSubproject = -2; + int idRemoveScope = -2; + int idAddScope = -2; + + + if ( spitem->scope->scopeType() == Scope::ProjectScope && ( !spitem->scope->parent() || spitem->scope->parent()->scopeType() == Scope::ProjectScope ) ) + { + idBuild = popup.insertItem( SmallIcon( "make_kdevelop" ), i18n( "Build" ) ); + popup.setWhatsThis( idBuild, i18n( "Build

Runs make from the selected subproject directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + idInstall = popup.insertItem( i18n( "Install" ) ); + popup.setWhatsThis( idBuild, i18n( "Install

Runs make install from the selected subproject directory.
" + "Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + idClean = popup.insertItem( i18n( "Clean" ) ); + popup.setWhatsThis( idBuild, i18n( "Clean project

Runs make clean command from the project " + "directory.
Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + idDistClean = popup.insertItem( i18n( "Dist-Clean" ) ); + popup.setWhatsThis( idBuild, i18n( "Dist-Clean project

Runs make distclean command from the project " + "directory.
Environment variables and make arguments can be specified " + "in the project settings dialog, Make Options tab." ) ); + + idRebuild = popup.insertItem( SmallIcon( "rebuild" ), i18n( "Rebuild" ) ); + popup.setWhatsThis( idRebuild, i18n( "Rebuild project

Runs make clean and then make from " + "the project directory.
Environment variables and make arguments can be " + "specified in the project settings dialog, Make Options tab." ) ); + idQmake = popup.insertItem( SmallIcon( "qmakerun" ), i18n( "Run qmake" ) ); + popup.setWhatsThis( idQmake, i18n( "Run qmake

Runs qmake from the selected subproject directory. This creates or regenerates Makefile." ) ); + idQmakeRecursive = popup.insertItem( SmallIcon( "qmakerun" ), i18n( "Run qmake recursively" ) ); + popup.setWhatsThis( idQmakeRecursive, i18n( "Run qmake recursively

Runs qmake from the selected " + "subproject directory and recurses into all subproject directories. " + "This creates or regenerates Makefile." ) ); + + popup.insertSeparator(); + idAddSubproject = popup.insertItem( SmallIcon( "folder_new" ), i18n( "Add Subproject..." ) ); + popup.setWhatsThis( idAddSubproject, i18n( "Add subproject

Creates a new or adds an existing subproject to a currently selected subproject. " + "This action is allowed only if a type of the subproject is 'subdirectories'. The type of the subproject can be " + "defined in Subproject Settings dialog (open it from the subproject context menu)." ) ); + if ( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) + popup.setItemEnabled( idAddSubproject, false ); + idRemoveSubproject = popup.insertItem( SmallIcon( "remove_subdir" ), i18n( "Remove Subproject..." ) ); + popup.setWhatsThis( idRemoveSubproject, i18n( "Remove subproject

Removes currently selected subproject. Does not delete any file from disk. Deleted subproject can be later added by calling 'Add Subproject' action." ) ); + if ( spitem->parent() == NULL ) + popup.setItemEnabled( idRemoveSubproject, false ); + idAddScope = popup.insertItem( SmallIcon( "qmake_scopenew" ), i18n( "Create Scope..." ) ); + popup.setWhatsThis( idAddScope, i18n( "Create scope

Creates QMake scope in the project file of the currently selected subproject." ) ); + popup.insertSeparator(); + idProjectConfiguration = popup.insertItem( SmallIcon( "configure" ), i18n( "Subproject Settings" ) ); + popup.setWhatsThis( idProjectConfiguration, i18n( "Subproject settings

Opens QMake Subproject Configuration dialog. " + "It provides settings for:
subproject type and configuration,
include and library paths,
lists of dependencies and " + "external libraries,
build order,
intermediate files locations,
compiler options." ) ); + } + else + { + idAddScope = popup.insertItem( SmallIcon( "qmake_scopenew" ), i18n( "Create Scope..." ) ); + popup.setWhatsThis( idAddScope, i18n( "Create Scope

Creates QMake scope in the currently selected scope." ) ); + idRemoveScope = popup.insertItem( SmallIcon( "editdelete" ), i18n( "Remove Scope" ) ); + popup.setWhatsThis( idRemoveScope, i18n( "Remove Scope

Removes currently selected scope." ) ); + popup.insertSeparator(); + idAddSubproject = popup.insertItem( SmallIcon( "folder_new" ), i18n( "Add Subproject..." ) ); + popup.setWhatsThis( idAddSubproject, i18n( "Add subproject

Creates a new or adds an existing subproject to the currently selected scope. " + "This action is allowed only if the type of the subproject is 'subdirectories'. The type of the subproject can be " + "defined in the Subproject Settings dialog (open it from the subproject context menu)." ) ); + if ( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) + popup.setItemEnabled( idAddSubproject, false ); + idDisableSubproject = popup.insertItem( SmallIcon( "remove_subdir" ), i18n( "Disable Subproject..." ) ); + popup.setWhatsThis( idRemoveSubproject, i18n( "Disable subproject

Disables the currently selected subproject when this scope is active. Does not delete the directory from disk. The deleted subproject can be later added by using the 'Add Subproject' action." ) ); + if( spitem->scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 && spitem->scope->parent()->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) == -1 ) + popup.setItemEnabled( idDisableSubproject, false ); + popup.insertSeparator(); + idProjectConfiguration = popup.insertItem( SmallIcon( "configure" ), i18n( "Scope Settings" ) ); + popup.setWhatsThis( idProjectConfiguration, i18n( "Scope settings

Opens QMake Subproject Configuration dialog. " + "It provides settings for:
subproject type and configuration,
include and library paths,
lists of dependencies and " + "external libraries,
build order,
intermediate files locations,
compiler options." ) ); + } + + int r = popup.exec( p ); + + QString relpath = spitem->relativePath(); + if ( r == idAddSubproject ) + { + slotAddSubproject( spitem ); + } + if ( r == idRemoveSubproject ) + { + slotRemoveSubproject( spitem ); + } + if ( r == idDisableSubproject ) + { + slotDisableSubproject( spitem ); + } + if ( r == idAddScope ) + { + slotCreateScope( spitem ); + } + else if ( r == idRemoveScope ) + { + slotRemoveScope( spitem ); + } + else if ( r == idBuild ) + { + slotBuildTarget(); + // m_part->startMakeCommand(projectDirectory() + relpath, QString::fromLatin1("")); + } + else if ( r == idInstall ) + { + slotInstallTarget(); + // m_part->startMakeCommand(projectDirectory() + relpath, QString::fromLatin1("")); + } + else if ( r == idRebuild ) + { + slotRebuildTarget(); + } + else if ( r == idClean ) + { + slotCleanTarget(); + } + else if ( r == idDistClean ) + { + slotDistCleanTarget(); + } + + else if ( r == idQmake ) + { + m_part->startQMakeCommand( projectDirectory() + QString(QChar(QDir::separator())) + relpath ); + } + else if ( r == idQmakeRecursive ) + { + runQMakeRecursive( spitem ); + } + + else if ( r == idProjectConfiguration ) + { + m_configDlg->updateSubproject( spitem ); + m_configDlg->show(); + } +} + +void TrollProjectWidget::addFileToCurrentSubProject( GroupItem *titem, const QString &filename ) +{ + + m_filesCached = false; + m_allFilesCache.clear(); + titem->addFileToScope( filename ); +} + +void TrollProjectWidget::addFileToCurrentSubProject( GroupItem::GroupType gtype, const QString &filename ) +{ + if ( !m_shownSubproject ) + return ; + + m_filesCached = false; + m_allFilesCache.clear(); + + GroupItem *gitem = 0; + + if ( m_shownSubproject->groups.contains( gtype ) ) + gitem = m_shownSubproject->groups[ gtype ]; + + if ( !gitem ) + return ; + + gitem->addFileToScope( filename ); +} + +/** +* Method adds a file to the current project by grouped +* by file extension +*/ +void TrollProjectWidget::addFiles( QStringList &files, bool relativeToProjectRoot ) +{ + if ( !m_shownSubproject ) + return ; + kdDebug(9024) << "Files to add:"<scope->variableValues( "TEMPLATE" ).findIndex( "subdirs" ) != -1 && !fileName.endsWith(".pro") ) + { + ChooseSubprojectDlg dlg( this, false ); + if ( dlg.exec() == QDialog::Accepted ) + { + if ( dlg.selectedSubproject() && dlg.selectedSubproject()->scope->variableValues("TEMPLATE").findIndex( "subdirs" ) != -1 ) + { + fileName = URLUtil::getRelativePath( dlg.selectedSubproject()->scope->projectDir() , + QDir::cleanDirPath( + m_shownSubproject->scope->projectDir()+ + QString(QChar(QDir::separator()))+ + fileName ) ); + overview->setCurrentItem( dlg.selectedSubproject() ); + + } + } + else + { + KMessageBox::error( this, i18n("You did not select a subproject to add the file to, or select a subproject that has subdirs."), i18n( "File adding aborted" ) ); + } + } + + QFileInfo info( fileName ); + QString ext = info.extension( false ).simplifyWhiteSpace(); + + QString noPathFileName; + if( relativeToProjectRoot ) + noPathFileName = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), QDir::cleanDirPath(projectDirectory()+QString(QChar(QDir::separator()))+fileName ) ); + else + noPathFileName = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), QDir::cleanDirPath(m_shownSubproject->scope->projectDir()+QString(QChar(QDir::separator()))+fileName ) ); + + if( DomUtil::readBoolEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/replacePaths", false ) ) + { + QString var = m_shownSubproject->scope->findCustomVarForPath( QFileInfo( noPathFileName ).dirPath() ); + if( !var.isEmpty() ) + { + noPathFileName = "$${"+var+"}"+QString( QChar( QDir::separator() ) )+QFileInfo( noPathFileName ).fileName(); + } + } + + kdDebug(9024) << "calc filename:" << noPathFileName << endl; +// GroupItem *gitem = 0; +// GroupItem::GroupType gtype = GroupItem::groupTypeForExtension( ext ); +// if ( m_shownSubproject->groups.contains( gtype ) ) +// gitem = m_shownSubproject->groups[ gtype ]; + + + if( ext == "pro" ) + { + addSubprojectToItem( findSubprojectForPath( QFileInfo( fileName ).dirPath() ), QFileInfo( fileName ).fileName() ); + }else + { + addFileToCurrentSubProject( GroupItem::groupTypeForExtension( ext ), noPathFileName ); + slotOverviewSelectionChanged( m_shownSubproject ); + kdDebug(9024) << "emitting" << relativeToProjectRoot << " " << fileName << endl; + if( relativeToProjectRoot ) + emitAddedFile ( projectDirectory()+QString( QChar( QDir::separator() ) ) + fileName ); + else + emitAddedFile ( m_shownSubproject->scope->projectDir()+QString( QChar( QDir::separator() ) ) + fileName ); + } + } + +} + + +void TrollProjectWidget::slotAddFiles() +{ + static KURL lastVisited; + QString cleanSubprojectDir = QDir::cleanDirPath( m_shownSubproject->scope->projectDir() ); + QString title, filter; + QString otherTitle, otherFilter; + + GroupItem* item = dynamic_cast( details->selectedItem() ); + GroupItem::GroupType type = item ? item->groupType : GroupItem::NoType; + GroupItem::groupTypeMeanings( type, title, filter ); + filter += "|" + title; + + m_filesCached = false; + m_allFilesCache.clear(); + + for ( int i = GroupItem::NoType + 1; i < GroupItem::MaxTypeEnum; ++i ) + { + if ( type != i ) + { + GroupItem::groupTypeMeanings( static_cast( i ), otherTitle, otherFilter ); + filter += "\n" + otherFilter + "|" + otherTitle; + } + } + + filter += "\n*|" + i18n( "All Files" ); + + AddFilesDialog *dialog = new AddFilesDialog( cleanSubprojectDir, + filter, + this, + "Insert existing files", + true, new QComboBox( false ) ); + + dialog->setMode( KFile::Files | KFile::ExistingOnly | KFile::LocalOnly ); + + if ( !lastVisited.isEmpty() ) + { + dialog->setURL( lastVisited ); + } + + dialog->exec(); + QStringList files = dialog->selectedFiles(); + lastVisited = dialog->baseURL(); + + for ( unsigned int i = 0; i < files.count(); i++ ) + { + switch ( dialog->mode() ) + { + case AddFilesDialog::Copy: + { + // Copy selected files to current subproject folder + // and add them to the filelist + QString filename = KURL( files[ i ] ).fileName(); + KIO::NetAccess::file_copy( files[ i ], cleanSubprojectDir + QString( QChar( QDir::separator() ) ) + filename, -1, false, false, this ); + QFile testExist( cleanSubprojectDir + QString( QChar( QDir::separator() ) ) + filename ); + + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Link: + { + // Link selected files to current subproject folder + KProcess *proc = new KProcess( this ); + *proc << "ln"; + *proc << "-s"; + *proc << files[ i ]; + *proc << cleanSubprojectDir; + proc->start(KProcess::Block); + QString filename = files[ i ].right( files[ i ].length() - files[ i ].findRev( '/' ) - 1 ); + // and add them to the filelist + QFile testExist( cleanSubprojectDir + QString( QChar( QDir::separator() ) ) + filename ); + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Relative: + { + // Form relative path to current subproject folder + QString theFile = files[ i ]; + QStringList files( URLUtil::relativePathToFile( cleanSubprojectDir , theFile ) + ); + addFiles( files, false ); + } + break; + } + } +} + +GroupItem* TrollProjectWidget::getInstallRoot( QMakeScopeItem* item ) +{ + if ( item->groups.contains( GroupItem::InstallRoot ) ) + return item->groups[ GroupItem::InstallRoot ]; + return 0; +} + +GroupItem* TrollProjectWidget::getInstallObject( QMakeScopeItem* item, const QString& objectname ) +{ + GroupItem * instroot = getInstallRoot( item ); + if ( !instroot ) + return 0; + QPtrListIterator it( instroot->installs ); + for ( ;it.current();++it ) + { + if ( ( *it ) ->groupType == GroupItem::InstallObject && + ( *it ) ->text( 0 ) == objectname ) + return * it; + } + return 0; + +} + +void TrollProjectWidget::slotNewFile() +{ + GroupItem * gitem = dynamic_cast( details->currentItem() ); + + m_filesCached = false; + m_allFilesCache.clear(); + + if( !gitem ) + { + gitem = dynamic_cast( details->currentItem()->parent() ); + } + + if ( gitem ) + { + if ( gitem->groupType == GroupItem::InstallObject ) + { + // QString relpath = m_shownSubproject->path.mid(projectDirectory().length()); + bool ok = FALSE; + QString filepattern = KInputDialog::getText( + i18n( "Insert New Filepattern" ), + i18n( "Please enter a filepattern relative the current " + "subproject (example docs/*.html):" ), + QString::null, &ok, this ); + if ( ok && !filepattern.isEmpty() ) + { + addFileToCurrentSubProject( gitem, filepattern ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + return ; + } + if ( gitem->groupType == GroupItem::InstallRoot ) + { + // QString relpath = m_shownSubproject->path.mid(projectDirectory().length()); + bool ok = FALSE; + QString install_obj = KInputDialog::getText( + i18n( "Insert New Install Object" ), + i18n( "Please enter a name for the new object:" ), + QString::null, &ok, this ); + if ( ok && !install_obj.isEmpty() ) + { + gitem->addInstallObject( install_obj ); + //GroupItem * institem = createGroupItem( GroupItem::InstallObject, install_obj , m_shownSubproject ); + //gitem->owner->scope->addToPlusOp("INSTALLS", install_obj); + gitem->owner->scope->saveToFile(); + slotOverviewSelectionChanged( m_shownSubproject ); + } + return ; + } + } + KDevCreateFile * createFileSupport = m_part->extension( "KDevelop/CreateFile" ); + QString fcext; + if( gitem ) + { + switch ( gitem->groupType ) + { + case GroupItem::Sources: + fcext = "cpp"; + break; + case GroupItem::Headers: + fcext = "h"; + break; + case GroupItem::Forms: + if ( !m_part->isQt4Project() ) + fcext = "ui-widget"; + else + fcext = "ui-widget-qt4"; + break; + case GroupItem::Translations: + fcext = "ts"; + break; + case GroupItem::Lexsources: + fcext = "l"; + break; + case GroupItem::Yaccsources: + fcext = "y"; + break; + case GroupItem::Resources: + fcext = "qrc"; + break; + default: + fcext = QString::null; + } + } + KDevCreateFile::CreatedFile crFile = + createFileSupport->createNewFile( fcext, projectDirectory() + QString(QChar(QDir::separator()))+ m_shownSubproject->relativePath() ); +} + +void TrollProjectWidget::slotRemoveFile() +{ + QListViewItem * selectedItem = details->currentItem(); + if ( !selectedItem ) + return ; + + m_filesCached = false; + m_allFilesCache.clear(); + + qProjectItem *pvitem = static_cast( selectedItem ); + // Check that it is a file (just in case) + if ( pvitem->type() != qProjectItem::File ) + return ; + FileItem *fitem = static_cast( pvitem ); + removeFile( m_shownSubproject, fitem ); +} + +void TrollProjectWidget::slotExcludeFileFromScopeButton() +{ + QListViewItem * selectedItem = details->currentItem(); + if ( !selectedItem ) + return ; + qProjectItem *pvitem = static_cast( selectedItem ); + // Check that it is a file (just in case) + if ( pvitem->type() != qProjectItem::File ) + return ; + FileItem *fitem = static_cast( pvitem ); + + GroupItem *gitem = static_cast( fitem->parent() ); + + gitem->removeFileFromScope( fitem->text( 0 ) ); +} + +void TrollProjectWidget::slotDetailsSelectionChanged( QListViewItem *item ) +{ + if ( !item ) + { + removefileButton->setEnabled( false ); + excludeFileFromScopeButton->setEnabled( false ); + return ; + } + removefileButton->setEnabled( false ); + excludeFileFromScopeButton->setEnabled( false ); + + qProjectItem *pvitem = static_cast( item ); + if ( pvitem->type() == qProjectItem::Group ) + { + GroupItem * gitem = static_cast( item ); + if ( gitem->groupType == GroupItem::InstallObject ) + { + excludeFileFromScopeButton->setEnabled( true ); + newfileButton->setEnabled( true ); + } + else if ( gitem->groupType == GroupItem::InstallRoot ) + { + newfileButton->setEnabled( true ); + } + else + { + addfilesButton->setEnabled( true ); + newfileButton->setEnabled( true ); + } + + + } + else if ( pvitem->type() == qProjectItem::File ) + { + removefileButton->setEnabled( true ); + excludeFileFromScopeButton->setEnabled( true ); + /* buildTargetButton->setEnabled(true); + rebuildTargetButton->setEnabled(true); + executeTargetButton->setEnabled(true);*/ + } +} + +void TrollProjectWidget::slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ) +{ + if ( !item ) + return ; + + qProjectItem *pvitem = static_cast( item ); + if ( pvitem->type() == qProjectItem::Group ) + { + GroupItem * titem = static_cast( pvitem ); + QString title, ext; + GroupItem::groupTypeMeanings( titem->groupType, title, ext ); + + KPopupMenu popup( this ); + popup.insertTitle( title ); + + int idInsExistingFile = -2; + int idInsNewFile = -2; + int idInsInstallObject = -2; + int idInsNewFilepatternItem = -2; + int idSetInstObjPath = -2; + int idLUpdate = -2; + int idLRelease = -2; + int idRemoveFile = -2; + + // int idFileProperties = popup.insertItem(SmallIconSet("filenew"),i18n("Properties...")); + if ( titem->groupType == GroupItem::InstallRoot ) + { + idInsInstallObject = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Install Object..." ) ); + popup.setWhatsThis( idInsInstallObject, i18n( "Add install object

Creates QMake install object. " + "It is possible to define a list of files to install and installation locations for each object. Warning! " + "Install objects without path specified will not be saved to a project file." ) ); + } + else if ( titem->groupType == GroupItem::InstallObject ) + { + idSetInstObjPath = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Install Path..." ) ); + popup.setWhatsThis( idSetInstObjPath, i18n( "Install path

Allows to choose the installation path for the current install object." ) ); + idInsNewFilepatternItem = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Pattern of Files to Install..." ) ); + popup.setWhatsThis( idInsNewFilepatternItem, i18n( "Add pattern of files to install

Defines the pattern to match files which will be installed. " + "It is possible to use wildcards and relative paths like docs/*." ) ); + idRemoveFile = popup.insertItem( SmallIconSet( "editdelete" ), i18n( "Remove Install Object" ) ); + popup.setWhatsThis( idRemoveFile, i18n( "Remove install object

Removes the install object the current group." ) ); + } + else if ( titem->groupType == GroupItem::Translations ) + { + idInsNewFile = popup.insertItem( SmallIconSet( "filenew" ), i18n( "Create New File..." ) ); + popup.setWhatsThis( idInsNewFile, i18n( "Create new file

Creates a new translation file and adds it to a currently selected TRANSLATIONS group." ) ); + idInsExistingFile = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Existing Files..." ) ); + popup.setWhatsThis( idInsExistingFile, i18n( "Add existing files

Adds existing translation (*.ts) files to a currently selected TRANSLATIONS group. It is " + "possible to copy files to a current subproject directory, create symbolic links or " + "add them with the relative path." ) ); + idLUpdate = popup.insertItem( SmallIconSet( "konsole" ), i18n( "Update Translation Files" ) ); + popup.setWhatsThis( idLUpdate, i18n( "Update Translation Files

Runs lupdate command from the current subproject directory. It collects translatable " + "messages and saves them into translation files." ) ); + idLRelease = popup.insertItem( SmallIconSet( "konsole" ), i18n( "Release Binary Translations" ) ); + popup.setWhatsThis( idLRelease, i18n( "Release Binary Translations

Runs lrelease command from the current subproject directory. It creates binary " + "translation files that are ready to be loaded at program execution." ) ); + } + else // File group containing files + { + idInsNewFile = popup.insertItem( SmallIconSet( "filenew" ), i18n( "Create New File..." ) ); + popup.setWhatsThis( idInsNewFile, i18n( "Create new file

Creates a new file and adds it to a currently selected group." ) ); + idInsExistingFile = popup.insertItem( SmallIconSet( "fileopen" ), i18n( "Add Existing Files..." ) ); + popup.setWhatsThis( idInsExistingFile, i18n( "Add existing files

Adds existing files to a currently selected group. It is " + "possible to copy files to a current subproject directory, create symbolic links or " + "add them with the relative path." ) ); + } + int r = popup.exec( p ); + QString cleanSubprojectPath = QDir::cleanDirPath( m_shownSubproject->scope->projectDir() ); + + if ( r == idSetInstObjPath ) + { + KURLRequesterDlg dialog( i18n( "Choose Install Path" ), i18n( "Enter a path " + "(example /usr/local/share/... ):" ), this, 0 ); + dialog.urlRequester() ->setMode( KFile::Directory ); + dialog.urlRequester() ->setURL( titem->owner->scope->variableValues( titem->text( 0 ) + ".path" ).front() ); + if ( dialog.exec() == QDialog::Accepted ) + { + titem->owner->scope->setEqualOp( titem->text( 0 ) + ".path", dialog.urlRequester() ->url() ); + titem->owner->scope->saveToFile( ); + } + } + else if ( r == idInsNewFilepatternItem ) + { + bool ok = FALSE; + QString filepattern = KInputDialog::getText( + i18n( "Add Pattern of Files to Install" ), + i18n( "Enter a pattern relative to the current " + "subproject (example docs/*.html):" ), + QString::null, &ok, this ); + if ( ok && !filepattern.isEmpty() ) + { + addFileToCurrentSubProject( titem, filepattern ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( r == idInsExistingFile ) + { + AddFilesDialog * dialog = new AddFilesDialog( cleanSubprojectPath, + ext + "|" + title + " (" + ext + ")", + this, + "Add existing files", + true, new QComboBox( false ) ); + dialog->setMode( KFile::Files | KFile::ExistingOnly | KFile::LocalOnly ); + if ( dialog->exec() == QDialog::Rejected ) + return ; + QStringList files = dialog->selectedFiles(); + for ( unsigned int i = 0;i < files.count();++i ) + { + switch ( dialog->mode() ) + { + case AddFilesDialog::Copy: + { + // Copy selected files to current subproject folder + // and add them to the filelist + QString filename = KURL( files[ i ] ).fileName(); + KIO::NetAccess::file_copy( files[ i ], cleanSubprojectPath + QString( QChar( QDir::separator() ) ) + filename, -1, false, false, this ); + QFile testExist( cleanSubprojectPath + QString( QChar( QDir::separator() ) ) + filename ); + + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Link: + { + // Link selected files to current subproject folder + KProcess *proc = new KProcess( this ); + *proc << "ln"; + *proc << "-s"; + *proc << files[ i ]; + *proc << cleanSubprojectPath; + proc->start(KProcess::Block); + QString filename = files[ i ].right( files[ i ].length() - files[ i ].findRev( '/' ) - 1 ); + // and add them to the filelist + QFile testExist( cleanSubprojectPath + QString( QChar( QDir::separator() ) ) + filename ); + if ( testExist.exists() ) + { + QStringList files( filename ); + addFiles( files, false ); + } + } + break; + + case AddFilesDialog::Relative: + { + // Form relative path to current subproject folder + QString theFile = files[ i ]; + QStringList files( URLUtil::relativePathToFile( cleanSubprojectPath, theFile ) + ); + addFiles( files, false ); + } + break; + } + } + // Update project file + if ( titem && titem->owner ) + { + titem->owner->scope->saveToFile( ); + } + // Update subprojectview + slotOverviewSelectionChanged( m_shownSubproject ); + } + else if ( r == idInsNewFile ) + { + KDevCreateFile * createFileSupport = m_part->extension( "KDevelop/CreateFile" ); + QString fcext; + switch ( titem->groupType ) + { + case GroupItem::Sources: + fcext = "cpp"; + break; + case GroupItem::Headers: + fcext = "h"; + break; + case GroupItem::Forms: + if ( !m_part->isQt4Project() ) + fcext = "ui-widget"; + else + fcext = "ui-widget-qt4"; + break; + case GroupItem::Translations: + fcext = "ts"; + break; + case GroupItem::Lexsources: + fcext = "l"; + break; + case GroupItem::Yaccsources: + fcext = "y"; + break; + case GroupItem::Resources: + fcext = "qrc"; + break; + default: + fcext = QString::null; + } + KDevCreateFile::CreatedFile crFile = + createFileSupport->createNewFile( fcext, cleanSubprojectPath ); + + } + else if ( r == idInsInstallObject ) + { + bool ok = FALSE; + QString install_obj = KInputDialog::getText( + i18n( "Add Install Object" ), + i18n( "Enter a name for the new object:" ), + QString::null, &ok, this ); + if ( ok && !install_obj.isEmpty() ) + { + titem->addInstallObject( install_obj ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( r == idLUpdate ) + { + QString cmd = "lupdate "; + cmd += m_shownSubproject->scope->fileName(); + m_part->appFrontend() ->startAppCommand( m_shownSubproject->scope->projectDir(), cmd, false ); + } + else if ( r == idLRelease ) + { + QString cmd = "lrelease "; + cmd += m_shownSubproject->scope->fileName(); + m_part->appFrontend() ->startAppCommand( m_shownSubproject->scope->projectDir(), cmd, false ); + }else if( r == idRemoveFile ) + { + static_cast(titem->parent())->removeInstallObject( titem ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( pvitem->type() == qProjectItem::File ) + { + + removefileButton->setEnabled( true ); + FileItem *fitem = static_cast( pvitem ); + GroupItem* gitem = static_cast( item->parent() ); + + KPopupMenu popup( this ); + if ( !( gitem->groupType == GroupItem::InstallObject ) ) + popup.insertTitle( i18n( "File: %1" ).arg( fitem->text( 0 ) ) ); + else + popup.insertTitle( i18n( "Pattern: %1" ).arg( fitem->text( 0 ) ) ); + + int idRemoveFile = -2; + int idSubclassWidget = -2; + int idUpdateWidgetclass = -2; + int idBuildFile = -2; + int idUISubclasses = -2; + int idViewUIH = -2; + int idFileProperties = -2; + int idEditInstallPattern = -2; + + if ( !fitem->uiFileLink.isEmpty() ) + { + idUpdateWidgetclass = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "Edit ui-Subclass..." ) ); + popup.setWhatsThis( idUpdateWidgetclass, i18n( "Edit ui-subclass

Launches Subclassing wizard " + "and prompts to implement missing in childclass slots and functions." ) ); + } + if ( fitem->text( 0 ).contains( ".ui" ) ) + { + idSubclassWidget = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "Subclassing Wizard..." ) ); + popup.setWhatsThis( idSubclassWidget, i18n( "Subclass widget

Launches Subclassing wizard. " + "It allows to create a subclass from the class defined in .ui file. " + "There is also possibility to implement slots and functions defined in the base class." ) ); + if ( !m_part->isQt4Project() ) + { + idViewUIH = popup.insertItem( SmallIconSet( "qmake_ui_h" ), i18n( "Open ui.h File" ) ); + popup.setWhatsThis( idViewUIH, i18n( "Open ui.h file

Opens .ui.h file associated with the selected .ui." ) ); + } + idUISubclasses = popup.insertItem( SmallIconSet( "qmake_subclass" ), i18n( "List of Subclasses..." ) ); + popup.setWhatsThis( idUISubclasses, i18n( "List of subclasses

Shows subclasses list editor. " + "There is possibility to add or remove subclasses from the list." ) ); + } + if ( !( gitem->groupType == GroupItem::InstallObject ) ) + { + idRemoveFile = popup.insertItem( SmallIconSet( "editdelete" ), i18n( "Remove File" ) ); + popup.setWhatsThis( idRemoveFile, i18n( "Remove file

Removes file from a current group. For sources, this also removes the subclassing information." ) ); + idFileProperties = popup.insertItem( SmallIconSet( "configure_file" ), i18n( "Exclude File" ) ); + popup.setWhatsThis( idFileProperties, i18n( "Exclude File

Excludes the file from this Scope. Does not touch subclassing information" ) ); + } + else + { + idEditInstallPattern = popup.insertItem( SmallIconSet( "configure_file" ), i18n( "Edit Pattern" ) ); + popup.setWhatsThis( idEditInstallPattern, i18n( "Edit pattern

Allows to edit install files pattern." ) ); + idRemoveFile = popup.insertItem( SmallIconSet( "editdelete" ), i18n( "Remove Pattern" ) ); + popup.setWhatsThis( idRemoveFile, i18n( "Remove pattern

Removes install files pattern from the current install object." ) ); + } + if ( !( gitem->groupType == GroupItem::InstallObject ) ) + { + KURL::List urls; + urls.append( m_shownSubproject->scope->projectDir() + QChar( QDir::separator() ) + m_shownSubproject->scope->resolveVariables( fitem->localFilePath ) ); + FileContext context( urls ); + m_part->core() ->fillContextMenu( &popup, &context ); + } + if ( gitem->groupType == GroupItem::Sources ) + { + idBuildFile = popup.insertItem( SmallIconSet( "make_kdevelop" ), i18n( "Build File" ) ); + popup.setWhatsThis( idBuildFile, i18n( "Build File

Builds the object file for this source file." ) ); + } + + int r = popup.exec( p ); + if ( r == idRemoveFile ) + removeFile( m_shownSubproject, fitem ); + else if ( r == idFileProperties ) + { + slotExcludeFileFromScopeButton(); + } + else if ( r == idViewUIH ) + { + kdDebug(9024) << "Opening:" << fitem->text(0) << ";" << fitem->text(0).replace(".ui","") << endl; + m_part->partController() ->editDocument( KURL( m_shownSubproject->scope->projectDir() + QChar( QDir::separator() ) + + fitem->localFilePath.replace(".ui","") + ".h" ) ); + + } + else if ( r == idSubclassWidget ) + { + QStringList newFileNames; + newFileNames = m_part->languageSupport() ->subclassWidget( m_shownSubproject->scope->projectDir() + QChar( QDir::separator() ) + fitem->localFilePath ); + kdDebug(9024) << "got new filenames: " << newFileNames << endl; + if ( !newFileNames.empty() ) + { + QDomDocument & dom = *( m_part->projectDom() ); + for ( uint i = 0; i < newFileNames.count(); ++i ) + { + QString srcfile_relpath = URLUtil::getRelativePath( m_shownSubproject->scope->projectDir(), newFileNames[ i ] ) ; + newFileNames[i] = URLUtil::getRelativePath( projectDirectory(), newFileNames[ i ] ) ; + QString uifile_relpath = m_shownSubproject->relativePath() + QChar( QDir::separator() ) + fitem->localFilePath; + DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + + list << DomUtil::Pair( srcfile_relpath, uifile_relpath ); + DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); + // newFileNames[i] = newFileNames[i].replace(QRegExp(projectDirectory()+"/"),""); + qWarning( "new file: %s", newFileNames[ i ].latin1() ); + } + m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + + m_part->addFiles( newFileNames ); + } + } + else if ( r == idUpdateWidgetclass ) + { + QString noext = fitem->text( 0 ); + if ( noext.findRev( '.' ) > -1 ) + noext = noext.left( noext.findRev( '.' ) ); + QStringList dummy; + QString uifile = fitem->uiFileLink; + if ( uifile.findRev( QString( QChar( QDir::separator() ) ) ) > -1 ) + { + QStringList uisplit = QStringList::split( QString( QChar( QDir::separator() ) ), uifile ); + uifile = uisplit[ uisplit.count() - 1 ]; + } + m_part->languageSupport() ->updateWidget( m_shownSubproject->scope->projectDir() + QString( QChar( QDir::separator() ) ) + uifile, noext ); + } + else if ( r == idUISubclasses ) + { + QDomDocument & dom = *( m_part->projectDom() ); + DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + SubclassesDlg *sbdlg = new SubclassesDlg( m_shownSubproject->relativePath() + QChar( QDir::separator() ) + fitem->localFilePath, + list, projectDirectory() ); + + if ( sbdlg->exec() ) + { + QDomElement el = DomUtil::elementByPath( dom, "/kdevtrollproject" ); + QDomElement el2 = DomUtil::elementByPath( dom, "/kdevtrollproject/subclassing" ); + if ( ( !el.isNull() ) && ( !el2.isNull() ) ) + { + el.removeChild( el2 ); + } + + DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); + + m_subclasslist = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + } + } + else if ( r == idEditInstallPattern ) + { + GroupItem * titem = static_cast( item->parent() ); + + bool ok = FALSE; + QString filepattern = KInputDialog::getText( + i18n( "Edit Pattern" ), + i18n( "Enter a pattern relative to the current " + "subproject (example docs/*.html):" ), + fitem->text( 0 ) , &ok, this ); + if ( ok && !filepattern.isEmpty() ) + { + removeFile( m_shownSubproject, fitem ); + addFileToCurrentSubProject( titem, filepattern ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } + else if ( r == idBuildFile ) + { + buildFile( m_shownSubproject, fitem ); + } + } +} + + +void TrollProjectWidget::removeFile( QMakeScopeItem *spitem, FileItem *fitem ) +{ + GroupItem * gitem = static_cast( fitem->parent() ); + + m_filesCached = false; + m_allFilesCache.clear(); + + QString realfilename = spitem->scope->resolveVariables( fitem->localFilePath ); + if ( KMessageBox::warningYesNo( this, + "" + + i18n( "Do you want to delete the file %1 from the project and your disk?" ) + .arg( fitem->text( 0 ) ) + + "", + i18n( "Remove File" ), + KStdGuiItem::remove(), + KStdGuiItem::no(), + "deleteFileFromQMakeProject" ) == KMessageBox::No ) + { + return; + }else + { + kdDebug(9024) << "Deleting file as the user wished: " << spitem->scope->projectDir() + QString( QChar( QDir::separator() ) ) + realfilename << endl; + KIO::NetAccess::del( KURL::fromPathOrURL( spitem->scope->projectDir() + QString( QChar( QDir::separator() ) ) + realfilename ), 0 ); + } + + if ( gitem->groupType != GroupItem::InstallObject ) + { + QString removedFileName = spitem->relativePath() + QString( QChar( QDir::separator() ) ) + realfilename; + if ( removedFileName.startsWith( QDir::rootDirPath() ) ) + removedFileName = removedFileName.mid( 1 ); + emitRemovedFile( removedFileName ); + } + + + //remove subclassing info + QDomDocument &dom = *( m_part->projectDom() ); + DomUtil::PairList list = DomUtil::readPairListEntry( dom, "/kdevtrollproject/subclassing" , + "subclass", "sourcefile", "uifile" ); + QPtrList pairsToRemove; + DomUtil::PairList::iterator it; + for ( it = list.begin(); it != list.end(); ++it ) + { + if ( ( ( *it ).first == realfilename ) || ( ( *it ).second == realfilename ) ) + { + pairsToRemove.append( &( *it ) ); + } + } + DomUtil::Pair *pair; + for ( pair = pairsToRemove.first(); pair; pair = pairsToRemove.next() ) + { + list.remove( *pair ); + } + QDomElement el = DomUtil::elementByPath( dom, "/kdevtrollproject" ); + QDomElement el2 = DomUtil::elementByPath( dom, "/kdevtrollproject/subclassing" ); + if ( ( !el.isNull() ) && ( !el2.isNull() ) ) + { + el.removeChild( el2 ); + } + DomUtil::writePairListEntry( dom, "/kdevtrollproject/subclassing", "subclass", "sourcefile", "uifile", list ); + + gitem->removeFileFromScope( fitem->text( 0 ) ); +} + +void TrollProjectWidget::emitAddedFile( const QString &fileName ) +{ + emit m_part->addedFilesToProject( QStringList( fileName ) ); +} + + +void TrollProjectWidget::emitRemovedFile( const QString &fileName ) +{ + emit m_part->removedFilesFromProject( QStringList( fileName ) ); +} + + +QString TrollProjectWidget::getUiFileLink( const QString &relpath, const QString& filename ) +{ + DomUtil::PairList::iterator it; + for ( it = m_subclasslist.begin();it != m_subclasslist.end(); ++it ) + { + if ( ( *it ).first == relpath + filename ) + return ( *it ).second; + } + return ""; +} + +void TrollProjectWidget::slotBuildOpenFile() +{ + KParts::ReadWritePart * part = dynamic_cast( m_part->partController() ->activePart() ); + if ( !part || !part->url().isLocalFile() ) + return ; + + QString fileName = part->url().path(); + QFileInfo fi( fileName ); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName( true ); + kdDebug( 9024 ) << "Compiling " << fileName + << "in dir " << sourceDir + << " with baseName " << baseName << endl; + + + QString buildDir = sourceDir; + QString target = baseName + ".o"; + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + // m_part->startMakeCommand(buildDir, target); + + QPtrList list = findSubprojectForFile( fi ); + + QMakeScopeItem *spitem; + for ( spitem = list.first(); spitem; spitem = list.next() ) + { + QString buildcmd = constructMakeCommandLine( spitem->scope ); + QString dircmd = "cd " + KProcess::quote( spitem->scope->projectDir() ) + " && " ; + kdDebug( 9024 ) << "builddir " << spitem->scope->projectDir() << ", cmd " << dircmd + buildcmd + " " + target << endl; + m_part->queueCmd( spitem->scope->projectDir(), dircmd + buildcmd + " " + target ); + } + + // startMakeCommand(buildDir, target); + +} + + +void TrollProjectWidget::slotExecuteProject() +{ + QString program = m_part->mainProgram(); + if ( program.isEmpty() ) + { + KMessageBox::sorry( this, i18n( "Please specify the executable name in the " + "project options dialog or select an application subproject in the QMake Manager." ), i18n( "No Executable Found" ) ); + return ; + } + + //only run once + if (m_part->appFrontend()->isRunning()) + { + if (KMessageBox::questionYesNo(this, i18n("Your application is currently running. Do you want to restart it?"), i18n("Application Already Running"), i18n("&Restart Application"), i18n("Do &Nothing")) == KMessageBox::No) + return; + m_part->appFrontend()->stopApplication(); + while(m_part->appFrontend()->isRunning()) + { + KApplication::kApplication()->processEvents(); + usleep(100); + } + } + + if ( !program.startsWith( QDir::rootDirPath() ) ) + program.prepend( "." + QString( QChar( QDir::separator() ) ) ); + + + // Build environment variables to prepend to the executable path + QString runEnvVars = QString::null; + DomUtil::PairList list = + DomUtil::readPairListEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/envvars", "envvar", "name", "value" ); + + DomUtil::PairList::ConstIterator it; + for ( it = list.begin(); it != list.end(); ++it ) + { + const DomUtil::Pair &pair = ( *it ); + if ( ( !pair.first.isEmpty() ) && ( !pair.second.isEmpty() ) ) + runEnvVars += pair.first + "=" + pair.second + " "; + } + program.prepend( runEnvVars ); + program.append( " " + m_part->runArguments() + " " ); + + bool inTerminal = DomUtil::readBoolEntry( *( m_part->projectDom() ), "/kdevtrollproject/run/terminal" ); + m_part->appFrontend() ->startAppCommand( m_part->runDirectory(), program, inTerminal ); +} + + +void TrollProjectWidget::slotCleanProject() +{ + runClean(m_rootSubproject, "clean"); +} + +void TrollProjectWidget::slotCleanTarget() +{ + runClean(m_shownSubproject, "clean"); +} + +void TrollProjectWidget::slotDistCleanProject() +{ + runClean(m_rootSubproject, "distclean"); + +} + +void TrollProjectWidget::slotDistCleanTarget() +{ + runClean(m_shownSubproject, "distclean"); +} + +void TrollProjectWidget::runClean( QMakeScopeItem* item, const QString& cleantargetname ) +{ + // no subproject selected + m_part->partController() ->saveAllFiles(); + if ( !item ) + return ; + // can't build from scope + if ( item->scope->scopeType() != Scope::ProjectScope ) + return ; + + QString dir = item->scope->projectDir(); + createMakefileIfMissing( dir, item ); + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + QString dircmd = "cd " + KProcess::quote( dir ) + " && " ; + QString rebuildcmd = constructMakeCommandLine( item->scope ) + " "+cleantargetname; + m_part->queueCmd( dir, dircmd + rebuildcmd ); +} + +QString TrollProjectWidget::constructMakeCommandLine( Scope* s ) +{ + QString makeFileName; + if ( s ) + makeFileName = s->resolveVariables( s->variableValues( "MAKEFILE", true, true, true ).front() ); + + QDomDocument & dom = *( m_part->projectDom() ); + + QString cmdline = DomUtil::readEntry( dom, "/kdevtrollproject/make/makebin" ); + if ( cmdline.isEmpty() ) + cmdline = MAKE_COMMAND; + if ( !makeFileName.isEmpty() ) + { + cmdline += " -f " + makeFileName; + } + if ( !DomUtil::readBoolEntry( dom, "/kdevtrollproject/make/abortonerror" ) ) + cmdline += " -k"; + bool runmultiple = DomUtil::readBoolEntry(dom, "/kdevtrollproject/make/runmultiplejobs"); + int jobs = DomUtil::readIntEntry( dom, "/kdevtrollproject/make/numberofjobs" ); + if ( jobs != 0 && runmultiple ) + { + cmdline += " -j"; + cmdline += QString::number( jobs ); + } + if ( DomUtil::readBoolEntry( dom, "/kdevtrollproject/make/dontact" ) ) + cmdline += " -n"; + + cmdline += " "; + cmdline.prepend( m_part->makeEnvironment() ); + + return cmdline; +} + + +void TrollProjectWidget::createMakefileIfMissing( const QString &dir, QMakeScopeItem *item ) +{ + QFileInfo fi; + QFileInfo fi2; + kdDebug(9024) << "Makefile:" << item->scope->variableValues( "MAKEFILE", true, true, true ) << endl; + if ( item->scope->variableValues( "MAKEFILE", true, true, true ).isEmpty() ) + { + fi.setFile( dir + QString( QChar( QDir::separator() ) ) + "Makefile" ); + fi2.setFile( dir + QString( QChar( QDir::separator() ) ) + "makefile" ); + } + else + { + QString realmf = item->scope->resolveVariables( item->scope->variableValues( "MAKEFILE", true, true, true ).front() ); + fi.setFile( realmf ); + fi2.setFile( dir + QString( QChar( QDir::separator() ) ) + realmf ); + } + if ( !fi.exists() && !fi2.exists() ) + { + int r = KMessageBox::questionYesNo( this, i18n( "There is no Makefile in this directory. Run qmake first?" ), QString::null, i18n( "Run qmake" ), i18n( "Do Not Run" ) ); + if ( r == KMessageBox::No ) + return ; + m_part->startQMakeCommand( dir ); + } +} + +QMakeScopeItem* TrollProjectWidget::findSubprojectForPath( const QString& relPath ) +{ + if( !m_rootSubproject ) + return 0; + QStringList dirs = QStringList::split("/", relPath); + QMakeScopeItem* pitem = static_cast(m_rootSubproject); + for( QStringList::iterator it = dirs.begin(); it != dirs.end(); ++it) + { + QListViewItem* item = pitem->firstChild(); + while( item ) + { + QMakeScopeItem* sitem = static_cast(item); + if( QFileInfo( sitem->scope->projectDir() ).fileName() == *it ) + { + pitem = sitem; + break; + } + } + } + return pitem; +} + +QPtrList TrollProjectWidget::findSubprojectForFile( QFileInfo fi ) +{ + QPtrList list; + findSubprojectForFile( list, m_rootSubproject, fi.absFilePath() ); + return list; +} + +void TrollProjectWidget::findSubprojectForFile( QPtrList &list, QMakeScopeItem * item, QString absFilePath ) +{ + if( !item ) + return; + + QDir d( item->scope->projectDir() ); + + QStringList vars = item->scope->variableValues( "SOURCES" ); + for ( QStringList::Iterator it = vars.begin(); it != vars.end(); ++it ) + { + QFileInfo fi2( d, item->scope->resolveVariables( *it ) ); + if ( absFilePath == fi2.absFilePath() ) + list.append( item ); + } + + vars = item->scope->variableValues( "HEADERS" ); + for ( QStringList::Iterator it = vars.begin(); it != vars.end(); ++it ) + { + QFileInfo fi2( d, item->scope->resolveVariables( *it ) ); + if ( absFilePath == fi2.absFilePath() ) + list.append( item ); + } + + QListViewItem * child = item->firstChild(); + while ( child ) + { + QMakeScopeItem * spitem = dynamic_cast( child ); + + if ( spitem ) + { + findSubprojectForFile( list, spitem, absFilePath ); + } + + child = child->nextSibling(); + } +} + +void TrollProjectWidget::slotRemoveScope( QMakeScopeItem * spitem ) +{ + if ( spitem == 0 && m_shownSubproject == 0 ) + return ; + else + { + m_filesCached = false; + m_allFilesCache.clear(); + + QMakeScopeItem* pitem = dynamic_cast( spitem->parent() ); + if ( pitem != 0 ) + { + switch ( spitem->scope->scopeType() ) + { + case Scope::FunctionScope: + if( !pitem->scope->deleteFunctionScope( spitem->scope->getNum() ) ) + { + KMessageBox::error(this, i18n("Could not delete Function Scope.\nThis is an internal error, please write a bug report to bugs.kde.org and include the output of kdevelop when run from a shell."),i18n("Function Scope Deletion failed")); + return; + } + // pitem->scopes.remove( spitem ); + break; + case Scope::IncludeScope: + if( !pitem->scope->deleteIncludeScope( spitem->scope->getNum() ) ) + { + KMessageBox::error(this, i18n("Could not delete Include Scope.\nThis is an internal error, please write a bug report to bugs.kde.org and include the output of kdevelop when run from a shell."),i18n("Include Scope Deletion failed")); + return; + } + // pitem->scopes.remove( spitem ); + delete spitem; + spitem = pitem; + pitem = dynamic_cast( pitem->parent() ); + // pitem->scopes.remove(spitem); + break; + case Scope::SimpleScope: + if( !pitem->scope->deleteSimpleScope( spitem->scope->getNum() ) ) + { + KMessageBox::error(this, i18n("Could not delete Scope.\nThis is an internal error, please write a bug report to bugs.kde.org and include the output of kdevelop when run from a shell."),i18n("Scope Deletion failed")); + return; + } + // pitem->scopes.remove( spitem ); + break; + default: + break; + } + pitem->scope->saveToFile(); + delete spitem; + m_shownSubproject = pitem; + overview->setCurrentItem ( m_shownSubproject ); + overview->setSelected( m_shownSubproject, true ); + slotOverviewSelectionChanged( m_shownSubproject ); + } + } +} + +QMakeScopeItem * TrollProjectWidget::findSubprojectForScope( QMakeScopeItem * scope ) +{ + if ( ( scope == 0 ) || ( scope->parent() == 0 ) ) + return 0; + if ( scope->scope->scopeType() == Scope::ProjectScope ) + return scope; + return findSubprojectForScope( dynamic_cast( scope->parent() ) ); +} + +void TrollProjectWidget::focusInEvent( QFocusEvent * /*e*/ ) +{ + switch ( m_lastFocusedView ) + { + case DetailsView: + details->setFocus(); + break; + case SubprojectView: + default: + overview->setFocus(); + } +} + +void TrollProjectWidget::setLastFocusedView( TrollProjectView view ) +{ + m_lastFocusedView = view; +} + +void TrollProjectWidget::runQMakeRecursive( QMakeScopeItem* proj ) +{ + if( m_part->isQt4Project() ) + { + m_part->startQMakeCommand( proj->scope->projectDir(), true ); + }else + { + if ( proj->scope->scopeType() == Scope::ProjectScope ) + { + m_part->startQMakeCommand( proj->scope->projectDir() ); + } + QMakeScopeItem* item = static_cast( proj->firstChild() ); + while ( item ) + { + runQMakeRecursive( item ); + item = static_cast( item->nextSibling() ); + } + } +} + +void TrollProjectWidget::slotBuildSelectedFile() +{ + QListViewItem * selectedItem = details->currentItem(); + if ( !selectedItem ) + return ; + qProjectItem *pvitem = static_cast( selectedItem ); + // Check that it is a file (just in case) + if ( pvitem->type() != qProjectItem::File ) + return ; + FileItem *fitem = static_cast( pvitem ); + buildFile( m_shownSubproject, fitem ); +} + +void TrollProjectWidget::buildFile( QMakeScopeItem* spitem, FileItem* fitem ) +{ + QFileInfo fi( spitem->scope->projectDir() + QChar( QDir::separator() ) + spitem->scope->resolveVariables( fitem->localFilePath ) ); + QString sourceDir = fi.dirPath(); + QString baseName = fi.baseName( true ); + kdDebug( 9024 ) << "Compiling " << spitem->scope->resolveVariables( fitem->text( 0 ) ) + << "in dir " << sourceDir + << " with baseName " << baseName << endl; + + QString buildDir = sourceDir; + QString target = baseName + ".o"; + if( !spitem->scope->variableValues("OBJECTS_DIR").isEmpty() ) + target = spitem->scope->resolveVariables( spitem->scope->variableValues("OBJECTS_DIR").first() )+ QString( QChar( QDir::separator() ) )+target; + kdDebug( 9024 ) << "builddir " << buildDir << ", target " << target << endl; + + m_part->mainWindow() ->raiseView( m_part->makeFrontend() ->widget() ); + // m_part->startMakeCommand(buildDir, target); + + QString buildcmd = constructMakeCommandLine( spitem->scope ); + QString dircmd = "cd " + KProcess::quote( spitem->scope->projectDir() ) + " && " ; + kdDebug( 9024 ) << "builddir " << spitem->scope->projectDir() << ", cmd " << dircmd + buildcmd + " " + target << endl; + m_part->queueCmd( spitem->scope->projectDir(), dircmd + buildcmd + " " + target ); + + + // startMakeCommand(buildDir, target); + +} + +TrollProjectWidget::SaveType TrollProjectWidget::dialogSaveBehaviour() const +{ + switch ( DomUtil::readIntEntry( *m_part->projectDom(), "/kdevtrollproject/qmake/savebehaviour", 2 ) ) + { + case 0: + return AlwaysSave; + break; + case 1: + return NeverSave; + break; + case 2: + default: + return Ask; + break; + } +} + +bool TrollProjectWidget::isTMakeProject() +{ + return m_part->isTMakeProject(); +} + +void TrollProjectWidget::slotDisableSubproject( QMakeScopeItem* spitem ) +{ + m_filesCached = false; + m_allFilesCache.clear(); + + if( spitem->scope->variableValues("TEMPLATE").findIndex("subdirs") != -1 ) + { + QStringList subdirs = spitem->scope->variableValues( "SUBDIRS" ); + DisableSubprojectDlg dlg( subdirs ); + if( dlg.exec() ) + { + QStringList values = dlg.selectedProjects(); + QListViewItem* item = spitem->firstChild(); + while( item ) + { + if( values.findIndex( item->text(0) ) != -1 ) + delete item; + item = item->nextSibling(); + } + spitem->disableSubprojects( values ); + spitem->scope->saveToFile(); + m_shownSubproject = spitem; + slotOverviewSelectionChanged( m_shownSubproject ); + } + }else + { + QMakeScopeItem* parent = static_cast(spitem->parent()); + parent->disableSubprojects( QStringList( spitem->scope->scopeName() ) ); + delete spitem; + parent->scope->saveToFile(); + m_shownSubproject = parent; + slotOverviewSelectionChanged( m_shownSubproject ); + } +} + +void TrollProjectWidget::slotProjectDirty(const QString& path) +{ + kdDebug(9024) << "File is dirty:" << path << " using method " << endl; + if( KMessageBox::warningYesNo(this, i18n("The project file \"%1\" has changed on disk\n(Or you have \"%2\" opened in the editor, which also triggers a reload when you change something in the QMake Manager).\n\nDo you want to reload it?").arg(path).arg(path), i18n("Project File Changed"), i18n("Reload"), i18n("Do Not Reload"), "trollproject_reload_project_file" ) != KMessageBox::No ) + { + m_part->dirWatch()->stopScan(); + QListViewItemIterator it(m_rootSubproject); + QValueList itemstoreload; + while( it.current() ) + { + QMakeScopeItem* projectitem = static_cast( it.current() ); + if( projectitem->scope->scopeType() == Scope::ProjectScope + || projectitem->scope->scopeType() == Scope::IncludeScope ) + { + QString projectfile = projectitem->scope->projectDir() + QString(QChar(QDir::separator())) + projectitem->scope->fileName(); + if( projectfile == path ) + { + itemstoreload.append(projectitem); + } + } + it++; + } + + QValueList::const_iterator reloadit = itemstoreload.begin(); + for( ; reloadit != itemstoreload.end() ; ++reloadit ) + { + (*reloadit)->reloadProject(); + if( m_shownSubproject == (*reloadit) ) + { + cleanDetailView(*reloadit); + setupContext(); + buildProjectDetailTree( *reloadit, details ); + } + if( m_configDlg->isShown() && m_configDlg->currentProjectItem() == (*reloadit) ) + { + m_configDlg->reject(); + m_configDlg->updateSubproject(m_shownSubproject); + m_configDlg->show(); + } + } + m_part->dirWatch()->startScan(); + } +} + + +QMakeScopeItem* TrollProjectWidget::currentSubproject() +{ + return m_shownSubproject; +} + +bool TrollProjectWidget::showFilenamesOnly() const +{ + return m_showFilenamesOnly; +} + +bool TrollProjectWidget::showVariablesInTree() const +{ + return m_showVariablesInTree; +} + + +QMap TrollProjectWidget::qmakeEnvironment() const +{ + QMap map; + DomUtil::PairList envvars = + DomUtil::readPairListEntry(*m_part->projectDom(), "/kdevtrollproject/make/envvars", "envvar", "name", "value"); + + QString environstr; + DomUtil::PairList::ConstIterator it; + bool hasQtDir = false; + for (it = envvars.begin(); it != envvars.end(); ++it) { + if( (*it).first == "QTDIR" ) + hasQtDir = true; + + map[(*it).first] = (*it).second; + } + + if( !hasQtDir && !m_part->isQt4Project() && !DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", "").isEmpty() ) + { + map["QTDIR="] = DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", ""); + map["PATH"] = map["PATH"].prepend( DomUtil::readEntry(*m_part->projectDom(), "/kdevcppsupport/qt/root", "") +"/bin" ); + } + return map; +} + +#include "trollprojectwidget.moc" + +//kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on + diff --git a/buildtools/qmake/trollprojectwidget.h b/buildtools/qmake/trollprojectwidget.h new file mode 100644 index 00000000..19595f78 --- /dev/null +++ b/buildtools/qmake/trollprojectwidget.h @@ -0,0 +1,218 @@ +/*************************************************************************** +* Copyright (C) 2001 by Bernd Gehrmann * +* bernd@kdevelop.org * +* Copyright (C) 2002 by Jakob Simon-Gaarde * +* jakob@jsg.dk * +* Copyright (C) 2002-2003 by Alexander Dymo * +* cloudtemple@mksat.net * +* Copyright (C) 2003 by Thomas Hasart * +* thasart@gmx.de * +* Copyright (C) 2006 by Andreas Pakulat * +* apaku@gmx.de * +* * +* 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. * +* * +***************************************************************************/ + +#ifndef _TROLLPROJECTWIDGET_H_ +#define _TROLLPROJECTWIDGET_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "choosesubprojectdlg.h" +#include "newwidgetdlg.h" +#include "domutil.h" +#include "qmakescopeitem.h" + +class TrollProjectPart; +class KListView; +class ProjectConfigurationDlg; + +class TrollProjectWidget : public QVBox +{ + Q_OBJECT + +public: + TrollProjectWidget( TrollProjectPart *part ); + ~TrollProjectWidget(); + + void openProject( const QString &dirName ); + void closeProject(); + + /** + * A list of the (relative) names of all subprojects (== subdirectories). + */ + //QStringList allSubprojects(); + /** + * A list of the (relative) names of all libraries. + */ + QStringList allLibraries(); + /** + * A list of all files that belong to the project. + **/ + QStringList allFiles(); + /** + * The top level directory of the project. + **/ + QString projectDirectory(); + /** + * The directory of the currently active subproject. + */ + QString subprojectDirectory(); + /** + * The directory of the currently active subproject. + */ + QString getCurrentTarget(); + + QString getCurrentDestDir(); + + QString getCurrentOutputFilename(); + + void addFileToCurrentSubProject( GroupItem *titem, const QString &filename ); + void addFileToCurrentSubProject( GroupItem::GroupType gtype, const QString &filename ); + void addFiles( QStringList &files, bool relativeToProjectRoot = true ); + void emitAddedFile( const QString &name ); + void emitRemovedFile( const QString &name ); + + QString getUiFileLink( const QString &path, const QString& filename ); + bool isTMakeProject(); + + enum TrollProjectView { SubprojectView, DetailsView }; + void setLastFocusedView( TrollProjectView view ); + enum SaveType { AlwaysSave, NeverSave, Ask }; + QMakeScopeItem* currentSubproject(); + + bool showFilenamesOnly() const; + bool showVariablesInTree() const; + +public slots: + void slotBuildTarget(); + void slotInstallTarget(); + void slotRebuildTarget(); + void slotCleanTarget(); + void slotDistCleanTarget(); + void slotExecuteTarget(); + + void slotBuildProject(); + void slotInstallProject(); + void slotRebuildProject(); + void slotCleanProject(); + void slotDistCleanProject(); + void slotExecuteProject(); + + void slotBuildOpenFile(); + void slotBuildSelectedFile(); + + void slotConfigureProject(); + void slotAddFiles(); + void slotNewFile(); + void slotRemoveFile(); + +protected: + virtual void focusInEvent( QFocusEvent *e ); + +private slots: + void slotOverviewSelectionChanged( QListViewItem *item ); + void slotOverviewContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + void slotDetailsSelectionChanged( QListViewItem* ); + void slotDetailsExecuted( QListViewItem *item ); + void slotDetailsContextMenu( KListView *, QListViewItem *item, const QPoint &p ); + void slotExcludeFileFromScopeButton(); + void slotAddSubproject( QMakeScopeItem *spitem = 0 ); + void slotRemoveSubproject( QMakeScopeItem *spitem = 0 ); + void slotCreateScope( QMakeScopeItem *spitem = 0 ); + void slotRemoveScope( QMakeScopeItem *spitem = 0 ); + void slotDisableSubproject( QMakeScopeItem* spitem = 0 ); + void slotProjectDirty( const QString& ); + + void createQMakeScopeItems(); + +private: + void cleanDetailView( QMakeScopeItem *item ); + void runClean( QMakeScopeItem*, const QString& ); + void buildProjectDetailTree( QMakeScopeItem *item, KListView *listviewControl ); + void removeFile( QMakeScopeItem *spitem, FileItem *fitem ); + void addSubprojectToItem( QMakeScopeItem*, const QString& ); + void setupContext(); + // void parseScope(QMakeScopeItem *item,QString scopeString, Scope *scope); + GroupItem* getInstallRoot( QMakeScopeItem *item ); + GroupItem* getInstallObject( QMakeScopeItem *item, const QString& objectname ); + QString constructMakeCommandLine( Scope* s = 0 ); + + void createMakefileIfMissing( const QString &dir, QMakeScopeItem *item ); + + void runQMakeRecursive( QMakeScopeItem* proj); + void buildFile( QMakeScopeItem* spitem, FileItem* fitem); + + /*fileName: full base file name like QFileInfo::baseName ( true )*/ + QPtrList findSubprojectForFile( QFileInfo fi ); + void findSubprojectForFile( QPtrList &list, QMakeScopeItem * item, QString absFilePath ); + QMakeScopeItem* findSubprojectForPath( const QString& ); + // QString makeEnvironment(); + + TrollProjectWidget::SaveType dialogSaveBehaviour() const; + + QMakeScopeItem *findSubprojectForScope( QMakeScopeItem *scope ); + + void reloadProjectFromFile( QMakeScopeItem* item ); + QMap qmakeEnvironment() const; + + QVBox *overviewContainer; + KListView *overview; + QHBox *projectTools; + QToolButton *addSubdirButton; + QToolButton *createScopeButton; + + QToolButton *buildProjectButton; + QToolButton *rebuildProjectButton; + QToolButton *executeProjectButton; + + QToolButton *buildTargetButton; + QToolButton *rebuildTargetButton; + QToolButton *executeTargetButton; + + QToolButton *buildFileButton; + QToolButton *projectconfButton; + + QVBox *detailContainer; + KListView *details; + QHBox *fileTools; + QToolButton *addfilesButton; + QToolButton *newfileButton; + QToolButton *removefileButton; + QToolButton *excludeFileFromScopeButton; + + DomUtil::PairList m_subclasslist; + QMakeScopeItem *m_shownSubproject; + QMakeScopeItem *m_rootSubproject; + Scope* m_rootScope; + TrollProjectPart *m_part; + ProjectConfigurationDlg* m_configDlg; + + TrollProjectView m_lastFocusedView; + + bool m_filesCached; + bool m_showFilenamesOnly; + bool m_showVariablesInTree; + QStringList m_allFilesCache; + + friend class ChooseSubprojectDlg; + friend class ProjectConfigurationDlg; +}; + +#endif + +// kate: space-indent on; indent-width 4; tab-width 4; replace-tabs on diff --git a/buildtools/script/Makefile.am b/buildtools/script/Makefile.am new file mode 100644 index 00000000..73cee869 --- /dev/null +++ b/buildtools/script/Makefile.am @@ -0,0 +1,26 @@ +# Here resides the script project part. +# This is a generic part for various scripting languages that simply +# includes all files from the project directory without managing +# them. If a language needs more specific features, it deserves +# its own part (or the respective features should be added to the +# language support part) + +INCLUDES = -I$(top_srcdir)/buildtools/lib/base \ + -I$(top_srcdir)/buildtools/lib/widgets -I$(top_srcdir)/lib/interfaces \ + -I$(top_srcdir)/lib/interfaces/extensions -I$(top_srcdir)/lib/interfaces/external -I$(top_srcdir)/lib/util \ + -I$(top_srcdir)/lib/external_interfaces $(all_includes) + +kde_module_LTLIBRARIES = libkdevscriptproject.la +libkdevscriptproject_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) +libkdevscriptproject_la_LIBADD = $(top_builddir)/lib/libkdevelop.la \ + $(top_builddir)/buildtools/lib/widgets/libkdevbuildtoolswidgets.la $(top_builddir)/buildtools/lib/base/libkdevbuildbase.la + +libkdevscriptproject_la_SOURCES = scriptprojectpart.cpp scriptoptionswidget.cpp scriptoptionswidgetbase.ui scriptnewfiledlg.cpp + +METASOURCES = AUTO + +servicedir = $(kde_servicesdir) +service_DATA = kdevscriptproject.desktop + +rcdir = $(kde_datadir)/kdevscriptproject +rc_DATA = kdevscriptproject.rc diff --git a/buildtools/script/README.dox b/buildtools/script/README.dox new file mode 100644 index 00000000..a7a19983 --- /dev/null +++ b/buildtools/script/README.dox @@ -0,0 +1,48 @@ +/** \class ScriptProjectPart +This is the script build tool part +Put a more detailed description of your part in these lines. It can span +over several lines. You can even use some html commands in these lines like: +This is code, html links link text, +and images. + +\authors Bernd Gehrmann + +\unmaintained This part is currently un-maintained + +\deprecated This class is deprecated, use GenericProjectPart (buildtools/generic) instead. + +\feature Describe the first feature +\feature Describe the second feature +... +\feature Describe the last feature + +\bug Describe a the 1st bug that you know of, but probably hasn't been reported yet. +.. +\bug Describe a the nth bug that you know of, but probably hasn't been reported yet. + +\requirement Describe a the 1st requirement of your part. +\requirement Describe a the 2nd requirement of your part. +... +\requirement Describe a the nth requirement of your part. + +\todo Describe a the 1st TODO of your part. +\todo Describe a the 2nd TODO of your part. +... +\todo Describe a the nth TODO of your part. + +\faq First frequenly asked question about your part ? Answer. +\faq Second frequenly asked question about your part ? Answer. +... +\faq Last frequenly asked question about your part ? Answer. + +\note First note text. +\note Second note text. +... +\note Last note text. + +\warning First warning text. +\warning Second warning text. +... +\warning Last warning text. + +*/ diff --git a/buildtools/script/kdevscriptproject.desktop b/buildtools/script/kdevscriptproject.desktop new file mode 100644 index 00000000..1200f9ba --- /dev/null +++ b/buildtools/script/kdevscriptproject.desktop @@ -0,0 +1,87 @@ +[Desktop Entry] +Type=Service +Exec=blubb +Comment=Scripting Language Project +Comment[ca]=Projecte de llenguatge escrivint scripts +Comment[da]=Scriptsprog-projekt +Comment[de]=Skriptsprachen-Projekt für KDevelop +Comment[el]=Έργο γλώσσας γραφής σεναρίων +Comment[es]=Proyecto de lenguaje de guiones +Comment[et]=Skriptikeele projekt +Comment[eu]=Script lengoai proiektua +Comment[fa]=پروژۀ زبان دست‌نوشته‌ای +Comment[fr]=Projet avec les langages de scripts +Comment[ga]=Tionscadal i dTeanga Scriptithe +Comment[gl]=Proxecto de linguaxe de scripting +Comment[hi]=स्क्रिप्टिंग भाषा परियोजना +Comment[hu]=Szkript-projekt +Comment[is]=Skriftumálsverkefni +Comment[it]=Progetto con linguaggio di scripting +Comment[ja]=スクリプト言語プロジェクト +Comment[ms]=Projek Bahasa Penskrip +Comment[nds]=Skriptspraak-Projekt +Comment[ne]=स्क्रिप्टिङ भाषा परियोजना +Comment[nl]=Scripttaal-project +Comment[pl]=Projekt w języku skryptowym +Comment[pt]=Projecto de uma Linguagem de 'Scripting' +Comment[pt_BR]=Projeto de Linguagem de Script +Comment[ru]=Проект скриптового языка +Comment[sk]=Skriptovací jazyk projekt +Comment[sl]=Projekt skriptnega jezika +Comment[sr]=Пројекат скриптног језика +Comment[sr@Latn]=Projekat skriptnog jezika +Comment[sv]=Projekt för skriptspråk +Comment[ta]=ஸ்கிரிப்டிங் மொழி பிராஜக்ட் +Comment[tg]=Лоиҳа бо забони ғарчкунӣ +Comment[tr]=Betik Dili Projesi +Comment[zh_CN]=脚本语言工程 +Comment[zh_TW]=文稿語言專案 +Name=KDevScriptProject +Name[da]=KDevelop script-projekt +Name[de]=Skriptsprachen-Projekt (KDevelop) +Name[hi]=के-डेव-स्क्रिप्ट-परियोजना +Name[nds]=Skriptspraak-Projekt (KDevelop) +Name[ne]=केडीई विकास स्क्रिप्ट परियोजना +Name[pl]=KDevProjektSkrypt +Name[sk]=KDevSkriptProjekt +Name[sv]=KDevelop skriptprojekt +Name[ta]=கெடெவ் ஸ்கிரிப்ட் பிராஜக்ட் +Name[tg]=KDevЛоиҳаи скрипт +Name[zh_TW]=KDevelop 文稿專案 +GenericName=Scripting Language Project +GenericName[ca]=Projecte de llenguatge escrivint scripts +GenericName[da]=Scriptsprog-projekt +GenericName[de]=Skriptsprachen-Projekt +GenericName[el]=Έργο γλώσσας γραφής σεναρίων +GenericName[es]=Proyecto de lenguaje de guiones +GenericName[et]=Skriptikeele projekt +GenericName[eu]=Script lengoaia proiektua +GenericName[fa]=پروژۀ زبان دست‌نوشته‌ای +GenericName[fr]=Projet avec les langages de scripts +GenericName[ga]=Tionscadal i dTeanga Scriptithe +GenericName[gl]=Proxecto de linguaxe de scripting +GenericName[hi]=स्क्रिप्टिंग भाषा परियोजना +GenericName[hu]=Szkript-projekt +GenericName[it]=Progetto con linguaggio di scripting +GenericName[ja]=スクリプト言語プロジェクト +GenericName[nds]=Skriptspraak-Projekt +GenericName[ne]=स्क्रिप्टिङ भाषा परियोजना +GenericName[nl]=Scripttaal-project +GenericName[pl]=Projekt w języku skryptowym +GenericName[pt]=Projecto de uma Linguagem de 'Scripting' +GenericName[pt_BR]=Projeto de Linguagem de Script +GenericName[ru]=Проект скриптового языка +GenericName[sk]=Skriptovací jazyk projekt +GenericName[sl]=Projekt skriptnega jezika +GenericName[sr]=Пројекат скриптног језика +GenericName[sr@Latn]=Projekat skriptnog jezika +GenericName[sv]=Projekt för skriptspråk +GenericName[ta]=ஸ்கிரிப்டிங் மொழி பிராஜக்ட் +GenericName[tg]=Лоиҳа бо забони ғарчкунӣ +GenericName[tr]=Betik Dili Projesi +GenericName[zh_CN]=脚本语言工程 +GenericName[zh_TW]=文稿語言專案 +ServiceTypes=KDevelop/Project +Icon=kdevelop +X-KDE-Library=libkdevscriptproject +X-KDevelop-Version=5 diff --git a/buildtools/script/kdevscriptproject.rc b/buildtools/script/kdevscriptproject.rc new file mode 100644 index 00000000..651b10b4 --- /dev/null +++ b/buildtools/script/kdevscriptproject.rc @@ -0,0 +1,12 @@ + + + +

+ + + + + + + + diff --git a/buildtools/script/scriptnewfiledlg.cpp b/buildtools/script/scriptnewfiledlg.cpp new file mode 100644 index 00000000..336187d3 --- /dev/null +++ b/buildtools/script/scriptnewfiledlg.cpp @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "scriptnewfiledlg.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "scriptprojectpart.h" +#include "filetemplate.h" + + +ScriptNewFileDialog::ScriptNewFileDialog(ScriptProjectPart *part, + QWidget *parent, const char *name) + : QDialog(parent, name, true) +{ + setCaption(i18n("New File")); + + QLabel *filename_label = new QLabel(i18n("&File name:"), this); + + filename_edit = new KLineEdit(this); + filename_edit->setFocus(); + filename_label->setBuddy(this); + QFontMetrics fm(filename_edit->fontMetrics()); + filename_edit->setMinimumWidth(fm.width('X')*35); + + usetemplate_box = new QCheckBox(i18n("&Use file template"), this); + usetemplate_box->setChecked(true); + + QFrame *frame = new QFrame(this); + frame->setFrameStyle(QFrame::HLine | QFrame::Sunken); + + KButtonBox *buttonbox = new KButtonBox(this); + buttonbox->addStretch(); + QPushButton *ok_button = buttonbox->addButton(KStdGuiItem::ok()); + QPushButton *cancel_button = buttonbox->addButton(KStdGuiItem::cancel()); + ok_button->setDefault(true); + connect( ok_button, SIGNAL(clicked()), this, SLOT(accept()) ); + connect( cancel_button, SIGNAL(clicked()), this, SLOT(reject()) ); + buttonbox->layout(); + + QVBoxLayout *layout = new QVBoxLayout(this, 10, 4); + layout->addWidget(filename_label); + layout->addWidget(filename_edit); + layout->addWidget(usetemplate_box); + layout->addWidget(frame, 0); + layout->addWidget(buttonbox, 0); + + m_part = part; +} + + +ScriptNewFileDialog::~ScriptNewFileDialog() +{} + + +void ScriptNewFileDialog::accept() +{ + QString fileName = filename_edit->text(); + if (fileName.find('/') != -1) { + KMessageBox::sorry(this, i18n("Please enter the file name without '/' and so on.")); + return; + } + + KDevProject *project = m_part->project(); + if (!project->activeDirectory().isEmpty()) + fileName.prepend(project->activeDirectory() + "/"); + QString destpath = project->projectDirectory() + "/" + fileName; + + if (QFileInfo(destpath).exists()) { + KMessageBox::sorry(this, i18n("A file with this name already exists.")); + return; + } + + bool success = false; + + if (usetemplate_box->isChecked()) { + QString extension = QFileInfo(destpath).extension(); + if (!FileTemplate::exists(m_part, extension)) { + KMessageBox::sorry(this, i18n("A file template for this extension does not exist.")); + return; + } + success = FileTemplate::copy(m_part, extension, destpath); + } else { + QFile f(destpath); + success = f.open(IO_WriteOnly); + if (success) + f.close(); + } + + if (!success) + KMessageBox::sorry(this, i18n("Could not create the new file.")); + + kdDebug(9015) << "AddFile1: " << fileName << endl; + m_part->addFile(fileName); + + QDialog::accept(); +} + +#include "scriptnewfiledlg.moc" diff --git a/buildtools/script/scriptnewfiledlg.h b/buildtools/script/scriptnewfiledlg.h new file mode 100644 index 00000000..b3c73713 --- /dev/null +++ b/buildtools/script/scriptnewfiledlg.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _SCRIPTNEWFILEDLG_H_ +#define _SCRIPTNEWFILEDLG_H_ + +#include + +class QCheckBox; +class KLineEdit; +class ScriptProjectPart; + + +class ScriptNewFileDialog : public QDialog +{ + Q_OBJECT + +public: + ScriptNewFileDialog( ScriptProjectPart *part, QWidget *parent=0, const char *name=0 ); + ~ScriptNewFileDialog(); + +protected: + virtual void accept(); + +private: + QCheckBox *usetemplate_box; + KLineEdit *filename_edit; + ScriptProjectPart *m_part; +}; + +#endif diff --git a/buildtools/script/scriptoptionswidget.cpp b/buildtools/script/scriptoptionswidget.cpp new file mode 100644 index 00000000..c1660b00 --- /dev/null +++ b/buildtools/script/scriptoptionswidget.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "scriptoptionswidget.h" + +#include +#include +#include +#include +#include "domutil.h" +#include "kdevlanguagesupport.h" + + +ScriptOptionsWidget::ScriptOptionsWidget(KDevPlugin *part, + QWidget *parent, const char *name) + : ScriptOptionsWidgetBase(parent, name) +{ + m_part = part; + + QDomDocument &dom = *m_part->projectDom(); + + QString includepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/includepatterns"); + + if (includepatterns.isNull() && part->languageSupport()){ + QStringList includepatternList; + KMimeType::List list = part->languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + includepatterns = includepatternList.join( "," ); + } + + QString excludepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns"); + if (excludepatterns.isNull()) + excludepatterns = "*~"; + + includepatterns_edit->setText(includepatterns); + excludepatterns_edit->setText(excludepatterns); +} + + +ScriptOptionsWidget::~ScriptOptionsWidget() +{} + + +void ScriptOptionsWidget::accept() +{ + QDomDocument &dom = *m_part->projectDom(); + + QString includepatterns = includepatterns_edit->text(); + QString excludepatterns = excludepatterns_edit->text(); + + DomUtil::writeEntry(dom, "/kdevscriptproject/general/includepatterns", includepatterns); + DomUtil::writeEntry(dom, "/kdevscriptproject/general/excludepatterns", excludepatterns); +} + +#include "scriptoptionswidget.moc" diff --git a/buildtools/script/scriptoptionswidget.h b/buildtools/script/scriptoptionswidget.h new file mode 100644 index 00000000..c33d099d --- /dev/null +++ b/buildtools/script/scriptoptionswidget.h @@ -0,0 +1,35 @@ +/*************************************************************************** + * Copyright (C) 2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _SCRIPTPROJECTOPTIONSWIDGET_H_ +#define _SCRIPTPROJECTOPTIONSWIDGET_H_ + +#include "scriptoptionswidgetbase.h" + +class KDevPlugin; + + +class ScriptOptionsWidget : public ScriptOptionsWidgetBase +{ + Q_OBJECT + +public: + ScriptOptionsWidget( KDevPlugin *part, QWidget *parent=0, const char *name=0 ); + ~ScriptOptionsWidget(); + +public slots: + void accept(); + +private: + KDevPlugin *m_part; +}; + +#endif diff --git a/buildtools/script/scriptoptionswidgetbase.ui b/buildtools/script/scriptoptionswidgetbase.ui new file mode 100644 index 00000000..3a8f7b99 --- /dev/null +++ b/buildtools/script/scriptoptionswidgetbase.ui @@ -0,0 +1,155 @@ + +ScriptOptionsWidgetBase + + + script_project_options + + + + 0 + 0 + 600 + 482 + + + + Script Project Options + + + + unnamed + + + + includepatterns_label + + + &Include files into the project with the following patterns: + + + includepatterns_edit + + + + + Layout2 + + + + unnamed + + + 0 + + + + Spacer4 + + + Horizontal + + + Minimum + + + + 20 + 20 + + + + + + includepatterns_edit + + + + + + + Spacer7 + + + Vertical + + + Minimum + + + + 20 + 20 + + + + + + excludepatterns_label + + + &Exclude the following patterns: + + + excludepatterns_edit + + + + + Layout2_2 + + + + unnamed + + + 0 + + + + Spacer4_2 + + + Horizontal + + + Minimum + + + + 20 + 20 + + + + + + excludepatterns_edit + + + + + + + Spacer6 + + + Vertical + + + Expanding + + + + 20 + 20 + + + + + + + kdialog.h + + + + diff --git a/buildtools/script/scriptprojectpart.cpp b/buildtools/script/scriptprojectpart.cpp new file mode 100644 index 00000000..ff560f23 --- /dev/null +++ b/buildtools/script/scriptprojectpart.cpp @@ -0,0 +1,446 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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 "scriptprojectpart.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "domutil.h" +#include "kdevcore.h" +#include "kdevmainwindow.h" +#include "kdevpartcontroller.h" +#include "kdevlanguagesupport.h" +#include "scriptoptionswidget.h" +#include "scriptnewfiledlg.h" +#include "kdevplugininfo.h" + +typedef KDevGenericFactory ScriptProjectFactory; +static const KDevPluginInfo data("kdevscriptproject"); +K_EXPORT_COMPONENT_FACTORY( libkdevscriptproject, ScriptProjectFactory( data ) ) + +ScriptProjectPart::ScriptProjectPart(QObject *parent, const char *name, const QStringList &) + : KDevBuildTool(&data, parent, name ? name : "ScriptProjectPart") +{ + setInstance(ScriptProjectFactory::instance()); + + setXMLFile("kdevscriptproject.rc"); + + // only create new file action if file creation part not available + if (!extension("KDevelop/CreateFile")) { + KAction *action; + action = new KAction( i18n("New File..."), 0, + this, SLOT(slotNewFile()), + actionCollection(), "file_newfile" ); + action->setWhatsThis( i18n("New file

Creates a new file.") ); + action->setToolTip( i18n("Create a new file") ); + } + new KAction( i18n("Rescan Project"), 0, CTRL+ALT+Key_R, + this, SLOT(rescan()), + actionCollection(), "rescan" ); + + connect( core(), SIGNAL(projectConfigWidget(KDialogBase*)), + this, SLOT(projectConfigWidget(KDialogBase*)) ); +} + + +ScriptProjectPart::~ScriptProjectPart() +{} + + +void ScriptProjectPart::projectConfigWidget(KDialogBase *dlg) +{ + QVBox *vbox; + vbox = dlg->addVBoxPage(i18n("Script Project Options"), i18n("Script Project Options"), BarIcon("kdevelop", KIcon::SizeMedium)); + ScriptOptionsWidget *w = new ScriptOptionsWidget(this, vbox); + connect( dlg, SIGNAL(okClicked()), w, SLOT(accept()) ); +} + + +/** + * @todo This should really be merged with FileTreeWidget::matchesHidePattern() + * and put in its own class. Currently this is repeated in scriptprojectpart.cpp, pascalproject_part.cpp, adaproject_part.cpp + */ +static bool matchesPattern(const QString &fileName, const QStringList &patternList) +{ + QStringList::ConstIterator it; + for (it = patternList.begin(); it != patternList.end(); ++it) { + QRegExp re(*it, true, true); + if (re.search(fileName) == 0 && re.matchedLength() == (int)fileName.length()) + return true; + } + + return false; +} + + +void ScriptProjectPart::openProject(const QString &dirName, const QString &projectName) +{ + if (!languageSupport()) + kdDebug(9015) << "ScriptProjectPart::openProject: no language support found!" << endl; + + m_projectDirectory = dirName; + m_projectName = projectName; + + QDomDocument &dom = *projectDom(); + + // Set the default directory radio to "executable" + if (DomUtil::readEntry(dom, "/kdevscriptproject/run/directoryradio") == "" ) { + DomUtil::writeEntry(dom, "/kdevscriptproject/run/directoryradio", "executable"); + } + + // Put all files from all subdirectories into file list + QValueStack s; + int prefixlen = m_projectDirectory.length()+1; + s.push(m_projectDirectory); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug(9015) << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + if ( dirEntries ) + { + QPtrListIterator it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + //do not follow symlinks which point to the themselves + if (it.current()->isSymLink()) + { + QString symLink = it.current()->readLink(); + if ((symLink == path) || (symLink == "./")) + continue; + } else if (canAddDirectoryToProject(path)) { + kdDebug(9015) << "Pushing: " << path << endl; + s.push(path); + } + } + else { + if (canAddToProject(path)) + m_sourceFiles.append(path.mid(prefixlen)); + } + } + } + } while (!s.isEmpty()); + + KDevProject::openProject( dirName, projectName ); +} + + +void ScriptProjectPart::closeProject() +{ +} + + +QString ScriptProjectPart::projectDirectory() const +{ + return m_projectDirectory; +} + + +QString ScriptProjectPart::buildDirectory() const +{ + return m_projectDirectory; +} + +QString ScriptProjectPart::projectName() const +{ + return m_projectName; +} + + +/** Retuns a PairList with the run environment variables */ +DomUtil::PairList ScriptProjectPart::runEnvironmentVars() const +{ + return DomUtil::readPairListEntry(*projectDom(), "/kdevscriptproject/run/envvars", "envvar", "name", "value"); +} + + +/** Retuns the currently selected run directory + * The returned string can be: + * if run/directoryradio == executable + * The directory where the executable is + * if run/directoryradio == build + * The directory where the executable is relative to build directory + * if run/directoryradio == custom + * The custom directory absolute path + */ +QString ScriptProjectPart::runDirectory() const +{ + QString cwd = defaultRunDirectory("kdevscriptproject"); + if (cwd.isEmpty()) + cwd = buildDirectory(); + return cwd; +} + + +/** Retuns the currently selected main program + * The returned string can be: + * if run/directoryradio == executable + * The executable name + * if run/directoryradio == build + * The path to executable relative to build directory + * if run/directoryradio == custom or relative == false + * The absolute path to executable + */ +QString ScriptProjectPart::mainProgram() const +{ + QDomDocument * dom = projectDom(); + + if ( !dom ) return QString(); + + QString DomMainProgram = DomUtil::readEntry( *dom, "/kdevscriptproject/run/mainprogram"); + + if ( DomMainProgram.isEmpty() ) return QString(); + + if ( DomMainProgram.startsWith("/") ) // assume absolute path + { + return DomMainProgram; + } + else // assume project relative path + { + return projectDirectory() + "/" + DomMainProgram; + } + + return QString(); +} + +/** Retuns a QString with the debug command line arguments */ +QString ScriptProjectPart::debugArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevscriptproject/run/globaldebugarguments"); +} + + +/** Retuns a QString with the run command line arguments */ +QString ScriptProjectPart::runArguments() const +{ + return DomUtil::readEntry(*projectDom(), "/kdevscriptproject/run/programargs"); +} + + +QString ScriptProjectPart::activeDirectory() const +{ + QDomDocument &dom = *projectDom(); + + return DomUtil::readEntry(dom, "/kdevscriptproject/general/activedir"); +} + + +QStringList ScriptProjectPart::allFiles() const +{ +/* QStringList res; + + QStringList::ConstIterator it; + for (it = m_sourceFiles.begin(); it != m_sourceFiles.end(); ++it) + res += (m_projectDirectory + "/" + (*it)); + + return res;*/ + + // return all files relative to the project directory! + return m_sourceFiles; +} + +void ScriptProjectPart::addFile(const QString &fileName) +{ + kdDebug(9015) << "AddFile2" << fileName << endl; + + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void ScriptProjectPart::addFiles ( const QStringList& fileList ) +{ + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.append ( ( *it ) ); + } + + emit addedFilesToProject ( fileList ); +} + +void ScriptProjectPart::removeFile(const QString &fileName) +{ + QStringList fileList; + fileList.append ( fileName ); + + this->addFiles ( fileList ); +} + +void ScriptProjectPart::removeFiles ( const QStringList& fileList ) +{ + emit removedFilesFromProject ( fileList ); + + QStringList::ConstIterator it; + + for ( it = fileList.begin(); it != fileList.end(); ++it ) + { + m_sourceFiles.remove ( ( *it ) ); + } +} + +void ScriptProjectPart::slotNewFile() +{ + ScriptNewFileDialog dlg(this); + dlg.exec(); +} + +/*! + \fn ScriptProjectPart::distFiles() const + */ +QStringList ScriptProjectPart::distFiles() const +{ + QStringList sourceList = allFiles(); + // Scan current source directory for any .pro files. + QString projectDir = projectDirectory(); + QDir dir(projectDir); + QStringList files = dir.entryList( "*README*"); + return sourceList + files; +} + +void ScriptProjectPart::rescan() +{ +// kdDebug() << "Directory " << path << " changed, scanning for new files in the project" << endl; + + // Put all files from all subdirectories into file list + QValueStack s; + int prefixlen = m_projectDirectory.length()+1; + s.push(m_projectDirectory); + + QDir dir; + do { + dir.setPath(s.pop()); + kdDebug(9015) << "Examining: " << dir.path() << endl; + const QFileInfoList *dirEntries = dir.entryInfoList(); + if ( dirEntries ) + { + QPtrListIterator it(*dirEntries); + for (; it.current(); ++it) { + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + QString path = it.current()->absFilePath(); + if (it.current()->isDir()) { + //do not follow symlinks which point to the themselves + if (it.current()->isSymLink()) + { + QString symLink = it.current()->readLink(); + if ((symLink == path) || (symLink == "./")) + continue; + } else if (canAddDirectoryToProject(path)) { + kdDebug(9015) << "Pushing: " << path << endl; + s.push(path); + } + } + else { + if (!isProjectFile(path) && canAddToProject(path)) + addFile(path.mid(prefixlen)); +// m_sourceFiles.append(path.mid(prefixlen)); + } + } + } + } while (!s.isEmpty()); + +/* const QFileInfoList *dirEntries = QDir(path).entryInfoList(); + if ( dirEntries ) + { + kdDebug() << "1" << endl; + QPtrListIterator it(*dirEntries); + for (; it.current(); ++it) { + kdDebug() << "2" << endl; + QString fileName = it.current()->fileName(); + if (fileName == "." || fileName == "..") + continue; + kdDebug() << "3" << endl; + QString filePath = it.current()->absFilePath(); + if (!it.current()->isDir() && canAddToProject(filePath) && !isProjectFile(filePath)) { + kdDebug() << "=== adding " << filePath << endl; + addFile(filePath); + } + } + }*/ +} + +bool ScriptProjectPart::canAddToProject(const QString & path) +{ + QDomDocument &dom = *projectDom(); + QString includepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/includepatterns"); + QStringList includepatternList; + if ( includepatterns.isNull() ) { + if ( languageSupport() ){ + KMimeType::List list = languageSupport()->mimeTypes(); + KMimeType::List::Iterator it = list.begin(); + while( it != list.end() ){ + includepatternList += (*it)->patterns(); + ++it; + } + } + } else { + includepatternList = QStringList::split(",", includepatterns); + } + + QString excludepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns"); + if (excludepatterns.isNull()) + excludepatterns = "*~"; + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + if (matchesPattern(path, includepatternList) + && !matchesPattern(path, excludepatternList)) { + kdDebug(9015) << "Adding: " << path << endl; + return true; + } else { + kdDebug(9015) << "Ignoring: " << path << endl; + return false; + } +} + +bool ScriptProjectPart::canAddDirectoryToProject(const QString & path) +{ + QDomDocument &dom = *projectDom(); + QString excludepatterns + = DomUtil::readEntry(dom, "/kdevscriptproject/general/excludepatterns"); + if (excludepatterns.isNull()) { + return true; + } + QStringList excludepatternList = QStringList::split(",", excludepatterns); + + if (!matchesPattern(path, excludepatternList)) { + return true; + } else { + kdDebug(9015) << "Ignoring Directory: " << path << endl; + return false; + } +} + +#include "scriptprojectpart.moc" diff --git a/buildtools/script/scriptprojectpart.h b/buildtools/script/scriptprojectpart.h new file mode 100644 index 00000000..b16c4ffb --- /dev/null +++ b/buildtools/script/scriptprojectpart.h @@ -0,0 +1,69 @@ +/*************************************************************************** + * Copyright (C) 2001-2002 by Bernd Gehrmann * + * bernd@kdevelop.org * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef _SCRIPTPROJECTPART_H_ +#define _SCRIPTPROJECTPART_H_ + +#include +#include + +#include "kdevbuildtool.h" + +class QListViewItem; +class QStringList; +class KDialogBase; +class ScriptProjectWidget; + +class ScriptProjectPart : public KDevBuildTool +{ + Q_OBJECT + +public: + ScriptProjectPart( QObject *parent, const char *name, const QStringList &args ); + ~ScriptProjectPart(); + QStringList distFiles() const; + +protected: + virtual void openProject(const QString &dirName, const QString &projectName); + virtual void closeProject(); + + virtual QString projectDirectory() const; + virtual QString projectName() const; + virtual QString mainProgram() const; + virtual QString activeDirectory() const; + virtual QStringList allFiles() const; + virtual void addFile(const QString &fileName); + virtual void addFiles ( const QStringList& fileList ); + virtual void removeFile(const QString &fileName); + virtual void removeFiles ( const QStringList& fileList ); + virtual QString buildDirectory() const; + virtual QString runDirectory() const; + virtual QString debugArguments() const; + virtual QString runArguments() const; + virtual DomUtil::PairList runEnvironmentVars() const; + + bool canAddToProject(const QString &path); + bool canAddDirectoryToProject(const QString &path); + +private slots: + void projectConfigWidget(KDialogBase *dlg); + void slotNewFile(); + void rescan(); + +private: + QString m_projectDirectory; + QString m_projectName; + QStringList m_sourceFiles; + + friend class ScriptNewFileDialog; +}; + +#endif -- cgit v1.2.3