[Cmake-commits] CMake branch, next, updated. v2.8.5-1608-g191c1d0

Alexander Neundorf neundorf at kde.org
Tue Aug 16 17:45:41 EDT 2011


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  191c1d0d9122dfe8c02ddc626e37c1476a56f1e9 (commit)
       via  2963d0b078bf9302cab37d9def16776bde45dd67 (commit)
       via  77a5c6e0d8c995f56fa1248443de0260384acca3 (commit)
       via  bf8ef778a317fd7cd82bcc658fc734bf3f29911e (commit)
       via  d045fd4ec5d88658988c8878b313b2bf7924f40f (commit)
       via  50cd6cef925a53dfbbb820ae7343981dcf00f36c (commit)
       via  cbaac2a587d8457b69d832e2c63de8fb755ec64d (commit)
       via  c27607baf860b6c57db84f21a298ad8257ff7153 (commit)
       via  24d9b7d7452bfd9b3d7cea670a3a5a2e9f5b2f16 (commit)
       via  58b7fe65453f1d4b25537950de2277af2951fd85 (commit)
       via  72caf4d1787bc464f68954853a4edc3cf169a5f0 (commit)
       via  ddb517d014bf2245b38a0b56c9b7e98e6aaf7988 (commit)
       via  93032953afb5bd939dceb3ce427f4b6fa50e2450 (commit)
       via  ace121534de464bc7da35694a93cfb8ccc3effb6 (commit)
       via  735a5bb321ff7b92bebe2769e98a1d6317e88d27 (commit)
       via  83b730cd1aeeafc05473d163e13fb5489817c149 (commit)
       via  126c6ead7707ac29f3b2fa779752025c7cc0da32 (commit)
       via  de91feb367c127294a56b492799c4bf042954fd8 (commit)
       via  d65689a3bd059b2f70e11644e43df4251c71987e (commit)
       via  d1c0a5fce6c9adccd1abf6b41ba448976ef895d0 (commit)
       via  a65011baf109fd0afe759cf3d9e7b6ab7013a805 (commit)
      from  91768b3ec06e3c1dfb3f220007a0947a09f5c3aa (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=191c1d0d9122dfe8c02ddc626e37c1476a56f1e9
commit 191c1d0d9122dfe8c02ddc626e37c1476a56f1e9
Merge: 91768b3 2963d0b
Author:     Alexander Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 17:45:35 2011 -0400
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Tue Aug 16 17:45:35 2011 -0400

    Merge topic 'AutomocForQt' into next
    
    2963d0b Fix logic which decides when to execute automoc test
    77a5c6e Add documentation for AUTOMOC, add initialization via CMAKE_AUTOMOC
    bf8ef77 Add a test for automoc
    d045fd4 Nicer progress message for the automoc target
    50cd6ce Move automoc processing from add_executable/library to cmGlobalGenerator
    cbaac2a Remove trailing whitespace
    c27607b Refactor SetupAutomocTarget() so it can be run after creating the target
    24d9b7d Remove trailing whitespace
    58b7fe6 Use cout instead of printf()
    72caf4d Add the generated automoc.cpp file to the cleaned files
    ddb517d Color output when running moc
    9303295 Initialize verbose based onb the env.var.
    ace1215 Move code for parsing a cpp-file from the big loop to separate function
    735a5bb Fix line lengths
    83b730c Add AUTOMOC to the add_library() command
    126c6ea Add the cmake module required currently for automoc
    de91feb Remove the need to check for .h/.cxx during buildtime
    d65689a Add actual automoc code from automoc
    d1c0a5f Start implementing skeleton for automoc in cmake
    a65011b Start work on automoc: add empty cmQtAutomoc class


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2963d0b078bf9302cab37d9def16776bde45dd67
commit 2963d0b078bf9302cab37d9def16776bde45dd67
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 23:48:01 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 23:48:01 2011 +0200

    Fix logic which decides when to execute automoc test
    
    Alex

diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 30549b6..7bf4ddb 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -842,22 +842,23 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
 
   IF(NOT QT4_FOUND)
     FIND_PACKAGE(Qt4)
-    IF(QT4_FOUND)
-      ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND}
-        --build-and-test
-        "${CMake_SOURCE_DIR}/Tests/QtAutomoc"
-        "${CMake_BINARY_DIR}/Tests/QtAutomoc"
-        --build-generator ${CMAKE_TEST_GENERATOR}
-        --build-project QtAutomoc
-        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
-        --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc"
-        --force-new-ctest-process
-        --test-command ${CMAKE_CTEST_COMMAND} -V
-        )
-      LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc")
-    ENDIF()
   ENDIF(NOT QT4_FOUND)
 
+  IF(QT4_FOUND)
+    ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND}
+      --build-and-test
+      "${CMake_SOURCE_DIR}/Tests/QtAutomoc"
+      "${CMake_BINARY_DIR}/Tests/QtAutomoc"
+      --build-generator ${CMAKE_TEST_GENERATOR}
+      --build-project QtAutomoc
+      --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+      --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc"
+      --force-new-ctest-process
+      --test-command ${CMAKE_CTEST_COMMAND} -V
+      )
+    LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc")
+  ENDIF()
+
   ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/ExternalProject"

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=77a5c6e0d8c995f56fa1248443de0260384acca3
commit 77a5c6e0d8c995f56fa1248443de0260384acca3
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 22:05:33 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 22:05:33 2011 +0200

    Add documentation for AUTOMOC, add initialization via CMAKE_AUTOMOC
    
    Alex

diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index ebe2988..26125d9 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -1085,6 +1085,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "Variables that Control the Build");
 
   cm->DefineProperty
+    ("CMAKE_AUTOMOC", cmProperty::VARIABLE,
+     "Whether to handle moc automatically for Qt targets.",
+     "This variable is used to initialize the "
+     "AUTOMOC property on all the targets. "
+     "See that target property for additional information.",
+     false,
+     "Variables that Control the Build");
+
+  cm->DefineProperty
     ("CMAKE_DEBUG_POSTFIX", cmProperty::VARIABLE,
      "See variable CMAKE_<CONFIG>_POSTFIX.",
      "This variable is a special case of the more-general "
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 17a26cc..4969b65 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -115,6 +115,28 @@ cmTarget::cmTarget()
 void cmTarget::DefineProperties(cmake *cm)
 {
   cm->DefineProperty
+    ("AUTOMOC", cmProperty::TARGET,
+     "Should the target be processed with automoc (for Qt projects).",
+     "AUTOMOC is a boolean specifying whether CMake will handle "
+     "the Qt moc preprocessor automatically, i.e. without having to use "
+     "the QT4_WRAP_CPP() macro. Currently Qt4 is supported. "
+     "When this property is set to TRUE, CMake will scan the source files "
+     "at build time and invoke moc accordingly. "
+     "If an #include statement like #include \"moc_foo.cpp\" is found, "
+     "the Q_OBJECT class declaration is expected in the header, and moc is "
+     "run on the header file. "
+     "If an #include statement like #include \"foo.moc\" is found, "
+     "then a Q_OBJECT is expected in the current source file and moc "
+     "is run on the file itself. "
+     "Additionally, all header files are parsed for Q_OBJECT macros, "
+     "and if found, moc is also executed on those files. The resulting "
+     "moc files, which are not included as shown above in any of the source "
+     "files are included in a generated <targetname>_automoc.cpp file, "
+     "which is compiled as part of the target."
+     "This property is initialized by the value of the variable "
+     "CMAKE_AUTOMOC if it is set when a target is created.");
+
+  cm->DefineProperty
     ("BUILD_WITH_INSTALL_RPATH", cmProperty::TARGET,
      "Should build tree targets have install tree rpaths.",
      "BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link "
@@ -1118,6 +1140,7 @@ void cmTarget::SetMakefile(cmMakefile* mf)
   this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
   this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
   this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
+  this->SetPropertyDefault("AUTOMOC", 0);
 
   // Collect the set of configuration types.
   std::vector<std::string> configNames;
@@ -1420,7 +1443,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep)
     // the fact that the name matched a target was just a coincidence.
     if(cmSystemTools::FileIsFullPath(dep.c_str()))
       {
-      if(t->GetType() >= cmTarget::EXECUTABLE && 
+      if(t->GetType() >= cmTarget::EXECUTABLE &&
          t->GetType() <= cmTarget::MODULE_LIBRARY)
         {
         // This is really only for compatibility so we do not need to

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=bf8ef778a317fd7cd82bcc658fc734bf3f29911e
commit bf8ef778a317fd7cd82bcc658fc734bf3f29911e
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 02:10:45 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 02:13:26 2011 +0200

    Add a test for automoc
    
    The files are taken from the Qt examples. They are BSD licensed, so it
    should be fine. I only edited main.cpp to use both widgets.
    
    Alex

diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 4bf83b7..30549b6 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -840,6 +840,24 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
     )
   LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment")
 
+  IF(NOT QT4_FOUND)
+    FIND_PACKAGE(Qt4)
+    IF(QT4_FOUND)
+      ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND}
+        --build-and-test
+        "${CMake_SOURCE_DIR}/Tests/QtAutomoc"
+        "${CMake_BINARY_DIR}/Tests/QtAutomoc"
+        --build-generator ${CMAKE_TEST_GENERATOR}
+        --build-project QtAutomoc
+        --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
+        --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc"
+        --force-new-ctest-process
+        --test-command ${CMAKE_CTEST_COMMAND} -V
+        )
+      LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc")
+    ENDIF()
+  ENDIF(NOT QT4_FOUND)
+
   ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND}
     --build-and-test
     "${CMake_SOURCE_DIR}/Tests/ExternalProject"
diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt
new file mode 100644
index 0000000..4a5ff10
--- /dev/null
+++ b/Tests/QtAutomoc/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 2.8)
+
+project(QtAutomoc)
+
+find_package(Qt4 REQUIRED)
+
+include(UseQt4)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
+
+add_definitions(-DFOO)
+
+# create an executable and a library target, both requiring automoc:
+add_library(codeeditorLib STATIC codeeditor.cpp)
+
+add_executable(foo main.cpp calwidget.cpp )
+
+set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE)
+
+target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} )
diff --git a/Tests/QtAutomoc/calwidget.cpp b/Tests/QtAutomoc/calwidget.cpp
new file mode 100644
index 0000000..24f3b4e
--- /dev/null
+++ b/Tests/QtAutomoc/calwidget.cpp
@@ -0,0 +1,424 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info at nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ **   * Redistributions of source code must retain the above copyright
+ **     notice, this list of conditions and the following disclaimer.
+ **   * 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 Nokia Corporation and its Subsidiary(-ies) 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #include <QtGui>
+
+ #include "calwidget.h"
+
+ Window::Window()
+ {
+     createPreviewGroupBox();
+     createGeneralOptionsGroupBox();
+     createDatesGroupBox();
+     createTextFormatsGroupBox();
+
+     QGridLayout *layout = new QGridLayout;
+     layout->addWidget(previewGroupBox, 0, 0);
+     layout->addWidget(generalOptionsGroupBox, 0, 1);
+     layout->addWidget(datesGroupBox, 1, 0);
+     layout->addWidget(textFormatsGroupBox, 1, 1);
+     layout->setSizeConstraint(QLayout::SetFixedSize);
+     setLayout(layout);
+
+     previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height());
+     previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width());
+
+     setWindowTitle(tr("Calendar Widget"));
+ }
+
+ void Window::localeChanged(int index)
+ {
+     calendar->setLocale(localeCombo->itemData(index).toLocale());
+ }
+
+ void Window::firstDayChanged(int index)
+ {
+     calendar->setFirstDayOfWeek(Qt::DayOfWeek(
+                                 firstDayCombo->itemData(index).toInt()));
+ }
+
+ void Window::selectionModeChanged(int index)
+ {
+     calendar->setSelectionMode(QCalendarWidget::SelectionMode(
+                                selectionModeCombo->itemData(index).toInt()));
+ }
+
+ void Window::horizontalHeaderChanged(int index)
+ {
+     calendar->setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat(
+         horizontalHeaderCombo->itemData(index).toInt()));
+ }
+
+ void Window::verticalHeaderChanged(int index)
+ {
+     calendar->setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat(
+         verticalHeaderCombo->itemData(index).toInt()));
+ }
+
+ void Window::selectedDateChanged()
+ {
+     currentDateEdit->setDate(calendar->selectedDate());
+ }
+
+ void Window::minimumDateChanged(const QDate &date)
+ {
+     calendar->setMinimumDate(date);
+     maximumDateEdit->setDate(calendar->maximumDate());
+ }
+
+ void Window::maximumDateChanged(const QDate &date)
+ {
+     calendar->setMaximumDate(date);
+     minimumDateEdit->setDate(calendar->minimumDate());
+ }
+
+ void Window::weekdayFormatChanged()
+ {
+     QTextCharFormat format;
+
+     format.setForeground(qvariant_cast<QColor>(
+         weekdayColorCombo->itemData(weekdayColorCombo->currentIndex())));
+     calendar->setWeekdayTextFormat(Qt::Monday, format);
+     calendar->setWeekdayTextFormat(Qt::Tuesday, format);
+     calendar->setWeekdayTextFormat(Qt::Wednesday, format);
+     calendar->setWeekdayTextFormat(Qt::Thursday, format);
+     calendar->setWeekdayTextFormat(Qt::Friday, format);
+ }
+
+ void Window::weekendFormatChanged()
+ {
+     QTextCharFormat format;
+
+     format.setForeground(qvariant_cast<QColor>(
+         weekendColorCombo->itemData(weekendColorCombo->currentIndex())));
+     calendar->setWeekdayTextFormat(Qt::Saturday, format);
+     calendar->setWeekdayTextFormat(Qt::Sunday, format);
+ }
+
+ void Window::reformatHeaders()
+ {
+     QString text = headerTextFormatCombo->currentText();
+     QTextCharFormat format;
+
+     if (text == tr("Bold")) {
+         format.setFontWeight(QFont::Bold);
+     } else if (text == tr("Italic")) {
+         format.setFontItalic(true);
+     } else if (text == tr("Green")) {
+         format.setForeground(Qt::green);
+     }
+     calendar->setHeaderTextFormat(format);
+ }
+
+ void Window::reformatCalendarPage()
+ {
+     if (firstFridayCheckBox->isChecked()) {
+         QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1);
+         while (firstFriday.dayOfWeek() != Qt::Friday)
+             firstFriday = firstFriday.addDays(1);
+         QTextCharFormat firstFridayFormat;
+         firstFridayFormat.setForeground(Qt::blue);
+         calendar->setDateTextFormat(firstFriday, firstFridayFormat);
+     }
+
+     //May First in Red takes precedence
+     if (mayFirstCheckBox->isChecked()) {
+         const QDate mayFirst(calendar->yearShown(), 5, 1);
+         QTextCharFormat mayFirstFormat;
+         mayFirstFormat.setForeground(Qt::red);
+         calendar->setDateTextFormat(mayFirst, mayFirstFormat);
+     }
+ }
+
+ void Window::createPreviewGroupBox()
+ {
+     previewGroupBox = new QGroupBox(tr("Preview"));
+
+     calendar = new QCalendarWidget;
+     calendar->setMinimumDate(QDate(1900, 1, 1));
+     calendar->setMaximumDate(QDate(3000, 1, 1));
+     calendar->setGridVisible(true);
+
+     connect(calendar, SIGNAL(currentPageChanged(int,int)),
+             this, SLOT(reformatCalendarPage()));
+
+     previewLayout = new QGridLayout;
+     previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter);
+     previewGroupBox->setLayout(previewLayout);
+ }
+
+ void Window::createGeneralOptionsGroupBox()
+ {
+     generalOptionsGroupBox = new QGroupBox(tr("General Options"));
+
+     localeCombo = new QComboBox;
+     int curLocaleIndex = -1;
+     int index = 0;
+     for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) {
+         QLocale::Language lang = static_cast<QLocale::Language>(_lang);
+         QList<QLocale::Country> countries = QLocale::countriesForLanguage(lang);
+         for (int i = 0; i < countries.count(); ++i) {
+             QLocale::Country country = countries.at(i);
+             QString label = QLocale::languageToString(lang);
+             label += QLatin1Char('/');
+             label += QLocale::countryToString(country);
+             QLocale locale(lang, country);
+             if (this->locale().language() == lang && this->locale().country() == country)
+                 curLocaleIndex = index;
+             localeCombo->addItem(label, locale);
+             ++index;
+         }
+     }
+     if (curLocaleIndex != -1)
+         localeCombo->setCurrentIndex(curLocaleIndex);
+     localeLabel = new QLabel(tr("&Locale"));
+     localeLabel->setBuddy(localeCombo);
+
+     firstDayCombo = new QComboBox;
+     firstDayCombo->addItem(tr("Sunday"), Qt::Sunday);
+     firstDayCombo->addItem(tr("Monday"), Qt::Monday);
+     firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday);
+     firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday);
+     firstDayCombo->addItem(tr("Thursday"), Qt::Thursday);
+     firstDayCombo->addItem(tr("Friday"), Qt::Friday);
+     firstDayCombo->addItem(tr("Saturday"), Qt::Saturday);
+
+     firstDayLabel = new QLabel(tr("Wee&k starts on:"));
+     firstDayLabel->setBuddy(firstDayCombo);
+
+     selectionModeCombo = new QComboBox;
+     selectionModeCombo->addItem(tr("Single selection"),
+                                 QCalendarWidget::SingleSelection);
+     selectionModeCombo->addItem(tr("None"), QCalendarWidget::NoSelection);
+
+     selectionModeLabel = new QLabel(tr("&Selection mode:"));
+     selectionModeLabel->setBuddy(selectionModeCombo);
+
+     gridCheckBox = new QCheckBox(tr("&Grid"));
+     gridCheckBox->setChecked(calendar->isGridVisible());
+
+     navigationCheckBox = new QCheckBox(tr("&Navigation bar"));
+     navigationCheckBox->setChecked(true);
+
+     horizontalHeaderCombo = new QComboBox;
+     horizontalHeaderCombo->addItem(tr("Single letter day names"),
+                                    QCalendarWidget::SingleLetterDayNames);
+     horizontalHeaderCombo->addItem(tr("Short day names"),
+                                    QCalendarWidget::ShortDayNames);
+     horizontalHeaderCombo->addItem(tr("None"),
+                                    QCalendarWidget::NoHorizontalHeader);
+     horizontalHeaderCombo->setCurrentIndex(1);
+
+     horizontalHeaderLabel = new QLabel(tr("&Horizontal header:"));
+     horizontalHeaderLabel->setBuddy(horizontalHeaderCombo);
+
+     verticalHeaderCombo = new QComboBox;
+     verticalHeaderCombo->addItem(tr("ISO week numbers"),
+                                  QCalendarWidget::ISOWeekNumbers);
+     verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader);
+
+     verticalHeaderLabel = new QLabel(tr("&Vertical header:"));
+     verticalHeaderLabel->setBuddy(verticalHeaderCombo);
+
+     connect(localeCombo, SIGNAL(currentIndexChanged(int)),
+             this, SLOT(localeChanged(int)));
+     connect(firstDayCombo, SIGNAL(currentIndexChanged(int)),
+             this, SLOT(firstDayChanged(int)));
+     connect(selectionModeCombo, SIGNAL(currentIndexChanged(int)),
+             this, SLOT(selectionModeChanged(int)));
+     connect(gridCheckBox, SIGNAL(toggled(bool)),
+             calendar, SLOT(setGridVisible(bool)));
+     connect(navigationCheckBox, SIGNAL(toggled(bool)),
+             calendar, SLOT(setNavigationBarVisible(bool)));
+     connect(horizontalHeaderCombo, SIGNAL(currentIndexChanged(int)),
+             this, SLOT(horizontalHeaderChanged(int)));
+     connect(verticalHeaderCombo, SIGNAL(currentIndexChanged(int)),
+             this, SLOT(verticalHeaderChanged(int)));
+
+     QHBoxLayout *checkBoxLayout = new QHBoxLayout;
+     checkBoxLayout->addWidget(gridCheckBox);
+     checkBoxLayout->addStretch();
+     checkBoxLayout->addWidget(navigationCheckBox);
+
+     QGridLayout *outerLayout = new QGridLayout;
+     outerLayout->addWidget(localeLabel, 0, 0);
+     outerLayout->addWidget(localeCombo, 0, 1);
+     outerLayout->addWidget(firstDayLabel, 1, 0);
+     outerLayout->addWidget(firstDayCombo, 1, 1);
+     outerLayout->addWidget(selectionModeLabel, 2, 0);
+     outerLayout->addWidget(selectionModeCombo, 2, 1);
+     outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
+     outerLayout->addWidget(horizontalHeaderLabel, 4, 0);
+     outerLayout->addWidget(horizontalHeaderCombo, 4, 1);
+     outerLayout->addWidget(verticalHeaderLabel, 5, 0);
+     outerLayout->addWidget(verticalHeaderCombo, 5, 1);
+     generalOptionsGroupBox->setLayout(outerLayout);
+
+     firstDayChanged(firstDayCombo->currentIndex());
+     selectionModeChanged(selectionModeCombo->currentIndex());
+     horizontalHeaderChanged(horizontalHeaderCombo->currentIndex());
+     verticalHeaderChanged(verticalHeaderCombo->currentIndex());
+ }
+
+ void Window::createDatesGroupBox()
+ {
+     datesGroupBox = new QGroupBox(tr("Dates"));
+
+     minimumDateEdit = new QDateEdit;
+     minimumDateEdit->setDisplayFormat("MMM d yyyy");
+     minimumDateEdit->setDateRange(calendar->minimumDate(),
+                                   calendar->maximumDate());
+     minimumDateEdit->setDate(calendar->minimumDate());
+
+     minimumDateLabel = new QLabel(tr("&Minimum Date:"));
+     minimumDateLabel->setBuddy(minimumDateEdit);
+
+     currentDateEdit = new QDateEdit;
+     currentDateEdit->setDisplayFormat("MMM d yyyy");
+     currentDateEdit->setDate(calendar->selectedDate());
+     currentDateEdit->setDateRange(calendar->minimumDate(),
+                                   calendar->maximumDate());
+
+     currentDateLabel = new QLabel(tr("&Current Date:"));
+     currentDateLabel->setBuddy(currentDateEdit);
+
+     maximumDateEdit = new QDateEdit;
+     maximumDateEdit->setDisplayFormat("MMM d yyyy");
+     maximumDateEdit->setDateRange(calendar->minimumDate(),
+                                   calendar->maximumDate());
+     maximumDateEdit->setDate(calendar->maximumDate());
+
+     maximumDateLabel = new QLabel(tr("Ma&ximum Date:"));
+     maximumDateLabel->setBuddy(maximumDateEdit);
+
+     connect(currentDateEdit, SIGNAL(dateChanged(QDate)),
+             calendar, SLOT(setSelectedDate(QDate)));
+     connect(calendar, SIGNAL(selectionChanged()),
+             this, SLOT(selectedDateChanged()));
+     connect(minimumDateEdit, SIGNAL(dateChanged(QDate)),
+             this, SLOT(minimumDateChanged(QDate)));
+     connect(maximumDateEdit, SIGNAL(dateChanged(QDate)),
+             this, SLOT(maximumDateChanged(QDate)));
+
+     QGridLayout *dateBoxLayout = new QGridLayout;
+     dateBoxLayout->addWidget(currentDateLabel, 1, 0);
+     dateBoxLayout->addWidget(currentDateEdit, 1, 1);
+     dateBoxLayout->addWidget(minimumDateLabel, 0, 0);
+     dateBoxLayout->addWidget(minimumDateEdit, 0, 1);
+     dateBoxLayout->addWidget(maximumDateLabel, 2, 0);
+     dateBoxLayout->addWidget(maximumDateEdit, 2, 1);
+     dateBoxLayout->setRowStretch(3, 1);
+
+     datesGroupBox->setLayout(dateBoxLayout);
+ }
+
+ void Window::createTextFormatsGroupBox()
+ {
+     textFormatsGroupBox = new QGroupBox(tr("Text Formats"));
+
+     weekdayColorCombo = createColorComboBox();
+     weekdayColorCombo->setCurrentIndex(
+             weekdayColorCombo->findText(tr("Black")));
+
+     weekdayColorLabel = new QLabel(tr("&Weekday color:"));
+     weekdayColorLabel->setBuddy(weekdayColorCombo);
+
+     weekendColorCombo = createColorComboBox();
+     weekendColorCombo->setCurrentIndex(
+             weekendColorCombo->findText(tr("Red")));
+
+     weekendColorLabel = new QLabel(tr("Week&end color:"));
+     weekendColorLabel->setBuddy(weekendColorCombo);
+
+     headerTextFormatCombo = new QComboBox;
+     headerTextFormatCombo->addItem(tr("Bold"));
+     headerTextFormatCombo->addItem(tr("Italic"));
+     headerTextFormatCombo->addItem(tr("Plain"));
+
+     headerTextFormatLabel = new QLabel(tr("&Header text:"));
+     headerTextFormatLabel->setBuddy(headerTextFormatCombo);
+
+     firstFridayCheckBox = new QCheckBox(tr("&First Friday in blue"));
+
+     mayFirstCheckBox = new QCheckBox(tr("May &1 in red"));
+
+     connect(weekdayColorCombo, SIGNAL(currentIndexChanged(int)),
+             this, SLOT(weekdayFormatChanged()));
+     connect(weekendColorCombo, SIGNAL(currentIndexChanged(int)),
+             this, SLOT(weekendFormatChanged()));
+     connect(headerTextFormatCombo, SIGNAL(currentIndexChanged(QString)),
+             this, SLOT(reformatHeaders()));
+     connect(firstFridayCheckBox, SIGNAL(toggled(bool)),
+             this, SLOT(reformatCalendarPage()));
+     connect(mayFirstCheckBox, SIGNAL(toggled(bool)),
+             this, SLOT(reformatCalendarPage()));
+
+     QHBoxLayout *checkBoxLayout = new QHBoxLayout;
+     checkBoxLayout->addWidget(firstFridayCheckBox);
+     checkBoxLayout->addStretch();
+     checkBoxLayout->addWidget(mayFirstCheckBox);
+
+     QGridLayout *outerLayout = new QGridLayout;
+     outerLayout->addWidget(weekdayColorLabel, 0, 0);
+     outerLayout->addWidget(weekdayColorCombo, 0, 1);
+     outerLayout->addWidget(weekendColorLabel, 1, 0);
+     outerLayout->addWidget(weekendColorCombo, 1, 1);
+     outerLayout->addWidget(headerTextFormatLabel, 2, 0);
+     outerLayout->addWidget(headerTextFormatCombo, 2, 1);
+     outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2);
+     textFormatsGroupBox->setLayout(outerLayout);
+
+     weekdayFormatChanged();
+     weekendFormatChanged();
+     reformatHeaders();
+     reformatCalendarPage();
+ }
+
+QComboBox *Window::createColorComboBox()
+ {
+     QComboBox *comboBox = new QComboBox;
+     comboBox->addItem(tr("Red"), Qt::red);
+     comboBox->addItem(tr("Blue"), Qt::blue);
+     comboBox->addItem(tr("Black"), Qt::black);
+     comboBox->addItem(tr("Magenta"), Qt::magenta);
+     return comboBox;
+ }
+
+//#include "moc_calwidget.cpp"
diff --git a/Tests/QtAutomoc/calwidget.h b/Tests/QtAutomoc/calwidget.h
new file mode 100644
index 0000000..8447389
--- /dev/null
+++ b/Tests/QtAutomoc/calwidget.h
@@ -0,0 +1,121 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info at nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ **   * Redistributions of source code must retain the above copyright
+ **     notice, this list of conditions and the following disclaimer.
+ **   * 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 Nokia Corporation and its Subsidiary(-ies) 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#ifndef WINDOW_H
+#define WINDOW_H
+
+#include <QWidget>
+
+ class QCalendarWidget;
+ class QCheckBox;
+ class QComboBox;
+ class QDate;
+ class QDateEdit;
+ class QGridLayout;
+ class QGroupBox;
+ class QLabel;
+
+ class Window : public QWidget
+ {
+     Q_OBJECT
+
+ public:
+     Window();
+
+ private slots:
+     void localeChanged(int index);
+     void firstDayChanged(int index);
+     void selectionModeChanged(int index);
+     void horizontalHeaderChanged(int index);
+     void verticalHeaderChanged(int index);
+     void selectedDateChanged();
+     void minimumDateChanged(const QDate &date);
+     void maximumDateChanged(const QDate &date);
+     void weekdayFormatChanged();
+     void weekendFormatChanged();
+     void reformatHeaders();
+     void reformatCalendarPage();
+
+ private:
+     void createPreviewGroupBox();
+     void createGeneralOptionsGroupBox();
+     void createDatesGroupBox();
+     void createTextFormatsGroupBox();
+     QComboBox *createColorComboBox();
+
+     QGroupBox *previewGroupBox;
+     QGridLayout *previewLayout;
+     QCalendarWidget *calendar;
+
+     QGroupBox *generalOptionsGroupBox;
+     QLabel *localeLabel;
+     QLabel *firstDayLabel;
+     QLabel *selectionModeLabel;
+     QLabel *horizontalHeaderLabel;
+     QLabel *verticalHeaderLabel;
+     QComboBox *localeCombo;
+     QComboBox *firstDayCombo;
+     QComboBox *selectionModeCombo;
+     QCheckBox *gridCheckBox;
+     QCheckBox *navigationCheckBox;
+     QComboBox *horizontalHeaderCombo;
+     QComboBox *verticalHeaderCombo;
+
+     QGroupBox *datesGroupBox;
+     QLabel *currentDateLabel;
+     QLabel *minimumDateLabel;
+     QLabel *maximumDateLabel;
+     QDateEdit *currentDateEdit;
+     QDateEdit *minimumDateEdit;
+     QDateEdit *maximumDateEdit;
+
+     QGroupBox *textFormatsGroupBox;
+     QLabel *weekdayColorLabel;
+     QLabel *weekendColorLabel;
+     QLabel *headerTextFormatLabel;
+     QComboBox *weekdayColorCombo;
+     QComboBox *weekendColorCombo;
+     QComboBox *headerTextFormatCombo;
+
+     QCheckBox *firstFridayCheckBox;
+     QCheckBox *mayFirstCheckBox;
+ };
+
+ #endif
diff --git a/Tests/QtAutomoc/codeeditor.cpp b/Tests/QtAutomoc/codeeditor.cpp
new file mode 100644
index 0000000..01da062
--- /dev/null
+++ b/Tests/QtAutomoc/codeeditor.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info at nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ **   * Redistributions of source code must retain the above copyright
+ **     notice, this list of conditions and the following disclaimer.
+ **   * 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 Nokia Corporation and its Subsidiary(-ies) 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #include <QtGui>
+
+ #include "codeeditor.h"
+
+
+ CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent)
+ {
+     lineNumberArea = new LineNumberArea(this);
+
+     connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int)));
+     connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int)));
+     connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
+
+     updateLineNumberAreaWidth(0);
+     highlightCurrentLine();
+ }
+
+
+
+ int CodeEditor::lineNumberAreaWidth()
+ {
+     int digits = 1;
+     int max = qMax(1, blockCount());
+     while (max >= 10) {
+         max /= 10;
+         ++digits;
+     }
+
+     int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits;
+
+     return space;
+ }
+
+
+
+ void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */)
+ {
+     setViewportMargins(lineNumberAreaWidth(), 0, 0, 0);
+ }
+
+
+
+ void CodeEditor::updateLineNumberArea(const QRect &rect, int dy)
+ {
+     if (dy)
+         lineNumberArea->scroll(0, dy);
+     else
+         lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height());
+
+     if (rect.contains(viewport()->rect()))
+         updateLineNumberAreaWidth(0);
+ }
+
+
+
+ void CodeEditor::resizeEvent(QResizeEvent *e)
+ {
+     QPlainTextEdit::resizeEvent(e);
+
+     QRect cr = contentsRect();
+     lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height()));
+ }
+
+
+
+ void CodeEditor::highlightCurrentLine()
+ {
+     QList<QTextEdit::ExtraSelection> extraSelections;
+
+     if (!isReadOnly()) {
+         QTextEdit::ExtraSelection selection;
+
+         QColor lineColor = QColor(Qt::yellow).lighter(160);
+
+         selection.format.setBackground(lineColor);
+         selection.format.setProperty(QTextFormat::FullWidthSelection, true);
+         selection.cursor = textCursor();
+         selection.cursor.clearSelection();
+         extraSelections.append(selection);
+     }
+
+     setExtraSelections(extraSelections);
+ }
+
+
+
+ void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event)
+ {
+     QPainter painter(lineNumberArea);
+     painter.fillRect(event->rect(), Qt::lightGray);
+
+
+     QTextBlock block = firstVisibleBlock();
+     int blockNumber = block.blockNumber();
+     int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top();
+     int bottom = top + (int) blockBoundingRect(block).height();
+
+     while (block.isValid() && top <= event->rect().bottom()) {
+         if (block.isVisible() && bottom >= event->rect().top()) {
+             QString number = QString::number(blockNumber + 1);
+             painter.setPen(Qt::black);
+             painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(),
+                              Qt::AlignRight, number);
+         }
+
+         block = block.next();
+         top = bottom;
+         bottom = top + (int) blockBoundingRect(block).height();
+         ++blockNumber;
+     }
+ }
+
+#include "codeeditor.moc"
diff --git a/Tests/QtAutomoc/codeeditor.h b/Tests/QtAutomoc/codeeditor.h
new file mode 100644
index 0000000..56e9e79
--- /dev/null
+++ b/Tests/QtAutomoc/codeeditor.h
@@ -0,0 +1,99 @@
+ /****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info at nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ **   * Redistributions of source code must retain the above copyright
+ **     notice, this list of conditions and the following disclaimer.
+ **   * 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 Nokia Corporation and its Subsidiary(-ies) 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+ #ifndef CODEEDITOR_H
+ #define CODEEDITOR_H
+
+ #include <QPlainTextEdit>
+ #include <QObject>
+
+ class QPaintEvent;
+ class QResizeEvent;
+ class QSize;
+ class QWidget;
+
+ class LineNumberArea;
+
+
+ class CodeEditor : public QPlainTextEdit
+ {
+     Q_OBJECT
+
+ public:
+     CodeEditor(QWidget *parent = 0);
+
+     void lineNumberAreaPaintEvent(QPaintEvent *event);
+     int lineNumberAreaWidth();
+
+ protected:
+     void resizeEvent(QResizeEvent *event);
+
+ private slots:
+     void updateLineNumberAreaWidth(int newBlockCount);
+     void highlightCurrentLine();
+     void updateLineNumberArea(const QRect &, int);
+
+ private:
+     QWidget *lineNumberArea;
+ };
+
+
+ class LineNumberArea : public QWidget
+ {
+ public:
+     LineNumberArea(CodeEditor *editor) : QWidget(editor) {
+         codeEditor = editor;
+     }
+
+     QSize sizeHint() const {
+         return QSize(codeEditor->lineNumberAreaWidth(), 0);
+     }
+
+ protected:
+     void paintEvent(QPaintEvent *event) {
+         codeEditor->lineNumberAreaPaintEvent(event);
+     }
+
+ private:
+     CodeEditor *codeEditor;
+ };
+
+
+ #endif
diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutomoc/main.cpp
new file mode 100644
index 0000000..7bf4a5d
--- /dev/null
+++ b/Tests/QtAutomoc/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+ **
+ ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+ ** All rights reserved.
+ ** Contact: Nokia Corporation (qt-info at nokia.com)
+ **
+ ** This file is part of the examples of the Qt Toolkit.
+ **
+ ** $QT_BEGIN_LICENSE:BSD$
+ ** You may use this file under the terms of the BSD license as follows:
+ **
+ ** "Redistribution and use in source and binary forms, with or without
+ ** modification, are permitted provided that the following conditions are
+ ** met:
+ **   * Redistributions of source code must retain the above copyright
+ **     notice, this list of conditions and the following disclaimer.
+ **   * 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 Nokia Corporation and its Subsidiary(-ies) 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+ ** $QT_END_LICENSE$
+ **
+ ****************************************************************************/
+
+#include <QtGui>
+
+#include "codeeditor.h"
+#include "calwidget.h"
+
+int main(int argv, char **args)
+{
+  QApplication app(argv, args);
+
+  CodeEditor editor;
+  editor.setWindowTitle(QObject::tr("Code Editor Example"));
+  editor.show();
+
+  Window w;
+  w.show();
+
+  return app.exec();
+}

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d045fd4ec5d88658988c8878b313b2bf7924f40f
commit d045fd4ec5d88658988c8878b313b2bf7924f40f
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 02:00:36 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 02:00:36 2011 +0200

    Nicer progress message for the automoc target
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 6dbc9e1..e8c4baa 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -66,11 +66,13 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
                                     "", makefile->GetCurrentOutputDirectory());
 
   std::vector<std::string> depends;
+  std::string automocComment = "Automoc for target ";
+  automocComment += targetName;
 
   cmTarget* mocTarget = makefile->AddUtilityCommand(automocTargetName.c_str(),
                                                     true,
-                                      workingDirectory.c_str(), depends,
-                                      commandLines, false, "Automoc target");
+                                  workingDirectory.c_str(), depends,
+                                  commandLines, false, automocComment.c_str());
   target->AddUtility(automocTargetName.c_str());
 
   // configure a file to get all information to automoc at buildtime:

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=50cd6cef925a53dfbbb820ae7343981dcf00f36c
commit 50cd6cef925a53dfbbb820ae7343981dcf00f36c
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 01:45:05 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 01:45:05 2011 +0200

    Move automoc processing from add_executable/library to cmGlobalGenerator
    
    Now automoc is enabled by setting the AUTOMOC target property to true,
    instead of using the AUTOMOC keyword in add_executable() or add_library()
    
    Alex

diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index ef75b3b..bac2430 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -10,7 +10,6 @@
   See the License for more information.
 ============================================================================*/
 #include "cmAddExecutableCommand.h"
-#include "cmQtAutomoc.h"
 
 // cmExecutableCommand
 bool cmAddExecutableCommand
@@ -30,7 +29,6 @@ bool cmAddExecutableCommand
   bool use_macbundle = false;
   bool excludeFromAll = false;
   bool importTarget = false;
-  bool doAutomoc = false;
   while ( s != args.end() )
     {
     if (*s == "WIN32")
@@ -43,11 +41,6 @@ bool cmAddExecutableCommand
       ++s;
       use_macbundle = true;
       }
-    else if ( *s == "AUTOMOC" )
-      {
-      ++s;
-      doAutomoc = true;
-      }
     else if(*s == "EXCLUDE_FROM_ALL")
       {
       ++s;
@@ -66,17 +59,12 @@ bool cmAddExecutableCommand
 
   // Special modifiers are not allowed with IMPORTED signature.
   if(importTarget
-      && (use_win32 || use_macbundle || excludeFromAll  || doAutomoc))
+      && (use_win32 || use_macbundle || excludeFromAll))
     {
     if(use_win32)
       {
       this->SetError("may not be given WIN32 for an IMPORTED target.");
       }
-    else if(doAutomoc)
-      {
-      this->SetError(
-        "may not be given AUTOMOC for an IMPORTED target.");
-      }
     else if(use_macbundle)
       {
       this->SetError(
@@ -137,11 +125,5 @@ bool cmAddExecutableCommand
     tgt->SetProperty("MACOSX_BUNDLE", "ON");
     }
 
-  if ( doAutomoc )
-    {
-    cmQtAutomoc automoc;
-    automoc.SetupAutomocTarget(tgt);
-    }
-
   return true;
 }
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index f0b2e0d..efa29e6 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -12,7 +12,6 @@
 #include "cmAddLibraryCommand.h"
 
 #include "cmake.h"
-#include "cmQtAutomoc.h"
 
 // cmLibraryCommand
 bool cmAddLibraryCommand
@@ -32,7 +31,6 @@ bool cmAddLibraryCommand
     }
   bool excludeFromAll = false;
   bool importTarget = false;
-  bool doAutomoc = false;
 
   std::vector<std::string>::const_iterator s = args.begin();
 
@@ -81,11 +79,6 @@ bool cmAddLibraryCommand
       ++s;
       importTarget = true;
       }
-    else if (*s == "AUTOMOC")
-      {
-      ++s;
-      doAutomoc = true;
-      }
     else
       {
       break;
@@ -120,13 +113,6 @@ bool cmAddLibraryCommand
       return false;
       }
 
-    // Don't run automoc on an imported library
-    if (doAutomoc)
-      {
-      this->SetError("cannot be called with AUTOMOC for an IMPORTED library.");
-      return false;
-      }
-
     // Make sure the target does not already exist.
     if(this->Makefile->FindTargetToUse(libName.c_str()))
       {
@@ -178,14 +164,7 @@ bool cmAddLibraryCommand
     ++s;
     }
 
-  cmTarget* tgt =this->Makefile->AddLibrary(libName.c_str(), type, srclists,
-                                            excludeFromAll);
-
-  if ( doAutomoc )
-    {
-    cmQtAutomoc automoc;
-    automoc.SetupAutomocTarget(tgt);
-    }
+  this->Makefile->AddLibrary(libName.c_str(), type, srclists, excludeFromAll);
 
   return true;
 }
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index f37b054..3016f5a 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -18,6 +18,7 @@
 #include "cmExternalMakefileProjectGenerator.h"
 #include "cmake.h"
 #include "cmMakefile.h"
+#include "cmQtAutomoc.h"
 #include "cmSourceFile.h"
 #include "cmVersion.h"
 #include "cmExportInstallFileGenerator.h"
@@ -832,6 +833,10 @@ void cmGlobalGenerator::Generate()
     return;
     }
 
+  // Iterate through all targets and set up automoc for those which have
+  // the AUTOMOC property set
+  this->CreateAutomocTargets();
+
   // For each existing cmLocalGenerator
   unsigned int i;
 
@@ -950,6 +955,33 @@ bool cmGlobalGenerator::CheckTargets()
   return true;
 }
 
+//----------------------------------------------------------------------------
+void cmGlobalGenerator::CreateAutomocTargets()
+{
+  for(unsigned int i=0; i < this->LocalGenerators.size(); ++i)
+    {
+    cmTargets& targets =
+      this->LocalGenerators[i]->GetMakefile()->GetTargets();
+    for(cmTargets::iterator ti = targets.begin();
+        ti != targets.end(); ++ti)
+      {
+      cmTarget& target = ti->second;
+      if(target.GetType() == cmTarget::EXECUTABLE ||
+         target.GetType() == cmTarget::STATIC_LIBRARY ||
+         target.GetType() == cmTarget::SHARED_LIBRARY ||
+         target.GetType() == cmTarget::MODULE_LIBRARY)
+        {
+        if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported())
+          {
+          cmQtAutomoc automoc;
+          automoc.SetupAutomocTarget(&target);
+          }
+        }
+      }
+    }
+}
+
+
 void cmGlobalGenerator::CheckLocalGenerators()
 {
   std::map<cmStdString, cmStdString> notFoundMap;
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index b7b1bff..88eb8b6 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -282,6 +282,8 @@ protected:
   virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS();
 
   bool CheckTargets();
+  void CreateAutomocTargets();
+
 
   // Fill the ProjectMap, this must be called after LocalGenerators
   // has been populated.

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=cbaac2a587d8457b69d832e2c63de8fb755ec64d
commit cbaac2a587d8457b69d832e2c63de8fb755ec64d
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 01:44:13 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 01:44:13 2011 +0200

    Remove trailing whitespace
    
    Alex

diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 2eae01e..f37b054 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -269,7 +269,7 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
     cmOStringStream windowsVersionString;
     windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion;
     windowsVersionString.str();
-    mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", 
+    mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION",
                       windowsVersionString.str().c_str());
 #endif
     // Read the DetermineSystem file
@@ -618,8 +618,8 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf)
     if (sscanf(linkerPref, "%d", &preference)!=1)
       {
       // backward compatibility: before 2.6 LINKER_PREFERENCE
-      // was either "None" or "Prefered", and only the first character was 
-      // tested. So if there is a custom language out there and it is 
+      // was either "None" or "Prefered", and only the first character was
+      // tested. So if there is a custom language out there and it is
       // "Prefered", set its preference high
       if (linkerPref[0]=='P')
         {
@@ -1019,9 +1019,9 @@ void cmGlobalGenerator::CheckLocalGenerators()
   if(notFoundMap.size())
     {
     std::string notFoundVars;
-    for(std::map<cmStdString, cmStdString>::const_iterator 
+    for(std::map<cmStdString, cmStdString>::const_iterator
         ii = notFoundMap.begin();
-        ii != notFoundMap.end(); 
+        ii != notFoundMap.end();
         ++ii)
       {
       notFoundVars += ii->first;
@@ -1057,7 +1057,7 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir,
       {
       this->FirstTimeProgress = 0.95f;
       }
-    this->CMakeInstance->UpdateProgress("Configuring", 
+    this->CMakeInstance->UpdateProgress("Configuring",
                                         this->FirstTimeProgress);
     }
 
@@ -1161,7 +1161,7 @@ int cmGlobalGenerator::Build(
     {
     outputPtr = &outputBuffer;
     }
-    
+
   // should we do a clean first?
   if (clean)
     {
@@ -1199,7 +1199,7 @@ int cmGlobalGenerator::Build(
   // now build
   std::string makeCommand =
     this->GenerateBuildCommand(makeCommandCSTR, projectName,
-                               extraOptions, target, 
+                               extraOptions, target,
                                config, false, fast);
   if(output)
     {
@@ -1272,8 +1272,8 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg)
     if(this->FirstTimeProgress > 0.95f)
       {
       this->FirstTimeProgress = 0.95f;
-      } 
-    this->CMakeInstance->UpdateProgress("Configuring", 
+      }
+    this->CMakeInstance->UpdateProgress("Configuring",
                                         this->FirstTimeProgress);
     return;
     }
@@ -1296,8 +1296,8 @@ void cmGlobalGenerator::AddInstallComponent(const char* component)
     }
 }
 
-void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, 
-                                           cmTarget* target, 
+void cmGlobalGenerator::AddTargetToExports(const char* exportSetName,
+                                           cmTarget* target,
                                            cmInstallTargetGenerator* archive,
                                            cmInstallTargetGenerator* runTime,
                                            cmInstallTargetGenerator* library,
@@ -1331,7 +1331,7 @@ void cmGlobalGenerator::ClearExportSets()
 const std::vector<cmTargetExport*>* cmGlobalGenerator::GetExportSet(
                                                         const char* name) const
 {
-  std::map<cmStdString, std::vector<cmTargetExport*> >::const_iterator 
+  std::map<cmStdString, std::vector<cmTargetExport*> >::const_iterator
                                      exportSetIt = this->ExportSets.find(name);
   if (exportSetIt != this->ExportSets.end())
     {
@@ -1443,7 +1443,7 @@ void cmGlobalGenerator::GetEnabledLanguages(std::vector<std::string>& lang)
 
 int cmGlobalGenerator::GetLinkerPreference(const char* lang)
 {
-  std::map<cmStdString, int>::const_iterator it = 
+  std::map<cmStdString, int>::const_iterator it =
                                    this->LanguageToLinkerPreference.find(lang);
   if (it != this->LanguageToLinkerPreference.end())
     {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c27607baf860b6c57db84f21a298ad8257ff7153
commit c27607baf860b6c57db84f21a298ad8257ff7153
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 01:27:30 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 01:27:30 2011 +0200

    Refactor SetupAutomocTarget() so it can be run after creating the target
    
    This makes it easier to move it from InitialPass() to some other
    location, e.g. FinalPass() or something else.
    
    Alex

diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index 9710d20..ef75b3b 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -126,14 +126,6 @@ bool cmAddExecutableCommand
     }
 
   std::vector<std::string> srclists(s, args.end());
-  cmQtAutomoc* automoc = 0;
-  if ( doAutomoc )
-    {
-    automoc = new cmQtAutomoc;
-    automoc->SetupAutomocTarget(this->Makefile, exename.c_str(), srclists);
-    }
-
-
   cmTarget* tgt = this->Makefile->AddExecutable(exename.c_str(), srclists,
                                                 excludeFromAll);
   if ( use_win32 )
@@ -145,11 +137,10 @@ bool cmAddExecutableCommand
     tgt->SetProperty("MACOSX_BUNDLE", "ON");
     }
 
-  if ( automoc )
+  if ( doAutomoc )
     {
-    automoc->AddTargetDependency(this->Makefile, tgt);
-    delete automoc;
-    automoc = 0;
+    cmQtAutomoc automoc;
+    automoc.SetupAutomocTarget(tgt);
     }
 
   return true;
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index a581ea1..f0b2e0d 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -178,21 +178,13 @@ bool cmAddLibraryCommand
     ++s;
     }
 
-  cmQtAutomoc* automoc = 0;
-  if ( doAutomoc )
-    {
-    automoc = new cmQtAutomoc;
-    automoc->SetupAutomocTarget(this->Makefile, libName.c_str(), srclists);
-    }
-
   cmTarget* tgt =this->Makefile->AddLibrary(libName.c_str(), type, srclists,
                                             excludeFromAll);
 
-  if ( automoc )
+  if ( doAutomoc )
     {
-    automoc->AddTargetDependency(this->Makefile, tgt);
-    delete automoc;
-    automoc = 0;
+    cmQtAutomoc automoc;
+    automoc.SetupAutomocTarget(tgt);
     }
 
   return true;
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index b03e9cf..6dbc9e1 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -32,10 +32,10 @@ cmQtAutomoc::cmQtAutomoc()
 }
 
 
-void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
-                                     const char* targetName,
-                                     std::vector<std::string>& srcs)
+void cmQtAutomoc::SetupAutomocTarget(cmTarget* target)
 {
+  cmMakefile* makefile = target->GetMakefile();
+  const char* targetName = target->GetName();
   // don't do anything if there is no Qt4:
   std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
   if (qtMajorVersion != "4")
@@ -43,6 +43,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
     return;
     }
 
+  // create a custom target for running automoc at buildtime:
   std::string automocTargetName = targetName;
   automocTargetName += "_automoc";
 
@@ -66,34 +67,32 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
 
   std::vector<std::string> depends;
 
-  cmTarget* target = makefile->AddUtilityCommand(automocTargetName.c_str(),
-                                                 true,
+  cmTarget* mocTarget = makefile->AddUtilityCommand(automocTargetName.c_str(),
+                                                    true,
                                       workingDirectory.c_str(), depends,
                                       commandLines, false, "Automoc target");
+  target->AddUtility(automocTargetName.c_str());
 
+  // configure a file to get all information to automoc at buildtime:
   std::string _moc_files;
   std::string _moc_headers;
   const char* sepFiles = "";
   const char* sepHeaders = "";
-  for(std::vector<std::string>::const_iterator fileIt = srcs.begin();
-      fileIt != srcs.end();
+
+  const std::vector<cmSourceFile*>& srcFiles = target->GetSourceFiles();
+
+  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
+      fileIt != srcFiles.end();
       ++fileIt)
     {
-    std::string absFile = cmSystemTools::CollapseFullPath(
-                             fileIt->c_str(), makefile->GetCurrentDirectory());
-
-    bool skip = false;
-    bool generated = false;
-    cmSourceFile* sf = makefile->GetSource(absFile.c_str());
-    if (sf)
-      {
-      skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
-      generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
-      }
+    cmSourceFile* sf = *fileIt;
+    std::string absFile = sf->GetFullPath();
+    bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
+    bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
 
     if ((skip==false) && (generated == false))
       {
-      std::string ext = cmSystemTools::GetFilenameExtension(fileIt->c_str());
+      std::string ext = sf->GetExtension();
       cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
                                                                   ext.c_str());
       if (fileType == cmSystemTools::CXX_FILE_FORMAT)
@@ -137,29 +136,15 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
   mocCppFile += "/";
   mocCppFile += automocTargetName;
   mocCppFile += ".cpp";
-  makefile->GetOrCreateSource(mocCppFile.c_str(), true);
-  srcs.push_back(mocCppFile);
+  cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(),
+                                                         true);
+  target->AddSourceFile(mocCppSource);
 
   makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
                            mocCppFile.c_str(), false);
 }
 
 
-void cmQtAutomoc::AddTargetDependency(cmMakefile* makefile, cmTarget* target)
-{
-  // don't do anything if there is no Qt4:
-  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
-  if (qtMajorVersion != "4")
-    {
-    return;
-    }
-
-  std::string automocTargetName = target->GetName();
-  automocTargetName += "_automoc";
-  target->AddUtility(automocTargetName.c_str());
-}
-
-
 bool cmQtAutomoc::Run(const char* targetDirectory)
 {
   cmake cm;
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index af77366..4fd9041 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -10,11 +10,7 @@ public:
   cmQtAutomoc();
   bool Run(const char* targetDirectory);
 
-  void SetupAutomocTarget(cmMakefile* makefile,
-                          const char* targetName,
-                          std::vector<std::string>& srcs);
-
-  void AddTargetDependency(cmMakefile* makefile, cmTarget* target);
+  void SetupAutomocTarget(cmTarget* target);
 
 private:
   cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=24d9b7d7452bfd9b3d7cea670a3a5a2e9f5b2f16
commit 24d9b7d7452bfd9b3d7cea670a3a5a2e9f5b2f16
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 16 01:26:02 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Tue Aug 16 01:26:02 2011 +0200

    Remove trailing whitespace
    
    Alex

diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 2e0604e..a581ea1 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -92,11 +92,11 @@ bool cmAddLibraryCommand
       }
     }
 
-  /* ideally we should check whether for the linker language of the target 
+  /* ideally we should check whether for the linker language of the target
     CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to
-    STATIC. But at this point we know only the name of the target, but not 
+    STATIC. But at this point we know only the name of the target, but not
     yet its linker language. */
-  if ((type != cmTarget::STATIC_LIBRARY) && 
+  if ((type != cmTarget::STATIC_LIBRARY) &&
        (this->Makefile->GetCMakeInstance()->GetPropertyAsBool(
                                       "TARGET_SUPPORTS_SHARED_LIBS") == false))
     {
@@ -172,9 +172,9 @@ bool cmAddLibraryCommand
     }
 
   std::vector<std::string> srclists;
-  while (s != args.end()) 
+  while (s != args.end())
     {
-    srclists.push_back(*s);  
+    srclists.push_back(*s);
     ++s;
     }
 
@@ -194,7 +194,7 @@ bool cmAddLibraryCommand
     delete automoc;
     automoc = 0;
     }
-  
+
   return true;
 }
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=58b7fe65453f1d4b25537950de2277af2951fd85
commit 58b7fe65453f1d4b25537950de2277af2951fd85
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Sun Aug 14 17:17:01 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 17:17:01 2011 +0200

    Use cout instead of printf()
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 316d824..b03e9cf 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -405,7 +405,7 @@ bool cmQtAutomoc::RunAutomocQt4()
     const std::string &absFilename = *it;
     if (this->Verbose)
       {
-      printf("Checking -%s-\n", absFilename.c_str());
+      std::cout << "AUTOMOC: Checking " << absFilename << std::endl;
       }
     this->ParseCppFile(absFilename, includedMocs, notIncludedMocs);
     }
@@ -419,7 +419,7 @@ bool cmQtAutomoc::RunAutomocQt4()
     const std::string &absFilename = *it;
     if (this->Verbose)
       {
-      printf("Checking -%s-\n", absFilename.c_str());
+      std::cout << "AUTOMOC: Checking " << absFilename << std::endl;
       }
     if (includedMocs.find(absFilename) == includedMocs.end()
               && notIncludedMocs.find(absFilename) == notIncludedMocs.end())
@@ -527,7 +527,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename,
   const std::string contentsString = this->ReadAll(absFilename);
   if (contentsString.empty())
     {
-    std::cerr << "automoc4: empty source file: " << absFilename << std::endl;
+    std::cerr << "AUTOMOC: empty source file: " << absFilename << std::endl;
     return;
     }
   const std::string absPath = cmsys::SystemTools::GetFilenamePath(
@@ -648,7 +648,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename,
               }
             if (!headerFound)
               {
-              std::cerr << "automoc4: The file \"" << absFilename
+              std::cerr << "AUTOMOC: The file \"" << absFilename
                         << "\" includes the moc file \"" << currentMoc
                         << "\", but neither \"" << absPath << basename
                         << '{' << this->Join(headerExtensions, ',')
@@ -660,7 +660,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename,
             }
           else
             {
-            std::cerr << "automoc4: The file \"" << absFilename
+            std::cerr << "AUTOMOC: The file \"" << absFilename
                       << "\" includes the moc file \"" << currentMoc
                       << "\", but \"" << absPath << basename << '{'
                       << this->Join(headerExtensions, ',') << '}'
@@ -728,9 +728,9 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
       {
       for(int i=0; i<command.size(); i++)
         {
-        printf("%s ", command[i].c_str());
+        std::cout << command[i] << " ";
         }
-      printf("\n");
+      std::cout << std::endl;
       }
 
     std::string output;
@@ -738,7 +738,7 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
     bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal);
     if (!result || retVal)
       {
-      std::cerr << "automoc4: process for " << mocFilePath << " failed:\n"
+      std::cerr << "AUTOMOC: process for " << mocFilePath << " failed:\n"
                 << output << std::endl;
       this->RunMocFailed = true;
       cmSystemTools::RemoveFile(mocFilePath.c_str());

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=72caf4d1787bc464f68954853a4edc3cf169a5f0
commit 72caf4d1787bc464f68954853a4edc3cf169a5f0
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Sun Aug 14 17:06:34 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 17:06:34 2011 +0200

    Add the generated automoc.cpp file to the cleaned files
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 6e8c77e..316d824 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -140,6 +140,8 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
   makefile->GetOrCreateSource(mocCppFile.c_str(), true);
   srcs.push_back(mocCppFile);
 
+  makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
+                           mocCppFile.c_str(), false);
 }
 
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ddb517d014bf2245b38a0b56c9b7e98e6aaf7988
commit ddb517d014bf2245b38a0b56c9b7e98e6aaf7988
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Sun Aug 14 16:43:04 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 16:43:04 2011 +0200

    Color output when running moc
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 2add7c0..6e8c77e 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -4,14 +4,31 @@
 #include "cmSourceFile.h"
 #include "cmSystemTools.h"
 
+# include <cmsys/Terminal.h>
+
 #include "cmQtAutomoc.h"
 
 
 cmQtAutomoc::cmQtAutomoc()
 :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
+,ColorOutput(true)
 ,RunMocFailed(false)
 ,GenerateAll(false)
 {
+
+  std::string colorEnv = "";
+  cmsys::SystemTools::GetEnv("COLOR", colorEnv);
+  if(!colorEnv.empty())
+    {
+    if(cmSystemTools::IsOn(colorEnv.c_str()))
+      {
+      this->ColorOutput = true;
+      }
+    else
+      {
+      this->ColorOutput = false;
+      }
+    }
 }
 
 
@@ -678,14 +695,11 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
       cmsys::SystemTools::MakeDirectory(mocDir.c_str());
       }
 
-/*    if (this->Verbose)
-      {
-      echoColor("Generating " + mocFilePath + " from " + sourceFile);
-      }
-    else
-      {
-      echoColor("Generating " + mocFileName);
-      }*/
+    std::string msg = "Generating ";
+    msg += mocFileName;
+    cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue
+                                           |cmsysTerminal_Color_ForegroundBold,
+                                     msg.c_str(), true, this->ColorOutput);
 
     std::vector<cmStdString> command;
     command.push_back(this->MocExecutable);
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index edb66f0..af77366 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -61,6 +61,7 @@ private:
   std::list<std::string> MocDefinitions;
 
   bool Verbose;
+  bool ColorOutput;
   bool RunMocFailed;
   bool GenerateAll;
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=93032953afb5bd939dceb3ce427f4b6fa50e2450
commit 93032953afb5bd939dceb3ce427f4b6fa50e2450
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Wed Aug 10 23:49:30 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:58:09 2011 +0200

    Initialize verbose based onb the env.var.
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 5bfb928..2add7c0 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -8,7 +8,7 @@
 
 
 cmQtAutomoc::cmQtAutomoc()
-:Verbose(true)
+:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0)
 ,RunMocFailed(false)
 ,GenerateAll(false)
 {

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=ace121534de464bc7da35694a93cfb8ccc3effb6
commit ace121534de464bc7da35694a93cfb8ccc3effb6
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Wed Aug 10 21:00:53 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:58:09 2011 +0200

    Move code for parsing a cpp-file from the big loop to separate function
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 64f6e5f..5bfb928 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -375,33 +375,6 @@ bool cmQtAutomoc::RunAutomocQt4()
   // key = moc source filepath, value = moc output filename
   std::map<std::string, std::string> notIncludedMocs;
 
-  cmsys::RegularExpression mocIncludeRegExp(
-              "[\n][ \t]*#[ \t]*include[ \t]+"
-              "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
-  cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]");
-  std::list<std::string> headerExtensions;
-#if defined(_WIN32)
-  // not case sensitive
-  headerExtensions.push_back(".h");
-  headerExtensions.push_back(".hpp");
-  headerExtensions.push_back(".hxx");
-#elif defined(__APPLE__)
-  headerExtensions.push_back(".h");
-  headerExtensions.push_back(".hpp");
-  headerExtensions.push_back(".hxx");
-
-  // detect case-sensitive filesystem
-  long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE);
-  if (caseSensitive == 1)
-  {
-    headerExtensions.push_back(".H");
-  }
-#else
-  headerExtensions.push_back(".h");
-  headerExtensions.push_back(".hpp");
-  headerExtensions.push_back(".hxx");
-  headerExtensions.push_back(".H");
-#endif
 
   std::vector<std::string> sourceFiles;
   cmSystemTools::ExpandListArgument(this->Sources, sourceFiles);
@@ -415,162 +388,7 @@ bool cmQtAutomoc::RunAutomocQt4()
       {
       printf("Checking -%s-\n", absFilename.c_str());
       }
-
-    const std::string contentsString = this->ReadAll(absFilename);
-    if (contentsString.empty())
-      {
-      std::cerr << "automoc4: empty source file: " << absFilename << std::endl;
-      continue;
-      }
-    const std::string absPath = cmsys::SystemTools::GetFilenamePath(
-                cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
-
-    int matchOffset = 0;
-    if (!mocIncludeRegExp.find(contentsString.c_str()))
-      {
-      // no moc #include, look whether we need to create a moc from
-      // the .h nevertheless
-      const std::string basename =
-            cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
-      for(std::list<std::string>::const_iterator ext =
-                                                    headerExtensions.begin();
-          ext != headerExtensions.end();
-          ++ext)
-        {
-        const std::string headername = absPath + basename + (*ext);
-        if (cmsys::SystemTools::FileExists(headername.c_str())
-                && includedMocs.find(headername) == includedMocs.end()
-                && notIncludedMocs.find(headername) == notIncludedMocs.end())
-          {
-          const std::string currentMoc = "moc_" + basename + ".cpp";
-          const std::string contents = this->ReadAll(headername);
-          if (qObjectRegExp.find(contents))
-            {
-            //std::cout << "header contains Q_OBJECT macro";
-            notIncludedMocs[headername] = currentMoc;
-            }
-          break;
-          }
-        }
-      for(std::list<std::string>::const_iterator ext =
-                                                    headerExtensions.begin();
-          ext != headerExtensions.end();
-          ++ext)
-        {
-        const std::string privateHeaderName = absPath+basename+"_p"+(*ext);
-        if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())
-           && includedMocs.find(privateHeaderName) == includedMocs.end()
-           && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end())
-          {
-          const std::string currentMoc = "moc_" + basename + "_p.cpp";
-          const std::string contents = this->ReadAll(privateHeaderName);
-          if (qObjectRegExp.find(contents))
-            {
-            //std::cout << "header contains Q_OBJECT macro";
-            notIncludedMocs[privateHeaderName] = currentMoc;
-            }
-          break;
-          }
-        }
-      }
-    else
-      {
-      // for every moc include in the file
-      do
-        {
-        const std::string currentMoc = mocIncludeRegExp.match(1);
-        //std::cout << "found moc include: " << currentMoc << std::endl;
-
-        std::string basename = cmsys::SystemTools::
-                                  GetFilenameWithoutLastExtension(currentMoc);
-        const bool moc_style = this->StartsWith(basename, "moc_");
-
-        // If the moc include is of the moc_foo.cpp style we expect
-        // the Q_OBJECT class declaration in a header file.
-        // If the moc include is of the foo.moc style we need to look for
-        // a Q_OBJECT macro in the current source file, if it contains the
-        // macro we generate the moc file from the source file, else from the
-        // header.
-        // Q_OBJECT
-        if (moc_style || !qObjectRegExp.find(contentsString))
-          {
-          if (moc_style)
-            {
-            // basename should be the part of the moc filename used for
-            // finding the correct header, so we need to remove the moc_ part
-            basename = basename.substr(4);
-            }
-
-          bool headerFound = false;
-          for(std::list<std::string>::const_iterator ext =
-                                                    headerExtensions.begin();
-              ext != headerExtensions.end();
-              ++ext)
-            {
-            const std::string &sourceFilePath = absPath + basename + (*ext);
-            if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
-              {
-              headerFound = true;
-              includedMocs[sourceFilePath] = currentMoc;
-              notIncludedMocs.erase(sourceFilePath);
-              break;
-              }
-            }
-          if (!headerFound)
-            {
-            // the moc file is in a subdir => look for the header in the
-            // same subdir
-            if (currentMoc.find_first_of('/') != std::string::npos)
-              {
-              const std::string &filepath = absPath
-                      + cmsys::SystemTools::GetFilenamePath(currentMoc)
-                      + '/' + basename;
-
-              for(std::list<std::string>::const_iterator ext =
-                                                    headerExtensions.begin();
-                  ext != headerExtensions.end();
-                  ++ext)
-                {
-                const std::string &sourceFilePath = filepath + (*ext);
-                if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
-                  {
-                  headerFound = true;
-                  includedMocs[sourceFilePath] = currentMoc;
-                  notIncludedMocs.erase(sourceFilePath);
-                  break;
-                  }
-                }
-              if (!headerFound)
-                {
-                std::cerr << "automoc4: The file \"" << absFilename
-                          << "\" includes the moc file \"" << currentMoc
-                          << "\", but neither \"" << absPath << basename
-                          << '{' << this->Join(headerExtensions, ',')
-                          << "}\" nor \"" << filepath << '{'
-                          << this->Join(headerExtensions, ',') << '}'
-                          << "\" exist." << std::endl;
-                ::exit(EXIT_FAILURE);
-                }
-              }
-            else
-              {
-              std::cerr << "automoc4: The file \"" << absFilename
-                        << "\" includes the moc file \"" << currentMoc
-                        << "\", but \"" << absPath << basename << '{'
-                        << this->Join(headerExtensions, ',') << '}'
-                        << "\" does not exist." << std::endl;
-              ::exit(EXIT_FAILURE);
-              }
-            }
-          }
-        else
-          {
-          includedMocs[absFilename] = currentMoc;
-          notIncludedMocs.erase(absFilename);
-          }
-        matchOffset += mocIncludeRegExp.end();
-        } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
-      }
+    this->ParseCppFile(absFilename, includedMocs, notIncludedMocs);
     }
 
   std::vector<std::string> headerFiles;
@@ -662,6 +480,187 @@ bool cmQtAutomoc::RunAutomocQt4()
 }
 
 
+void cmQtAutomoc::ParseCppFile(const std::string& absFilename,
+                           std::map<std::string, std::string>& includedMocs,
+                           std::map<std::string, std::string>& notIncludedMocs)
+{
+  cmsys::RegularExpression mocIncludeRegExp(
+              "[\n][ \t]*#[ \t]*include[ \t]+"
+              "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
+  cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]");
+  std::list<std::string> headerExtensions;
+  headerExtensions.push_back(".h");
+  headerExtensions.push_back(".hpp");
+  headerExtensions.push_back(".hxx");
+#if defined(_WIN32)
+  // not case sensitive, don't add ".H"
+#elif defined(__APPLE__)
+  // detect case-sensitive filesystem
+  long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE);
+  if (caseSensitive == 1)
+  {
+    headerExtensions.push_back(".H");
+  }
+#else
+  headerExtensions.push_back(".H");
+#endif
+
+  const std::string contentsString = this->ReadAll(absFilename);
+  if (contentsString.empty())
+    {
+    std::cerr << "automoc4: empty source file: " << absFilename << std::endl;
+    return;
+    }
+  const std::string absPath = cmsys::SystemTools::GetFilenamePath(
+                   cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
+
+  int matchOffset = 0;
+  if (!mocIncludeRegExp.find(contentsString.c_str()))
+    {
+    // no moc #include, look whether we need to create a moc from
+    // the .h nevertheless
+    const std::string basename =
+              cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
+    for(std::list<std::string>::const_iterator ext = headerExtensions.begin();
+        ext != headerExtensions.end();
+        ++ext)
+      {
+      const std::string headername = absPath + basename + (*ext);
+      if (cmsys::SystemTools::FileExists(headername.c_str())
+              && includedMocs.find(headername) == includedMocs.end()
+              && notIncludedMocs.find(headername) == notIncludedMocs.end())
+        {
+        const std::string currentMoc = "moc_" + basename + ".cpp";
+        const std::string contents = this->ReadAll(headername);
+        if (qObjectRegExp.find(contents))
+          {
+          //std::cout << "header contains Q_OBJECT macro";
+          notIncludedMocs[headername] = currentMoc;
+          }
+        break;
+        }
+      }
+    for(std::list<std::string>::const_iterator ext = headerExtensions.begin();
+        ext != headerExtensions.end();
+        ++ext)
+      {
+      const std::string privateHeaderName = absPath+basename+"_p"+(*ext);
+      if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())
+          && includedMocs.find(privateHeaderName) == includedMocs.end()
+          && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end())
+        {
+        const std::string currentMoc = "moc_" + basename + "_p.cpp";
+        const std::string contents = this->ReadAll(privateHeaderName);
+        if (qObjectRegExp.find(contents))
+          {
+          //std::cout << "header contains Q_OBJECT macro";
+          notIncludedMocs[privateHeaderName] = currentMoc;
+          }
+        break;
+        }
+      }
+    }
+  else
+    {
+    // for every moc include in the file
+    do
+      {
+      const std::string currentMoc = mocIncludeRegExp.match(1);
+      //std::cout << "found moc include: " << currentMoc << std::endl;
+
+      std::string basename = cmsys::SystemTools::
+                                   GetFilenameWithoutLastExtension(currentMoc);
+      const bool moc_style = this->StartsWith(basename, "moc_");
+
+      // If the moc include is of the moc_foo.cpp style we expect
+      // the Q_OBJECT class declaration in a header file.
+      // If the moc include is of the foo.moc style we need to look for
+      // a Q_OBJECT macro in the current source file, if it contains the
+      // macro we generate the moc file from the source file, else from the
+      // header.
+      // Q_OBJECT
+      if (moc_style || !qObjectRegExp.find(contentsString))
+        {
+        if (moc_style)
+          {
+          // basename should be the part of the moc filename used for
+          // finding the correct header, so we need to remove the moc_ part
+          basename = basename.substr(4);
+          }
+
+        bool headerFound = false;
+        for(std::list<std::string>::const_iterator ext =
+                                                      headerExtensions.begin();
+            ext != headerExtensions.end();
+            ++ext)
+          {
+          const std::string &sourceFilePath = absPath + basename + (*ext);
+          if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
+            {
+            headerFound = true;
+            includedMocs[sourceFilePath] = currentMoc;
+            notIncludedMocs.erase(sourceFilePath);
+            break;
+            }
+          }
+        if (!headerFound)
+          {
+          // the moc file is in a subdir => look for the header in the
+          // same subdir
+          if (currentMoc.find_first_of('/') != std::string::npos)
+            {
+            const std::string &filepath = absPath
+                    + cmsys::SystemTools::GetFilenamePath(currentMoc)
+                    + '/' + basename;
+
+            for(std::list<std::string>::const_iterator ext =
+                                                      headerExtensions.begin();
+                ext != headerExtensions.end();
+                ++ext)
+              {
+              const std::string &sourceFilePath = filepath + (*ext);
+              if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
+                {
+                headerFound = true;
+                includedMocs[sourceFilePath] = currentMoc;
+                notIncludedMocs.erase(sourceFilePath);
+                break;
+                }
+              }
+            if (!headerFound)
+              {
+              std::cerr << "automoc4: The file \"" << absFilename
+                        << "\" includes the moc file \"" << currentMoc
+                        << "\", but neither \"" << absPath << basename
+                        << '{' << this->Join(headerExtensions, ',')
+                        << "}\" nor \"" << filepath << '{'
+                        << this->Join(headerExtensions, ',') << '}'
+                        << "\" exist." << std::endl;
+              ::exit(EXIT_FAILURE);
+              }
+            }
+          else
+            {
+            std::cerr << "automoc4: The file \"" << absFilename
+                      << "\" includes the moc file \"" << currentMoc
+                      << "\", but \"" << absPath << basename << '{'
+                      << this->Join(headerExtensions, ',') << '}'
+                      << "\" does not exist." << std::endl;
+            ::exit(EXIT_FAILURE);
+            }
+          }
+        }
+      else
+        {
+        includedMocs[absFilename] = currentMoc;
+        notIncludedMocs.erase(absFilename);
+        }
+      matchOffset += mocIncludeRegExp.end();
+      } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
+    }
+}
+
+
 bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
                               const std::string& mocFileName)
 {
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index e573610..edb66f0 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -29,6 +29,10 @@ private:
   bool RunAutomocQt4();
   bool GenerateMoc(const std::string& sourceFile,
                    const std::string& mocFileName);
+  void ParseCppFile(const std::string& absFilename,
+                    std::map<std::string, std::string>& includedMocs,
+                    std::map<std::string, std::string>& notIncludedMocs);
+
   void Init();
 
   std::string Join(const std::list<std::string>& lst, char separator);

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=735a5bb321ff7b92bebe2769e98a1d6317e88d27
commit 735a5bb321ff7b92bebe2769e98a1d6317e88d27
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Wed Aug 10 20:45:22 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:58:09 2011 +0200

    Fix line lengths
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 1431551..64f6e5f 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -7,8 +7,6 @@
 #include "cmQtAutomoc.h"
 
 
-#define TRACE_LINE() printf(" %s %d\n", __PRETTY_FUNCTION__, __LINE__)
-
 cmQtAutomoc::cmQtAutomoc()
 :Verbose(true)
 ,RunMocFailed(false)
@@ -79,7 +77,8 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
     if ((skip==false) && (generated == false))
       {
       std::string ext = cmSystemTools::GetFilenameExtension(fileIt->c_str());
-      cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(ext.c_str());
+      cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
+                                                                  ext.c_str());
       if (fileType == cmSystemTools::CXX_FILE_FORMAT)
         {
         _moc_files += sepFiles;
@@ -200,11 +199,13 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile,
   this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR");
   this->Sources = makefile->GetSafeDefinition("AM_SOURCES");
   this->Headers = makefile->GetSafeDefinition("AM_HEADERS");
-  this->IncludeProjectDirsBefore = makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
+  this->IncludeProjectDirsBefore = makefile->IsOn(
+                                "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
   this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
   this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
   this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
-  this->MocCompileDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS");
+  this->MocCompileDefinitionsStr = makefile->GetSafeDefinition(
+                                                 "AM_MOC_COMPILE_DEFINITIONS");
   this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS");
   this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES");
   this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
@@ -361,13 +362,18 @@ bool cmQtAutomoc::RunAutomocQt4()
     this->GenerateAll = true;
     }
 
-  // the program goes through all .cpp files to see which moc files are included. It is not really
-  // interesting how the moc file is named, but what file the moc is created from. Once a moc is
-  // included the same moc may not be included in the _automoc.cpp file anymore. OTOH if there's a
-  // header containing Q_OBJECT where no corresponding moc file is included anywhere a
-  // moc_<filename>.cpp file is created and included in the _automoc.cpp file.
-  std::map<std::string, std::string> includedMocs;    // key = moc source filepath, value = moc output filepath
-  std::map<std::string, std::string> notIncludedMocs; // key = moc source filepath, value = moc output filename
+  // the program goes through all .cpp files to see which moc files are
+  // included. It is not really interesting how the moc file is named, but
+  // what file the moc is created from. Once a moc is included the same moc
+  // may not be included in the _automoc.cpp file anymore. OTOH if there's a
+  // header containing Q_OBJECT where no corresponding moc file is included
+  // anywhere a moc_<filename>.cpp file is created and included in
+  // the _automoc.cpp file.
+
+  // key = moc source filepath, value = moc output filepath
+  std::map<std::string, std::string> includedMocs;
+  // key = moc source filepath, value = moc output filename
+  std::map<std::string, std::string> notIncludedMocs;
 
   cmsys::RegularExpression mocIncludeRegExp(
               "[\n][ \t]*#[ \t]*include[ \t]+"
@@ -422,8 +428,8 @@ bool cmQtAutomoc::RunAutomocQt4()
     int matchOffset = 0;
     if (!mocIncludeRegExp.find(contentsString.c_str()))
       {
-      // no moc #include, look whether we need to create a moc from the .h nevertheless
-      //std::cout << "no moc #include in the .cpp file";
+      // no moc #include, look whether we need to create a moc from
+      // the .h nevertheless
       const std::string basename =
             cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
       for(std::list<std::string>::const_iterator ext =
@@ -453,8 +459,8 @@ bool cmQtAutomoc::RunAutomocQt4()
         {
         const std::string privateHeaderName = absPath+basename+"_p"+(*ext);
         if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())
-                && includedMocs.find(privateHeaderName) == includedMocs.end()
-                && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end())
+           && includedMocs.find(privateHeaderName) == includedMocs.end()
+           && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end())
           {
           const std::string currentMoc = "moc_" + basename + "_p.cpp";
           const std::string contents = this->ReadAll(privateHeaderName);
@@ -479,20 +485,19 @@ bool cmQtAutomoc::RunAutomocQt4()
                                   GetFilenameWithoutLastExtension(currentMoc);
         const bool moc_style = this->StartsWith(basename, "moc_");
 
-        // If the moc include is of the moc_foo.cpp style we expect the Q_OBJECT class
-        // declaration in a header file.
-        // If the moc include is of the foo.moc style we need to look for a Q_OBJECT
-        // macro in the current source file, if it contains the macro we generate the
-        // moc file from the source file, else from the header.
-        //
-        // TODO: currently any .moc file name will be used if the source contains
+        // If the moc include is of the moc_foo.cpp style we expect
+        // the Q_OBJECT class declaration in a header file.
+        // If the moc include is of the foo.moc style we need to look for
+        // a Q_OBJECT macro in the current source file, if it contains the
+        // macro we generate the moc file from the source file, else from the
+        // header.
         // Q_OBJECT
         if (moc_style || !qObjectRegExp.find(contentsString))
           {
           if (moc_style)
             {
-            // basename should be the part of the moc filename used for finding the
-            // correct header, so we need to remove the moc_ part
+            // basename should be the part of the moc filename used for
+            // finding the correct header, so we need to remove the moc_ part
             basename = basename.substr(4);
             }
 
@@ -513,7 +518,8 @@ bool cmQtAutomoc::RunAutomocQt4()
             }
           if (!headerFound)
             {
-            // the moc file is in a subdir => look for the header in the same subdir
+            // the moc file is in a subdir => look for the header in the
+            // same subdir
             if (currentMoc.find_first_of('/') != std::string::npos)
               {
               const std::string &filepath = absPath
@@ -536,20 +542,23 @@ bool cmQtAutomoc::RunAutomocQt4()
                 }
               if (!headerFound)
                 {
-                std::cerr << "automoc4: The file \"" << absFilename <<
-                    "\" includes the moc file \"" << currentMoc << "\", but neither \"" <<
-                    absPath + basename + '{' + this->Join(headerExtensions, ',') + "}\" nor \"" <<
-                    filepath + '{' + this->Join(headerExtensions, ',') + '}' <<
-                    "\" exist." << std::endl;
+                std::cerr << "automoc4: The file \"" << absFilename
+                          << "\" includes the moc file \"" << currentMoc
+                          << "\", but neither \"" << absPath << basename
+                          << '{' << this->Join(headerExtensions, ',')
+                          << "}\" nor \"" << filepath << '{'
+                          << this->Join(headerExtensions, ',') << '}'
+                          << "\" exist." << std::endl;
                 ::exit(EXIT_FAILURE);
                 }
               }
             else
               {
-              std::cerr << "automoc4: The file \"" << absFilename <<
-                  "\" includes the moc file \"" << currentMoc << "\", but \"" <<
-                  absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' <<
-                  "\" does not exist." << std::endl;
+              std::cerr << "automoc4: The file \"" << absFilename
+                        << "\" includes the moc file \"" << currentMoc
+                        << "\", but \"" << absPath << basename << '{'
+                        << this->Join(headerExtensions, ',') << '}'
+                        << "\" does not exist." << std::endl;
               ::exit(EXIT_FAILURE);
               }
             }
@@ -578,17 +587,20 @@ bool cmQtAutomoc::RunAutomocQt4()
     if (includedMocs.find(absFilename) == includedMocs.end()
               && notIncludedMocs.find(absFilename) == notIncludedMocs.end())
       {
-      // if this header is not getting processed yet and is explicitly mentioned for the
-      // automoc the moc is run unconditionally on the header and the resulting file is
-      // included in the _automoc.cpp file (unless there's a .cpp file later on that
-      // includes the moc from this header)
-      const std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp";
+      // if this header is not getting processed yet and is explicitly
+      // mentioned for the automoc the moc is run unconditionally on the
+      // header and the resulting file is included in the _automoc.cpp file
+      // (unless there's a .cpp file later on that includes the moc from
+      // this header)
+      const std::string currentMoc = "moc_" + cmsys::SystemTools::
+                         GetFilenameWithoutLastExtension(absFilename) + ".cpp";
       notIncludedMocs[absFilename] = currentMoc;
       }
     }
 
   // run moc on all the moc's that are #included in source files
-  for(std::map<std::string, std::string>::const_iterator it = includedMocs.begin();
+  for(std::map<std::string, std::string>::const_iterator
+                                                     it = includedMocs.begin();
       it != includedMocs.end();
       ++it)
     {
@@ -605,8 +617,10 @@ bool cmQtAutomoc::RunAutomocQt4()
     }
   else
     {
-    // run moc on the remaining headers and include them in the _automoc.cpp file
-    for(std::map<std::string, std::string>::const_iterator it = notIncludedMocs.begin();
+    // run moc on the remaining headers and include them in
+    // the _automoc.cpp file
+    for(std::map<std::string, std::string>::const_iterator
+                                                  it = notIncludedMocs.begin();
         it != notIncludedMocs.end();
         ++it)
       {
@@ -621,8 +635,6 @@ bool cmQtAutomoc::RunAutomocQt4()
 
   if (this->RunMocFailed)
     {
-    // if any moc process failed we don't want to touch the _automoc.cpp file so that
-    // automoc4 is rerun until the issue is fixed
     std::cerr << "returning failed.."<< std::endl;
     return false;
     }
@@ -638,7 +650,6 @@ bool cmQtAutomoc::RunAutomocQt4()
       return true;
       }
     }
-  // either the contents of the _automoc.cpp file or one of the mocs included by it have changed
 
   // source file that includes all remaining moc files (_automoc.cpp file)
   std::fstream outfile;
@@ -654,7 +665,6 @@ bool cmQtAutomoc::RunAutomocQt4()
 bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
                               const std::string& mocFileName)
 {
-    //std::cout << "AutoMoc::generateMoc" << sourceFile << mocFileName << std::endl;
   const std::string mocFilePath = this->Builddir + mocFileName;
   int sourceNewerThanMoc = 0;
   bool success = cmsys::SystemTools::FileTimeCompare(sourceFile.c_str(),
@@ -710,10 +720,11 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
 
     std::string output;
     int retVal = 0;
-    const bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal);
+    bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal);
     if (!result || retVal)
       {
-      std::cerr << "automoc4: process for " << mocFilePath << " failed:\n" << output << std::endl;
+      std::cerr << "automoc4: process for " << mocFilePath << " failed:\n"
+                << output << std::endl;
       this->RunMocFailed = true;
       cmSystemTools::RemoveFile(mocFilePath.c_str());
       }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=83b730cd1aeeafc05473d163e13fb5489817c149
commit 83b730cd1aeeafc05473d163e13fb5489817c149
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Wed Aug 10 19:51:07 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:58:08 2011 +0200

    Add AUTOMOC to the add_library() command
    
    Alex

diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index f522cee..2e0604e 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -12,6 +12,7 @@
 #include "cmAddLibraryCommand.h"
 
 #include "cmake.h"
+#include "cmQtAutomoc.h"
 
 // cmLibraryCommand
 bool cmAddLibraryCommand
@@ -31,13 +32,14 @@ bool cmAddLibraryCommand
     }
   bool excludeFromAll = false;
   bool importTarget = false;
-  
+  bool doAutomoc = false;
+
   std::vector<std::string>::const_iterator s = args.begin();
 
   std::string libName = *s;
 
   ++s;
-  
+
   // If the second argument is "SHARED" or "STATIC", then it controls
   // the type of library.  Otherwise, it is treated as a source or
   // source list name. There may be two keyword arguments, check for them
@@ -79,6 +81,11 @@ bool cmAddLibraryCommand
       ++s;
       importTarget = true;
       }
+    else if (*s == "AUTOMOC")
+      {
+      ++s;
+      doAutomoc = true;
+      }
     else
       {
       break;
@@ -103,16 +110,23 @@ bool cmAddLibraryCommand
     type = cmTarget::STATIC_LIBRARY;
     }
 
-  // The IMPORTED signature requires a type to be specified explicitly.
-  if(importTarget && !haveSpecifiedType)
-    {
-    this->SetError("called with IMPORTED argument but no library type.");
-    return false;
-    }
-
   // Handle imported target creation.
   if(importTarget)
     {
+    // The IMPORTED signature requires a type to be specified explicitly.
+    if (!haveSpecifiedType)
+      {
+      this->SetError("called with IMPORTED argument but no library type.");
+      return false;
+      }
+
+    // Don't run automoc on an imported library
+    if (doAutomoc)
+      {
+      this->SetError("cannot be called with AUTOMOC for an IMPORTED library.");
+      return false;
+      }
+
     // Make sure the target does not already exist.
     if(this->Makefile->FindTargetToUse(libName.c_str()))
       {
@@ -164,8 +178,22 @@ bool cmAddLibraryCommand
     ++s;
     }
 
-  this->Makefile->AddLibrary(libName.c_str(), type, srclists,
-                             excludeFromAll);
+  cmQtAutomoc* automoc = 0;
+  if ( doAutomoc )
+    {
+    automoc = new cmQtAutomoc;
+    automoc->SetupAutomocTarget(this->Makefile, libName.c_str(), srclists);
+    }
+
+  cmTarget* tgt =this->Makefile->AddLibrary(libName.c_str(), type, srclists,
+                                            excludeFromAll);
+
+  if ( automoc )
+    {
+    automoc->AddTargetDependency(this->Makefile, tgt);
+    delete automoc;
+    automoc = 0;
+    }
   
   return true;
 }
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index a5cdee4..45165e5 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -1886,7 +1886,7 @@ void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
 }
 
 
-void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
+cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
                             const std::vector<std::string> &srcs,
                             bool excludeFromAll)
 {
@@ -1909,6 +1909,7 @@ void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
     }
   target->AddSources(srcs);
   this->AddGlobalLinkInformation(lname, *target);
+  return target;
 }
 
 cmTarget* cmMakefile::AddExecutable(const char *exeName,
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index c01bb5d..618f4f3 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -325,7 +325,7 @@ public:
   /**
    * Set the name of the library.
    */
-  void AddLibrary(const char *libname, cmTarget::TargetType type,
+  cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type,
                   const std::vector<std::string> &srcs,
                   bool excludeFromAll = false);
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=126c6ead7707ac29f3b2fa779752025c7cc0da32
commit 126c6ead7707ac29f3b2fa779752025c7cc0da32
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 9 09:18:37 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:58:00 2011 +0200

    Add the cmake module required currently for automoc
    
    Alex

diff --git a/Modules/Automoc.cmake b/Modules/Automoc.cmake
new file mode 100644
index 0000000..1e77c96
--- /dev/null
+++ b/Modules/Automoc.cmake
@@ -0,0 +1,158 @@
+
+#  AUTOMOC4_MOC_HEADERS(<target> header1.h header2.h ...)
+#    Use this to add more header files to be processed with automoc4.
+#
+#  AUTOMOC4_ADD_EXECUTABLE(<target_NAME> src1 src2 ...)
+#    This macro does the same as ADD_EXECUTABLE, but additionally
+#    adds automoc4 handling for all source files.
+#
+# AUTOMOC4_ADD_LIBRARY(<target_NAME> src1 src2 ...)
+#    This macro does the same as ADD_LIBRARY, but additionally
+#    adds automoc4 handling for all source files.
+
+# Internal helper macro, may change or be removed anytime:
+# _ADD_AUTOMOC4_TARGET(<target_NAME> <SRCS_VAR>)
+#
+# Since version 0.9.88:
+# The following two macros are only to be used for KDE4 projects
+# and do something which makes sure automoc4 works for KDE. Don't
+# use them anywhere else. See kdelibs/cmake/modules/KDE4Macros.cmake.
+# _AUTOMOC4_KDE4_PRE_TARGET_HANDLING(<target_NAME> <SRCS_VAR>)
+# _AUTOMOC4_KDE4_POST_TARGET_HANDLING(<target_NAME>)
+
+#     Copyright (C) 2007 Matthias Kretz <kretz at kde.org>
+#     Copyright (C) 2008-2009 Alexander Neundorf <neundorf at kde.org>
+#
+#     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.
+#
+#     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+#     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+#     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+#     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+#     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+#     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+#     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+macro (AUTOMOC4_MOC_HEADERS _target_NAME)
+   set (_headers_to_moc)
+   foreach (_current_FILE ${ARGN})
+      get_filename_component(_suffix "${_current_FILE}" EXT)
+      if (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
+         list(APPEND _headers_to_moc ${_current_FILE})
+      else (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
+         message(STATUS "AUTOMOC4_MOC_HEADERS: ignoring non-header file ${_current_FILE}")
+      endif (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
+   endforeach (_current_FILE)
+   # need to create moc_<filename>.cpp file using automoc4
+   # and add it to the target
+   if(_headers_to_moc)
+       set(_automoc4_headers_${_target_NAME} "${_headers_to_moc}")
+   endif(_headers_to_moc)
+endmacro (AUTOMOC4_MOC_HEADERS)
+
+
+macro(_ADD_AUTOMOC4_TARGET _target_NAME _SRCS)
+   set(_moc_files)
+   set(_moc_headers)
+
+   # first list all explicitly set headers
+   foreach(_header_to_moc ${_automoc4_headers_${_target_NAME}} )
+      get_filename_component(_abs_header ${_header_to_moc} ABSOLUTE)
+      list(APPEND _moc_headers ${_abs_header})
+   endforeach(_header_to_moc)
+
+   # now add all the sources for the automoc
+   foreach (_current_FILE ${${_SRCS}})
+      get_filename_component(_abs_current_FILE "${_current_FILE}" ABSOLUTE)
+      get_source_file_property(_skip      "${_abs_current_FILE}" SKIP_AUTOMOC)
+      get_source_file_property(_generated "${_abs_current_FILE}" GENERATED)
+
+      if(NOT  _generated  AND NOT  _skip)
+         get_filename_component(_suffix "${_current_FILE}" EXT)
+         # skip every source file that's not C++
+         if(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL ".cxx" OR _suffix STREQUAL ".C" OR _suffix STREQUAL ".mm")
+             list(APPEND _moc_files ${_abs_current_FILE})
+         endif(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL ".cxx" OR _suffix STREQUAL ".C" OR _suffix STREQUAL ".mm")
+      endif(NOT  _generated  AND NOT  _skip)
+   endforeach (_current_FILE)
+
+   if(_moc_files OR _moc_headers)
+      set(_automoc_source "${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}.cpp")
+      get_directory_property(_moc_incs INCLUDE_DIRECTORIES)
+      get_directory_property(_moc_defs DEFINITIONS)
+      get_directory_property(_moc_cdefs COMPILE_DEFINITIONS)
+
+      # configure_file replaces _moc_files, _moc_incs, _moc_cdefs and _moc_defs
+      set(_automocTargetDir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target_NAME}.dir/" )
+      set(AM_TARGET_NAME ${_target_NAME})
+      configure_file(${CMAKE_ROOT}/Modules/AutomocInfo.cmake.in ${_automocTargetDir}/AutomocInfo.cmake @ONLY)
+
+      add_custom_target(${_target_NAME}
+         COMMAND ${CMAKE_COMMAND} -E cmake_automoc "${_automocTargetDir}" )
+
+      set_source_files_properties(${_automoc_source} PROPERTIES GENERATED TRUE)
+      get_directory_property(_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
+      list(APPEND _extra_clean_files "${_automoc_source}")
+      set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${_extra_clean_files}")
+      set(${_SRCS} ${_automoc_source} ${${_SRCS}})
+   endif(_moc_files OR _moc_headers)
+endmacro(_ADD_AUTOMOC4_TARGET)
+
+
+macro(AUTOMOC4_ADD_EXECUTABLE _target_NAME)
+   set(_SRCS ${ARGN})
+
+   set(_add_executable_param)
+   foreach(_argName "WIN32" "MACOSX_BUNDLE" "EXCLUDE_FROM_ALL")
+      list(FIND _SRCS ${_argName} _index)
+      if(_index GREATER -1)
+         list(APPEND _add_executable_param ${_argName})
+         list(REMOVE_AT _SRCS ${_index})
+      endif(_index GREATER -1)
+   endforeach(_argName)
+
+   _add_automoc4_target("${_target_NAME}_automoc" _SRCS)
+   add_executable(${_target_NAME} ${_add_executable_param} ${_SRCS})
+   add_dependencies(${_target_NAME} "${_target_NAME}_automoc")
+
+endmacro(AUTOMOC4_ADD_EXECUTABLE)
+
+
+macro(AUTOMOC4_ADD_LIBRARY _target_NAME)
+   set(_SRCS ${ARGN})
+
+   set(_add_executable_param)
+   foreach(_argName "STATIC" "SHARED" "MODULE" "EXCLUDE_FROM_ALL")
+      list(FIND _SRCS ${_argName} _index)
+      if(_index GREATER -1)
+         list(APPEND _add_executable_param ${_argName})
+         list(REMOVE_AT _SRCS ${_index})
+      endif(_index GREATER -1)
+   endforeach(_argName)
+
+   _add_automoc4_target("${_target_NAME}_automoc" _SRCS)
+   add_library(${_target_NAME} ${_add_executable_param} ${_SRCS})
+   add_dependencies(${_target_NAME} "${_target_NAME}_automoc")
+endmacro(AUTOMOC4_ADD_LIBRARY)
+
+
+macro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING _target _srcs)
+   _add_automoc4_target("${_target}_automoc" ${_srcs})
+endmacro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING)
+
+
+macro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING _target)
+   add_dependencies(${_target} "${_target}_automoc")
+endmacro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING)
diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in
new file mode 100644
index 0000000..2dc3aa2
--- /dev/null
+++ b/Modules/AutomocInfo.cmake.in
@@ -0,0 +1,13 @@
+set(AM_SOURCES "@_moc_files@" )
+set(AM_HEADERS "@_moc_headers@" )
+set(AM_MOC_COMPILE_DEFINITIONS "@_moc_compile_defs@")
+set(AM_MOC_DEFINITIONS "@_moc_defs@")
+set(AM_MOC_INCLUDES "@_moc_incs@")
+set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@")
+set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/")
+set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/")
+set(AM_QT_MOC_EXECUTABLE "@QT_MOC_EXECUTABLE@")
+set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/")
+set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/")
+set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" )
+set(AM_TARGET_NAME "@_moc_target_name@")
diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx
index a625c47..9710d20 100644
--- a/Source/cmAddExecutableCommand.cxx
+++ b/Source/cmAddExecutableCommand.cxx
@@ -10,6 +10,7 @@
   See the License for more information.
 ============================================================================*/
 #include "cmAddExecutableCommand.h"
+#include "cmQtAutomoc.h"
 
 // cmExecutableCommand
 bool cmAddExecutableCommand
@@ -29,6 +30,7 @@ bool cmAddExecutableCommand
   bool use_macbundle = false;
   bool excludeFromAll = false;
   bool importTarget = false;
+  bool doAutomoc = false;
   while ( s != args.end() )
     {
     if (*s == "WIN32")
@@ -41,6 +43,11 @@ bool cmAddExecutableCommand
       ++s;
       use_macbundle = true;
       }
+    else if ( *s == "AUTOMOC" )
+      {
+      ++s;
+      doAutomoc = true;
+      }
     else if(*s == "EXCLUDE_FROM_ALL")
       {
       ++s;
@@ -58,12 +65,18 @@ bool cmAddExecutableCommand
     }
 
   // Special modifiers are not allowed with IMPORTED signature.
-  if(importTarget && (use_win32 || use_macbundle || excludeFromAll))
+  if(importTarget
+      && (use_win32 || use_macbundle || excludeFromAll  || doAutomoc))
     {
     if(use_win32)
       {
       this->SetError("may not be given WIN32 for an IMPORTED target.");
       }
+    else if(doAutomoc)
+      {
+      this->SetError(
+        "may not be given AUTOMOC for an IMPORTED target.");
+      }
     else if(use_macbundle)
       {
       this->SetError(
@@ -113,6 +126,14 @@ bool cmAddExecutableCommand
     }
 
   std::vector<std::string> srclists(s, args.end());
+  cmQtAutomoc* automoc = 0;
+  if ( doAutomoc )
+    {
+    automoc = new cmQtAutomoc;
+    automoc->SetupAutomocTarget(this->Makefile, exename.c_str(), srclists);
+    }
+
+
   cmTarget* tgt = this->Makefile->AddExecutable(exename.c_str(), srclists,
                                                 excludeFromAll);
   if ( use_win32 )
@@ -124,5 +145,12 @@ bool cmAddExecutableCommand
     tgt->SetProperty("MACOSX_BUNDLE", "ON");
     }
 
+  if ( automoc )
+    {
+    automoc->AddTargetDependency(this->Makefile, tgt);
+    delete automoc;
+    automoc = 0;
+    }
+
   return true;
 }
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 5494b2a..1431551 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -1,6 +1,7 @@
 #include "cmGlobalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmMakefile.h"
+#include "cmSourceFile.h"
 #include "cmSystemTools.h"
 
 #include "cmQtAutomoc.h"
@@ -16,6 +17,131 @@ cmQtAutomoc::cmQtAutomoc()
 }
 
 
+void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile,
+                                     const char* targetName,
+                                     std::vector<std::string>& srcs)
+{
+  // don't do anything if there is no Qt4:
+  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+  if (qtMajorVersion != "4")
+    {
+    return;
+    }
+
+  std::string automocTargetName = targetName;
+  automocTargetName += "_automoc";
+
+  std::string targetDir = makefile->GetCurrentOutputDirectory();
+  targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
+  targetDir += "/";
+  targetDir += automocTargetName;
+  targetDir += ".dir/";
+
+  cmCustomCommandLine currentLine;
+  currentLine.push_back(makefile->GetCMakeInstance()->GetCMakeCommand());
+  currentLine.push_back("-E");
+  currentLine.push_back("cmake_automoc");
+  currentLine.push_back(targetDir);
+
+  cmCustomCommandLines commandLines;
+  commandLines.push_back(currentLine);
+
+  std::string workingDirectory = cmSystemTools::CollapseFullPath(
+                                    "", makefile->GetCurrentOutputDirectory());
+
+  std::vector<std::string> depends;
+
+  cmTarget* target = makefile->AddUtilityCommand(automocTargetName.c_str(),
+                                                 true,
+                                      workingDirectory.c_str(), depends,
+                                      commandLines, false, "Automoc target");
+
+  std::string _moc_files;
+  std::string _moc_headers;
+  const char* sepFiles = "";
+  const char* sepHeaders = "";
+  for(std::vector<std::string>::const_iterator fileIt = srcs.begin();
+      fileIt != srcs.end();
+      ++fileIt)
+    {
+    std::string absFile = cmSystemTools::CollapseFullPath(
+                             fileIt->c_str(), makefile->GetCurrentDirectory());
+
+    bool skip = false;
+    bool generated = false;
+    cmSourceFile* sf = makefile->GetSource(absFile.c_str());
+    if (sf)
+      {
+      skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
+      generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));
+      }
+
+    if ((skip==false) && (generated == false))
+      {
+      std::string ext = cmSystemTools::GetFilenameExtension(fileIt->c_str());
+      cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(ext.c_str());
+      if (fileType == cmSystemTools::CXX_FILE_FORMAT)
+        {
+        _moc_files += sepFiles;
+        _moc_files += absFile;
+        sepFiles = ";";
+        }
+      else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
+        {
+        _moc_headers += sepHeaders;
+        _moc_headers += absFile;
+        sepHeaders = ";";
+        }
+      }
+    }
+
+  std::string _moc_incs = makefile->GetProperty("INCLUDE_DIRECTORIES");
+  std::string _moc_defs = makefile->GetProperty("DEFINITIONS");
+  std::string _moc_compile_defs = makefile->GetProperty("COMPILE_DEFINITIONS");
+  // forget the variables added here afterwards again:
+  cmMakefile::ScopePushPop varScope(makefile);
+  static_cast<void>(varScope);
+
+  makefile->AddDefinition("_moc_target_name", automocTargetName.c_str());
+  makefile->AddDefinition("_moc_incs", _moc_incs.c_str());
+  makefile->AddDefinition("_moc_defs", _moc_defs.c_str());
+  makefile->AddDefinition("_moc_compile_defs", _moc_compile_defs.c_str());
+  makefile->AddDefinition("_moc_files", _moc_files.c_str());
+  makefile->AddDefinition("_moc_headers", _moc_headers.c_str());
+
+  const char* cmakeRoot = makefile->GetDefinition("CMAKE_ROOT");
+  std::string inputFile = cmakeRoot;
+  inputFile += "/Modules/AutomocInfo.cmake.in";
+  std::string outputFile = targetDir;
+  outputFile += "/AutomocInfo.cmake";
+  makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
+                          false, true, false);
+
+  std::string mocCppFile =  makefile->GetCurrentOutputDirectory();
+  mocCppFile += "/";
+  mocCppFile += automocTargetName;
+  mocCppFile += ".cpp";
+  makefile->GetOrCreateSource(mocCppFile.c_str(), true);
+  srcs.push_back(mocCppFile);
+
+}
+
+
+void cmQtAutomoc::AddTargetDependency(cmMakefile* makefile, cmTarget* target)
+{
+  // don't do anything if there is no Qt4:
+  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
+  if (qtMajorVersion != "4")
+    {
+    return;
+    }
+
+  std::string automocTargetName = target->GetName();
+  automocTargetName += "_automoc";
+  target->AddUtility(automocTargetName.c_str());
+}
+
+
 bool cmQtAutomoc::Run(const char* targetDirectory)
 {
   cmake cm;
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index 891b47a..e573610 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -10,6 +10,12 @@ public:
   cmQtAutomoc();
   bool Run(const char* targetDirectory);
 
+  void SetupAutomocTarget(cmMakefile* makefile,
+                          const char* targetName,
+                          std::vector<std::string>& srcs);
+
+  void AddTargetDependency(cmMakefile* makefile, cmTarget* target);
+
 private:
   cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
                                            const char* targetDirectory);
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 06229e0..c5eff1c 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -2927,6 +2927,13 @@ const char* cmake::GetCPackCommand()
     return this->CPackCommand.c_str();
 }
 
+
+const char* cmake::GetCMakeCommand()
+{
+  return this->CMakeCommand.c_str();
+}
+
+
 void cmake::MarkCliAsUsed(const std::string& variable)
 {
   this->UsedCliVariables[variable] = true;
diff --git a/Source/cmake.h b/Source/cmake.h
index f2a2ae3..09f6c37 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -301,6 +301,7 @@ class cmake
    */
   const char* GetCTestCommand();
   const char* GetCPackCommand();
+  const char* GetCMakeCommand();
 
   // Do we want debug output during the cmake run.
   bool GetDebugOutput() { return this->DebugOutput; }

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=de91feb367c127294a56b492799c4bf042954fd8
commit de91feb367c127294a56b492799c4bf042954fd8
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Tue Aug 9 09:11:53 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:53:50 2011 +0200

    Remove the need to check for .h/.cxx during buildtime
    
    Instead it now relies on cmake time to put that information
    correctly into AutomocInfo.cmake
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 7fac2f2..5494b2a 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -73,6 +73,7 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile,
 
   this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR");
   this->Sources = makefile->GetSafeDefinition("AM_SOURCES");
+  this->Headers = makefile->GetSafeDefinition("AM_HEADERS");
   this->IncludeProjectDirsBefore = makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
   this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
   this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
@@ -282,184 +283,181 @@ bool cmQtAutomoc::RunAutomocQt4()
       {
       printf("Checking -%s-\n", absFilename.c_str());
       }
-    std::string extension = absFilename.substr(absFilename.find_last_of('.'));
 
-    if (extension == ".cpp" || extension == ".cc" || extension == ".mm"
-         || extension == ".cxx" || extension == ".C")
+    const std::string contentsString = this->ReadAll(absFilename);
+    if (contentsString.empty())
       {
-      const std::string contentsString = this->ReadAll(absFilename);
-      if (contentsString.empty())
-        {
-        std::cerr << "automoc4: empty source file: " << absFilename << std::endl;
-        continue;
-        }
-      const std::string absPath = cmsys::SystemTools::GetFilenamePath(
-                  cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
+      std::cerr << "automoc4: empty source file: " << absFilename << std::endl;
+      continue;
+      }
+    const std::string absPath = cmsys::SystemTools::GetFilenamePath(
+                cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
 
-      int matchOffset = 0;
-      if (!mocIncludeRegExp.find(contentsString.c_str()))
+    int matchOffset = 0;
+    if (!mocIncludeRegExp.find(contentsString.c_str()))
+      {
+      // no moc #include, look whether we need to create a moc from the .h nevertheless
+      //std::cout << "no moc #include in the .cpp file";
+      const std::string basename =
+            cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
+      for(std::list<std::string>::const_iterator ext =
+                                                    headerExtensions.begin();
+          ext != headerExtensions.end();
+          ++ext)
         {
-        // no moc #include, look whether we need to create a moc from the .h nevertheless
-        //std::cout << "no moc #include in the .cpp file";
-        const std::string basename =
-              cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
-        for(std::list<std::string>::const_iterator ext =
-                                                      headerExtensions.begin();
-            ext != headerExtensions.end();
-            ++ext)
+        const std::string headername = absPath + basename + (*ext);
+        if (cmsys::SystemTools::FileExists(headername.c_str())
+                && includedMocs.find(headername) == includedMocs.end()
+                && notIncludedMocs.find(headername) == notIncludedMocs.end())
           {
-          const std::string headername = absPath + basename + (*ext);
-          if (cmsys::SystemTools::FileExists(headername.c_str())
-                  && includedMocs.find(headername) == includedMocs.end()
-                  && notIncludedMocs.find(headername) == notIncludedMocs.end())
+          const std::string currentMoc = "moc_" + basename + ".cpp";
+          const std::string contents = this->ReadAll(headername);
+          if (qObjectRegExp.find(contents))
             {
-            const std::string currentMoc = "moc_" + basename + ".cpp";
-            const std::string contents = this->ReadAll(headername);
-            if (qObjectRegExp.find(contents))
-              {
-              //std::cout << "header contains Q_OBJECT macro";
-              notIncludedMocs[headername] = currentMoc;
-              }
-            break;
+            //std::cout << "header contains Q_OBJECT macro";
+            notIncludedMocs[headername] = currentMoc;
             }
+          break;
           }
-        for(std::list<std::string>::const_iterator ext =
-                                                      headerExtensions.begin();
-            ext != headerExtensions.end();
-            ++ext)
+        }
+      for(std::list<std::string>::const_iterator ext =
+                                                    headerExtensions.begin();
+          ext != headerExtensions.end();
+          ++ext)
+        {
+        const std::string privateHeaderName = absPath+basename+"_p"+(*ext);
+        if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())
+                && includedMocs.find(privateHeaderName) == includedMocs.end()
+                && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end())
           {
-          const std::string privateHeaderName = absPath+basename+"_p"+(*ext);
-          if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())
-                  && includedMocs.find(privateHeaderName) == includedMocs.end()
-                  && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end())
+          const std::string currentMoc = "moc_" + basename + "_p.cpp";
+          const std::string contents = this->ReadAll(privateHeaderName);
+          if (qObjectRegExp.find(contents))
             {
-            const std::string currentMoc = "moc_" + basename + "_p.cpp";
-            const std::string contents = this->ReadAll(privateHeaderName);
-            if (qObjectRegExp.find(contents))
-              {
-              //std::cout << "header contains Q_OBJECT macro";
-              notIncludedMocs[privateHeaderName] = currentMoc;
-              }
-            break;
+            //std::cout << "header contains Q_OBJECT macro";
+            notIncludedMocs[privateHeaderName] = currentMoc;
             }
+          break;
           }
         }
-      else
+      }
+    else
+      {
+      // for every moc include in the file
+      do
         {
-        // for every moc include in the file
-        do
+        const std::string currentMoc = mocIncludeRegExp.match(1);
+        //std::cout << "found moc include: " << currentMoc << std::endl;
+
+        std::string basename = cmsys::SystemTools::
+                                  GetFilenameWithoutLastExtension(currentMoc);
+        const bool moc_style = this->StartsWith(basename, "moc_");
+
+        // If the moc include is of the moc_foo.cpp style we expect the Q_OBJECT class
+        // declaration in a header file.
+        // If the moc include is of the foo.moc style we need to look for a Q_OBJECT
+        // macro in the current source file, if it contains the macro we generate the
+        // moc file from the source file, else from the header.
+        //
+        // TODO: currently any .moc file name will be used if the source contains
+        // Q_OBJECT
+        if (moc_style || !qObjectRegExp.find(contentsString))
           {
-          const std::string currentMoc = mocIncludeRegExp.match(1);
-          //std::cout << "found moc include: " << currentMoc << std::endl;
-
-          std::string basename = cmsys::SystemTools::
-                                   GetFilenameWithoutLastExtension(currentMoc);
-          const bool moc_style = this->StartsWith(basename, "moc_");
-
-          // If the moc include is of the moc_foo.cpp style we expect the Q_OBJECT class
-          // declaration in a header file.
-          // If the moc include is of the foo.moc style we need to look for a Q_OBJECT
-          // macro in the current source file, if it contains the macro we generate the
-          // moc file from the source file, else from the header.
-          //
-          // TODO: currently any .moc file name will be used if the source contains
-          // Q_OBJECT
-          if (moc_style || !qObjectRegExp.find(contentsString))
+          if (moc_style)
             {
-            if (moc_style)
-              {
-              // basename should be the part of the moc filename used for finding the
-              // correct header, so we need to remove the moc_ part
-              basename = basename.substr(4);
-              }
+            // basename should be the part of the moc filename used for finding the
+            // correct header, so we need to remove the moc_ part
+            basename = basename.substr(4);
+            }
 
-            bool headerFound = false;
-            for(std::list<std::string>::const_iterator ext =
-                                                      headerExtensions.begin();
-                ext != headerExtensions.end();
-                ++ext)
+          bool headerFound = false;
+          for(std::list<std::string>::const_iterator ext =
+                                                    headerExtensions.begin();
+              ext != headerExtensions.end();
+              ++ext)
+            {
+            const std::string &sourceFilePath = absPath + basename + (*ext);
+            if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
               {
-              const std::string &sourceFilePath = absPath + basename + (*ext);
-              if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
-                {
-                headerFound = true;
-                includedMocs[sourceFilePath] = currentMoc;
-                notIncludedMocs.erase(sourceFilePath);
-                break;
-                }
+              headerFound = true;
+              includedMocs[sourceFilePath] = currentMoc;
+              notIncludedMocs.erase(sourceFilePath);
+              break;
               }
-            if (!headerFound)
+            }
+          if (!headerFound)
+            {
+            // the moc file is in a subdir => look for the header in the same subdir
+            if (currentMoc.find_first_of('/') != std::string::npos)
               {
-              // the moc file is in a subdir => look for the header in the same subdir
-              if (currentMoc.find_first_of('/') != std::string::npos)
+              const std::string &filepath = absPath
+                      + cmsys::SystemTools::GetFilenamePath(currentMoc)
+                      + '/' + basename;
+
+              for(std::list<std::string>::const_iterator ext =
+                                                    headerExtensions.begin();
+                  ext != headerExtensions.end();
+                  ++ext)
                 {
-                const std::string &filepath = absPath
-                        + cmsys::SystemTools::GetFilenamePath(currentMoc)
-                        + '/' + basename;
-
-                for(std::list<std::string>::const_iterator ext =
-                                                      headerExtensions.begin();
-                    ext != headerExtensions.end();
-                    ++ext)
-                  {
-                  const std::string &sourceFilePath = filepath + (*ext);
-                  if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
-                    {
-                    headerFound = true;
-                    includedMocs[sourceFilePath] = currentMoc;
-                    notIncludedMocs.erase(sourceFilePath);
-                    break;
-                    }
-                  }
-                if (!headerFound)
+                const std::string &sourceFilePath = filepath + (*ext);
+                if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
                   {
-                  std::cerr << "automoc4: The file \"" << absFilename <<
-                      "\" includes the moc file \"" << currentMoc << "\", but neither \"" <<
-                      absPath + basename + '{' + this->Join(headerExtensions, ',') + "}\" nor \"" <<
-                      filepath + '{' + this->Join(headerExtensions, ',') + '}' <<
-                      "\" exist." << std::endl;
-                  ::exit(EXIT_FAILURE);
+                  headerFound = true;
+                  includedMocs[sourceFilePath] = currentMoc;
+                  notIncludedMocs.erase(sourceFilePath);
+                  break;
                   }
                 }
-              else
+              if (!headerFound)
                 {
                 std::cerr << "automoc4: The file \"" << absFilename <<
-                    "\" includes the moc file \"" << currentMoc << "\", but \"" <<
-                    absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' <<
-                    "\" does not exist." << std::endl;
+                    "\" includes the moc file \"" << currentMoc << "\", but neither \"" <<
+                    absPath + basename + '{' + this->Join(headerExtensions, ',') + "}\" nor \"" <<
+                    filepath + '{' + this->Join(headerExtensions, ',') + '}' <<
+                    "\" exist." << std::endl;
                 ::exit(EXIT_FAILURE);
                 }
               }
+            else
+              {
+              std::cerr << "automoc4: The file \"" << absFilename <<
+                  "\" includes the moc file \"" << currentMoc << "\", but \"" <<
+                  absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' <<
+                  "\" does not exist." << std::endl;
+              ::exit(EXIT_FAILURE);
+              }
             }
-          else
-            {
-            includedMocs[absFilename] = currentMoc;
-            notIncludedMocs.erase(absFilename);
-            }
-          matchOffset += mocIncludeRegExp.end();
-          } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
-        }
+          }
+        else
+          {
+          includedMocs[absFilename] = currentMoc;
+          notIncludedMocs.erase(absFilename);
+          }
+        matchOffset += mocIncludeRegExp.end();
+        } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
       }
-    else if (extension == ".h" || extension == ".hpp"
-            || extension == ".hxx" || extension == ".H")
+    }
+
+  std::vector<std::string> headerFiles;
+  cmSystemTools::ExpandListArgument(this->Headers, headerFiles);
+  for (std::vector<std::string>::const_iterator it = headerFiles.begin();
+       it != headerFiles.end();
+       ++it)
+    {
+    const std::string &absFilename = *it;
+    if (this->Verbose)
       {
-      if (includedMocs.find(absFilename) == includedMocs.end()
-              && notIncludedMocs.find(absFilename) == notIncludedMocs.end())
-        {
-        // if this header is not getting processed yet and is explicitly mentioned for the
-        // automoc the moc is run unconditionally on the header and the resulting file is
-        // included in the _automoc.cpp file (unless there's a .cpp file later on that
-        // includes the moc from this header)
-        const std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp";
-        notIncludedMocs[absFilename] = currentMoc;
-        }
+      printf("Checking -%s-\n", absFilename.c_str());
       }
-    else
+    if (includedMocs.find(absFilename) == includedMocs.end()
+              && notIncludedMocs.find(absFilename) == notIncludedMocs.end())
       {
-      if (this->Verbose)
-        {
-        std::cout << "automoc4: ignoring file '" << absFilename << "' with unknown suffix" << std::endl;
-        }
+      // if this header is not getting processed yet and is explicitly mentioned for the
+      // automoc the moc is run unconditionally on the header and the resulting file is
+      // included in the _automoc.cpp file (unless there's a .cpp file later on that
+      // includes the moc from this header)
+      const std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp";
+      notIncludedMocs[absFilename] = currentMoc;
       }
     }
 
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index 0dafd4a..891b47a 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -32,6 +32,7 @@ private:
 
   std::string QtMajorVersion;
   std::string Sources;
+  std::string Headers;
   bool IncludeProjectDirsBefore;
   std::string Srcdir;
   std::string Builddir;

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d65689a3bd059b2f70e11644e43df4251c71987e
commit d65689a3bd059b2f70e11644e43df4251c71987e
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Mon Aug 8 15:20:13 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:53:38 2011 +0200

    Add actual automoc code from automoc
    
    It already works :-)
    Needs more refactoring, e.g. using the cmake facilities to turn a string
    into a vector etc.
    Also still missing is the part which creates the custom target.
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index 26d359d..7fac2f2 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -5,7 +5,13 @@
 
 #include "cmQtAutomoc.h"
 
+
+#define TRACE_LINE() printf(" %s %d\n", __PRETTY_FUNCTION__, __LINE__)
+
 cmQtAutomoc::cmQtAutomoc()
+:Verbose(true)
+,RunMocFailed(false)
+,GenerateAll(false)
 {
 }
 
@@ -19,9 +25,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory)
   this->ReadAutomocInfoFile(makefile, targetDirectory);
   this->ReadOldMocDefinitionsFile(makefile, targetDirectory);
 
-  delete gg;
-  gg = NULL;
-  makefile = NULL;
+  this->Init();
 
   if (this->QtMajorVersion == "4")
     {
@@ -29,6 +33,11 @@ bool cmQtAutomoc::Run(const char* targetDirectory)
     }
 
   this->WriteOldMocDefinitionsFile(targetDirectory);
+
+  delete gg;
+  gg = NULL;
+  makefile = NULL;
+
 }
 
 
@@ -59,7 +68,22 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile,
   if (!makefile->ReadListFile(0, filename.c_str()))
     {
     cmSystemTools::Error("Error processing file:", filename.c_str());
+    return false;
     }
+
+  this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR");
+  this->Sources = makefile->GetSafeDefinition("AM_SOURCES");
+  this->IncludeProjectDirsBefore = makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE");
+  this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR");
+  this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
+  this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE");
+  this->MocCompileDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS");
+  this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS");
+  this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES");
+  this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR");
+  this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR");
+  this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME");
+
   return true;
 }
 
@@ -71,20 +95,550 @@ bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile,
   cmSystemTools::ConvertToUnixSlashes(filename);
   filename += "/AutomocOldMocDefinitions.cmake";
 
-  if (!makefile->ReadListFile(0, filename.c_str()))
+  if (makefile->ReadListFile(0, filename.c_str()))
     {
-    cmSystemTools::Error("Error processing file:", filename.c_str());
+    this->OldMocDefinitionsStr =
+                         makefile->GetSafeDefinition("AM_OLD_MOC_DEFINITIONS");
     }
   return true;
 }
 
 
+void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory)
+{
+  std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
+  cmSystemTools::ConvertToUnixSlashes(filename);
+  filename += "/AutomocOldMocDefinitions.cmake";
+
+  std::fstream outfile;
+  outfile.open(filename.c_str(),
+               std::ios_base::out | std::ios_base::trunc);
+  outfile << "set(AM_OLD_MOC_DEFINITIONS \""
+              << this->Join(this->MocDefinitions, ' ') << "\")\n";
+
+  outfile.close();
+}
+
+
+void cmQtAutomoc::Init()
+{
+  this->OutMocCppFilename = this->Builddir;
+  this->OutMocCppFilename += this->TargetName;
+  this->OutMocCppFilename += ".cpp";
+
+  std::vector<std::string> cdefList;
+  cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList);
+  if (!cdefList.empty())
+    {
+    for(std::vector<std::string>::const_iterator it = cdefList.begin();
+        it != cdefList.end();
+        ++it)
+      {
+      this->MocDefinitions.push_back("-D" + (*it));
+      }
+    }
+  else
+    {
+    std::string tmpMocDefs = this->MocDefinitionsStr;
+    cmSystemTools::ReplaceString(tmpMocDefs, " ", ";");
+
+    std::vector<std::string> defList;
+    cmSystemTools::ExpandListArgument(tmpMocDefs, defList);
+
+    for(std::vector<std::string>::const_iterator it = defList.begin();
+        it != defList.end();
+        ++it)
+      {
+      if (this->StartsWith(*it, "-D"))
+        {
+        this->MocDefinitions.push_back(*it);
+        }
+      }
+    }
+
+  std::vector<std::string> incPaths;
+  cmSystemTools::ExpandListArgument(this->MocIncludesStr, incPaths);
+
+  std::set<std::string> frameworkPaths;
+  for(std::vector<std::string>::const_iterator it = incPaths.begin();
+      it != incPaths.end();
+      ++it)
+    {
+    const std::string &path = *it;
+    this->MocIncludes.push_back("-I" + path);
+    if (this->EndsWith(path, ".framework/Headers"))
+      {
+      // Go up twice to get to the framework root
+      std::vector<std::string> pathComponents;
+      cmsys::SystemTools::SplitPath(path.c_str(), pathComponents);
+      std::string frameworkPath =cmsys::SystemTools::JoinPath(
+                             pathComponents.begin(), pathComponents.end() - 2);
+      frameworkPaths.insert(frameworkPath);
+      }
+    }
+
+  for (std::set<std::string>::const_iterator it = frameworkPaths.begin();
+         it != frameworkPaths.end(); ++it)
+    {
+    this->MocIncludes.push_back("-F");
+    this->MocIncludes.push_back(*it);
+    }
+
+
+    if (this->IncludeProjectDirsBefore)
+      {
+      const std::string &binDir = "-I" + this->ProjectBinaryDir;
+
+      const std::string srcDir = "-I" + this->ProjectSourceDir;
+
+      std::list<std::string> sortedMocIncludes;
+      std::list<std::string>::iterator it = this->MocIncludes.begin();
+      while (it != this->MocIncludes.end())
+        {
+        if (this->StartsWith(*it, binDir))
+          {
+          sortedMocIncludes.push_back(*it);
+          it = this->MocIncludes.erase(it);
+          }
+        else
+          {
+          ++it;
+          }
+        }
+      it = this->MocIncludes.begin();
+      while (it != this->MocIncludes.end())
+        {
+        if (this->StartsWith(*it, srcDir))
+          {
+          sortedMocIncludes.push_back(*it);
+          it = this->MocIncludes.erase(it);
+          }
+        else
+          {
+          ++it;
+          }
+        }
+      sortedMocIncludes.insert(sortedMocIncludes.end(),
+                           this->MocIncludes.begin(), this->MocIncludes.end());
+      this->MocIncludes = sortedMocIncludes;
+    }
+
+}
+
+
 bool cmQtAutomoc::RunAutomocQt4()
 {
+  if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str())
+    || (this->OldMocDefinitionsStr != this->Join(this->MocDefinitions, ' ')))
+    {
+    this->GenerateAll = true;
+    }
+
+  // the program goes through all .cpp files to see which moc files are included. It is not really
+  // interesting how the moc file is named, but what file the moc is created from. Once a moc is
+  // included the same moc may not be included in the _automoc.cpp file anymore. OTOH if there's a
+  // header containing Q_OBJECT where no corresponding moc file is included anywhere a
+  // moc_<filename>.cpp file is created and included in the _automoc.cpp file.
+  std::map<std::string, std::string> includedMocs;    // key = moc source filepath, value = moc output filepath
+  std::map<std::string, std::string> notIncludedMocs; // key = moc source filepath, value = moc output filename
+
+  cmsys::RegularExpression mocIncludeRegExp(
+              "[\n][ \t]*#[ \t]*include[ \t]+"
+              "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]");
+  cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]");
+  std::list<std::string> headerExtensions;
+#if defined(_WIN32)
+  // not case sensitive
+  headerExtensions.push_back(".h");
+  headerExtensions.push_back(".hpp");
+  headerExtensions.push_back(".hxx");
+#elif defined(__APPLE__)
+  headerExtensions.push_back(".h");
+  headerExtensions.push_back(".hpp");
+  headerExtensions.push_back(".hxx");
+
+  // detect case-sensitive filesystem
+  long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE);
+  if (caseSensitive == 1)
+  {
+    headerExtensions.push_back(".H");
+  }
+#else
+  headerExtensions.push_back(".h");
+  headerExtensions.push_back(".hpp");
+  headerExtensions.push_back(".hxx");
+  headerExtensions.push_back(".H");
+#endif
+
+  std::vector<std::string> sourceFiles;
+  cmSystemTools::ExpandListArgument(this->Sources, sourceFiles);
+
+  for (std::vector<std::string>::const_iterator it = sourceFiles.begin();
+       it != sourceFiles.end();
+       ++it)
+    {
+    const std::string &absFilename = *it;
+    if (this->Verbose)
+      {
+      printf("Checking -%s-\n", absFilename.c_str());
+      }
+    std::string extension = absFilename.substr(absFilename.find_last_of('.'));
+
+    if (extension == ".cpp" || extension == ".cc" || extension == ".mm"
+         || extension == ".cxx" || extension == ".C")
+      {
+      const std::string contentsString = this->ReadAll(absFilename);
+      if (contentsString.empty())
+        {
+        std::cerr << "automoc4: empty source file: " << absFilename << std::endl;
+        continue;
+        }
+      const std::string absPath = cmsys::SystemTools::GetFilenamePath(
+                  cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/';
+
+      int matchOffset = 0;
+      if (!mocIncludeRegExp.find(contentsString.c_str()))
+        {
+        // no moc #include, look whether we need to create a moc from the .h nevertheless
+        //std::cout << "no moc #include in the .cpp file";
+        const std::string basename =
+              cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename);
+        for(std::list<std::string>::const_iterator ext =
+                                                      headerExtensions.begin();
+            ext != headerExtensions.end();
+            ++ext)
+          {
+          const std::string headername = absPath + basename + (*ext);
+          if (cmsys::SystemTools::FileExists(headername.c_str())
+                  && includedMocs.find(headername) == includedMocs.end()
+                  && notIncludedMocs.find(headername) == notIncludedMocs.end())
+            {
+            const std::string currentMoc = "moc_" + basename + ".cpp";
+            const std::string contents = this->ReadAll(headername);
+            if (qObjectRegExp.find(contents))
+              {
+              //std::cout << "header contains Q_OBJECT macro";
+              notIncludedMocs[headername] = currentMoc;
+              }
+            break;
+            }
+          }
+        for(std::list<std::string>::const_iterator ext =
+                                                      headerExtensions.begin();
+            ext != headerExtensions.end();
+            ++ext)
+          {
+          const std::string privateHeaderName = absPath+basename+"_p"+(*ext);
+          if (cmsys::SystemTools::FileExists(privateHeaderName.c_str())
+                  && includedMocs.find(privateHeaderName) == includedMocs.end()
+                  && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end())
+            {
+            const std::string currentMoc = "moc_" + basename + "_p.cpp";
+            const std::string contents = this->ReadAll(privateHeaderName);
+            if (qObjectRegExp.find(contents))
+              {
+              //std::cout << "header contains Q_OBJECT macro";
+              notIncludedMocs[privateHeaderName] = currentMoc;
+              }
+            break;
+            }
+          }
+        }
+      else
+        {
+        // for every moc include in the file
+        do
+          {
+          const std::string currentMoc = mocIncludeRegExp.match(1);
+          //std::cout << "found moc include: " << currentMoc << std::endl;
+
+          std::string basename = cmsys::SystemTools::
+                                   GetFilenameWithoutLastExtension(currentMoc);
+          const bool moc_style = this->StartsWith(basename, "moc_");
+
+          // If the moc include is of the moc_foo.cpp style we expect the Q_OBJECT class
+          // declaration in a header file.
+          // If the moc include is of the foo.moc style we need to look for a Q_OBJECT
+          // macro in the current source file, if it contains the macro we generate the
+          // moc file from the source file, else from the header.
+          //
+          // TODO: currently any .moc file name will be used if the source contains
+          // Q_OBJECT
+          if (moc_style || !qObjectRegExp.find(contentsString))
+            {
+            if (moc_style)
+              {
+              // basename should be the part of the moc filename used for finding the
+              // correct header, so we need to remove the moc_ part
+              basename = basename.substr(4);
+              }
+
+            bool headerFound = false;
+            for(std::list<std::string>::const_iterator ext =
+                                                      headerExtensions.begin();
+                ext != headerExtensions.end();
+                ++ext)
+              {
+              const std::string &sourceFilePath = absPath + basename + (*ext);
+              if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
+                {
+                headerFound = true;
+                includedMocs[sourceFilePath] = currentMoc;
+                notIncludedMocs.erase(sourceFilePath);
+                break;
+                }
+              }
+            if (!headerFound)
+              {
+              // the moc file is in a subdir => look for the header in the same subdir
+              if (currentMoc.find_first_of('/') != std::string::npos)
+                {
+                const std::string &filepath = absPath
+                        + cmsys::SystemTools::GetFilenamePath(currentMoc)
+                        + '/' + basename;
+
+                for(std::list<std::string>::const_iterator ext =
+                                                      headerExtensions.begin();
+                    ext != headerExtensions.end();
+                    ++ext)
+                  {
+                  const std::string &sourceFilePath = filepath + (*ext);
+                  if (cmsys::SystemTools::FileExists(sourceFilePath.c_str()))
+                    {
+                    headerFound = true;
+                    includedMocs[sourceFilePath] = currentMoc;
+                    notIncludedMocs.erase(sourceFilePath);
+                    break;
+                    }
+                  }
+                if (!headerFound)
+                  {
+                  std::cerr << "automoc4: The file \"" << absFilename <<
+                      "\" includes the moc file \"" << currentMoc << "\", but neither \"" <<
+                      absPath + basename + '{' + this->Join(headerExtensions, ',') + "}\" nor \"" <<
+                      filepath + '{' + this->Join(headerExtensions, ',') + '}' <<
+                      "\" exist." << std::endl;
+                  ::exit(EXIT_FAILURE);
+                  }
+                }
+              else
+                {
+                std::cerr << "automoc4: The file \"" << absFilename <<
+                    "\" includes the moc file \"" << currentMoc << "\", but \"" <<
+                    absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' <<
+                    "\" does not exist." << std::endl;
+                ::exit(EXIT_FAILURE);
+                }
+              }
+            }
+          else
+            {
+            includedMocs[absFilename] = currentMoc;
+            notIncludedMocs.erase(absFilename);
+            }
+          matchOffset += mocIncludeRegExp.end();
+          } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset));
+        }
+      }
+    else if (extension == ".h" || extension == ".hpp"
+            || extension == ".hxx" || extension == ".H")
+      {
+      if (includedMocs.find(absFilename) == includedMocs.end()
+              && notIncludedMocs.find(absFilename) == notIncludedMocs.end())
+        {
+        // if this header is not getting processed yet and is explicitly mentioned for the
+        // automoc the moc is run unconditionally on the header and the resulting file is
+        // included in the _automoc.cpp file (unless there's a .cpp file later on that
+        // includes the moc from this header)
+        const std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp";
+        notIncludedMocs[absFilename] = currentMoc;
+        }
+      }
+    else
+      {
+      if (this->Verbose)
+        {
+        std::cout << "automoc4: ignoring file '" << absFilename << "' with unknown suffix" << std::endl;
+        }
+      }
+    }
+
+  // run moc on all the moc's that are #included in source files
+  for(std::map<std::string, std::string>::const_iterator it = includedMocs.begin();
+      it != includedMocs.end();
+      ++it)
+    {
+    this->GenerateMoc(it->first, it->second);
+    }
+
+  std::stringstream outStream(std::stringstream::out);
+  outStream << "/* This file is autogenerated, do not edit*/\n";
+
+  bool automocCppChanged = false;
+  if (notIncludedMocs.empty())
+    {
+    outStream << "enum some_compilers { need_more_than_nothing };\n";
+    }
+  else
+    {
+    // run moc on the remaining headers and include them in the _automoc.cpp file
+    for(std::map<std::string, std::string>::const_iterator it = notIncludedMocs.begin();
+        it != notIncludedMocs.end();
+        ++it)
+      {
+      bool mocSuccess = this->GenerateMoc(it->first, it->second);
+      if (mocSuccess)
+        {
+        automocCppChanged = true;
+        }
+      outStream << "#include \"" << it->second << "\"\n";
+      }
+    }
+
+  if (this->RunMocFailed)
+    {
+    // if any moc process failed we don't want to touch the _automoc.cpp file so that
+    // automoc4 is rerun until the issue is fixed
+    std::cerr << "returning failed.."<< std::endl;
+    return false;
+    }
+  outStream.flush();
+  std::string automocSource = outStream.str();
+  if (!automocCppChanged)
+    {
+    // compare contents of the _automoc.cpp file
+    const std::string oldContents = this->ReadAll(this->OutMocCppFilename);
+    if (oldContents == automocSource)
+      {
+      // nothing changed: don't touch the _automoc.cpp file
+      return true;
+      }
+    }
+  // either the contents of the _automoc.cpp file or one of the mocs included by it have changed
+
+  // source file that includes all remaining moc files (_automoc.cpp file)
+  std::fstream outfile;
+  outfile.open(this->OutMocCppFilename.c_str(),
+               std::ios_base::out | std::ios_base::trunc);
+  outfile << automocSource;
+  outfile.close();
+
   return true;
 }
 
 
-void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory)
+bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile,
+                              const std::string& mocFileName)
+{
+    //std::cout << "AutoMoc::generateMoc" << sourceFile << mocFileName << std::endl;
+  const std::string mocFilePath = this->Builddir + mocFileName;
+  int sourceNewerThanMoc = 0;
+  bool success = cmsys::SystemTools::FileTimeCompare(sourceFile.c_str(),
+                                                     mocFilePath.c_str(),
+                                                     &sourceNewerThanMoc);
+  if (this->GenerateAll || !success || sourceNewerThanMoc >= 0)
+    {
+    // make sure the directory for the resulting moc file exists
+    std::string mocDir = mocFilePath.substr(0, mocFilePath.rfind('/'));
+    if (!cmsys::SystemTools::FileExists(mocDir.c_str(), false))
+      {
+      cmsys::SystemTools::MakeDirectory(mocDir.c_str());
+      }
+
+/*    if (this->Verbose)
+      {
+      echoColor("Generating " + mocFilePath + " from " + sourceFile);
+      }
+    else
+      {
+      echoColor("Generating " + mocFileName);
+      }*/
+
+    std::vector<cmStdString> command;
+    command.push_back(this->MocExecutable);
+    for (std::list<std::string>::const_iterator it = this->MocIncludes.begin();
+         it != this->MocIncludes.end();
+         ++it)
+      {
+      command.push_back(*it);
+      }
+    for(std::list<std::string>::const_iterator it=this->MocDefinitions.begin();
+        it != this->MocDefinitions.end();
+        ++it)
+      {
+      command.push_back(*it);
+      }
+#ifdef _WIN32
+    command.push_back("-DWIN32");
+#endif
+    command.push_back("-o");
+    command.push_back(mocFilePath);
+    command.push_back(sourceFile);
+
+    if (this->Verbose)
+      {
+      for(int i=0; i<command.size(); i++)
+        {
+        printf("%s ", command[i].c_str());
+        }
+      printf("\n");
+      }
+
+    std::string output;
+    int retVal = 0;
+    const bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal);
+    if (!result || retVal)
+      {
+      std::cerr << "automoc4: process for " << mocFilePath << " failed:\n" << output << std::endl;
+      this->RunMocFailed = true;
+      cmSystemTools::RemoveFile(mocFilePath.c_str());
+      }
+    return true;
+    }
+  return false;
+}
+
+
+std::string cmQtAutomoc::Join(const std::list<std::string>& lst,char separator)
+{
+    if (lst.empty())
+      {
+      return "";
+      }
+
+    std::string result;
+    for (std::list<std::string>::const_iterator it = lst.begin();
+         it != lst.end();
+         ++it)
+      {
+      result += (*it) + separator;
+      }
+    result.erase(result.end() - 1);
+    return result;
+}
+
+
+bool cmQtAutomoc::StartsWith(const std::string& str, const std::string& with)
+{
+  return (str.substr(0, with.length()) == with);
+}
+
+
+bool cmQtAutomoc::EndsWith(const std::string& str, const std::string& with)
+{
+  if (with.length() > (str.length()))
+    {
+    return false;
+    }
+  return (str.substr(str.length() - with.length(), with.length()) == with);
+}
+
+
+std::string cmQtAutomoc::ReadAll(const std::string& filename)
 {
+  std::ifstream file(filename.c_str());
+  std::stringstream stream;
+  stream << file.rdbuf();
+  file.close();
+  return stream.str();
 }
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index d6f809c..0dafd4a 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -21,8 +21,37 @@ private:
   void WriteOldMocDefinitionsFile(const char* targetDirectory);
 
   bool RunAutomocQt4();
+  bool GenerateMoc(const std::string& sourceFile,
+                   const std::string& mocFileName);
+  void Init();
+
+  std::string Join(const std::list<std::string>& lst, char separator);
+  bool EndsWith(const std::string& str, const std::string& with);
+  bool StartsWith(const std::string& str, const std::string& with);
+  std::string ReadAll(const std::string& filename);
 
   std::string QtMajorVersion;
+  std::string Sources;
+  bool IncludeProjectDirsBefore;
+  std::string Srcdir;
+  std::string Builddir;
+  std::string MocExecutable;
+  std::string MocCompileDefinitionsStr;
+  std::string MocDefinitionsStr;
+  std::string MocIncludesStr;
+  std::string ProjectBinaryDir;
+  std::string ProjectSourceDir;
+  std::string TargetName;
+
+  std::string OldMocDefinitionsStr;
+
+  std::string OutMocCppFilename;
+  std::list<std::string> MocIncludes;
+  std::list<std::string> MocDefinitions;
+
+  bool Verbose;
+  bool RunMocFailed;
+  bool GenerateAll;
 
 };
 

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=d1c0a5fce6c9adccd1abf6b41ba448976ef895d0
commit d1c0a5fce6c9adccd1abf6b41ba448976ef895d0
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Sun Aug 7 17:16:00 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 14 15:45:13 2011 +0200

    Start implementing skeleton for automoc in cmake
    
    Alex

diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
index efbfc38..26d359d 100644
--- a/Source/cmQtAutomoc.cxx
+++ b/Source/cmQtAutomoc.cxx
@@ -1,3 +1,8 @@
+#include "cmGlobalGenerator.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmSystemTools.h"
+
 #include "cmQtAutomoc.h"
 
 cmQtAutomoc::cmQtAutomoc()
@@ -7,4 +12,79 @@ cmQtAutomoc::cmQtAutomoc()
 
 bool cmQtAutomoc::Run(const char* targetDirectory)
 {
+  cmake cm;
+  cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory);
+  cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile();
+
+  this->ReadAutomocInfoFile(makefile, targetDirectory);
+  this->ReadOldMocDefinitionsFile(makefile, targetDirectory);
+
+  delete gg;
+  gg = NULL;
+  makefile = NULL;
+
+  if (this->QtMajorVersion == "4")
+    {
+    this->RunAutomocQt4();
+    }
+
+  this->WriteOldMocDefinitionsFile(targetDirectory);
+}
+
+
+cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm,
+                                                  const char* targetDirectory)
+{
+  cmGlobalGenerator* gg = new cmGlobalGenerator();
+  gg->SetCMakeInstance(cm);
+
+  cmLocalGenerator* lg = gg->CreateLocalGenerator();
+  lg->GetMakefile()->SetHomeOutputDirectory(targetDirectory);
+  lg->GetMakefile()->SetStartOutputDirectory(targetDirectory);
+  lg->GetMakefile()->SetHomeDirectory(targetDirectory);
+  lg->GetMakefile()->SetStartDirectory(targetDirectory);
+  gg->SetCurrentLocalGenerator(lg);
+
+  return gg;
+}
+
+
+bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile,
+                                      const char* targetDirectory)
+{
+  std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
+  cmSystemTools::ConvertToUnixSlashes(filename);
+  filename += "/AutomocInfo.cmake";
+
+  if (!makefile->ReadListFile(0, filename.c_str()))
+    {
+    cmSystemTools::Error("Error processing file:", filename.c_str());
+    }
+  return true;
+}
+
+
+bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile,
+                                            const char* targetDirectory)
+{
+  std::string filename(cmSystemTools::CollapseFullPath(targetDirectory));
+  cmSystemTools::ConvertToUnixSlashes(filename);
+  filename += "/AutomocOldMocDefinitions.cmake";
+
+  if (!makefile->ReadListFile(0, filename.c_str()))
+    {
+    cmSystemTools::Error("Error processing file:", filename.c_str());
+    }
+  return true;
+}
+
+
+bool cmQtAutomoc::RunAutomocQt4()
+{
+  return true;
+}
+
+
+void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory)
+{
 }
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
index 657b208..d6f809c 100644
--- a/Source/cmQtAutomoc.h
+++ b/Source/cmQtAutomoc.h
@@ -1,11 +1,29 @@
 #ifndef cmQtAutomoc_h
 #define cmQtAutomoc_h
 
+class cmGlobalGenerator;
+class cmMakefile;
+
 class cmQtAutomoc
 {
 public:
   cmQtAutomoc();
   bool Run(const char* targetDirectory);
+
+private:
+  cmGlobalGenerator* CreateGlobalGenerator(cmake* cm,
+                                           const char* targetDirectory);
+
+  bool ReadAutomocInfoFile(cmMakefile* makefile,
+                           const char* targetDirectory);
+  bool ReadOldMocDefinitionsFile(cmMakefile* makefile,
+                                 const char* targetDirectory);
+  void WriteOldMocDefinitionsFile(const char* targetDirectory);
+
+  bool RunAutomocQt4();
+
+  std::string QtMajorVersion;
+
 };
 
 #endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 47520df..06229e0 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -1578,7 +1578,8 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
     else if (args[1] == "cmake_automoc")
       {
         cmQtAutomoc automoc;
-        automoc.Run("target directory");
+        automoc.Run(args[2].c_str());
+        return 0;
       }
 
     // Tar files

http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a65011baf109fd0afe759cf3d9e7b6ab7013a805
commit a65011baf109fd0afe759cf3d9e7b6ab7013a805
Author:     Alex Neundorf <neundorf at kde.org>
AuthorDate: Sun Aug 7 12:02:46 2011 +0200
Commit:     Alex Neundorf <neundorf at kde.org>
CommitDate: Sun Aug 7 12:02:46 2011 +0200

    Start work on automoc: add empty cmQtAutomoc class
    
    Alex

diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 1c942ba..96b3ea0 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -228,6 +228,8 @@ SET(SRCS
   cmPropertyDefinitionMap.h
   cmPropertyMap.cxx
   cmPropertyMap.h
+  cmQtAutomoc.cxx
+  cmQtAutomoc.h
   cmScriptGenerator.h
   cmScriptGenerator.cxx
   cmSourceFile.cxx
diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx
new file mode 100644
index 0000000..efbfc38
--- /dev/null
+++ b/Source/cmQtAutomoc.cxx
@@ -0,0 +1,10 @@
+#include "cmQtAutomoc.h"
+
+cmQtAutomoc::cmQtAutomoc()
+{
+}
+
+
+bool cmQtAutomoc::Run(const char* targetDirectory)
+{
+}
diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h
new file mode 100644
index 0000000..657b208
--- /dev/null
+++ b/Source/cmQtAutomoc.h
@@ -0,0 +1,11 @@
+#ifndef cmQtAutomoc_h
+#define cmQtAutomoc_h
+
+class cmQtAutomoc
+{
+public:
+  cmQtAutomoc();
+  bool Run(const char* targetDirectory);
+};
+
+#endif
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 51cc9d4..47520df 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -20,6 +20,7 @@
 #include "cmCommand.h"
 #include "cmFileTimeComparison.h"
 #include "cmGeneratedFileStream.h"
+#include "cmQtAutomoc.h"
 #include "cmSourceFile.h"
 #include "cmVersion.h"
 #include "cmTest.h"
@@ -1574,6 +1575,12 @@ int cmake::ExecuteCMakeCommand(std::vector<std::string>& args)
       }
 #endif
 
+    else if (args[1] == "cmake_automoc")
+      {
+        cmQtAutomoc automoc;
+        automoc.Run("target directory");
+      }
+
     // Tar files
     else if (args[1] == "tar" && args.size() > 3)
       {

-----------------------------------------------------------------------

Summary of changes:
 Modules/Automoc.cmake             |  158 ++++++++
 Modules/AutomocInfo.cmake.in      |   13 +
 Source/CMakeLists.txt             |    2 +
 Source/cmAddExecutableCommand.cxx |    3 +-
 Source/cmAddLibraryCommand.cxx    |   33 +-
 Source/cmDocumentVariables.cxx    |    9 +
 Source/cmGlobalGenerator.cxx      |   60 +++-
 Source/cmGlobalGenerator.h        |    2 +
 Source/cmMakefile.cxx             |    3 +-
 Source/cmMakefile.h               |    2 +-
 Source/cmQtAutomoc.cxx            |  781 +++++++++++++++++++++++++++++++++++++
 Source/cmQtAutomoc.h              |   66 ++++
 Source/cmTarget.cxx               |   25 ++-
 Source/cmake.cxx                  |   15 +
 Source/cmake.h                    |    1 +
 Tests/CMakeLists.txt              |   19 +
 Tests/QtAutomoc/CMakeLists.txt    |   20 +
 Tests/QtAutomoc/calwidget.cpp     |  424 ++++++++++++++++++++
 Tests/QtAutomoc/calwidget.h       |  121 ++++++
 Tests/QtAutomoc/codeeditor.cpp    |  153 ++++++++
 Tests/QtAutomoc/codeeditor.h      |   99 +++++
 Tests/QtAutomoc/main.cpp          |   58 +++
 22 files changed, 2032 insertions(+), 35 deletions(-)
 create mode 100644 Modules/Automoc.cmake
 create mode 100644 Modules/AutomocInfo.cmake.in
 create mode 100644 Source/cmQtAutomoc.cxx
 create mode 100644 Source/cmQtAutomoc.h
 create mode 100644 Tests/QtAutomoc/CMakeLists.txt
 create mode 100644 Tests/QtAutomoc/calwidget.cpp
 create mode 100644 Tests/QtAutomoc/calwidget.h
 create mode 100644 Tests/QtAutomoc/codeeditor.cpp
 create mode 100644 Tests/QtAutomoc/codeeditor.h
 create mode 100644 Tests/QtAutomoc/main.cpp


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list