00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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_");
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
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
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 }