home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 May / Pcwk5b98.iso / Borland / Cplus45 / BC45 / STEP14.PAK / STEP14DV.CPP < prev    next >
C/C++ Source or Header  |  1995-08-29  |  20KB  |  809 lines

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