ui: vs plugin integration

Reworked vs solution based project setup to utilize new CDB feature
This commit is contained in:
Manuel Dobusch
2016-11-10 17:40:14 +01:00
parent 9aed97eee2
commit 0a3200f8ff
32 changed files with 744 additions and 254 deletions
+2 -1
View File
@@ -281,6 +281,7 @@ add_files(
utility/messaging/type/MessageGraphNodeBundleSplit.h
utility/messaging/type/MessageGraphNodeExpand.h
utility/messaging/type/MessageGraphNodeMove.h
utility/messaging/type/MessageIDECreateCDB.h
utility/messaging/type/MessageInterruptTasks.h
utility/messaging/type/MessageLoadProject.h
utility/messaging/type/MessageMoveIDECursor.h
@@ -307,7 +308,7 @@ add_files(
utility/messaging/type/MessageWindowClosed.h
utility/messaging/type/MessageWindowFocus.h
utility/messaging/type/MessageZoom.h
utility/messaging/Message.h
utility/messaging/MessageBase.h
utility/messaging/MessageInterruptTasksCounter.cpp
@@ -44,6 +44,10 @@ void IDECommunicationController::handleIncomingMessage(const std::string& messag
{
handleSetActiveTokenMessage(NetworkProtocolHelper::parseSetActiveTokenMessage(message));
}
else if (type == NetworkProtocolHelper::MESSAGE_TYPE::CREATE_CDB_MESSAGE)
{
handleCreateCDBProjectMessage(NetworkProtocolHelper::parseCreateCDBProjectMessage(message));
}
else
{
handleCreateProjectMessage(NetworkProtocolHelper::parseCreateProjectMessage(message));
@@ -139,9 +143,37 @@ void IDECommunicationController::handleCreateProjectMessage(const NetworkProtoco
}
}
void IDECommunicationController::handleCreateCDBProjectMessage(const NetworkProtocolHelper::CreateCDBProjectMessage& message)
{
if (message.valid)
{
std::shared_ptr<MessageProjectNew> msg = std::make_shared<MessageProjectNew>();
msg->setSolutionPath(message.cdbFileLocation);
msg->setHeaderPaths(message.headerPaths);
msg->ideId = message.ideId;
bool foo = msg->fromCDB();
MessageDispatchWhenLicenseValid(msg).dispatch();
}
else
{
LOG_ERROR_STREAM(<< "Unable to parse provided CDB, invalid data received");
}
}
void IDECommunicationController::handleMessage(MessageIDECreateCDB* message)
{
std::string networkMessage = NetworkProtocolHelper::buildCreateCDBMessage();
MessageStatus("Requesting IDE to create CDB.").dispatch();
sendMessage(networkMessage);
}
void IDECommunicationController::handleMessage(MessageMoveIDECursor* message)
{
std::string networkMessage = NetworkProtocolHelper::buildMessage(
std::string networkMessage = NetworkProtocolHelper::buildSetIDECursorMessage(
message->FilePosition, message->Row, message->Column
);
@@ -7,6 +7,7 @@
#include "component/controller/helper/NetworkProtocolHelper.h"
#include "utility/messaging/MessageListener.h"
#include "utility/messaging/type/MessageIDECreateCDB.h"
#include "utility/messaging/type/MessageMoveIDECursor.h"
#include "utility/messaging/type/MessagePluginPortChange.h"
@@ -14,6 +15,7 @@ class StorageAccess;
class IDECommunicationController
: public Controller
, public MessageListener<MessageIDECreateCDB>
, public MessageListener<MessageMoveIDECursor>
, public MessageListener<MessagePluginPortChange>
{
@@ -35,7 +37,9 @@ public:
private:
void handleSetActiveTokenMessage(const NetworkProtocolHelper::SetActiveTokenMessage& message);
void handleCreateProjectMessage(const NetworkProtocolHelper::CreateProjectMessage& message);
void handleCreateCDBProjectMessage(const NetworkProtocolHelper::CreateCDBProjectMessage& message);
virtual void handleMessage(MessageIDECreateCDB* message);
virtual void handleMessage(MessageMoveIDECursor* message);
virtual void handleMessage(MessagePluginPortChange* message);
virtual void sendMessage(const std::string& message) const = 0;
@@ -14,6 +14,8 @@ std::string NetworkProtocolHelper::m_setActiveTokenPrefix = "setActiveToken";
std::string NetworkProtocolHelper::m_moveCursorPrefix = "moveCursor";
std::string NetworkProtocolHelper::m_endOfMessageToken = "<EOM>";
std::string NetworkProtocolHelper::m_createProjectPrefix = "createProject";
std::string NetworkProtocolHelper::m_createCDBProjectPrefix = "createCDBProject";
std::string NetworkProtocolHelper::m_createCDBPrefix = "createCDB";
NetworkProtocolHelper::MESSAGE_TYPE NetworkProtocolHelper::getMessageType(const std::string& message)
{
@@ -29,6 +31,10 @@ NetworkProtocolHelper::MESSAGE_TYPE NetworkProtocolHelper::getMessageType(const
{
return MESSAGE_TYPE::CREATE_PROJECT;
}
else if (subMessages[0] == m_createCDBProjectPrefix)
{
return MESSAGE_TYPE::CREATE_CDB_MESSAGE;
}
else
{
return MESSAGE_TYPE::UNKNOWN;
@@ -74,7 +80,7 @@ NetworkProtocolHelper::SetActiveTokenMessage NetworkProtocolHelper::parseSetActi
}
else
{
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token");
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token: " << subMessages[0] << ". Expected " << m_setActiveTokenPrefix);
}
}
@@ -111,18 +117,88 @@ NetworkProtocolHelper::CreateProjectMessage NetworkProtocolHelper::parseCreatePr
networkMessage.valid = true;
}
else
{
LOG_WARNING_STREAM(<< "Failed to parse ide ID string. Is " << ideId);
}
}
}
else
{
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token");
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token: " << subMessages[0] << ". Expected " << m_createProjectPrefix);
}
}
return networkMessage;
}
std::string NetworkProtocolHelper::buildMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column)
NetworkProtocolHelper::CreateCDBProjectMessage NetworkProtocolHelper::parseCreateCDBProjectMessage(const std::string& message)
{
std::vector<std::string> subMessages = divideMessage(message);
NetworkProtocolHelper::CreateCDBProjectMessage networkMessage;
if (subMessages.size() > 0)
{
if (subMessages[0] == m_createCDBProjectPrefix)
{
if (subMessages.size() < 4)
{
LOG_ERROR_STREAM(<< "Failed to parse createCDBProject message, too few tokens");
}
else
{
int subMessageCount = subMessages.size();
std::string cdbPath = subMessages[1];
if (cdbPath.length() > 0)
{
networkMessage.cdbFileLocation = cdbPath;
}
else
{
LOG_WARNING_STREAM(<< "CDB file path is not set.");
}
std::vector<std::string> headerPaths;
for (int i = 2; i < subMessageCount - 2; i++)
{
if (subMessages[i].length() > 0)
{
headerPaths.push_back(subMessages[i]);
}
}
networkMessage.headerPaths = headerPaths;
std::string ideId = subMessages[subMessageCount - 2];
if (ideId.length() > 0)
{
std::string nonConstId = ideId;
boost::algorithm::to_lower(nonConstId);
networkMessage.ideId = nonConstId;
}
else
{
LOG_WARNING_STREAM(<< "Failed to parse ide ID string. Is " << ideId);
}
if (networkMessage.cdbFileLocation.length() > 0 && networkMessage.ideId.length() > 0)
{
networkMessage.valid = true;
}
}
}
else
{
LOG_ERROR_STREAM(<< "Failed to parse message, invalid type token: " << subMessages[0] << ". Expected " << m_createCDBProjectPrefix);
}
}
return networkMessage;
}
std::string NetworkProtocolHelper::buildSetIDECursorMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column)
{
std::stringstream messageStream;
@@ -138,6 +214,16 @@ std::string NetworkProtocolHelper::buildMessage(const std::string& fileLocation,
return messageStream.str();
}
std::string NetworkProtocolHelper::buildCreateCDBMessage()
{
std::stringstream messageStream;
messageStream << m_createCDBPrefix;
messageStream << m_endOfMessageToken;
return messageStream.str();
}
std::vector<std::string> NetworkProtocolHelper::divideMessage(const std::string& message)
{
std::vector<std::string> result;
@@ -37,19 +37,38 @@ public:
bool valid;
};
struct CreateCDBProjectMessage
{
public:
CreateCDBProjectMessage()
: cdbFileLocation("")
, headerPaths()
, ideId("")
, valid(false)
{}
std::string cdbFileLocation;
std::vector<std::string> headerPaths;
std::string ideId;
bool valid;
};
enum MESSAGE_TYPE
{
UNKNOWN = 0,
SET_ACTIVE_TOKEN,
CREATE_PROJECT
CREATE_PROJECT,
CREATE_CDB_MESSAGE
};
static MESSAGE_TYPE getMessageType(const std::string& message);
static SetActiveTokenMessage parseSetActiveTokenMessage(const std::string& message);
static CreateProjectMessage parseCreateProjectMessage(const std::string& message);
static CreateCDBProjectMessage parseCreateCDBProjectMessage(const std::string& message);
static std::string buildMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column);
static std::string buildSetIDECursorMessage(const std::string& fileLocation, const unsigned int row, const unsigned int column);
static std::string buildCreateCDBMessage();
private:
static std::vector<std::string> divideMessage(const std::string& message);
@@ -64,6 +83,8 @@ private:
static std::string m_moveCursorPrefix;
static std::string m_endOfMessageToken;
static std::string m_createProjectPrefix;
static std::string m_createCDBProjectPrefix;
static std::string m_createCDBPrefix;
};
#endif // NETWORK_PROTOCOL_HELPER_H
@@ -0,0 +1,24 @@
#ifndef MESSAGE_IDE_CREATE_CDB_H
#define MESSAGE_IDE_CREATE_CDB_H
#include "utility/messaging/Message.h"
class MessageIDECreateCDB : public Message<MessageIDECreateCDB>
{
public:
MessageIDECreateCDB()
{
}
static const std::string getStaticType()
{
return "MessageIDECreateCDB";
}
virtual void print(std::ostream& os) const
{
os << "Create CDB from current solution";
}
};
#endif // MESSAGE_IDE_CREATE_CDB_H
@@ -9,6 +9,7 @@ class MessageProjectNew
public:
MessageProjectNew()
: solutionPath("")
, headerPaths()
, ideId("")
{
}
@@ -23,12 +24,38 @@ public:
return solutionPath.size() > 0;
}
bool fromCDB() const
{
if (solutionPath.length() > 0)
{
size_t pos = solutionPath.find_last_of('.');
if (pos != std::string::npos)
{
std::string extension = solutionPath.substr(pos + 1);
return (extension == "json");
}
else
{
return false;
}
}
return false;
}
void setSolutionPath(const std::string& path)
{
solutionPath = path;
}
void setHeaderPaths(const std::vector<std::string>& headerPaths)
{
this->headerPaths = headerPaths;
}
std::string solutionPath;
std::vector<std::string> headerPaths;
std::string ideId;
};
+23 -2
View File
@@ -1,4 +1,5 @@
#include "QtTcpWrapper.h"
#include "qdatastream.h"
#include "utility/logging/logging.h"
@@ -100,12 +101,32 @@ void QtTcpWrapper::acceptConnection()
void QtTcpWrapper::startRead()
{
char buffer[1024] = { 0 };
QByteArray byteArray;
while (m_tcpClient->atEnd() == false)
{
QByteArray data = m_tcpClient->read(128);
byteArray += data;
}
/*QDataStream stream(&byteArray, QIODevice::ReadOnly);
QString string;
stream >> string;*/
QString string = QString::fromUtf8(byteArray);
if (m_readCallback != NULL)
{
std::string message = string.toStdString();
m_readCallback(message);
}
/*char buffer[1024] = { 0 };
m_tcpClient->read(buffer, m_tcpClient->bytesAvailable());
m_tcpClient->close();
if (m_readCallback != NULL)
{
m_readCallback(buffer);
}
}*/
}
+14 -1
View File
@@ -5,6 +5,7 @@
QtMainView::QtMainView()
: m_editProjectFunctor(std::bind(&QtMainView::doEditProject, this))
, m_createNewProjectFromSolutionFunctor(std::bind(&QtMainView::doCreateNewProjectFromSolution, this, std::placeholders::_1, std::placeholders::_2))
, m_createNewProjectFromCDBFunctor(std::bind(&QtMainView::doCreateNewProjectFromCDB, this, std::placeholders::_1, std::placeholders::_2))
, m_showStartScreenFunctor(std::bind(&QtMainView::doShowStartScreen, this))
, m_hideStartScreenFunctor(std::bind(&QtMainView::doHideStartScreen, this))
, m_setTitleFunctor(std::bind(&QtMainView::doSetTitle, this, std::placeholders::_1))
@@ -117,7 +118,14 @@ void QtMainView::handleMessage(MessageProjectNew* message)
{
if (message->ideId.size() != 0 && message->solutionPath.size() != 0)
{
m_createNewProjectFromSolutionFunctor(message->ideId, message->solutionPath);
if (message->fromCDB() == false)
{
m_createNewProjectFromSolutionFunctor(message->ideId, message->solutionPath);
}
else
{
m_createNewProjectFromCDBFunctor(message->solutionPath, message->headerPaths);
}
}
}
@@ -136,6 +144,11 @@ void QtMainView::doCreateNewProjectFromSolution(const std::string& ideId, const
m_window->newProjectFromSolution(ideId, solutionPath);
}
void QtMainView::doCreateNewProjectFromCDB(const std::string& filePath, const std::vector<std::string>& headerPaths)
{
m_window->newProjectFromCDB(filePath, headerPaths);
}
void QtMainView::doShowStartScreen()
{
m_window->showStartScreen();
+2
View File
@@ -58,6 +58,7 @@ private:
void doEditProject();
void doCreateNewProjectFromSolution(const std::string& ideId, const std::string& solutionPath);
void doCreateNewProjectFromCDB(const std::string& filePath, const std::vector<std::string>& headerPaths);
void doShowStartScreen();
void doHideStartScreen();
void doSetTitle(const std::string& title);
@@ -70,6 +71,7 @@ private:
QtThreadedFunctor<> m_editProjectFunctor;
QtThreadedFunctor<const std::string&, const std::string&> m_createNewProjectFromSolutionFunctor;
QtThreadedFunctor<const std::string&, const std::vector<std::string>&> m_createNewProjectFromCDBFunctor;
QtThreadedFunctor<> m_showStartScreenFunctor;
QtThreadedFunctor<> m_hideStartScreenFunctor;
QtThreadedFunctor<const std::string&> m_setTitleFunctor;
+6
View File
@@ -436,6 +436,12 @@ void QtMainWindow::newProjectFromSolution(const std::string& ideId, const std::s
wizzard->newProjectFromSolution(ideId, solutionPath);
}
void QtMainWindow::newProjectFromCDB(const std::string& filePath, const std::vector<std::string>& headerPaths)
{
QtProjectWizzard* wizzard = createWindow<QtProjectWizzard>();
wizzard->newProjectFromCDB(filePath, headerPaths);
}
void QtMainWindow::openProject()
{
QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "", "Coati Project Files (*.coatiproject)");
+1
View File
@@ -110,6 +110,7 @@ public slots:
void newProject();
void newProjectFromSolution(const std::string& ideId, const std::string& solutionPath);
void newProjectFromCDB(const std::string& filePath, const std::vector<std::string>& headerPaths);
void openProject();
void editProject();
@@ -116,6 +116,26 @@ void QtProjectWizzard::newProjectFromSolution(const std::string& ideId, const st
}
}
void QtProjectWizzard::newProjectFromCDB(const std::string& filePath, const std::vector<std::string>& headerPaths)
{
FilePath fp(filePath);
std::vector<FilePath> hp;
for (int i = 0; i < headerPaths.size(); i++)
{
hp.push_back(FilePath(headerPaths[i]));
}
std::shared_ptr<CxxProjectSettings> settings = std::make_shared<CxxProjectSettings>();
settings->setLanguage(LanguageType::LANGUAGE_CPP);
settings->setProjectName(fp.withoutExtension().fileName());
settings->setProjectFileLocation(fp.parentDirectory());
settings->setCompilationDatabasePath(fp);
settings->setSourcePaths(hp);
m_settings = settings;
emptyProjectCDBVS();
}
void QtProjectWizzard::refreshProjectFromSolution(const std::string& ideId, const std::string& visualStudioSolutionPath)
{
if (m_parserManager->canParseSolution(ideId))
@@ -323,7 +343,7 @@ void QtProjectWizzard::selectedProjectType(LanguageType languageType, QtProjectW
break;
case QtProjectWizzardContentSelect::PROJECT_MANAGED:
{
/*{
std::string fileEndings = "(";
for (unsigned int i = 0; i < m_parserManager->getParserCount(); i++)
{
@@ -346,7 +366,12 @@ void QtProjectWizzard::selectedProjectType(LanguageType languageType, QtProjectW
}
}
break;
}
}*/
m_settings = std::make_shared<CxxProjectSettings>();
m_settings->setLanguage(languageType);
emptyProjectCDBVS();
break;
case QtProjectWizzardContentSelect::PROJECT_CDB:
m_settings = std::make_shared<CxxProjectSettings>();
@@ -428,6 +453,13 @@ void QtProjectWizzard::frameworkSearchPaths()
connect(window, SIGNAL(next()), this, SLOT(showSummary()));
}
void QtProjectWizzard::emptyProjectCDBVS()
{
QtProjectWizzardWindow* window = createWindowWithContent<QtProjectWizzardContentDataCDBVS>();
connect(window, SIGNAL(next()), this, SLOT(headerPathsCDB()));
}
void QtProjectWizzard::emptyProjectCDB()
{
QtProjectWizzardWindow* window = createWindowWithContent<QtProjectWizzardContentDataCDB>();
@@ -34,6 +34,7 @@ public slots:
void newProject();
void newProjectFromSolution(const std::string& ideId, const std::string& visualStudioSolutionPath);
void newProjectFromCDB(const std::string& filePath, const std::vector<std::string>& headerPaths);
void refreshProjectFromSolution(const std::string& ideId, const std::string& visualStudioSolutionPath);
void editProject(const FilePath& settingsPath);
@@ -72,6 +73,8 @@ private slots:
void headerSearchPathsDone();
void frameworkSearchPaths();
void emptyProjectCDBVS();
void emptyProjectCDB();
void headerPathsCDB();
@@ -5,6 +5,7 @@
#include "settings/CxxProjectSettings.h"
#include "utility/messaging/type/MessageIDECreateCDB.h"
#include "utility/logging/logging.h"
QtProjectWizzardContentData::QtProjectWizzardContentData(std::shared_ptr<ProjectSettings> settings, QtProjectWizzardWindow* window)
@@ -257,3 +258,81 @@ bool QtProjectWizzardContentDataCDB::check()
void QtProjectWizzardContentDataCDB::refreshClicked()
{
}
QtProjectWizzardContentDataCDBVS::QtProjectWizzardContentDataCDBVS(std::shared_ptr<ProjectSettings> settings, QtProjectWizzardWindow* window)
: QtProjectWizzardContentDataCDB(settings, window)
{
}
void QtProjectWizzardContentDataCDBVS::populate(QGridLayout* layout, int& row)
{
if (!isInForm())
{
layout->setRowMinimumHeight(row, 15);
row++;
}
QLabel* nameLabel = createFormLabel("Create Compilation Database");
layout->addWidget(nameLabel, row, QtProjectWizzardWindow::FRONT_COL);
addHelpButton("To create a new Compilation Database from a Visual Studio Solution, this Solution has to be open in Visual Studio.\n\
Coati will call Visual Studio to open the 'Create Compilation Database' dialog.\
Please follow the instructions in Visual Studio to complete the process.\n\
Note: Coati's Visual Studio plugin has to be installed. Visual Studio has to be running with an eligible Solution, containing C/C++ projects, loaded.", layout, row);
QLabel* descriptionLabel = createFormLabel("Call Visual Studio to create a Compilation Database from the loaded Solution.");
descriptionLabel->setObjectName("description");
descriptionLabel->setAlignment(Qt::AlignmentFlag::AlignLeft);
layout->addWidget(descriptionLabel, row, QtProjectWizzardWindow::BACK_COL);
row++;
QPushButton* button = new QPushButton("Create CDB");
button->setObjectName("windowButton");
layout->addWidget(button, row, QtProjectWizzardWindow::BACK_COL);
row++;
QLabel* skipLabel = createFormLabel("*Skip this step if you already have a Compilation Database for your Solution.");
skipLabel->setObjectName("description");
skipLabel->setAlignment(Qt::AlignmentFlag::AlignLeft);
layout->addWidget(skipLabel, row, QtProjectWizzardWindow::BACK_COL);
row++;
QFrame* separator = new QFrame();
separator->setFrameShape(QFrame::HLine);
QPalette palette = separator->palette();
palette.setColor(QPalette::WindowText, Qt::lightGray);
separator->setPalette(palette);
layout->addWidget(separator, row++, 0, 1, -1);
connect(button, SIGNAL(clicked()), this, SLOT(handleVSCDBClicked()));
addNameAndLocation(layout, row);
layout->setRowMinimumHeight(row++, 20);
QString name = "Compilation Database";
QString filter = "JSON Compilation Database (*.json)";
addBuildFilePicker(layout, row, name, filter);
if (!isInForm())
{
layout->setRowMinimumHeight(row, 15);
layout->setRowStretch(row, 1);
}
}
void QtProjectWizzardContentDataCDBVS::refreshClicked()
{
}
void QtProjectWizzardContentDataCDBVS::handleVSCDBClicked()
{
MessageIDECreateCDB().dispatch();
}
@@ -55,4 +55,19 @@ private slots:
void refreshClicked();
};
class QtProjectWizzardContentDataCDBVS
: public QtProjectWizzardContentDataCDB
{
Q_OBJECT
public:
QtProjectWizzardContentDataCDBVS(std::shared_ptr<ProjectSettings> settings, QtProjectWizzardWindow* window);
virtual void populate(QGridLayout* layout, int& row) override;
private slots:
void refreshClicked();
void handleVSCDBClicked();
};
#endif // QT_PROJECT_WIZZARD_CONTENT_DATA_H
@@ -44,7 +44,7 @@ void QtProjectWizzardWindow::populateWindow(QWidget* widget)
{
QGridLayout* layout = new QGridLayout();
layout->setContentsMargins(0, 0, 0, 0);
layout->setColumnStretch(QtProjectWizzardWindow::FRONT_COL, 1);
layout->setColumnStretch(QtProjectWizzardWindow::BACK_COL, 3);