Changeset 27da386750c112ed04942bbc385964b4332bb128

Show
Ignore:
Timestamp:
01/06/07 23:57:10 (6 years ago)
Author:
Philipp Kern <phil@…>
Parents:
c2b92c82bb989b2a80f8fb8b5707f4165443e796
Children:
124a20ea0ece36b7e067b4b033f65127f2cee14a
git-committer:
Philipp Kern <phil@0x539.de> / 2007-01-06T22:57:10Z+0000
Message:

[project @ Gobby seems to work now, but still needs further testing]

Original author: Armin Burgmeier <armin@…>
Date: 2006-02-23 15:40:50+00:00

Files:
6 modified

Legend:

Unmodified
Added
Removed
  • inc/document.hpp

    rc2b92c8 r27da386  
    2424#include <obby/user_table.hpp> 
    2525#include <obby/text.hpp> 
     26#include <obby/local_buffer.hpp> 
     27#include "gselector.hpp" 
    2628#include "sourceview/sourcebuffer.hpp" 
    2729 
     
    9193        }; 
    9294 
     95        // TODO: Only take user table as soon as the user table has signals 
     96        // like on_user_join and on_user_part 
    9397        class template_type 
    9498        { 
    9599        public: 
     100                // buffer_def cannot be included since it depends on this file 
     101                typedef obby::basic_local_buffer<Document, GSelector> 
     102                        buffer_type; 
     103 
    96104                template_type(); // Default ctor, needed by obby, invalid 
    97                 template_type(const obby::user_table& user_table); 
    98  
    99                 const obby::user_table& get_user_table() const; 
     105                template_type(const buffer_type& buffer); 
     106 
     107                const buffer_type& get_buffer() const; 
    100108 
    101109        protected: 
    102                 const obby::user_table* m_user_table; 
     110                const buffer_type* m_buffer; 
    103111        }; 
     112 
     113        typedef sigc::signal<void, obby::position, const std::string> 
     114                signal_insert_type; 
     115        typedef sigc::signal<void, obby::position, obby::position> 
     116                signal_erase_type; 
    104117 
    105118        /** @brief Creates a new document that belongs to the given buffer. 
     
    162175         */ 
    163176        Glib::RefPtr<Gtk::SourceBuffer> get_buffer() const; 
     177 
     178        /** @brief Signal that is emitted when the local user wants to insert 
     179         * text. 
     180         */ 
     181        signal_insert_type insert_event() const; 
     182 
     183        /** @brief Signal that is emitted when the local user wants to erase 
     184         * text. 
     185         */ 
     186        signal_erase_type erase_event() const; 
    164187protected: 
    165188        typedef std::list<Glib::RefPtr<const Gtk::TextTag> > tag_list_type; 
     
    174197         */ 
    175198        void on_user_color(const obby::user& user); 
     199 
     200        /** @brief Callback when text is inserted. This tells obby to insert 
     201         * text into the document. 
     202         */ 
     203        void on_insert_before(const Gtk::TextIter& iter, 
     204                              const Glib::ustring& text); 
     205 
     206        /** @brief Callback when text is inserted. This tags newly inserted 
     207         * text. 
     208         */ 
     209        void on_insert_after(const Gtk::TextIter& iter, 
     210                             const Glib::ustring& text); 
     211 
     212        /** @brief Callback when text is erased. This tells obby to erase 
     213         * text from the document. 
     214         */ 
     215        void on_erase_before(const Gtk::TextIter& begin, 
     216                             const Gtk::TextIter& end); 
     217 
     218        /** @brief Denies application of tags we do not want. 
     219         */ 
     220        void on_apply_tag_before(const Glib::RefPtr<Gtk::TextTag>& tag, 
     221                                 const Gtk::TextIter& begin, 
     222                                 const Gtk::TextIter& end); 
    176223 
    177224        /** @brief Returns an iterator that points at the given position. 
     
    211258                                  const std::string& str, 
    212259                                  const obby::user* author); 
     260 
     261        /** @brief Tags a given range of text as written by <em>with</em>. 
     262         */ 
     263        void tag_text(const Gtk::TextIter& begin, 
     264                      const Gtk::TextIter& end, 
     265                      const obby::user* with); 
    213266 
    214267        /** @brief Helper class to use Glib::RefPtr<Gtk::TextTag> as index 
     
    239292        map_user_type m_map_user; 
    240293        map_tag_type m_map_tag; 
    241  
     294        const obby::user& m_self; 
     295 
     296        // Whether text is currently edited, needed to prevent recursion 
     297        // in signal emission 
     298        bool m_editing; 
    242299        Glib::RefPtr<Gtk::SourceBuffer> m_buffer; 
     300 
     301        signal_insert_type m_signal_insert; 
     302        signal_erase_type m_signal_erase; 
    243303}; 
    244304 
  • inc/docwindow.hpp

    rc2b92c8 r27da386  
    9090        bool get_modified() const; // TODO: Remove this in favor of get_document().get_buffer()->get_modified() 
    9191 
     92        /** @brief Gives the focus to the underlaying sourceview instead of 
     93         * the scrolled window containing it. 
     94         */ 
     95        void grab_focus(); 
     96 
    9297        /** @brief Returns the current Gtk::SourceLanguage the document is 
    9398         * highlighted with. 
     
    152157        void on_changed(); 
    153158 
     159        /** @brief Callback when text has to be inserted. 
     160         */ 
     161        void on_insert(obby::position pos, 
     162                       const std::string& text); 
     163 
     164        /** @brief Callback when text has to be erased. 
     165         */ 
     166        void on_erase(obby::position pos, 
     167                      obby::position len); 
     168 
    154169        /** @brief Helper function that applies the preferences to the buffer. 
    155170         */ 
  • src/document.cpp

    rc2b92c8 r27da386  
    3939        void forward_bytes(Gtk::TextIter& iter, std::size_t bytes) 
    4040        { 
    41                 while(bytes > 0) 
     41                while(bytes > 0 && !iter.is_end() ) 
    4242                { 
    4343                        std::size_t remaining_bytes = 
     
    4949                                iter.set_line_index( 
    5050                                        iter.get_line_index() + 
    51                                         remaining_bytes 
     51                                        bytes 
    5252                                ); 
    5353 
     
    6060 
    6161                        bytes -= remaining_bytes; 
     62                } 
     63 
     64                if(bytes > 0 && iter.is_end() ) 
     65                { 
     66                        throw std::logic_error( 
     67                                "document.cpp:forward_bytes:\n" 
     68                                "Bytes to forward exceed buffer size" 
     69                        ); 
    6270                } 
    6371        } 
     
    95103        } 
    96104 
    97 } 
    98  
    99 // TODO: Apply tags to self-written text 
     105        class editor: private net6::non_copyable 
     106        { 
     107        public: 
     108                editor(bool& edit_var): 
     109                        m_edit_var(edit_var) 
     110                { 
     111                        if(m_edit_var == true) 
     112                        { 
     113                                throw std::logic_error( 
     114                                        "document.cpp:editor::editor:\n" 
     115                                        "Edit var is already true" 
     116                                ); 
     117                        } 
     118 
     119                        m_edit_var = true; 
     120                } 
     121 
     122                ~editor() 
     123                { 
     124                        m_edit_var = false; 
     125                } 
     126 
     127        private: 
     128                bool& m_edit_var; 
     129        }; 
     130} 
    100131 
    101132Gobby::Document::chunk_iterator::chunk_iterator(const Document& doc, 
     
    119150Gobby::Document::chunk_iterator& Gobby::Document::chunk_iterator::operator++() 
    120151{ 
     152        m_author = m_next_author; 
    121153        m_iter_begin = m_iter_end; 
     154 
    122155        proceed_end(); 
     156        return *this; 
    123157} 
    124158 
     
    144178void Gobby::Document::chunk_iterator::proceed_end() 
    145179{ 
    146         m_author = m_next_author; 
     180        //m_author = m_next_author; 
    147181        m_next_author = m_doc.forward_chunk(m_iter_end); 
    148182} 
    149183 
    150184Gobby::Document::template_type::template_type(): 
    151         m_user_table(NULL) 
     185        m_buffer(NULL) 
    152186{ 
    153187} 
    154188 
    155189Gobby::Document::template_type:: 
    156         template_type(const obby::user_table& user_table): 
    157         m_user_table(&user_table) 
    158 { 
    159 } 
    160  
    161 const obby::user_table& Gobby::Document::template_type::get_user_table() const 
    162 { 
    163         if(m_user_table == NULL) 
     190        template_type(const buffer_type& buffer): 
     191        m_buffer(&buffer) 
     192{ 
     193} 
     194 
     195const Gobby::Document::template_type::buffer_type& 
     196Gobby::Document::template_type::get_buffer() const 
     197{ 
     198        if(m_buffer == NULL) 
    164199        { 
    165200                throw std::logic_error( 
    166                         "Gobby::Document::template_type::get_user_table:\n" 
    167                         "Invalid template, no user table present" 
     201                        "Gobby::Document::template_type::get_buffer:\n" 
     202                        "Invalid template, no buffer present" 
    168203                ); 
    169204        } 
    170205 
    171         return *m_user_table; 
     206        return *m_buffer; 
    172207} 
    173208 
    174209Gobby::Document::Document(const template_type& tmpl): 
    175         m_buffer(Gtk::SourceBuffer::create() ) 
    176 { 
    177         const obby::user_table& table = tmpl.get_user_table(); 
     210        m_self(tmpl.get_buffer().get_self() ), 
     211        m_editing(false), m_buffer(Gtk::SourceBuffer::create() ) 
     212{ 
     213        const template_type::buffer_type& buf = tmpl.get_buffer(); 
     214        const obby::user_table& table = buf.get_user_table(); 
     215 
    178216        for(obby::user_table::iterator iter = 
    179217                table.begin(obby::user::flags::NONE, obby::user::flags::NONE); 
     
    184222        } 
    185223 
     224        m_buffer->signal_insert().connect( 
     225                sigc::hide(sigc::mem_fun(*this, &Document::on_insert_before)), 
     226                false 
     227        ); 
     228 
     229        m_buffer->signal_insert().connect( 
     230                sigc::hide(sigc::mem_fun(*this, &Document::on_insert_after)), 
     231                true 
     232        ); 
     233 
     234        m_buffer->signal_erase().connect( 
     235                sigc::mem_fun(*this, &Document::on_erase_before), 
     236                false 
     237        ); 
     238 
     239        m_buffer->signal_apply_tag().connect( 
     240                sigc::mem_fun(*this, &Document::on_apply_tag_before), 
     241                false 
     242        ); 
     243 
    186244        // TODO: Connect to user table's signal handler - as soon as it 
    187245        // has some... 
    188 /*      buf.user_join_event().connect( 
     246        buf.user_join_event().connect( 
    189247                sigc::mem_fun(*this, &Document::on_user_join) ); 
    190248        buf.user_colour_event().connect( 
    191                 sigc::mem_fun(*this, &Document::on_user_color) );*/ 
     249                sigc::mem_fun(*this, &Document::on_user_color) ); 
    192250} 
    193251 
     
    249307                ); 
    250308        } 
     309 
     310        return result; 
    251311} 
    252312 
     
    264324                             const obby::text& str) 
    265325{ 
     326        if(m_editing) return; 
     327        editor edit(m_editing); 
     328 
    266329        Gtk::TextIter iter = get_iter(pos); 
    267330        insert_impl(iter, str); 
     
    272335                             const obby::user* author) 
    273336{ 
     337        if(m_editing) return; 
     338        editor edit(m_editing); 
     339 
    274340        Gtk::TextIter iter = get_iter(pos); 
    275341        insert_impl(iter, str, author); 
     
    278344void Gobby::Document::erase(obby::position pos, obby::position len) 
    279345{ 
     346        if(m_editing) return; 
     347        editor edit(m_editing); 
     348 
    280349        Gtk::TextIter begin = get_iter(pos); 
    281350        Gtk::TextIter end = begin; 
     
    287356void Gobby::Document::append(const obby::text& str) 
    288357{ 
     358        if(m_editing) return; 
     359        editor edit(m_editing); 
     360 
    289361        insert_impl(m_buffer->end(), str); 
    290362} 
     
    293365                             const obby::user* author) 
    294366{ 
     367        if(m_editing) return; 
     368        editor edit(m_editing); 
     369 
    295370        insert_impl(m_buffer->end(), str, author); 
    296371} 
     
    299374{ 
    300375        return m_buffer; 
     376} 
     377 
     378Gobby::Document::signal_insert_type Gobby::Document::insert_event() const 
     379{ 
     380        return m_signal_insert; 
     381} 
     382 
     383Gobby::Document::signal_erase_type Gobby::Document::erase_event() const 
     384{ 
     385        return m_signal_erase; 
    301386} 
    302387 
     
    336421} 
    337422 
     423void Gobby::Document::on_insert_before(const Gtk::TextIter& iter, 
     424                                       const Glib::ustring& text) 
     425{ 
     426        // Only local edits that are not done via insert 
     427        if(m_editing) return; 
     428        editor edit(m_editing); 
     429 
     430        m_signal_insert.emit(diff_bytes(m_buffer->begin(), iter), text); 
     431} 
     432 
     433void Gobby::Document::on_insert_after(const Gtk::TextIter& iter, 
     434                                      const Glib::ustring& text) 
     435{ 
     436        if(m_editing) return; 
     437        editor edit(m_editing); 
     438 
     439        Gtk::TextIter begin = iter; 
     440        begin.backward_chars(text.length() ); 
     441 
     442        tag_text(begin, iter, &m_self); 
     443} 
     444 
     445void Gobby::Document::on_erase_before(const Gtk::TextIter& begin, 
     446                                      const Gtk::TextIter& end) 
     447{ 
     448        // Only local edits that are not done via erase 
     449        if(m_editing) return; 
     450 
     451        editor edit(m_editing); 
     452        m_signal_erase.emit( 
     453                diff_bytes(m_buffer->begin(), begin), 
     454                diff_bytes(begin, end) 
     455        ); 
     456} 
     457 
     458void Gobby::Document::on_apply_tag_before(const Glib::RefPtr<Gtk::TextTag>& tag, 
     459                                          const Gtk::TextIter& begin, 
     460                                          const Gtk::TextIter& end) 
     461{ 
     462        if(m_map_tag.find(tag) != m_map_tag.end() && !m_editing) 
     463                m_buffer->signal_apply_tag().emission_stop(); 
     464} 
     465 
    338466Gtk::TextIter Gobby::Document::get_iter(obby::position at) const 
    339467{ 
    340468        Gtk::TextIter pos; 
    341469        for(pos = m_buffer->begin(); 
    342             at > 0 && pos != m_buffer->end(); 
    343             pos.forward_line() ) 
     470            at > 0 && pos != m_buffer->end();) 
    344471        { 
    345472                obby::position new_bytes = pos.get_bytes_in_line(); 
     473 
    346474                if(new_bytes > at) 
    347475                { 
    348476                        pos.set_line_index(at); 
    349                         return pos; 
     477                        new_bytes = at; 
     478                } 
     479                else 
     480                { 
     481                        pos.forward_line(); 
    350482                } 
    351483 
     
    361493        } 
    362494 
    363         return m_buffer->end(); 
     495        return pos; //m_buffer->end(); 
    364496} 
    365497 
     
    375507        } 
    376508 
    377         return false; 
     509        return NULL; 
    378510} 
    379511 
     
    427559                                           const obby::user* author) 
    428560{ 
    429         if(author != NULL) 
    430         { 
    431                 map_user_type::const_iterator user_it = 
    432                         m_map_user.find(author); 
     561        Gtk::TextIter result = m_buffer->insert(iter, str); 
     562 
     563        Gtk::TextIter begin = result; 
     564        begin.backward_chars(g_utf8_strlen(str.c_str(), -1)); 
     565 
     566        tag_text(begin, result, author); 
     567        return result; 
     568 
     569        return result; 
     570} 
     571 
     572Gtk::TextIter Gobby::Document::insert_impl(const Gtk::TextIter& iter, 
     573                                           const obby::text& str) 
     574{ 
     575        Gtk::TextIter pos = iter; 
     576 
     577        for(obby::text::chunk_iterator chunk_it = str.chunk_begin(); 
     578            chunk_it != str.chunk_end(); 
     579            ++ chunk_it) 
     580        { 
     581                pos = insert_impl( 
     582                        pos, 
     583                        chunk_it->get_text(), 
     584                        chunk_it->get_author() 
     585                ); 
     586        } 
     587 
     588        return pos; 
     589} 
     590 
     591void Gobby::Document::tag_text(const Gtk::TextIter& begin, 
     592                               const Gtk::TextIter& end, 
     593                               const obby::user* with) 
     594{ 
     595        for(map_user_type::const_iterator user_iter = m_map_user.begin(); 
     596            user_iter != m_map_user.end(); 
     597            ++ user_iter) 
     598        { 
     599                m_buffer->remove_tag(user_iter->second, begin, end); 
     600        } 
     601 
     602        if(with != NULL) 
     603        { 
     604                map_user_type::const_iterator user_it = m_map_user.find(with); 
    433605 
    434606                if(user_it == m_map_user.end() ) 
     
    440612                } 
    441613 
    442                 // TODO: Remove all other tags. 
    443                 // TODO: on_apply_tag_after 
    444                 return m_buffer->insert_with_tag(iter, str, user_it->second); 
    445         } 
    446         else 
    447         { 
    448                 // TODO: Remove all other tags. 
    449                 // TODO: on_apply_tag_after 
    450                 return m_buffer->insert(iter, str); 
    451         } 
    452 } 
    453  
    454 Gtk::TextIter Gobby::Document::insert_impl(const Gtk::TextIter& iter, 
    455                                            const obby::text& str) 
    456 { 
    457         Gtk::TextIter pos = iter; 
    458  
    459         for(obby::text::chunk_iterator chunk_it = str.chunk_begin(); 
    460             chunk_it != str.chunk_end(); 
    461             ++ chunk_it) 
    462         { 
    463                 pos = insert_impl( 
    464                         pos, 
    465                         chunk_it->get_text(), 
    466                         chunk_it->get_author() 
    467                 ); 
    468         } 
    469  
    470         return pos; 
    471 } 
     614                m_buffer->apply_tag(user_it->second, begin, end); 
     615        } 
     616} 
     617 
    472618#if 0 
    473619 
  • src/docwindow.cpp

    rc2b92c8 r27da386  
    7373        ); 
    7474 
     75        m_doc.insert_event().connect( 
     76                sigc::mem_fun(*this, &DocWindow::on_insert) 
     77        ); 
     78 
     79        m_doc.erase_event().connect( 
     80                sigc::mem_fun(*this, &DocWindow::on_erase) 
     81        ); 
     82 
    7583        apply_preferences(); 
    7684        buf->set_modified(!m_doc.empty() ); 
     
    148156} 
    149157 
     158void Gobby::DocWindow::grab_focus() 
     159{ 
     160        m_view.grab_focus(); 
     161} 
     162 
    150163Glib::RefPtr<Gtk::SourceLanguage> Gobby::DocWindow::get_language() const 
    151164{ 
     
    226239        m_signal_cursor_moved.emit(); 
    227240        m_signal_content_changed.emit(); 
     241} 
     242 
     243void Gobby::DocWindow::on_insert(obby::position pos, 
     244                                 const std::string& error) 
     245{ 
     246        m_info.insert(pos, error); 
     247} 
     248 
     249void Gobby::DocWindow::on_erase(obby::position pos, 
     250                                obby::position len) 
     251{ 
     252        m_info.erase(pos, len); 
    228253} 
    229254 
  • src/hostprogressdialog.cpp

    rc2b92c8 r27da386  
    8080                buffer->set_document_template( 
    8181                        HostBuffer::document_type::template_type( 
    82                                 buffer->get_user_table() 
     82                                *buffer 
    8383                        ) 
    8484                ); 
  • src/joinprogressdialog.cpp

    rc2b92c8 r27da386  
    131131                buffer->set_document_template( 
    132132                        ClientBuffer::document_type::template_type( 
    133                                 buffer->get_user_table() 
     133                                *buffer 
    134134                        ) 
    135135                );