dialogline.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. // Copyright (C) 2003 Mooffie <mooffie@typo.co.il>
  2. //
  3. // This program is free software; you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation; either version 2 of the License, or
  6. // (at your option) any later version.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
  16. #include <config.h>
  17. #include <stdarg.h>
  18. #include "dialogline.h"
  19. #include "editor.h"
  20. #include "inputline.h"
  21. #include "question.h"
  22. #include "dbg.h"
  23. DialogLine::DialogLine(Editor *aApp)
  24. {
  25. app = aApp;
  26. modal_widget = NULL;
  27. transient = false;
  28. }
  29. void DialogLine::resize(int lines, int columns, int y, int x)
  30. {
  31. Label::resize(lines, columns, y, x);
  32. if (modal_widget)
  33. modal_widget->resize(lines, columns, y, x);
  34. }
  35. void DialogLine::show_message(const char *msg)
  36. {
  37. set_text(msg);
  38. transient = true;
  39. }
  40. void DialogLine::show_error_message(const char *msg)
  41. {
  42. set_text(msg);
  43. transient = false;
  44. }
  45. void DialogLine::show_message_fmt(const char *fmt, ...)
  46. {
  47. u8string msg;
  48. va_list ap;
  49. va_start(ap, fmt);
  50. msg.vcformat(fmt, ap);
  51. va_end(ap);
  52. show_message(msg.c_str());
  53. }
  54. INTERACTIVE void DialogLine::layout_windows()
  55. {
  56. app->layout_windows();
  57. // move the cursor back to the modal widget
  58. if (modal_widget)
  59. modal_widget->invalidate_view();
  60. }
  61. INTERACTIVE void DialogLine::refresh()
  62. {
  63. app->refresh();
  64. // move the cursor back to the modal widget
  65. if (modal_widget)
  66. modal_widget->invalidate_view();
  67. }
  68. void DialogLine::clear_transient_message()
  69. {
  70. if (!empty() && transient)
  71. set_text("");
  72. }
  73. INTERACTIVE void DialogLine::cancel_modal()
  74. {
  75. modal_canceled = true;
  76. }
  77. // modalize() - does event pumping on some interactive widget.
  78. void DialogLine::modalize(Widget *wgt)
  79. {
  80. modal_widget = wgt;
  81. wgt->resize(window_height(), window_width(), window_begy(), window_begx());
  82. modal_canceled = false;
  83. while (wgt->is_modal() && !modal_canceled) {
  84. Event evt;
  85. wgt->update();
  86. doupdate();
  87. get_next_event(evt, wgt->wnd);
  88. if (!handle_event(evt))
  89. wgt->handle_event(evt);
  90. }
  91. modal_widget = NULL;
  92. show_message(modal_canceled ? _("Canceled") : "");
  93. }
  94. bool DialogLine::ask_yes_or_no(const char *msg, bool *canceled)
  95. {
  96. Question ipt(msg);
  97. modalize(&ipt);
  98. if (canceled)
  99. *canceled = modal_canceled;
  100. return modal_canceled ? false : ipt.get_answer();
  101. }
  102. int DialogLine::get_number(const char *msg, int default_num, bool *canceled)
  103. {
  104. u8string cstrnum;
  105. cstrnum.cformat("%d", default_num);
  106. unistring strnum;
  107. strnum.init_from_utf8(cstrnum.c_str());
  108. InputLine ipt(msg, strnum);
  109. modalize(&ipt);
  110. if (canceled)
  111. *canceled = modal_canceled;
  112. if (modal_canceled) {
  113. return 0;
  114. } else {
  115. cstrnum.init_from_unichars(ipt.get_text());
  116. return atoi(cstrnum.c_str());
  117. }
  118. }
  119. unistring DialogLine::query(const char *msg, const char *default_text,
  120. int history_set, InputLine::CompleteType complete,
  121. bool *alt_kbd)
  122. {
  123. unistring text;
  124. text.init_from_utf8(default_text);
  125. return query(msg, text, history_set, complete, alt_kbd);
  126. }
  127. unistring DialogLine::query(const char *msg, const unistring &default_text,
  128. int history_set, InputLine::CompleteType complete,
  129. bool *alt_kbd)
  130. {
  131. InputLine ipt(msg, default_text, history_set, complete);
  132. if (alt_kbd)
  133. ipt.set_alt_kbd(*alt_kbd);
  134. modalize(&ipt);
  135. if (alt_kbd)
  136. *alt_kbd = ipt.get_alt_kbd();
  137. return modal_canceled ? unistring() : ipt.get_text();
  138. }
  139. void DialogLine::update()
  140. {
  141. if (modal_widget)
  142. modal_widget->update();
  143. else
  144. Label::update();
  145. }
  146. // immediate_update() - called when we want to update the terminal
  147. // immediately, without having to wait for the event pump. As an intentional
  148. // side effect, the terminal cursor moves to this window.
  149. // TODO: move to the Widget class?
  150. void DialogLine::immediate_update()
  151. {
  152. if (terminal::is_interactive()) {
  153. update();
  154. doupdate();
  155. }
  156. }