src/tools/uic/driver.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the tools applications of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "driver.h"
00025 #include "uic.h"
00026 #include "ui4.h"
00027 
00028 #include <QRegExp>
00029 #include <QFileInfo>
00030 #include <QtDebug>
00031 
00032 Driver::Driver()
00033     : m_stdout(stdout, QFile::WriteOnly | QFile::Text)
00034 {
00035     m_output = &m_stdout;
00036 }
00037 
00038 Driver::~Driver()
00039 {
00040 }
00041 
00042 QString Driver::findOrInsertWidget(DomWidget *ui_widget)
00043 {
00044     if (!m_widgets.contains(ui_widget))
00045         m_widgets.insert(ui_widget, unique(ui_widget->attributeName(), ui_widget->attributeClass()));
00046 
00047     return m_widgets.value(ui_widget);
00048 }
00049 
00050 QString Driver::findOrInsertSpacer(DomSpacer *ui_spacer)
00051 {
00052     if (!m_spacers.contains(ui_spacer))
00053         m_spacers.insert(ui_spacer, unique(QString(), QLatin1String("QSpacerItem")));
00054 
00055     return m_spacers.value(ui_spacer);
00056 }
00057 
00058 QString Driver::findOrInsertLayout(DomLayout *ui_layout)
00059 {
00060     if (!m_layouts.contains(ui_layout))
00061         m_layouts.insert(ui_layout, unique(QString(), ui_layout->attributeClass()));
00062 
00063     return m_layouts.value(ui_layout);
00064 }
00065 
00066 QString Driver::findOrInsertLayoutItem(DomLayoutItem *ui_layoutItem)
00067 {
00068     switch (ui_layoutItem->kind()) {
00069         case DomLayoutItem::Widget:
00070             return findOrInsertWidget(ui_layoutItem->elementWidget());
00071         case DomLayoutItem::Spacer:
00072             return findOrInsertSpacer(ui_layoutItem->elementSpacer());
00073         case DomLayoutItem::Layout:
00074             return findOrInsertLayout(ui_layoutItem->elementLayout());
00075         case DomLayoutItem::Unknown:
00076             break;
00077     }
00078 
00079     Q_ASSERT( 0 );
00080 
00081     return QString();
00082 }
00083 
00084 QString Driver::findOrInsertActionGroup(DomActionGroup *ui_group)
00085 {
00086     if (!m_actionGroups.contains(ui_group))
00087         m_actionGroups.insert(ui_group, unique(ui_group->attributeName(), QLatin1String("QActionGroup")));
00088 
00089     return m_actionGroups.value(ui_group);
00090 }
00091 
00092 QString Driver::findOrInsertAction(DomAction *ui_action)
00093 {
00094     if (!m_actions.contains(ui_action))
00095         m_actions.insert(ui_action, unique(ui_action->attributeName(), QLatin1String("QAction")));
00096 
00097     return m_actions.value(ui_action);
00098 }
00099 
00100 QString Driver::findOrInsertName(const QString &name)
00101 {
00102     return unique(name);
00103 }
00104 
00105 QString Driver::normalizedName(const QString &name)
00106 {
00107     QString result = name;
00108     result.replace(QRegExp(QLatin1String("[^a-zA-Z_0-9]")), QLatin1String("_"));
00109     return result;
00110 }
00111 
00112 QString Driver::unique(const QString &instanceName, const QString &className)
00113 {
00114     QString name;
00115     bool alreadyUsed = false;
00116 
00117     if (instanceName.size()) {
00118         int id = 1;
00119         name = instanceName;
00120         name = normalizedName(name);
00121         QString base = name;
00122 
00123         while (m_nameRepository.contains(name)) {
00124             alreadyUsed = true;
00125             name = base + QString::number(id++);
00126         }
00127     } else if (className.size()) {
00128         name = unique(qtify(className));
00129     } else {
00130         name = unique(QLatin1String("var"));
00131     }
00132 
00133     if (alreadyUsed && className.size()) {
00134         fprintf(stderr, "Warning: name %s is already used\n", qPrintable(instanceName));
00135     }
00136 
00137     m_nameRepository.insert(name, true);
00138     return name;
00139 }
00140 
00141 QString Driver::qtify(const QString &name)
00142 {
00143     QString qname = name;
00144 
00145     if (qname.at(0) == QLatin1Char('Q') || qname.at(0) == QLatin1Char('K'))
00146         qname = qname.mid(1);
00147 
00148     int i=0;
00149     while (i < qname.length()) {
00150         if (qname.at(i).toLower() != qname.at(i))
00151             qname[i] = qname.at(i).toLower();
00152         else
00153             break;
00154 
00155         ++i;
00156     }
00157 
00158     return qname;
00159 }
00160 
00161 static bool isAnsiCCharacter(const QChar& c)
00162 {
00163     return c.toUpper() >= QLatin1Char('A') && c.toUpper() <= QLatin1Char('Z')
00164            || c.isDigit() || c == QLatin1Char('_');
00165 }
00166 
00167 QString Driver::headerFileName() const
00168 {
00169     QString name = m_option.outputFile;
00170 
00171     if (name.isEmpty()) {
00172         name = QLatin1String("ui_"); // ### use ui_ as prefix.
00173         name.append(m_option.inputFile);
00174     }
00175 
00176     return headerFileName(name);
00177 }
00178 
00179 QString Driver::headerFileName(const QString &fileName)
00180 {
00181     if (fileName.isEmpty())
00182         return headerFileName(QLatin1String("noname"));
00183 
00184     QFileInfo info(fileName);
00185     QString baseName = info.baseName();
00186     // Transform into a valid C++ identifier
00187     if (!baseName.isEmpty() && baseName.at(0).isDigit())
00188         baseName.prepend(QLatin1Char('_'));
00189     for (int i = 0; i < baseName.size(); ++i) {
00190         QChar c = baseName.at(i);
00191         if (!isAnsiCCharacter(c)) {
00192             // Replace character by its unicode value
00193             QString hex = QString::number(c.unicode(), 16);
00194             baseName.replace(i, 1, "_" + hex + "_");
00195             i += hex.size() + 1;
00196         }
00197     }
00198     return baseName.toUpper() + QLatin1String("_H");
00199 }
00200 
00201 bool Driver::printDependencies(const QString &fileName)
00202 {
00203     Q_ASSERT(m_option.dependencies == true);
00204 
00205     m_option.inputFile = fileName;
00206 
00207     Uic tool(this);
00208     return tool.printDependencies();
00209 }
00210 
00211 bool Driver::uic(const QString &fileName, DomUI *ui, QTextStream *out)
00212 {
00213     m_option.inputFile = fileName;
00214 
00215     QTextStream *oldOutput = m_output;
00216 
00217     m_output = out != 0 ? out : &m_stdout;
00218 
00219     Uic tool(this);
00220     bool rtn = false;
00221 #ifdef QT_UIC_CPP_GENERATOR
00222     rtn = tool.write(ui);
00223 #else
00224     Q_UNUSED(ui);
00225     fprintf(stderr, "uic: option to generate cpp code not compiled in [%s:%d]\n",
00226             __FILE__, __LINE__);
00227 #endif
00228 
00229     m_output = oldOutput;
00230 
00231     return rtn;
00232 }
00233 
00234 bool Driver::uic(const QString &fileName, QTextStream *out)
00235 {
00236     QFile f;
00237     if (fileName.isEmpty())
00238         f.open(stdin, QIODevice::ReadOnly);
00239     else {
00240         f.setFileName(fileName);
00241         if (!f.open(QIODevice::ReadOnly))
00242             return false;
00243     }
00244 
00245     m_option.inputFile = fileName;
00246 
00247     QTextStream *oldOutput = m_output;
00248     bool deleteOutput = false;
00249 
00250     if (out) {
00251         m_output = out;
00252     } else {
00253         m_output = new QTextStream(stdout, QIODevice::WriteOnly | QFile::Text);
00254         deleteOutput = true;
00255     }
00256 
00257     Uic tool(this);
00258     bool rtn = tool.write(&f);
00259     f.close();
00260 
00261     if (deleteOutput)
00262         delete m_output;
00263 
00264     m_output = oldOutput;
00265 
00266     return rtn;
00267 }
00268 
00269 void Driver::reset()
00270 {
00271     Q_ASSERT( m_output == 0 );
00272 
00273     m_option = Option();
00274     m_output = 0;
00275     m_problems.clear();
00276 
00277     QStringList m_problems;
00278 
00279     m_widgets.clear();
00280     m_spacers.clear();
00281     m_layouts.clear();
00282     m_actionGroups.clear();
00283     m_actions.clear();
00284     m_nameRepository.clear();
00285     m_pixmaps.clear();
00286 }
00287 
00288 void Driver::insertPixmap(const QString &pixmap)
00289 {
00290     m_pixmaps.insert(pixmap, true);
00291 }
00292 
00293 bool Driver::containsPixmap(const QString &pixmap) const
00294 {
00295     return m_pixmaps.contains(pixmap);
00296 }
00297 
00298 DomWidget *Driver::widgetByName(const QString &name) const
00299 {
00300     return m_widgets.key(name);
00301 }
00302 
00303 DomSpacer *Driver::spacerByName(const QString &name) const
00304 {
00305     return m_spacers.key(name);
00306 }
00307 
00308 DomLayout *Driver::layoutByName(const QString &name) const
00309 {
00310     return m_layouts.key(name);
00311 }
00312 
00313 DomActionGroup *Driver::actionGroupByName(const QString &name) const
00314 {
00315     return m_actionGroups.key(name);
00316 }
00317 
00318 DomAction *Driver::actionByName(const QString &name) const
00319 {
00320     return m_actions.key(name);
00321 }

Generated on Thu Mar 15 12:00:22 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1