/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
using EnvDTE;
using EnvDTE80;
using Microsoft.VisualStudio.VCProjectEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace QtVsTools.Core
{
///
/// Summary description for ProjectExporter.
///
public class ProjectExporter
{
private DTE dteObject;
public ProjectExporter(DTE dte)
{
dteObject = dte;
}
private static void MakeFilesRelativePath(VCProject vcproj, List files, string path)
{
for (var i = 0; i < files.Count; i++) {
var relPath = string.Empty;
if (files[i].IndexOf(':') != 1) {
relPath = HelperFunctions.GetRelativePath(path,
vcproj.ProjectDirectory + "\\" + files[i]);
} else {
relPath = HelperFunctions.GetRelativePath(path, files[i]);
}
files[i] = HelperFunctions.ChangePathFormat(relPath);
}
}
private static bool ContainsFilesWithSpaces(List files)
{
for (var i = 0; i < files.Count; i++) {
if (files[i].IndexOf(' ') != -1)
return true;
}
return false;
}
public static List ConvertFilesToFullPath(List files, string path)
{
var ret = new List(files.Count);
foreach (var file in files) {
FileInfo fi;
if (file.IndexOf(':') != 1)
fi = new FileInfo(path + "\\" + file);
else
fi = new FileInfo(file);
ret.Add(fi.FullName);
}
return ret;
}
private ProSolution CreateProFileSolution(Solution sln)
{
ProFileContent content;
var prosln = new ProSolution(sln);
foreach (var proj in HelperFunctions.ProjectsInSolution(sln.DTE)) {
try {
// only add qt projects
if (HelperFunctions.IsQtProject(proj)) {
content = CreateProFileContent(proj);
prosln.ProFiles.Add(content);
} else if (proj.Kind == ProjectKinds.vsProjectKindSolutionFolder) {
addProjectsInFolder(proj, prosln);
}
} catch {
// Catch all exceptions. Try to add as many projects as possible.
}
}
return prosln;
}
private void addProjectsInFolder(Project solutionFolder, ProSolution sln)
{
foreach (ProjectItem pi in solutionFolder.ProjectItems) {
var containedProject = pi.Object as Project;
if (HelperFunctions.IsQtProject(containedProject)) {
var content = CreateProFileContent(containedProject);
sln.ProFiles.Add(content);
} else if (containedProject.Kind == ProjectKinds.vsProjectKindSolutionFolder) {
addProjectsInFolder(containedProject, sln);
}
}
}
private static ProFileContent CreateProFileContent(Project project)
{
ProFileOption option;
var qtPro = QtProject.Create(project);
var content = new ProFileContent(qtPro.VCProject);
// hack to get active config
var activeConfig = project.ConfigurationManager.ActiveConfiguration.ConfigurationName;
var activePlatform = project.ConfigurationManager.ActiveConfiguration.PlatformName;
var config = (VCConfiguration)((IVCCollection)qtPro.VCProject.Configurations).Item(activeConfig);
var compiler = CompilerToolWrapper.Create(config);
var linker = (VCLinkerTool)((IVCCollection)config.Tools).Item("VCLinkerTool");
var libTool = (VCLibrarianTool)((IVCCollection)config.Tools).Item("VCLibrarianTool");
var outPut = config.PrimaryOutput;
var fi = new FileInfo(outPut);
var destdir = HelperFunctions.GetRelativePath(qtPro.VCProject.ProjectDirectory, fi.DirectoryName);
destdir = HelperFunctions.ChangePathFormat(destdir);
var target = qtPro.VCProject.Name;
option = new ProFileOption("TEMPLATE");
option.Comment = Resources.ec_Template;
option.ShortComment = "Template";
option.NewOption = null; // just one option...
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
content.Options.Add(option);
if (config.ConfigurationType == ConfigurationTypes.typeApplication)
option.List.Add("app");
else
option.List.Add("lib");
option = new ProFileOption("TARGET");
option.Comment = Resources.ec_Target;
option.ShortComment = "Target Name";
option.NewOption = null; // just one option...
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
content.Options.Add(option);
option.List.Add(target);
option = new ProFileOption("DESTDIR");
option.Comment = Resources.ec_DestDir;
option.ShortComment = "Destination Directory";
option.NewOption = null; // just one option...
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
content.Options.Add(option);
option.List.Add(destdir);
// add the qt option
option = new ProFileOption("QT");
var optionQT = option;
option.Comment = Resources.ec_Qt;
option.ShortComment = "Qt Options";
option.NewOption = " "; // just space between the options...
content.Options.Add(option);
// add the config option
option = new ProFileOption("CONFIG");
var optionCONFIG = option;
option.Comment = Resources.ec_Config;
option.ShortComment = "Config Options";
option.NewOption = " "; // just space between the options...
content.Options.Add(option);
AddModules(qtPro, optionQT, optionCONFIG);
if (config.ConfigurationType == ConfigurationTypes.typeStaticLibrary)
option.List.Add("staticlib");
if (linker != null) {
var linkerRule = linker as IVCRulePropertyStorage;
var generateDebugInformation = (linkerRule != null) ?
linkerRule.GetUnevaluatedPropertyValue("GenerateDebugInformation") : null;
if (generateDebugInformation != "false")
option.List.Add("debug");
else
option.List.Add("release");
if (linker.SubSystem == subSystemOption.subSystemConsole)
option.List.Add("console");
if (linker.AdditionalDependencies != null) {
if (linker.AdditionalDependencies.IndexOf("QAxServer", StringComparison.Ordinal) > -1)
option.List.Add("qaxserver");
else if (linker.AdditionalDependencies.IndexOf("QAxContainer", StringComparison.Ordinal) > -1)
option.List.Add("qaxcontainer");
else if (linker.AdditionalDependencies.IndexOf("QtHelp", StringComparison.Ordinal) > -1)
option.List.Add("help");
}
}
if (qtPro.IsDesignerPluginProject()) {
option.List.Add("designer");
option.List.Add("plugin");
}
// add defines
option = new ProFileOption("DEFINES");
option.Comment = Resources.ec_Defines;
option.ShortComment = "Defines";
option.NewOption = " ";
option.AssignSymbol = ProFileOption.AssignType.AT_PlusEquals;
content.Options.Add(option);
AddPreprocessorDefinitions(option, compiler.GetPreprocessorDefinitions());
// add the include path option
option = new ProFileOption("INCLUDEPATH");
option.Comment = Resources.ec_IncludePath;
option.ShortComment = "Include Path";
content.Options.Add(option);
AddIncludePaths(project, option, compiler.GetAdditionalIncludeDirectories());
option = new ProFileOption("LIBS");
option.Comment = Resources.ec_Libs;
option.ShortComment = "Additional Libraries";
content.Options.Add(option);
if (linker != null) {
AddLibraries(project, option, linker.AdditionalLibraryDirectories,
linker.AdditionalDependencies);
} else if (libTool != null) {
AddLibraries(project, option, libTool.AdditionalLibraryDirectories,
libTool.AdditionalDependencies);
}
option = new ProFileOption("PRECOMPILED_HEADER");
option.Comment = Resources.ec_PrecompiledHeader;
option.ShortComment = "Using Precompiled Headers";
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
content.Options.Add(option);
if (qtPro.UsesPrecompiledHeaders())
option.List.Add(compiler.GetPrecompiledHeaderThrough());
// add the depend path option
option = new ProFileOption("DEPENDPATH");
option.Comment = Resources.ec_DependPath;
option.ShortComment = "Depend Path";
content.Options.Add(option);
option.List.Add(".");
var mocDir = QtVSIPSettings.GetMocDirectory(project, activeConfig.ToLower(), activePlatform.ToLower());
mocDir = mocDir.Replace('\\', '/');
option = new ProFileOption("MOC_DIR");
option.Comment = Resources.ec_MocDir;
option.ShortComment = "Moc Directory";
option.NewOption = null; // just one option...
content.Options.Add(option);
option.List.Add(mocDir);
option = new ProFileOption("OBJECTS_DIR");
option.Comment = Resources.ec_ObjDir;
option.ShortComment = "Objects Directory";
option.NewOption = null; // just one option...
content.Options.Add(option);
option.List.Add(config.ConfigurationName.ToLower());
var uiDir = QtVSIPSettings.GetUicDirectory(project);
uiDir = uiDir.Replace('\\', '/');
option = new ProFileOption("UI_DIR");
option.Comment = Resources.ec_UiDir;
option.ShortComment = "UI Directory";
option.NewOption = null; // just one option...
content.Options.Add(option);
option.List.Add(uiDir);
var rccDir = QtVSIPSettings.GetRccDirectory(project);
rccDir = rccDir.Replace('\\', '/');
option = new ProFileOption("RCC_DIR");
option.Comment = Resources.ec_RccDir;
option.ShortComment = "RCC Directory";
option.NewOption = null; // just one option...
content.Options.Add(option);
option.List.Add(rccDir);
// add the include path option
option = new ProFileOption("include");
option.Comment = Resources.ec_Include;
option.ShortComment = "Include file(s)";
option.IncludeComment = false; // print the comment in the output file
option.AssignSymbol = ProFileOption.AssignType.AT_Function;
content.Options.Add(option);
// add the translation files
option = new ProFileOption("TRANSLATIONS");
option.Comment = Resources.ec_Translations;
option.ShortComment = "Translation files";
option.IncludeComment = false;
content.Options.Add(option);
option.List.AddRange(HelperFunctions.GetProjectFiles(project, FilesToList.FL_Translation));
// add the rc file
if (File.Exists(qtPro.VCProject.ProjectDirectory + "\\" + project.Name + ".rc")) {
option = new ProFileOption("win32:RC_FILE");
option.Comment = Resources.ec_rcFile;
option.ShortComment = "Windows resource file";
option.IncludeComment = false;
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
content.Options.Add(option);
option.List.Add(project.Name + ".rc");
}
if (qtPro.IsDesignerPluginProject()) {
option = new ProFileOption("target.path");
option.ShortComment = "Install the plugin in the designer plugins directory.";
option.IncludeComment = true;
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
option.List.Add("$$[QT_INSTALL_PLUGINS]/designer");
content.Options.Add(option);
option = new ProFileOption("INSTALLS");
option.IncludeComment = false;
option.AssignSymbol = ProFileOption.AssignType.AT_PlusEquals;
option.List.Add("target");
content.Options.Add(option);
}
return content;
}
private static ProFileContent CreatePriFileContent(Project project, string priFileDirectory)
{
ProFileOption option;
var qtPro = QtProject.Create(project);
var content = new ProFileContent(qtPro.VCProject);
var hasSpaces = false;
// add the header files
option = new ProFileOption("HEADERS");
option.ShortComment = "Header files";
option.IncludeComment = false;
content.Options.Add(option);
option.List.AddRange(HelperFunctions.GetProjectFiles(project, FilesToList.FL_HFiles));
MakeFilesRelativePath(qtPro.VCProject, option.List, priFileDirectory);
hasSpaces |= ContainsFilesWithSpaces(option.List);
// add the source files
option = new ProFileOption("SOURCES");
option.ShortComment = "Source files";
option.IncludeComment = false;
content.Options.Add(option);
option.List.AddRange(HelperFunctions.GetProjectFiles(project, FilesToList.FL_CppFiles));
MakeFilesRelativePath(qtPro.VCProject, option.List, priFileDirectory);
hasSpaces |= ContainsFilesWithSpaces(option.List);
// add the form files
option = new ProFileOption("FORMS");
option.ShortComment = "Forms";
option.IncludeComment = false;
content.Options.Add(option);
option.List.AddRange(HelperFunctions.GetProjectFiles(project, FilesToList.FL_UiFiles));
MakeFilesRelativePath(qtPro.VCProject, option.List, priFileDirectory);
hasSpaces |= ContainsFilesWithSpaces(option.List);
// add the translation files
option = new ProFileOption("TRANSLATIONS");
option.Comment = Resources.ec_Translations;
option.ShortComment = "Translation file(s)";
option.IncludeComment = false;
option.List.AddRange(HelperFunctions.GetProjectFiles(project, FilesToList.FL_Translation));
MakeFilesRelativePath(qtPro.VCProject, option.List, priFileDirectory);
hasSpaces |= ContainsFilesWithSpaces(option.List);
content.Options.Add(option);
// add the resource files
option = new ProFileOption("RESOURCES");
option.Comment = Resources.ec_Resources;
option.ShortComment = "Resource file(s)";
option.IncludeComment = false;
content.Options.Add(option);
foreach (var resFile in qtPro.GetResourceFiles())
option.List.Add(resFile.RelativePath.Replace('\\', '/'));
if (hasSpaces)
Messages.DisplayWarningMessage(SR.GetString("ExportProject_PriFileContainsSpaces"));
return content;
}
private static void AddPreprocessorDefinitions(ProFileOption option, string preprocessorDefinitions)
{
if (preprocessorDefinitions == null)
return;
var excludeList = "UNICODE WIN32 NDEBUG QDESIGNER_EXPORT_WIDGETS ";
excludeList += "QT_THREAD_SUPPORT QT_PLUGIN QT_NO_DEBUG QT_CORE_LIB QT_GUI_LIB";
foreach (var define in preprocessorDefinitions.Split(';', ',')) {
if (excludeList.IndexOf(define, StringComparison.OrdinalIgnoreCase) == -1)
option.List.Add(define);
}
}
private static void AddIncludePaths(Project project, ProFileOption option, string includePaths)
{
if (QtProject.GetFormatVersion(project) >= Resources.qtMinFormatVersion_ClProperties)
return;
if (includePaths == null)
return;
var versionManager = QtVersionManager.The();
var qtDir = versionManager.GetInstallPath(project);
if (qtDir == null)
qtDir = Environment.GetEnvironmentVariable("QTDIR");
if (qtDir == null)
qtDir = "";
qtDir = HelperFunctions.NormalizeRelativeFilePath(qtDir);
foreach (var s in includePaths.Split(';', ',')) {
var d = HelperFunctions.NormalizeRelativeFilePath(s);
if (!d.StartsWith("$(qtdir)\\include", StringComparison.OrdinalIgnoreCase) &&
!d.StartsWith(qtDir + "\\include", StringComparison.OrdinalIgnoreCase) &&
!d.EndsWith("win32-msvc2005", StringComparison.OrdinalIgnoreCase)) {
var vcConfig = project.ConfigurationManager.ActiveConfiguration.Object
as VCConfiguration;
if (vcConfig != null)
HelperFunctions.ExpandString(ref d, vcConfig);
if (HelperFunctions.IsAbsoluteFilePath(d))
d = HelperFunctions.GetRelativePath(project.FullName, d);
if (!HelperFunctions.IsAbsoluteFilePath(d))
option.List.Add(HelperFunctions.ChangePathFormat(d));
}
}
}
private static void AddLibraries(Project project, ProFileOption option, string paths, string deps)
{
if (QtProject.GetFormatVersion(project) < Resources.qtMinFormatVersion_ClProperties)
return;
var versionManager = QtVersionManager.The();
var qtDir = versionManager.GetInstallPath(project);
if (qtDir == null)
qtDir = Environment.GetEnvironmentVariable("QTDIR");
if (qtDir == null)
qtDir = "";
qtDir = HelperFunctions.NormalizeRelativeFilePath(qtDir);
if (paths != null) {
foreach (var s in paths.Split(';', ',')) {
var d = HelperFunctions.NormalizeRelativeFilePath(s);
if (!d.StartsWith("$(qtdir)\\lib", StringComparison.OrdinalIgnoreCase) &&
!d.StartsWith(qtDir + "\\lib", StringComparison.OrdinalIgnoreCase)) {
if (HelperFunctions.IsAbsoluteFilePath(d))
d = HelperFunctions.GetRelativePath(project.FullName, d);
if (!HelperFunctions.IsAbsoluteFilePath(d))
option.List.Add("-L\"" + HelperFunctions.ChangePathFormat(d) + "\"");
}
}
}
if (deps != null) {
foreach (var d in deps.Split(' ')) {
if (d.Length > 0 &&
!d.StartsWith("$(qtdir)\\lib", StringComparison.OrdinalIgnoreCase) &&
!d.StartsWith(qtDir + "\\lib", StringComparison.OrdinalIgnoreCase) &&
!d.StartsWith("qt", StringComparison.OrdinalIgnoreCase) &&
!d.StartsWith(".\\qt", StringComparison.OrdinalIgnoreCase) && d != ".")
option.List.Add("-l" + HelperFunctions.ChangePathFormat(d).Replace(".lib", ""));
}
}
}
private static void AddModules(QtProject qtPrj, ProFileOption optionQT, ProFileOption optionCONFIG)
{
foreach (var module in QtModules.Instance.GetAvailableModules()) {
if (!qtPrj.HasModule(module.Id))
continue;
if (module.proVarQT != null)
optionQT.List.Add(module.proVarQT);
if (module.proVarCONFIG != null)
optionCONFIG.List.Add(module.proVarCONFIG);
}
}
private void WriteProSolution(ProSolution prosln, bool openFile)
{
var sln = prosln.ProjectSolution;
if (string.IsNullOrEmpty(sln.FileName))
return;
var fi = new FileInfo(sln.FullName);
var slnDir = fi.Directory;
var createSlnFile = false;
if ((slnDir != null) && (prosln.ProFiles.Count > 1)) {
if (MessageBox.Show(SR.GetString("ExportProject_SolutionProFileBuildIn", slnDir.FullName),
SR.GetString("ExportSolution"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
createSlnFile = true;
}
if (createSlnFile) {
StreamWriter sw;
var slnName = HelperFunctions.RemoveFileNameExtension(fi);
var slnFileName = slnDir.FullName + "\\" + slnName + ".pro";
if (File.Exists(slnFileName)) {
if (MessageBox.Show(SR.GetString("ExportProject_ExistsOverwriteQuestion", slnFileName),
SR.GetString("ExportSolution"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
return;
}
try {
sw = new StreamWriter(File.Create(slnFileName));
} catch (Exception e) {
Messages.DisplayErrorMessage(e);
return;
}
var content = new ProFileContent(null);
var option = new ProFileOption("TEMPLATE");
option.NewOption = null; // just one option...
option.AssignSymbol = ProFileOption.AssignType.AT_Equals;
content.Options.Add(option);
option.List.Add("subdirs");
option = new ProFileOption("SUBDIRS");
option.ShortComment = "#Projects";
content.Options.Add(option);
string proFullName, relativePath;
char[] trimChars = { '\\' };
foreach (var profile in prosln.ProFiles) {
var fiProject = new FileInfo(profile.Project.ProjectFile);
var projectBaseName = HelperFunctions.RemoveFileNameExtension(fiProject);
proFullName = profile.Project.ProjectDirectory + projectBaseName + ".pro";
relativePath = HelperFunctions.GetRelativePath(slnDir.FullName, proFullName);
relativePath = relativePath.TrimEnd(trimChars);
relativePath = HelperFunctions.ChangePathFormat(relativePath.Remove(0, 2));
option.List.Add(relativePath);
}
using (sw) {
sw.WriteLine(Resources.exportSolutionHeader);
for (var i = 0; i < content.Options.Count; i++)
WriteProFileOption(sw, content.Options[i]);
}
if (openFile)
dteObject.OpenFile(Constants.vsViewKindTextView, slnFileName).Activate();
}
}
private void WriteProFile(ProFileContent content, string proFile, string priFileToInclude, bool openFile)
{
StreamWriter sw;
if (File.Exists(proFile)) {
if (MessageBox.Show(SR.GetString("ExportProject_ExistsOverwriteQuestion", proFile),
SR.GetString("ExportSolution"), MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) {
return;
}
}
try {
sw = new StreamWriter(File.Create(proFile));
} catch (Exception e) {
Messages.DisplayErrorMessage(e);
return;
}
if (!string.IsNullOrEmpty(priFileToInclude)) {
foreach (var option in content.Options) {
if (option.Name == "include" && !option.List.Contains(priFileToInclude)) {
var relativePriPath = HelperFunctions.GetRelativePath(Path.GetDirectoryName(proFile), priFileToInclude);
if (relativePriPath.StartsWith(".\\", StringComparison.Ordinal))
relativePriPath = relativePriPath.Substring(2);
relativePriPath = HelperFunctions.ChangePathFormat(relativePriPath);
option.List.Add(relativePriPath);
break;
}
}
}
using (sw) {
sw.WriteLine(Resources.exportPriHeader);
WriteProFileOptions(sw, content.Options);
}
// open the file in vs
if (openFile)
dteObject.OpenFile(Constants.vsViewKindTextView, proFile).Activate();
}
private void WritePriFile(ProFileContent content, string priFile)
{
StreamWriter sw;
try {
sw = new StreamWriter(File.Create(priFile));
} catch (Exception e) {
Messages.DisplayErrorMessage(e);
return;
}
using (sw) {
sw.WriteLine(Resources.exportProHeader);
WriteProFileOptions(sw, content.Options);
}
}
private static void WriteProFileOptions(StreamWriter sw, List options)
{
foreach (var option in options)
WriteProFileOption(sw, option);
}
private static void WriteProFileOption(StreamWriter sw, ProFileOption option)
{
if (option.List.Count <= 0)
return;
if (option.IncludeComment)
sw.WriteLine(sw.NewLine + "#" + option.ShortComment);
if (option.AssignSymbol != ProFileOption.AssignType.AT_Function) {
sw.Write(option.Name);
switch (option.AssignSymbol) {
case ProFileOption.AssignType.AT_Equals:
sw.Write(" = ");
break;
case ProFileOption.AssignType.AT_MinusEquals:
sw.Write(" -= ");
break;
case ProFileOption.AssignType.AT_PlusEquals:
sw.Write(" += ");
break;
}
for (var i = 0; i < option.List.Count - 1; i++)
sw.Write(option.List[i] + option.NewOption);
sw.Write(option.List[option.List.Count - 1] + sw.NewLine);
} else {
for (var i = 0; i < option.List.Count; i++)
sw.WriteLine(option.Name + "(" + option.List[i] + ")");
}
}
private static VCFilter BestMatch(string path, Hashtable pathFilterTable)
{
var bestMatch = ".";
var inPath = path;
if (inPath.StartsWith(".\\", StringComparison.Ordinal))
inPath = inPath.Substring(2);
foreach (string p in pathFilterTable.Keys) {
var best = 0;
for (var i = 0; i < inPath.Length; ++i) {
if (i < p.Length && inPath[i] == p[i])
++best;
else
break;
}
if (best > bestMatch.Length && p.Length == best)
bestMatch = p;
}
return pathFilterTable[bestMatch] as VCFilter;
}
private static void CollectFilters(VCFilter filter, string path, ref Hashtable filterPathTable,
ref Hashtable pathFilterTable)
{
var newPath = ".";
if (path != null)
newPath = path + "\\" + filter.Name;
newPath = newPath.ToLower().Trim();
newPath = Regex.Replace(newPath, @"\\+\.?\\+", "\\");
newPath = Regex.Replace(newPath, @"\\\.?$", "");
if (newPath.StartsWith(".\\", StringComparison.Ordinal))
newPath = newPath.Substring(2);
filterPathTable.Add(filter, newPath);
pathFilterTable.Add(newPath, filter);
foreach (VCFilter f in (IVCCollection)filter.Filters)
CollectFilters(f, newPath, ref filterPathTable, ref pathFilterTable);
}
public static void SyncIncludeFiles(VCProject vcproj, List priFiles,
List projFiles, DTE dte, bool flat, FakeFilter fakeFilter)
{
var cmpPriFiles = new List(priFiles.Count);
foreach (var s in priFiles)
cmpPriFiles.Add(HelperFunctions.NormalizeFilePath(s).ToLower());
cmpPriFiles.Sort();
var cmpProjFiles = new List(projFiles.Count);
foreach (var s in projFiles)
cmpProjFiles.Add(HelperFunctions.NormalizeFilePath(s).ToLower());
var qtPro = QtProject.Create(vcproj);
var filterPathTable = new Hashtable(17);
var pathFilterTable = new Hashtable(17);
if (!flat && fakeFilter != null) {
var rootFilter = qtPro.FindFilterFromGuid(fakeFilter.UniqueIdentifier);
if (rootFilter == null)
qtPro.AddFilterToProject(Filters.SourceFiles());
CollectFilters(rootFilter, null, ref filterPathTable, ref pathFilterTable);
}
// first check for new files
foreach (var file in cmpPriFiles) {
if (cmpProjFiles.IndexOf(file) > -1)
continue;
if (flat) {
vcproj.AddFile(file); // the file is not in the project
} else {
var path = HelperFunctions.GetRelativePath(vcproj.ProjectDirectory, file);
if (path.StartsWith(".\\", StringComparison.Ordinal))
path = path.Substring(2);
var i = path.LastIndexOf('\\');
if (i > -1)
path = path.Substring(0, i);
else
path = ".";
if (pathFilterTable.Contains(path)) {
var f = pathFilterTable[path] as VCFilter;
f.AddFile(file);
continue;
}
var filter = BestMatch(path, pathFilterTable);
var filterDir = filterPathTable[filter] as string;
var name = path;
if (!name.StartsWith("..", StringComparison.Ordinal) && name.StartsWith(filterDir, StringComparison.Ordinal))
name = name.Substring(filterDir.Length + 1);
var newFilter = filter.AddFilter(name) as VCFilter;
newFilter.AddFile(file);
filterPathTable.Add(newFilter, path);
pathFilterTable.Add(path, newFilter);
}
}
// then check for deleted files
foreach (var file in cmpProjFiles) {
if (cmpPriFiles.IndexOf(file) == -1) {
// the file is not in the pri file
// (only removes it from the project, does not del. the file)
var info = new FileInfo(file);
HelperFunctions.RemoveFileInProject(vcproj, file);
Messages.Print("--- (Importing .pri file) file: " + info.Name +
" does not exist in .pri file, move to " + vcproj.ProjectDirectory + "Deleted");
}
}
}
public void ExportToProFile()
{
var expDlg = new ExportProjectDialog();
var sln = dteObject.Solution;
var prosln = CreateProFileSolution(sln);
if (prosln.ProFiles.Count <= 0) {
Messages.DisplayWarningMessage(SR.GetString("ExportProject_NoProjectsToExport"));
return;
}
expDlg.ProFileSolution = prosln;
expDlg.StartPosition = FormStartPosition.CenterParent;
var ww = new MainWinWrapper(dteObject);
if (expDlg.ShowDialog(ww) == DialogResult.OK) {
WriteProSolution(prosln, expDlg.OpenFiles);
// create all the project .pro files
foreach (var profile in prosln.ProFiles) {
if (profile.Export) {
var project = HelperFunctions.VCProjectToProject(profile.Project);
string priFile = null;
if (expDlg.CreatePriFile)
priFile = ExportToPriFile(project);
else {
var priContent = CreatePriFileContent(project, profile.Project.ProjectDirectory);
profile.Options.AddRange(priContent.Options);
}
WriteProFile(profile, profile.Project.ProjectDirectory + profile.Project.Name + ".pro", priFile, expDlg.OpenFiles);
}
}
}
}
public string ExportToPriFile(Project proj)
{
VCProject vcproj;
if (HelperFunctions.IsQtProject(proj)) {
try {
vcproj = (VCProject)proj.Object;
} catch (Exception e) {
Messages.DisplayErrorMessage(e);
return null;
}
// make the user able to choose .pri file
var fd = new SaveFileDialog();
fd.OverwritePrompt = true;
fd.CheckPathExists = true;
fd.Title = SR.GetString("ExportProject_ExportPriFile");
fd.Filter = "Project Include Files (*.pri)|*.pri";
fd.InitialDirectory = vcproj.ProjectDirectory;
fd.FileName = vcproj.Name + ".pri";
if (fd.ShowDialog() != DialogResult.OK)
return null;
ExportToPriFile(proj, fd.FileName);
return fd.FileName;
}
return null;
}
public void ExportToPriFile(Project proj, string fileName)
{
var priFile = new FileInfo(fileName);
var content = CreatePriFileContent(proj, priFile.DirectoryName);
WritePriFile(content, priFile.FullName);
}
}
}