viewer.cxx
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
00030
00031 #include <cxxtls/viewermanager.h>
00032 #include <cxxtls/file.h>
00033 #include <cxxtls/cursesinterface.h>
00034 #include <cxxtls/strtool.h>
00035 #include <cxxtls/foreach.h>
00036
00037 using namespace std;
00038
00039 namespace cxxtls
00040 {
00041
00042 bool ListViewer::policies::is_special(size_t)
00043 {
00044 return false;
00045 }
00046
00047 inline
00048 int
00049 ListViewer::
00050 line_attribute(bool selected, size_t index, bool is_bottom)
00053 {
00054 int i=0;
00055
00056 if(selected) i += 1;
00057 if(com_->is_marked(index)) i += 2;
00058 if(com_->is_special(index)) i += 4;
00059
00060 switch(i)
00061 {
00062 case 1: return active_ ? ViewerManager::highlighted_att
00063 : ViewerManager::inactive_mark_att;
00064
00065
00066 case 2: return ViewerManager::inactive_mark_att;
00067
00068 case 3: return active_ ? ViewerManager::active_mark_att
00069 : ViewerManager::inactive_mark_att;
00070
00071 case 4: return is_bottom ? CursorWindow::bold_ul : CursorWindow::bold;
00072
00073
00074 case 5: return active_ ? CursorWindow::rev_ul_bold
00075 : CursorWindow::bold_ul;
00076
00077
00078 case 6: return ViewerManager::inactive_mark_att;
00079
00080 case 7: return active_ ? ViewerManager::active_mark_att
00081 : CursorWindow::bold_ul;
00082
00083 }
00084
00085
00086
00087 return is_bottom ? ViewerManager::bottom_att : ViewerManager::normal_att;
00088 }
00089
00090 ListViewer::
00091 policies::
00092 ~policies()
00093 {
00094 }
00095
00096 void
00097 ListViewer::
00098 policies::
00099 handle_resize(CursorWindow::row_col const &)
00100 {
00101
00102 }
00103
00104
00105 void
00106 ListViewer::
00107 operator() ( CursorWindow::viewport * vp,int cmd)
00108 {
00109
00110
00111 if(cmd == CursorWindow::viewport::repaint_handler::deactivate)
00112 {
00113 active_ = false;
00114 }
00115 else
00116 if(cmd == CursorWindow::viewport::repaint_handler::activate)
00117 {
00118 active_ = true;
00119 }
00120
00121 size_t apps = com_->strings_.size();
00122 row_col vpsize = vp->size();
00123 row_col vporigin= vp->origin();
00124
00125 com_->handle_resize(vpsize);
00126
00127
00128 int left = 0;
00129
00130 if(vporigin.col_) ++left;
00131
00132
00133
00134
00135 vp->set_curpos(0,0);
00136 vp->set_text_attribute(ViewerManager::normal_att);
00137 vp->fill_to_eos();
00138
00139 if(left)
00140 {
00141 vp->set_text_attribute(CursorWindow::bold);
00142
00143 for(int i = 0; i < vpsize.row_; ++i)
00144 {
00145 vp->set_curpos(i, 0);
00146
00147 using namespace CursesInterface;
00148
00149 vp->write(line_chars[VL_MIDDLE]);
00150 }
00151
00152 vp->set_text_attribute(ViewerManager::normal_att);
00153 }
00154
00155
00156 vp->set_curpos(vpsize.row_-1, left);
00157 vp->set_text_attribute(ViewerManager::bottom_att);
00158 vp->fill_to_eol();
00159
00160
00161
00162
00163 vp->set_curpos(0,left);
00164
00165 if(active_)
00166 vp->set_text_attribute(ViewerManager::active_title_att);
00167 else
00168 vp->set_text_attribute(ViewerManager::inactive_title_att);
00169
00170 {
00171 FileName tmp(com_->title_);
00172
00173 *vp << tmp.shorten(vpsize.col_);
00174 }
00175
00176 vp->fill_to_eol();
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187 int row = first_row_;
00188
00189
00190
00191 {
00192 size_t avail = vpsize.row_ - row;
00193
00194 if(cur_row_ - display_top_ >= avail)
00195 {
00196 display_top_ += avail/2;
00197 }
00198 }
00199
00200
00201 for(size_t i = display_top_;
00202 row < vpsize.row_ && i < apps;
00203 ++i, ++row
00204 )
00205 {
00206 int att = line_attribute(i == cur_row_, i, row == vpsize.row_-1);
00207
00208 vp->set_text_attribute(att);
00209
00210 if(i == cur_row_)
00211 {
00212
00213
00214 vp->set_curpos(row, left);
00215 vp->fill_to_eol();
00216
00217
00218 }
00219
00220 vp->set_curpos(row, 2+left);
00221
00222 output_row_text(vp, i);
00223
00224 if(att != ViewerManager::normal_att)
00225 vp->fill_to_eol();
00226
00227 }
00228
00229 vp->set_text_attribute(ViewerManager::normal_att);
00230
00231 vp->set_curpos(first_row_ + cur_row_ - display_top_,left);
00232
00233
00234 }
00235
00236 bool
00237 ListViewer::
00238 handle_event( CursorWindow::input_event const * e,
00239 CursorWindow::viewport * vp
00240 )
00241 {
00242
00243
00244
00245
00246
00247 if(e->type_ == CursorWindow::input_event::ForceExitKey)
00248 return true;
00249
00250
00251 if(e->type_ != CursorWindow::input_event::DataKey &&
00252 e->type_ != CursorWindow::input_event::FunctionKey
00253 )
00254 return false;
00255
00256
00257
00258
00259 int row = first_row_ + (cur_row_ - display_top_);
00260 row_col size = vp->size();
00261
00262 row_col vporigin= vp->origin();
00263
00264 int left = 0;
00265
00266 if(vporigin.col_) ++left;
00267
00268 vp->set_curpos(row,left);
00269 vp->set_text_attribute(line_attribute(false,
00270 cur_row_,
00271 (int)(cur_row_ - display_top_) == (size.row_ - first_row_ )-1
00272 ));
00273
00274 *vp << " ";
00275
00276 output_row_text(vp, cur_row_);
00277
00278 vp->fill_to_eol();
00279
00280 vp->set_curpos(row,left);
00281
00282 int edit_func = vp->window()->func[e->value_];
00283
00284 switch(edit_func)
00285 {
00286 case CursorWindow::func_top:
00287 row = first_row_;
00288 cur_row_ = 0;
00289 display_top_ = 0;
00290 vp->activate();
00291 break;
00292
00293 case CursorWindow::func_bottom:
00294 row = first_row_;
00295 cur_row_ = com_->strings_.size()-1;
00296
00297 if( (int) cur_row_ < 0)
00298 cur_row_ = 0;
00299
00300 display_top_ = cur_row_;
00301 vp->activate();
00302 break;
00303
00304 case CursorWindow::func_up:
00305
00306 if(com_->strings_.size() == 0)
00307 break;
00308
00309
00310
00311 if(row == first_row_)
00312 {
00313 if(cur_row_ > 0)
00314 {
00315 --cur_row_;
00316 --display_top_;
00317 repaint(vp);
00318
00319 }
00320 }
00321 else
00322 {
00323 --row;
00324 --cur_row_;
00325 }
00326
00327 break;
00328 case CursorWindow::func_down:
00329
00330
00331
00332 if(com_->strings_.size() == 0)
00333 break;
00334
00335 if(row == size.row_ - 1 && cur_row_ < com_->strings_.size()-1 )
00336 {
00337 ++cur_row_;
00338 ++display_top_;
00339 repaint(vp);
00340 }
00341 else
00342 {
00343
00344
00345 if(cur_row_ < com_->strings_.size()-1)
00346 {
00347 ++row;
00348 ++cur_row_;
00349 }
00350 }
00351 break;
00352 case CursorWindow::func_prior:
00353
00354
00355
00356 display_top_ -= size.row_ - first_row_;
00357
00358 if( (int)(display_top_) < 0)
00359 display_top_ = 0;
00360
00361 cur_row_ = display_top_;
00362
00363 row = first_row_;
00364
00365 repaint(vp);
00366
00367 break;
00368
00369 case CursorWindow::func_next:
00370
00371
00372
00373 display_top_ += size.row_ - first_row_;
00374
00375 if( (int)(display_top_) >= (int)com_->strings_.size() )
00376 display_top_ = com_->strings_.size()-1;
00377
00378 if( (int)(display_top_) < 0 )
00379 display_top_ = 0;
00380
00381 cur_row_ = display_top_;
00382
00383 row = first_row_;
00384
00385 repaint(vp);
00386
00387 break;
00388
00389 case CursorWindow::func_find:
00390
00391 find_string(cur_row_, manager_);
00392
00393 if( (int)(cur_row_ - display_top_) >= size.row_ - first_row_)
00394 {
00395 display_top_ = cur_row_;
00396
00397 row = first_row_;
00398
00399 repaint(vp);
00400 }
00401 else
00402 row = first_row_ + cur_row_ - display_top_;
00403
00404 break;
00405
00406 case CursorWindow::func_findnxt:
00407
00408 find_string(cur_row_);
00409
00410 if( (int)(cur_row_ - display_top_) >= size.row_ - first_row_)
00411 {
00412 display_top_ = cur_row_;
00413
00414 row = first_row_;
00415
00416 repaint(vp);
00417 }
00418 else
00419 row = first_row_ + cur_row_ - display_top_;
00420
00421 repaint(vp);
00422
00423 break;
00424
00425
00426 default:
00427
00428
00429
00430 {
00431 int rv = com_->handle_event(e, cur_row_, manager_);
00432
00433 switch(rv)
00434 {
00435 case 0: break;
00436 case 1:
00437 {
00438 if(cur_row_ >= com_->strings_.size())
00439 {
00440 cur_row_ = com_->strings_.size() -1;
00441
00442 if( (int)(cur_row_) < 0 )
00443 {
00444 cur_row_ = 0;
00445 }
00446
00447 if(display_top_ > cur_row_)
00448 display_top_ = cur_row_;
00449
00450 }
00451 vp->activate();
00452
00453 row = first_row_ + (cur_row_ - display_top_);
00454 }
00455 break;
00456 case 2:
00457 return true;
00458 }
00459
00460 if(manager_->active_viewer() != this)
00461 {
00462
00463
00464
00465 return false;
00466 }
00467
00468 }
00469 break;
00470
00471 }
00472
00473
00474
00475 row_col saved_curpos = manager_->window()->curpos();
00476
00477 vp->set_curpos(row,left);
00478 vp->set_text_attribute(line_attribute(true,
00479 cur_row_,
00480 (int)(cur_row_ - display_top_) == (size.row_ - first_row_ )-1
00481 ));
00482
00483 *vp << " ";
00484
00485 output_row_text(vp, cur_row_);
00486
00487 vp->fill_to_eol();
00488
00489
00490 vp->set_curpos(row,left);
00491 vp->set_text_attribute(ViewerManager::normal_att);
00492
00493 if(vp != manager_->active_viewport())
00494 {
00495 manager_->window()->set_curpos(saved_curpos);
00496 }
00497
00498
00499
00500 return false;
00501 }
00502
00503 static string toLower(string inp)
00504 {
00505 std::string::const_iterator first = inp.begin(),
00506 last = inp.end();
00507
00508 string rv;
00509
00510
00511 while(first != last)
00512 {
00513 char cur = *first++;
00514
00515 if(isupper(cur))
00516 cur = tolower(cur);
00517
00518 rv += cur;
00519 }
00520
00521 return rv;
00522
00523 }
00524
00525
00526 int
00527 ListViewer::
00528 find_string(size_t index, ViewerManager*vm)
00529 {
00530 CursorWindow::Dialog d("Find String");
00531
00532 d += new CursorWindow::Dialog::String("name",
00533 "String to search for",
00534 "",
00535 15
00536 );
00537
00538 if(d.popup(vm->window()))
00539 return 0;
00540
00541 search_string_ = toLower(d.element_value("name"));
00542
00543 if(search_string_.size() == 0)
00544 return 0;
00545
00546 return find_string(index-1);
00547
00548 }
00549
00550 int
00551 ListViewer::
00552 find_string(size_t index)
00553 {
00554 if(index >= com_->strings_.size())
00555 index = 0;
00556 else
00557 ++index;
00558
00559 while(index < com_->strings_.size())
00560 {
00561 string curLine = toLower( com_->strings_[index] );
00562
00563 std::string::iterator match = std::search( curLine.begin(),
00564 curLine.end(),
00565 search_string_.begin(),
00566 search_string_.end()
00567 );
00568
00569 if(match != curLine.end())
00570 {
00571 cur_row_ = index;
00572 return 1;
00573 }
00574
00575 ++index;
00576
00577 }
00578
00579 return 0;
00580
00581 }
00582
00583 void Viewer::help()
00584 {
00585
00586 }
00587
00588 void
00589 ListViewer::
00590 help()
00591 {
00592
00593
00594 std::auto_ptr< std::list< std::string > > viewer_help(com_->help_text());
00595
00596 manager_->help_helper(*viewer_help);
00597
00598 }
00599
00600 Viewer::paste_buffer_type*
00601 Viewer::paste_buffer()
00602 {
00603 fetchPasteBuffer();
00604
00605
00606
00607 return &manager_->paste_buffer_;
00608 }
00609
00610 bool
00611 Viewer::is_dirty() const
00612 {
00613 return false;
00614 }
00615
00616 #ifdef _MSC_VER
00617
00618 #include <windows.h>
00619 #include <wincon.h>
00620
00621 #endif
00622
00623
00624 void
00625 Viewer::commitPasteBuffer() const
00626 {
00627 #ifdef _MSC_VER
00628
00629 OpenClipboard(0);
00630
00631 EmptyClipboard();
00632
00633 string tmp;
00634
00635 list<string>::iterator first = manager_->paste_buffer_.begin(),
00636 last = manager_->paste_buffer_.end();
00637
00638 while(first != last)
00639 {
00640 string const &cur = *first++;
00641
00642 tmp += cur;
00643
00644 if(first != last)
00645 tmp += "\r\n";
00646 }
00647
00648 char *buffer = (char*)(GlobalAlloc(GMEM_FIXED, 1 + tmp.size()));
00649
00650 strcpy(buffer, tmp.c_str());
00651
00652 SetClipboardData(CF_TEXT, buffer);
00653
00654 CloseClipboard();
00655
00656 #else
00657 #endif
00658 }
00659
00660 void
00661 Viewer::fetchPasteBuffer()
00662 {
00663 #ifdef _MSC_VER
00664
00665 if(IsClipboardFormatAvailable(CF_TEXT))
00666 {
00667 OpenClipboard(0);
00668
00669 char *p = reinterpret_cast<char*>(GetClipboardData(CF_TEXT));
00670
00671 if(p)
00672 {
00673 manager_->paste_buffer_.clear();
00674
00675 string curline;
00676
00677 while(*p)
00678 {
00679 if(*p == '\r')
00680 ++p;
00681 else
00682 if(*p == '\n')
00683 {
00684 manager_->paste_buffer_.push_back(StrTool::expand_tabs(curline.c_str()));
00685 curline.resize(0);
00686 ++p;
00687 }
00688 else
00689 {
00690 curline += *p++;
00691 }
00692 }
00693
00694 if(!curline.empty())
00695 manager_->paste_buffer_.push_back(StrTool::expand_tabs(curline.c_str()));
00696
00697 }
00698
00699 CloseClipboard();
00700 }
00701 #else
00702 #endif
00703 }
00704
00705 bool Viewer::fetchAllLines(std::list<std::string> &output)
00706 {
00707 return false;
00708 }
00709
00710 bool
00711 ListViewer::
00712 fetchAllLines(std::list<std::string> &output)
00713 {
00714 if(com_.get())
00715 return com_.get()->fetchAllLines(output);
00716 else
00717 return false;
00718 }
00719
00720 bool
00721 ListViewer::
00722 policies::
00723 fetchAllLines(std::list<std::string> &output)
00724 {
00725 CXXTLS_FOREACH(std::string const &cur, strings_)
00726 output.push_back(cur);
00727
00728 return true;
00729 }
00730
00731
00732 }