Browse Source

merged

merge-requests/365/head
tedjk 11 years ago
parent
commit
5af78ac69a
  1. 4
      juci/api.h
  2. 4
      juci/config.cc
  3. 6
      juci/config.json
  4. 2
      juci/menu.cc
  5. 6
      juci/menu.xml
  6. 385
      juci/notebook.cc
  7. 51
      juci/notebook.h
  8. 75
      juci/source.cc
  9. 98
      juci/source.h
  10. 88
      juci/terminal.cc
  11. 33
      juci/terminal.h
  12. 53
      juci/window.cc
  13. 8
      juci/window.h

4
juci/api.h

@ -55,9 +55,9 @@ namespace libjuci {
const std::string plugin_path,
const std::string menu_keybinding);
void AddMenuXml(const std::string plugin_name,
const string parent_menu);
const std::string parent_menu);
void AddSubMenuXml(const std::string plugin_name,
const string parent_menu);
const std::string parent_menu);
//////////////////////////////
//// Boost.Python methods ////
//////////////////////////////

4
juci/config.cc

@ -17,16 +17,14 @@ void MainConfig::GenerateSource() {
boost::property_tree::ptree colors_json = source_json.get_child("colors");
for ( auto &i : colors_json ) {
source_cfg_.InsertTag(i.first, i.second.get_value<std::string>());
std::cout << "inserting tag, key: " << i.first << " value: " << i.second.get_value<std::string>() << std::endl;
}
for ( auto &i : syntax_json ) {
source_cfg_.InsertType(i.first, i.second.get_value<std::string>());
std::cout << "inserting type, key: " << i.first << " value: " << i.second.get_value<std::string>() << std::endl;
}
}
void MainConfig::GenerateKeybindings() {
string line;
std::string line;
std::ifstream menu_xml("menu.xml");
if (menu_xml.is_open()) {
while (getline(menu_xml, line)) {

6
juci/config.json

@ -24,7 +24,11 @@
"new_cc_file": "<alt>c",
"close_tab": "<control>w",
"open_folder": "<control><alt>o",
"edit_undo": "<control>z"
"edit_undo": "<control>z",
"save": "<control>s",
"save_as": "<control><shift>s",
"compile_and_run": "<control><alt>r>",
"compile": "<control>r"
},
"directoryfilter": {
"ignore": [

2
juci/menu.cc

@ -27,6 +27,8 @@ Menu::Controller::Controller(Keybindings::Controller& keybindings) :
[this]() {
OnWindowSplitWindow();
});
keybindings_.action_group_menu()->add(Gtk::Action::create("ProjectMenu",
"P_roject"));
keybindings_.action_group_menu()->add(Gtk::Action::create("PluginMenu",
"_Plugins"));
keybindings_.action_group_menu()->add(Gtk::Action::create("HelpMenu",

6
juci/menu.xml

@ -8,6 +8,8 @@
</menu>
<menuitem action='FileOpenFile'/>
<menuitem action='FileOpenFolder'/>
<menuitem action='FileSave'/>
<menuitem action='FileSaveAs'/>
<separator/>
<menuitem action='FileQuit'/>
</menu>
@ -19,6 +21,10 @@
<menuitem action='EditFind'/>
<menuitem action='EditUndo'/>
</menu>
<menu action='ProjectMenu'>
<menuitem action='ProjectCompileAndRun'/>
<menuitem action='ProjectCompile'/>
</menu>
<menu action='WindowMenu'>
<menuitem action='WindowCloseTab'/>
<menuitem action='WindowSplitWindow'/>

385
juci/notebook.cc

@ -1,4 +1,5 @@
#include "notebook.h"
#include <fstream>
Notebook::Model::Model() {
cc_extension_ = ".cc";
@ -6,22 +7,26 @@ Notebook::Model::Model() {
scrollvalue_ = 50;
}
Notebook::View::View() {
Notebook::View::View() : notebook_() {
view_.pack2(notebook_);
view_.set_position(120);
}
Notebook::Controller::Controller(Keybindings::Controller& keybindings,
Notebook::Controller::Controller(Gtk::Window* window, Keybindings::Controller& keybindings,
Source::Config& source_cfg,
Directories::Config& dir_cfg) :
source_config_(source_cfg),
directories_(dir_cfg) {
directories_(dir_cfg),
index_(0, 1) {
window_ = window;
OnNewPage("juCi++");
refClipboard_ = Gtk::Clipboard::get();
ispopup = false;
view().pack1(directories_.widget(), true, true);
CreateKeybindings(keybindings);
} // Constructor
void Notebook::Controller::CreateKeybindings(Keybindings::Controller
&keybindings) {
directories().m_TreeView.signal_row_activated()
@ -100,14 +105,7 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller
Gtk::AccelKey(keybindings.config_
.key_map()["edit_undo"]),
[this]() {
OnUndo();
});
keybindings.action_group_hidden()->
add(Gtk::Action::create("EditPaste",
Gtk::Stock::PASTE),
[this]() {
OnEditPaste();
//OnUndo();
});
entry_.view_.entry().signal_activate().
connect(
@ -142,53 +140,108 @@ void Notebook::Controller::CreateKeybindings(Keybindings::Controller
});
}
void Notebook::Controller::GeneratePopup(std::vector<string> items) {
bool Notebook::Controller:: OnMouseRelease(GdkEventButton* button) {
if (button->button == 1 && ispopup) {
popup_.response(Gtk::RESPONSE_DELETE_EVENT);
return true;
}
return false;
}
bool Notebook::Controller::OnKeyRelease(GdkEventKey* key) {
return GeneratePopup(key->keyval);
}
bool Notebook::Controller::GeneratePopup(int key_id) {
// Get function to fill popup with suggests item vector under is for testing
Gtk::TextIter beg = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter end = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter tmp = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter tmp1 = CurrentTextView().get_buffer()->get_insert()->get_iter();
Gtk::TextIter line =
CurrentTextView().get_buffer()->get_iter_at_line(tmp.get_line());
if (end.backward_char() && end.backward_char()) {
bool illegal_chars =
end.backward_search("\"", Gtk::TEXT_SEARCH_VISIBLE_ONLY, tmp, tmp1, line)
||
end.backward_search("//", Gtk::TEXT_SEARCH_VISIBLE_ONLY, tmp, tmp1, line);
if (illegal_chars) {
return false;
}
std::string c = text_vec_[CurrentPage()]->buffer()->get_text(end, beg);
switch (key_id) {
case 46:
break;
case 58:
if (c != "::") return false;
break;
case 60:
if (c != "->") return false;
break;
case 62:
if (c != "->") return false;
break;
default:
return false;
}
} else {
return false;
}
std::vector<Source::AutoCompleteData> acdata;
text_vec_.at(CurrentPage())->
GetAutoCompleteSuggestions(beg.get_line()+1,
beg.get_line_offset()+2,
&acdata);
std::map<std::string, std::string> items;
for (auto &data : acdata) {
std::stringstream ss;
std::string return_value;
for (auto &chunk : data.chunks_) {
switch (chunk.kind()) {
case clang::CompletionChunk_ResultType:
return_value = chunk.chunk();
break;
case clang::CompletionChunk_Informative:
break;
default:
ss << chunk.chunk();
break;
}
}
items[ss.str() + " --> " + return_value] = ss.str();
}
// Replace over with get suggestions from zalox! OVER IS JUST FOR TESTING
Gtk::ScrolledWindow popup_scroll_;
Gtk::ListViewText listview_(1, false, Gtk::SelectionMode::SELECTION_SINGLE);
Gtk::Dialog popup_("", true);
listview_.set_enable_search(false);
popup_scroll_.set_policy(Gtk::PolicyType::POLICY_NEVER,
Gtk::PolicyType::POLICY_NEVER);
listview_.set_enable_search(true);
listview_.set_headers_visible(false);
listview_.set_hscroll_policy(Gtk::ScrollablePolicy::SCROLL_NATURAL);
listview_.set_activate_on_single_click(true);
listview_.signal_row_activated().
connect([this, &listview_, &popup_](const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn*) {
std::string t = listview_.get_text(listview_.get_selected()[0]);
CurrentTextView().get_buffer()->insert_at_cursor(t);
popup_.response(Gtk::RESPONSE_DELETE_EVENT);
});
for (auto &i : items) listview_.append(i);
listview_.set_headers_visible(false);
if (items.empty()) {
items["No suggestions found..."] = "";
}
for (auto &i : items) {
listview_.append(i.first);
}
popup_scroll_.add(listview_);
popup_.get_vbox()->pack_start(popup_scroll_);
popup_.set_size_request(80, 80);
popup_.set_transient_for(*window_);
popup_.show_all();
Gdk::Rectangle temp1, temp2;
CurrentTextView().
get_cursor_locations(
CurrentTextView().
get_buffer()->get_insert()->
get_iter(), temp1, temp2);
int x = temp1.get_x();
int y = temp1.get_y();
text_vec_.at(CurrentPage())->
view().buffer_to_window_coords(
Gtk::TextWindowType::TEXT_WINDOW_WIDGET,
temp2.get_x(),
temp2.get_y(),
x, y);
int widht = Notebook().get_width()-88;
int height = Notebook().get_height()-180;
if (x > widht) {
x = widht; }
if (y > height) {
y = height;
}
popup_.move(x, y+88);
int popup_x = popup_.get_width();
int popup_y = items.size() * 20;
PopupSetSize(popup_scroll_, popup_x, popup_y);
int x, y;
FindPopupPosition(CurrentTextView(), popup_x, popup_y, x, y);
popup_.move(x, y+15);
PopupSelectHandler(popup_, listview_, &items);
ispopup = true;
popup_.run();
popup_.hide();
ispopup = false;
return true;
}
bool Notebook::Controller::ScrollEventCallback(GdkEventScroll* scroll_event) {
@ -229,28 +282,35 @@ void Notebook::Controller::OnNewPage(std::string name) {
Notebook().show_all_children();
Notebook().set_current_page(Pages()-1);
Notebook().set_focus_child(text_vec_.at(Pages()-1)->view());
NewBufferHistory(text_vec_.back()->view().get_buffer());
}
void Notebook::Controller::
MapBuffers(std::map<std::string, std::string> *buffers) {
for (auto &buffer : text_vec_) {
buffers->operator[](buffer->model().file_path()) =
buffer->buffer()->get_text().raw();
}
}
void Notebook::Controller::OnOpenFile(std::string path) {
OnCreatePage();
text_vec_.back()->OnOpenFile(path);
text_vec_.back()->set_is_saved(true);
unsigned pos = path.find_last_of("/\\");
Notebook().append_page(*editor_vec_.back(), path.substr(pos+1));
Notebook().show_all_children();
std::cout << "setting current page"<< std::endl;
Notebook().set_current_page(Pages()-1);
std::cout << "current page set" << std::endl;
Notebook().set_focus_child(text_vec_.back()->view());
OnBufferChange();
NewBufferHistory(text_vec_.back()->view().get_buffer());
}
void Notebook::Controller::OnCreatePage() {
text_vec_.push_back(new Source::Controller(source_config()));
linenumbers_vec_.push_back(new Source::Controller(source_config()));
text_vec_.push_back(new Source::Controller(source_config(), this));
linenumbers_vec_.push_back(new Source::Controller(source_config(), this));
scrolledline_vec_.push_back(new Gtk::ScrolledWindow());
scrolledtext_vec_.push_back(new Gtk::ScrolledWindow());
editor_vec_.push_back(new Gtk::HBox());
@ -265,7 +325,7 @@ void Notebook::Controller::OnCreatePage() {
linenumbers_vec_.back()->view().set_sensitive(false);
editor_vec_.back()->pack_start(*scrolledline_vec_.back(), false, false);
editor_vec_.back()->pack_start(*scrolledtext_vec_.back(), true, true);
BufferChangeHandler(text_vec_.back()->view().get_buffer());
TextViewHandlers(text_vec_.back()->view());
}
void Notebook::Controller::OnCloseCurrentPage() {
@ -396,24 +456,6 @@ void Notebook::Controller::OnBufferChange() {
ScrollEventCallback(scroll);
delete scroll;
}
Gtk::TextIter start, end;
std::string word, last_word;
start = Buffer(text_vec_.at(page))->get_insert()->get_iter();
end = Buffer(text_vec_.at(page))->get_insert()->get_iter();
start.backward_char();
word = Buffer(text_vec_.at(page))->get_text(start, end);
last_word = Buffer(text_vec_.at(page))->get_text(--start, --end);
if (word == ".") {
// TODO(Forgie) Zalox,Forgie) Remove TEST
UpdateHistory();
std::vector<std::string> TEST;
TEST.push_back("toString()");
TEST.push_back("toLower()");
TEST.push_back("toUpper()");
TEST.push_back("fuckOFF()");
TEST.push_back("fuckOFF()");
GeneratePopup(TEST);
}
}
void Notebook::Controller
::OnDirectoryNavigation(const Gtk::TreeModel::Path& path,
@ -464,91 +506,142 @@ void Notebook::Controller::BufferChangeHandler(Glib::RefPtr<Gtk::TextBuffer>
});
buffer->signal_end_user_action().connect(
[this]() {
UpdateHistory();
//UpdateHistory();
});
}
void Notebook::Controller::TextViewHandlers(Gtk::TextView& textview) {
textview.get_buffer()->signal_changed().connect(
[this]() {
OnBufferChange();
});
// History methods
void Notebook::Controller::
NewBufferHistory(Glib::RefPtr<Gtk::TextBuffer> buffer) {
Glib::ustring text = buffer->get_text();
std::deque<Glib::ustring> queue;
queue.push_back(text);
history_.push_back(queue);
}
textview.signal_button_release_event().
connect(sigc::mem_fun(*this, &Notebook::Controller::OnMouseRelease), false);
void Notebook::Controller::UpdateHistory() {
Gtk::TextIter start, end;
std::string word, last_word;
int page = CurrentPage();
start = Buffer(text_vec_.at(page))->get_insert()->get_iter();
end = Buffer(text_vec_.at(page))->get_insert()->get_iter();
start.backward_char();
word = Buffer(text_vec_.at(page))->get_text(start, end);
last_word = Buffer(text_vec_.at(page))->get_text(--start, --end);
/*if(word == "."
|| word == " "
|| word == ";"
|| word == ":"
|| word == "}"
|| word == ")"
|| word == "]"
|| word == ">") {
if(last_word != "."
&& last_word != " "
&& last_word != ";"
&& last_word != ":"
&& last_word != "}"
&& last_word != ")"
&& last_word != "]"
&& last_word != ">") {*/
AppendBufferState();
// }
// }
}
void Notebook::Controller::
AppendBufferState() {
Glib::ustring text = CurrentTextView().get_buffer()->get_text();
std::cout << "buf.size(): " << text.size() << std::endl;
if(BufferHistory().size() < kHistorySize) {
BufferHistory().push_back(text);
} else {
BufferHistory().pop_front();
BufferHistory().push_back(text);
}
textview.signal_key_release_event().
connect(sigc::mem_fun(*this, &Notebook::Controller::OnKeyRelease), false);
}
void Notebook::Controller::RemoveBufferHistory() {
history_.erase(history_.begin()+CurrentPage());
void Notebook::Controller::PopupSelectHandler(Gtk::Dialog &popup,
Gtk::ListViewText &listview,
std::map<std::string, std::string>
*items) {
listview.signal_row_activated().
connect([this, &listview, &popup, items](const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn*) {
std::string selected = items->
at(listview.get_text(listview.get_selected()[0]));
CurrentTextView().get_buffer()->insert_at_cursor(selected);
popup.response(Gtk::RESPONSE_DELETE_EVENT);
});
}
void Notebook::Controller::PopupSetSize(Gtk::ScrolledWindow &scroll,
int &current_x,
int &current_y) {
int textview_x = CurrentTextView().get_width();
int textview_y = 150;
bool is_never_scroll_x = true;
bool is_never_scroll_y = true;
if (current_x > textview_x) {
current_x = textview_x;
is_never_scroll_x = false;
}
if (current_y > textview_y) {
current_y = textview_y;
is_never_scroll_y = false;
}
scroll.set_size_request(current_x, current_y);
if (!is_never_scroll_x && !is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC,
Gtk::PolicyType::POLICY_AUTOMATIC);
} else if (!is_never_scroll_x && is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_AUTOMATIC,
Gtk::PolicyType::POLICY_NEVER);
} else if (is_never_scroll_x && !is_never_scroll_y) {
scroll.set_policy(Gtk::PolicyType::POLICY_NEVER,
Gtk::PolicyType::POLICY_AUTOMATIC);
}
}
void Notebook::Controller::FindPopupPosition(Gtk::TextView& textview,
int popup_x,
int popup_y,
int &x,
int &y) {
Gdk::Rectangle temp1, temp2;
textview.get_cursor_locations(
CurrentTextView().
get_buffer()->get_insert()->
get_iter(), temp1, temp2);
int textview_edge_x = 0;
int textview_edge_y = 0;
textview.buffer_to_window_coords(
Gtk::TextWindowType::TEXT_WINDOW_WIDGET,
temp1.get_x(),
temp1.get_y(),
x, y);
Glib::RefPtr<Gdk::Window> gdkw =
CurrentTextView().get_window(Gtk::TextWindowType::TEXT_WINDOW_WIDGET);
gdkw->get_origin(textview_edge_x, textview_edge_y);
std::deque<Glib::ustring>& Notebook::Controller::BufferHistory() {
return history_.at(CurrentPage());
x += textview_edge_x;
y += textview_edge_y;
if ((textview_edge_x-x)*-1 > textview.get_width()-popup_x) {
x -= popup_x;
if (x < textview_edge_x) x = textview_edge_x;
}
if ((textview_edge_y-y)*-1 > textview.get_height()-popup_y) {
y -= (popup_y+14) + 15;
if (x < textview_edge_y) y = textview_edge_y +15;
}
}
Glib::ustring& Notebook::Controller::LastBufferState() {
if(BufferHistory().size() > 1) {
BufferHistory().pop_back();
void Notebook::Controller:: OnSaveFile() {
if (text_vec_.at(CurrentPage())->is_saved()) {
std::ofstream file;
file.open (text_vec_.at(CurrentPage())->path());
file << CurrentTextView().get_buffer()->get_text();
file.close();
} else {
std::cout << "Reached end of history, can't undo any more" << std::endl;
std::string path = OnSaveFileAs();
if (path != "") {
std::ofstream file;
file.open (path);
file << CurrentTextView().get_buffer()->get_text();
file.close();
text_vec_.at(CurrentPage())->set_file_path(path);
text_vec_.at(CurrentPage())->set_is_saved(true);
}
}
}
std::string Notebook::Controller::OnSaveFileAs(){
Gtk::FileChooserDialog dialog("Please choose a file",
Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.set_transient_for(*window_);
dialog.set_position(Gtk::WindowPosition::WIN_POS_CENTER_ALWAYS);
dialog.add_button("_Cancel", Gtk::RESPONSE_CANCEL);
dialog.add_button("_Save", Gtk::RESPONSE_OK);
int result = dialog.run();
switch (result) {
case(Gtk::RESPONSE_OK): {
std::string path = dialog.get_filename();
unsigned pos = path.find_last_of("/\\");
std::cout << path<< std::endl;
//notebook_.OnSaveFile(path);
return path;
break;
}
return BufferHistory().back();
case(Gtk::RESPONSE_CANCEL): {
break;
}
void Notebook::Controller::OnUndo() {
// PrintQue();
// std::cout << "UNDOING SOMETHING TERRIBLE" << std::endl;
Glib::RefPtr<Gtk::TextBuffer> buf = CurrentTextView().get_buffer();
buf->set_text(LastBufferState());
std::cout << "Undoing.."<< std::endl;
PrintQue();
default: {
std::cout << "Unexpected button clicked." << std::endl;
break;
}
void Notebook::Controller::PrintQue(){
int size = BufferHistory().back().size();
std::cout << "buffer size: "<< size << std::endl
<< "buffer #: " << CurrentPage() << std::endl
<< "historylength: "<< BufferHistory().size() << std::endl;
}
//TODO remove first history event after open file
return "";
}

51
juci/notebook.h

@ -8,8 +8,9 @@
#include "directories.h"
#include <boost/algorithm/string/case_conv.hpp>
#include <type_traits>
#include <map>
#include <sigc++/sigc++.h>
#include <deque>
#include "clangmm.h"
namespace Notebook {
class Model {
@ -30,7 +31,7 @@ namespace Notebook {
};
class Controller {
public:
Controller(Keybindings::Controller& keybindings,
Controller(Gtk::Window* window, Keybindings::Controller& keybindings,
Source::Config& config,
Directories::Config& dir_cfg);
~Controller();
@ -40,6 +41,8 @@ namespace Notebook {
Gtk::Box& entry_view();
Gtk::Notebook& Notebook();
void OnBufferChange();
void BufferChangeHandler(Glib::RefPtr<Gtk::TextBuffer>
buffer);
void OnCloseCurrentPage();
std::string GetCursorWord();
void OnEditCopy();
@ -50,40 +53,40 @@ namespace Notebook {
void OnFileNewEmptyfile();
void OnFileNewHeaderFile();
void OnFileOpenFolder();
void OnSaveFile();
void OnDirectoryNavigation(const Gtk::TreeModel::Path& path,
Gtk::TreeViewColumn* column);
void OnNewPage(std::string name);
void OnOpenFile(std::string filename);
void OnCreatePage();
bool ScrollEventCallback(GdkEventScroll* scroll_event);
void MapBuffers(std::map<std::string, std::string> *buffers);
clang::Index* index() { return &index_; }
int Pages();
Directories::Controller& directories() { return directories_; }
Gtk::Paned& view();
void GeneratePopup(std::vector<string> items);
// Gtk::HBox& view();
bool GeneratePopup(int key);
void Search(bool forward);
const Source::Config& source_config() { return source_config_; }
bool OnMouseRelease(GdkEventButton* button);
bool OnKeyRelease(GdkEventKey* key);
std::string OnSaveFileAs();
protected:
void BufferChangeHandler(Glib::RefPtr<Gtk::TextBuffer> buffer);
void TextViewHandlers(Gtk::TextView& textview);
void PopupSelectHandler(Gtk::Dialog &popup,
Gtk::ListViewText &listview,
std::map<std::string, std::string>
*items);
private:
std::vector<std::deque<Glib::ustring>> history_;
const int kHistorySize = 30;
void NewBufferHistory(Glib::RefPtr<Gtk::TextBuffer> buffer);
void RemoveBufferHistory();
void UpdateHistory();
void AppendBufferState();
std::deque<Glib::ustring>& BufferHistory();
void PrintQue();
Glib::ustring& LastBufferState();
void OnUndo();
void CreateKeybindings(Keybindings::Controller& keybindings);
void FindPopupPosition(Gtk::TextView& textview,
int popup_x,
int popup_y,
int &x,
int &y);
void PopupSetSize(Gtk::ScrolledWindow& scroll,
int &current_x,
int &current_y);
Glib::RefPtr<Gtk::Builder> m_refBuilder;
Glib::RefPtr<Gio::SimpleActionGroup> refActionGroup;
Source::Config source_config_;
@ -100,6 +103,10 @@ namespace Notebook {
Gtk::TextIter search_match_end_;
Gtk::TextIter search_match_start_;
Glib::RefPtr<Gtk::Clipboard> refClipboard_;
bool ispopup;
Gtk::Dialog popup_;
Gtk::Window* window_;
clang::Index index_;
}; // class controller
} // namespace Notebook
#endif // JUCI_NOTEBOOK_H_

75
juci/source.cc

@ -4,7 +4,7 @@
#include <boost/property_tree/json_parser.hpp>
#include <fstream>
#include <boost/timer/timer.hpp>
#include "notebook.h"
#define log( var ) \
std::cout << "source.cc (" << __LINE__ << ") " << #var << std::endl
@ -102,16 +102,17 @@ Source::Model::Model(const Source::Config &config) :
void Source::Model::
InitSyntaxHighlighting(const std::string &filepath,
const std::string &project_path,
const std::string &text,
const std::map<std::string, std::string>
&buffers,
int start_offset,
int end_offset) {
set_file_path(filepath);
int end_offset,
clang::Index *index) {
set_project_path(project_path);
std::vector<const char*> arguments = get_compilation_commands();
tu_ = clang::TranslationUnit(true,
tu_ = clang::TranslationUnit(index,
filepath,
arguments,
text);
buffers);
}
// Source::View::UpdateLine
@ -123,7 +124,7 @@ OnLineEdit(const std::vector<Source::Range> &locations,
// Source::Model::UpdateLine
int Source::Model::
ReParse(const std::string &buffer) {
ReParse(const std::map<std::string, std::string> &buffer) {
return tu_.ReparseTranslationUnit(file_path(), buffer);
}
@ -132,6 +133,42 @@ ReParse(const std::string &buffer) {
// fired when a line in the buffer is edited
void Source::Controller::OnLineEdit() { }
void Source::Controller::
GetAutoCompleteSuggestions(int line_number,
int column,
std::vector<Source::AutoCompleteData>
*suggestions) {
parsing.lock();
std::map<std::string, std::string> buffers;
notebook_->MapBuffers(&buffers);
model().GetAutoCompleteSuggestions(buffers,
line_number,
column,
suggestions);
parsing.unlock();
}
void Source::Model::
GetAutoCompleteSuggestions(const std::map<std::string, std::string> &buffers,
int line_number,
int column,
std::vector<Source::AutoCompleteData>
*suggestions) {
clang::CodeCompleteResults results(&tu_,
file_path(),
buffers,
line_number,
column);
for (int i = 0; i < results.size(); i++) {
const vector<clang::CompletionChunk> chunks_ = results.get(i).get_chunks();
std::vector<AutoCompleteChunk> chunks;
for (auto &chunk : chunks_) {
chunks.emplace_back(chunk);
}
suggestions->emplace_back(chunks);
}
}
// sets the filepath for this mvc
void Source::Model::
set_file_path(const std::string &file_path) {
@ -228,9 +265,9 @@ HighlightToken(clang::Token *token,
// Source::Controller::Controller()
// Constructor for Controller
Source::Controller::Controller(const Source::Config &config) :
model_(config) {
}
Source::Controller::Controller(const Source::Config &config,
Notebook::Controller *notebook) :
model_(config), notebook_(notebook) { }
// Source::Controller::view()
// return shared_ptr to the view
@ -278,7 +315,7 @@ void Source::View::OnUpdateSyntax(const std::vector<Source::Range> &ranges,
Glib::RefPtr<Gtk::TextBuffer> buffer = get_buffer();
buffer->remove_all_tags(buffer->begin(), buffer->end());
for (auto &range : ranges) {
string type = std::to_string(range.kind());
std::string type = std::to_string(range.kind());
try {
config.typetable().at(type);
} catch (std::exception) {
@ -301,18 +338,22 @@ void Source::View::OnUpdateSyntax(const std::vector<Source::Range> &ranges,
}
void Source::Controller::OnOpenFile(const string &filepath) {
set_file_path(filepath);
sourcefile s(filepath);
std::map<std::string, std::string> buffers;
notebook_->MapBuffers(&buffers);
buffers[filepath] = s.get_content();
buffer()->set_text(s.get_content());
int start_offset = buffer()->begin().get_offset();
int end_offset = buffer()->end().get_offset();
if (check_extention(filepath)) {
view().ApplyConfig(model().config());
model().InitSyntaxHighlighting(filepath,
extract_file_path(filepath),
buffer()->get_text().raw(),
buffers,
start_offset,
end_offset);
end_offset,
notebook_->index());
view().OnUpdateSyntax(model().ExtractTokens(start_offset, end_offset),
model().config());
}
@ -323,7 +364,10 @@ void Source::Controller::OnOpenFile(const string &filepath) {
if (parsing.try_lock()) {
while (true) {
const std::string raw = buffer()->get_text().raw();
if (model().ReParse(raw) == 0 &&
std::map<std::string, std::string> buffers;
notebook_->MapBuffers(&buffers);
buffers[model().file_path()] = raw;
if (model().ReParse(buffers) == 0 &&
raw == buffer()->get_text().raw()) {
syntax.lock();
go = true;
@ -338,7 +382,6 @@ void Source::Controller::OnOpenFile(const string &filepath) {
}
});
buffer()->signal_begin_user_action().connect([this]() {
if (go) {
syntax.lock();

98
juci/source.h

@ -3,31 +3,34 @@
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
#include "gtkmm.h"
#include "clangmm.h"
#include <thread>
#include <mutex>
#include <string>
using std::string;
namespace Notebook {
class Controller;
}
namespace Source {
class Config {
public:
Config(const Config &original);
Config();
const std::unordered_map<string, string>& tagtable() const;
const std::unordered_map<string, string>& typetable() const;
void SetTagTable(const std::unordered_map<string, string> &tagtable);
void InsertTag(const string &key, const string &value);
void SetTypeTable(const std::unordered_map<string, string> &tagtable);
void InsertType(const string &key, const string &value);
const std::unordered_map<std::string, std::string>& tagtable() const;
const std::unordered_map<std::string, std::string>& typetable() const;
void SetTagTable(const std::unordered_map<std::string, std::string>
&tagtable);
void InsertTag(const std::string &key, const std::string &value);
void SetTypeTable(const std::unordered_map<std::string, std::string>
&tagtable);
void InsertType(const std::string &key, const std::string &value);
private:
std::unordered_map<string, string> tagtable_;
std::unordered_map<string, string> typetable_;
string background_;
std::unordered_map<std::string, std::string> tagtable_;
std::unordered_map<std::string, std::string> typetable_;
std::string background_;
}; // class Config
class Location {
@ -48,13 +51,6 @@ namespace Source {
const Location& start() const { return start_; }
const Location& end() const { return end_; }
int kind() const { return kind_; }
void to_stream() const {
std::cout << "range: [" << start_.line_number()-1;
std::cout << ", " << end_.line_number()-1 << "] ";
std::cout << "<" << start_.column_offset()-1;
std::cout << ", " << end_.column_offset()-1 << ">";
std::cout << std::endl;
}
private:
Location start_;
Location end_;
@ -64,6 +60,7 @@ namespace Source {
class View : public Gtk::TextView {
public:
View();
virtual ~View() { }
void ApplyConfig(const Config &config);
void OnLineEdit(const std::vector<Range> &locations,
const Config &config);
@ -71,9 +68,27 @@ namespace Source {
const Config &config);
private:
string GetLine(const Gtk::TextIter &begin);
std::string GetLine(const Gtk::TextIter &begin);
}; // class View
class AutoCompleteChunk {
public:
explicit AutoCompleteChunk(const clang::CompletionChunk &chunk) :
chunk_(chunk.chunk()), kind_(chunk.kind()) { }
const std::string& chunk() const { return chunk_; }
const clang::CompletionChunkKind& kind() const { return kind_; }
private:
std::string chunk_;
enum clang::CompletionChunkKind kind_;
};
class AutoCompleteData {
public:
explicit AutoCompleteData(const std::vector<AutoCompleteChunk> &chunks) :
chunks_(chunks) { }
std::vector<AutoCompleteChunk> chunks_;
};
class Model{
public:
// constructor for Source::Model
@ -81,47 +96,64 @@ namespace Source {
// inits the syntax highligthing on file open
void InitSyntaxHighlighting(const std::string &filepath,
const std::string &project_path,
const std::string &text,
const std::map<std::string, std::string>
&buffers,
int start_offset,
int end_offset);
int end_offset,
clang::Index *index);
// sets the filepath for this mvc
void set_file_path(const string &file_path);
void set_file_path(const std::string &file_path);
// sets the project path for this mvc
void set_project_path(const string &project_path);
void set_project_path(const std::string &project_path);
// gets the file_path member
const string& file_path() const;
const std::string& file_path() const;
// gets the project_path member
const string& project_path() const;
const std::string& project_path() const;
// gets the config member
const Config& config() const;
void GetAutoCompleteSuggestions(const std::map<std::string, std::string>
&buffers,
int line_number,
int column,
std::vector<AutoCompleteData>
*suggestions);
~Model() { }
int ReParse(const std::string &buffer);
int ReParse(const std::map<std::string, std::string> &buffers);
std::vector<Range> ExtractTokens(int, int);
private:
Config config_;
string file_path_;
string project_path_;
std::string file_path_;
std::string project_path_;
clang::TranslationUnit tu_;
void HighlightToken(clang::Token *token,
std::vector<Range> *source_ranges,
int token_kind);
void HighlightCursor(clang::Token *token,
std::vector<Range> *source_ranges);
std::vector<const char*> get_compilation_commands();
};
class Controller {
public:
explicit Controller(const Source::Config &config);
Controller(const Source::Config &config,
Notebook::Controller *notebook);
Controller();
View& view();
Model& model();
void OnNewEmptyFile();
void OnOpenFile(const string &filename);
void OnOpenFile(const std::string &filename);
void GetAutoCompleteSuggestions(int line_number,
int column,
std::vector<AutoCompleteData>
*suggestions);
Glib::RefPtr<Gtk::TextBuffer> buffer();
bool is_saved() { return is_saved_; }
std::string path() { return model().file_path(); }
void set_is_saved(bool isSaved) { is_saved_ = isSaved; }
void set_file_path(std::string path) { model().set_file_path(path); }
private:
void OnLineEdit();
@ -129,10 +161,12 @@ namespace Source {
std::mutex syntax;
std::mutex parsing;
bool go = false;
bool is_saved_ = false;
protected:
View view_;
Model model_;
Notebook::Controller *notebook_;
}; // class Controller
} // namespace Source
#endif // JUCI_SOURCE_H_

88
juci/terminal.cc

@ -1,6 +1,94 @@
#include "terminal.h"
#include <iostream>
#include <thread>
Terminal::View::View(){
scrolledwindow_.add(textview_);
scrolledwindow_.set_size_request(-1,150);
view_.add(scrolledwindow_);
textview_.set_editable(false);
//Pango::TabArray tabsize;
//tabsize.set_tab(200,Pango::TAB_LEFT, 200);
//textview_.set_tabs(tabsize);
}
Terminal::Controller::Controller() {
folder_command_ = "";
}
void Terminal::Controller::SetFolderCommand(std::string path) {
int pos = path.find_last_of("/\\");
path.erase(path.begin()+pos,path.end());
folder_command_ = "cd "+ path + "; ";
}
void Terminal::Controller::CompileAndRun(std::string project_name) {
if (folder_command_=="") {
PrintMessage("juCi++ ERROR: Can not find project's CMakeList.txt\n");
} else {
if (running.try_lock()) {
std::thread execute([=]() {
Terminal().get_buffer()->set_text("");
ExecuteCommand("cmake .");
if (ExistInConsole(cmake_sucsess)){
ExecuteCommand("make");
if (ExistInConsole(make_built)){
if (FindExecutable(project_name)) {
ExecuteCommand("./"+project_name);
} else {
PrintMessage("juCi++ ERROR: Can not find Executable\n");
}
}
}
});
execute.detach();
running.unlock();
}
}
}
void Terminal::Controller::PrintMessage(std::string message){
Terminal().get_buffer()->
insert(Terminal().get_buffer()-> end(),"> "+message);
}
bool Terminal::Controller::FindExecutable(std::string executable) {
std::string build = Terminal().get_buffer()->get_text();
double pos = build.find(make_built);
Gtk::TextIter start = Terminal().get_buffer()->get_iter_at_offset(pos);
Gtk::TextIter end = Terminal().get_buffer()->get_iter_at_offset(pos);
while (!end.ends_line()) {
end.forward_char();
}
build = Terminal().get_buffer()->get_text(start, end);
pos = build.find_last_of(" ");
std::cout << "FINNER NY POS" << std::endl;
build = build.substr(pos+1);
std::cout <<"BUILD TARGET = "<< build << std::endl;
std::cout << "EXECUTABLE FILE = "<< executable << std::endl;
if(build != executable) return false;
return true;
}
bool Terminal::Controller::ExistInConsole(std::string string) {
double pos = Terminal().get_buffer()->
get_text().find(string);
if (pos == std::string::npos) return false;
return true;
}
void Terminal::Controller::ExecuteCommand(std::string command) {
command = folder_command_+command;
std::cout << "EXECUTE COMMAND: "<< command << std::endl;
FILE* p = popen(command.c_str(), "r");
if (p == NULL) {
PrintMessage("juCi++ ERROR: Failed to run command" + command + "\n");
}else {
char buffer[1028];
while (fgets(buffer, 1028, p) != NULL) {
PrintMessage(buffer);
}
pclose(p);
}
}

33
juci/terminal.h

@ -1,8 +1,7 @@
#ifndef JUCI_TERMINAL_H_
#define JUCI_TERMINAL_H_
#ifndef JUCI_NOTEBOOK_H_
#define JUCI_NOTEBOOK_H_
#include <iostream>
#include <mutex>
#include "gtkmm.h"
namespace Terminal {
@ -10,18 +9,34 @@ namespace Terminal {
class View {
public:
View();
//Gtk::HBox view() {return view_;}
Gtk::HBox& view() {return view_;}
Gtk::TextView& textview() {return textview_;}
private:
Gtk::HBox view_;
Gtk::TextBuffer buffer_;
Gtk::TextView textview_;
Gtk::ScrolledWindow scrolledwindow_;
}; // class view
class Controller {
public:
Controller();
Gtk::HBox& view() {return view_.view();}
Gtk::TextView& Terminal(){return view_.textview();}
void SetFolderCommand(std::string path);
void CompileAndRun(std::string project_name);
private:
void ExecuteCommand(std::string command);
bool OnButtonRealeaseEvent(GdkEventKey* key);
bool ExistInConsole(std::string string);
bool FindExecutable(std::string executable);
void PrintMessage(std::string message);
Terminal::View view_;
std::string folder_command_;
std::mutex running;
const std::string cmake_sucsess = "Build files have been written to:";
const std::string make_built = "Built target";
const std::string make_executable = "Linking CXX executable";
}; // class controller
} // namespace Terminal
#endif // JUCI_NOTEBOOK_H_
#endif // JUCI_TERMINAL_H_

53
juci/window.cc

@ -4,7 +4,7 @@ Window::Window() :
window_box_(Gtk::ORIENTATION_VERTICAL),
main_config_(),
keybindings_(main_config_.keybindings_cfg()),
notebook_(keybindings(), main_config_.source_cfg(), main_config_.dir_cfg()),
notebook_(this,keybindings(), main_config_.source_cfg(), main_config_.dir_cfg()),
menu_(keybindings()) {
set_title("juCi++");
set_default_size(600, 400);
@ -26,6 +26,50 @@ Window::Window() :
[this]() {
OnFileOpenFolder();
});
keybindings_.action_group_menu()->add(Gtk::Action::create("FileSaveAs",
"Save as"),
Gtk::AccelKey(keybindings_.config_
.key_map()["save_as"]),
[this]() {
notebook_.OnSaveFile();
});
keybindings_.action_group_menu()->add(Gtk::Action::create("FileSave",
"Save"),
Gtk::AccelKey(keybindings_.config_
.key_map()["save"]),
[this]() {
notebook_.OnSaveFile();
});
keybindings_.action_group_menu()->add(Gtk::Action::create("ProjectCompileAndRun",
"Compile And Run"),
Gtk::AccelKey(keybindings_.config_
.key_map()["compile_and_run"]),
[this]() {
terminal_.
SetFolderCommand("/home/gm/ClionProjects/testi/CM.txt");
std::string p = notebook_.directories().get_project_name("/home/gm/ClionProjects/testi");
terminal_.CompileAndRun(p);
});
keybindings_.action_group_menu()->add(Gtk::Action::create("ProjectCompile",
"Compile"),
Gtk::AccelKey(keybindings_.config_
.key_map()["compile"]),
[this]() {
terminal_.
SetFolderCommand("/home/gm/ClionProjects/testi/CM.txt");
std::string p = notebook_.directories().get_project_name("/home/gm/ClionProjects/testi");
terminal_.CompileAndRun(p);
});
this->signal_button_release_event().
connect(sigc::mem_fun(*this,&Window::OnMouseRelease),false);
terminal_.Terminal().signal_button_release_event().
connect(sigc::mem_fun(*this,&Window::OnMouseRelease),false);
PluginApi::menu_ = &menu_;
PluginApi::notebook_ = &notebook_;
PluginApi::InitPlugins();
@ -37,6 +81,7 @@ Window::Window() :
window_box_.pack_start(menu_.view(), Gtk::PACK_SHRINK);
window_box_.pack_start(notebook_.entry_view(), Gtk::PACK_SHRINK);
window_box_.pack_start(notebook_.view());
window_box_.pack_end(terminal_.view(),Gtk::PACK_SHRINK);
show_all_children();
} // Window constructor
@ -62,6 +107,7 @@ void Window::OnFileOpenFolder() {
std::cout << "Folder selected: " << dialog.get_filename()
<< std::endl;
notebook_.directories().open_folder(dialog.get_filename());
std::cout << dialog.get_filename()<< std::endl;
break;
}
case(Gtk::RESPONSE_CANCEL):
@ -112,6 +158,7 @@ void Window::OnOpenFile() {
case(Gtk::RESPONSE_OK): {
std::cout << "Open clicked." << std::endl;
std::string path = dialog.get_filename();
std::cout << "File selected: " << path << std::endl;
notebook_.OnOpenFile(path);
break;
@ -126,3 +173,7 @@ void Window::OnOpenFile() {
}
}
}
bool Window::OnMouseRelease(GdkEventButton *button){
return notebook_.OnMouseRelease(button);
}

8
juci/window.h

@ -3,6 +3,7 @@
#include "api.h"
#include "config.h"
#include "terminal.h"
#include <cstddef>
@ -10,8 +11,9 @@ class Window : public Gtk::Window {
public:
Window();
MainConfig& main_config() { return main_config_; }
// std::string OnSaveFileAs();
Gtk::Box window_box_;
virtual ~Window() { }
//private:
@ -19,8 +21,7 @@ public:
Keybindings::Controller keybindings_;
Menu::Controller menu_;
Notebook::Controller notebook_;
Terminal::Controller terminal_;
Keybindings::Controller& keybindings() { return keybindings_; }
private:
@ -29,6 +30,7 @@ public:
void OnOpenFile();
void OnFileOpenFolder();
bool OnMouseRelease(GdkEventButton* button);
};
#endif // JUCI_WINDOW_H

Loading…
Cancel
Save