home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / docview.pak / LINEDOC.CPP < prev    next >
Text File  |  1997-07-23  |  20KB  |  836 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1991, 1993 by Borland International
  3. //   Implements classes TDrawDocument, TDrawView, TDrawListView
  4. //----------------------------------------------------------------------------
  5. #include <owl\owlpch.h>
  6. #include <owl\docmanag.h>
  7. #include <owl\filedoc.h>
  8. #include <owl\dc.h>
  9. #include <owl\inputdia.h>
  10. #include <owl\chooseco.h>
  11. #include <owl\gdiobjec.h>
  12. #include <owl\listbox.h>
  13. #include <owl\docview.h>
  14. #include <classlib\arrays.h>
  15. #include "linedoc.rc"
  16.  
  17. typedef TArray<TPoint> TPoints;
  18. typedef TArrayIterator<TPoint> TPointsIterator;
  19.  
  20. class TLine : public TPoints {
  21.   public:
  22.     // Constructor to allow construction from a color and a pen size.
  23.     // Also serves as default constructor.
  24.     TLine(const TColor &color = TColor(0), int penSize = 1)
  25.       : TPoints(10, 0, 10), PenSize(penSize), Color(color) {}
  26.  
  27.     // Functions to modify and query pen attributes.
  28.     int QueryPenSize() const { return PenSize; }
  29.     const TColor& QueryColor() const { return Color; }
  30.     void SetPen(TColor &newColor, int penSize = 0);
  31.     void SetPen(int penSize);
  32.     BOOL GetPenSize();
  33.     BOOL GetPenColor();
  34.  
  35.     // TLine draws itself.  Returns TRUE if everything went OK.
  36.     virtual BOOL Draw(TDC &) const;
  37.  
  38.     // The == operator must be defined for the container class, even if unused
  39.     BOOL operator ==(const TLine& other) const { return &other == this; }
  40.     friend ostream& operator <<(ostream& os, const TLine& line);
  41.     friend istream& operator >>(istream& is, TLine& line);
  42.  
  43.   protected:
  44.     int PenSize;
  45.     TColor Color;
  46. };
  47.  
  48. typedef TArray<TLine> TLines;
  49. typedef TArrayIterator<TLine> TLinesIterator;
  50.  
  51. class _DOCVIEWCLASS TDrawDocument : public TFileDocument
  52. {
  53.   public:
  54.     enum {
  55.       PrevProperty = TFileDocument::NextProperty-1,
  56.       LineCount,
  57.       Description,
  58.       NextProperty,
  59.     };
  60.  
  61.     enum {
  62.       UndoNone,
  63.       UndoDelete,
  64.       UndoAppend,
  65.       UndoModify
  66.     };
  67.  
  68.     TDrawDocument(TDocument* parent = 0)
  69.         : TFileDocument(parent), Lines(0), UndoLine(0), UndoState(UndoNone) {}
  70.    ~TDrawDocument() { delete Lines; delete UndoLine; }
  71.  
  72.     // implement virtual methods of TDocument
  73.     BOOL   Open(int mode, const char far* path=0);
  74.     BOOL   Close();
  75.     BOOL   IsOpen() { return Lines != 0; }
  76.     BOOL   Commit(BOOL force = FALSE);
  77.     BOOL   Revert(BOOL clear = FALSE);
  78.  
  79.     int         FindProperty(const char far* name);  // return index
  80.     int         PropertyFlags(int index);
  81.     const char* PropertyName(int index);
  82.     int         PropertyCount() {return NextProperty - 1;}
  83.     int         GetProperty(int index, void far* dest, int textlen=0);
  84.  
  85.     // data access functions
  86.     const TLine* GetLine(unsigned int index);
  87.     int    AddLine(TLine& line);
  88.     void   DeleteLine(unsigned int index);
  89.     void   ModifyLine(TLine& line, unsigned int index);
  90.     void   Clear();
  91.     void   Undo();
  92.  
  93.   protected:
  94.     TLines* Lines;
  95.     TLine* UndoLine;
  96.     int    UndoState;
  97.     int    UndoIndex;
  98.     string FileInfo;
  99.  
  100.   DECLARE_STREAMABLE(, TDrawDocument,1);
  101. };
  102.  
  103. class _DOCVIEWCLASS TDrawView : public TWindowView
  104. {
  105.   public:
  106.     TDrawView(TDrawDocument& doc, TWindow *parent = 0);
  107.    ~TDrawView() {delete DragDC; delete Line;}
  108.     static const char far* StaticName() {return "Draw View";}
  109.     const char far* GetViewName(){return StaticName();}
  110.  
  111.   protected:
  112.     TDrawDocument* DrawDoc;  // same as Doc member, but cast to derived class
  113.     TDC *DragDC;
  114.     TPen *Pen;
  115.     TLine *Line; // To hold a single line sent or received from document
  116.  
  117.     // Message response functions
  118.     void EvLButtonDown(UINT, TPoint&);
  119.     void EvRButtonDown(UINT, TPoint&);
  120.     void EvMouseMove(UINT, TPoint&);
  121.     void EvLButtonUp(UINT, TPoint&);
  122.     void Paint(TDC&, BOOL, TRect&);
  123.     void CmPenSize();
  124.     void CmPenColor();
  125.     void CmClear();
  126.     void CmUndo();
  127.  
  128.     // Document notifications
  129.     BOOL VnCommit(BOOL force);
  130.     BOOL VnRevert(BOOL clear);
  131.     BOOL VnAppend(unsigned int index);
  132.     BOOL VnDelete(unsigned int index);
  133.     BOOL VnModify(unsigned int index);
  134.  
  135.   DECLARE_RESPONSE_TABLE(TDrawView);
  136.   DECLARE_STREAMABLE(,TDrawView,1);
  137. };
  138.  
  139. class _DOCVIEWCLASS TDrawListView : public TListBox, public TView {
  140.   public:
  141.     TDrawListView(TDrawDocument& doc, TWindow* parent = 0);
  142.    ~TDrawListView(){}
  143.     static const char far* StaticName() {return "DrawList View";}
  144.  
  145.     // Overridden virtuals from TView
  146.     //
  147.     const char far* GetViewName(){return StaticName();}
  148.     TWindow* GetWindow()  {return (TWindow*)this;}
  149.     BOOL     SetDocTitle(const char far* docname, int index)
  150.                           {return TListBox::SetDocTitle(docname, index); }
  151.  
  152.     // Overridden virtuals from TWindow
  153.     //
  154.     BOOL CanClose()   {return TListBox::CanClose() && Doc->CanClose();}
  155.     BOOL Create();
  156.  
  157.   protected:
  158.     TDrawDocument* DrawDoc;  // same as Doc member, but cast to derived class
  159.     void LoadData();
  160.     void FormatData(const TLine* line, unsigned int index);
  161.  
  162.     // Message response functions
  163.     void CmPenSize();
  164.     void CmPenColor();
  165.     void CmClear();
  166.     void CmUndo();
  167.     void CmDelete();
  168.  
  169.     // Document notifications
  170.     BOOL VnIsWindow(HWND hWnd) {return HWindow == hWnd;}
  171.     BOOL VnCommit(BOOL force);
  172.     BOOL VnRevert(BOOL clear);
  173.     BOOL VnAppend(unsigned int index);
  174.     BOOL VnDelete(unsigned int index);
  175.     BOOL VnModify(unsigned int index);
  176.  
  177.   DECLARE_RESPONSE_TABLE(TDrawListView);
  178.   DECLARE_STREAMABLE(,TDrawListView,1);
  179. };
  180.  
  181. const int vnDrawAppend = vnCustomBase+0;
  182. const int vnDrawDelete = vnCustomBase+1;
  183. const int vnDrawModify = vnCustomBase+2;
  184.  
  185. NOTIFY_SIG(vnDrawAppend, unsigned int)
  186. NOTIFY_SIG(vnDrawDelete, unsigned int)
  187. NOTIFY_SIG(vnDrawModify, unsigned int)
  188.  
  189. #define EV_VN_DRAWAPPEND  VN_DEFINE(vnDrawAppend,  VnAppend,  int)
  190. #define EV_VN_DRAWDELETE  VN_DEFINE(vnDrawDelete,  VnDelete,  int)
  191. #define EV_VN_DRAWMODIFY  VN_DEFINE(vnDrawModify,  VnModify,  int)
  192.  
  193. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawView,   DrawTemplate);
  194. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawListView,   DrawListTemplate);
  195. DrawTemplate drawTpl("Draw Line Files (*.PTS)","*.pts",0,"PTS",dtAutoDelete|dtUpdateDir);
  196. DrawListTemplate drawListTpl("Line List","  *.pts",0,"PTS",dtAutoDelete|dtHidden);
  197.  
  198. void TLine::SetPen(int penSize)
  199. {
  200.   if (penSize < 1)
  201.     PenSize = 1;
  202.   else
  203.     PenSize = penSize;
  204. }
  205.  
  206. void TLine::SetPen(TColor &newColor, int penSize)
  207. {
  208.   // If penSize isn't the default (0), set PenSize to the new size.
  209.   if (penSize)
  210.     PenSize = penSize;
  211.  
  212.   Color = newColor;
  213. }
  214.  
  215. BOOL TLine::Draw(TDC &dc) const
  216. {
  217.   // Set pen for the dc to the values for this line
  218.   TPen pen(Color, PenSize);
  219.   dc.SelectObject(pen);
  220.  
  221.   // Iterates through the points in the line i.
  222.   TPointsIterator j(*this);
  223.   BOOL first = TRUE;
  224.  
  225.   while (j) {
  226.     TPoint p = j++;
  227.  
  228.     if (!first)
  229.       dc.LineTo(p);
  230.     else {
  231.       dc.MoveTo(p);
  232.       first = FALSE;
  233.     }
  234.   }
  235.   dc.RestorePen();
  236.   return TRUE;
  237. }
  238.  
  239. ostream& operator <<(ostream& os, const TLine& line)
  240. {
  241.   // Write the number of points in the line
  242.   os << line.GetItemsInContainer();
  243.  
  244.   // Get and write pen attributes.
  245.   os << ' ' << line.Color << ' ' << line.PenSize;
  246.  
  247.   // Get an iterator for the array of points
  248.   TPointsIterator j(line);
  249.  
  250.   // While the iterator is valid (i.e. we haven't run out of points)
  251.   while(j)
  252.     // Write the point from the iterator and increment the array.
  253.     os << j++;
  254.   os << '\n';
  255.  
  256.   // return the stream object
  257.   return os;
  258. }
  259.  
  260. istream& operator >>(istream& is, TLine& line)
  261. {
  262.   unsigned numPoints;
  263.   is >> numPoints;
  264.  
  265.   COLORREF color;
  266.   int penSize;
  267.   is >> color >> penSize;
  268.   line.SetPen(TColor(color), penSize);
  269.  
  270.   while (numPoints--) {
  271.     TPoint point;
  272.     is >> point;
  273.     line.Add(point);
  274.   }
  275.  
  276.   // return the stream object
  277.   return is;
  278. }
  279.  
  280. BOOL TDrawDocument::Commit(BOOL force)
  281. {
  282.   if (!IsDirty() && !force)
  283.     return TRUE;
  284.  
  285.   TOutStream* os = OutStream(ofWrite);
  286.   if (!os)
  287.     return FALSE;
  288.  
  289.   // Write the number of lines in the figure
  290.   *os << Lines->GetItemsInContainer();
  291.  
  292.   // Append a description using a resource string
  293.   *os << ' ' << FileInfo << '\n';
  294.  
  295.   // Get an iterator for the array of lines
  296.   TLinesIterator i(*Lines);
  297.  
  298.   // While the iterator is valid (i.e. we haven't run out of lines)
  299.   while (i) {
  300.     // Copy the current line from the iterator and increment the array.
  301.     *os << i++;
  302.   }
  303.   delete os;
  304.  
  305.   SetDirty(FALSE);
  306.   return TRUE;
  307. }
  308.  
  309. BOOL TDrawDocument::Revert(BOOL clear)
  310. {
  311.   if (!TFileDocument::Revert(clear))
  312.     return FALSE;
  313.   if (!clear)
  314.     Open(0);
  315.   return TRUE;
  316. }
  317.  
  318. BOOL TDrawDocument::Open(int /*mode*/, const char far* path)
  319. {
  320.   char fileinfo[100];
  321.   Lines = new TLines(5, 0, 5);
  322.   if (path)
  323.     SetDocPath(path);
  324.   if (GetDocPath()) {
  325.     TInStream* is = InStream(ofRead);
  326.     if (!is)
  327.       return FALSE;
  328.  
  329.     unsigned numLines;
  330.     *is >> numLines;
  331.     is->getline(fileinfo, sizeof(fileinfo));
  332.     while (numLines--) {
  333.       TLine line;
  334.       *is >> line;
  335.       Lines->Add(line);
  336.     }
  337.     delete is;
  338.     FileInfo = fileinfo;
  339.   } else {
  340.     FileInfo = string(*::Module,IDS_FILEINFO);
  341.   }  
  342.   SetDirty(FALSE);
  343.   UndoState = UndoNone;
  344.   return TRUE;
  345. }
  346.  
  347. BOOL TDrawDocument::Close()
  348. {
  349.   delete Lines;
  350.   Lines = 0;
  351.   return TRUE;
  352. }
  353.  
  354. const TLine* TDrawDocument::GetLine(unsigned int index)
  355. {
  356.   if (!IsOpen() && !Open(ofRead | ofWrite))
  357.     return 0;
  358.   return index < Lines->GetItemsInContainer() ? &(*Lines)[index] : 0;
  359. }
  360.  
  361. int TDrawDocument::AddLine(TLine& line)
  362. {
  363.   int index = Lines->GetItemsInContainer();
  364.   Lines->Add(line);
  365.   SetDirty(TRUE);
  366.   NotifyViews(vnDrawAppend, index); 
  367.   UndoState = UndoAppend;
  368.   return index;
  369. }
  370.  
  371. void TDrawDocument::DeleteLine(unsigned int index)
  372. {
  373.   const TLine* oldLine = GetLine(index);
  374.   if (!oldLine)
  375.     return;
  376.   delete UndoLine;
  377.   UndoLine = new TLine(*oldLine);
  378.   Lines->Detach(index);
  379.   SetDirty(TRUE);
  380.   NotifyViews(vnDrawDelete, index); 
  381.   UndoState = UndoDelete;
  382. }
  383.  
  384. void TDrawDocument::ModifyLine(TLine& line, unsigned int index)
  385. {
  386.   delete UndoLine;
  387.   UndoLine = new TLine((*Lines)[index]);
  388.   SetDirty(TRUE);
  389.   (*Lines)[index] = line;
  390.   NotifyViews(vnDrawModify, index);
  391.   UndoState = UndoModify;
  392.   UndoIndex = index;
  393. }
  394.  
  395. void TDrawDocument::Clear()
  396. {
  397.   Lines->Flush();
  398.   NotifyViews(vnRevert, TRUE); 
  399. }
  400.  
  401. void TDrawDocument::Undo()
  402. {
  403.   switch (UndoState) {
  404.     case UndoAppend:
  405.       DeleteLine(Lines->GetItemsInContainer()-1);
  406.       return;
  407.     case UndoDelete:
  408.       AddLine(*UndoLine);
  409.       delete UndoLine;
  410.       UndoLine = 0;
  411.       return;
  412.     case UndoModify:
  413.       TLine* temp = UndoLine;
  414.       UndoLine = 0;
  415.       ModifyLine(*temp, UndoIndex);
  416.       delete temp;
  417.   }
  418. }
  419.  
  420. BOOL TLine::GetPenSize()
  421. {
  422.   char inputText[6];
  423.  
  424.   wsprintf(inputText, "%d", PenSize);
  425.   if (TInputDialog(0, "Line Thickness",
  426.                         "Input a new thickness:",
  427.                         inputText,
  428.                         sizeof(inputText),::Module).Execute() != IDOK)
  429.     return FALSE;
  430.   PenSize = atoi(inputText);
  431.  
  432.   if (PenSize < 1)
  433.     PenSize = 1;
  434.  
  435.   return TRUE;
  436. }
  437.  
  438. BOOL TLine::GetPenColor()
  439. {
  440.   TChooseColorDialog::TData colors;
  441.   static TColor custColors[16] =
  442.   {
  443.     0x010101L, 0x101010L, 0x202020L, 0x303030L,
  444.     0x404040L, 0x505050L, 0x606060L, 0x707070L,
  445.     0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L,
  446.     0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L
  447.   };
  448.  
  449.   colors.Flags = CC_RGBINIT;
  450.   colors.Color = TColor(QueryColor());
  451.   colors.CustColors = custColors;
  452.   if (TChooseColorDialog(0, colors).Execute() != IDOK)
  453.     return FALSE;
  454.   SetPen(colors.Color);
  455.   return TRUE;
  456. }
  457.  
  458. DEFINE_RESPONSE_TABLE1(TDrawView, TWindowView)
  459.   EV_WM_LBUTTONDOWN,
  460.   EV_WM_RBUTTONDOWN,
  461.   EV_WM_MOUSEMOVE,
  462.   EV_WM_LBUTTONUP,
  463.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  464.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  465.   EV_COMMAND(CM_CLEAR, CmClear),
  466.   EV_COMMAND(CM_UNDO, CmUndo),
  467.   EV_VN_COMMIT,
  468.   EV_VN_REVERT,
  469.   EV_VN_DRAWAPPEND,
  470.   EV_VN_DRAWDELETE,
  471.   EV_VN_DRAWMODIFY,
  472. END_RESPONSE_TABLE;
  473.  
  474. TDrawView::TDrawView(TDrawDocument& doc,TWindow *parent)
  475.          : TWindowView(doc,parent), DrawDoc(&doc)
  476. {
  477.   DragDC = 0;
  478.   Line = new TLine(TColor::Black, 1);
  479.   SetViewMenu(new TMenuDescr(IDM_DRAWVIEW,0,2,0,0,0,1));
  480. }
  481.  
  482. void TDrawView::EvLButtonDown(UINT, TPoint& point)
  483. {
  484.   if (!DragDC) {
  485.     SetCapture();
  486.     DragDC = new TClientDC(*this);
  487.     Pen = new TPen(Line->QueryColor(), Line->QueryPenSize());
  488.     DragDC->SelectObject(*Pen);
  489.     DragDC->MoveTo(point);
  490.     Line->Add(point);
  491.   }
  492. }
  493.  
  494. void TDrawView::EvRButtonDown(UINT, TPoint&)
  495. {
  496.   CmUndo();
  497. }
  498.  
  499. void TDrawView::EvMouseMove(UINT, TPoint& point)
  500. {
  501.   if (DragDC) {
  502.     DragDC->LineTo(point);
  503.     Line->Add(point);
  504.   }
  505. }
  506.  
  507. void TDrawView::EvLButtonUp(UINT, TPoint&)
  508. {
  509.   if (DragDC) {
  510.     ReleaseCapture();
  511.     if (Line->GetItemsInContainer() > 1)
  512.       DrawDoc->AddLine(*Line);
  513.     Line->Flush();
  514.     delete DragDC;
  515.     delete Pen;
  516.     DragDC = 0;
  517.   }
  518. }
  519.  
  520. void TDrawView::CmPenSize()
  521. {
  522.   Line->GetPenSize();
  523. }
  524.  
  525. void TDrawView::CmPenColor()
  526. {
  527.   Line->GetPenColor();
  528. }
  529.  
  530. void TDrawView::CmClear()
  531. {
  532.   DrawDoc->Clear();
  533. }
  534.  
  535. void TDrawView::CmUndo()
  536. {
  537.   DrawDoc->Undo();
  538. }
  539.  
  540. void TDrawView::Paint(TDC& dc, BOOL, TRect&)
  541. {
  542.   // Iterates through the array of line objects.
  543.   int i = 0;
  544.   const TLine* line;
  545.   while ((line = DrawDoc->GetLine(i++)) != 0)
  546.     line->Draw(dc);
  547. }
  548.  
  549. BOOL TDrawView::VnCommit(BOOL /*force*/)
  550. {
  551.   // nothing to do here, no data held in view
  552.   return TRUE;
  553. }
  554.  
  555. BOOL TDrawView::VnRevert(BOOL /*clear*/)
  556. {
  557.   Invalidate();  // force full repaint
  558.   return TRUE;
  559. }
  560.  
  561. BOOL TDrawView::VnAppend(unsigned int index)
  562. {
  563.   TClientDC dc(*this);
  564.   const TLine* line = DrawDoc->GetLine(index);
  565.   line->Draw(dc);
  566.   return TRUE;
  567. }
  568.  
  569. BOOL TDrawView::VnModify(unsigned int /*index*/)
  570. {
  571.   Invalidate();  // force full repaint
  572.   return TRUE;
  573. }
  574.  
  575. BOOL TDrawView::VnDelete(unsigned int /*index*/)
  576. {
  577.   Invalidate();  // force full repaint
  578.   return TRUE;
  579. }
  580.  
  581. DEFINE_RESPONSE_TABLE1(TDrawListView, TListBox)
  582.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  583.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  584.   EV_COMMAND(CM_CLEAR, CmClear),
  585.   EV_COMMAND(CM_UNDO, CmUndo),
  586.   EV_COMMAND(CM_DELETE, CmDelete),
  587.   EV_VN_ISWINDOW,
  588.   EV_VN_COMMIT,
  589.   EV_VN_REVERT,
  590.   EV_VN_DRAWAPPEND,
  591.   EV_VN_DRAWDELETE,
  592.   EV_VN_DRAWMODIFY,
  593. END_RESPONSE_TABLE;
  594.  
  595. TDrawListView::TDrawListView(TDrawDocument& doc,TWindow *parent)
  596.        : TView(doc), TListBox(parent, GetNextViewId(), 0,0,0,0), DrawDoc(&doc)
  597. {
  598.   Attr.Style &= ~(WS_BORDER | LBS_SORT);
  599.   Attr.AccelTable = IDA_DRAWLISTVIEW;   
  600.   SetViewMenu(new TMenuDescr(IDM_DRAWLISTVIEW,0,1,0,0,0,1));
  601.  
  602. BOOL TDrawListView::Create()
  603. {
  604.   TListBox::Create();
  605.   LoadData();
  606.   return TRUE;
  607. }
  608.  
  609. void TDrawListView::LoadData()
  610. {
  611.   ClearList();
  612.   int i = 0;
  613.   const TLine* line;
  614.   while ((line = DrawDoc->GetLine(i)) != 0)
  615.     FormatData(line, i++);
  616.  
  617.   SetSelIndex(0);
  618. }
  619.  
  620. void TDrawListView::FormatData(const TLine* line, int unsigned index)
  621. {
  622.   char buf[80];
  623.   TColor color(line->QueryColor());
  624.   wsprintf(buf, "Color = R%d G%d B%d, Size = %d, Points = %d",
  625.            color.Red(), color.Green(), color.Blue(),
  626.            line->QueryPenSize(), line->GetItemsInContainer());
  627.   DeleteString(index);
  628.   InsertString(buf, index);
  629.   SetSelIndex(index);
  630. }
  631.   
  632. void TDrawListView::CmPenSize()
  633. {
  634.   int index = GetSelIndex();
  635.   const TLine* line = DrawDoc->GetLine(index);
  636.   if (line) {
  637.     TLine* newline = new TLine(*line);
  638.     if (newline->GetPenSize())
  639.       DrawDoc->ModifyLine(*newline, index);
  640.     delete newline;
  641.   }
  642. }
  643.  
  644. void TDrawListView::CmPenColor()
  645. {
  646.   int index = GetSelIndex();
  647.   const TLine* line = DrawDoc->GetLine(index);
  648.   if (line) {
  649.     TLine* newline = new TLine(*line);
  650.     if (newline->GetPenColor())
  651.       DrawDoc->ModifyLine(*newline, index);
  652.     delete newline;
  653.   }
  654. }
  655.  
  656. void TDrawListView::CmClear()
  657. {
  658.   DrawDoc->Clear();
  659. }
  660.  
  661. void TDrawListView::CmUndo()
  662. {
  663.   DrawDoc->Undo();
  664. }
  665.  
  666. void TDrawListView::CmDelete()
  667. {
  668.   DrawDoc->DeleteLine(GetSelIndex());
  669. }
  670.  
  671. BOOL TDrawListView::VnCommit(BOOL /*force*/)
  672. {
  673.   return TRUE;
  674. }
  675.  
  676. BOOL TDrawListView::VnRevert(BOOL /*clear*/)
  677. {
  678.   LoadData();
  679.   return TRUE;
  680. }
  681.  
  682. BOOL TDrawListView::VnAppend(unsigned int index)
  683. {
  684.   const TLine* line = DrawDoc->GetLine(index);
  685.   FormatData(line, index);
  686.   SetSelIndex(index);
  687.   return TRUE;
  688. }
  689.  
  690. BOOL TDrawListView::VnDelete(unsigned int index)
  691. {
  692.   DeleteString(index);
  693.   HandleMessage(WM_KEYDOWN,VK_DOWN); // force selection
  694.   return TRUE;
  695. }
  696.  
  697. BOOL TDrawListView::VnModify(unsigned int index)
  698. {
  699.   const TLine* line = DrawDoc->GetLine(index);
  700.   FormatData(line, index);
  701.   return TRUE;
  702. }
  703.  
  704. static char* PropNames[] = {
  705.   "Line Count",             // LineCount
  706.   "Description",             // Description
  707. };
  708.  
  709. static int PropFlags[] = {
  710.   pfGetBinary|pfGetText, // LineCount
  711.   pfGetText,             // Description
  712. };
  713.  
  714. const char*
  715. TDrawDocument::PropertyName(int index)
  716. {
  717.   if (index <= PrevProperty)
  718.     return TFileDocument::PropertyName(index);
  719.   else if (index < NextProperty)
  720.     return PropNames[index-PrevProperty-1];
  721.   else
  722.     return 0;
  723. }
  724.  
  725. int
  726. TDrawDocument::PropertyFlags(int index)
  727. {
  728.   if (index <= PrevProperty)
  729.     return TFileDocument::PropertyFlags(index);
  730.   else if (index < NextProperty)
  731.     return PropFlags[index-PrevProperty-1];
  732.   else
  733.     return 0;
  734. }
  735.  
  736. int
  737. TDrawDocument::FindProperty(const char far* name)
  738. {
  739.   for (int i=0; i < NextProperty-PrevProperty-1; i++)
  740.     if (strcmp(PropNames[i], name) == 0)
  741.       return i+PrevProperty+1;
  742.   return 0;
  743. }
  744.  
  745. int
  746. TDrawDocument::GetProperty(int prop, void far* dest, int textlen)
  747. {
  748.   if (IsOpen())
  749.     switch(prop)
  750.     {
  751.       case LineCount:
  752.       {
  753.         int count = Lines->GetItemsInContainer();
  754.         if (!textlen) {
  755.           *(int far*)dest = count;
  756.           return sizeof(int);
  757.         }
  758.         return wsprintf((char far*)dest, "%d", count);
  759.       }
  760.       case Description:
  761.         char* temp = new char[textlen]; // need local copy for medium model
  762.         int len = FileInfo.copy(temp, textlen);
  763.         strcpy((char far*)dest, temp);
  764.         return len;
  765.     }
  766.   return TFileDocument::GetProperty(prop, dest, textlen);
  767. }
  768.  
  769. IMPLEMENT_STREAMABLE1(TDrawDocument, TFileDocument);
  770.  
  771. void*
  772. TDrawDocument::Streamer::Read(ipstream& is, uint32 /*version*/) const
  773. {
  774.   TDrawDocument* o = GetObject();
  775.   o->UndoState = UndoNone;
  776.   o->UndoLine = 0;
  777.   o->Lines = 0;
  778.   ReadBaseObject((TFileDocument*)o, is);
  779.   return o;
  780. }
  781.  
  782. void
  783. TDrawDocument::Streamer::Write(opstream& os) const
  784. {
  785.   WriteBaseObject((TFileDocument*)GetObject(), os);
  786. }
  787.  
  788. IMPLEMENT_STREAMABLE1(TDrawView, TWindowView);
  789.  
  790. void*
  791. TDrawView::Streamer::Read(ipstream& is, uint32 /*version*/) const
  792. {
  793.   TDrawView* o = GetObject();
  794.   ReadBaseObject((TWindowView*)o, is);
  795.   is >> o->DrawDoc;
  796.   int width;
  797.   COLORREF color;  
  798.   is >> width >> color;
  799.   o->Line = new TLine(TColor(color), width);
  800.   o->DragDC = 0;
  801.   return o;
  802. }
  803.  
  804. void
  805. TDrawView::Streamer::Write(opstream &os) const
  806. {
  807.   TDrawView* o = GetObject();
  808.   WriteBaseObject((TWindowView*)o, os);
  809.   os << o->DrawDoc;
  810.   os << o->Line->QueryPenSize();
  811.   os << COLORREF(o->Line->QueryColor());
  812. }
  813.  
  814. IMPLEMENT_STREAMABLE2(TDrawListView, TListBox, TView);
  815.  
  816. void*
  817. TDrawListView::Streamer::Read(ipstream& is, uint32 /*version*/) const
  818. {
  819.   TDrawListView* o = GetObject();
  820.   ReadBaseObject((TListBox*)o, is);
  821.   ReadBaseObject((TView*)o, is);
  822.   is >> o->DrawDoc;
  823.   return o;
  824. }
  825.  
  826. void
  827. TDrawListView::Streamer::Write(opstream &os) const
  828. {
  829.   TDrawListView* o = GetObject();
  830.   WriteBaseObject((TListBox*)o, os);
  831.   WriteBaseObject((TView*)o, os);
  832.   os << o->DrawDoc;
  833. }
  834.  
  835.