// // CmdDialog.cc for pekwm // Copyright © 2004-2009 Claes Nästén // // This program is licensed under the GNU GPL. // See the LICENSE file for more information. // #ifdef HAVE_CONFIG_H #include "config.h" #endif // HAVE_CONFIG_H #include #include #include extern "C" { #include #include // XLookupString #include } #include "PWinObj.hh" #include "PDecor.hh" #include "CmdDialog.hh" #include "Config.hh" #include "PScreen.hh" #include "PixmapHandler.hh" #include "KeyGrabber.hh" #include "ScreenResources.hh" #include "Workspaces.hh" using std::cerr; using std::endl; using std::list; using std::string; using std::wstring; /** * CmdDialog constructor, init and load history file. * * @todo Make size configurable. */ CmdDialog::CmdDialog(Theme *theme) : InputDialog(theme, L"Enter command"), _completer(L";"), _exec_count(0) { _type = PWinObj::WO_CMD_DIALOG; // Setup completer _completer.add_method(new ActionCompleterMethod()); _completer.add_method(new PathCompleterMethod()); if (Config::instance()->getCmdDialogHistoryFile().size() > 0) { _hist_list.load(Config::instance()->getCmdDialogHistoryFile()); } } /** * CmdDialog de-structor, clean up and save history file. */ CmdDialog::~CmdDialog(void) { if (Config::instance()->getCmdDialogHistoryFile().size() > 0) { _hist_list.save(Config::instance()->getCmdDialogHistoryFile()); } } //! @brief Parses _buf and tries to generate an ActionEvent //! @return Pointer to ActionEvent. ActionEvent* CmdDialog::exec(void) { // Update history if (Config::instance()->isCmdDialogHistoryUnique()) { _hist_list.push_back_unique(_buf); } else { _hist_list.push_back(_buf); } if (_hist_list.size() > static_cast(Config::instance()->getCmdDialogHistorySize())) { _hist_list.pop_front(); } // Persist changes if (Config::instance()->getCmdDialogHistorySaveInterval() > 0 && Config::instance()->getCmdDialogHistoryFile().size() > 0 && ++_exec_count > Config::instance()->getCmdDialogHistorySaveInterval()) { _hist_list.save(Config::instance()->getCmdDialogHistoryFile()); _exec_count = 0; } // Check if it's a valid Action, if not we assume it's a command and try // to execute it. string buf_mb(Util::to_mb_str(_buf)); if (! Config::instance()->parseAction(buf_mb, _ae.action_list.back(), KEYGRABBER_OK)) { _ae.action_list.back().setAction(ACTION_EXEC); _ae.action_list.back().setParamS(buf_mb); } return &_ae; } //! @brief Unmaps window, overloaded to clear buffer. void CmdDialog::unmapWindow(void) { if (_mapped) { InputDialog::unmapWindow(); setWORef(0); bufClear(); } } /** * Tab completion, complete word at cursor position. */ void CmdDialog::complete(void) { // Find completion if changed since last time. if (_buf != _buf_on_complete_result) { InputDialog::complete(); _complete_list = _completer.find_completions(_buf, _pos); _complete_it = _complete_list.begin(); } if (_complete_list.size()) { _buf = _completer.do_complete(_buf_on_complete, _pos, _complete_list, _complete_it); _buf_on_complete_result = _buf; } } /** * Map CmdDialog centered on wo_ref is specified, else _wo_ref. */ void CmdDialog::mapCentered(const std::string &buf, bool focus, PWinObj *wo_ref) { if (wo_ref != 0) { setWORef(wo_ref); } InputDialog::mapCentered(buf, focus, wo_ref); }