logic: visual studio solution parsing
Can now parse visual studio solutions. VS Plugin can send a command, parsing is implemented in Coati. Some minor changes: added project file icon, added language check to vs plugin
This commit is contained in:
@@ -18,6 +18,9 @@
|
||||
#include "version.h"
|
||||
|
||||
|
||||
#include "utility/solution/SolutionParserVisualStudio.h"
|
||||
#include "settings/ProjectSettings.h"
|
||||
|
||||
void init()
|
||||
{
|
||||
std::shared_ptr<ConsoleLogger> consoleLogger = std::make_shared<ConsoleLogger>();
|
||||
|
||||
@@ -237,6 +237,7 @@ add_files(
|
||||
utility/messaging/type/MessageInterruptTasks.h
|
||||
utility/messaging/type/MessageLoadProject.h
|
||||
utility/messaging/type/MessageMoveIDECursor.h
|
||||
utility/messaging/type/MessageNewProject.h
|
||||
utility/messaging/type/MessageRedo.h
|
||||
utility/messaging/type/MessageRefresh.h
|
||||
utility/messaging/type/MessageResetZoom.h
|
||||
@@ -273,6 +274,11 @@ add_files(
|
||||
utility/scheduling/TaskScheduler.cpp
|
||||
utility/scheduling/TaskScheduler.h
|
||||
|
||||
utility/solution/ISolutionParser.cpp
|
||||
utility/solution/ISolutionParser.h
|
||||
utility/solution/SolutionParserVisualStudio.cpp
|
||||
utility/solution/SolutionParserVisualStudio.h
|
||||
|
||||
utility/text/Dictionary.cpp
|
||||
utility/text/Dictionary.h
|
||||
utility/text/TextAccess.cpp
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
#include "IDECommunicationController.h"
|
||||
|
||||
#include "component/controller/helper/NetworkProtocolHelper.h"
|
||||
#include "data/access/StorageAccess.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "data/location/TokenLocation.h"
|
||||
|
||||
#include "utility/messaging/type/MessageActivateTokenLocations.h"
|
||||
#include "utility/messaging/type/MessageActivateWindow.h"
|
||||
#include "utility/messaging/type/MessageLoadProject.h"
|
||||
#include "utility/messaging/type/MessageStatus.h"
|
||||
#include "utility/messaging/type/MessageNewProject.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/solution/SolutionParserVisualStudio.h"
|
||||
|
||||
#include "settings/ProjectSettings.h"
|
||||
|
||||
IDECommunicationController::IDECommunicationController(StorageAccess* storageAccess)
|
||||
: m_storageAccess(storageAccess)
|
||||
@@ -21,30 +25,44 @@ IDECommunicationController::~IDECommunicationController()
|
||||
|
||||
void IDECommunicationController::handleIncomingMessage(const std::string& message)
|
||||
{
|
||||
LOG_WARNING_STREAM(<< message);
|
||||
NetworkProtocolHelper::MESSAGE_TYPE type = NetworkProtocolHelper::getMessageType(message);
|
||||
|
||||
NetworkProtocolHelper::NetworkMessage parsedMessage = NetworkProtocolHelper::parseMessage(message);
|
||||
|
||||
if (parsedMessage.valid)
|
||||
if (type == NetworkProtocolHelper::MESSAGE_TYPE::UNKNOWN)
|
||||
{
|
||||
const unsigned int cursorColumn = parsedMessage.column;
|
||||
LOG_ERROR_STREAM(<< "Invalid message type");
|
||||
}
|
||||
else if (type == NetworkProtocolHelper::MESSAGE_TYPE::SET_ACTIVE_TOKEN)
|
||||
{
|
||||
handleSetActiveTokenMessage(NetworkProtocolHelper::parseSetActiveTokenMessage(message));
|
||||
}
|
||||
else
|
||||
{
|
||||
handleCreateProjectMessage(NetworkProtocolHelper::parseCreateProjectMessage(message));
|
||||
}
|
||||
}
|
||||
|
||||
void IDECommunicationController::handleSetActiveTokenMessage(const NetworkProtocolHelper::SetActiveTokenMessage& message)
|
||||
{
|
||||
if (message.valid)
|
||||
{
|
||||
const unsigned int cursorColumn = message.column;
|
||||
|
||||
std::shared_ptr<TokenLocationFile> tokenLocationFile = m_storageAccess->getTokenLocationsForLinesInFile(
|
||||
parsedMessage.fileLocation, parsedMessage.row, parsedMessage.row
|
||||
);
|
||||
message.fileLocation, message.row, message.row
|
||||
);
|
||||
|
||||
std::vector<Id> selectedLocationIds;
|
||||
tokenLocationFile->forEachStartTokenLocation(
|
||||
[&](TokenLocation* startLocation)
|
||||
{
|
||||
TokenLocation* endLocation = startLocation->getEndTokenLocation();
|
||||
{
|
||||
TokenLocation* endLocation = startLocation->getEndTokenLocation();
|
||||
|
||||
if (!startLocation->isScopeTokenLocation() &&
|
||||
startLocation->getColumnNumber() <= cursorColumn && endLocation->getColumnNumber() + 1 >= cursorColumn)
|
||||
{
|
||||
selectedLocationIds.push_back(startLocation->getId());
|
||||
}
|
||||
if (!startLocation->isScopeTokenLocation() &&
|
||||
startLocation->getColumnNumber() <= cursorColumn && endLocation->getColumnNumber() + 1 >= cursorColumn)
|
||||
{
|
||||
selectedLocationIds.push_back(startLocation->getId());
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (selectedLocationIds.size() > 0)
|
||||
@@ -57,7 +75,53 @@ void IDECommunicationController::handleIncomingMessage(const std::string& messag
|
||||
{
|
||||
MessageStatus(
|
||||
"Activating a source location from external failed. No symbol(s) have been found at the selected location."
|
||||
).dispatch();
|
||||
).dispatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IDECommunicationController::handleCreateProjectMessage(const NetworkProtocolHelper::CreateProjectMessage& message)
|
||||
{
|
||||
if (message.valid)
|
||||
{
|
||||
if (message.ideId == NetworkProtocolHelper::CreateProjectMessage::IDE_ID::VS)
|
||||
{
|
||||
SolutionParserVisualStudio parser;
|
||||
|
||||
parser.openSolutionFile(message.solutionFileLocation);
|
||||
std::vector<std::string> includePaths = parser.getIncludePaths();
|
||||
std::vector<std::string> projectItems = parser.getProjectItems();
|
||||
|
||||
std::vector<FilePath> projectFPs;
|
||||
std::vector<FilePath> includeFPs;
|
||||
|
||||
for (unsigned int i = 0; i < projectItems.size(); i++)
|
||||
{
|
||||
projectFPs.push_back(FilePath(projectItems[i]));
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < includePaths.size(); i++)
|
||||
{
|
||||
includeFPs.push_back(FilePath(includePaths[i]));
|
||||
}
|
||||
|
||||
/*ProjectSettings* projSettings = ProjectSettings::getInstance().get();
|
||||
projSettings->clear();
|
||||
|
||||
projSettings->setLanguage("c++");
|
||||
projSettings->setStandard("11");
|
||||
|
||||
projSettings->setSourcePaths(projectFPs);
|
||||
projSettings->setHeaderSearchPaths(includeFPs);
|
||||
|
||||
std::string filePath = parser.getSolutionPath() + parser.getSolutionName() + ".coatiproject";
|
||||
projSettings->save(filePath);*/
|
||||
|
||||
MessageNewProject(parser.getSolutionName(), parser.getSolutionPath(), projectItems, includePaths).dispatch();
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Unable to parse provided solution, unknown format");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "component/controller/Controller.h"
|
||||
|
||||
#include "component/controller/helper/NetworkProtocolHelper.h"
|
||||
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageMoveIDECursor.h"
|
||||
|
||||
@@ -21,6 +23,9 @@ public:
|
||||
void handleIncomingMessage(const std::string& message);
|
||||
|
||||
private:
|
||||
void handleSetActiveTokenMessage(const NetworkProtocolHelper::SetActiveTokenMessage& message);
|
||||
void handleCreateProjectMessage(const NetworkProtocolHelper::CreateProjectMessage& message);
|
||||
|
||||
virtual void handleMessage(MessageMoveIDECursor* message);
|
||||
virtual void sendMessage(const std::string& message) const = 0;
|
||||
|
||||
|
||||
@@ -3,38 +3,119 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
std::string NetworkProtocolHelper::m_divider = ">>";
|
||||
std::string NetworkProtocolHelper::m_setActiveTokenPrefix = "setActiveToken";
|
||||
std::string NetworkProtocolHelper::m_moveCursorPrefix = "moveCursor";
|
||||
std::string NetworkProtocolHelper::m_endOfMessageToken = "<EOM>";
|
||||
std::string NetworkProtocolHelper::m_createProjectPrefix = "createProject";
|
||||
|
||||
NetworkProtocolHelper::NetworkMessage NetworkProtocolHelper::parseMessage(const std::string& message)
|
||||
NetworkProtocolHelper::MESSAGE_TYPE NetworkProtocolHelper::getMessageType(const std::string& message)
|
||||
{
|
||||
NetworkMessage networkMessage;
|
||||
|
||||
size_t pos = message.find(m_setActiveTokenPrefix);
|
||||
std::vector<std::string> subMessages = divideMessage(message);
|
||||
|
||||
if(pos != std::string::npos)
|
||||
if (subMessages.size() > 0)
|
||||
{
|
||||
std::string tmpMessage = "";
|
||||
getSubstringAfterString(message, m_divider, tmpMessage); // just get rid of message type
|
||||
tmpMessage = removeEndOfMessageToken(tmpMessage);
|
||||
if (subMessages[0] == m_setActiveTokenPrefix)
|
||||
{
|
||||
return MESSAGE_TYPE::SET_ACTIVE_TOKEN;
|
||||
}
|
||||
else if (subMessages[0] == m_createProjectPrefix)
|
||||
{
|
||||
return MESSAGE_TYPE::CREATE_PROJECT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MESSAGE_TYPE::UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
return MESSAGE_TYPE::UNKNOWN;
|
||||
}
|
||||
|
||||
std::string fileLocation = getSubstringAfterString(tmpMessage, m_divider, tmpMessage);
|
||||
std::string row = getSubstringAfterString(tmpMessage, m_divider, tmpMessage);
|
||||
std::string column = tmpMessage; // there should be nothing left in the message but the column number
|
||||
NetworkProtocolHelper::SetActiveTokenMessage NetworkProtocolHelper::parseSetActiveTokenMessage(const std::string& message)
|
||||
{
|
||||
std::vector<std::string> subMessages = divideMessage(message);
|
||||
|
||||
if(
|
||||
fileLocation.length() > 0
|
||||
&& row.length() > 0
|
||||
&& column.length() > 0
|
||||
&& isDigits(row)
|
||||
&& isDigits(column)
|
||||
){
|
||||
networkMessage.fileLocation = fileLocation;
|
||||
networkMessage.row = std::stoi(row);
|
||||
networkMessage.column = std::stoi(column);
|
||||
networkMessage.valid = true;
|
||||
SetActiveTokenMessage networkMessage;
|
||||
|
||||
if (subMessages.size() > 0)
|
||||
{
|
||||
if (subMessages[0] == m_setActiveTokenPrefix)
|
||||
{
|
||||
if (subMessages.size() != 5)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse setActiveToken message, invalid token count");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fileLocation = subMessages[1];
|
||||
std::string row = subMessages[2];
|
||||
std::string column = subMessages[3];
|
||||
|
||||
if(
|
||||
fileLocation.length() > 0
|
||||
&& row.length() > 0
|
||||
&& column.length() > 0
|
||||
&& isDigits(row)
|
||||
&& isDigits(column)
|
||||
){
|
||||
networkMessage.fileLocation = fileLocation;
|
||||
networkMessage.row = std::stoi(row);
|
||||
networkMessage.column = std::stoi(column);
|
||||
networkMessage.valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token");
|
||||
}
|
||||
}
|
||||
|
||||
return networkMessage;
|
||||
}
|
||||
|
||||
NetworkProtocolHelper::CreateProjectMessage NetworkProtocolHelper::parseCreateProjectMessage(const std::string& message)
|
||||
{
|
||||
std::vector<std::string> subMessages = divideMessage(message);
|
||||
|
||||
NetworkProtocolHelper::CreateProjectMessage networkMessage;
|
||||
|
||||
if (subMessages.size() > 0)
|
||||
{
|
||||
if (subMessages[0] == m_createProjectPrefix)
|
||||
{
|
||||
if (subMessages.size() != 4)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse createProject message, invalid token count");
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string fileLocation = subMessages[1];
|
||||
std::string ideId = subMessages[2];
|
||||
if (fileLocation.length() > 0
|
||||
&& ideId.length() > 0)
|
||||
{
|
||||
networkMessage.solutionFileLocation = fileLocation;
|
||||
|
||||
if (ideId == "vs")
|
||||
{
|
||||
networkMessage.ideId = CreateProjectMessage::IDE_ID::VS;
|
||||
}
|
||||
else
|
||||
{
|
||||
networkMessage.ideId = CreateProjectMessage::IDE_ID::UNKNOWN;
|
||||
}
|
||||
|
||||
networkMessage.valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +138,36 @@ std::string NetworkProtocolHelper::buildMessage(const std::string& fileLocation,
|
||||
return messageStream.str();
|
||||
}
|
||||
|
||||
std::vector<std::string> NetworkProtocolHelper::divideMessage(const std::string& message)
|
||||
{
|
||||
std::vector<std::string> result;
|
||||
|
||||
std::string msg = message;
|
||||
size_t pos = msg.find(m_divider);
|
||||
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
std::string subMessage = msg.substr(0, pos);
|
||||
result.push_back(subMessage);
|
||||
msg = msg.substr(pos + m_divider.size());
|
||||
pos = msg.find(m_divider);
|
||||
}
|
||||
|
||||
if (msg.size() > 0)
|
||||
{
|
||||
pos = msg.find(m_endOfMessageToken);
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string subMessage = msg.substr(0, pos);
|
||||
result.push_back(subMessage);
|
||||
msg = msg.substr(pos);
|
||||
result.push_back(msg);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string NetworkProtocolHelper::removeEndOfMessageToken(const std::string& message)
|
||||
{
|
||||
size_t pos = message.find(m_endOfMessageToken);
|
||||
|
||||
@@ -2,14 +2,15 @@
|
||||
#define NETWORK_PROTOCOL_HELPER_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class NetworkProtocolHelper
|
||||
{
|
||||
public:
|
||||
struct NetworkMessage
|
||||
struct SetActiveTokenMessage
|
||||
{
|
||||
public:
|
||||
NetworkMessage()
|
||||
SetActiveTokenMessage()
|
||||
: fileLocation("")
|
||||
, row(0)
|
||||
, column(0)
|
||||
@@ -22,10 +23,43 @@ public:
|
||||
bool valid;
|
||||
};
|
||||
|
||||
static NetworkMessage parseMessage(const std::string& message);
|
||||
struct CreateProjectMessage
|
||||
{
|
||||
public:
|
||||
CreateProjectMessage()
|
||||
: solutionFileLocation("")
|
||||
, ideId(IDE_ID::UNKNOWN)
|
||||
, valid(false)
|
||||
{}
|
||||
|
||||
enum IDE_ID
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
VS
|
||||
};
|
||||
|
||||
std::string solutionFileLocation;
|
||||
IDE_ID ideId;
|
||||
bool valid;
|
||||
};
|
||||
|
||||
enum MESSAGE_TYPE
|
||||
{
|
||||
UNKNOWN = 0,
|
||||
SET_ACTIVE_TOKEN,
|
||||
CREATE_PROJECT
|
||||
};
|
||||
|
||||
static MESSAGE_TYPE getMessageType(const std::string& message);
|
||||
|
||||
static SetActiveTokenMessage parseSetActiveTokenMessage(const std::string& message);
|
||||
static CreateProjectMessage parseCreateProjectMessage(const std::string& message);
|
||||
|
||||
static std::string buildMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column);
|
||||
|
||||
private:
|
||||
static std::vector<std::string> divideMessage(const std::string& message);
|
||||
|
||||
static std::string removeEndOfMessageToken(const std::string& message);
|
||||
|
||||
static std::string getSubstringAfterString(const std::string& message, const std::string& searchString, std::string& subMessage);
|
||||
@@ -35,6 +69,7 @@ private:
|
||||
static std::string m_setActiveTokenPrefix;
|
||||
static std::string m_moveCursorPrefix;
|
||||
static std::string m_endOfMessageToken;
|
||||
static std::string m_createProjectPrefix;
|
||||
};
|
||||
|
||||
#endif // NETWORK_PROTOCOL_HELPER_H
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef MESSAGE_NEW_PROJECT_H
|
||||
#define MESSAGE_NEW_PROJECT_H
|
||||
|
||||
#include "utility/messaging/Message.h"
|
||||
|
||||
class MessageNewProject : public Message<MessageNewProject>
|
||||
{
|
||||
public:
|
||||
MessageNewProject(const std::string& projectName, const std::string projectLocation,
|
||||
const std::vector<std::string>& sourceFiles, const std::vector<std::string>& includePaths)
|
||||
: projectName(projectName)
|
||||
, projectLocation(projectLocation)
|
||||
, projectSourceFiles(sourceFiles)
|
||||
, projectIncludePaths(includePaths)
|
||||
{
|
||||
}
|
||||
|
||||
static const std::string getStaticType()
|
||||
{
|
||||
return "MessageNewProject";
|
||||
}
|
||||
|
||||
virtual void print(std::ostream& os) const
|
||||
{
|
||||
}
|
||||
|
||||
const std::string projectName;
|
||||
const std::string projectLocation;
|
||||
const std::vector<std::string> projectSourceFiles;
|
||||
const std::vector<std::string> projectIncludePaths;
|
||||
};
|
||||
|
||||
#endif // MESSAGE_NEW_PROJECT_H
|
||||
@@ -0,0 +1,48 @@
|
||||
#include "ISolutionParser.h"
|
||||
|
||||
std::string ISolutionParser::getSolutionPath()
|
||||
{
|
||||
return m_solutionPath;
|
||||
}
|
||||
|
||||
void ISolutionParser::openSolutionFile(const std::string& solutionFilePath)
|
||||
{
|
||||
m_solution = loadFile(solutionFilePath);
|
||||
|
||||
size_t pos = solutionFilePath.find_last_of("/");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
pos = solutionFilePath.find_last_of("\\");
|
||||
}
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
if (pos > 0)
|
||||
{
|
||||
pos += 1;
|
||||
}
|
||||
|
||||
m_solutionPath = solutionFilePath.substr(0, pos);
|
||||
m_solutionName = solutionFilePath.substr(pos);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int ISolutionParser::getSolutionCharCount() const
|
||||
{
|
||||
return m_solution.size();
|
||||
}
|
||||
|
||||
std::string ISolutionParser::loadFile(const std::string& filePath)
|
||||
{
|
||||
std::string file = "";
|
||||
|
||||
std::ifstream ifstream;
|
||||
ifstream.open(filePath);
|
||||
|
||||
if (ifstream.is_open())
|
||||
{
|
||||
file = std::string(std::istreambuf_iterator<char>(ifstream), std::istreambuf_iterator<char>());
|
||||
}
|
||||
|
||||
return file;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef I_SOLUTION_PARSER_H
|
||||
#define I_SOLUTION_PARSER_H
|
||||
|
||||
#include <fstream>
|
||||
#include <vector>
|
||||
|
||||
class ISolutionParser
|
||||
{
|
||||
public:
|
||||
ISolutionParser()
|
||||
: m_solutionPath("")
|
||||
, m_solution("")
|
||||
{};
|
||||
virtual ~ISolutionParser(){};
|
||||
|
||||
void openSolutionFile(const std::string& solutionFilePath);
|
||||
unsigned int getSolutionCharCount() const;
|
||||
|
||||
virtual std::string getSolutionName() = 0; // to be overwritten to account for different file endings
|
||||
std::string getSolutionPath();
|
||||
|
||||
virtual std::vector<std::string> getProjects() = 0;
|
||||
virtual std::vector<std::string> getProjectFiles() = 0;
|
||||
virtual std::vector<std::string> getProjectItems() = 0;
|
||||
|
||||
protected:
|
||||
std::string loadFile(const std::string& filePath);
|
||||
|
||||
std::string m_solutionName;
|
||||
std::string m_solutionPath;
|
||||
std::string m_solution;
|
||||
};
|
||||
|
||||
#endif // I_SOLUTION_PARSER_H
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "SolutionParserCMake.h"
|
||||
|
||||
SolutionParserCMake::SolutionParserCMake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SolutionParserCMake::~SolutionParserCMake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserCMake::getProjects()
|
||||
{
|
||||
std::vector<std::string> projects;
|
||||
|
||||
return projects;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef SOLUTION_PARSER_C_MAKE_H
|
||||
#define SOLUTION_PARSER_C_MAKE_H
|
||||
|
||||
#include "ISolutionParser.h"
|
||||
|
||||
class SolutionParserCMake : public ISolutionParser
|
||||
{
|
||||
public:
|
||||
SolutionParserCMake();
|
||||
virtual ~SolutionParserCMake();
|
||||
|
||||
virtual std::vector<std::string> getProjects();
|
||||
virtual std::vector<std::string> getProjectFiles();
|
||||
};
|
||||
|
||||
#endif // SOLUTION_PARSER_C_MAKE_H
|
||||
@@ -0,0 +1,604 @@
|
||||
#include "SolutionParserVisualStudio.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <set>
|
||||
|
||||
#include "boost/filesystem/path.hpp"
|
||||
#include "boost/filesystem.hpp"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
SolutionParserVisualStudio::SolutionParserVisualStudio()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
SolutionParserVisualStudio::~SolutionParserVisualStudio()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::string SolutionParserVisualStudio::getSolutionName()
|
||||
{
|
||||
std::string result = "";
|
||||
|
||||
if (m_solutionName.size() > 0)
|
||||
{
|
||||
size_t pos = m_solutionName.find(".sln");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
result = m_solutionName.substr(0, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = m_solution;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::getProjects()
|
||||
{
|
||||
std::vector<std::string> projectFiles;
|
||||
|
||||
if (m_solution.size() > 0)
|
||||
{
|
||||
std::vector<std::string> blocks = getProjectBlocks(m_solution);
|
||||
|
||||
for (unsigned int i = 0; i < blocks.size(); i++)
|
||||
{
|
||||
projectFiles.push_back(getProjectFilePath(blocks[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return projectFiles;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::getProjectFiles()
|
||||
{
|
||||
std::vector<std::string> projectFiles;
|
||||
std::vector<std::string> projectFilesNames = getProjects();
|
||||
|
||||
for (unsigned int i = 0; i < projectFilesNames.size(); i++)
|
||||
{
|
||||
projectFiles.push_back(loadFile(m_solutionPath + projectFilesNames[i]));
|
||||
}
|
||||
|
||||
//projectFiles.push_back(loadFile(m_solutionPath + "foo.xml"));
|
||||
|
||||
return projectFiles;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::getProjectItems()
|
||||
{
|
||||
std::vector<std::string> projectItems;
|
||||
|
||||
std::vector<std::string> projectFilesNames = getProjects();
|
||||
std::vector<std::string> projectFiles = getProjectFiles();
|
||||
|
||||
std::vector<std::string> relativeProjectPaths;
|
||||
|
||||
for (unsigned int i = 0; i < projectFilesNames.size(); i++)
|
||||
{
|
||||
size_t pos = projectFilesNames[i].find_last_of("/");
|
||||
if (pos == std::string::npos)
|
||||
{
|
||||
pos = projectFilesNames[i].find_last_of("\\");
|
||||
}
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
relativeProjectPaths.push_back(projectFilesNames[i].substr(0, pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
relativeProjectPaths.push_back("");
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < projectFiles.size(); i++)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(projectFiles[i].c_str(), 0, TIXML_ENCODING_UTF8);
|
||||
|
||||
std::string error = doc.ErrorDesc();
|
||||
|
||||
if (error.length() > 0)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse project file " << i << ": " << error);
|
||||
continue;
|
||||
}
|
||||
|
||||
TiXmlElement* root = getFirstTagByNameWithAttribute(doc.RootElement(), "ClCompile", "Include");
|
||||
if (root != NULL)
|
||||
{
|
||||
// std::string text(root->GetText());
|
||||
std::string tag = root->Value();
|
||||
std::string text = "";
|
||||
if (root->Attribute("Include") != NULL)
|
||||
{
|
||||
text = root->Attribute("Include");
|
||||
}
|
||||
|
||||
if (text.find(".cpp") == std::string::npos)
|
||||
{
|
||||
root = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
root = root->Parent()->ToElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (root == NULL)
|
||||
{
|
||||
TiXmlElement* root = getFirstTagByNameWithAttribute(doc.RootElement(), "ClInclude", "Include");
|
||||
if (root != NULL)
|
||||
{
|
||||
root = root->Parent()->ToElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
root = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (root != NULL)
|
||||
{
|
||||
for (TiXmlElement* child = root->FirstChildElement(); child != NULL; child = child->NextSiblingElement())
|
||||
{
|
||||
std::string filePath = child->Attribute("Include");
|
||||
|
||||
if (relativeProjectPaths[i].size() > 0)
|
||||
{
|
||||
filePath = relativeProjectPaths[i] + "/" + filePath;
|
||||
}
|
||||
|
||||
projectItems.push_back(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::set<std::string> s(projectItems.begin(), projectItems.end());
|
||||
projectItems.assign(s.begin(), s.end());
|
||||
|
||||
projectItems = resolveEnvironmentVariables(projectItems);
|
||||
projectItems = makePathsAbsolute(projectItems);
|
||||
projectItems = makePathsCanonical(projectItems);
|
||||
|
||||
return projectItems;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::getIncludePaths()
|
||||
{
|
||||
std::vector<std::string> includePaths;
|
||||
|
||||
std::vector<std::string> projectFiles = getProjectFiles();
|
||||
|
||||
for (unsigned int i = 0; i < projectFiles.size(); i++)
|
||||
{
|
||||
TiXmlDocument doc;
|
||||
doc.Parse(projectFiles[i].c_str(), 0, TIXML_ENCODING_UTF8);
|
||||
|
||||
std::string error = doc.ErrorDesc();
|
||||
|
||||
if (error.length() > 0)
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "Failed to parse project file " << i << ": " << error);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::vector<TiXmlElement*> nodes = getAllTagsByName(doc.RootElement(), "AdditionalIncludeDirectories");
|
||||
|
||||
for (unsigned int j = 0; j < nodes.size(); j++)
|
||||
{
|
||||
includePaths.push_back(nodes[j]->GetText());
|
||||
}
|
||||
}
|
||||
|
||||
includePaths = seperateIncludePaths(includePaths);
|
||||
|
||||
std::set<std::string> s(includePaths.begin(), includePaths.end());
|
||||
includePaths.assign(s.begin(), s.end());
|
||||
|
||||
includePaths = resolveEnvironmentVariables(includePaths);
|
||||
includePaths = makePathsAbsolute(includePaths);
|
||||
includePaths = makePathsCanonical(includePaths);
|
||||
|
||||
return includePaths;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::getProjectBlocks(const std::string& solution) const
|
||||
{
|
||||
std::vector<std::string> blocks;
|
||||
|
||||
std::string subSolution = solution;
|
||||
|
||||
std::string solutionOpenTag = "\nProject";
|
||||
std::string solutionCloseTag = "\nEndProject";
|
||||
|
||||
size_t blockStart = subSolution.find(solutionOpenTag, 0);
|
||||
size_t blockEnd = subSolution.find(solutionCloseTag, 0);
|
||||
|
||||
while (blockStart != std::string::npos && blockEnd != std::string::npos)
|
||||
{
|
||||
std::string block = subSolution.substr(blockStart, blockEnd - blockStart + solutionCloseTag.size());
|
||||
|
||||
if (subSolution.size() > blockEnd + solutionCloseTag.size())
|
||||
{
|
||||
subSolution = subSolution.substr(blockEnd + solutionCloseTag.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
subSolution = "";
|
||||
}
|
||||
|
||||
blockStart = subSolution.find(solutionOpenTag);
|
||||
blockEnd = subSolution.find(solutionCloseTag);
|
||||
|
||||
blocks.push_back(block);
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
|
||||
std::string SolutionParserVisualStudio::getProjectFilePath(const std::string& projectBlock) const
|
||||
{
|
||||
std::string projectFilePath;
|
||||
|
||||
std::string fileEnding = "vcxproj";
|
||||
|
||||
size_t pos = projectBlock.find(fileEnding);
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
std::string searchArea = projectBlock.substr(0, pos + fileEnding.size());
|
||||
pos = searchArea.find_last_of("\"");
|
||||
projectFilePath = searchArea.substr(pos + 1);
|
||||
}
|
||||
|
||||
return projectFilePath;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::seperateIncludePaths(const std::vector<std::string>& includePaths) const
|
||||
{
|
||||
std::vector<std::string> seperatedPaths;
|
||||
|
||||
for (unsigned int i = 0; i < includePaths.size(); i++)
|
||||
{
|
||||
std::vector<std::string> paths = seperateIncludePaths(includePaths[i]);
|
||||
for (unsigned int j = 0; j < paths.size(); j++)
|
||||
{
|
||||
seperatedPaths.push_back(paths[j]);
|
||||
}
|
||||
}
|
||||
|
||||
return seperatedPaths;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::seperateIncludePaths(const std::string& includePaths) const
|
||||
{
|
||||
std::string paths = includePaths;
|
||||
std::string seperator = ";";
|
||||
|
||||
std::vector<std::string> seperatedPaths;
|
||||
|
||||
size_t pos = includePaths.find(seperator);
|
||||
|
||||
while (pos != std::string::npos)
|
||||
{
|
||||
std::string path = paths.substr(0, pos);
|
||||
paths = paths.substr(pos + 1);
|
||||
|
||||
seperatedPaths.push_back(path);
|
||||
|
||||
pos = paths.find(seperator);
|
||||
}
|
||||
|
||||
return seperatedPaths;
|
||||
}
|
||||
|
||||
TiXmlElement* SolutionParserVisualStudio::getFirstTagByName(TiXmlElement* root, const std::string& tag)
|
||||
{
|
||||
TiXmlElement* element = root;
|
||||
|
||||
while (element)
|
||||
{
|
||||
if (element == NULL)
|
||||
{
|
||||
int foo = 0;
|
||||
}
|
||||
|
||||
std::string value = element->Value();
|
||||
|
||||
if (value == tag) // "ClInclude") // || value == "ClCompile")
|
||||
{
|
||||
if (element->Parent() != NULL)
|
||||
{
|
||||
return element; // ->Parent()->ToElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (element->FirstChildElement() != NULL)
|
||||
{
|
||||
element = element->FirstChildElement();
|
||||
}
|
||||
else if (element->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (element == NULL)
|
||||
{
|
||||
int foo = 0;
|
||||
}
|
||||
|
||||
while (element->Parent()->ToElement() != NULL && element->Parent()->NextSiblingElement() == NULL)
|
||||
{
|
||||
TiXmlElement* newElement = element->Parent()->ToElement();
|
||||
|
||||
if (newElement == NULL)
|
||||
{
|
||||
int foo = 0;
|
||||
}
|
||||
|
||||
element = newElement;
|
||||
}
|
||||
if (element->Parent() != NULL && element->Parent()->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->Parent()->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<TiXmlElement*> SolutionParserVisualStudio::getAllTagsByName(TiXmlElement* root, const std::string& tag)
|
||||
{
|
||||
std::vector<TiXmlElement*> nodes;
|
||||
|
||||
TiXmlElement* element = root;
|
||||
|
||||
while (element)
|
||||
{
|
||||
std::string value = element->Value();
|
||||
|
||||
if (value == tag)
|
||||
{
|
||||
nodes.push_back(element);
|
||||
}
|
||||
|
||||
if (element->FirstChildElement() != NULL)
|
||||
{
|
||||
element = element->FirstChildElement();
|
||||
}
|
||||
else if (element->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (element == NULL)
|
||||
{
|
||||
int foo = 0;
|
||||
}
|
||||
|
||||
while (element->Parent()->ToElement() != NULL && element->Parent()->NextSiblingElement() == NULL)
|
||||
{
|
||||
TiXmlElement* newElement = element->Parent()->ToElement();
|
||||
|
||||
if (newElement == NULL)
|
||||
{
|
||||
int foo = 0;
|
||||
}
|
||||
|
||||
element = newElement;
|
||||
}
|
||||
if (element->Parent() != NULL && element->Parent()->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->Parent()->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
TiXmlElement* SolutionParserVisualStudio::getFirstTagByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute)
|
||||
{
|
||||
TiXmlElement* element = root;
|
||||
|
||||
while (element)
|
||||
{
|
||||
if (element == NULL)
|
||||
{
|
||||
int foo = 0;
|
||||
}
|
||||
|
||||
std::string value = element->Value();
|
||||
|
||||
bool hasAttribute = false;
|
||||
if (element->Attribute(attribute.c_str()) != NULL)
|
||||
{
|
||||
hasAttribute = true;
|
||||
}
|
||||
|
||||
if (value == tag && hasAttribute) // "ClInclude") // || value == "ClCompile")
|
||||
{
|
||||
if (element->Parent() != NULL)
|
||||
{
|
||||
return element; // ->Parent()->ToElement();
|
||||
}
|
||||
}
|
||||
|
||||
if (element->FirstChildElement() != NULL)
|
||||
{
|
||||
element = element->FirstChildElement();
|
||||
}
|
||||
else if (element->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (element->Parent()->ToElement() != NULL && element->Parent()->NextSiblingElement() == NULL)
|
||||
{
|
||||
TiXmlElement* newElement = element->Parent()->ToElement();
|
||||
|
||||
element = newElement;
|
||||
}
|
||||
if (element->Parent() != NULL && element->Parent()->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->Parent()->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<TiXmlElement*> SolutionParserVisualStudio::getAllTagsByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute)
|
||||
{
|
||||
std::vector<TiXmlElement*> nodes;
|
||||
|
||||
TiXmlElement* element = root;
|
||||
|
||||
while (element)
|
||||
{
|
||||
std::string value = element->Value();
|
||||
|
||||
bool hasAttribute = false;
|
||||
if (element->Attribute(attribute.c_str()) != NULL)
|
||||
{
|
||||
hasAttribute = true;
|
||||
}
|
||||
|
||||
if (value == tag && hasAttribute)
|
||||
{
|
||||
nodes.push_back(element);
|
||||
}
|
||||
|
||||
if (element->FirstChildElement() != NULL)
|
||||
{
|
||||
element = element->FirstChildElement();
|
||||
}
|
||||
else if (element->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
while (element->Parent()->ToElement() != NULL && element->Parent()->NextSiblingElement() == NULL)
|
||||
{
|
||||
TiXmlElement* newElement = element->Parent()->ToElement();
|
||||
|
||||
element = newElement;
|
||||
}
|
||||
if (element->Parent() != NULL && element->Parent()->NextSiblingElement() != NULL)
|
||||
{
|
||||
element = element->Parent()->NextSiblingElement();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::resolveEnvironmentVariables(const std::vector<std::string>& paths)
|
||||
{
|
||||
std::vector<std::string> resolvedPaths;
|
||||
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
{
|
||||
resolvedPaths.push_back(findAndResolveEnvironmentVariable(paths[i]));
|
||||
}
|
||||
|
||||
return resolvedPaths;
|
||||
}
|
||||
|
||||
std::string SolutionParserVisualStudio::findAndResolveEnvironmentVariable(const std::string& path)
|
||||
{
|
||||
std::string resolvedPath;
|
||||
|
||||
size_t pos = path.find("$(");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
size_t endPos = path.substr(pos).find(")");
|
||||
|
||||
std::string envVariable = path.substr(pos+2, (endPos-2) - pos);
|
||||
std::string envPath = getenv(envVariable.c_str());
|
||||
|
||||
std::string prePath = path.substr(0, pos);
|
||||
std::string postPath = path.substr(endPos + 1);
|
||||
|
||||
resolvedPath = prePath + envPath + postPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
resolvedPath = path;
|
||||
}
|
||||
|
||||
return resolvedPath;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::makePathsAbsolute(const std::vector<std::string>& paths)
|
||||
{
|
||||
std::vector<std::string> absolutePaths;
|
||||
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
{
|
||||
std::string path = paths[i];
|
||||
|
||||
boost::filesystem::path boostPath(path);
|
||||
if (boostPath.is_relative())
|
||||
{
|
||||
path = m_solutionPath + path;
|
||||
}
|
||||
|
||||
absolutePaths.push_back(path);
|
||||
}
|
||||
|
||||
return absolutePaths;
|
||||
}
|
||||
|
||||
std::vector<std::string> SolutionParserVisualStudio::makePathsCanonical(const std::vector<std::string>& paths)
|
||||
{
|
||||
std::vector<std::string> canonicalPaths;
|
||||
|
||||
for (unsigned int i = 0; i < paths.size(); i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
boost::filesystem::path canonicalPath = boost::filesystem::canonical(boost::filesystem::path(paths[i]));
|
||||
canonicalPaths.push_back(canonicalPath.string());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
LOG_WARNING_STREAM(<< e.what());
|
||||
}
|
||||
}
|
||||
|
||||
return canonicalPaths;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef SOLUTION_PARSER_VISUAL_STUDIO_H
|
||||
#define SOLUTION_PARSER_VISUAL_STUDIO_H
|
||||
|
||||
#include "ISolutionParser.h"
|
||||
|
||||
#include "tinyxml/tinyxml.h"
|
||||
|
||||
class SolutionParserVisualStudio : public ISolutionParser
|
||||
{
|
||||
public:
|
||||
SolutionParserVisualStudio();
|
||||
virtual ~SolutionParserVisualStudio();
|
||||
|
||||
virtual std::string getSolutionName();
|
||||
|
||||
virtual std::vector<std::string> getProjects();
|
||||
virtual std::vector<std::string> getProjectFiles();
|
||||
virtual std::vector<std::string> getProjectItems();
|
||||
virtual std::vector<std::string> getIncludePaths();
|
||||
|
||||
private:
|
||||
std::vector<std::string> getProjectBlocks(const std::string& solution) const;
|
||||
std::string getProjectFilePath(const std::string& projectBlock) const;
|
||||
|
||||
std::vector<std::string> seperateIncludePaths(const std::vector<std::string>& includePaths) const;
|
||||
std::vector<std::string> seperateIncludePaths(const std::string& includePaths) const;
|
||||
|
||||
TiXmlElement* getFirstTagByName(TiXmlElement* root, const std::string& tag);
|
||||
std::vector<TiXmlElement*> getAllTagsByName(TiXmlElement* root, const std::string& tag);
|
||||
|
||||
TiXmlElement* getFirstTagByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute);
|
||||
std::vector<TiXmlElement*> getAllTagsByNameWithAttribute(TiXmlElement* root, const std::string& tag, const std::string& attribute);
|
||||
|
||||
std::vector<std::string> resolveEnvironmentVariables(const std::vector<std::string>& paths);
|
||||
std::string findAndResolveEnvironmentVariable(const std::string& path);
|
||||
std::vector<std::string> makePathsAbsolute(const std::vector<std::string>& paths);
|
||||
std::vector<std::string> makePathsCanonical(const std::vector<std::string>& paths);
|
||||
};
|
||||
|
||||
#endif // SOLUTION_PARSER_VISUAL_STUDIO_H
|
||||
@@ -106,6 +106,7 @@ bool MouseWheelFilter::eventFilter(QObject* obj, QEvent* event)
|
||||
|
||||
QtMainWindow::QtMainWindow()
|
||||
: m_showDockWidgetTitleBars(true)
|
||||
, m_createNewProjectFunctor(std::bind(&QtMainWindow::doCreateNewProject, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4))
|
||||
{
|
||||
setObjectName("QtMainWindow");
|
||||
setCentralWidget(nullptr);
|
||||
@@ -252,6 +253,11 @@ void QtMainWindow::forceEnterLicense()
|
||||
m_enterLicenseWindow->setEnabled(true);
|
||||
}
|
||||
|
||||
void QtMainWindow::handleMessage(MessageNewProject* message)
|
||||
{
|
||||
m_createNewProjectFunctor(message->projectName, message->projectLocation, message->projectSourceFiles, message->projectIncludePaths);
|
||||
}
|
||||
|
||||
bool QtMainWindow::event(QEvent* event)
|
||||
{
|
||||
if (event->type() == QEvent::WindowActivate)
|
||||
@@ -599,6 +605,13 @@ void QtMainWindow::toggleShowDockWidgetTitleBars()
|
||||
setShowDockWidgetTitleBars(!m_showDockWidgetTitleBars);
|
||||
}
|
||||
|
||||
void QtMainWindow::doCreateNewProject(const std::string& name, const std::string& location,
|
||||
const std::vector<std::string>& sourceFiles, const std::vector<std::string>& includePaths)
|
||||
{
|
||||
newProject();
|
||||
m_newProjectDialog->setPresets(name, location, sourceFiles, includePaths);
|
||||
}
|
||||
|
||||
void QtMainWindow::setupEditMenu()
|
||||
{
|
||||
QMenu *menu = new QMenu(tr("&Edit"), this);
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
#include <QMainWindow>
|
||||
#include <QShortcut>
|
||||
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageNewProject.h"
|
||||
|
||||
#include "qt/utility/QtThreadedFunctor.h"
|
||||
#include "qt/window/QtApplicationSettingsScreen.h"
|
||||
#include "qt/window/QtStartScreen.h"
|
||||
#include "qt/window/QtProjectSetupScreen.h"
|
||||
@@ -66,6 +70,7 @@ protected:
|
||||
|
||||
class QtMainWindow
|
||||
: public QMainWindow
|
||||
, public MessageListener<MessageNewProject>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -86,6 +91,8 @@ public:
|
||||
|
||||
void forceEnterLicense();
|
||||
|
||||
void handleMessage(MessageNewProject* message);
|
||||
|
||||
protected:
|
||||
bool event(QEvent* event);
|
||||
void keyPressEvent(QKeyEvent* event);
|
||||
@@ -143,6 +150,8 @@ private:
|
||||
QtViewToggle* toggle;
|
||||
};
|
||||
|
||||
void doCreateNewProject(const std::string& name, const std::string& location,
|
||||
const std::vector<std::string>& sourceFiles, const std::vector<std::string>& includePaths);
|
||||
|
||||
void setupEditMenu();
|
||||
void setupProjectMenu();
|
||||
@@ -174,6 +183,8 @@ private:
|
||||
QShortcut* m_escapeShortcut;
|
||||
|
||||
static std::string m_windowSettingsPath;
|
||||
|
||||
QtThreadedFunctor<std::string, std::string, std::vector<std::string>, std::vector<std::string>> m_createNewProjectFunctor;
|
||||
};
|
||||
|
||||
#endif // QT_MAIN_WINDOW_H
|
||||
|
||||
@@ -142,6 +142,28 @@ void QtProjectSetupScreen::loadProjectSettings()
|
||||
}
|
||||
}
|
||||
|
||||
void QtProjectSetupScreen::setPresets(const std::string& name, const std::string& location,
|
||||
const std::vector<std::string>& sourceFiles, const std::vector<std::string>& includePaths)
|
||||
{
|
||||
m_projectName->setText(QString::fromStdString(name));
|
||||
m_projectFileLocation->setText(QString::fromStdString(location));
|
||||
|
||||
std::vector<FilePath> sourceFilePaths;
|
||||
for (unsigned int i = 0; i < sourceFiles.size(); i++)
|
||||
{
|
||||
sourceFilePaths.push_back(FilePath(sourceFiles[i]));
|
||||
}
|
||||
|
||||
std::vector<FilePath> includePathsPaths;
|
||||
for (unsigned int i = 0; i < includePaths.size(); i++)
|
||||
{
|
||||
includePathsPaths.push_back(FilePath(sourceFiles[i]));
|
||||
}
|
||||
|
||||
m_sourcePaths->setList(sourceFilePaths);
|
||||
m_includePaths->setList(includePathsPaths);
|
||||
}
|
||||
|
||||
void QtProjectSetupScreen::populateForm(QFormLayout* layout)
|
||||
{
|
||||
int minimumWidthForSecondCol = 360;
|
||||
|
||||
@@ -49,6 +49,10 @@ public:
|
||||
|
||||
void projectSetupScreen();
|
||||
|
||||
// fill screen without having to set project setting beforehand (e.g. when creating a new project)
|
||||
void setPresets(const std::string& name, const std::string& location,
|
||||
const std::vector<std::string>& sourceFiles, const std::vector<std::string>& includePaths);
|
||||
|
||||
signals:
|
||||
void showPreferences();
|
||||
|
||||
|
||||
@@ -31,4 +31,5 @@ add_files(
|
||||
TokenLocationCollectionTestSuite.h
|
||||
UtilityStringTestSuite.h
|
||||
Vector2TestSuite.h
|
||||
VsSolutionParserTestSuite.h
|
||||
)
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
std::stringstream message;
|
||||
message << type << divider << filePath << divider << row << divider << column << endOfMessageToken;
|
||||
|
||||
NetworkProtocolHelper::NetworkMessage networkMessage = NetworkProtocolHelper::parseMessage(message.str());
|
||||
NetworkProtocolHelper::SetActiveTokenMessage networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.fileLocation, filePath);
|
||||
TS_ASSERT_EQUALS(networkMessage.row, row);
|
||||
@@ -28,7 +28,7 @@ public:
|
||||
// invalid type
|
||||
message.str("");
|
||||
message << "foo" << divider << filePath << divider << row << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseMessage(message.str());
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.fileLocation, "");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
// missing divider
|
||||
message.str("");
|
||||
message << type << divider << filePath << row << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseMessage(message.str());
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.fileLocation, "");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
@@ -48,7 +48,7 @@ public:
|
||||
// invalid row
|
||||
message.str("");
|
||||
message << type << divider << filePath << divider << "potato" << divider << column << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseMessage(message.str());
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.fileLocation, "");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
@@ -58,7 +58,7 @@ public:
|
||||
// invalid column
|
||||
message.str("");
|
||||
message << type << divider << filePath << divider << row << divider << "laz0r" << endOfMessageToken;
|
||||
networkMessage = NetworkProtocolHelper::parseMessage(message.str());
|
||||
networkMessage = NetworkProtocolHelper::parseSetActiveTokenMessage(message.str());
|
||||
|
||||
TS_ASSERT_EQUALS(networkMessage.fileLocation, "");
|
||||
TS_ASSERT_EQUALS(networkMessage.row, 0);
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "cxxtest/TestSuite.h"
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/solution/SolutionParserVisualStudio.h"
|
||||
|
||||
class VsSolutionParserTestSuite : public CxxTest::TestSuite
|
||||
{
|
||||
public:
|
||||
void test_load_solution()
|
||||
{
|
||||
SolutionParserVisualStudio parser;
|
||||
parser.openSolutionFile("data/vsSolutionParserTestSuite/Coati.sln");
|
||||
|
||||
// TS_ASSERT_EQUALS(10186, parser.getSolutionCharCount());
|
||||
}
|
||||
|
||||
void test_get_project_files()
|
||||
{
|
||||
SolutionParserVisualStudio parser;
|
||||
parser.openSolutionFile("data/vsSolutionParserTestSuite/Coati.sln");
|
||||
std::vector<std::string> projects = parser.getProjects();
|
||||
|
||||
TS_ASSERT_EQUALS(9, projects.size());
|
||||
TS_ASSERT_EQUALS("ALL_BUILD.vcxproj", projects[0]);
|
||||
TS_ASSERT_EQUALS("Coati.vcxproj", projects[1]);
|
||||
TS_ASSERT_EQUALS("Coati_lib.vcxproj", projects[2]);
|
||||
TS_ASSERT_EQUALS("Coati_lib_gui.vcxproj", projects[3]);
|
||||
TS_ASSERT_EQUALS("Coati_lib_parser.vcxproj", projects[4]);
|
||||
TS_ASSERT_EQUALS("Coati_test.vcxproj", projects[5]);
|
||||
TS_ASSERT_EQUALS("Coati_trial.vcxproj", projects[6]);
|
||||
TS_ASSERT_EQUALS("ZERO_CHECK.vcxproj", projects[7]);
|
||||
TS_ASSERT_EQUALS("versionnumber.vcxproj", projects[8]);
|
||||
}
|
||||
|
||||
void test_get_solution_name()
|
||||
{
|
||||
SolutionParserVisualStudio parser;
|
||||
parser.openSolutionFile("data/vsSolutionParserTestSuite/Coati.sln");
|
||||
std::string solutionName = parser.getSolutionName();
|
||||
|
||||
TS_ASSERT_EQUALS("Coati", solutionName);
|
||||
}
|
||||
|
||||
void test_get_include_paths()
|
||||
{
|
||||
SolutionParserVisualStudio parser;
|
||||
parser.openSolutionFile("data/vsSolutionParserTestSuite/Coati.sln");
|
||||
std::vector<std::string> includePaths = parser.getIncludePaths();
|
||||
|
||||
TS_ASSERT_EQUALS(23, includePaths.size());
|
||||
}
|
||||
|
||||
void test_get_()
|
||||
{
|
||||
SolutionParserVisualStudio parser;
|
||||
parser.openSolutionFile("data/vsSolutionParserTestSuite/Coati.sln");
|
||||
std::vector<std::string> projectItems = parser.getProjectItems();
|
||||
|
||||
TS_ASSERT_EQUALS(447, projectItems.size());
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user