dialogline.cc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  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 <stdlib.h>
  19. #include "dialogline.h"
  20. #include "editor.h"
  21. #include "inputline.h"
  22. #include "question.h"
  23. #include "dbg.h"
  24. DialogLine::DialogLine(Editor *aApp)
  25. {
  26. app = aApp;
  27. modal_widget = NULL;
  28. transient = false;
  29. }
  30. void DialogLine::resize(int lines, int columns, int y, int x)
  31. {
  32. Label::resize(lines, columns, y, x);
  33. if (modal_widget)
  34. modal_widget->resize(lines, columns, y, x);
  35. }
  36. void DialogLine::show_message(const char *msg)
  37. {
  38. set_text(msg);
  39. transient = true;
  40. }
  41. void DialogLine::show_error_message(const char *msg)
  42. {
  43. set_text(msg);
  44. transient = false;
  45. }
  46. void DialogLine::show_message_fmt(const char *fmt, ...)
  47. {
  48. u8string msg;
  49. va_list ap;
  50. va_start(ap, fmt);
  51. msg.vcformat(fmt, ap);
  52. va_end(ap);
  53. show_message(msg.c_str());
  54. }
  55. INTERACTIVE void DialogLine::layout_windows()
  56. {
  57. app->layout_windows();
  58. // move the cursor back to the modal widget
  59. if (modal_widget)
  60. modal_widget->invalidate_view();
  61. }
  62. INTERACTIVE void DialogLine::refresh()
  63. {
  64. app->refresh();
  65. // move the cursor back to the modal widget
  66. if (modal_widget)
  67. modal_widget->invalidate_view();
  68. }
  69. void DialogLine::clear_transient_message()
  70. {
  71. if (!empty() && transient)
  72. set_text("");
  73. }
  74. INTERACTIVE void DialogLine::cancel_modal()
  75. {
  76. modal_canceled = true;
  77. }
  78. // modalize() - does event pumping on some interactive widget.
  79. void DialogLine::modalize(Widget *wgt)
  80. {
  81. modal_widget = wgt;
  82. wgt->resize(window_height(), window_width(), window_begy(), window_begx());
  83. modal_canceled = false;
  84. while (wgt->is_modal() && !modal_canceled) {
  85. Event evt;
  86. wgt->update();
  87. doupdate();
  88. get_next_event(evt, wgt->wnd);
  89. if (!handle_event(evt))
  90. wgt->handle_event(evt);
  91. }
  92. modal_widget = NULL;
  93. show_message(modal_canceled ? _("Canceled") : "");
  94. }
  95. bool DialogLine::ask_yes_or_no(const char *msg, bool *canceled)
  96. {
  97. Question ipt(msg);
  98. modalize(&ipt);
  99. if (canceled)
  100. *canceled = modal_canceled;
  101. return modal_canceled ? false : ipt.get_answer();
  102. }
  103. int DialogLine::get_number(const char *msg, int default_num, bool *canceled)
  104. {
  105. u8string cstrnum;
  106. cstrnum.cformat("%d", default_num);
  107. unistring strnum;
  108. strnum.init_from_utf8(cstrnum.c_str());
  109. InputLine ipt(msg, strnum);
  110. modalize(&ipt);
  111. if (canceled)
  112. *canceled = modal_canceled;
  113. if (modal_canceled) {
  114. return 0;
  115. } else {
  116. cstrnum.init_from_unichars(ipt.get_text());
  117. return atoi(cstrnum.c_str());
  118. }
  119. }
  120. unistring DialogLine::query(const char *msg, const char *default_text,
  121. int history_set, InputLine::CompleteType complete,
  122. bool *alt_kbd)
  123. {
  124. unistring text;
  125. text.init_from_utf8(default_text);
  126. return query(msg, text, history_set, complete, alt_kbd);
  127. }
  128. unistring DialogLine::query(const char *msg, const unistring &default_text,
  129. int history_set, InputLine::CompleteType complete,
  130. bool *alt_kbd)
  131. {
  132. InputLine ipt(msg, default_text, history_set, complete);
  133. if (alt_kbd)
  134. ipt.set_alt_kbd(*alt_kbd);
  135. modalize(&ipt);
  136. if (alt_kbd)
  137. *alt_kbd = ipt.get_alt_kbd();
  138. return modal_canceled ? unistring() : ipt.get_text();
  139. }
  140. void DialogLine::update()
  141. {
  142. if (modal_widget)
  143. modal_widget->update();
  144. else
  145. Label::update();
  146. }
  147. // immediate_update() - called when we want to update the terminal
  148. // immediately, without having to wait for the event pump. As an intentional
  149. // side effect, the terminal cursor moves to this window.
  150. // TODO: move to the Widget class?
  151. void DialogLine::immediate_update()
  152. {
  153. if (terminal::is_interactive()) {
  154. update();
  155. doupdate();
  156. }
  157. }