OSDN Git Service

Update license.
[qt-creator-jp/qt-creator-jp.git] / src / plugins / cpptools / uicodecompletionsupport.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (info@qt.nokia.com)
8 **
9 **
10 ** GNU Lesser General Public License Usage
11 **
12 ** This file may be used under the terms of the GNU Lesser General Public
13 ** License version 2.1 as published by the Free Software Foundation and
14 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
15 ** Please review the following information to ensure the GNU Lesser General
16 ** Public License version 2.1 requirements will be met:
17 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 **
19 ** In addition, as a special exception, Nokia gives you certain additional
20 ** rights. These rights are described in the Nokia Qt LGPL Exception
21 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 **
23 ** Other Usage
24 **
25 ** Alternatively, this file may be used in accordance with the terms and
26 ** conditions contained in a signed written agreement between you and Nokia.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **************************************************************************/
32
33 #include "uicodecompletionsupport.h"
34
35 #include <QtCore/QProcess>
36 #include <QtCore/QFile>
37 #include <QtCore/QFileInfo>
38
39 enum { debug = 0 };
40
41 using namespace CppTools;
42 using namespace CPlusPlus;
43
44 UiCodeModelSupport::UiCodeModelSupport(CppModelManagerInterface *modelmanager,
45                                        const QString &source,
46                                        const QString &uiHeaderFile)
47     : AbstractEditorSupport(modelmanager),
48       m_sourceName(source),
49       m_fileName(uiHeaderFile),
50       m_updateIncludingFiles(false),
51       m_initialized(false)
52 {
53     if (debug)
54         qDebug()<<"ctor UiCodeModelSupport for"<<m_sourceName<<uiHeaderFile;
55 }
56
57 UiCodeModelSupport::~UiCodeModelSupport()
58 {
59     if (debug)
60         qDebug()<<"dtor ~UiCodeModelSupport for"<<m_sourceName;
61 }
62
63 void UiCodeModelSupport::init() const
64 {
65     m_initialized = true;
66     QDateTime sourceTime = QFileInfo(m_sourceName).lastModified();
67     QFileInfo uiHeaderFileInfo(m_fileName);
68     QDateTime uiHeaderTime = uiHeaderFileInfo.exists() ? uiHeaderFileInfo.lastModified() : QDateTime();
69     if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
70         QFile file(m_fileName);
71         if (file.open(QFile::ReadOnly)) {
72             if (debug)
73                 qDebug()<<"ui*h file is more recent then source file, using information from ui*h file"<<m_fileName;
74             QTextStream stream(&file);
75             m_contents = stream.readAll().toUtf8();
76             m_cacheTime = uiHeaderTime;
77             return;
78         }
79     }
80
81     if (debug)
82         qDebug()<<"ui*h file not found, or not recent enough, trying to create it on the fly";
83     QFile file(m_sourceName);
84     if (file.open(QFile::ReadOnly)) {
85         QTextStream stream(&file);
86         const QString contents = stream.readAll();
87         if (runUic(contents)) {
88             if (debug)
89                 qDebug()<<"created on the fly";
90             return;
91         } else {
92             // uic run was unsuccesfull
93             if (debug)
94                 qDebug()<<"uic run wasn't succesfull";
95             m_cacheTime = QDateTime ();
96             m_contents = QByteArray();
97             // and if the header file wasn't there, next time we need to update
98             // all of the files that include this header
99             if (!uiHeaderFileInfo.exists())
100                 m_updateIncludingFiles = true;
101             return;
102         }
103     } else {
104         if (debug)
105             qDebug()<<"Could open "<<m_sourceName<<"needed for the cpp model";
106         m_contents = QByteArray();
107     }
108 }
109
110 QByteArray UiCodeModelSupport::contents() const
111 {
112     if (!m_initialized)
113         init();
114
115     return m_contents;
116 }
117
118 QString UiCodeModelSupport::fileName() const
119 {
120     return m_fileName;
121 }
122
123 void UiCodeModelSupport::setFileName(const QString &name)
124 {
125     if (m_fileName == name && m_cacheTime.isValid())
126         return;
127
128     if (debug)
129         qDebug() << "UiCodeModelSupport::setFileName"<<name;
130
131     m_fileName = name;
132     m_contents.clear();
133     m_cacheTime = QDateTime();
134     init();
135 }
136
137 bool UiCodeModelSupport::runUic(const QString &ui) const
138 {
139     QProcess process;
140     const QString uic = uicCommand();
141     process.setEnvironment(environment());
142
143     if (debug)
144         qDebug() << "UiCodeModelSupport::runUic " << uic << " on " << ui.size() << " bytes";
145     process.start(uic, QStringList(), QIODevice::ReadWrite);
146     if (!process.waitForStarted())
147         return false;
148     process.write(ui.toUtf8());
149     process.closeWriteChannel();
150     if (process.waitForFinished() && process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0) {
151         m_contents = process.readAllStandardOutput();
152         m_cacheTime = QDateTime::currentDateTime();
153         if (debug)
154             qDebug() << "ok" << m_contents.size() << "bytes.";
155         return true;
156     } else {
157         if (debug)
158             qDebug() << "failed" << process.readAllStandardError();
159         process.kill();
160     }
161     return false;
162 }
163
164 void UiCodeModelSupport::updateFromEditor(const QString &formEditorContents)
165 {
166     if (runUic(formEditorContents)) {
167         updateDocument();
168     }
169 }
170
171 void UiCodeModelSupport::updateFromBuild()
172 {
173     if (debug)
174         qDebug()<<"UiCodeModelSupport::updateFromBuild() for file"<<m_sourceName;
175     // This is mostly a fall back for the cases when uic couldn't be run
176     // it pays special attention to the case where a ui_*h was newly created
177     QDateTime sourceTime = QFileInfo(m_sourceName).lastModified();
178     if (m_cacheTime.isValid() && m_cacheTime >= sourceTime) {
179         if (debug)
180             qDebug()<<"Cache is still more recent then source";
181         return;
182     } else {
183         QFileInfo fi(m_fileName);
184         QDateTime uiHeaderTime = fi.exists() ? fi.lastModified() : QDateTime();
185         if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
186             if (m_cacheTime >= uiHeaderTime)
187                 return;
188             if (debug)
189                 qDebug()<<"found ui*h updating from it";
190
191             QFile file(m_fileName);
192             if (file.open(QFile::ReadOnly)) {
193                 QTextStream stream(&file);
194                 m_contents = stream.readAll().toUtf8();
195                 m_cacheTime = uiHeaderTime;
196                 updateDocument();
197                 return;
198             }
199         }
200         if (debug)
201             qDebug()<<"ui*h not found or not more recent then source not changing anything";
202     }
203 }
204