// // Simple Text Editor Implementation // // Copyright (C) 1993 Ellemtel Telecommunication Systems Labratories // // Permission is granted to any individual or institution to use, copy, // modify, and distribute this software, provided that this complete // copyright and permission notice is maintained, intact, in all copies // and supporting documentation. // // Ellemtel Telecommunication Systems Labratories make no representation // of the suitability of this software for any purpose. It is provided // "as is" without any expressed or implied warranty. // // Jan Andersson, Torpa Konsult AB // janne@torpa.se - 1993-08-29 // /* * Modifications by Vectaport Inc.: * * scroll to follow cursor in (hopefully) all cases * fix scrollbar (actually its adjustable) so it positions perfectly * fix alt-V on linux/pc keyboard (and any other <0 characters) * improved layout/color * added text get/set methods for easier integration */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "textbuff.h" #include "textedit.h" #include "texteditor.h" #include "textview.h" // TE Adjustable TE_Adjustable::TE_Adjustable(TE_View* te_view) { te_view_ = te_view; } void TE_Adjustable::update(Observable*) { notify(Dimension_Y); // notify scrollbar } Coord TE_Adjustable::lower(DimensionName) const { return Coord(0); } Coord TE_Adjustable::upper(DimensionName) const { return Coord(te_view_->lines()); } Coord TE_Adjustable::length(DimensionName) const { return Coord(te_view_->lines() /*- 1*/); } Coord TE_Adjustable::cur_lower(DimensionName) const { return Coord(te_view_->lines() - te_view_->end_row() -1); } Coord TE_Adjustable::cur_upper(DimensionName) const { return Coord(te_view_->lines() /*- 1*/ - te_view_->start_row()); } Coord TE_Adjustable::cur_length(DimensionName) const { return Coord(te_view_->end_row() - te_view_->start_row() +1); } void TE_Adjustable::scroll_forward(DimensionName d) { scroll_by(d, -long(small_scroll(d))); } void TE_Adjustable::scroll_backward(DimensionName d) { scroll_by(d, long(small_scroll(d))); } void TE_Adjustable::page_forward(DimensionName d) { scroll_by(d, -long(large_scroll(d))); } void TE_Adjustable::page_backward(DimensionName d) { scroll_by(d, long(large_scroll(d))); } void TE_Adjustable::scroll_to(DimensionName, Coord lower) { GlyphIndex max_end = te_view_->lines(); GlyphIndex new_end = max_end - Math::round(lower); GlyphIndex new_start = new_end - te_view_->end_row() + te_view_->start_row(); te_view_->do_scroll(new_start); notify(Dimension_Y); // notify scrollbar } void TE_Adjustable::scroll_by(DimensionName, long offset) { te_view_->do_scroll(te_view_->start_row() + offset); notify(Dimension_Y); // notify scrollbar } EivTextEditor::EivTextEditor() { } EivTextEditor::EivTextEditor(Style* s, boolean active) { const LayoutKit& layout = *LayoutKit::instance(); WidgetKit& kit = *WidgetKit::instance(); style_ = new Style("TextEditor", s); Resource::ref(style_); double rows = 24; (void) style_->find_attribute("rows", rows); double cols = 80; (void) style_->find_attribute("columns", cols); // create buffer and view EivTextBuffer* te_buffer = new EivTextBuffer(); te_view_ = new TE_View(style_, te_buffer, int(rows), int(cols), active); // attach adjustable and scrollbar te_adjustable_ = new TE_Adjustable(te_view_); te_view_->attach(te_adjustable_); sb_ = kit.vscroll_bar(te_adjustable_); Display* d = Session::instance()->default_display(); const Color* bg = Color::lookup(d, "#aaaaaa"); if (bg == nil) bg = new Color(0.7,0.7,0.7,1.0); body( new Background( layout.margin( layout.hbox( kit.inset_frame( layout.vcenter(layout.margin(te_view_, 2.0), 1.0) ), layout.hspace(4.0), sb_ ), 5.0), bg ) ); } EivTextEditor::~EivTextEditor() { te_view_->detach(te_adjustable_); delete te_adjustable_; delete te_view_; delete sb_; Resource::unref(style_); } int EivTextEditor::load(const char* path) { if (path == nil || *path == '\0') return 1; return te_view_->load(path); } int EivTextEditor::save(const char* path) { if (path == nil) return te_view_->save_current(); else return te_view_->save_as(path); } void EivTextEditor::save_popup() { te_view_->save_popup(); } void EivTextEditor::load_popup() { te_view_->load_popup(); } void EivTextEditor::quit() { // quit without error check; Bug Alert! te_view_->quit(); } int EivTextEditor::dot() { return te_view_->text_editor()->Dot(); } int EivTextEditor::mark() { return te_view_->text_editor()->Mark(); } void EivTextEditor::select(const int dot, const int mark) { te_view_->text_editor()->Select(dot, mark); } void EivTextEditor::select_all() { te_view_->text_editor()->SelectAll(); } void EivTextEditor::select_beginning(const EivTextUnit unit) { switch (unit) { case EivTextEditor::Character: // not implemented break; case EivTextEditor::Word: te_view_->beginning_of_word(); break; case EivTextEditor::Line: te_view_->beginning_of_line(); break; case EivTextEditor::Text: te_view_->beginning_of_text(); break; } } void EivTextEditor::select_end(const EivTextUnit unit) { switch (unit) { case EivTextEditor::Character: // not implemented break; case EivTextEditor::Word: te_view_->end_of_word(); break; case EivTextEditor::Line: te_view_->end_of_line(); break; case EivTextEditor::Text: te_view_->end_of_text(); break; } } void EivTextEditor::select_backward(const EivTextUnit unit, const int count) { switch (unit) { case EivTextEditor::Character: te_view_->backward_char(count); break; case EivTextEditor::Word: te_view_->backward_word(count); break; case EivTextEditor::Line: te_view_->backward_line(count); break; case EivTextEditor::Text: // not implemented break; } } void EivTextEditor::select_forward(const EivTextUnit unit, const int count) { switch (unit) { case EivTextEditor::Character: te_view_->forward_char(count); break; case EivTextEditor::Word: te_view_->forward_word(count); break; case EivTextEditor::Line: te_view_->forward_line(count); break; case EivTextEditor::Text: // not implemented break; } } void EivTextEditor::find_forward(const char* pattern) { te_view_->find_forward(pattern); } void EivTextEditor::find_backward(const char* pattern) { te_view_->find_backward(pattern); } const char* EivTextEditor::text() { return te_view_->text(); } void EivTextEditor::text(const char* txt, boolean update) { te_view_->text(txt, update); } void EivTextEditor::insert_string(char* str, int count) { te_view_->insert_string(str, count); } InputHandler* EivTextEditor::focusable() { return te_view_; } TE_View* EivTextEditor::textview() { return te_view_; }