Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
816be7b654 | ||
|
|
901fa1a387 | ||
|
|
88b94a21d0 | ||
|
|
102bc8945a | ||
|
|
86f06c9f78 | ||
|
|
42afbce300 | ||
|
|
8f0213e18c | ||
|
|
fc816240cb | ||
|
|
7fce4cfae6 | ||
|
|
3c2804797a | ||
|
|
df7c5ea9b7 | ||
|
|
de4f2973bc | ||
|
|
00b74d2f30 | ||
|
|
28e3880e10 | ||
|
|
42aa99d99b | ||
|
|
3351e4aad7 | ||
|
|
5ef9ef9e7d | ||
|
|
a4c134ebe2 | ||
|
|
f2a202c064 | ||
|
|
372f262204 | ||
|
|
50bc970c30 | ||
|
|
e186eefdff | ||
|
|
bcbeacb951 | ||
|
|
961d0fe541 | ||
|
|
5dada05bc5 | ||
|
|
884e42a30c | ||
|
|
9f684ad9f5 | ||
|
|
78259c7123 | ||
|
|
7d03166282 | ||
|
|
006e73ef4c | ||
|
|
11147e982f | ||
|
|
9c4dc7b71f | ||
|
|
a524a7a71c | ||
|
|
42ab36fbad | ||
|
|
1ad2dbe86e | ||
|
|
e8c8a4ca50 | ||
|
|
58daa633c9 | ||
|
|
a7ad0a60f3 | ||
|
|
c7a2533dc4 | ||
|
|
cbb6fcd8e2 | ||
|
|
c704b4f65c | ||
|
|
c06beb21cb | ||
|
|
1382356a39 |
@@ -18,4 +18,10 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $BRANCH_NAME == "public_beta" ]
|
||||
then
|
||||
echo -e $ABORT "Commiting to public_beta is prohibited."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
+6
-3
@@ -4,10 +4,9 @@
|
||||
/bin/app/Debug/
|
||||
/bin/app/Release/
|
||||
/bin/app/data/log/
|
||||
/bin/app/data/projects/
|
||||
/bin/app/data/projects/ignored/
|
||||
/bin/app/data/ApplicationSettings.xml
|
||||
/bin/app/data/window_settings.ini
|
||||
/bin/app/data/*.sqlite
|
||||
|
||||
/bin/lib/
|
||||
|
||||
@@ -16,9 +15,13 @@
|
||||
/bin/test/data/log/
|
||||
/bin/test/data/temp.xml
|
||||
/bin/test/data/TestSettings.xml
|
||||
/bin/test/data/*.sqlite
|
||||
|
||||
/setup/Linux/lib/*
|
||||
|
||||
.DS_Store
|
||||
.idea
|
||||
/ide_plugins/vs/vs2012/CoatiPlugin/CoatiPlugin/bin
|
||||
/ide_plugins/vs/vs2012/CoatiPlugin/CoatiPlugin/obj
|
||||
|
||||
*.sqlite
|
||||
*.swp
|
||||
|
||||
@@ -28,6 +28,24 @@ For Win32:
|
||||
Run setup script:
|
||||
$ ./script/setup.sh
|
||||
|
||||
#### Release
|
||||
|
||||
##### App
|
||||
* create release build
|
||||
* make sure it uses the Coati icon
|
||||
* obfuscate the executable using upx
|
||||
|
||||
##### Data folder
|
||||
* put data folder in working directory
|
||||
* add empty log folder
|
||||
* add working tictactoe.xml project to /projects/tictactoe with sources in /projects/tictactoe/src
|
||||
* add empty app settings with one recent project tictactoe.xml
|
||||
* leave window_settings.ini with correct Coati start layout
|
||||
|
||||
##### Package
|
||||
* add app
|
||||
* add web/coati_manual.pdf to package
|
||||
|
||||
##### Updating Clang on UNIX
|
||||
|
||||
$ cd .../clang_llvm
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<config>
|
||||
<user>
|
||||
<recent_projects>
|
||||
<recent_project>./data/projects/tutorial/tutorial.xml</recent_project>
|
||||
<recent_project>./data/projects/tictactoe/tictactoe.xml</recent_project>
|
||||
</recent_projects>
|
||||
</user>
|
||||
</config>
|
||||
@@ -62,7 +62,7 @@
|
||||
</file>
|
||||
|
||||
<snippet>
|
||||
<background>transparent</background>
|
||||
<background>white</background>
|
||||
|
||||
<title>
|
||||
<text>#A0A0A0</text>
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
<line_number>
|
||||
<text>black</text>
|
||||
<background>transparent</background>
|
||||
<background>white</background>
|
||||
</line_number>
|
||||
|
||||
<syntax>
|
||||
@@ -86,20 +86,50 @@
|
||||
<function>#CC9533</function>
|
||||
</syntax>
|
||||
|
||||
<highlight>
|
||||
<selection>
|
||||
<location>
|
||||
<normal>#90EBEBEB</normal>
|
||||
<hover>#90B6D1DD</hover>
|
||||
<normal>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</normal>
|
||||
<focus>
|
||||
<border>#B2B2B2</border>
|
||||
<fill>transparent</fill>
|
||||
</focus>
|
||||
<active>
|
||||
<border>#B2B2B2</border>
|
||||
<fill>#EDEDED</fill>
|
||||
</active>
|
||||
</location>
|
||||
<scope>
|
||||
<normal>#60E4EEF2</normal>
|
||||
<hover>#90E4EEF2</hover>
|
||||
<normal>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</normal>
|
||||
<focus>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</focus>
|
||||
<active>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</active>
|
||||
</scope>
|
||||
<error>
|
||||
<normal>#80FF0000</normal>
|
||||
<hover>#FFFF0000</hover>
|
||||
<normal>
|
||||
<border>transparent</border>
|
||||
<fill>#80FF0000</fill>
|
||||
</normal>
|
||||
<focus>
|
||||
<border>transparent</border>
|
||||
<fill>#FFFF0000</fill>
|
||||
</focus>
|
||||
<active>
|
||||
<border>transparent</border>
|
||||
<fill>#FFFF0000</fill>
|
||||
</active>
|
||||
</error>
|
||||
</highlight>
|
||||
</selection>
|
||||
</snippet>
|
||||
</code>
|
||||
|
||||
@@ -234,6 +264,10 @@
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_specialization>
|
||||
<template_member_specialization>
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_member_specialization>
|
||||
|
||||
<include>
|
||||
<normal>#878787</normal>
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
</file>
|
||||
|
||||
<snippet>
|
||||
<background>transparent</background>
|
||||
<background>#272728</background>
|
||||
|
||||
<title>
|
||||
<text>#A0A0A0</text>
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
<line_number>
|
||||
<text>#F7F7F7</text>
|
||||
<background>transparent</background>
|
||||
<background>#272728</background>
|
||||
</line_number>
|
||||
|
||||
<syntax>
|
||||
@@ -86,20 +86,50 @@
|
||||
<function>#D69C36</function>
|
||||
</syntax>
|
||||
|
||||
<highlight>
|
||||
<selection>
|
||||
<location>
|
||||
<normal>#20EBEBEB</normal>
|
||||
<hover>#40B6D1DD</hover>
|
||||
<normal>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</normal>
|
||||
<focus>
|
||||
<border>#B2B2B2</border>
|
||||
<fill>transparent</fill>
|
||||
</focus>
|
||||
<active>
|
||||
<border>#B2B2B2</border>
|
||||
<fill>#4A4A4A</fill>
|
||||
</active>
|
||||
</location>
|
||||
<scope>
|
||||
<normal>#10E4EEF2</normal>
|
||||
<hover>#18E4EEF2</hover>
|
||||
<normal>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</normal>
|
||||
<focus>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</focus>
|
||||
<active>
|
||||
<border>transparent</border>
|
||||
<fill>transparent</fill>
|
||||
</active>
|
||||
</scope>
|
||||
<error>
|
||||
<normal>#A0FF0000</normal>
|
||||
<hover>#FFFF0000</hover>
|
||||
<normal>
|
||||
<border>transparent</border>
|
||||
<fill>#A0FF0000</fill>
|
||||
</normal>
|
||||
<focus>
|
||||
<border>transparent</border>
|
||||
<fill>#FFFF0000</fill>
|
||||
</focus>
|
||||
<active>
|
||||
<border>transparent</border>
|
||||
<fill>#FFFF0000</fill>
|
||||
</active>
|
||||
</error>
|
||||
</highlight>
|
||||
</selection>
|
||||
</snippet>
|
||||
</code>
|
||||
|
||||
@@ -234,6 +264,10 @@
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_specialization>
|
||||
<template_member_specialization>
|
||||
<normal>#C1305D</normal>
|
||||
<hover>#C1305D</hover>
|
||||
</template_member_specialization>
|
||||
|
||||
<include>
|
||||
<normal>#247368</normal>
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 697 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,67 @@
|
||||
#include "artificial_player.h"
|
||||
|
||||
ArtificialPlayer::ArtificialPlayer( Field::Token token, const char* name )
|
||||
: Player( token, name ) {
|
||||
}
|
||||
|
||||
ArtificialPlayer::~ArtificialPlayer() {
|
||||
}
|
||||
|
||||
Field::Move ArtificialPlayer::Turn( const Field& field ) const {
|
||||
Field fakeField = field.Clone();
|
||||
Node node = MinMax( fakeField, token_ );
|
||||
return node.move;
|
||||
}
|
||||
|
||||
ArtificialPlayer::Node ArtificialPlayer::MinMax( Field& field, Field::Token token ) const {
|
||||
Node node;
|
||||
node.value = -10000;
|
||||
|
||||
Field::Move move;
|
||||
int sameMove;
|
||||
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
move.row = i;
|
||||
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
move.col = j;
|
||||
|
||||
if ( !field.IsEmpty( move ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
field.MakeMove( move, token );
|
||||
|
||||
int turnValue = Evaluate( field, token );
|
||||
if ( !turnValue && !field.IsFull() ) {
|
||||
turnValue = -MinMax( field, Field::Opponent( token ) ).value;
|
||||
}
|
||||
|
||||
field.ClearMove( move );
|
||||
|
||||
if ( turnValue > node.value ) {
|
||||
node.move = move;
|
||||
node.value = turnValue;
|
||||
sameMove = 1;
|
||||
} else if ( turnValue == node.value ) {
|
||||
sameMove++;
|
||||
if ( 1 % sameMove == 0 ) {
|
||||
node.move = move;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
int ArtificialPlayer::Evaluate( const Field& field, Field::Token token ) const {
|
||||
if ( field.SameInRow( token, 3 ) ) {
|
||||
return 2;
|
||||
} else if ( field.SameInRow( Field::Opponent( token ), 2 ) ) {
|
||||
return -1;
|
||||
} else if ( field.SameInRow( token, 2 ) > 1 ) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _ARTIFICIAL_PLAYER_
|
||||
#define _ARTIFICIAL_PLAYER_
|
||||
|
||||
#include "player.h"
|
||||
|
||||
class ArtificialPlayer : public Player {
|
||||
public:
|
||||
ArtificialPlayer( Field::Token token, const char* name );
|
||||
virtual ~ArtificialPlayer();
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const;
|
||||
|
||||
private:
|
||||
struct Node {
|
||||
Field::Move move;
|
||||
int value;
|
||||
};
|
||||
|
||||
Node MinMax( Field& field, Field::Token token ) const;
|
||||
|
||||
int Evaluate( const Field& field, Field::Token token ) const;
|
||||
};
|
||||
|
||||
#endif // _ARTIFICIAL_PLAYER_
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "field.h"
|
||||
|
||||
#include "io.h"
|
||||
|
||||
Field::Token Field::Opponent( Token token ) {
|
||||
if ( token == PlayerA ) {
|
||||
return PlayerB;
|
||||
} else if (token == PlayerB){
|
||||
return PlayerA;
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
||||
Field::Field()
|
||||
: left_( 9 ) {
|
||||
grid_ = new Token* [3];
|
||||
for ( int i = 0; i < 3 ; i++ ) {
|
||||
grid_[i] = new Token[3];
|
||||
}
|
||||
}
|
||||
|
||||
Field::~Field() {
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
delete grid_[i];
|
||||
}
|
||||
delete [] grid_;
|
||||
}
|
||||
|
||||
Field Field::Clone() const {
|
||||
Field field;
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
field.grid_[i][j] = grid_[i][j];
|
||||
}
|
||||
}
|
||||
field.left_ = left_;
|
||||
return field;
|
||||
}
|
||||
|
||||
void Field::Clear() {
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
for ( int j = 0; j < 3; j++ ) {
|
||||
grid_[i][j] = None;
|
||||
}
|
||||
}
|
||||
left_ = 9;
|
||||
}
|
||||
|
||||
void Field::Show() const {
|
||||
io::stringOut(" 1 2 3\n");
|
||||
for ( int row = 0; row < 3; row++ ) {
|
||||
io::numberOut(row + 1);
|
||||
io::stringOut(" ");
|
||||
|
||||
for ( int col = 0; col < 3; col++ ) {
|
||||
if ( grid_[row][col] == PlayerA ) {
|
||||
io::stringOut(" X ");
|
||||
} else if ( grid_[row][col] == PlayerB ) {
|
||||
io::stringOut(" O ");
|
||||
} else {
|
||||
io::stringOut(" ");
|
||||
}
|
||||
|
||||
if ( col < 2 ) {
|
||||
io::stringOut("|");
|
||||
}
|
||||
}
|
||||
|
||||
if ( row < 2 ) {
|
||||
io::stringOut("\n -----------\n");
|
||||
}
|
||||
}
|
||||
io::stringOut("\n\n");
|
||||
}
|
||||
|
||||
int Field::SameInRow( Token token, int amount ) const {
|
||||
int sum = amount * token;
|
||||
int count = 0;
|
||||
|
||||
for ( int i = 0; i < 3; i++ ) {
|
||||
if ( grid_[i][0] + grid_[i][1] + grid_[i][2] == sum ) {
|
||||
count++;
|
||||
} else if ( grid_[0][i] + grid_[1][i] + grid_[2][i] == sum ) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( grid_[0][0] + grid_[1][1] + grid_[2][2] == sum ) {
|
||||
count++;
|
||||
} else if ( grid_[2][0] + grid_[1][1] + grid_[0][2] == sum ) {
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
bool Field::InRange( const Move& move ) const {
|
||||
return move.row >= 0 && move.row < 3 && move.col >= 0 && move.col < 3;
|
||||
}
|
||||
|
||||
bool Field::IsEmpty( const Move& move ) const {
|
||||
return grid_[move.row][move.col] == None;
|
||||
}
|
||||
|
||||
bool Field::IsFull() const {
|
||||
return left_ == 0;
|
||||
}
|
||||
|
||||
void Field::MakeMove( const Move& move, Token token ) {
|
||||
if ( !InRange( move ) || !IsEmpty( move ) || token == None || !left_ ) {
|
||||
return;
|
||||
}
|
||||
|
||||
grid_[move.row][move.col] = token;
|
||||
left_--;
|
||||
}
|
||||
|
||||
void Field::ClearMove( const Move& move ) {
|
||||
if ( !InRange( move ) || !IsEmpty( move ) || left_ == 9 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
grid_[move.row][move.col] = None;
|
||||
left_++;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef _FIELD_
|
||||
#define _FIELD_
|
||||
|
||||
class Field {
|
||||
public:
|
||||
enum Token {
|
||||
None = 0,
|
||||
PlayerA = 1,
|
||||
PlayerB = 4
|
||||
};
|
||||
|
||||
static Token Opponent( Token token );
|
||||
|
||||
struct Move {
|
||||
int row;
|
||||
int col;
|
||||
};
|
||||
|
||||
Field();
|
||||
~Field();
|
||||
|
||||
Field Clone() const;
|
||||
void Clear();
|
||||
|
||||
void Show() const;
|
||||
|
||||
int SameInRow( Token token, int amount ) const;
|
||||
|
||||
bool InRange( const Move& move ) const;
|
||||
bool IsEmpty( const Move& move ) const;
|
||||
bool IsFull() const;
|
||||
|
||||
void MakeMove( const Move& move, Token token );
|
||||
void ClearMove( const Move& move );
|
||||
|
||||
private:
|
||||
Token** grid_;
|
||||
int left_;
|
||||
};
|
||||
|
||||
#endif // _FIELD_
|
||||
@@ -0,0 +1,49 @@
|
||||
#include "human_player.h"
|
||||
|
||||
#include "io.h"
|
||||
|
||||
HumanPlayer::HumanPlayer( Field::Token token, const char* name )
|
||||
: Player( token, name ) {
|
||||
}
|
||||
|
||||
HumanPlayer::~HumanPlayer() {
|
||||
}
|
||||
|
||||
Field::Move HumanPlayer::Turn( const Field& field ) const {
|
||||
Field::Move move;
|
||||
io::stringOut(name_);
|
||||
io::stringOut("\n");
|
||||
|
||||
do {
|
||||
move = Input();
|
||||
move.row -= 1;
|
||||
move.col -= 1;
|
||||
} while ( !Check( field, move ) );
|
||||
return move;
|
||||
}
|
||||
|
||||
Field::Move HumanPlayer::Input() const {
|
||||
Field::Move move;
|
||||
move.row = -1;
|
||||
move.col = -1;
|
||||
|
||||
io::stringOut("Insert row: ");
|
||||
move.row = io::numberIn();
|
||||
|
||||
io::stringOut("Insert column: ");
|
||||
move.col = io::numberIn();
|
||||
|
||||
io::stringOut("\n");
|
||||
return move;
|
||||
}
|
||||
|
||||
bool HumanPlayer::Check( const Field& field, const Field::Move& move ) const {
|
||||
if ( !field.InRange( move ) ) {
|
||||
io::stringOut("Wrong input!\n");
|
||||
return false;
|
||||
} else if ( !field.IsEmpty( move ) ) {
|
||||
io::stringOut("Is occupied!\n");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef _HUMAN_PLAYER_
|
||||
#define _HUMAN_PLAYER_
|
||||
|
||||
#include "player.h"
|
||||
|
||||
class HumanPlayer : public Player {
|
||||
public:
|
||||
HumanPlayer( Field::Token token, const char* name );
|
||||
virtual ~HumanPlayer();
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const;
|
||||
|
||||
private:
|
||||
Field::Move Input() const;
|
||||
|
||||
bool Check( const Field& field, const Field::Move& move ) const;
|
||||
};
|
||||
|
||||
#endif // _HUMAN_PLAYER_
|
||||
@@ -0,0 +1,23 @@
|
||||
#include "io.h"
|
||||
|
||||
// #include <iostream>
|
||||
// #include <sstream>
|
||||
// #include <string>
|
||||
|
||||
int io::numberIn() {
|
||||
// std::string input;
|
||||
// getline( std::cin, input );
|
||||
// std::stringstream stream( input );
|
||||
|
||||
int number;
|
||||
// stream >> number;
|
||||
return number;
|
||||
}
|
||||
|
||||
void io::numberOut(int num) {
|
||||
// std::cout << num;
|
||||
}
|
||||
|
||||
void io::stringOut(const char* str) {
|
||||
// std::cout << str;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef _IO_
|
||||
#define _IO_
|
||||
|
||||
namespace io {
|
||||
|
||||
int numberIn();
|
||||
void numberOut(int num);
|
||||
|
||||
void stringOut(const char* str);
|
||||
|
||||
}
|
||||
|
||||
#endif // _IO_
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "tictactoe.h"
|
||||
|
||||
int main() {
|
||||
TicTacToe tictactoe;
|
||||
|
||||
while ( tictactoe.Start() ) {
|
||||
tictactoe.Run();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#include "player.h"
|
||||
|
||||
Player::Player( Field::Token token, const char* name )
|
||||
: token_( token )
|
||||
, name_( name ) {
|
||||
}
|
||||
|
||||
Player::~Player() {
|
||||
}
|
||||
|
||||
const Field::Token& Player::getToken() const
|
||||
{
|
||||
return token_;
|
||||
}
|
||||
|
||||
const char* Player::getName() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef _PLAYER_
|
||||
#define _PLAYER_
|
||||
|
||||
#include "field.h"
|
||||
|
||||
class Player {
|
||||
public:
|
||||
Player( Field::Token token, const char* name );
|
||||
virtual ~Player();
|
||||
|
||||
virtual Field::Move Turn( const Field& field ) const = 0;
|
||||
|
||||
const Field::Token& getToken() const;
|
||||
const char* getName() const;
|
||||
|
||||
protected:
|
||||
const Field::Token token_;
|
||||
const char* name_;
|
||||
};
|
||||
|
||||
#endif // _PLAYER_
|
||||
@@ -0,0 +1,85 @@
|
||||
#include "tictactoe.h"
|
||||
|
||||
#include "artificial_player.h"
|
||||
#include "human_player.h"
|
||||
#include "io.h"
|
||||
|
||||
TicTacToe::TicTacToe() {
|
||||
players_[0] = 0;
|
||||
players_[1] = 0;
|
||||
}
|
||||
|
||||
TicTacToe::~TicTacToe() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
bool TicTacToe::Start() {
|
||||
Reset();
|
||||
io::stringOut("Tic Tac Toe\n\n[1] Human\n[2] Computer\n[3] Quit\n\n");
|
||||
|
||||
players_[0] = SelectPlayer( Field::PlayerA, "Player A" );
|
||||
if ( !players_[0] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
players_[1] = SelectPlayer( Field::PlayerB, "Player B" );
|
||||
if ( !players_[1] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
io::stringOut("\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void TicTacToe::Run() {
|
||||
field_.Show();
|
||||
|
||||
int playerIndex = 0;
|
||||
|
||||
for ( int i = 0; i < 9; i++ ) {
|
||||
Player& player = *players_[playerIndex];
|
||||
|
||||
field_.MakeMove( player.Turn( field_ ), player.getToken() );
|
||||
field_.Show();
|
||||
|
||||
if ( field_.SameInRow( player.getToken(), 3 ) ) {
|
||||
io::stringOut(player.getName());
|
||||
io::stringOut(" won!\n\n");
|
||||
return;
|
||||
}
|
||||
|
||||
playerIndex = ( playerIndex + 1 ) % 2;
|
||||
}
|
||||
|
||||
io::stringOut("Game ends in draw!\n\n");
|
||||
}
|
||||
|
||||
void TicTacToe::Reset() {
|
||||
field_.Clear();
|
||||
|
||||
for ( int i = 0; i < 2; i++ ) {
|
||||
if ( players_[i] ) {
|
||||
delete players_[i];
|
||||
players_[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Player* TicTacToe::SelectPlayer( Field::Token token, const char* name ) const {
|
||||
int selection = 0;
|
||||
|
||||
while ( true ) {
|
||||
io::stringOut("Choose ");
|
||||
io::stringOut(name);
|
||||
io::stringOut(": ");
|
||||
|
||||
selection = io::numberIn();
|
||||
|
||||
switch ( selection ) {
|
||||
case 1 : return new HumanPlayer( token, name );
|
||||
case 2 : return new ArtificialPlayer( token, name );
|
||||
case 3 : return 0;
|
||||
default : io::stringOut("Wrong input!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _TIC_TAC_TOE_
|
||||
#define _TIC_TAC_TOE_
|
||||
|
||||
#include "field.h"
|
||||
#include "player.h"
|
||||
|
||||
class TicTacToe {
|
||||
public:
|
||||
TicTacToe();
|
||||
~TicTacToe();
|
||||
|
||||
bool Start();
|
||||
void Run();
|
||||
|
||||
private:
|
||||
void Reset();
|
||||
Player* SelectPlayer( Field::Token token, const char* name ) const;
|
||||
|
||||
Player* players_[2];
|
||||
Field field_;
|
||||
};
|
||||
|
||||
#endif // _TIC_TAC_TOE_
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<config>
|
||||
<source>
|
||||
<extensions>
|
||||
<header_extensions>.h</header_extensions>
|
||||
<source_extensions>.cpp</source_extensions>
|
||||
</extensions>
|
||||
<source_paths>
|
||||
<source_path>./src</source_path>
|
||||
</source_paths>
|
||||
</source>
|
||||
</config>
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef CODE_TUTORIAL_1_H
|
||||
#define CODE_TUTORIAL_1_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 1 - THE CODE TUTORIAL
|
||||
// As you already know the code view displays the snippets of code that are
|
||||
// related to your currently active symbol. These snippets show the relevant
|
||||
// lines in combination with some context.
|
||||
// In case you discover something interesting as part of the snippet's context
|
||||
// you can activate that symbol with a left-click. That way you dig deeper
|
||||
// through your code base.
|
||||
// Have you ever wondered what's the meaning of life, the universe and
|
||||
// everything? Click the respective symbol to find out.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class CodeTutorial
|
||||
{
|
||||
public:
|
||||
CodeTutorial()
|
||||
{
|
||||
}
|
||||
|
||||
static int meaning_of_life_the_universe_and_everything;
|
||||
};
|
||||
|
||||
|
||||
#endif // CODE_TUTORIAL_1_H
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef CODE_TUTORIAL_2_H
|
||||
#define CODE_TUTORIAL_2_H
|
||||
|
||||
|
||||
#include "code_tutorial_1.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 5 - NO MORE CONTEXT
|
||||
// At this stage you see the entire file and no more context can be expanded.
|
||||
// For the final part of this introduction please have a look at where the
|
||||
// "unrelated_but_very_important()" function is used.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
void unrelated_but_very_important()
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
int calculate(int (*problem)())
|
||||
{
|
||||
return problem();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 4 - MORE CONTEXT
|
||||
// Who would have expected such a simple question?
|
||||
// Note that expanding the view didn't change the active symbol. You can
|
||||
// proceed expanding the view until you hit the level of the file scope.
|
||||
// So go ahead and find out what else is hidden inside this file!
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void deep_thought()
|
||||
{
|
||||
int (*the_question)() = [](){ return 6 * 7; };
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 2 - CONTEXT
|
||||
// We just talked about Coati providing context to the important lines of code.
|
||||
// But it feels like something is missing here. What is "the_question"? And
|
||||
// where does it come from?
|
||||
//
|
||||
// 3 - EXPANDING TO SCOPES
|
||||
// Do you see first line of this snippet? I mean the one that has just two dots
|
||||
// as line number and reads "deep_thought". Actually that's the name of the
|
||||
// function's scope that encapsulates the snippet. By clicking that line you
|
||||
// can tell Coati to expand the view to show the entire scope.
|
||||
// Give it a try!
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
int the_answer = calculate(the_question);
|
||||
CodeTutorial::meaning_of_life_the_universe_and_everything = the_answer;
|
||||
}
|
||||
|
||||
|
||||
#endif // CODE_TUTORIAL_2_H
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef CODE_TUTORIAL_3_H
|
||||
#define CODE_TUTORIAL_3_H
|
||||
|
||||
|
||||
#include "the_central_hub.h"
|
||||
#include "code_tutorial_2.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 6 - SNIPPETS AND FILES
|
||||
// It looks like this function is called in two different places inside the
|
||||
// same file. When two different snippets are located in the same file they
|
||||
// share a single file box. The line numbers to the left indicate where each of
|
||||
// these snippets is located inside the file.
|
||||
//
|
||||
// 7 - MERGING SNIPPETS
|
||||
// The top line of each snippet shows the name of its own parent's scope.
|
||||
// If you want to show the lines in between the two snippets below you can
|
||||
// either expand the upper snippet's scope to show the whole file or you can
|
||||
// tell the lower snippet to reveal its scope.
|
||||
// Try one of these approaches now.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void function_with_snippets()
|
||||
{
|
||||
unrelated_but_very_important();
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 8 - YOU FOUND THE HIDDEN COMMENT
|
||||
// Well done! As you see Coati merged the two snippets from before because
|
||||
// expanding a scope would have caused them to overlap. That's all for the code
|
||||
// view tutorial.
|
||||
//
|
||||
// 9 - EDIT YOUR CODE
|
||||
// In case you wondered if you can edit your code using Coati: You can't. Coati
|
||||
// is designed for code exploration, not as a text editor or an IDE. But there
|
||||
// is a chance that Coati can talk to your favourite editor (that you already
|
||||
// know how to operate) via plugin. For more information about available
|
||||
// plugins please take a look at Coati's user manual.
|
||||
//
|
||||
// We hope you enjoyed this tutorial. You can follow the call below to get back
|
||||
// to the central hub.
|
||||
//
|
||||
// P.S.
|
||||
// You can also click the file name above (i guess you need to scroll up a
|
||||
// little bit) to activate the file's node in case you want to explore your
|
||||
// include hierarchy.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
the_central_hub();
|
||||
|
||||
|
||||
unrelated_but_very_important();
|
||||
};
|
||||
|
||||
|
||||
#endif // CODE_TUTORIAL_3_H
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef GRAPH_TUTORIAL_1_H
|
||||
#define GRAPH_TUTORIAL_1_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 1 - THE GRAPH TUTORIAL
|
||||
// In Coati's default window layout the graph is shown to the left, next to the
|
||||
// code. It displays the structure of your project where all named symbols are
|
||||
// nodes and all relations are edges. Like the code view it shows only the
|
||||
// currently active symbol and all the incoming and outgoing dependencies.
|
||||
//
|
||||
// 2 - HOW DO I NAVIGATE THE GRAPH
|
||||
// You can activate a new symbol by left-clicking on the node you are
|
||||
// interested in. For example: to find out where the function
|
||||
// "where_am_i_called()" is called get over to the graph and click that
|
||||
// function's node.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class GraphTutorial
|
||||
{
|
||||
public:
|
||||
GraphTutorial()
|
||||
{
|
||||
}
|
||||
|
||||
static void where_am_i_called()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // GRAPH_TUTORIAL_1_H
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef GRAPH_TUTORIAL_2_H
|
||||
#define GRAPH_TUTORIAL_2_H
|
||||
|
||||
|
||||
#include "graph_tutorial_1.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 3 - WELL DONE
|
||||
// You activated a node and both, the graph and the code view have been updated
|
||||
// accordingly.
|
||||
// Note that even though Coati provides a graph view it does not remove the
|
||||
// need for reading code. The graph view is great for gaining a quick overview
|
||||
// on relations and navigating code, but once you found something you are
|
||||
// interested in you should still consider the code view to actually read up on
|
||||
// all the important details.
|
||||
//
|
||||
// 4 - HIDDEN ELEMENTS
|
||||
// In order not to flood you with information the graph is hiding a lot of
|
||||
// elements. Do you see the "ClassWithHiddenMembers" for example? It actually
|
||||
// contains more members than you currently see. Members that are not important
|
||||
// for the current context are hidden. Nevertheless you can reveal them by
|
||||
// clicking the arrow next the the class name. Try that now and read those
|
||||
// members' names.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class ClassWithHiddenMembers
|
||||
{
|
||||
public:
|
||||
void potential_caller()
|
||||
{
|
||||
GraphTutorial::where_am_i_called();
|
||||
}
|
||||
|
||||
void now_you_see_all_contents_of_this_class()
|
||||
{
|
||||
}
|
||||
|
||||
void coati_uses_different_colors()
|
||||
{
|
||||
}
|
||||
|
||||
void to_distinguish_between_functions()
|
||||
{
|
||||
}
|
||||
|
||||
int and_variables;
|
||||
|
||||
int to_continue_click;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 5 - RELATIONS
|
||||
// As you see in the graph, this member is accessed at quite some places
|
||||
// throughout the code base. Lets say you wonder what code causes the edge
|
||||
// between "reading" and "this_last_member" to appear. What will happen if you
|
||||
// click the edge?
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
static int this_last_member;
|
||||
};
|
||||
|
||||
|
||||
#endif // GRAPH_TUTORIAL_2_H
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef GRAPH_TUTORIAL_3_H
|
||||
#define GRAPH_TUTORIAL_3_H
|
||||
|
||||
|
||||
#include "graph_tutorial_2.h"
|
||||
|
||||
class ProducerOfTheLastMember
|
||||
{
|
||||
public:
|
||||
void go()
|
||||
{
|
||||
ClassWithHiddenMembers::this_last_member = 42;
|
||||
}
|
||||
|
||||
void on()
|
||||
{
|
||||
ClassWithHiddenMembers::this_last_member++;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 6 - FOCUSING EDGES
|
||||
// Even though Coati doesn't allow to activate an edge, you can still focus on
|
||||
// edges. This doesn't change the currently active symbol (which would cause
|
||||
// Coati to hide everything but the edge). Instead Coati just highlights the
|
||||
// relation's location in the code and scrolls you there, so you don't lose
|
||||
// context.
|
||||
// Try to activate an edge that comes from the "ConsumerOfTheLastMember" class.
|
||||
// Which one you pick doesn't really matter for this tutorial.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
void reading()
|
||||
{
|
||||
ClassWithHiddenMembers::this_last_member *= 2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // GRAPH_TUTORIAL_3_H
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef GRAPH_TUTORIAL_4_H
|
||||
#define GRAPH_TUTORIAL_4_H
|
||||
|
||||
|
||||
#include "graph_tutorial_2.h"
|
||||
#include "the_central_hub.h"
|
||||
|
||||
class ConsumerOfTheLastMember
|
||||
{
|
||||
public:
|
||||
void in()
|
||||
{
|
||||
ClassWithHiddenMembers::this_last_member--;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 7 - THAT'S IT
|
||||
// You completed the tutorial on the graph view. There is still more to learn
|
||||
// but I guess you will figure it out on your own. One last thing: If you see
|
||||
// an element with a hatched background please call us. It's a runaway!
|
||||
// Just kidding. Those are elements that are used within your code, but without
|
||||
// a definition anywhere in your source folder. So if you click them, Coati
|
||||
// will display all the relations for the element, but the code view won't show
|
||||
// a definition. If you want to learn more about Coati, go back to the central
|
||||
// hub. It is called in the function below but you can also try to get there
|
||||
// using only the graph.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
void the()
|
||||
{
|
||||
if (ClassWithHiddenMembers::this_last_member <= 0);
|
||||
{
|
||||
the_central_hub();
|
||||
}
|
||||
}
|
||||
|
||||
void codeview()
|
||||
{
|
||||
ClassWithHiddenMembers::this_last_member /= 2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // GRAPH_TUTORIAL_4_H
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#ifndef MAIN_H
|
||||
#define MAIN_H
|
||||
|
||||
|
||||
#include "my_first_step.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// WHAT IS THIS?
|
||||
// This is a tutorial and it is one of the fastest ways to get to know Coati.
|
||||
//
|
||||
// WHERE AM I?
|
||||
// This is Coati's Code View and you are looking at the main function of this
|
||||
// project's program.
|
||||
//
|
||||
// WHY AM I HERE?
|
||||
// Every time you open up a project in Coati it will go through your project in
|
||||
// search for a function called "main". In case this function is defined the
|
||||
// corresponding symbol is activated. Otherwise Coati will just activate the
|
||||
// first thing in your codebase it happens to stumble across.
|
||||
//
|
||||
// WHAT CAN I DO NOW?
|
||||
// Left-click the "my_first_step()" function call inside the main function.
|
||||
// Lets see what happens.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
int main()
|
||||
{
|
||||
my_first_step();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif // MAIN_H
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef MY_FIRST_STEP_H
|
||||
#define MY_FIRST_STEP_H
|
||||
|
||||
|
||||
#include "the_central_hub.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// WHAT JUST HAPPENED?
|
||||
// As I mentioned earlier, Coati knows the concept of an "active" symbol. You
|
||||
// just changed the active symbol by clicking on the name of a function.
|
||||
//
|
||||
// OK, BUT WHAT IS AN ACTIVE SYMBOL?
|
||||
// Coati doesn't show your entire code base on a single screen. Even for
|
||||
// relatively small projects that would be pointless - trust me on that. So
|
||||
// instead of showing everything at once, Coati keeps a strongly focused view
|
||||
// on your code. This focus only includes the currently active symbol and its
|
||||
// direct relations. Nothing more. By changing the active symbol as you just
|
||||
// did, Coati allows you to jump through the code base on your own.
|
||||
//
|
||||
// I THINK I GOT IT!
|
||||
// Now that you understand Coati's central concept you are ready to jump
|
||||
// further by activating "the_central_hub()" of this tutorial.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void my_first_step()
|
||||
{
|
||||
the_central_hub();
|
||||
}
|
||||
|
||||
|
||||
#endif // MY_FIRST_STEP_H
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef SEARCH_TUTORIAL_1_H
|
||||
#define SEARCH_TUTORIAL_1_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 1 - THE SEARCH TUTORIAL
|
||||
// If you haven't messed up anything yet, you'll find the search bar to the
|
||||
// upper left of Coati's user interface. Initially it shows the name of the
|
||||
// currently active symbol.
|
||||
// Use the shortcut "CTRL/CMD + F" to focus the search bar. You can also just
|
||||
// click it. Try that now and enter the string "find_me_if_you_can" to search
|
||||
// for the respective symbol. Press enter or click the magnification glass to
|
||||
// execute the search.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class SearchTutorial
|
||||
{
|
||||
public:
|
||||
SearchTutorial()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // SEARCH_TUTORIAL_1_H
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef SEARCH_TUTORIAL_2_H
|
||||
#define SEARCH_TUTORIAL_2_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 2 - THE AUTOCOMPLETION
|
||||
// I hope you have been lazy enough to not enter the whole string from start to
|
||||
// finish. So you already noticed Coati's autocompletion box.
|
||||
// While you enter your search request Coati already tries to find a subset of
|
||||
// matching symbols to help you get where you want pretty fast.
|
||||
// But that's not all Coati does. Keep an eye on the search bar while entering
|
||||
// the string "aux" and activate the symbol showing up.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void finde_me_if_you_can()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif // SEARCH_TUTORIAL_2_H
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef SEARCH_TUTORIAL_3_H
|
||||
#define SEARCH_TUTORIAL_3_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 3 - FUZZY MATCHING
|
||||
// While looking for matching symbols the search bar does not only consider
|
||||
// strict matches to the entered substring. Instead it uses a more fuzzy
|
||||
// approach. This is really helpful when you only have a rough idea of what the
|
||||
// element you are really looking for is called.
|
||||
// While showing the list of results the autocompletion also display the kind
|
||||
// of each of the results to the very right.
|
||||
// Try to activate the class with the name "NameConflict" next.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void autocompletion_example()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif // SEARCH_TUTORIAL_3_H
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef SEARCH_TUTORIAL_4_H
|
||||
#define SEARCH_TUTORIAL_4_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 4 - WHAT ARE THE OTHER BUTTONS?
|
||||
// Well done. Lets get over the other buttons left to the search bar really
|
||||
// quick.
|
||||
//
|
||||
// 5 - UNDO AND REDO
|
||||
// You can use the buttons to the very left to undo and redo your actions. This
|
||||
// may seem odd since Coati doesn't include any features to actually change
|
||||
// code. Instead Coati offers these buttons to help you navigate. So they
|
||||
// really come in handy in case you ask yourself something like "How did I end
|
||||
// up here?"
|
||||
//
|
||||
// 6 - REFRESH
|
||||
// The next button allows you to refresh you project in case you changed some
|
||||
// of your code. The second button toggels the auto-refresh option. When
|
||||
// enabled Coati refreshes your project every time it's window gets focused.
|
||||
//
|
||||
// 7 - WHAT'S NEXT?
|
||||
// Instead of the class activate the struct with the same name as before.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace a
|
||||
{
|
||||
class NameConflict
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // SEARCH_TUTORIAL_4_H
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef SEARCH_TUTORIAL_5_H
|
||||
#define SEARCH_TUTORIAL_5_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 8 - CONGRATULATONS
|
||||
// You have completed the challenge of search.
|
||||
// Oh, I almost forgot: You can only find nodes such as symbols via the search
|
||||
// bar. It doesn't allow you to find edges like calls or inheritance. At least
|
||||
// not yet.
|
||||
// Try to get back to the the central hub using the search bar!
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace b
|
||||
{
|
||||
struct NameConflict
|
||||
{
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // SEARCH_TUTORIAL_5_H
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#ifndef START_EXPLORING_H
|
||||
#define START_EXPLORING_H
|
||||
|
||||
|
||||
#include "utility.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// FURTHER EXPLORATION
|
||||
// If you completed all the other tutorials you might want to put your new
|
||||
// skills to use and do some exploration on your own.
|
||||
// Here comes the bad news: Even though this tutorial contains some code that
|
||||
// would compile, the code doesn't make much sense. So trying to explore this
|
||||
// project any further would be rather unproductive.
|
||||
// The good news is: In addition to this tutorial Coati also ships with a real
|
||||
// example project that implements the game Tic-Tac-Toe! You can open the
|
||||
// project via the "Project -> Recent Projects" menu.
|
||||
// You can also start exploring your own projects by creating a new Coati
|
||||
// project where you can add all your source and include paths.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
class StartExploring
|
||||
{
|
||||
public:
|
||||
StartExploring()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // START_EXPLORING_H
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef THE_CENTRAL_HUB_H
|
||||
#define THE_CENTRAL_HUB_H
|
||||
|
||||
|
||||
#include "search_tutorial_1.h"
|
||||
#include "graph_tutorial_1.h"
|
||||
#include "code_tutorial_1.h"
|
||||
#include "start_exploring.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// THE HUB
|
||||
// This is the central hub of Coati's tutorial. From here you can embark on
|
||||
// short trips to explore the different parts of Coati. Most important: You
|
||||
// will get to know how all the different parts of Coati interact.
|
||||
// The function below references all the available tutorials. So pick one and
|
||||
// jump right to action.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void the_central_hub()
|
||||
{
|
||||
SearchTutorial* the_challenge_of_search;
|
||||
GraphTutorial* reading_the_map;
|
||||
CodeTutorial* explore_the_details;
|
||||
|
||||
StartExploring* going_beyond_this_tutorial;
|
||||
}
|
||||
|
||||
|
||||
#endif // THE_CENTRAL_HUB_H
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef UTILITY_H
|
||||
#define UTILITY_H
|
||||
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
|
||||
#endif // UTILITY_H
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<config>
|
||||
<source>
|
||||
<extensions>
|
||||
<header_extensions>.h</header_extensions>
|
||||
<source_extensions>.cpp</source_extensions>
|
||||
</extensions>
|
||||
<source_paths>
|
||||
<source_path>./src</source_path>
|
||||
</source_paths>
|
||||
</source>
|
||||
</config>
|
||||
@@ -0,0 +1,16 @@
|
||||
void lambdaCaller()
|
||||
{
|
||||
[](){}();
|
||||
}
|
||||
|
||||
void lambdaSuperCaller()
|
||||
{
|
||||
lambdaCaller();
|
||||
}
|
||||
|
||||
void lambdaMetaCaller()
|
||||
{
|
||||
[](){
|
||||
lambdaCaller();
|
||||
}();
|
||||
}
|
||||
@@ -21,6 +21,7 @@ int calculate(int i)
|
||||
return a;
|
||||
}
|
||||
|
||||
#define PI 3.1415
|
||||
|
||||
#define CALL_CALCULATE() \
|
||||
do \
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
<String>Hello World!</String>
|
||||
|
||||
<source>
|
||||
<SourcePaths>
|
||||
<SourcePath>data</SourcePath>
|
||||
</SourcePaths>
|
||||
<HeaderSearchPaths>
|
||||
<HeaderSearchPath>data/</HeaderSearchPath>
|
||||
<HeaderSearchPath>src/</HeaderSearchPath>
|
||||
</HeaderSearchPaths>
|
||||
<source_paths>
|
||||
<source_path>data</source_path>
|
||||
</source_paths>
|
||||
<header_search_paths>
|
||||
<header_search_path>data/</header_search_path>
|
||||
<header_search_path>src/</header_search_path>
|
||||
</header_search_paths>
|
||||
|
||||
</source>
|
||||
</config>
|
||||
|
||||
@@ -1,310 +1,4 @@
|
||||
ConfigManager.cpp WARNING: value path/to/nowhere is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Settings.cpp WARNING: File for Settings not found: data/TestSettings.xml
|
||||
ConfigManager.cpp WARNING: value source/HeaderSearchPaths/HeaderSearchPath is not present in config.
|
||||
Token.cpp ERROR: Location Id was not referenced by this Token.
|
||||
Edge.cpp ERROR: Edge type_of can't go from Node undefined to Node undefined
|
||||
Node.cpp WARNING: Cannot change NodeType after it was already set from namespace to class
|
||||
|
||||
+23
-26
@@ -4,45 +4,40 @@
|
||||
# )
|
||||
|
||||
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/app/data
|
||||
DESTINATION share/coati/.config/coati
|
||||
DESTINATION coati/data
|
||||
PATTERN "log/*" EXCLUDE
|
||||
PATTERN "projects" EXCLUDE
|
||||
PATTERN "projects/ingored" EXCLUDE
|
||||
PATTERN "src" EXCLUDE
|
||||
PATTERN "ApplicationSettings.xml" EXCLUDE
|
||||
PATTERN "ApplicationSettings_distr.xml" EXCLUDE
|
||||
PATTERN "ApplicationSettings_for_package.xml" EXCLUDE
|
||||
PATTERN "ProjectSettings_template.xml" EXCLUDE
|
||||
PATTERN "ApplicationSettings_template.xml" EXCLUDE
|
||||
)
|
||||
|
||||
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/bin/app/data/src/tictactoe
|
||||
DESTINATION share/coati/.config/coati/data/projects
|
||||
)
|
||||
|
||||
INSTALL(FILES ${CMAKE_SOURCE_DIR}/bin/app/data/projects/tictactoe.xml
|
||||
DESTINATION share/coati/.config/coati/data/projects/tictactoe
|
||||
)
|
||||
|
||||
INSTALL(FILES ${CMAKE_SOURCE_DIR}/bin/app/data/ApplicationSettings_distr.xml
|
||||
DESTINATION share/coati/.config/coati/data
|
||||
INSTALL(FILES ${CMAKE_SOURCE_DIR}/bin/app/data/ApplicationSettings_for_package.xml
|
||||
DESTINATION coati/data
|
||||
RENAME ApplicationSettings.xml)
|
||||
|
||||
INSTALL(FILES ${CMAKE_SOURCE_DIR}/setup/Linux/coati.desktop
|
||||
DESTINATION share/applications
|
||||
DESTINATION applications
|
||||
)
|
||||
INSTALL(FILES ${CMAKE_SOURCE_DIR}/bin/app/data/gui/icon/logo_1024_1024.png
|
||||
DESTINATION share/icons
|
||||
DESTINATION icons
|
||||
RENAME coati.png)
|
||||
|
||||
INSTALL(FILES ${CMAKE_SOURCE_DIR}/web/coati_manual.pdf
|
||||
DESTINATION coati)
|
||||
|
||||
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/setup/Linux/lib
|
||||
DESTINATION share/coati
|
||||
DESTINATION coati
|
||||
)
|
||||
INSTALL(FILES
|
||||
${CMAKE_SOURCE_DIR}/setup/Linux/libqxcb.so
|
||||
DESTINATION share/coati/platforms
|
||||
DESTINATION coati/platforms
|
||||
)
|
||||
INSTALL(PROGRAMS
|
||||
${CMAKE_SOURCE_DIR}/setup/Linux/Coati.sh
|
||||
DESTINATION share/coati
|
||||
DESTINATION coati
|
||||
)
|
||||
INSTALL(PROGRAMS ${CMAKE_SOURCE_DIR}/setup/Linux/coati
|
||||
DESTINATION bin/
|
||||
@@ -52,21 +47,23 @@ INSTALL(PROGRAMS ${CMAKE_SOURCE_DIR}/setup/Linux/coati
|
||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
INSTALL(TARGETS ${APP_PROJECT_NAME}
|
||||
DESTINATION share/coati
|
||||
DESTINATION coati
|
||||
)
|
||||
|
||||
SET(CPACK_GENERATOR "DEB;TGZ")
|
||||
# SET(CPACK_GENERATOR "DEB;TGZ")
|
||||
SET(CPACK_GENERATOR "TGZ")
|
||||
SET(CPACK_ARCHIVE_COMPONENT_INSTALL "ON")
|
||||
|
||||
# DEBIAN PACKAGE
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Andreas Stallinger <astallinger@coati.io>")
|
||||
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
|
||||
# SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Andreas Stallinger <astallinger@coati.io>")
|
||||
# SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
|
||||
# SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://coati.io")
|
||||
# SET(CPACK_DEBIAN_PACKAGE_SECTION "devel")
|
||||
|
||||
SET(CPACK_PACKAGE_NAME "Coati")
|
||||
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "http://coati.io")
|
||||
SET(CPACK_DEBIAN_PACKAGE_SECTION "devel")
|
||||
SET(CPACK_PACKAGING_INSTALL_PREFIX "/usr/local")
|
||||
SET(CPACK_PACKAGING_INSTALL_PREFIX "")
|
||||
SET(CPACK_PACKAGE_VERSION ${GIT_VERSION_NUMBER})
|
||||
SET(CPACK_PACKAGE_EXECUTABLES "Coati")
|
||||
SET(CPACK_STRIP_FILES "share/coati/Coati")
|
||||
SET(CPACK_STRIP_FILES "coati/Coati")
|
||||
|
||||
INCLUDE(CPack)
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import sublime
|
||||
import sublime_plugin
|
||||
import threading
|
||||
import socket
|
||||
import os.path
|
||||
|
||||
try: # use this for Sublime Text 2
|
||||
import SocketServer
|
||||
except ImportError: # use this for Sublime Text 3
|
||||
import socketserver as SocketServer
|
||||
|
||||
MESSAGE_SPLIT_STRING = ">>"
|
||||
|
||||
|
||||
# Handling Coati to Sublime communication
|
||||
|
||||
def setCursorPosition(filePath, row, col):
|
||||
if (os.path.exists(filePath)):
|
||||
sublime.active_window().open_file(filePath + ":" + str(row) + ":" + str(col), sublime.ENCODED_POSITION)
|
||||
else:
|
||||
sublime.error_message("Coati is trying to jump to a file that does not exist: " + filePath)
|
||||
|
||||
|
||||
class ConnectionHandler(SocketServer.BaseRequestHandler): # This class is instantiated once per connection to the server
|
||||
def handle(self):
|
||||
data = self.request.recv(1024).strip()
|
||||
text = data.decode('utf-8')
|
||||
eom_index = text.find("<EOM>")
|
||||
if (not eom_index == 0):
|
||||
message_string = text[0:eom_index]
|
||||
message_fields = message_string.split(MESSAGE_SPLIT_STRING)
|
||||
if (message_fields[0] == "moveCursor"):
|
||||
sublime.set_timeout(lambda: setCursorPosition(message_fields[1], int(message_fields[2]), int(message_fields[3]) + 1), 0)
|
||||
|
||||
|
||||
class ServerThreadHandler(threading.Thread):
|
||||
def __init__ (self, ip, port):
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
threading.Thread.__init__(self)
|
||||
|
||||
def run(self):
|
||||
server = SocketServer.TCPServer((self.ip, self.port), ConnectionHandler)
|
||||
server.serve_forever()
|
||||
|
||||
|
||||
class ServerStartupListener(sublime_plugin.EventListener):
|
||||
def __init__(self):
|
||||
self.running = False
|
||||
|
||||
def on_activated(self, view):
|
||||
if (not self.running):
|
||||
self.running = True
|
||||
|
||||
settings = sublime.load_settings('CoatiPlugin.sublime-settings')
|
||||
host_ip = settings.get('host_ip')
|
||||
coati_to_plugin_port = settings.get('coati_to_sublime_port')
|
||||
|
||||
networkListener = ServerThreadHandler(host_ip, coati_to_plugin_port)
|
||||
networkListener.start()
|
||||
|
||||
|
||||
# Handling Sublime to Coati communication
|
||||
|
||||
class SetActiveTokenCommand(sublime_plugin.TextCommand):
|
||||
def run(self, edit):
|
||||
filePath = self.view.file_name();
|
||||
|
||||
selectionPos = self.view.sel()[0].begin()
|
||||
(row, col) = self.view.rowcol(selectionPos)
|
||||
col += 1 # cols returned by rowcol() are 0-based.
|
||||
row += 1 # rows returned by rowcol() are 0-based.
|
||||
|
||||
text = "setActiveToken" + MESSAGE_SPLIT_STRING + filePath + MESSAGE_SPLIT_STRING + str(row) + MESSAGE_SPLIT_STRING + str(col) + "<EOM>"
|
||||
data = text.encode()
|
||||
|
||||
settings = sublime.load_settings('CoatiPlugin.sublime-settings')
|
||||
host_ip = settings.get('host_ip')
|
||||
plugin_to_coati_port = settings.get('sublime_to_coati_port')
|
||||
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((host_ip, plugin_to_coati_port))
|
||||
s.send(data)
|
||||
s.close()
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"host_ip": "localhost",
|
||||
"coati_to_sublime_port": 6666,
|
||||
"sublime_to_coati_port": 6667
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
{ "caption": "-", "id": "coati" },
|
||||
{ "command": "set_active_token", "caption": "Coati - Set active Token" }
|
||||
]
|
||||
@@ -0,0 +1,5 @@
|
||||
How to Install:
|
||||
|
||||
Just copy and past this "CoatiPlugin" folder into your Packages folder of Sublime Text. (You can find
|
||||
that folder from within Sublime via the menu: Preferences -> Browse Packages...). Restart Sublime before
|
||||
starting to use the plugin.
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,20 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CoatiPlugin", "CoatiPlugin\CoatiPlugin.csproj", "{A585A530-E120-4C74-934E-D57ED12A7DA9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A585A530-E120-4C74-934E-D57ED12A7DA9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
Binary file not shown.
@@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{A585A530-E120-4C74-934E-D57ED12A7DA9}</ProjectGuid>
|
||||
<ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>SnowForest.CoatiPlugin</RootNamespace>
|
||||
<AssemblyName>CoatiPlugin</AssemblyName>
|
||||
<SignAssembly>True</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<RunCodeAnalysis>true</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="Microsoft.VisualStudio.OLE.Interop" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.8.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.9.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.10.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Interop.11.0">
|
||||
<EmbedInteropTypes>true</EmbedInteropTypes>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.11.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0" />
|
||||
<Reference Include="Microsoft.VisualStudio.Shell.Immutable.11.0" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Design" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<COMReference Include="EnvDTE">
|
||||
<Guid>{80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}</Guid>
|
||||
<VersionMajor>8</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="EnvDTE100">
|
||||
<Guid>{26AD1324-4B7C-44BC-84F8-B86AED45729F}</Guid>
|
||||
<VersionMajor>10</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="EnvDTE80">
|
||||
<Guid>{1A31287A-4D7D-413E-8E32-3B374931BD89}</Guid>
|
||||
<VersionMajor>8</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="EnvDTE90">
|
||||
<Guid>{2CE2370E-D744-4936-A090-3FFFE667B0E1}</Guid>
|
||||
<VersionMajor>9</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="Microsoft.VisualStudio.CommandBars">
|
||||
<Guid>{1CBA492E-7263-47BB-87FE-639000619B15}</Guid>
|
||||
<VersionMajor>8</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
<COMReference Include="stdole">
|
||||
<Guid>{00020430-0000-0000-C000-000000000046}</Guid>
|
||||
<VersionMajor>2</VersionMajor>
|
||||
<VersionMinor>0</VersionMinor>
|
||||
<Lcid>0</Lcid>
|
||||
<WrapperTool>primary</WrapperTool>
|
||||
<Isolated>False</Isolated>
|
||||
<EmbedInteropTypes>False</EmbedInteropTypes>
|
||||
</COMReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FileUtility.cs" />
|
||||
<Compile Include="Guids.cs" />
|
||||
<Compile Include="NetworkProtocolUtility.cs" />
|
||||
<Compile Include="NetworkUtility.cs" />
|
||||
<Compile Include="Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="GlobalSuppressions.cs" />
|
||||
<Compile Include="CoatiPluginPackage.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="PkgCmdID.cs" />
|
||||
<Compile Include="SystemUtility.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="VSPackage.resx">
|
||||
<MergeWithCTO>true</MergeWithCTO>
|
||||
<ManifestResourceName>VSPackage</ManifestResourceName>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="source.extension.vsixmanifest">
|
||||
<SubType>Designer</SubType>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Key.snk" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<VSCTCompile Include="CoatiPlugin.vsct">
|
||||
<ResourceName>Menus.ctmenu</ResourceName>
|
||||
<SubType>Designer</SubType>
|
||||
</VSCTCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\favicon_16x16.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="coati.ico">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
<IncludeInVSIX>true</IncludeInVSIX>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<UseCodebase>true</UseCodebase>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>C:\Program Files %28x86%29\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe</StartProgram>
|
||||
<StartArguments>/rootsuffix Exp</StartArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
|
||||
<StartAction>Program</StartAction>
|
||||
<StartProgram>C:\Program Files %28x86%29\Microsoft Visual Studio 11.0\Common7\IDE\devenv.exe</StartProgram>
|
||||
<StartArguments>/rootsuffix Exp</StartArguments>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
|
||||
|
||||
<!-- This is the file that defines the actual layout and type of the commands.
|
||||
It is divided in different sections (e.g. command definition, command
|
||||
placement, ...), with each defining a specific set of properties.
|
||||
See the comment before each section for more details about how to
|
||||
use it. -->
|
||||
|
||||
<!-- The VSCT compiler (the tool that translates this file into the binary
|
||||
format that VisualStudio will consume) has the ability to run a preprocessor
|
||||
on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
|
||||
it is possible to define includes and macros with the same syntax used
|
||||
in C++ files. Using this ability of the compiler here, we include some files
|
||||
defining some of the constants that we will use inside the file. -->
|
||||
|
||||
<!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
|
||||
<Extern href="stdidcmd.h"/>
|
||||
|
||||
<!--This header contains the command ids for the menus provided by the shell. -->
|
||||
<Extern href="vsshlids.h"/>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--The Commands section is where we the commands, menus and menu groups are defined.
|
||||
This section uses a Guid to identify the package that provides the command defined inside it. -->
|
||||
<Commands package="guidCoatiPluginPkg">
|
||||
<Bitmaps>
|
||||
<Bitmap guid="icon" href="Resources\favicon_16x16.png" usedList="icon0"/>
|
||||
</Bitmaps>
|
||||
|
||||
<Groups>
|
||||
|
||||
<Group guid="guidCoatiPluginCmdSet" id="MyMenuGroup" priority="0x0600">
|
||||
<Parent guid="guidSHLMainMenu" id="IDM_VS_CTXT_CODEWIN"/>
|
||||
</Group>
|
||||
|
||||
|
||||
|
||||
</Groups>
|
||||
|
||||
<!--Buttons section. -->
|
||||
<!--This section defines the elements the user can interact with, like a menu command or a button
|
||||
or combo box in a toolbar. -->
|
||||
<Buttons>
|
||||
<!--To define a menu group you have to specify its ID, the parent menu and its display priority.
|
||||
The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use
|
||||
the CommandFlag node.
|
||||
You can add more than one CommandFlag node e.g.:
|
||||
<CommandFlag>DefaultInvisible</CommandFlag>
|
||||
<CommandFlag>DynamicVisibility</CommandFlag>
|
||||
If you do not want an image next to your command, remove the Icon node /> -->
|
||||
|
||||
<Button guid="guidCoatiPluginCmdSet" id="cmdidCoatiSetActiveToken" priority="0x0100" type="Button">
|
||||
<Parent guid="guidCoatiPluginCmdSet" id="MyMenuGroup" />
|
||||
<Icon guid="icon" id="icon0" />
|
||||
<Strings>
|
||||
<ButtonText>Set active Token</ButtonText>
|
||||
</Strings>
|
||||
</Button>
|
||||
|
||||
</Buttons>
|
||||
|
||||
</Commands>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<Symbols>
|
||||
<!-- This is the package guid. -->
|
||||
<GuidSymbol name="guidCoatiPluginPkg" value="{acf15780-03b5-440e-a41e-db79b7043fc2}" />
|
||||
|
||||
<!-- This is the guid used to group the menu commands together -->
|
||||
<GuidSymbol name="guidCoatiPluginCmdSet" value="{0efb005b-715c-4a62-8a9b-1e5a870e6c34}">
|
||||
|
||||
<IDSymbol name="MyMenuGroup" value="0x1020" />
|
||||
<IDSymbol name="cmdidCoatiPing" value="0x0100" />
|
||||
<IDSymbol name="cmdidCoatiFile" value="0x0101"/>
|
||||
<IDSymbol name="cmdidCoatiGetActiveFileName" value="0x0102"/>
|
||||
<IDSymbol name="cmdidCoatiGetActiveLineNumber" value="0x0103"/>
|
||||
<IDSymbol name="cmdidCoatiSetActiveToken" value="0x0104"/>
|
||||
</GuidSymbol>
|
||||
|
||||
|
||||
|
||||
<GuidSymbol name="guidImages" value="{e447cfde-511d-4f75-80c1-a40b8a03152a}" >
|
||||
<IDSymbol name="bmpPic1" value="1" />
|
||||
<IDSymbol name="bmpPic2" value="2" />
|
||||
<IDSymbol name="bmpPicSearch" value="3" />
|
||||
<IDSymbol name="bmpPicX" value="4" />
|
||||
<IDSymbol name="bmpPicArrows" value="5" />
|
||||
<IDSymbol name="bmpPicStrikethrough" value="6" />
|
||||
</GuidSymbol>
|
||||
|
||||
<GuidSymbol name="icon" value="{403BFDD2-B84C-4BCE-A1D1-B16F9F2B8230}" >
|
||||
<IDSymbol name="icon0" value="1" />
|
||||
</GuidSymbol>
|
||||
|
||||
</Symbols>
|
||||
|
||||
</CommandTable>
|
||||
@@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.ComponentModel.Design;
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.VisualStudio;
|
||||
using Microsoft.VisualStudio.Shell.Interop;
|
||||
using Microsoft.VisualStudio.OLE.Interop;
|
||||
using Microsoft.VisualStudio.Shell;
|
||||
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
using EnvDTE;
|
||||
using EnvDTE80;
|
||||
|
||||
namespace SnowForest.CoatiPlugin
|
||||
{
|
||||
[PackageRegistration(UseManagedResourcesOnly = true)]
|
||||
[InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)]
|
||||
[ProvideMenuResource("Menus.ctmenu", 1)]
|
||||
[Guid(GuidList.guidCoatiPluginPkgString)]
|
||||
[ProvideAutoLoad(Microsoft.VisualStudio.Shell.Interop.UIContextGuids80.NoSolution)]
|
||||
|
||||
public sealed class CoatiPluginPackage : Package
|
||||
{
|
||||
System.Threading.Thread _serverThread = null;
|
||||
|
||||
public CoatiPluginPackage()
|
||||
{}
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
AsynchronousSocketListener server = new AsynchronousSocketListener();
|
||||
AsynchronousSocketListener._onReadCallback = new AsynchronousSocketListener.OnReadCallback(OnNetworkReadCallback);
|
||||
AsynchronousSocketListener._onErrorCallback = new AsynchronousSocketListener.OnReadCallback(OnNetworkErrorCallback);
|
||||
_serverThread = new System.Threading.Thread(server.DoWork);
|
||||
_serverThread.Start();
|
||||
|
||||
AsynchronousClient._onErrorCallback = new AsynchronousSocketListener.OnReadCallback(OnNetworkErrorCallback);
|
||||
|
||||
FileUtility._errorCallback = new FileUtility.ErrorCallback(OnFileUtilityError);
|
||||
|
||||
OleMenuCommandService mcs = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
|
||||
if ( null != mcs )
|
||||
{
|
||||
CommandID setActiveTokenCommandID = new CommandID(GuidList.guidCoatiPluginCmdSet, (int)PkgCmdIDList.cmdidCoatiSetActiveToken);
|
||||
MenuCommand menuItemSetActiveToken = new MenuCommand(MenuItemCallback, setActiveTokenCommandID);
|
||||
mcs.AddCommand(menuItemSetActiveToken);
|
||||
}
|
||||
}
|
||||
|
||||
private void MenuItemCallback(object sender, EventArgs e)
|
||||
{
|
||||
MenuCommand menuCommand = sender as MenuCommand;
|
||||
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
|
||||
if (menuCommand != null)
|
||||
{
|
||||
if (menuCommand.CommandID.ID == (int)PkgCmdIDList.cmdidCoatiSetActiveToken)
|
||||
{
|
||||
string fileName = FileUtility.GetActiveDocumentName(dte);
|
||||
string filePath = FileUtility.GetActiveDocumentPath(dte);
|
||||
|
||||
int lineNumber = FileUtility.GetActiveLineNumber(dte);
|
||||
int columnNumber = FileUtility.GetActiveColumnNumber(dte);
|
||||
|
||||
string message = NetworkProtocolUtility.createOutMessage(filePath + fileName, lineNumber, columnNumber);
|
||||
|
||||
AsynchronousClient.Send(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkReadCallback(string message)
|
||||
{
|
||||
NetworkProtocolUtility.CursorPosition cursorPosition = NetworkProtocolUtility.parseInMessage(message);
|
||||
if (cursorPosition.Valid)
|
||||
{
|
||||
cursorPosition.ColumnNumber += 1; // VS counts columns starting at 1, coati starts at 0
|
||||
DTE dte = (DTE)GetService(typeof(DTE));
|
||||
if (FileUtility.OpenSourceFile(dte, cursorPosition.FilePath))
|
||||
{
|
||||
FileUtility.GoToLine(dte, cursorPosition.LineNumber, cursorPosition.ColumnNumber);
|
||||
|
||||
SystemUtility.GetWindowFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnNetworkErrorCallback(string message)
|
||||
{
|
||||
DisplayMessage("Coati Network Error", message);
|
||||
}
|
||||
|
||||
private void OnFileUtilityError(string message)
|
||||
{
|
||||
DisplayMessage("Coati File Error", message);
|
||||
}
|
||||
|
||||
private void DisplayMessage(string title, string message)
|
||||
{
|
||||
IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));
|
||||
Guid clsid = Guid.Empty;
|
||||
int result;
|
||||
Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
|
||||
0,
|
||||
ref clsid,
|
||||
title,
|
||||
message,
|
||||
string.Empty,
|
||||
0,
|
||||
OLEMSGBUTTON.OLEMSGBUTTON_OK,
|
||||
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
|
||||
OLEMSGICON.OLEMSGICON_INFO,
|
||||
0, // false
|
||||
out result));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using EnvDTE;
|
||||
|
||||
namespace SnowForest.CoatiPlugin
|
||||
{
|
||||
class FileUtility
|
||||
{
|
||||
public delegate void ErrorCallback(string message);
|
||||
|
||||
public static ErrorCallback _errorCallback = null;
|
||||
|
||||
/**
|
||||
* Returns true when file was found, false otherwise
|
||||
*/
|
||||
public static bool OpenSourceFile(DTE dte, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
dte.ItemOperations.OpenFile(fileName);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (_errorCallback != null)
|
||||
{
|
||||
_errorCallback("Failed to open file at " + fileName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void GoToLine(DTE dte, int lineNumber, int columnNumber)
|
||||
{
|
||||
try
|
||||
{
|
||||
((EnvDTE.TextSelection)dte.ActiveDocument.Selection).MoveToLineAndOffset(lineNumber, columnNumber);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (_errorCallback != null)
|
||||
{
|
||||
_errorCallback("Failed to set cursor to position [" + lineNumber.ToString() + "," + columnNumber.ToString() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetActiveDocumentName(DTE dte)
|
||||
{
|
||||
return dte.ActiveDocument.Name;
|
||||
}
|
||||
|
||||
public static string GetActiveDocumentPath(DTE dte)
|
||||
{
|
||||
return dte.ActiveDocument.Path;
|
||||
}
|
||||
|
||||
public static int GetActiveLineNumber(DTE dte)
|
||||
{
|
||||
return ((EnvDTE.TextSelection)dte.ActiveDocument.Selection).ActivePoint.Line;
|
||||
}
|
||||
|
||||
public static int GetActiveColumnNumber(DTE dte)
|
||||
{
|
||||
return ((EnvDTE.TextSelection)dte.ActiveDocument.Selection).ActivePoint.LineCharOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project. Project-level
|
||||
// suppressions either have no target or are given a specific target
|
||||
// and scoped to a namespace, type, member, etc.
|
||||
//
|
||||
// To add a suppression to this file, right-click the message in the
|
||||
// Error List, point to "Suppress Message(s)", and click "In Project
|
||||
// Suppression File". You do not need to add suppressions to this
|
||||
// file manually.
|
||||
|
||||
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
|
||||
@@ -0,0 +1,14 @@
|
||||
// Guids.cs
|
||||
// MUST match guids.h
|
||||
using System;
|
||||
|
||||
namespace SnowForest.CoatiPlugin
|
||||
{
|
||||
static class GuidList
|
||||
{
|
||||
public const string guidCoatiPluginPkgString = "acf15780-03b5-440e-a41e-db79b7043fc2";
|
||||
public const string guidCoatiPluginCmdSetString = "0efb005b-715c-4a62-8a9b-1e5a870e6c34";
|
||||
|
||||
public static readonly Guid guidCoatiPluginCmdSet = new Guid(guidCoatiPluginCmdSetString);
|
||||
};
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,132 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SnowForest.CoatiPlugin
|
||||
{
|
||||
class NetworkProtocolUtility
|
||||
{
|
||||
private static string s_divider = ">>";
|
||||
private static string s_setActiveTokenPrefix = "setActiveToken";
|
||||
private static string s_moveCursorPrefix = "moveCursor";
|
||||
private static string s_endOfMessageToken = "<EOM>";
|
||||
|
||||
public class CursorPosition
|
||||
{
|
||||
private string _filePath = "";
|
||||
private int _lineNumber = 0;
|
||||
private int _columnNumber = 0;
|
||||
private bool _valid = false;
|
||||
|
||||
public string FilePath
|
||||
{
|
||||
get { return _filePath; }
|
||||
set { _filePath = value; }
|
||||
}
|
||||
|
||||
public int LineNumber
|
||||
{
|
||||
get { return _lineNumber; }
|
||||
set { _lineNumber = value; }
|
||||
}
|
||||
|
||||
public int ColumnNumber
|
||||
{
|
||||
get { return _columnNumber; }
|
||||
set { _columnNumber = value; }
|
||||
}
|
||||
|
||||
public bool Valid
|
||||
{
|
||||
get { return _valid; }
|
||||
set { _valid = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public static string createOutMessage(string filePath, int lineNumber, int columnNumber)
|
||||
{
|
||||
string message = s_setActiveTokenPrefix;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += filePath;
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += lineNumber.ToString();
|
||||
|
||||
message += s_divider;
|
||||
|
||||
message += columnNumber.ToString();
|
||||
|
||||
message += s_endOfMessageToken;
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: debug
|
||||
*/
|
||||
public static CursorPosition parseInMessage(string message)
|
||||
{
|
||||
CursorPosition result = new CursorPosition();
|
||||
|
||||
// remove eof token right away
|
||||
if(message.IndexOf(s_endOfMessageToken) > -1)
|
||||
{
|
||||
message = message.Substring(0, message.IndexOf(s_endOfMessageToken));
|
||||
}
|
||||
|
||||
int pos = message.IndexOf(s_moveCursorPrefix);
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
message = message.Substring(pos + s_moveCursorPrefix.Length + s_divider.Length);
|
||||
|
||||
pos = message.IndexOf(s_divider);
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
string filePath = message.Substring(0, pos);
|
||||
result.FilePath = filePath;
|
||||
|
||||
message = message.Substring(pos+2);
|
||||
|
||||
pos = message.IndexOf(s_divider);
|
||||
|
||||
if (pos < 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
string sLineNumber = message.Substring(0, pos);
|
||||
int lineNumber = 0;
|
||||
bool valid = int.TryParse(sLineNumber, out lineNumber);
|
||||
if (valid)
|
||||
{
|
||||
result.LineNumber = lineNumber;
|
||||
}
|
||||
|
||||
message = message.Substring(pos+2);
|
||||
|
||||
string sColumnNumber = message;
|
||||
int columnNumber = 0;
|
||||
valid = int.TryParse(sColumnNumber, out columnNumber);
|
||||
if (valid)
|
||||
{
|
||||
result.ColumnNumber = columnNumber;
|
||||
result.Valid = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using System.Net.Sockets;
|
||||
using System.Net;
|
||||
|
||||
namespace SnowForest.CoatiPlugin
|
||||
{
|
||||
public class StateObject
|
||||
{
|
||||
public Socket _workSocket = null;
|
||||
public const int _bufferSize = 1024;
|
||||
public byte[] _buffer = new byte[_bufferSize];
|
||||
public StringBuilder _stringBuilder = new StringBuilder();
|
||||
}
|
||||
|
||||
public class AsynchronousSocketListener
|
||||
{
|
||||
public static ManualResetEvent _allDone = new ManualResetEvent(false);
|
||||
|
||||
public delegate void OnReadCallback(string message);
|
||||
|
||||
public static OnReadCallback _onReadCallback = null;
|
||||
public static OnReadCallback _onErrorCallback = null;
|
||||
|
||||
private static string _endOfMessageToken = "<EOM>";
|
||||
|
||||
public AsynchronousSocketListener()
|
||||
{
|
||||
}
|
||||
|
||||
public void DoWork()
|
||||
{
|
||||
StartListening();
|
||||
}
|
||||
|
||||
public static void StartListening()
|
||||
{
|
||||
const int port = 6666;
|
||||
const string ipAddressString = "127.0.0.1";
|
||||
|
||||
byte[] bytes = new Byte[1024];
|
||||
|
||||
IPAddress ipAddress = IPAddress.Parse(ipAddressString);
|
||||
IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
|
||||
|
||||
Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
|
||||
try
|
||||
{
|
||||
listener.Bind(localEndPoint);
|
||||
listener.Listen(100);
|
||||
|
||||
while (true)
|
||||
{
|
||||
_allDone.Reset();
|
||||
|
||||
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
|
||||
_allDone.WaitOne();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
//if(_onErrorCallback != null)
|
||||
//{
|
||||
// _onErrorCallback(e.ToString());
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
public static void AcceptCallback(IAsyncResult ar)
|
||||
{
|
||||
_allDone.Set();
|
||||
|
||||
Socket listener = (Socket)ar.AsyncState;
|
||||
Socket handler = listener.EndAccept(ar);
|
||||
|
||||
StateObject state = new StateObject();
|
||||
state._workSocket = handler;
|
||||
handler.BeginReceive(state._buffer, 0, StateObject._bufferSize, 0, new AsyncCallback(ReadCallback), state);
|
||||
}
|
||||
|
||||
public static void ReadCallback(IAsyncResult ar)
|
||||
{
|
||||
String content = String.Empty;
|
||||
|
||||
StateObject state = (StateObject)ar.AsyncState;
|
||||
Socket handler = state._workSocket;
|
||||
|
||||
int bytesRead = handler.EndReceive(ar);
|
||||
|
||||
if (bytesRead > 0)
|
||||
{
|
||||
state._stringBuilder.Append(Encoding.ASCII.GetString(state._buffer, 0, bytesRead));
|
||||
|
||||
content = state._stringBuilder.ToString();
|
||||
if (content.IndexOf(_endOfMessageToken) > -1)
|
||||
{
|
||||
if (_onReadCallback != null)
|
||||
{
|
||||
_onReadCallback(content);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
handler.BeginReceive(state._buffer, 0, StateObject._bufferSize, 0, new AsyncCallback(ReadCallback), state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Send(Socket handler, String data)
|
||||
{
|
||||
byte[] byteData = Encoding.ASCII.GetBytes(data);
|
||||
handler.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), handler);
|
||||
}
|
||||
|
||||
private static void SendCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket handler = (Socket)ar.AsyncState;
|
||||
|
||||
int bytesSent = handler.EndSend(ar);
|
||||
Console.WriteLine("Sent {0} bytes to client.", bytesSent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (_onErrorCallback != null)
|
||||
{
|
||||
_onErrorCallback(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class AsynchronousClient
|
||||
{
|
||||
private const int _port = 6667;
|
||||
|
||||
private static ManualResetEvent connectDone = new ManualResetEvent(false);
|
||||
private static ManualResetEvent sendDone = new ManualResetEvent(false);
|
||||
|
||||
private static String response = String.Empty;
|
||||
|
||||
public static AsynchronousSocketListener.OnReadCallback _onErrorCallback = null;
|
||||
|
||||
public static void Send(string message)
|
||||
{
|
||||
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
|
||||
IPEndPoint remoteEP = new IPEndPoint(ipAddress, _port);
|
||||
|
||||
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
|
||||
IAsyncResult ar = client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client);
|
||||
if (!connectDone.WaitOne(1000))
|
||||
{
|
||||
client.EndConnect(ar);
|
||||
}
|
||||
|
||||
Send(client, message);
|
||||
sendDone.WaitOne();
|
||||
|
||||
client.Shutdown(SocketShutdown.Both);
|
||||
client.Close();
|
||||
}
|
||||
|
||||
private static void ConnectCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket client = (Socket)ar.AsyncState;
|
||||
|
||||
if (client.Connected == false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
client.EndConnect(ar);
|
||||
|
||||
connectDone.Set();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (_onErrorCallback != null)
|
||||
{
|
||||
_onErrorCallback(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void Send(Socket client, String data)
|
||||
{
|
||||
byte[] byteData = Encoding.ASCII.GetBytes(data);
|
||||
|
||||
client.BeginSend(byteData, 0, byteData.Length, 0, new AsyncCallback(SendCallback), client);
|
||||
}
|
||||
|
||||
private static void SendCallback(IAsyncResult ar)
|
||||
{
|
||||
try
|
||||
{
|
||||
Socket client = (Socket)ar.AsyncState;
|
||||
|
||||
int bytesSent = client.EndSend(ar);
|
||||
|
||||
sendDone.Set();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (_onErrorCallback != null)
|
||||
{
|
||||
_onErrorCallback(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// PkgCmdID.cs
|
||||
// MUST match PkgCmdID.h
|
||||
using System;
|
||||
|
||||
namespace SnowForest.CoatiPlugin
|
||||
{
|
||||
static class PkgCmdIDList
|
||||
{
|
||||
public const uint cmdidCoatiSetActiveToken = 0x104;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Resources;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("CoatiPlugin")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Coati Software")]
|
||||
[assembly: AssemblyProduct("CoatiPlugin")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: ComVisible(false)]
|
||||
[assembly: CLSCompliant(false)]
|
||||
[assembly: NeutralResourcesLanguage("en-US")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Revision and Build Numbers
|
||||
// by using the '*' as shown below:
|
||||
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace SnowForest.CoatiPlugin {
|
||||
using System;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources {
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources() {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||
get {
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SnowForest.CoatiPlugin.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
set {
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
VS SDK Notes: This resx file contains the resources that will be consumed directly by your package.
|
||||
For example, if you chose to create a tool window, there is a resource with ID 'CanNotCreateWindow'. This
|
||||
is used in VsPkg.cs to determine the string to show the user if there is an error when attempting to create
|
||||
the tool window.
|
||||
|
||||
Resources that are accessed directly from your package *by Visual Studio* are stored in the VSPackage.resx
|
||||
file.
|
||||
-->
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
@@ -0,0 +1,137 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
VS SDK Notes: This resx file contains the resources that will be consumed from your package by Visual Studio.
|
||||
For example, Visual Studio will attempt to load resource '400' from this resource stream when it needs to
|
||||
load your package's icon. Because Visual Studio will always look in the VSPackage.resources stream first for
|
||||
resources it needs, you should put additional resources that Visual Studio will load directly into this resx
|
||||
file.
|
||||
|
||||
Resources that you would like to access directly from your package in a strong-typed fashion should be stored
|
||||
in Resources.resx or another resx file.
|
||||
-->
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="110" xml:space="preserve">
|
||||
<value>CoatiPlugin</value>
|
||||
</data>
|
||||
<data name="112" xml:space="preserve">
|
||||
<value>Coati plugin test</value>
|
||||
</data>
|
||||
</root>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 73 KiB |
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
|
||||
<Metadata>
|
||||
<Identity Id="acf15780-03b5-440e-a41e-db79b7043fc2" Version="0.1.2" Language="en-US" Publisher="Coati Software" />
|
||||
<DisplayName>CoatiPlugin</DisplayName>
|
||||
<Description xml:space="preserve">This package allows Coati to communicate with Visual Studio and vice versa.</Description>
|
||||
<Icon>coati.ico</Icon>
|
||||
</Metadata>
|
||||
<Installation InstalledByMsi="false">
|
||||
<InstallationTarget Id="Microsoft.VisualStudio.Pro" Version="11.0" />
|
||||
</Installation>
|
||||
<Dependencies>
|
||||
<Dependency Id="Microsoft.Framework.NDP" DisplayName="Microsoft .NET Framework" d:Source="Manual" Version="4.5" />
|
||||
<Dependency Id="Microsoft.VisualStudio.MPF.11.0" DisplayName="Visual Studio MPF 11.0" d:Source="Installed" Version="11.0" />
|
||||
</Dependencies>
|
||||
<Assets>
|
||||
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
|
||||
</Assets>
|
||||
</PackageManifest>
|
||||
+1
-1
@@ -30,7 +30,7 @@ then
|
||||
elif [ "$1" = "package" ] || [ "$1" = "p" ]
|
||||
then
|
||||
ninja package -C build/Release Coati
|
||||
mkdir -p distr && cp build/Release/Coati*.deb distr && cp build/Release/Coati*.tar.gz distr
|
||||
mkdir -p distr && cp build/Release/Coati*.tar.gz distr #&& cp build/Release/Coati*.deb distr
|
||||
echo "Packages copied into the distr folder"
|
||||
else
|
||||
echo "no arguments: first argument 'release' or 'debug', second argument 'test' for tests"
|
||||
|
||||
+28
-19
@@ -6,6 +6,15 @@ INFO="\033[33mInfo:\033[00m"
|
||||
|
||||
echo -e $INFO "Checking index"
|
||||
|
||||
#set branch to commit to
|
||||
if [[ $# -gt 0 ]]
|
||||
then
|
||||
PUBLISH_TO_BRANCH=$1
|
||||
else
|
||||
PUBLISH_TO_BRANCH="master"
|
||||
fi
|
||||
echo -e $INFO "branch to commit: $PUBLISH_TO_BRANCH"
|
||||
|
||||
# check clean index
|
||||
if [[ -n $(git diff HEAD) ]]
|
||||
then
|
||||
@@ -25,44 +34,44 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if on master
|
||||
if [ $BRANCH_NAME == "master" ]
|
||||
# check if on $PUBLISH_TO_BRANCH
|
||||
if [ $BRANCH_NAME == $PUBLISH_TO_BRANCH ]
|
||||
then
|
||||
echo -e $ABORT "You are on master. Use this script only from a feature branch."
|
||||
echo -e $ABORT "You are on $PUBLISH_TO_BRANCH. Use this script only from a feature branch."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
git checkout -q master
|
||||
git checkout -q $PUBLISH_TO_BRANCH
|
||||
git remote update &>/dev/null
|
||||
|
||||
echo -e $INFO "Checking master"
|
||||
echo -e $INFO "Checking $PUBLISH_TO_BRANCH"
|
||||
|
||||
# check if master is up to date
|
||||
if [[ -n $(git diff origin/master) ]]
|
||||
# check if $PUBLISH_TO_BRANCH is up to date
|
||||
if [[ -n $(git diff origin/$PUBLISH_TO_BRANCH) ]]
|
||||
then
|
||||
echo -e $ABORT "Your master is not up-to-date. Run 'git-sync-master.sh' to update master and rebase $BRANCH_NAME."
|
||||
echo -e $ABORT "Your $PUBLISH_TO_BRANCH is not up-to-date. Run 'git-sync.sh' to update $PUBLISH_TO_BRANCH and rebase $BRANCH_NAME."
|
||||
git checkout -q $BRANCH_NAME
|
||||
exit 1
|
||||
fi
|
||||
|
||||
MASTER_HEAD_COMMIT=$(git rev-parse HEAD)
|
||||
BASE_COMMIT=$(git merge-base $BRANCH_NAME master)
|
||||
PUBLIC_BRANCH_HEAD_COMMIT=$(git rev-parse HEAD)
|
||||
BASE_COMMIT=$(git merge-base $BRANCH_NAME $PUBLISH_TO_BRANCH)
|
||||
|
||||
git checkout -q $BRANCH_NAME
|
||||
|
||||
BRANCH_HEAD_COMMIT=$(git rev-parse HEAD)
|
||||
|
||||
# check if feature has commits
|
||||
if [ $BRANCH_HEAD_COMMIT == $MASTER_HEAD_COMMIT ]
|
||||
if [ $BRANCH_HEAD_COMMIT == $PUBLIC_BRANCH_HEAD_COMMIT ]
|
||||
then
|
||||
echo -e $ABORT "Your feature branch has no commits."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check if feature is not behind master
|
||||
if [ $BASE_COMMIT != $MASTER_HEAD_COMMIT ]
|
||||
# check if feature is not behind $PUBLIC_BRANCH_HEAD_COMMIT
|
||||
if [ $BASE_COMMIT != $PUBLIC_BRANCH_HEAD_COMMIT ]
|
||||
then
|
||||
echo -e $ABORT "Your feature branch is behind master. Use 'git rebase master' to update your feature branch."
|
||||
echo -e $ABORT "Your feature branch is behind $PUBLISH_TO_BRANCH. Use 'git rebase $PUBLISH_TO_BRANCH' to update your feature branch."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -87,19 +96,19 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e $INFO "Rebasing on master"
|
||||
git checkout -q master
|
||||
echo -e $INFO "Rebasing on $PUBLISH_TO_BRANCH"
|
||||
git checkout -q $PUBLISH_TO_BRANCH
|
||||
git rebase -q $PUBLISH_BRANCH_NAME
|
||||
git branch -q -d $PUBLISH_BRANCH_NAME
|
||||
|
||||
echo -e $INFO "Uploading to origin master"
|
||||
git push origin master
|
||||
echo -e $INFO "Uploading to origin $PUBLISH_TO_BRANCH"
|
||||
git push origin $PUBLISH_TO_BRANCH
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
git reset --hard -q HEAD^
|
||||
git checkout -q $BRANCH_NAME
|
||||
echo -e $ABORT "Pushing to origin master has failed, there are new remote changes. Run 'git-sync-master.sh' to update master and rebase $BRANCH_NAME."
|
||||
echo -e $ABORT "Pushing to origin $PUBLISH_TO_BRANCH has failed, there are new remote changes. Run 'git-sync.sh' to update $PUBLISH_TO_BRANCH and rebase $BRANCH_NAME."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
ABORT="\033[31mAbort:\033[00m"
|
||||
ALERT="\033[31mAlert:\033[00m"
|
||||
SUCCESS="\033[32mSuccess:\033[00m"
|
||||
INFO="\033[33mInfo:\033[00m"
|
||||
|
||||
BRANCH_NAME=$(git symbolic-ref -q --short HEAD)
|
||||
|
||||
# check if on branch
|
||||
echo -e $INFO "Checking on branch"
|
||||
|
||||
if [ -z $BRANCH_NAME ]
|
||||
then
|
||||
echo -e $ABORT "You are not on any branch."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check clean index
|
||||
echo -e $INFO "Checking index"
|
||||
|
||||
if [[ -n $(git diff HEAD) ]]
|
||||
then
|
||||
echo -e $ABORT "You have uncommited changes."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# switch to master
|
||||
if [ $BRANCH_NAME != 'master' ]
|
||||
then
|
||||
echo -e $INFO "Switching to master"
|
||||
git checkout -q master
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ABORT "Switching to master failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# fetch remote changes
|
||||
echo -e $INFO "Fetching changes"
|
||||
git fetch origin master --tags
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ABORT "Fetching from origin master failed"
|
||||
git checkout -q "$BRANCH_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rebase master to origin/master
|
||||
if [[ -z $(git diff origin/master) ]]
|
||||
then
|
||||
echo -e $SUCCESS "Your master is up-to-date"
|
||||
else
|
||||
echo -e $INFO "Rebasing to origin/master"
|
||||
git rebase origin/master
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ALERT "Rebasing on master caused conflicts. This should never happen. Follow the instructions above to resolve them then use 'git push origin master' to update the remote."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e $SUCCESS "Updated master"
|
||||
fi
|
||||
|
||||
if [ $BRANCH_NAME == 'master' ]
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# switch to branch
|
||||
echo -e $INFO "Switching back to $BRANCH_NAME"
|
||||
git checkout -q "$BRANCH_NAME"
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ABORT "Switching back to $BRANCH_NAME failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rebase branch to master
|
||||
echo -e $INFO "Rebasing $BRANCH_NAME to master"
|
||||
git rebase master
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ALERT "Rebasing $BRANCH_NAME to master caused conflicts. Follow the instructions above to resolve them."
|
||||
exit 1
|
||||
else
|
||||
echo -e $SUCCESS "$BRANCH_NAME is now up-to-date."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Executable
+105
@@ -0,0 +1,105 @@
|
||||
#!/bin/bash
|
||||
|
||||
ABORT="\033[31mAbort:\033[00m"
|
||||
ALERT="\033[31mAlert:\033[00m"
|
||||
SUCCESS="\033[32mSuccess:\033[00m"
|
||||
INFO="\033[33mInfo:\033[00m"
|
||||
|
||||
BRANCH_NAME=$(git symbolic-ref -q --short HEAD)
|
||||
|
||||
#set branch to sync with
|
||||
if [[ $# -gt 0 ]]
|
||||
then
|
||||
SYNC_BRANCH=$1
|
||||
else
|
||||
SYNC_BRANCH="master"
|
||||
fi
|
||||
echo -e $INFO "branch to commit: $SYNC_BRANCH"
|
||||
|
||||
# check if on branch
|
||||
echo -e $INFO "Checking on branch"
|
||||
|
||||
if [ -z $BRANCH_NAME ]
|
||||
then
|
||||
echo -e $ABORT "You are not on any branch."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# check clean index
|
||||
echo -e $INFO "Checking index"
|
||||
|
||||
if [[ -n $(git diff HEAD) ]]
|
||||
then
|
||||
echo -e $ABORT "You have uncommited changes."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# switch to $SYNC_BRANCH
|
||||
if [ $BRANCH_NAME != '$SYNC_BRANCH' ]
|
||||
then
|
||||
echo -e $INFO "Switching to $SYNC_BRANCH"
|
||||
git checkout -q $SYNC_BRANCH
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ABORT "Switching to $SYNC_BRANCH failed."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# fetch remote changes
|
||||
echo -e $INFO "Fetching changes"
|
||||
git fetch origin $SYNC_BRANCH --tags
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ABORT "Fetching from origin $SYNC_BRANCH failed"
|
||||
git checkout -q "$BRANCH_NAME"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rebase $SYNC_BRANCH to origin/$SYNC_BRANCH
|
||||
if [[ -z $(git diff origin/$SYNC_BRANCH) ]]
|
||||
then
|
||||
echo -e $SUCCESS "Your $SYNC_BRANCH is up-to-date"
|
||||
else
|
||||
echo -e $INFO "Rebasing to origin/$SYNC_BRANCH"
|
||||
git rebase origin/$SYNC_BRANCH
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ALERT "Rebasing on $SYNC_BRANCH caused conflicts. This should never happen. Follow the instructions above to resolve them then use 'git push origin master' to update the remote."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e $SUCCESS "Updated $SYNC_BRANCH"
|
||||
fi
|
||||
|
||||
if [ $BRANCH_NAME == '$SYNC_BRANCH' ]
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# switch to branch
|
||||
echo -e $INFO "Switching back to $BRANCH_NAME"
|
||||
git checkout -q "$BRANCH_NAME"
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ABORT "Switching back to $BRANCH_NAME failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rebase branch to $SYNC_BRANCH
|
||||
echo -e $INFO "Rebasing $BRANCH_NAME to $SYNC_BRANCH"
|
||||
git rebase $SYNC_BRANCH
|
||||
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo -e $ALERT "Rebasing $BRANCH_NAME to $SYNC_BRANCH caused conflicts. Follow the instructions above to resolve them."
|
||||
exit 1
|
||||
else
|
||||
echo -e $SUCCESS "$BRANCH_NAME is now up-to-date."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,80 @@
|
||||
#!/bin/bash
|
||||
|
||||
ABORT="\033[31mAbort:\033[00m"
|
||||
SUCCESS="\033[32mSuccess:\033[00m"
|
||||
INFO="\033[33mInfo:\033[00m"
|
||||
|
||||
read -r -p "Is your current release build up to date? [y/N] " response
|
||||
case $response in
|
||||
[yY][eE][sS]|[yY])
|
||||
;;
|
||||
*)
|
||||
echo -e $ABORT "Aborting the creation of a release package."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
ORIGINAL_PATH_TO_SCRIPT="${0}"
|
||||
CLEANED_PATH_TO_SCRIPT="${ORIGINAL_PATH_TO_SCRIPT//\\//}"
|
||||
BASE_DIR=`dirname "$CLEANED_PATH_TO_SCRIPT"`
|
||||
|
||||
cd $BASE_DIR/..
|
||||
|
||||
VERSION_STRING=$(git describe)
|
||||
VERSION_STRING="${VERSION_STRING//-/_}"
|
||||
VERSION_STRING="${VERSION_STRING//./_}"
|
||||
VERSION_STRING="${VERSION_STRING%_*}"
|
||||
|
||||
PACKAGE_NAME=Coati_${VERSION_STRING}_windows
|
||||
|
||||
echo -e $INFO Creating Package with Name: $PACKAGE_NAME
|
||||
|
||||
PACKAGE_DIR=release/$PACKAGE_NAME
|
||||
|
||||
|
||||
echo -e $INFO Creating Folders
|
||||
rm -rf $PACKAGE_DIR
|
||||
mkdir -p $PACKAGE_DIR
|
||||
|
||||
mkdir -p $PACKAGE_DIR/data/color_schemes/
|
||||
cp -u -r bin/app/data/color_schemes/* $PACKAGE_DIR/data/color_schemes/
|
||||
mkdir -p $PACKAGE_DIR/data/fonts/
|
||||
cp -u -r bin/app/data/fonts/* $PACKAGE_DIR/data/fonts/
|
||||
mkdir -p $PACKAGE_DIR/data/gui/
|
||||
cp -u -r bin/app/data/gui/* $PACKAGE_DIR/data/gui/
|
||||
mkdir -p $PACKAGE_DIR/data/log/
|
||||
mkdir -p $PACKAGE_DIR/data/projects/tutorial/src/
|
||||
cp -u -r bin/app/data/projects/tutorial/src/* $PACKAGE_DIR/data/projects/tutorial/src/
|
||||
cp -u -r bin/app/data/projects/tutorial/tutorial.xml $PACKAGE_DIR/data/projects/tutorial/
|
||||
mkdir -p $PACKAGE_DIR/data/projects/tictactoe/src/
|
||||
cp -u -r bin/app/data/projects/tictactoe/src/* $PACKAGE_DIR/data/projects/tictactoe/src/
|
||||
cp -u -r bin/app/data/projects/tictactoe/tictactoe.xml $PACKAGE_DIR/data/projects/tictactoe/
|
||||
|
||||
cp -u -r bin/app/data/ApplicationSettings_for_package.xml $PACKAGE_DIR/data/ApplicationSettings.xml
|
||||
cp -u -r bin/app/data/window_settings.ini $PACKAGE_DIR/data/
|
||||
|
||||
mkdir -p $PACKAGE_DIR/plugins/visual_studio/
|
||||
cp -u -r ide_plugins/vs/coati_plugin_vs_2012.vsix $PACKAGE_DIR/plugins/visual_studio/
|
||||
cp -u -r ide_plugins/vs/coati_plugin_vs_2013.vsix $PACKAGE_DIR/plugins/visual_studio/
|
||||
cp -u -r ide_plugins/vs/coati_plugin_vs_2015.vsix $PACKAGE_DIR/plugins/visual_studio/
|
||||
mkdir -p $PACKAGE_DIR/plugins/sublime_text/
|
||||
cp -u -r ide_plugins/sublime_text/* $PACKAGE_DIR/plugins/sublime_text/
|
||||
|
||||
cp -u -r web/coati_manual.pdf $PACKAGE_DIR/
|
||||
cp -u -r bin/app/Release/Coati.exe $PACKAGE_DIR/
|
||||
cp -u -r setup/dynamic_libraries/windows/app/Release/* $PACKAGE_DIR/
|
||||
|
||||
|
||||
echo -e $INFO Obfuscation Executable
|
||||
#upx --brute $PACKAGE_DIR/Coati.exe
|
||||
|
||||
echo -e $INFO Packaging Coati
|
||||
cd ./release/
|
||||
winrar a -afzip $PACKAGE_NAME.zip $PACKAGE_NAME
|
||||
cd ../
|
||||
|
||||
|
||||
echo -e $INFO Cleaning up
|
||||
rm -rf $PACKAGE_DIR
|
||||
|
||||
echo -e $SUCCESS Packaging Complete!
|
||||
@@ -1,9 +1,11 @@
|
||||
#!/bin/sh
|
||||
COATI_PATH=`dirname "$0"`
|
||||
|
||||
if [ ! -d "${HOME}/.config/coati" ]; then
|
||||
# Control will enter here if $DIRECTORY doesn't exist.
|
||||
cp -r /usr/local/share/coati/.config/coati ${HOME}/.config/coati
|
||||
cp -r $COATI_PATH/coati/data ${HOME}/.config/coati
|
||||
echo "First start of Coati from this user, copy default configfiles to ~/.config/coati"
|
||||
fi
|
||||
|
||||
export LD_LIBRARY_PATH=/usr/local/share/coati/lib
|
||||
cd ~/.config/coati && exec /usr/local/share/coati/Coati
|
||||
export LD_LIBRARY_PATH=$COATI_PATH/coati/lib
|
||||
cd ~/.config/coati && exec $COATI_PAT/coati/Coati
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>at.ac.fh-salzburg.masterproject</string>
|
||||
<string>io.coati</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
@@ -37,6 +37,6 @@
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>icon</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>10.10</string>
|
||||
<string>10.9</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
Binary file not shown.
+5
-2
@@ -5,6 +5,7 @@
|
||||
#include "utility/logging/ConsoleLogger.h"
|
||||
#include "utility/logging/FileLogger.h"
|
||||
#include "utility/logging/LogManager.h"
|
||||
#include "utility/Version.h"
|
||||
|
||||
#include "Application.h"
|
||||
#include "includes.h" // defines 'void setup(int argc, char *argv[])'
|
||||
@@ -31,6 +32,8 @@ void init()
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
Version version = Version::fromString(GIT_VERSION_NUMBER);
|
||||
|
||||
setup(argc, argv);
|
||||
QApplication qtApp(argc, argv);
|
||||
|
||||
@@ -41,7 +44,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
QtSplashScreen* splash = new QtSplashScreen(whitePixmap, Qt::WindowStaysOnTopHint);
|
||||
splash->setMessage("Loading UI");
|
||||
splash->setVersion(GIT_VERSION_NUMBER);
|
||||
splash->setVersion(version.toDisplayString().c_str());
|
||||
splash->exec(qtApp);
|
||||
|
||||
init();
|
||||
@@ -49,7 +52,7 @@ int main(int argc, char *argv[])
|
||||
QtViewFactory viewFactory;
|
||||
QtNetworkFactory networkFactory;
|
||||
|
||||
std::shared_ptr<Application> app = Application::create(&viewFactory, &networkFactory);
|
||||
std::shared_ptr<Application> app = Application::create(version, &viewFactory, &networkFactory);
|
||||
|
||||
if (splash)
|
||||
{
|
||||
|
||||
+376
-152
@@ -1,7 +1,9 @@
|
||||
#include "qt/element/QtCodeArea.h"
|
||||
|
||||
#include <qapplication.h>
|
||||
#include <QFont>
|
||||
#include <QHBoxLayout>
|
||||
#include <qmenu.h>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QToolTip>
|
||||
@@ -11,6 +13,7 @@
|
||||
#include "utility/messaging/type/MessageShowFile.h"
|
||||
#include "utility/messaging/type/MessageFocusIn.h"
|
||||
#include "utility/messaging/type/MessageFocusOut.h"
|
||||
#include "utility/messaging/type/MessageMoveIDECursor.h"
|
||||
#include "utility/utility.h"
|
||||
|
||||
#include "data/location/TokenLocation.h"
|
||||
@@ -21,6 +24,33 @@
|
||||
#include "settings/ApplicationSettings.h"
|
||||
#include "settings/ColorScheme.h"
|
||||
|
||||
std::vector<QtCodeArea::AnnotationColor> QtCodeArea::s_annotationColors;
|
||||
|
||||
MouseWheelOverScrollbarFilter::MouseWheelOverScrollbarFilter(QObject* parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool MouseWheelOverScrollbarFilter::eventFilter(QObject* obj, QEvent* event)
|
||||
{
|
||||
QScrollBar* scrollbar = dynamic_cast<QScrollBar*>(obj);
|
||||
if (event->type() == QEvent::Wheel && scrollbar)
|
||||
{
|
||||
QRect scrollbarArea(scrollbar->pos(), scrollbar->size());
|
||||
QPoint globalMousePos = dynamic_cast<QWheelEvent*>(event)->globalPos();
|
||||
QPoint localMousePos = scrollbar->mapFromGlobal(globalMousePos);
|
||||
|
||||
// instead of "scrollbar->underMouse()" we need this check implemented here because "underMouse()"
|
||||
// does not work when the mouse enters the area without being moved
|
||||
if (scrollbarArea.contains(localMousePos))
|
||||
{
|
||||
event->ignore();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return QObject::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
QtCodeArea::LineNumberArea::LineNumberArea(QtCodeArea *codeArea)
|
||||
: QWidget(codeArea)
|
||||
, m_codeArea(codeArea)
|
||||
@@ -42,6 +72,10 @@ void QtCodeArea::LineNumberArea::paintEvent(QPaintEvent *event)
|
||||
m_codeArea->lineNumberAreaPaintEvent(event);
|
||||
}
|
||||
|
||||
void QtCodeArea::clearAnnotationColors()
|
||||
{
|
||||
s_annotationColors.clear();
|
||||
}
|
||||
|
||||
QtCodeArea::QtCodeArea(
|
||||
uint startLineNumber,
|
||||
@@ -54,9 +88,11 @@ QtCodeArea::QtCodeArea(
|
||||
, m_fileWidget(file)
|
||||
, m_startLineNumber(startLineNumber)
|
||||
, m_locationFile(locationFile)
|
||||
, m_hoveredAnnotation(nullptr)
|
||||
, m_digits(0)
|
||||
, m_panningValue(-1)
|
||||
, m_setIDECursorPositionAction(nullptr)
|
||||
, m_eventPosition(0, 0)
|
||||
, m_isActiveFile(false)
|
||||
{
|
||||
setObjectName("code_area");
|
||||
setReadOnly(true);
|
||||
@@ -85,10 +121,20 @@ QtCodeArea::QtCodeArea(
|
||||
connect(this, SIGNAL(selectionChanged()), this, SLOT(clearSelection()));
|
||||
|
||||
this->setMouseTracking(true);
|
||||
|
||||
// MouseWheelOverScrollbarFilter is deleted by parent.
|
||||
horizontalScrollBar()->installEventFilter(new MouseWheelOverScrollbarFilter(this));
|
||||
|
||||
createActions();
|
||||
}
|
||||
|
||||
QtCodeArea::~QtCodeArea()
|
||||
{
|
||||
if (m_setIDECursorPositionAction != nullptr)
|
||||
{
|
||||
m_setIDECursorPositionAction->disconnect();
|
||||
delete m_setIDECursorPositionAction;
|
||||
}
|
||||
}
|
||||
|
||||
QSize QtCodeArea::sizeHint() const
|
||||
@@ -134,12 +180,23 @@ void QtCodeArea::lineNumberAreaPaintEvent(QPaintEvent *event)
|
||||
int top = static_cast<int>(blockBoundingGeometry(block).translated(contentOffset()).top());
|
||||
int bottom = top + static_cast<int>(blockBoundingRect(block).height());
|
||||
|
||||
std::set<int> activeLineNumbers = getActiveLineNumbers();
|
||||
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
QColor backgroundColor(scheme->getColor("code/snippet/line_number/background").c_str());
|
||||
backgroundColor.setAlpha(150);
|
||||
|
||||
while (block.isValid() && top <= event->rect().bottom())
|
||||
{
|
||||
if (block.isVisible() && bottom >= event->rect().top())
|
||||
{
|
||||
QString number = QString::number(blockNumber + m_startLineNumber);
|
||||
painter.drawText(0, top, m_lineNumberArea->width() - 13, fontMetrics().height(), Qt::AlignRight, number);
|
||||
int number = blockNumber + m_startLineNumber;
|
||||
painter.drawText(0, top, m_lineNumberArea->width() - 13, fontMetrics().height(), Qt::AlignRight, QString::number(number));
|
||||
|
||||
if (!m_isActiveFile && activeLineNumbers.find(number) == activeLineNumbers.end())
|
||||
{
|
||||
painter.fillRect(0, top, m_lineNumberArea->width(), fontMetrics().height(), backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
block = block.next();
|
||||
@@ -186,6 +243,27 @@ bool QtCodeArea::isActive() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void QtCodeArea::setIsActiveFile(bool isActiveFile)
|
||||
{
|
||||
m_isActiveFile = isActiveFile;
|
||||
}
|
||||
|
||||
QRectF QtCodeArea::getFirstActiveLineRect() const
|
||||
{
|
||||
int lineNumber = 0;
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
if (annotation.isActive)
|
||||
{
|
||||
lineNumber = annotation.startLine;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QTextBlock block = document()->findBlockByLineNumber(lineNumber - m_startLineNumber);
|
||||
return blockBoundingGeometry(block);
|
||||
}
|
||||
|
||||
void QtCodeArea::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QPlainTextEdit::resizeEvent(e);
|
||||
@@ -209,22 +287,50 @@ void QtCodeArea::paintEvent(QPaintEvent* event)
|
||||
QTextBlock block = firstVisibleBlock();
|
||||
int top = blockBoundingGeometry(block).translated(contentOffset()).top();
|
||||
int blockHeight = blockBoundingRect(block).height();
|
||||
int borderRadius = 3;
|
||||
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
|
||||
QColor scopeColor(scheme->getColor("code/snippet/highlight/scope/normal").c_str());
|
||||
QColor activeScopeColor(scheme->getColor("code/snippet/highlight/scope/hover").c_str());
|
||||
|
||||
for (const ScopeAnnotation& scope : m_scopeAnnotations)
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
painter.fillRect(
|
||||
0, top + scope.startLine * blockHeight,
|
||||
width(), (scope.endLine - scope.startLine + 1) * blockHeight,
|
||||
(scope.isFocused || scope.startLine == scope.endLine) ? activeScopeColor : scopeColor
|
||||
);
|
||||
const AnnotationColor& color = getAnnotationColorForAnnotation(annotation);
|
||||
|
||||
painter.setPen(QPen(color.border.c_str()));
|
||||
painter.setBrush(QBrush(color.fill.c_str()));
|
||||
|
||||
if (annotation.isScope)
|
||||
{
|
||||
painter.drawRoundedRect(
|
||||
0, top + (annotation.startLine - m_startLineNumber) * blockHeight,
|
||||
width(), (annotation.endLine - annotation.startLine + 1) * blockHeight,
|
||||
borderRadius, borderRadius
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<QRect> rects = getCursorRectsForAnnotation(annotation);
|
||||
for (QRect rect : rects)
|
||||
{
|
||||
rect.adjust(-1, 0, 1, 1);
|
||||
painter.drawRoundedRect(rect, borderRadius, borderRadius);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QPlainTextEdit::paintEvent(event);
|
||||
|
||||
QPainter painter2(viewport());
|
||||
std::set<int> activeLineNumbers = getActiveLineNumbers();
|
||||
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
QColor backgroundColor(scheme->getColor("code/snippet/background").c_str());
|
||||
backgroundColor.setAlpha(75);
|
||||
|
||||
for (int i = 0; i < document()->blockCount(); i++)
|
||||
{
|
||||
if (!m_isActiveFile && activeLineNumbers.find(i + m_startLineNumber) == activeLineNumbers.end())
|
||||
{
|
||||
painter.fillRect(0, top + i * blockHeight, width(), blockHeight, backgroundColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeArea::enterEvent(QEvent* event)
|
||||
@@ -233,7 +339,7 @@ void QtCodeArea::enterEvent(QEvent* event)
|
||||
|
||||
void QtCodeArea::leaveEvent(QEvent* event)
|
||||
{
|
||||
setHoveredAnnotation(nullptr);
|
||||
setHoveredAnnotations(std::vector<const Annotation*>());
|
||||
}
|
||||
|
||||
void QtCodeArea::mousePressEvent(QMouseEvent* event)
|
||||
@@ -249,12 +355,21 @@ void QtCodeArea::mouseReleaseEvent(QMouseEvent* event)
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
m_panningValue = -1;
|
||||
QTextCursor cursor = this->cursorForPosition(event->pos());
|
||||
std::vector<Id> locationIds = findLocationIdsForPosition(cursor.position());
|
||||
|
||||
if (locationIds.size())
|
||||
if (Qt::KeyboardModifier::ControlModifier && QApplication::keyboardModifiers())
|
||||
{
|
||||
MessageActivateTokenLocations(locationIds).dispatch();
|
||||
// std::pair<int, int> lineColumn = toLineColumn(this->cursorForPosition(event->pos()).position());
|
||||
m_eventPosition = event->pos();
|
||||
setIDECursorPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
QTextCursor cursor = this->cursorForPosition(event->pos());
|
||||
std::vector<Id> locationIds = findLocationIdsForPosition(cursor.position());
|
||||
if (locationIds.size() && !m_fileWidget->getErrorMessages().size())
|
||||
{
|
||||
MessageActivateTokenLocations(locationIds).dispatch();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -263,13 +378,13 @@ void QtCodeArea::mouseDoubleClickEvent(QMouseEvent* event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton)
|
||||
{
|
||||
MessageShowFile(m_fileWidget->getFilePath().str(), m_startLineNumber, m_startLineNumber + blockCount() - 1).dispatch();
|
||||
MessageShowFile(m_fileWidget->getFilePath().str(), (m_fileWidget->getErrorMessages().size() > 0)).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeArea::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
if (m_panningValue!= -1)
|
||||
if (m_panningValue != -1)
|
||||
{
|
||||
int panningCurrentPosition = event->pos().x();
|
||||
int deltaPos = panningCurrentPosition - m_panningValue;
|
||||
@@ -283,30 +398,44 @@ void QtCodeArea::mouseMoveEvent(QMouseEvent* event)
|
||||
|
||||
|
||||
QTextCursor cursor = this->cursorForPosition(event->pos());
|
||||
std::vector<const Annotation*> annotations = getAnnotationsForPosition(cursor.position());
|
||||
|
||||
m_hoveredLocationIds = findLocationIdsForPosition(cursor.position());
|
||||
const Annotation* annotation = findAnnotationForPosition(cursor.position());
|
||||
|
||||
if (annotation && annotation->isScope)
|
||||
bool same = annotations.size() == m_hoveredAnnotations.size();
|
||||
if (same)
|
||||
{
|
||||
annotation = nullptr;
|
||||
for (size_t i = 0; i < annotations.size(); i++)
|
||||
{
|
||||
if (annotations[i] != m_hoveredAnnotations[i])
|
||||
{
|
||||
same = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QToolTip::hideText();
|
||||
|
||||
if (annotation != m_hoveredAnnotation)
|
||||
if (!same)
|
||||
{
|
||||
setHoveredAnnotation(annotation);
|
||||
setHoveredAnnotations(annotations);
|
||||
|
||||
const std::vector<std::string>& errorMessages = m_fileWidget->getErrorMessages();
|
||||
if (annotation && errorMessages.size() > annotation->tokenId)
|
||||
if (annotations.size() == 1 && errorMessages.size() > annotations[0]->tokenId)
|
||||
{
|
||||
QToolTip::showText(event->globalPos(), QString::fromStdString(errorMessages[annotation->tokenId]));
|
||||
QToolTip::showText(event->globalPos(), QString::fromStdString(errorMessages[annotations[0]->tokenId]));
|
||||
}
|
||||
}
|
||||
else if (m_hoveredLocationIds.size())
|
||||
}
|
||||
|
||||
void QtCodeArea::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
if (m_setIDECursorPositionAction != nullptr)
|
||||
{
|
||||
updateContent();
|
||||
m_eventPosition = event->pos();
|
||||
|
||||
QMenu menu(this);
|
||||
menu.addAction(m_setIDECursorPositionAction);
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,38 +468,11 @@ void QtCodeArea::clearSelection()
|
||||
setTextCursor(cursor);
|
||||
}
|
||||
|
||||
QtCodeArea::ScopeAnnotation::ScopeAnnotation()
|
||||
: startLine(0)
|
||||
, endLine(0)
|
||||
, tokenId(0)
|
||||
, isFocused(false)
|
||||
void QtCodeArea::setIDECursorPosition()
|
||||
{
|
||||
}
|
||||
std::pair<int, int> lineColumn = toLineColumn(this->cursorForPosition(m_eventPosition).position());
|
||||
|
||||
bool QtCodeArea::ScopeAnnotation::operator!=(const ScopeAnnotation& other) const
|
||||
{
|
||||
return (startLine != other.startLine || endLine != other.endLine || tokenId != other.tokenId || isFocused != other.isFocused);
|
||||
}
|
||||
|
||||
const QtCodeArea::Annotation* QtCodeArea::findAnnotationForPosition(int pos) const
|
||||
{
|
||||
const Annotation* annotationPtr = nullptr;
|
||||
int diff = endTextEditPosition() + 1;
|
||||
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
if (pos >= annotation.start && pos <= annotation.end)
|
||||
{
|
||||
int d = annotation.end - annotation.start;
|
||||
if (d < diff)
|
||||
{
|
||||
diff = d;
|
||||
annotationPtr = &annotation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return annotationPtr;
|
||||
MessageMoveIDECursor(m_locationFile->getFilePath().str(), lineColumn.first, lineColumn.second).dispatch();
|
||||
}
|
||||
|
||||
std::vector<Id> QtCodeArea::findLocationIdsForPosition(int pos) const
|
||||
@@ -388,6 +490,21 @@ std::vector<Id> QtCodeArea::findLocationIdsForPosition(int pos) const
|
||||
return locationIds;
|
||||
}
|
||||
|
||||
std::vector<const QtCodeArea::Annotation*> QtCodeArea::getAnnotationsForPosition(int pos) const
|
||||
{
|
||||
std::vector<const QtCodeArea::Annotation*> annotations;
|
||||
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
if (!annotation.isScope && pos >= annotation.start && pos <= annotation.end)
|
||||
{
|
||||
annotations.push_back(&annotation);
|
||||
}
|
||||
}
|
||||
|
||||
return annotations;
|
||||
}
|
||||
|
||||
void QtCodeArea::createAnnotations(std::shared_ptr<TokenLocationFile> locationFile)
|
||||
{
|
||||
locationFile->forEachStartTokenLocation(
|
||||
@@ -400,10 +517,14 @@ void QtCodeArea::createAnnotations(std::shared_ptr<TokenLocationFile> locationFi
|
||||
if (startLocation->getLineNumber() < m_startLineNumber)
|
||||
{
|
||||
annotation.start = startTextEditPosition();
|
||||
annotation.startLine = m_startLineNumber;
|
||||
annotation.startCol = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
annotation.start = toTextEditPosition(startLocation->getLineNumber(), startLocation->getColumnNumber() - 1);
|
||||
annotation.startLine = startLocation->getLineNumber();
|
||||
annotation.startCol = startLocation->getColumnNumber() - 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -417,10 +538,14 @@ void QtCodeArea::createAnnotations(std::shared_ptr<TokenLocationFile> locationFi
|
||||
if (endLocation->getLineNumber() > endLineNumber)
|
||||
{
|
||||
annotation.end = endTextEditPosition();
|
||||
annotation.endLine = endLineNumber;
|
||||
annotation.endCol = document()->findBlockByLineNumber(document()->blockCount() - 1).length();
|
||||
}
|
||||
else
|
||||
{
|
||||
annotation.end = toTextEditPosition(endLocation->getLineNumber(), endLocation->getColumnNumber());
|
||||
annotation.endLine = endLocation->getLineNumber();
|
||||
annotation.endCol = endLocation->getColumnNumber();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -430,7 +555,13 @@ void QtCodeArea::createAnnotations(std::shared_ptr<TokenLocationFile> locationFi
|
||||
|
||||
annotation.tokenId = startLocation->getTokenId();
|
||||
annotation.locationId = startLocation->getId();
|
||||
|
||||
annotation.isScope = (startLocation->getType() == TokenLocation::LOCATION_SCOPE);
|
||||
annotation.isError = false;
|
||||
|
||||
annotation.isActive = false;
|
||||
annotation.isFocused = false;
|
||||
|
||||
m_annotations.push_back(annotation);
|
||||
}
|
||||
);
|
||||
@@ -438,117 +569,59 @@ void QtCodeArea::createAnnotations(std::shared_ptr<TokenLocationFile> locationFi
|
||||
|
||||
void QtCodeArea::annotateText()
|
||||
{
|
||||
Id focusedTokenId = m_fileWidget->getFocusedTokenId();
|
||||
const std::vector<Id>& activeIds = m_fileWidget->getActiveTokenIds();
|
||||
const std::vector<Id>& hoverIds = m_hoveredLocationIds;
|
||||
const std::vector<std::string>& errorMessages = m_fileWidget->getErrorMessages();
|
||||
const std::vector<Id>& focusIds = m_fileWidget->getFocusedTokenIds();
|
||||
|
||||
std::vector<ScopeAnnotation> scopeAnnotations;
|
||||
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
|
||||
QColor locationColor(scheme->getColor("code/snippet/highlight/location/normal").c_str());
|
||||
QColor activeLocationColor(scheme->getColor("code/snippet/highlight/location/hover").c_str());
|
||||
|
||||
QColor errorColor(scheme->getColor("code/snippet/highlight/error/normal").c_str());
|
||||
QColor activeErrorColor(scheme->getColor("code/snippet/highlight/error/hover").c_str());
|
||||
|
||||
QList<QTextEdit::ExtraSelection> extraSelections;
|
||||
|
||||
for (const Annotation& annotation: m_annotations)
|
||||
{
|
||||
bool isActive = std::find(activeIds.begin(), activeIds.end(), annotation.tokenId) != activeIds.end();
|
||||
bool isHovered = std::find(hoverIds.begin(), hoverIds.end(), annotation.locationId) != hoverIds.end();
|
||||
bool isFocused = (annotation.tokenId == focusedTokenId);
|
||||
|
||||
QColor color;
|
||||
if (isHovered && errorMessages.size())
|
||||
{
|
||||
color = activeErrorColor;
|
||||
}
|
||||
else if (errorMessages.size())
|
||||
{
|
||||
color = errorColor;
|
||||
}
|
||||
else if (isActive || isFocused || isHovered)
|
||||
{
|
||||
color = activeLocationColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = locationColor;
|
||||
}
|
||||
|
||||
QTextEdit::ExtraSelection selection;
|
||||
selection.format.setBackground(color);
|
||||
|
||||
ScopeAnnotation scopeAnnotation;
|
||||
|
||||
selection.cursor = textCursor();
|
||||
selection.cursor.clearSelection();
|
||||
selection.cursor.setPosition(annotation.start);
|
||||
scopeAnnotation.startLine = selection.cursor.blockNumber();
|
||||
selection.cursor.setPosition(annotation.end, QTextCursor::KeepAnchor);
|
||||
scopeAnnotation.endLine = selection.cursor.blockNumber();
|
||||
|
||||
if (annotation.isScope || (isActive && activeIds.size() == 1))
|
||||
{
|
||||
if (isActive || isFocused)
|
||||
{
|
||||
scopeAnnotation.tokenId = annotation.tokenId;
|
||||
if (!isActive)
|
||||
{
|
||||
scopeAnnotation.isFocused = isFocused;
|
||||
}
|
||||
scopeAnnotations.push_back(scopeAnnotation);
|
||||
}
|
||||
}
|
||||
|
||||
if (!annotation.isScope || (isActive && activeIds.size() == 1 && scopeAnnotation.startLine == scopeAnnotation.endLine))
|
||||
{
|
||||
extraSelections.append(selection);
|
||||
}
|
||||
}
|
||||
|
||||
setExtraSelections(extraSelections);
|
||||
bool isError = m_fileWidget->getErrorMessages().size() > 0;
|
||||
|
||||
bool needsUpdate = false;
|
||||
if (scopeAnnotations.size() != m_scopeAnnotations.size())
|
||||
for (Annotation& annotation: m_annotations)
|
||||
{
|
||||
needsUpdate = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < scopeAnnotations.size(); i++)
|
||||
bool wasActive = annotation.isActive;
|
||||
bool wasFocused = annotation.isFocused;
|
||||
|
||||
annotation.isActive = std::find(activeIds.begin(), activeIds.end(), annotation.tokenId) != activeIds.end();
|
||||
annotation.isFocused = std::find(focusIds.begin(), focusIds.end(), annotation.tokenId) != focusIds.end();
|
||||
|
||||
annotation.isError = isError;
|
||||
|
||||
if (wasFocused != annotation.isFocused || wasActive != annotation.isActive)
|
||||
{
|
||||
if (scopeAnnotations[i] != m_scopeAnnotations[i])
|
||||
{
|
||||
needsUpdate = true;
|
||||
break;
|
||||
}
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
m_scopeAnnotations = scopeAnnotations;
|
||||
|
||||
if (needsUpdate)
|
||||
{
|
||||
m_lineNumberArea->update();
|
||||
viewport()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeArea::setHoveredAnnotation(const Annotation* annotation)
|
||||
void QtCodeArea::setHoveredAnnotations(const std::vector<const Annotation*>& annotations)
|
||||
{
|
||||
if (m_hoveredAnnotation)
|
||||
if (m_hoveredAnnotations.size())
|
||||
{
|
||||
MessageFocusOut(m_hoveredAnnotation->tokenId).dispatch();
|
||||
std::vector<Id> tokenIds;
|
||||
for (const Annotation* annotation : m_hoveredAnnotations)
|
||||
{
|
||||
tokenIds.push_back(annotation->tokenId);
|
||||
}
|
||||
|
||||
MessageFocusOut(tokenIds).dispatch();
|
||||
}
|
||||
|
||||
m_hoveredAnnotation = annotation;
|
||||
m_hoveredAnnotations = annotations;
|
||||
|
||||
if (annotation)
|
||||
if (annotations.size())
|
||||
{
|
||||
MessageFocusIn(annotation->tokenId).dispatch();
|
||||
std::vector<Id> tokenIds;
|
||||
for (const Annotation* annotation : annotations)
|
||||
{
|
||||
tokenIds.push_back(annotation->tokenId);
|
||||
}
|
||||
|
||||
MessageFocusIn(tokenIds).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,6 +639,25 @@ int QtCodeArea::toTextEditPosition(int lineNumber, int columnNumber) const
|
||||
return position;
|
||||
}
|
||||
|
||||
std::pair<int, int> QtCodeArea::toLineColumn(int textEditPosition) const
|
||||
{
|
||||
int lineNumber = m_startLineNumber;
|
||||
for (int i = 0; i < document()->lineCount(); i++)
|
||||
{
|
||||
int nextTextEditPosition = textEditPosition - document()->findBlockByLineNumber(i).length();
|
||||
if (nextTextEditPosition >= 0)
|
||||
{
|
||||
textEditPosition = nextTextEditPosition;
|
||||
lineNumber++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
return std::make_pair(lineNumber, textEditPosition);
|
||||
}
|
||||
|
||||
int QtCodeArea::startTextEditPosition() const
|
||||
{
|
||||
return 0;
|
||||
@@ -582,3 +674,135 @@ int QtCodeArea::endTextEditPosition() const
|
||||
|
||||
return position - 1;
|
||||
}
|
||||
|
||||
std::set<int> QtCodeArea::getActiveLineNumbers() const
|
||||
{
|
||||
std::set<int> activeLineNumbers;
|
||||
|
||||
if (m_isActiveFile)
|
||||
{
|
||||
return activeLineNumbers;
|
||||
}
|
||||
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
if (annotation.isActive)
|
||||
{
|
||||
for (int i = annotation.startLine; i <= annotation.endLine; i++)
|
||||
{
|
||||
activeLineNumbers.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (activeLineNumbers.size())
|
||||
{
|
||||
for (const Annotation& annotation : m_annotations)
|
||||
{
|
||||
if (annotation.isFocused)
|
||||
{
|
||||
for (int i = annotation.startLine; i <= annotation.endLine; i++)
|
||||
{
|
||||
activeLineNumbers.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return activeLineNumbers;
|
||||
}
|
||||
|
||||
std::vector<QRect> QtCodeArea::getCursorRectsForAnnotation(const Annotation& annotation) const
|
||||
{
|
||||
std::vector<QRect> rects;
|
||||
|
||||
QTextCursor cursor = textCursor();
|
||||
cursor.clearSelection();
|
||||
cursor.setPosition(annotation.start);
|
||||
QRect rectStart = cursorRect(cursor);
|
||||
QRect rectEnd;
|
||||
|
||||
int line = annotation.startLine;
|
||||
while (line <= annotation.endLine)
|
||||
{
|
||||
if (line == annotation.endLine)
|
||||
{
|
||||
cursor.setPosition(annotation.end);
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor.setPosition(toTextEditPosition(line, document()->findBlockByLineNumber(line - m_startLineNumber).length() - 1));
|
||||
}
|
||||
|
||||
rectEnd = cursorRect(cursor);
|
||||
rects.push_back(QRect(rectStart.left(), rectStart.top(), rectEnd.right() - rectStart.left(), rectEnd.bottom() - rectStart.top()));
|
||||
|
||||
line++;
|
||||
|
||||
if (int(line - m_startLineNumber) < document()->blockCount())
|
||||
{
|
||||
cursor.setPosition(toTextEditPosition(line, 0));
|
||||
rectStart = cursorRect(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
return rects;
|
||||
}
|
||||
|
||||
const QtCodeArea::AnnotationColor& QtCodeArea::getAnnotationColorForAnnotation(const Annotation& annotation)
|
||||
{
|
||||
if (!s_annotationColors.size())
|
||||
{
|
||||
ColorScheme* scheme = ColorScheme::getInstance().get();
|
||||
std::vector<std::string> types;
|
||||
types.push_back("location");
|
||||
types.push_back("scope");
|
||||
types.push_back("error");
|
||||
|
||||
std::vector<std::string> states;
|
||||
states.push_back("normal");
|
||||
states.push_back("focus");
|
||||
states.push_back("active");
|
||||
|
||||
for (const std::string& type : types)
|
||||
{
|
||||
for (const std::string& state : states)
|
||||
{
|
||||
AnnotationColor color;
|
||||
color.border = scheme->getColor("code/snippet/selection/" + type + "/" + state + "/border");
|
||||
color.fill = scheme->getColor("code/snippet/selection/" + type + "/" + state + "/fill");
|
||||
s_annotationColors.push_back(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
if (annotation.isScope)
|
||||
{
|
||||
i = 3;
|
||||
}
|
||||
else if (annotation.isError)
|
||||
{
|
||||
i = 6;
|
||||
}
|
||||
|
||||
if (annotation.isActive)
|
||||
{
|
||||
i += 2;
|
||||
}
|
||||
else if (annotation.isFocused)
|
||||
{
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return s_annotationColors[i];
|
||||
}
|
||||
|
||||
void QtCodeArea::createActions()
|
||||
{
|
||||
m_setIDECursorPositionAction = new QAction(tr("Set IDE Cursor"), this);
|
||||
m_setIDECursorPositionAction->setStatusTip(tr("Set the IDE Cursor to this code position"));
|
||||
m_setIDECursorPositionAction->setToolTip(tr("Set the IDE Cursor to this code position"));
|
||||
connect(m_setIDECursorPositionAction, SIGNAL(triggered()), this, SLOT(setIDECursorPosition()));
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
#ifndef QT_CODE_AREA_H
|
||||
#define QT_CODE_AREA_H
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <QPlainTextEdit>
|
||||
|
||||
@@ -19,6 +20,18 @@ class QWidget;
|
||||
class TokenLocation;
|
||||
class TokenLocationFile;
|
||||
|
||||
class MouseWheelOverScrollbarFilter
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MouseWheelOverScrollbarFilter(QObject* parent);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject*obj, QEvent* event);
|
||||
};
|
||||
|
||||
class QtCodeArea
|
||||
: public QPlainTextEdit
|
||||
{
|
||||
@@ -32,15 +45,17 @@ public:
|
||||
LineNumberArea(QtCodeArea *codeArea);
|
||||
virtual ~LineNumberArea();
|
||||
|
||||
QSize sizeHint() const;
|
||||
QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual void paintEvent(QPaintEvent* event);
|
||||
virtual void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
private:
|
||||
QtCodeArea *m_codeArea;
|
||||
};
|
||||
|
||||
static void clearAnnotationColors();
|
||||
|
||||
QtCodeArea(
|
||||
uint startLineNumber,
|
||||
const std::string& code,
|
||||
@@ -50,7 +65,7 @@ public:
|
||||
);
|
||||
virtual ~QtCodeArea();
|
||||
|
||||
virtual QSize sizeHint() const;
|
||||
virtual QSize sizeHint() const Q_DECL_OVERRIDE;
|
||||
|
||||
uint getStartLineNumber() const;
|
||||
uint getEndLineNumber() const;
|
||||
@@ -66,57 +81,79 @@ public:
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
void setIsActiveFile(bool isActiveFile);
|
||||
|
||||
QRectF getFirstActiveLineRect() const;
|
||||
|
||||
protected:
|
||||
virtual void resizeEvent(QResizeEvent *event);
|
||||
virtual void showEvent(QShowEvent* event);
|
||||
virtual void paintEvent(QPaintEvent* event);
|
||||
virtual void enterEvent(QEvent* event);
|
||||
virtual void leaveEvent(QEvent* event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent* event);
|
||||
virtual void mousePressEvent(QMouseEvent* event);
|
||||
virtual void mouseMoveEvent(QMouseEvent* event);
|
||||
virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
|
||||
virtual void showEvent(QShowEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void paintEvent(QPaintEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void enterEvent(QEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void leaveEvent(QEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void mouseReleaseEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void mousePressEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
|
||||
virtual void mouseMoveEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
virtual void contextMenuEvent(QContextMenuEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void updateLineNumberAreaWidth(int newBlockCount);
|
||||
void updateLineNumberArea(const QRect &, int);
|
||||
void clearSelection();
|
||||
void setIDECursorPosition();
|
||||
|
||||
private:
|
||||
struct Annotation
|
||||
{
|
||||
int start;
|
||||
int end;
|
||||
Id tokenId;
|
||||
Id locationId;
|
||||
bool isScope;
|
||||
};
|
||||
|
||||
struct ScopeAnnotation
|
||||
{
|
||||
ScopeAnnotation();
|
||||
bool operator!=(const ScopeAnnotation& other) const;
|
||||
|
||||
int startLine;
|
||||
int endLine;
|
||||
|
||||
int startCol;
|
||||
int endCol;
|
||||
|
||||
int start;
|
||||
int end;
|
||||
|
||||
Id tokenId;
|
||||
Id locationId;
|
||||
|
||||
bool isScope;
|
||||
bool isError;
|
||||
|
||||
bool isActive;
|
||||
bool isFocused;
|
||||
};
|
||||
|
||||
const Annotation* findAnnotationForPosition(int pos) const;
|
||||
struct AnnotationColor
|
||||
{
|
||||
std::string border;
|
||||
std::string fill;
|
||||
};
|
||||
|
||||
std::vector<Id> findLocationIdsForPosition(int pos) const;
|
||||
std::vector<const Annotation*> getAnnotationsForPosition(int pos) const;
|
||||
|
||||
void createAnnotations(std::shared_ptr<TokenLocationFile> locationFile);
|
||||
void annotateText();
|
||||
|
||||
void setHoveredAnnotation(const Annotation* annotation);
|
||||
|
||||
bool locationBelongsToSnippet(TokenLocation* location) const;
|
||||
void setHoveredAnnotations(const std::vector<const Annotation*>& annotations);
|
||||
|
||||
int toTextEditPosition(int lineNumber, int columnNumber) const;
|
||||
std::pair<int, int> toLineColumn(int textEditPosition) const;
|
||||
int startTextEditPosition() const;
|
||||
int endTextEditPosition() const;
|
||||
|
||||
std::set<int> getActiveLineNumbers() const;
|
||||
|
||||
std::vector<QRect> getCursorRectsForAnnotation(const Annotation& annotation) const;
|
||||
const AnnotationColor& getAnnotationColorForAnnotation(const Annotation& annotation);
|
||||
|
||||
void createActions();
|
||||
|
||||
static std::vector<AnnotationColor> s_annotationColors;
|
||||
|
||||
QtCodeFile* m_fileWidget;
|
||||
|
||||
QWidget* m_lineNumberArea;
|
||||
@@ -127,13 +164,16 @@ private:
|
||||
std::shared_ptr<TokenLocationFile> m_locationFile;
|
||||
|
||||
std::vector<Annotation> m_annotations;
|
||||
std::vector<ScopeAnnotation> m_scopeAnnotations;
|
||||
|
||||
const Annotation* m_hoveredAnnotation;
|
||||
std::vector<Id> m_hoveredLocationIds;
|
||||
std::vector<const Annotation*> m_hoveredAnnotations;
|
||||
|
||||
int m_digits;
|
||||
int m_panningValue; // just for horizontal panning
|
||||
|
||||
QAction* m_setIDECursorPositionAction;
|
||||
QPoint m_eventPosition; // is needed for IDE cursor control via context menu
|
||||
// the position where the context menu is opened needs to be stored]
|
||||
|
||||
bool m_isActiveFile;
|
||||
};
|
||||
|
||||
#endif // QT_CODE_AREA_H
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/messaging/type/MessageActivateFile.h"
|
||||
#include "utility/messaging/type/MessageShowFile.h"
|
||||
#include "utility/messaging/type/MessageShowSnippets.h"
|
||||
@@ -19,6 +21,7 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeFileList* parent)
|
||||
: QFrame(parent)
|
||||
, m_parent(parent)
|
||||
, m_filePath(filePath)
|
||||
, m_updateTitleBarFunctor(std::bind(&QtCodeFile::doUpdateTitleBar, this))
|
||||
{
|
||||
setObjectName("code_file");
|
||||
|
||||
@@ -28,15 +31,15 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeFileList* parent)
|
||||
layout->setAlignment(Qt::AlignTop);
|
||||
setLayout(layout);
|
||||
|
||||
QPushButton* titleWidget = new QPushButton(this);
|
||||
titleWidget->setObjectName("title_widget");
|
||||
layout->addWidget(titleWidget);
|
||||
m_titleBar = new QPushButton(this);
|
||||
m_titleBar->setObjectName("title_widget");
|
||||
layout->addWidget(m_titleBar);
|
||||
|
||||
QHBoxLayout* titleLayout = new QHBoxLayout();
|
||||
titleLayout->setMargin(0);
|
||||
titleLayout->setSpacing(0);
|
||||
titleLayout->setAlignment(Qt::AlignLeft);
|
||||
titleWidget->setLayout(titleLayout);
|
||||
m_titleBar->setLayout(titleLayout);
|
||||
|
||||
m_title = new QPushButton(filePath.fileName().c_str(), this);
|
||||
m_title->setObjectName("title_label");
|
||||
@@ -54,7 +57,7 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeFileList* parent)
|
||||
|
||||
titleLayout->addWidget(m_title);
|
||||
|
||||
titleWidget->setMinimumHeight(m_title->height() + 4);
|
||||
m_titleBar->setMinimumHeight(m_title->height() + 4);
|
||||
|
||||
m_referenceCount = new QLabel(this);
|
||||
m_referenceCount->setObjectName("references_label");
|
||||
@@ -85,7 +88,7 @@ QtCodeFile::QtCodeFile(const FilePath& filePath, QtCodeFileList* parent)
|
||||
m_snippetButton->setEnabled(false);
|
||||
m_maximizeButton->setEnabled(false);
|
||||
|
||||
connect(titleWidget, SIGNAL(clicked()), this, SLOT(clickedTitleBar()));
|
||||
connect(m_titleBar, SIGNAL(clicked()), this, SLOT(clickedTitleBar()));
|
||||
connect(m_title, SIGNAL(clicked()), this, SLOT(clickedTitle()));
|
||||
connect(m_minimizeButton, SIGNAL(clicked()), this, SLOT(clickedMinimizeButton()));
|
||||
connect(m_snippetButton, SIGNAL(clicked()), this, SLOT(clickedSnippetButton()));
|
||||
@@ -105,6 +108,12 @@ QtCodeFile::~QtCodeFile()
|
||||
{
|
||||
}
|
||||
|
||||
void QtCodeFile::setModificationTime(TimePoint modificationTime)
|
||||
{
|
||||
m_modificationTime = modificationTime;
|
||||
updateTitleBar();
|
||||
}
|
||||
|
||||
const FilePath& QtCodeFile::getFilePath() const
|
||||
{
|
||||
return m_filePath;
|
||||
@@ -115,16 +124,16 @@ std::string QtCodeFile::getFileName() const
|
||||
return m_filePath.fileName();
|
||||
}
|
||||
|
||||
Id QtCodeFile::getFocusedTokenId() const
|
||||
{
|
||||
return m_parent->getFocusedTokenId();
|
||||
}
|
||||
|
||||
const std::vector<Id>& QtCodeFile::getActiveTokenIds() const
|
||||
{
|
||||
return m_parent->getActiveTokenIds();
|
||||
}
|
||||
|
||||
const std::vector<Id>& QtCodeFile::getFocusedTokenIds() const
|
||||
{
|
||||
return m_parent->getFocusedTokenIds();
|
||||
}
|
||||
|
||||
const std::vector<std::string>& QtCodeFile::getErrorMessages() const
|
||||
{
|
||||
return m_parent->getErrorMessages();
|
||||
@@ -151,6 +160,10 @@ void QtCodeFile::addCodeSnippet(
|
||||
snippet->setProperty("isLast", true);
|
||||
|
||||
m_fileSnippet = snippet;
|
||||
if (!m_snippets.size())
|
||||
{
|
||||
m_fileSnippet->setIsActiveFile(true);
|
||||
}
|
||||
|
||||
clickedMaximizeButton();
|
||||
if (refCount != -1)
|
||||
@@ -166,7 +179,7 @@ void QtCodeFile::addCodeSnippet(
|
||||
updateRefCount(refCount);
|
||||
}
|
||||
|
||||
QWidget* QtCodeFile::insertCodeSnippet(
|
||||
QtCodeSnippet* QtCodeFile::insertCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
@@ -216,7 +229,7 @@ QWidget* QtCodeFile::insertCodeSnippet(
|
||||
return snippet.get();
|
||||
}
|
||||
|
||||
QWidget* QtCodeFile::findFirstActiveSnippet() const
|
||||
QtCodeSnippet* QtCodeFile::findFirstActiveSnippet() const
|
||||
{
|
||||
if (m_locationFile)
|
||||
{
|
||||
@@ -373,7 +386,7 @@ void QtCodeFile::clickedMaximizeButton()
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageShowFile(m_filePath, 0, 0).dispatch();
|
||||
MessageShowFile(m_filePath, (getErrorMessages().size() > 0)).dispatch();
|
||||
}
|
||||
|
||||
m_minimizeButton->setEnabled(true);
|
||||
@@ -386,6 +399,11 @@ void QtCodeFile::clickedMaximizeButton()
|
||||
m_minimizePlaceholder->hide();
|
||||
}
|
||||
|
||||
void QtCodeFile::handleMessage(MessageWindowFocus* message)
|
||||
{
|
||||
updateTitleBar();
|
||||
}
|
||||
|
||||
void QtCodeFile::updateSnippets()
|
||||
{
|
||||
int maxDigits = 1;
|
||||
@@ -420,3 +438,22 @@ void QtCodeFile::updateRefCount(int refCount)
|
||||
m_referenceCount->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFile::updateTitleBar()
|
||||
{
|
||||
m_updateTitleBarFunctor();
|
||||
}
|
||||
|
||||
void QtCodeFile::doUpdateTitleBar()
|
||||
{
|
||||
// cannot use m_filePath.exists() here since it is only checked when FilePath is constructed.
|
||||
if ((!FileSystem::exists(m_filePath.str())) ||
|
||||
(FileSystem::getLastWriteTime(m_filePath) > m_modificationTime))
|
||||
{
|
||||
m_title->setStyleSheet("background-image: url(data/gui/code_view/images/pattern.png);");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_title->setStyleSheet("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
#include <QFrame>
|
||||
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/TimePoint.h"
|
||||
#include "utility/types.h"
|
||||
#include "utility/messaging/MessageListener.h"
|
||||
#include "utility/messaging/type/MessageWindowFocus.h"
|
||||
#include "qt/utility/QtThreadedFunctor.h"
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
@@ -19,6 +23,7 @@ class TokenLocationFile;
|
||||
|
||||
class QtCodeFile
|
||||
: public QFrame
|
||||
, MessageListener<MessageWindowFocus>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
@@ -26,10 +31,13 @@ public:
|
||||
QtCodeFile(const FilePath& filePath, QtCodeFileList* parent);
|
||||
virtual ~QtCodeFile();
|
||||
|
||||
void setModificationTime(TimePoint modificationTime);
|
||||
|
||||
const FilePath& getFilePath() const;
|
||||
std::string getFileName() const;
|
||||
Id getFocusedTokenId() const;
|
||||
|
||||
const std::vector<Id>& getActiveTokenIds() const;
|
||||
const std::vector<Id>& getFocusedTokenIds() const;
|
||||
const std::vector<std::string>& getErrorMessages() const;
|
||||
|
||||
void addCodeSnippet(
|
||||
@@ -41,7 +49,7 @@ public:
|
||||
int refCount
|
||||
);
|
||||
|
||||
QWidget* insertCodeSnippet(
|
||||
QtCodeSnippet* insertCodeSnippet(
|
||||
uint startLineNumber,
|
||||
const std::string& title,
|
||||
Id titleId,
|
||||
@@ -50,7 +58,7 @@ public:
|
||||
int refCount
|
||||
);
|
||||
|
||||
QWidget* findFirstActiveSnippet() const;
|
||||
QtCodeSnippet* findFirstActiveSnippet() const;
|
||||
bool openCollapsedActiveSnippet() const;
|
||||
|
||||
void updateContent();
|
||||
@@ -67,11 +75,18 @@ private slots:
|
||||
void clickedMaximizeButton();
|
||||
|
||||
private:
|
||||
virtual void handleMessage(MessageWindowFocus* message);
|
||||
|
||||
void updateSnippets();
|
||||
void updateRefCount(int refCount);
|
||||
void updateTitleBar();
|
||||
void doUpdateTitleBar();
|
||||
|
||||
QtThreadedFunctor<> m_updateTitleBarFunctor;
|
||||
|
||||
QtCodeFileList* m_parent;
|
||||
|
||||
QPushButton* m_titleBar;
|
||||
QPushButton* m_title;
|
||||
QLabel* m_referenceCount;
|
||||
|
||||
@@ -85,6 +100,7 @@ private:
|
||||
QWidget* m_minimizePlaceholder;
|
||||
|
||||
const FilePath m_filePath;
|
||||
TimePoint m_modificationTime;
|
||||
std::shared_ptr<TokenLocationFile> m_locationFile;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "qt/element/QtCodeFile.h"
|
||||
#include "qt/element/QtCodeSnippet.h"
|
||||
|
||||
QtCodeFileList::QtCodeFileList(QWidget* parent)
|
||||
: QScrollArea(parent)
|
||||
, m_focusedTokenId(0)
|
||||
{
|
||||
setObjectName("code_file_list_base");
|
||||
|
||||
@@ -28,7 +28,7 @@ QtCodeFileList::QtCodeFileList(QWidget* parent)
|
||||
setWidgetResizable(true);
|
||||
setWidget(m_frame.get());
|
||||
|
||||
connect(this, SIGNAL(shouldScrollToSnippet(QWidget*)), this, SLOT(scrollToSnippet(QWidget*)), Qt::QueuedConnection);
|
||||
connect(this, SIGNAL(shouldScrollToSnippet(QtCodeSnippet*)), this, SLOT(scrollToSnippet(QtCodeSnippet*)), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
QtCodeFileList::~QtCodeFileList()
|
||||
@@ -47,25 +47,28 @@ void QtCodeFileList::addCodeSnippet(
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile,
|
||||
int refCount,
|
||||
TimePoint modificationTime,
|
||||
bool insert
|
||||
){
|
||||
QtCodeFile* file = getFile(locationFile);
|
||||
|
||||
if (insert)
|
||||
{
|
||||
QWidget* snippet = file->insertCodeSnippet(startLineNumber, title, titleId, code, locationFile, refCount);
|
||||
QtCodeSnippet* snippet = file->insertCodeSnippet(startLineNumber, title, titleId, code, locationFile, refCount);
|
||||
emit shouldScrollToSnippet(snippet);
|
||||
}
|
||||
else
|
||||
{
|
||||
file->addCodeSnippet(startLineNumber, title, titleId, code, locationFile, refCount);
|
||||
}
|
||||
file->setModificationTime(modificationTime);
|
||||
}
|
||||
|
||||
void QtCodeFileList::addFile(std::shared_ptr<TokenLocationFile> locationFile, int refCount)
|
||||
void QtCodeFileList::addFile(std::shared_ptr<TokenLocationFile> locationFile, int refCount, TimePoint modificationTime)
|
||||
{
|
||||
QtCodeFile* file = getFile(locationFile);
|
||||
file->setLocationFile(locationFile, refCount);
|
||||
file->setModificationTime(modificationTime);
|
||||
}
|
||||
|
||||
void QtCodeFileList::clearCodeSnippets()
|
||||
@@ -74,11 +77,6 @@ void QtCodeFileList::clearCodeSnippets()
|
||||
this->verticalScrollBar()->setValue(0);
|
||||
}
|
||||
|
||||
Id QtCodeFileList::getFocusedTokenId() const
|
||||
{
|
||||
return m_focusedTokenId;
|
||||
}
|
||||
|
||||
const std::vector<Id>& QtCodeFileList::getActiveTokenIds() const
|
||||
{
|
||||
return m_activeTokenIds;
|
||||
@@ -89,6 +87,16 @@ void QtCodeFileList::setActiveTokenIds(const std::vector<Id>& activeTokenIds)
|
||||
m_activeTokenIds = activeTokenIds;
|
||||
}
|
||||
|
||||
const std::vector<Id>& QtCodeFileList::getFocusedTokenIds() const
|
||||
{
|
||||
return m_focusedTokenIds;
|
||||
}
|
||||
|
||||
void QtCodeFileList::setFocusedTokenIds(const std::vector<Id>& focusedTokenIds)
|
||||
{
|
||||
m_focusedTokenIds = focusedTokenIds;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& QtCodeFileList::getErrorMessages() const
|
||||
{
|
||||
return m_errorMessages;
|
||||
@@ -103,18 +111,18 @@ bool QtCodeFileList::scrollToFirstActiveSnippet()
|
||||
{
|
||||
updateFiles();
|
||||
|
||||
QWidget* widget = nullptr;
|
||||
QtCodeSnippet* snippet = nullptr;
|
||||
for (std::shared_ptr<QtCodeFile> file: m_files)
|
||||
{
|
||||
widget = file->findFirstActiveSnippet();
|
||||
if (widget)
|
||||
snippet = file->findFirstActiveSnippet();
|
||||
if (snippet)
|
||||
{
|
||||
if (!widget->isVisible())
|
||||
if (!snippet->isVisible())
|
||||
{
|
||||
file->clickedSnippetButton();
|
||||
}
|
||||
|
||||
emit shouldScrollToSnippet(widget);
|
||||
emit shouldScrollToSnippet(snippet);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -133,21 +141,21 @@ void QtCodeFileList::expandActiveSnippetFile()
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFileList::focusToken(Id tokenId)
|
||||
void QtCodeFileList::focusTokenIds(const std::vector<Id>& focusedTokenIds)
|
||||
{
|
||||
m_focusedTokenId = tokenId;
|
||||
setFocusedTokenIds(focusedTokenIds);
|
||||
updateFiles();
|
||||
}
|
||||
|
||||
void QtCodeFileList::defocusToken()
|
||||
void QtCodeFileList::defocusTokenIds()
|
||||
{
|
||||
m_focusedTokenId = 0;
|
||||
setFocusedTokenIds(std::vector<Id>());
|
||||
updateFiles();
|
||||
}
|
||||
|
||||
void QtCodeFileList::scrollToSnippet(QWidget* widget)
|
||||
void QtCodeFileList::scrollToSnippet(QtCodeSnippet* snippet)
|
||||
{
|
||||
this->ensureWidgetVisibleAnimated(widget);
|
||||
this->ensureWidgetVisibleAnimated(snippet, snippet->getFirstActiveLineRect());
|
||||
}
|
||||
|
||||
QtCodeFile* QtCodeFileList::getFile(std::shared_ptr<TokenLocationFile> locationFile)
|
||||
@@ -184,7 +192,7 @@ void QtCodeFileList::updateFiles()
|
||||
}
|
||||
}
|
||||
|
||||
void QtCodeFileList::ensureWidgetVisibleAnimated(QWidget *childWidget, int xmargin, int ymargin)
|
||||
void QtCodeFileList::ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF rect)
|
||||
{
|
||||
if (!widget()->isAncestorOf(childWidget))
|
||||
{
|
||||
@@ -198,54 +206,21 @@ void QtCodeFileList::ensureWidgetVisibleAnimated(QWidget *childWidget, int xmarg
|
||||
: QRect(childWidget->mapTo(widget(), QPoint(0, 0)), childWidget->size());
|
||||
const QRect visibleRect(-widget()->pos(), viewport()->size());
|
||||
|
||||
if (visibleRect.contains(focusRect))
|
||||
if (rect.height() > 0)
|
||||
{
|
||||
return;
|
||||
focusRect = QRect(childWidget->mapTo(widget(), rect.topLeft().toPoint()), rect.size().toSize());
|
||||
focusRect.adjust(0, 0, 0, 100);
|
||||
}
|
||||
|
||||
focusRect.adjust(-xmargin, -ymargin, xmargin, ymargin);
|
||||
QScrollBar* scrollBar = verticalScrollBar();
|
||||
int value = focusRect.center().y() - visibleRect.center().y();
|
||||
|
||||
QScrollBar* scrollBar = nullptr;
|
||||
int value = 0;
|
||||
|
||||
if (focusRect.width() > visibleRect.width())
|
||||
{
|
||||
scrollBar = horizontalScrollBar();
|
||||
value = focusRect.center().x() - viewport()->width() / 2;
|
||||
}
|
||||
else if (focusRect.right() > visibleRect.right())
|
||||
{
|
||||
scrollBar = horizontalScrollBar();
|
||||
value = focusRect.right() - viewport()->width();
|
||||
}
|
||||
else if (focusRect.left() < visibleRect.left())
|
||||
{
|
||||
scrollBar = horizontalScrollBar();
|
||||
value = focusRect.left();
|
||||
}
|
||||
|
||||
if (focusRect.height() > visibleRect.height())
|
||||
{
|
||||
scrollBar = verticalScrollBar();
|
||||
value = focusRect.center().y() - viewport()->height() / 2;
|
||||
}
|
||||
else if (focusRect.bottom() > visibleRect.bottom())
|
||||
{
|
||||
scrollBar = verticalScrollBar();
|
||||
value = focusRect.bottom() - viewport()->height();
|
||||
}
|
||||
else if (focusRect.top() < visibleRect.top())
|
||||
{
|
||||
scrollBar = verticalScrollBar();
|
||||
value = focusRect.top();
|
||||
}
|
||||
|
||||
if (scrollBar)
|
||||
if (scrollBar && value != 0)
|
||||
{
|
||||
QPropertyAnimation* anim = new QPropertyAnimation(scrollBar, "value");
|
||||
anim->setDuration(500);
|
||||
anim->setStartValue(scrollBar->value());
|
||||
anim->setEndValue(value);
|
||||
anim->setEndValue(scrollBar->value() + value);
|
||||
anim->setEasingCurve(QEasingCurve::InOutQuad);
|
||||
anim->start();
|
||||
}
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
#include <QFrame>
|
||||
#include <QScrollArea>
|
||||
|
||||
#include "utility/TimePoint.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class QtCodeFile;
|
||||
class QtCodeSnippet;
|
||||
class TokenLocationFile;
|
||||
|
||||
class QtCodeFileList
|
||||
@@ -18,7 +20,7 @@ class QtCodeFileList
|
||||
Q_OBJECT
|
||||
|
||||
signals:
|
||||
void shouldScrollToSnippet(QWidget* widget);
|
||||
void shouldScrollToSnippet(QtCodeSnippet* widget);
|
||||
|
||||
public:
|
||||
QtCodeFileList(QWidget* parent = 0);
|
||||
@@ -33,42 +35,44 @@ public:
|
||||
const std::string& code,
|
||||
std::shared_ptr<TokenLocationFile> locationFile,
|
||||
int refCount,
|
||||
TimePoint modificationTime,
|
||||
bool insert = false
|
||||
);
|
||||
|
||||
void addFile(std::shared_ptr<TokenLocationFile> locationFile, int refCount);
|
||||
void addFile(std::shared_ptr<TokenLocationFile> locationFile, int refCount, TimePoint modificationTime);
|
||||
|
||||
void clearCodeSnippets();
|
||||
|
||||
Id getFocusedTokenId() const;
|
||||
|
||||
const std::vector<Id>& getActiveTokenIds() const;
|
||||
void setActiveTokenIds(const std::vector<Id>& activeTokenIds);
|
||||
|
||||
const std::vector<Id>& getFocusedTokenIds() const;
|
||||
void setFocusedTokenIds(const std::vector<Id>& focusedTokenIds);
|
||||
|
||||
const std::vector<std::string>& getErrorMessages() const;
|
||||
void setErrorMessages(const std::vector<std::string>& errorMessages);
|
||||
|
||||
bool scrollToFirstActiveSnippet();
|
||||
void expandActiveSnippetFile();
|
||||
|
||||
void focusToken(Id tokenId);
|
||||
void defocusToken();
|
||||
void focusTokenIds(const std::vector<Id>& focusedTokenIds);
|
||||
void defocusTokenIds();
|
||||
|
||||
private slots:
|
||||
void scrollToSnippet(QWidget* widget);
|
||||
void scrollToSnippet(QtCodeSnippet* snippet);
|
||||
|
||||
private:
|
||||
QtCodeFile* getFile(std::shared_ptr<TokenLocationFile> locationFile);
|
||||
|
||||
void updateFiles();
|
||||
|
||||
void ensureWidgetVisibleAnimated(QWidget *childWidget, int xmargin = 50, int ymargin = 50);
|
||||
void ensureWidgetVisibleAnimated(QWidget *childWidget, QRectF rect);
|
||||
|
||||
std::shared_ptr<QFrame> m_frame;
|
||||
std::vector<std::shared_ptr<QtCodeFile>> m_files;
|
||||
|
||||
Id m_focusedTokenId;
|
||||
std::vector<Id> m_activeTokenIds;
|
||||
std::vector<Id> m_focusedTokenIds;
|
||||
std::vector<std::string> m_errorMessages;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "qt/element/QtCodeSnippet.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <qmenu.h>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "utility/messaging/type/MessageShowScope.h"
|
||||
@@ -139,6 +140,25 @@ bool QtCodeSnippet::isActive() const
|
||||
return m_codeArea->isActive();
|
||||
}
|
||||
|
||||
void QtCodeSnippet::setIsActiveFile(bool isActiveFile)
|
||||
{
|
||||
m_codeArea->setIsActiveFile(isActiveFile);
|
||||
}
|
||||
|
||||
QRectF QtCodeSnippet::getFirstActiveLineRect() const
|
||||
{
|
||||
return m_codeArea->getFirstActiveLineRect();
|
||||
}
|
||||
|
||||
void QtCodeSnippet::contextMenuEvent(QContextMenuEvent* event)
|
||||
{
|
||||
QMenu menu(this);
|
||||
menu.addAction(new QAction("Bar", this));
|
||||
menu.addAction(new QAction("Brew Tea", this));
|
||||
menu.addAction(new QAction("Translate", this));
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
void QtCodeSnippet::clickedTitle()
|
||||
{
|
||||
if (m_titleId > 0)
|
||||
@@ -147,7 +167,7 @@ void QtCodeSnippet::clickedTitle()
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageShowFile(FilePath(m_titleString), 0, 0).dispatch();
|
||||
MessageShowFile(FilePath(m_titleString), (dynamic_cast<QtCodeFile*>(parent())->getErrorMessages().size() > 0)).dispatch();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,6 +42,13 @@ public:
|
||||
|
||||
bool isActive() const;
|
||||
|
||||
void setIsActiveFile(bool isActiveFile);
|
||||
|
||||
QRectF getFirstActiveLineRect() const;
|
||||
|
||||
protected:
|
||||
virtual void contextMenuEvent(QContextMenuEvent* event) Q_DECL_OVERRIDE;
|
||||
|
||||
private slots:
|
||||
void clickedTitle();
|
||||
|
||||
|
||||
@@ -133,6 +133,11 @@ QtDirectoryListBox::QtDirectoryListBox(QWidget *parent)
|
||||
resize();
|
||||
}
|
||||
|
||||
void QtDirectoryListBox::clear()
|
||||
{
|
||||
m_list->clear();
|
||||
}
|
||||
|
||||
void QtDirectoryListBox::dropEvent(QDropEvent *event)
|
||||
{
|
||||
QFileInfo fileInfo;
|
||||
|
||||
@@ -48,6 +48,8 @@ class QtDirectoryListBox
|
||||
public:
|
||||
QtDirectoryListBox(QWidget *parent);
|
||||
|
||||
void clear();
|
||||
|
||||
std::vector<FilePath> getList();
|
||||
void setList(const std::vector<FilePath>& list);
|
||||
|
||||
|
||||
@@ -397,8 +397,11 @@ void QtSmartSearchBox::onTextEdited(const QString& text)
|
||||
|
||||
if (match.nameHierarchy.size() && !m_allowMultipleElements)
|
||||
{
|
||||
if (m_matches.size())
|
||||
{
|
||||
matchesChanged = true;
|
||||
}
|
||||
clearMatches();
|
||||
matchesChanged = true;
|
||||
}
|
||||
|
||||
if (matchesChanged)
|
||||
@@ -822,7 +825,7 @@ void QtSmartSearchBox::clearLineEdit()
|
||||
|
||||
void QtSmartSearchBox::requestAutoCompletions() const
|
||||
{
|
||||
MessageSearchAutocomplete("", text().toStdString()).dispatch();
|
||||
MessageSearchAutocomplete(text().toStdString()).dispatch();
|
||||
}
|
||||
|
||||
void QtSmartSearchBox::hideAutoCompletions()
|
||||
@@ -832,5 +835,10 @@ void QtSmartSearchBox::hideAutoCompletions()
|
||||
|
||||
std::deque<SearchMatch> QtSmartSearchBox::getMatchesForInput(const std::string& text) const
|
||||
{
|
||||
return std::deque<SearchMatch>(1, SearchMatch(text));
|
||||
std::deque<SearchMatch> matches;
|
||||
if (text.size())
|
||||
{
|
||||
matches.push_back(SearchMatch(text));
|
||||
}
|
||||
return matches;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
#include <QMovie>
|
||||
|
||||
#include "qt/utility/utilityQt.h"
|
||||
#include "utility/messaging/type/MessageShowErrors.h"
|
||||
|
||||
QtStatusBar::QtStatusBar()
|
||||
: m_text(this)
|
||||
{
|
||||
@@ -19,6 +22,17 @@ QtStatusBar::QtStatusBar()
|
||||
|
||||
m_text.setText("");
|
||||
addWidget(&m_text);
|
||||
|
||||
m_errorButton.hide();
|
||||
m_errorButton.setFlat(true);
|
||||
m_errorButton.setStyleSheet("QPushButton { color: #D00000; margin-right: 0; spacing: none; }");
|
||||
m_errorButton.setIcon(utility::colorizePixmap(
|
||||
QPixmap("data/gui/statusbar_view/octagon.png"),
|
||||
"#D00000"
|
||||
).scaledToHeight(10));
|
||||
addPermanentWidget(&m_errorButton);
|
||||
|
||||
connect(&m_errorButton, SIGNAL(clicked()), this, SLOT(showErrors()));
|
||||
}
|
||||
|
||||
QtStatusBar::~QtStatusBar()
|
||||
@@ -29,7 +43,7 @@ void QtStatusBar::setText(const std::string& text, bool isError, bool showLoader
|
||||
{
|
||||
if (isError)
|
||||
{
|
||||
m_text.setStyleSheet("QLabel { color: #E00000 }");
|
||||
m_text.setStyleSheet("QLabel { color: #D00000 }");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -47,3 +61,21 @@ void QtStatusBar::setText(const std::string& text, bool isError, bool showLoader
|
||||
|
||||
m_text.setText(text.c_str());
|
||||
}
|
||||
|
||||
void QtStatusBar::setErrorCount(size_t count)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
m_errorButton.setText(QString::number(count) + " error(s)");
|
||||
m_errorButton.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorButton.hide();
|
||||
}
|
||||
}
|
||||
|
||||
void QtStatusBar::showErrors()
|
||||
{
|
||||
MessageShowErrors().dispatch();
|
||||
}
|
||||
|
||||
@@ -2,21 +2,30 @@
|
||||
#define QT_STATUS_BAR_H
|
||||
|
||||
#include <string>
|
||||
#include <QStatusBar>
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QLabel>
|
||||
#include <QStatusBar>
|
||||
|
||||
class QtStatusBar
|
||||
: public QStatusBar
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtStatusBar(void);
|
||||
~QtStatusBar(void);
|
||||
virtual ~QtStatusBar(void);
|
||||
|
||||
void setText(const std::string& text, bool isError, bool showLoader);
|
||||
void setErrorCount(size_t count);
|
||||
|
||||
private slots:
|
||||
void showErrors();
|
||||
|
||||
private:
|
||||
QLabel m_text;
|
||||
QLabel m_loader;
|
||||
QPushButton m_errorButton;
|
||||
};
|
||||
|
||||
#endif // QT_STATUS_BAR_H
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
QtIDECommunicationController::QtIDECommunicationController(QObject* parent)
|
||||
: m_tcpWrapper(parent)
|
||||
QtIDECommunicationController::QtIDECommunicationController(QObject* parent, StorageAccess* storageAccess)
|
||||
: IDECommunicationController(storageAccess)
|
||||
, m_tcpWrapper(parent)
|
||||
{
|
||||
m_tcpWrapper.setReadCallback(std::bind(&QtIDECommunicationController::handleIncomingMessage, this, std::placeholders::_1));
|
||||
}
|
||||
|
||||
@@ -7,11 +7,13 @@
|
||||
|
||||
#include "component/controller/IDECommunicationController.h"
|
||||
|
||||
class StorageAccess;
|
||||
|
||||
class QtIDECommunicationController
|
||||
: public IDECommunicationController
|
||||
{
|
||||
public:
|
||||
QtIDECommunicationController(QObject* parent);
|
||||
QtIDECommunicationController(QObject* parent, StorageAccess* storageAccess);
|
||||
~QtIDECommunicationController();
|
||||
|
||||
private:
|
||||
|
||||
@@ -10,7 +10,7 @@ QtNetworkFactory::~QtNetworkFactory()
|
||||
{
|
||||
}
|
||||
|
||||
std::shared_ptr<IDECommunicationController> QtNetworkFactory::createIDECommunicationController() const
|
||||
std::shared_ptr<IDECommunicationController> QtNetworkFactory::createIDECommunicationController(StorageAccess* storageAccess) const
|
||||
{
|
||||
return std::make_shared<QtIDECommunicationController>(nullptr);
|
||||
return std::make_shared<QtIDECommunicationController>(nullptr, storageAccess);
|
||||
}
|
||||
@@ -9,7 +9,7 @@ public:
|
||||
QtNetworkFactory();
|
||||
virtual ~QtNetworkFactory();
|
||||
|
||||
virtual std::shared_ptr<IDECommunicationController> createIDECommunicationController() const;
|
||||
virtual std::shared_ptr<IDECommunicationController> createIDECommunicationController(StorageAccess* storageAccess) const;
|
||||
};
|
||||
|
||||
#endif // QT_NETWORK_FACTORY_H
|
||||
@@ -2,23 +2,6 @@
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
QtTcpWrapper::QtTcpWrapper(QObject* parent)
|
||||
: QObject(parent)
|
||||
, m_port(6667)
|
||||
, m_ip("127.0.0.1")
|
||||
{
|
||||
QHostAddress address(m_ip.c_str());
|
||||
|
||||
m_tcpServer = new QTcpServer(this);
|
||||
|
||||
connect(m_tcpServer, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
|
||||
|
||||
if (!m_tcpServer->listen(QHostAddress::LocalHost, m_port))
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "TCP server failed to start. Unable to listen for IDE plugin messages.");
|
||||
}
|
||||
}
|
||||
|
||||
QtTcpWrapper::QtTcpWrapper(QObject* parent, const std::string& ip, const quint16 port)
|
||||
: QObject(parent)
|
||||
, m_port(port)
|
||||
@@ -32,7 +15,7 @@ QtTcpWrapper::QtTcpWrapper(QObject* parent, const std::string& ip, const quint16
|
||||
|
||||
if (!m_tcpServer->listen(QHostAddress::LocalHost, m_port))
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "TCP server failed to start. Unable to listen for IDE plugin messages.");
|
||||
LOG_ERROR_STREAM(<< "TCP server failed to start with error: \"" + m_tcpServer->errorString().toStdString() + "\". Unable to listen for IDE plugin messages.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ class QtTcpWrapper : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QtTcpWrapper(QObject* parent);
|
||||
QtTcpWrapper(QObject* parent, const std::string& ip, const quint16 port);
|
||||
QtTcpWrapper(QObject* parent, const std::string& ip = "127.0.0.1", const quint16 port = 6667);
|
||||
~QtTcpWrapper();
|
||||
|
||||
void sendMessage(const std::string& message) const;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user