Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "element.h"
00036
00037 #include "dialog.h"
00038
00039 #include "common/wave_ex.h"
00040 #include "datahash/datahash_util.h"
00041
00042
00043 namespace dialog {
00044
00045
00046 static const int s_max = 126;
00047
00048
00049
00050
00051
00052
00053
00054 class Textbox : public Element {
00055 public:
00056 Textbox(void) throw();
00057 ~Textbox(void) throw() { }
00058
00059
00060 void initialize(IN const Datahash * hash,
00061 IN smart_ptr<Drawer>& drawer);
00062
00063
00064 int getWidth(void) { return m_width; }
00065 int getHeight(void) { return m_height; }
00066 void draw(IN const point_t& offset);
00067 void cursor(IN const point_t& pos) { }
00068 const char * keyboard(IN int key, IN int mods);
00069 Element * getFocus(IN const point_t& pos) { return this; }
00070 void notifyFocus(IN bool haveFocus) { m_haveFocus = haveFocus; }
00071 const char * button(IN int button, IN int state,
00072 IN const point_t& pos) { return NULL; }
00073 void addData(IN crypto::DESKey * key,
00074 IN Datahash * data);
00075
00076 private:
00077
00078
00079
00080 std::string m_name;
00081 char m_value[s_max + 2];
00082 std::string m_label;
00083 int m_max;
00084 int m_width;
00085 int m_height;
00086 int m_valueOffset;
00087 int m_size;
00088 int m_rise;
00089 int m_border;
00090 bool m_haveFocus;
00091 bool m_encrypt;
00092 smart_ptr<Drawer> m_drawer;
00093 };
00094
00095
00096
00097 Textbox::Textbox(void) throw()
00098 {
00099 m_max = 0;
00100 m_haveFocus = false;
00101 m_size = 0;
00102 m_border = 0;
00103 m_value[0] = 0;
00104 m_encrypt = false;
00105 }
00106
00107
00108
00109 void
00110 Textbox::initialize
00111 (
00112 IN const Datahash * hash,
00113 IN smart_ptr<Drawer>& drawer
00114 )
00115 {
00116 ASSERT(hash, "null");
00117 ASSERT(drawer, "null");
00118
00119 m_drawer = drawer;
00120 m_name = getString(hash, "name");
00121 std::string value = getString(hash, "value");
00122 m_max = getInt(hash, "max");
00123 if (m_max < 1) {
00124 WAVE_EX(wex);
00125 wex << "Bad textbox max size: " << m_max;
00126 }
00127 if (m_max > s_max) {
00128 DPRINTF("Truncating textbox size! Max is %d", s_max);
00129 m_max = s_max;
00130 }
00131 std::string enc = getOptionalString(hash, "encrypt", "");
00132 m_encrypt = ("true" == enc);
00133
00134
00135
00136
00137
00138
00139 m_label = m_name;
00140 m_label += ": ";
00141
00142
00143 font_size_t fs =
00144 m_drawer->getFontSizing(eElement_Textbox, m_label.c_str());
00145 m_width = fs.lead + fs.trail + 1;
00146 m_height = fs.rise + fs.drop + 1;
00147 m_rise = fs.rise;
00148
00149 border_size_t bs = m_drawer->getBorderSizing(eElement_Textbox);
00150 m_border = bs.size;
00151 m_width += bs.size;
00152 m_valueOffset = m_width + bs.size;
00153
00154
00155 for (int i = 0; i < m_max; ++i) {
00156 m_value[i] = 'M';
00157 }
00158 m_value[m_max] = '|';
00159 m_value[m_max + 1] = 0;
00160
00161
00162 fs = m_drawer->getFontSizing(eElement_Textbox, m_value);
00163 m_width += fs.lead + fs.trail + 1;
00164 m_width += 3 * bs.size;
00165
00166
00167 strncpy(m_value, value.c_str(), m_max);
00168 m_value[m_max] = 0;
00169 m_size = strlen(m_value);
00170
00171 ASSERT(m_size <= m_max, "Bad size? %d vs max %d", m_size, m_max);
00172
00173
00174 int height = fs.rise + fs.drop + 1;
00175 if (height > m_height) {
00176 m_height = height;
00177 }
00178 if (fs.rise > m_rise) {
00179 m_rise = fs.rise;
00180 }
00181 m_height += 2 * bs.size;
00182 }
00183
00184
00185
00186 void
00187 Textbox::draw
00188 (
00189 IN const point_t& offset
00190 )
00191 {
00192 ASSERT(m_drawer, "null");
00193
00194
00195 point_t pos(offset.x + m_border, offset.y + m_border + m_rise);
00196 m_drawer->drawString(eElement_Textbox, pos, m_label.c_str());
00197
00198
00199 if (m_haveFocus) {
00200 DPRINTF("TODO: focus?");
00201 }
00202 rect_t r(offset.x + m_valueOffset, offset.y,
00203 offset.x + m_width, offset.y + m_height);
00204 m_drawer->drawRectWithBorder(eElement_Textbox, r);
00205
00206
00207
00208 char save_val[s_max + 1];
00209 if (m_encrypt) {
00210 for (int i = 0; i < m_size; ++i) {
00211 save_val[i] = m_value[i];
00212 m_value[i] = '*';
00213 }
00214 save_val[m_size] = 0;
00215 }
00216
00217
00218
00219 bool showCaret = m_haveFocus && (time(NULL) % 2);
00220 if (showCaret) {
00221 m_value[m_size] = '|';
00222 m_value[m_size + 1] = 0;
00223 }
00224
00225 pos.x = offset.x + m_valueOffset + m_border;
00226 pos.y = offset.y + m_border + m_rise;
00227 m_drawer->drawString(eElement_Textbox, pos, m_value);
00228 if (showCaret) {
00229 m_value[m_size] = 0;
00230 }
00231
00232
00233 if (m_encrypt) {
00234 for (int i = 0; i < m_size; ++i) {
00235 m_value[i] = save_val[i];
00236 }
00237 m_value[m_size] = 0;
00238 }
00239 }
00240
00241
00242
00243 const char *
00244 Textbox::keyboard
00245 (
00246 IN int key,
00247 IN int mods
00248 )
00249 {
00250 char a = (char) key;
00251
00252 if (8 == key || 127 == key) {
00253
00254 if (m_size > 0) {
00255 m_size--;
00256 m_value[m_size] = 0;
00257 }
00258 } else if (isalnum(a) || 32 == a) {
00259
00260 if (m_size < m_max) {
00261 m_value[m_size] = a;
00262 ++m_size;
00263 m_value[m_size] = 0;
00264 }
00265 } else if (13 == key) {
00266
00267 return m_name.c_str();
00268 }
00269
00270
00271 return NULL;
00272 }
00273
00274
00275
00276 void
00277 Textbox::addData
00278 (
00279 IN crypto::DESKey * key,
00280 IN Datahash * data
00281 )
00282 {
00283
00284 ASSERT(data, "null");
00285
00286
00287 std::string enc;
00288 const char * val = m_value;
00289 if (m_encrypt) {
00290 if (!key) {
00291 WAVE_EX(wex);
00292 wex << "Asked to encrypt, but no encryption key ";
00293 wex << "provided. textbox name: " << m_name;
00294 }
00295 enc = key->encrypt(m_value, m_max);
00296 val = enc.c_str();
00297 }
00298 data->insert(m_name, val);
00299 }
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 smart_ptr<Element>
00310 createTextboxElement
00311 (
00312 IN Manager * mgr,
00313 IN const Datahash * hash
00314 )
00315 {
00316 ASSERT(mgr, "null");
00317 ASSERT(hash, "null");
00318
00319 smart_ptr<Textbox> local = new Textbox;
00320 ASSERT(local, "out of memory");
00321
00322 smart_ptr<Drawer> drawer = mgr->getDrawer();
00323 local->initialize(hash, drawer);
00324
00325 return local;
00326 }
00327
00328
00329
00330 };
00331