/* vim:set ts=4 sw=4 sts=4 et cindent: */ /* * nanodc - The ncurses DC++ client * Copyright © 2005-2006 Markus Lindqvist * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Contributor(s): * */ #include #include #include #include #include #include #include namespace input { TextInput::List TextInput::m_history; TextInput::List::const_iterator TextInput::m_historyPos = m_history.begin(); TextInput::TextInput(): m_utf8(false), m_pos(0) { m_bindings[KEY_HOME] = std::tr1::bind(&TextInput::set_pos, this, 0); m_bindings[KEY_END] = std::tr1::bind(&TextInput::set_pos, this, std::tr1::bind(&TextInput::length, this)); } void TextInput::update_config() { m_utf8 = core::Settings::get()->find_bool("utf8_input", false); } size_t TextInput::length() const { return g_utf8_strlen(c_str(), -1); } size_t TextInput::get_pos() const { return g_utf8_pointer_to_offset(c_str(), c_str()+m_pos); } void TextInput::enter() { if(m_history.size() > MAX_HISTORY) m_history.pop_back(); if(!this->empty()) m_history.push_front(*this); m_historyPos = m_history.begin(); std::string content = this->str(); clear(); m_pos = 0; } void TextInput::text_insert(const std::string &ch) { try { if(!g_utf8_validate(ch.c_str(), -1, 0)) throw std::runtime_error("g_utf8_validate failed"); String::insert(m_pos, ch); m_pos += ch.length(); } catch(std::exception &e) { core::Log::get()->log(std::string("Bug in TextInput::text_insert? ") + e.what()); return; } } void TextInput::key_insert(wint_t key) { char str[20]; utils::utf16_char_to_utf8(key, str)[str] = 0; text_insert(std::string(str)); } void TextInput::pressed(int key) { if(m_bindings.find(key) != m_bindings.end()) { m_bindings[key](); return; } switch (key) { // ^W case 0x17: { break; } case 0x7F: case 0x08: case KEY_BACKSPACE: if (m_pos != 0) { int prev = g_utf8_prev_char(c_str()+m_pos)-c_str(); erase(prev, m_pos-prev); m_pos = prev; } break; case KEY_DC: if (m_pos != size()) { int next = g_utf8_find_next_char(c_str()+m_pos, 0)-c_str(); erase(m_pos, (next-m_pos)); } break; case KEY_LEFT: if (m_pos != 0) { m_pos = g_utf8_prev_char(c_str()+m_pos)-c_str(); } break; case KEY_RIGHT: if (m_pos != size()) { m_pos = g_utf8_find_next_char(c_str()+m_pos, 0)-c_str(); } break; case KEY_UP: if(m_history.size() > 0) { if((m_historyPos == m_history.begin()) && (this->empty())) { assign(*m_historyPos); } else if(m_historyPos != m_history.end()-1) { assign(*(++m_historyPos)); } else { m_historyPos = m_history.begin(); clear(); } m_pos = size(); } break; case KEY_DOWN: if(m_historyPos != m_history.begin()) { assign(*(--m_historyPos)); } else { // save the written line even if enter // is not pressed (just like in Irssi) if(m_history.empty() || (!empty() && m_history.at(0) != str())) { m_history.push_front(*this); m_historyPos = m_history.begin(); } clear(); } m_pos = length(); break; case 0x0A: enter(); break; default: return; } } } // namespace input