Compare commits

...
43 Commits
Author SHA1 Message Date
Eberhard Graether 816be7b654 ui: undefined symbols bundle needs at least 2 nodes 2015-11-18 13:22:57 +01:00
malte_langkabel 901fa1a387 data: template argument handling
* storing template argument relations for cases where at lease one of these (template class, template argument) is defined inside the parsed project files.
* prevented storage from saving the same source location multiple times.
2015-11-17 18:09:20 +01:00
Andreas Stallinger 88b94a21d0 build: linux package
linux package
2015-11-17 16:41:49 +01:00
malte_langkabel 102bc8945a test: comment parsing
added tests for comment parsing.
2015-11-17 14:03:56 +01:00
Andreas Stallinger 86f06c9f78 ui: recent projects menu fix
recent projects updates now when a projects is loaded
2015-11-17 12:13:48 +01:00
malte_langkabel 42afbce300 resources: Tutorial Project Improvements
* implemented "user study" feedback
2015-11-17 10:54:56 +01:00
malte_langkabel 8f0213e18c build: Packaging Script for Windows
* added packaging script for windows
* renamed sublime plugin.
* added tictactoe project to packages projects
2015-11-16 15:42:23 +01:00
Andreas Stallinger fc816240cb ui: Recent projects in menu
add a recent projects menu in the project menu
2015-11-13 22:53:37 +01:00
malte_langkabel 7fce4cfae6 resources: Tutorial Project
* added tutorial project to coati projects.
* ignoring all .sqlite files for git.
2015-11-13 18:55:10 +01:00
Eberhard Graether 3c2804797a logic: improvements for IDE communication
* fixed Sublime Text plugin to correctly send messages
* activate and focus Coati window when receiving a message
* extended lookup range for activate token message from plugin
2015-11-13 13:09:22 +01:00
Eberhard Graether df7c5ea9b7 ui: code view scrolls directly to active line
This change makes the code view first look for the rect of the first active line and then tries to scroll this line into
the middle of the view.
2015-11-13 10:39:30 +01:00
Eberhard Graether de4f2973bc ui: Fixed search query without node disappears when submiting search request 2015-11-12 13:45:57 +01:00
Eberhard Graether 00b74d2f30 ui: focusing multiple tokens at once
This change focuses all token locations underneath the cursor at once by extending the focus handling to use vectors.
2015-11-12 10:14:46 +01:00
Eberhard Graether 28e3880e10 ui: Fixed cursor jumping to end position when editing search query 2015-11-11 15:13:48 +01:00
Eberhard Graether 42aa99d99b ui: reworked code view highlighting
This change draws the annotations in the code view in the paintEvent handler instead of using the ExtraSelections API.
Annotations are now drawn with a slight corner radius. Fill and border colors are defined in the ColorScheme.
2015-11-11 15:02:23 +01:00
Eberhard Graether 3351e4aad7 data: fixed parsing problems
* fixed calleeDecl pointer not checked for CallExpr
* fixed CommentHandler not checking if valid file in FileRegister
2015-11-10 10:25:47 +01:00
Andreas Stallinger 5ef9ef9e7d build: publish and sync script modification
now you can pass a branch to the publish and sync script to sync or publish to another branch  then master
2015-11-10 10:11:50 +01:00
Andreas Stallinger a4c134ebe2 src: fix clang warnings in QtCodeArea 2015-11-09 15:32:42 +01:00
Manuel Dobusch f2a202c064 logic: vs focus
Setting cursor in VS via Coati now sets the focus to the VS window.
2015-11-09 13:59:55 +01:00
Eberhard Graether 372f262204 data: don't parse lambda calls to avoid subnodes within functions 2015-11-06 14:50:25 +01:00
malte_langkabel 50bc970c30 data, ui: comment handling
* CodeView displays comments as atomic regions. They are either displayed as a whole or not at all. Do nothing halfway!
* added CommentHandler that handles comments detected by clang.
* stored CommentLocations in database.
2015-11-06 14:03:20 +01:00
Manuel Dobusch e186eefdff ui: context menu
Context menu for code view added, including option to set IDE cursor.
2015-11-04 18:51:49 +01:00
Eberhard Graether bcbeacb951 utility: Fixed crash when creating Timepoint with empty string 2015-11-04 15:12:35 +01:00
Eberhard Graether 961d0fe541 ui: clearing data in ProjectSetupScreen after creating new project 2015-11-04 14:14:20 +01:00
Eberhard Graether 5dada05bc5 data: saving macro definition scopes 2015-11-04 13:47:33 +01:00
Eberhard Graether 884e42a30c test: fixed TestSettings.xml and cleansed test_log.txt 2015-11-04 13:02:35 +01:00
Eberhard Graether 9f684ad9f5 data: saving errors to Storage
* saving errors in separate sqlite table
* use MessageShowErrors to show the errors in the UI
* show error count permanently in the right side of the status bar with click to show
* fixed clicking of error locations
* fixed expanding of files with errors
2015-11-04 12:00:28 +01:00
malte_langkabel 78259c7123 src: refactoring TimePoint
* removed typedef utility::TimePoint and replaced all its usages by using the class TimePoint instead.
2015-11-03 16:48:55 +01:00
Manuel Dobusch 7d03166282 logic: VS plugin fixes
Fixed some vs plugin issues and added plugin project to repo
2015-11-03 15:26:47 +01:00
malte_langkabel 006e73ef4c ui: horizontal scroll fix
* prevented the mouse wheel from scrolling a horizontal scrollbar when the mouse happens to enter the scrollbar's area.
2015-11-03 12:40:03 +01:00
malte_langkabel 11147e982f test: template scope fixes
* changed expected scope locations of template classes in tests to include template parameters.
2015-11-03 11:11:20 +01:00
malte_langkabel 9c4dc7b71f src: Sublime Text 3 compatibility. 2015-11-03 10:53:14 +01:00
malte_langkabel a524a7a71c ui: file not up to date display
* the codeview now displays a hatched background for a filename when the file's content has changed or the file does not exist anymore.
* added TimePoint class to encapsulate boost.
2015-11-03 10:29:29 +01:00
Eberhard Graether 42ab36fbad data: Saving application version to storage and refresh when version changes
The version string of the application is stored on every parse. The utility class Version is used to parse the version
string and compare application and stored string. The third number in the version string is now the storage refresh
number, the project will be refreshed when it changes. (0.2.1 -> 0.2.2)
2015-11-02 10:14:03 +01:00
malte_langkabel 1ad2dbe86e ui: status messages for IDE communication
* added status messages that are displayed when sending commands to the IDE.
* added status messages that are displayed when receiving commands from the IDE.
2015-10-30 11:34:28 +01:00
malte_langkabel e8c8a4ca50 logic: sublime plugin fix
* implemted checking if file really exists before letting sublime jump there.
2015-10-30 10:54:56 +01:00
Andreas Stallinger 58daa633c9 data: check for nullptr in searchindex 2015-10-29 13:33:12 +01:00
malte_langkabel a7ad0a60f3 ui: coati plugin for sublime
* Added first version of the CoatiCommunicator for Sublime.
* This version has only been tested with Sublime Text 2.
2015-10-28 15:10:47 +01:00
Eberhard Graether c7a2533dc4 data: increased autocomplete performance by caching and limiting results to 100 2015-10-27 14:22:45 +01:00
Andreas Stallinger cbb6fcd8e2 test: fixed settingstestsuite
changed settings.xml to new/refactored xml tags
2015-10-27 10:13:29 +01:00
malte_langkabel c704b4f65c ui: IDE communication integration
* handled communication from VS to Coati and vice versa.
* one bug still remains: Coati regards a tab as a single character while VS regards it as multiple characters. This causes offsets in communicated positions.
2015-10-23 13:25:15 +02:00
malte_langkabel c06beb21cb data: template class/function scope locations
* Added source locations of template parameters to the scope of template classes and functions to improve context availability in the code view.
2015-10-21 19:56:47 +02:00
Eberhard Graether 1382356a39 build: added release instructions to README 2015-10-21 10:34:11 +02:00
188 changed files with 5275 additions and 1214 deletions
+6
View File
@@ -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
View File
@@ -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
+18
View File
@@ -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>
+44 -10
View File
@@ -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>
+44 -10
View File
@@ -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;
}
+13
View File
@@ -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>
+16
View File
@@ -0,0 +1,16 @@
void lambdaCaller()
{
[](){}();
}
void lambdaSuperCaller()
{
lambdaCaller();
}
void lambdaMetaCaller()
{
[](){
lambdaCaller();
}();
}
+1
View File
@@ -21,6 +21,7 @@ int calculate(int i)
return a;
}
#define PI 3.1415
#define CALL_CALCULATE() \
do \
+7 -7
View File
@@ -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>
-306
View File
@@ -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
View File
@@ -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" }
]
+5
View File
@@ -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
@@ -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);
};
}
@@ -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
View File
@@ -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
View File
@@ -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
-96
View File
@@ -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
+105
View File
@@ -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
+80
View File
@@ -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!
+5 -3
View File
@@ -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
+2 -2
View File
@@ -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>
+5 -2
View File
@@ -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
View File
@@ -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()));
}
+73 -33
View File
@@ -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
+51 -14
View File
@@ -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("");
}
}
+19 -3
View File
@@ -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;
};
+36 -61
View File
@@ -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();
}
+13 -9
View File
@@ -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;
};
+21 -1
View File
@@ -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();
}
}
+7
View File
@@ -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;
+2
View File
@@ -48,6 +48,8 @@ class QtDirectoryListBox
public:
QtDirectoryListBox(QWidget *parent);
void clear();
std::vector<FilePath> getList();
void setList(const std::vector<FilePath>& list);
+11 -3
View File
@@ -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;
}
+33 -1
View File
@@ -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();
}
+11 -2
View File
@@ -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:
+2 -2
View File
@@ -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);
}
+1 -1
View File
@@ -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
+1 -18
View File
@@ -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.");
}
}
+1 -2
View File
@@ -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