home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c083 / 11.ddi / OWLSRC.PAK / LISTVIEW.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-02  |  7.2 KB  |  317 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1993 by Borland International
  3. //   include\owl\listview.cpp
  4. //   Implements class TListView
  5. //----------------------------------------------------------------------------
  6. #pragma hdrignore SECTION
  7. #include <owl\owlpch.h>
  8. #include <owl\listview.h>
  9. #include <owl\listview.rc>
  10. #include <owl\docview.rc>
  11. #include <owl\inputdia.h>
  12.  
  13. DIAG_DECLARE_GROUP(OwlDocView);        // General Doc/View diagnostic group
  14.  
  15. #if !defined(SECTION) || SECTION == 1
  16.  
  17. //  class TListView
  18. //  ----- ---------
  19. //
  20. DEFINE_RESPONSE_TABLE1(TListView, TListBox)
  21.   EV_COMMAND(CM_LISTUNDO,    CmEditUndo),
  22.   EV_COMMAND(CM_LISTCUT,     CmEditCut),
  23.   EV_COMMAND(CM_LISTCOPY,    CmEditCopy),
  24.   EV_COMMAND(CM_LISTPASTE,   CmEditPaste),
  25.   EV_COMMAND(CM_LISTCLEAR,   CmEditClear),
  26.   EV_COMMAND(CM_LISTDELETE,  CmEditDelete),
  27.   EV_COMMAND(CM_LISTADD,     CmEditAdd),
  28.   EV_COMMAND(CM_LISTEDIT,    CmEditItem),
  29.   EV_WM_GETDLGCODE,
  30.   EV_NOTIFY_AT_CHILD(LBN_DBLCLK, CmEditItem),
  31.   EV_NOTIFY_AT_CHILD(LBN_SELCHANGE, CmSelChange),
  32.   EV_VN_DOCCLOSED,
  33.   EV_VN_ISWINDOW,
  34.   EV_VN_ISDIRTY,
  35.   EV_VN_COMMIT,
  36.   EV_VN_REVERT,
  37. END_RESPONSE_TABLE;
  38.  
  39. TListView::TListView(TDocument& doc, TWindow* parent)
  40.    : TView(doc),TListBox(parent, GetNextViewId(), 0,0,0,0),
  41.      Origin(0), MaxWidth(0), DirtyFlag(FALSE)
  42. {
  43.   Attr.Style &= ~(WS_BORDER | LBS_SORT);
  44.   Attr.Style |= (WS_HSCROLL | LBS_NOINTEGRALHEIGHT);
  45.   Attr.AccelTable = IDA_LISTVIEW;
  46.   SetViewMenu(new TMenuDescr(IDM_LISTVIEW,0,1,0,0,0,1));
  47. }
  48.  
  49. void
  50. TListView::SetExtent(LPSTR str)
  51. {
  52.   HDC hdc;
  53.   int len;
  54.   TSize extent;
  55.   if ((len = strlen(str)) == 0)
  56.     return;
  57.   hdc = ::GetDC(HWindow);
  58.   ::GetTextExtentPoint(hdc, str, len, &extent);
  59.   extent.cx += 2; // room for focus rectangle
  60.  
  61.   if (extent.cx > MaxWidth){
  62.     SetHorizontalExtent(MaxWidth = extent.cx);
  63.   }
  64.   ::ReleaseDC(HWindow, hdc);
  65. }
  66.  
  67. BOOL
  68. TListView::VnDocClosed(int omode)
  69. {
  70.   int top;
  71.   int sel;
  72.   if (DirtyFlag == 2 || !(omode & ofWrite))  // make sure someone else's write
  73.     return FALSE;
  74.   top = GetTopIndex();
  75.   sel = GetSelIndex();
  76.   LoadData(top, sel);
  77.   return TRUE;
  78. }
  79.  
  80. BOOL
  81. TListView::LoadData(int top, int sel)
  82. {
  83.   char buf[100+1];
  84.   istream* inStream;
  85.   BOOL status = TRUE;
  86.  
  87.   CmEditClear();
  88.   DirtyFlag = FALSE;
  89.   if ((inStream = Doc->InStream(ios::in)) == 0) {
  90.     Doc->PostError(IDS_UNABLEOPEN, MB_OK);
  91.     return FALSE;
  92.   }
  93.   for (;;) {
  94.     inStream->getline(buf, sizeof(buf)-1);
  95.     if (!inStream->gcount() && !inStream->good()) {
  96.       status = inStream->eof();
  97.       break;
  98.     }
  99.     AddString(buf);
  100.     SetExtent(buf);
  101.   }
  102.   SetTopIndex(top);
  103.   SetSelIndex(sel);
  104.   delete inStream;   // close file in case process switch
  105.   if (!status)
  106.     Doc->PostError(IDS_READERROR, MB_OK);
  107.   return status;
  108. }
  109.  
  110. BOOL
  111. TListView::Create()
  112. {
  113.   TRY {
  114.     TListBox::Create();   // throws exception TWindow::TXWindow
  115.   }
  116.   CATCH( (TXOwl& x) {
  117.     Doc->PostError(IDS_NOMEMORYFORVIEW, MB_OK);
  118.     return TRUE;   // cannot return FALSE - throws another exception
  119.   })
  120.   if (Doc->GetDocPath() == 0) {  
  121.     return TRUE;           // new file, no data to display
  122.   }
  123.   if (!LoadData(0, 0))
  124.     NotOK();
  125.   return TRUE;
  126. }
  127.  
  128. BOOL
  129. TListView::VnCommit(BOOL force)
  130. {
  131.   int count;
  132.   int index;
  133.   int len;
  134.   char* buf;
  135.   ostream* outStream;
  136.   BOOL status;
  137.  
  138.   if (!force && !DirtyFlag)
  139.     return TRUE;
  140.   if ((outStream = Doc->OutStream(ios::out)) == 0) {
  141.     Doc->PostError(IDS_UNABLEOPEN, MB_OK);
  142.     return FALSE;
  143.   }
  144.   outStream->seekp(Origin);
  145.   count = GetCount();
  146.   for (index = 0; index < count; index++) {
  147.     len = GetStringLen(index);
  148.     buf = new char[len+1];
  149.     GetString(buf, index);
  150.     *outStream << buf << '\n';
  151.     delete buf;
  152.   }
  153.   DirtyFlag = 2;           // to detect our own close notification
  154.   status = outStream->good();
  155.   delete outStream;
  156.   DirtyFlag = FALSE;
  157.   if (!status)
  158.     Doc->PostError(IDS_WRITEERROR, MB_OK);
  159.   return status;
  160. }
  161.  
  162. BOOL
  163. TListView::VnRevert(BOOL clear)
  164. {
  165.   if (!clear && Doc->GetDocPath() != 0)
  166.     return LoadData(0,0);
  167.   CmEditClear();
  168.   DirtyFlag = FALSE;
  169.   return TRUE;
  170. }
  171.  
  172. UINT
  173. TListView::EvGetDlgCode(MSG far*)
  174. {
  175.   UINT retVal = (UINT)DefaultProcessing();
  176.   retVal |= DLGC_WANTCHARS;
  177.   return retVal;
  178. }
  179.  
  180. void
  181. TListView::CmEditUndo()
  182. {
  183.   MessageBox("Feature not implemented", "Undo", MB_OK);
  184. }
  185.  
  186. void
  187. TListView::CmEditCut()
  188. {
  189.   CmEditCopy();
  190.   CmEditDelete();
  191. }
  192.  
  193. void
  194. TListView::CmEditCopy()
  195. {
  196.   HANDLE cbhdl;
  197.   char far* buf;
  198.   int index = GetSelIndex();
  199.   if (!GetCount()) return;
  200.   int len = GetStringLen(index);
  201.   TClipboard& cb = OpenClipboard();
  202.   if (cb.EmptyClipboard()) {
  203.     cbhdl = GlobalAlloc(GHND,len+0+1);
  204.     buf = (char far*)GlobalLock(cbhdl);
  205.     GetString(buf, index);
  206.     GlobalUnlock(cbhdl);
  207.     cb.SetClipboardData(CF_TEXT, cbhdl);
  208.   }
  209.   cb.CloseClipboard();
  210. }
  211.  
  212. void
  213. TListView::CmEditPaste()
  214. {
  215.   HANDLE cbhdl;
  216.   char far* text;
  217.   int index = GetSelIndex();
  218.   if (index < 0)
  219.     index = 0;
  220.   TClipboard& cb = OpenClipboard();
  221.   if (!cb) return;   // clipboard open by another program
  222.   if ((cbhdl = cb.GetClipboardData(CF_TEXT)) != 0) {
  223.     text = (char far*)GlobalLock(cbhdl);
  224.     InsertString(text, index);
  225.     SetSelIndex(index);
  226.     DirtyFlag = TRUE;
  227.     GlobalUnlock(cbhdl);
  228.   }
  229.   cb.CloseClipboard();
  230. }
  231.  
  232. void
  233. TListView::CmEditDelete()
  234. {
  235.   int count = GetCount();
  236.   int index = GetSelIndex();
  237.   if (!count) return;
  238.   DeleteString(index);
  239.   if (index == count-1) index--;
  240.   SetSelIndex(index);
  241.   DirtyFlag = TRUE;
  242. }
  243.  
  244. void
  245. TListView::CmEditClear()
  246. {
  247.   if (GetCount()) {
  248.     ClearList();
  249.     DirtyFlag = TRUE;
  250.     SetHorizontalExtent(MaxWidth = 0);
  251.   }
  252. }
  253.  
  254. static int linePrompt(TWindow* parent,int index,UINT id,LPSTR buf,int buflen)
  255. {
  256.   char msg[41];
  257.   wsprintf(msg, string(*parent->GetModule(), IDS_LISTNUM).c_str(), index);
  258.   LPCSTR prompt = string(*parent->GetModule(), id).c_str();
  259.   return TInputDialog(parent, msg, prompt, buf, buflen).Execute();
  260. }
  261.  
  262. void
  263. TListView::CmEditAdd()
  264. {
  265.   char inputText[101];
  266.   int index = GetSelIndex() + 1;   // becomes 0 if list box is empty
  267.   inputText[0] = 0;
  268.   if (linePrompt(this,index+1,CM_LISTADD,inputText,sizeof(inputText))==IDOK) {
  269.     InsertString(inputText, index);
  270.     SetSelIndex(index);
  271.     SetExtent(inputText);
  272.     DirtyFlag = TRUE;
  273.   }
  274. }
  275.  
  276. void
  277. TListView::CmEditItem()
  278. {
  279.   char inputText[101];
  280.   int index = GetSelIndex();
  281.   if (index < 0)
  282.     return;
  283.   GetSelString(inputText, sizeof(inputText)-1);
  284.   if (linePrompt(this,index+1,CM_LISTEDIT,inputText,sizeof(inputText))==IDOK){
  285.     DeleteString(index);
  286.     InsertString(inputText, index);
  287.     SetExtent(inputText);
  288.     SetSelIndex(index);
  289.     DirtyFlag = TRUE;
  290.   }
  291. }
  292.  
  293. #endif
  294. #if !defined(SECTION) || SECTION == 2
  295.  
  296. IMPLEMENT_STREAMABLE2(TListView, TListBox, TView);
  297.  
  298. void*
  299. TListView::Streamer::Read(ipstream& is, uint32 /*version*/) const
  300. {
  301.   ReadBaseObject((TListBox*)GetObject(), is);
  302.   ReadBaseObject((TView*)GetObject(), is);
  303.   is >> GetObject()->Origin;
  304.   return GetObject();
  305. }
  306.  
  307. void
  308. TListView::Streamer::Write(opstream &os) const
  309. {
  310.   WriteBaseObject((TListBox*)GetObject(), os);
  311.   WriteBaseObject((TView*)GetObject(), os);
  312.   os << GetObject()->Origin;
  313. }
  314.  
  315. #endif
  316.  
  317.