home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / step17.pak / STEP17DV.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  34KB  |  1,486 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows - (C) Copyright 1994 by Borland International
  3. //   Tutorial application -- step17dv.cpp
  4. //   Automation Container Server 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 <owl/controlb.h>
  14. #include <owl/buttonga.h>
  15. #include <owl/scroller.h>  // scrolling support
  16. #include <classlib/arrays.h>
  17. #include <owl/olemdifr.h>
  18. #include <owl/oledoc.h>
  19. #include <owl/oleview.h>
  20. #include <ocf/automacr.h>
  21. #include <ocf/ocdata.h>
  22. #include <ocf/ocremvie.h>
  23. #include "step17dv.h"
  24. #include "step17.h"
  25. #include "step17dv.rc"
  26.  
  27. const char  DocContent[] = "All";
  28. const char  DrawPadFormat[] = "DrawPad";
  29.  
  30. BEGIN_REGISTRATION(DocReg)
  31.   REGDATA(progid,     "DrawPad.Drawing.17")
  32.   REGDATA(description,"DrawPad (Step17--AutoContServer) Drawing")
  33.   REGDATA(menuname,   "Drawing")
  34.   REGDATA(extension,  "p17")
  35.   REGDATA(docfilter,  "*.p17")
  36.   REGDOCFLAGS(dtAutoOpen | dtAutoDelete | dtUpdateDir | dtCreatePrompt | dtRegisterExt)
  37. #if defined(BI_PLAT_WIN32)
  38.   REGDATA(debugger,   "TD32")
  39. #else
  40.   REGDATA(debugger,   "TDW")
  41. #endif
  42.   REGDATA(debugprogid,"DrawPad.Drawing.D.17")
  43.   REGDATA(debugdesc,  "DrawPad (Step17--AutoContServer, debug) Drawing")
  44.   REGDATA(insertable, "")
  45.   REGDATA(verb0,      "&Edit")
  46.   REGDATA(verb1,      "&Open")
  47.   REGFORMAT(0, DrawPadFormat,   ocrContent,  ocrHGlobal,              ocrGetSet)
  48.   REGFORMAT(1, ocrEmbedSource,  ocrContent,  ocrIStorage,             ocrGetSet)
  49.   REGFORMAT(2, ocrMetafilePict, ocrContent,  ocrMfPict|ocrStaticMed,  ocrGet)
  50.   REGFORMAT(3, ocrBitmap,       ocrContent,  ocrGDI|ocrStaticMed,     ocrGet)
  51.   REGFORMAT(4, ocrDib,          ocrContent,  ocrHGlobal|ocrStaticMed, ocrGet)
  52. END_REGISTRATION
  53. BEGIN_REGISTRATION(ListReg)
  54.   REGDATA(description,"Line List")
  55.   REGDATA(extension,  "p17")
  56.   REGDATA(docfilter,  "*.p17")
  57.   REGDOCFLAGS(dtAutoDelete | dtHidden)
  58. END_REGISTRATION
  59.  
  60. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawView,       DrawTemplate);
  61. DEFINE_DOC_TEMPLATE_CLASS(TDrawDocument, TDrawListView,   DrawListTemplate);
  62. DrawTemplate drawTpl(DocReg);
  63. DrawListTemplate drawListTpl(ListReg);
  64.  
  65. //===============================  TLine  =====================================
  66. //
  67. void
  68. TLine::SetPen(int penSize)
  69. {
  70.   if (penSize < 1)
  71.     PenSize = 1;
  72.   else
  73.     PenSize = penSize;
  74. }
  75.  
  76. void
  77. TLine::SetPen(TColor& newColor, int penSize)
  78. {
  79.   // If penSize isn't the default (0), set PenSize to the new size.
  80.   if (penSize)
  81.     PenSize = penSize;
  82.  
  83.   Color = newColor;
  84. }
  85.  
  86. void
  87. TLine::Invalidate(TDrawView& view)
  88. {
  89.   TOleClientDC dc(view);
  90.  
  91.   TRect rUpdate(GetBound());
  92.   rUpdate.Inflate(1, 1);
  93.   dc.LPtoDP((TPoint *)&rUpdate, 2);
  94.   TUIHandle handle(rUpdate, TUIHandle::Framed);
  95.   rUpdate = handle.GetBoundingRect();
  96.  
  97.   view.GetDocument().NotifyViews(vnInvalidate, (long)&rUpdate, 0);
  98. }
  99.  
  100. void
  101. TLine::UpdateBound()
  102. {
  103.   // Iterates through the points in the line i.
  104.   TPointsIterator j(*this);
  105.   if (!j)
  106.     return;
  107.   TPoint p = j++;
  108.   Bound.Set(p.x, p.y, 0, 0);
  109.  
  110.   while (j) {
  111.     p = j++;
  112.    if ((p.x - PenSize) < Bound.left)
  113.      Bound.left = (p.x - PenSize);
  114.    if ((p.x + PenSize) > Bound.right)
  115.      Bound.right = (p.x + PenSize);
  116.    if ((p.y - PenSize) < Bound.top)
  117.      Bound.top = (p.y - PenSize);
  118.    if ((p.y + PenSize) > Bound.bottom)
  119.      Bound.bottom = (p.y + PenSize);
  120.   }
  121.   Bound.right  += 1;
  122.   Bound.bottom += 1;
  123. }
  124.  
  125. void
  126. TLine::UpdatePosition(TPoint& newPos)
  127. {
  128.   for (TPointsIterator i(*this); i; i++) {
  129.     TPoint* pt = (TPoint *)&i.Current();
  130.     pt->x += newPos.x;
  131.     pt->y += newPos.y;
  132.   }
  133.  
  134.   Bound.Offset(newPos.x, newPos.y);
  135. }
  136.  
  137. void
  138. TLine::UpdateSize(TSize& newSize)
  139. {
  140.   TSize delta = newSize - GetSize();
  141.   for (TPointsIterator i(*this); i; i++) {
  142.     TPoint* pt = (TPoint *)&i.Current();
  143.     pt->x += (((pt->x - Bound.left) * delta.cx + (GetSize().cx >> 1))/GetSize().cx);
  144.     pt->y += (((pt->y - Bound.top) * delta.cy + (GetSize().cy >> 1))/GetSize().cy);
  145.   }
  146.  
  147.   Bound.right = Bound.left + newSize.cx;
  148.   Bound.bottom = Bound.top  + newSize.cy;
  149. }
  150.  
  151. void
  152. TLine::DrawSelection(TDC &dc)
  153. {
  154.   TUIHandle(Bound, TUIHandle::DashFramed).Paint(dc);
  155. }
  156.  
  157. bool
  158. TLine::Draw(TDC& dc) const
  159. {
  160.   // Set pen for the dc to the values for this line
  161.   TPen pen(Color, PenSize, PS_INSIDEFRAME);
  162.   dc.SelectObject(pen);
  163.  
  164.   // Iterates through the points in the line i.
  165.   TPointsIterator j(*this);
  166.   bool first = true;
  167.  
  168.   while (j) {
  169.     TPoint p = j++;
  170.  
  171.     if (!first)
  172.       dc.LineTo(p);
  173.     else {
  174.       dc.MoveTo(p);
  175.       first = false;
  176.     }
  177.   }
  178.   dc.RestorePen();
  179.   return true;
  180. }
  181.  
  182. ostream&
  183. operator <<(ostream& os, const TLine& line)
  184. {
  185.   // Write the number of points in the line
  186.   os << line.GetItemsInContainer();
  187.  
  188.   // Get and write pen attributes.
  189.   os << ' ' << line.Color << ' ' << line.PenSize;
  190.  
  191.   // Get an iterator for the array of points
  192.   TPointsIterator j(line);
  193.  
  194.   // While the iterator is valid (i.e. we haven't run out of points)
  195.   while(j)
  196.     // Write the point from the iterator and increment the array.
  197.     os << j++;
  198.   os << '\n';
  199.  
  200.   // return the stream object
  201.   return os;
  202. }
  203.  
  204. istream&
  205. operator >>(istream& is, TLine& line)
  206. {
  207.   unsigned numPoints;
  208.   is >> numPoints;
  209.  
  210.   COLORREF color;
  211.   int penSize;
  212.   is >> color >> penSize;
  213.   line.SetPen(TColor(color), penSize);
  214.  
  215.   while (numPoints--) {
  216.     TPoint point;
  217.     is >> point;
  218.     line.Add(point);
  219.   }
  220.  
  221.   // return the stream object
  222.   return is;
  223. }
  224.  
  225. DEFINE_AUTOCLASS(TDrawDocument)
  226.   EXPOSE_PROPRW(PenSize,    TAutoShort, "PenSize",    "Current pen size", 0)
  227.   EXPOSE_PROPRW(PenColor,   TAutoLong,  "PenColor",   "Current pen color", 0)
  228.   EXPOSE_METHOD(AddPoint,   TAutoVoid,  "AddPoint",   "Add a point to the current line", 0)
  229.    REQUIRED_ARG(            TAutoShort, "X")
  230.    REQUIRED_ARG(            TAutoShort, "Y")
  231.   EXPOSE_METHOD(AddLine,    TAutoVoid,  "AddLine",    "Add current line into drawing", 0)
  232.   EXPOSE_METHOD(ClearLine,  TAutoVoid,  "ClearLine",  "Erases current line", 0)
  233.   EXPOSE_APPLICATION(       TDrawApp,   "Application","Application object", 0)
  234. END_AUTOCLASS(TDrawDocument, tfNormal,  "TDrawDoc",   "Draw document class", 0)
  235.  
  236. TDrawDocument::TDrawDocument(TDocument* parent)
  237.   : TOleDocument(parent), UndoLine(0), UndoState(UndoNone)
  238. {
  239.   Lines         = new TLines(100, 0, 5);
  240.   AutoPenSize   = 1;
  241.   AutoPenColor  = RGB(0, 0, 0);
  242.   AutoLine      = new TLine(AutoPenColor, AutoPenSize);
  243.  
  244.   TScreenDC dc;
  245.  
  246.   // 8.5"" x 11" draw document
  247.   DocSize.cx = dc.GetDeviceCaps(LOGPIXELSX)* 85 / 10;
  248.   DocSize.cy = dc.GetDeviceCaps(LOGPIXELSY)* 11;
  249. }
  250.  
  251. TDrawDocument::~TDrawDocument()
  252. {
  253.   delete AutoLine;
  254.   delete Lines;
  255.   delete UndoLine;
  256. }
  257.  
  258. TLine*
  259. TDrawDocument::GetLine(TString& moniker)
  260. {
  261.   int index = atoi(moniker);
  262.   return GetLine(index);
  263. }
  264.  
  265. bool
  266. TDrawDocument::CommitSelection(TOleWindow& oleWin, void* userData)
  267. {
  268.   TOleDocument::CommitSelection(oleWin, userData);
  269.  
  270.   TDrawView* drawView = TYPESAFE_DOWNCAST(&oleWin, TDrawView);
  271.   TOutStream* os = OutStream(ofWrite);
  272.   if (!os || !drawView)
  273.     return false;
  274.  
  275.   // Make the line usable in a container by adjusting its origin
  276.   //
  277.   TLine* line = (TLine*)userData;
  278.   int i = line? 1 : 0;
  279.   TPoint newPos(Margin, Margin);
  280.   if (line) {
  281.     newPos -= line->GetBound().TopLeft();
  282.     line->UpdatePosition(newPos);
  283.   }
  284.  
  285.   // Write the number of lines in the figure
  286.   *os << i;
  287.  
  288.   // Append a description using a resource string
  289.   *os << ' ' << FileInfo << '\n';
  290.  
  291.   // Copy the current line from the iterator and increment the array.
  292.   if (line)
  293.     *os << *line;
  294.  
  295.   delete os;
  296.  
  297.   // restore line
  298.   //
  299.   if (line)
  300.     line->UpdatePosition(-newPos);
  301.  
  302.   //
  303.   // Commit the storage if it was opened in transacted mode
  304. //  TOleDocument::CommitTransactedStorage();
  305.  
  306.   return true;
  307. }
  308.  
  309. bool
  310. TDrawDocument::Commit(bool force)
  311. {
  312.   TOleDocument::Commit(force);
  313.  
  314.   TOutStream* os = OutStream(ofWrite);
  315.   if (!os)
  316.     return false;
  317.  
  318.   // Write the number of lines in the figure
  319.   *os << Lines->GetItemsInContainer();
  320.  
  321.   // Append a description using a resource string
  322.   *os << ' ' << FileInfo << '\n';
  323.  
  324.   // Get an iterator for the array of lines
  325.   TLinesIterator i(*Lines);
  326.  
  327.   // While the iterator is valid (i.e. we haven't run out of lines)
  328.   while (i) {
  329.     // Copy the current line from the iterator and increment the array.
  330.     *os << i++;
  331.   }
  332.   delete os;
  333.  
  334.   //
  335.   // Commit the storage if it was opened in transacted mode
  336.   TOleDocument::CommitTransactedStorage();
  337.   SetDirty(false);
  338.  
  339.   return true;
  340. }
  341.  
  342. bool
  343. TDrawDocument::Open(int mode, const char far* path)
  344. {
  345.   char fileinfo[100];
  346.  
  347.   TOleDocument::Open(mode, path);   // normally path should be null
  348.   if (GetDocPath()) {
  349.     TInStream* is = (TInStream*)InStream(ofRead);
  350.     if (!is)
  351.       return false;
  352.  
  353.     unsigned numLines;
  354.     *is >> numLines;
  355.     is->getline(fileinfo, sizeof(fileinfo));
  356.     while (numLines--) {
  357.       TLine line;
  358.       *is >> line;
  359.       line.UpdateBound();
  360.       Lines->Add(line);
  361.     }
  362.  
  363.     delete is;
  364.  
  365.     FileInfo = fileinfo;
  366.   } else {
  367.     FileInfo = string(*::Module,IDS_FILEINFO);
  368.   }
  369.   SetDirty(false);
  370.   UndoState = UndoNone;
  371.   return true;
  372. }
  373.  
  374. //
  375. // Read in the lines from a storage and put them at the location specified
  376. // by where
  377. //
  378. bool
  379. TDrawDocument::OpenSelection(int mode, const char far* path, TPoint far* where)
  380. {
  381.   char fileinfo[100];
  382.  
  383.   TOleDocument::Open(mode, path);   // normally path should be null
  384.   TInStream* is = (TInStream*)InStream(ofRead);
  385.   if (!is)
  386.     return false;
  387.  
  388.   unsigned numLines;
  389.   *is >> numLines;
  390.   is->getline(fileinfo, sizeof(fileinfo));
  391.   while (numLines--) {
  392.     TLine line;
  393.     *is >> line;
  394.     if (where) {
  395.       TPoint newPos(where->x, where->y);
  396.       newPos -= line.GetBound().TopLeft();
  397.       line.UpdatePosition(newPos);
  398.     }
  399.     line.UpdateBound();
  400.     Lines->Add(line);
  401.   }
  402.  
  403.   delete is;
  404.  
  405.   FileInfo = fileinfo;
  406.   SetDirty(false);
  407.   UndoState = UndoNone;
  408.   return true;
  409. }
  410.  
  411. bool
  412. TDrawDocument::Close()
  413. {
  414.   if (TOleDocument::Close()) {
  415.     Lines->Flush();
  416.     return true;
  417.   }
  418.  
  419.   return false;
  420. }
  421.  
  422. TLine*
  423. TDrawDocument::GetLine(uint index)
  424. {
  425.   return index < Lines->GetItemsInContainer() ? &(*Lines)[index] : 0;
  426. }
  427.  
  428. int
  429. TDrawDocument::AddLine(TLine& line)
  430. {
  431.   int index = Lines->GetItemsInContainer();
  432.   Lines->Add(line);
  433.   SetDirty(true);
  434.   NotifyViews(vnDrawAppend, index);
  435.   UndoState = UndoAppend;
  436.   return index;
  437. }
  438.  
  439. void
  440. TDrawDocument::DeleteLine(uint index)
  441. {
  442.   const TLine* oldLine = GetLine(index);
  443.   if (!oldLine)
  444.     return;
  445.   delete UndoLine;
  446.   UndoLine = new TLine(*oldLine);
  447.   Lines->Detach(index);
  448.   SetDirty(true);
  449.   NotifyViews(vnDrawDelete, index);
  450.   UndoState = UndoDelete;
  451. }
  452.  
  453. void
  454. TDrawDocument::ModifyLine(TLine& line, uint index)
  455. {
  456.   delete UndoLine;
  457.   UndoLine = new TLine((*Lines)[index]);
  458.   SetDirty(true);
  459.   (*Lines)[index] = line;
  460.   NotifyViews(vnDrawModify, index);
  461.   UndoState = UndoModify;
  462.   UndoIndex = index;
  463. }
  464.  
  465. void
  466. TDrawDocument::Clear()
  467. {
  468.   Lines->Flush();
  469.   NotifyViews(vnRevert, true);
  470. }
  471.  
  472. void
  473. TDrawDocument::Undo()
  474. {
  475.   switch (UndoState) {
  476.     case UndoAppend:
  477.       DeleteLine(Lines->GetItemsInContainer()-1);
  478.       return;
  479.     case UndoDelete:
  480.       AddLine(*UndoLine);
  481.       delete UndoLine;
  482.       UndoLine = 0;
  483.       return;
  484.     case UndoModify:
  485.       TLine* temp = UndoLine;
  486.       UndoLine = 0;
  487.       ModifyLine(*temp, UndoIndex);
  488.       delete temp;
  489.   }
  490. }
  491.  
  492. bool
  493. GetPenSize(TWindow* parent, TLine& line)
  494. {
  495.   char inputText[6];
  496.  
  497.   wsprintf(inputText, "%d", line.QueryPenSize());
  498.   if (TInputDialog(parent, "Line Thickness",
  499.                    "Input a new thickness:",
  500.                    inputText,
  501.                    sizeof(inputText)).Execute() != IDOK)
  502.     return false;
  503.   line.SetPen(atoi(inputText));
  504.  
  505.   if (line.QueryPenSize() < 1)
  506.     line.SetPen(1);
  507.  
  508.   return true;
  509. }
  510.  
  511. bool
  512. GetPenColor(TWindow* parent, TLine& line)
  513. {
  514.   TChooseColorDialog::TData colors;
  515.   static TColor custColors[16] =
  516.   {
  517.     0x010101L, 0x101010L, 0x202020L, 0x303030L,
  518.     0x404040L, 0x505050L, 0x606060L, 0x707070L,
  519.     0x808080L, 0x909090L, 0xA0A0A0L, 0xB0B0B0L,
  520.     0xC0C0C0L, 0xD0D0D0L, 0xE0E0E0L, 0xF0F0F0L
  521.   };
  522.  
  523.   colors.Flags = CC_RGBINIT;
  524.   colors.Color = TColor(line.QueryColor());
  525.   colors.CustColors = custColors;
  526.   if (TChooseColorDialog(parent, colors).Execute() != IDOK)
  527.     return false;
  528.   line.SetPen(colors.Color);
  529.   return true;
  530. }
  531.  
  532. DEFINE_RESPONSE_TABLE1(TDrawLinkView, TOleLinkView)
  533.   EV_VN_DRAWDELETE,
  534.   EV_VN_DRAWMODIFY,
  535. END_RESPONSE_TABLE;
  536.  
  537. TDrawLinkView::TDrawLinkView(TDocument& doc, TOcLinkView& view)
  538.   :TOleLinkView(doc, view)
  539. {
  540.   DrawDoc = TYPESAFE_DOWNCAST(&doc, TDrawDocument);
  541.   CHECK(DrawDoc);
  542. }
  543.  
  544. TDrawLinkView::~TDrawLinkView()
  545. {
  546. }
  547.  
  548. //
  549. // Line was modified
  550. //
  551. bool
  552. TDrawLinkView::VnModify(uint index)
  553. {
  554.   // Get the selection correspondign to the moniker
  555.   //
  556.   TLine * line = DrawDoc->GetLine(GetMoniker());
  557.   if (!line)
  558.     return false;
  559.  
  560.   // Notify the container
  561.   //
  562.   if (index == DrawDoc->GetLines()->Find(*line)) {
  563.     UpdateLinks();
  564.   }
  565.  
  566.   return true;
  567. }
  568.  
  569. //
  570. // Line was deleted
  571. //
  572. bool
  573. TDrawLinkView::VnDelete(uint index)
  574. {
  575.   // Get the selection correspondign to the moniker
  576.   //
  577.   TLine * line = DrawDoc->GetLine(GetMoniker());
  578.   if (!line)
  579.     return false;
  580.  
  581.   // Notify the container
  582.   //
  583.   if (index == DrawDoc->GetLines()->Find(*line)) {
  584.     UpdateLinks();
  585.   }
  586.   return true;
  587. }
  588.  
  589. DEFINE_RESPONSE_TABLE1(TDrawView, TOleView)
  590.   EV_WM_LBUTTONDOWN,
  591.   EV_WM_MOUSEMOVE,
  592.   EV_WM_LBUTTONUP,
  593.   EV_COMMAND(CM_PEN, CmPen),
  594.   EV_COMMAND_ENABLE(CM_PEN, CePen),
  595.   EV_COMMAND(CM_SELECT, CmSelect),
  596.   EV_COMMAND_ENABLE(CM_SELECT, CeSelect),
  597.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  598.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  599.   EV_COMMAND(CM_EDITCLEAR, CmClear),
  600.   EV_COMMAND(CM_EDITUNDO, CmUndo),
  601.   EV_COMMAND(CM_EDITCUT, CmEditCut),
  602.   EV_COMMAND(CM_EDITCOPY, CmEditCopy),
  603.   EV_COMMAND_ENABLE(CM_EDITCUT, CeEditCut),
  604.   EV_COMMAND_ENABLE(CM_EDITCOPY, CeEditCopy),
  605.   EV_COMMAND(CM_ORGSIZE, CmOrgSize),
  606.   EV_COMMAND(CM_DOUBLESIZE, CmDoubleSize),
  607.   EV_COMMAND(CM_HALFSIZE, CmHalfSize),
  608.   EV_COMMAND_ENABLE(CM_ORGSIZE, CeOrgSize),
  609.   EV_COMMAND_ENABLE(CM_DOUBLESIZE, CeDoubleSize),
  610.   EV_COMMAND_ENABLE(CM_HALFSIZE, CeHalfSize),
  611.   EV_VN_COMMIT,
  612.   EV_VN_REVERT,
  613.   EV_VN_DRAWAPPEND,
  614.   EV_VN_DRAWDELETE,
  615.   EV_VN_DRAWMODIFY,
  616.  
  617.   EV_WM_SETFOCUS,
  618.   EV_OC_VIEWPARTSIZE,
  619.   EV_OC_VIEWSHOWTOOLS,
  620.   EV_OC_VIEWGETITEMNAME,
  621.   EV_OC_VIEWSETLINK,
  622.   EV_OC_VIEWCLIPDATA,
  623.  
  624. END_RESPONSE_TABLE;
  625.  
  626. TDrawView::TDrawView(TDrawDocument& doc, TWindow* parent)
  627. :
  628.   TOleView(doc, parent), DrawDoc(&doc)
  629. {
  630.   Selected  = 0;
  631.   Tool      = DrawPen;
  632.   ToolBar   = 0;
  633.  
  634.   Line = new TLine(TColor::Black, 1);
  635.   Attr.AccelTable = IDA_DRAWVIEW;
  636.   SetViewMenu(new TMenuDescr(IDM_DRAWVIEW));
  637.  
  638.   // Name our clipboard format
  639.   //
  640.   OcApp->AddUserFormatName("DrawPad Native Data", "Owl DrawPad native data", DrawPadFormat);
  641. }
  642.  
  643. void
  644. TDrawView::SetupWindow()
  645. {
  646.   TOleView::SetupWindow();
  647.  
  648.   // Scroll bars
  649.   Attr.Style |= WS_VSCROLL | WS_HSCROLL;
  650.  
  651.   Scroller = new TScroller(this, 1, 1, 0, 0);
  652.   AdjustScroller();
  653.  
  654.   // Set this option to force all embedded servers to open out of place
  655.   // GetOcView()->SetOption(voNoInPlace,true);
  656.  
  657.   // Set this option to force all embedded servers to open out of place
  658.   // when the container/server is inplace
  659.   // GetOcView()->SetOption(voNoNestedInPlace,true);
  660.   
  661. }
  662.  
  663. //
  664. // Adjust the Scroller range
  665. //
  666. void
  667. TDrawView::AdjustScroller()
  668. {
  669.   TDrawDocument *drawDoc = TYPESAFE_DOWNCAST(&GetDocument(), TDrawDocument);
  670.   CHECK(drawDoc);
  671.   TSize range = drawDoc->GetDocSize();
  672.  
  673.   // Use device unit for scroll range
  674.   //
  675.   TOleClientDC dc(*this);
  676.   dc.LPtoDP((TPoint*)&range);
  677.  
  678.   range -= GetClientRect().Size();
  679.   Scroller->SetRange(range.cx, range.cy);
  680. }
  681.  
  682. //
  683. // Reset scroller range.
  684. //
  685. void
  686. TDrawView::EvSize(UINT SizeType, TSize& Size)
  687. {
  688.   TOleView::EvSize(SizeType, Size);
  689.   if (SizeType != SIZEICONIC) {
  690.     AdjustScroller();
  691.   }
  692. }
  693.  
  694. static int
  695. Intersect(const TLine& line, void* param)
  696. {
  697.   TPoint*  pt = (TPoint*)param;
  698.   TLine &modify = const_cast<TLine&>(line);
  699.   if (modify.IsSelected()) {
  700.     modify.Where = TUIHandle(modify.GetBound(), TUIHandle::Framed).HitTest(*pt);
  701.   }
  702.   else {
  703.     if (modify.GetBound().Contains(*pt))
  704.       modify.Where = TUIHandle::MidCenter;
  705.     else
  706.       modify.Where = TUIHandle::Outside;
  707.   }
  708.  
  709.   return line.Where != TUIHandle::Outside;
  710. }
  711.  
  712. TLine*
  713. TDrawView::HitTest(TPoint& pt)
  714. {
  715.   return DrawDoc->GetLines()->LastThat(Intersect, &pt);
  716. }
  717.  
  718. bool
  719. TDrawView::ShowCursor(HWND /*wnd*/, uint hitTest, uint /*mouseMsg*/)
  720. {
  721.   TPoint pt;
  722.   GetCursorPos(pt);
  723.   ScreenToClient(pt);
  724.   if (Tool == DrawSelect) {
  725.     ::SetCursor(::LoadCursor(0, IDC_ARROW));
  726.     return true;
  727.   }
  728.  
  729.   if (Tool == DrawPen && (hitTest == HTCLIENT)) {
  730.     HCURSOR cur = ::LoadCursor(*GetModule(), MAKEINTRESOURCE(IDC_PENCIL));
  731.     ::SetCursor(cur);
  732.     return true;
  733.   }
  734.  
  735.   if (Tool == DrawPen && ((hitTest == HTHSCROLL) || (hitTest == HTVSCROLL))) {
  736.     ::SetCursor(::LoadCursor(0, IDC_ARROW));
  737.     return true;
  738.   }
  739.  
  740.   return false;
  741. }
  742.  
  743.  
  744. //
  745. // Let container know about the server view size in pixels
  746. //
  747. bool
  748. TDrawView::EvOcViewPartSize(TOcPartSize far& ps)
  749. {
  750.   TClientDC dc(*this);
  751.  
  752.   TRect rect(0, 0, 0, 0);
  753.   TLine* line = 0;
  754.   if (ps.Selection) {
  755.     if (ps.Moniker) {
  756.       if (strcmp(*ps.Moniker, OleStr(DocContent)) == 0)
  757.         line = 0; // whole document
  758.       else
  759.         line = DrawDoc->GetLine(*ps.Moniker);
  760.     }
  761.     else{
  762.       line = (TLine*) ps.UserData;
  763.     }
  764.   }
  765.  
  766.   if (line) {
  767.     *(TPoint*)&rect.left   = line->GetBound().TopLeft();
  768.     rect.right  = rect.left + line->GetBound().Width()  + 2 * Margin;
  769.     rect.bottom = rect.top  + line->GetBound().Height() + 2 * Margin;
  770.   }
  771.   else {
  772.     // a 2" x 2" extent for server
  773.     //
  774.     rect.right  = dc.GetDeviceCaps(LOGPIXELSX) * 2;
  775.     rect.bottom = dc.GetDeviceCaps(LOGPIXELSY) * 2;
  776.   }
  777.  
  778.   ps.PartRect = rect;
  779.   return true;
  780. }
  781.  
  782. bool
  783. TDrawView::EvOcViewShowTools(TOcToolBarInfo far& tbi)
  784. {
  785.   // Construct & create a control bar for show, destroy our bar for hide
  786.   //
  787.   if (tbi.Show) {
  788.     if (!ToolBar) {
  789.       ToolBar = new TControlBar(this);
  790.       ToolBar->Insert(*new TButtonGadget(CM_PENSIZE, CM_PENSIZE, TButtonGadget::Command));
  791.       ToolBar->Insert(*new TButtonGadget(CM_PENCOLOR, CM_PENCOLOR, TButtonGadget::Command));
  792.       ToolBar->Insert(*new TSeparatorGadget);
  793.       ToolBar->Insert(*new TButtonGadget(CM_PEN, CM_PEN, TButtonGadget::Exclusive));
  794.       ToolBar->Insert(*new TButtonGadget(CM_SELECT, CM_SELECT, TButtonGadget::Exclusive));
  795.       ToolBar->Insert(*new TButtonGadget(CM_ABOUT, CM_ABOUT, TButtonGadget::Command));
  796.       ToolBar->SetHintMode(TGadgetWindow::EnterHints);
  797.     }
  798.     ToolBar->Create();
  799.     tbi.HTopTB = (HWND)*ToolBar;
  800.   }
  801.   else {
  802.     if (ToolBar) {
  803.       ToolBar->Destroy();
  804.       delete ToolBar;
  805.       ToolBar = 0;
  806.     }
  807.   }
  808.   return true;
  809. }
  810.  
  811. //
  812. // Find the item name for whole doc or selection
  813. //
  814. bool
  815. TDrawView::EvOcViewGetItemName(TOcItemName& item)
  816. {
  817.   if (item.Selection) {
  818.     if (!Selected)
  819.       return false;
  820.     char name[32];
  821.     itoa(DrawDoc->GetLines()->Find(*Selected), name, 10);
  822.     item.Name = name;
  823.   }
  824.   else {
  825.     item.Name = "content"; // item name representing the whole document
  826.   }
  827.   return true;
  828. }
  829.  
  830.  
  831. //
  832. // Ask server to provide data according to the format in a handle
  833. //
  834. bool
  835. TDrawView::EvOcViewClipData(TOcFormatData far& formatData)
  836. {
  837.   if (strcmp(OleStr(formatData.Format.GetRegName()), OleStr(DrawPadFormat)) != 0)
  838.     return false; // not our clipboard format
  839.  
  840.   bool status = true;
  841.   if (formatData.Paste) { // Pasting native data
  842.     DrawDoc->SetHandle(ofReadWrite, formatData.Handle, false);
  843.     DrawDoc->OpenSelection(ofRead, 0, formatData.Where);
  844.     Invalidate();
  845.     // Restore the original storage
  846.     //
  847.     DrawDoc->RestoreStorage();
  848.  
  849.   }
  850.   else { // Copying native data
  851.     HANDLE data = GlobalAlloc(GHND|GMEM_SHARE, 0);
  852.     DrawDoc->SetHandle(ofReadWrite, data, true);
  853.  
  854.     // Copy the selection if the target format is "DrawPad"
  855.     //
  856.     if (formatData.UserData) {
  857.       status = DrawDoc->CommitSelection(*this, formatData.UserData);
  858.     }
  859.     else {
  860.       status = DrawDoc->Commit(true);
  861.     }
  862.  
  863.     formatData.Handle = data;
  864.     // Restore the original storage
  865.     //
  866.     DrawDoc->RestoreStorage();
  867.   }
  868.  
  869.   return status;
  870. }
  871.  
  872.  
  873. //
  874. // object selection
  875. //
  876. bool
  877. TDrawView::Select(uint modKeys, TPoint& point)
  878. {
  879.   if (Tool != DrawSelect)
  880.     return false;
  881.  
  882.   // Clicked in lines?
  883.   TLine *line = HitTest(point);
  884.   SetLineSelection(line);
  885.  
  886.   if (Selected) { // there is a selection
  887.     TOleView::SetSelection(0);
  888.     DragRect = line->GetBound();
  889.     DragRect.right++;
  890.     DragRect.bottom++;
  891.     DragHit = line->Where;
  892.     DragStart = DragPt = point;
  893.     if (!DragDC)
  894.       DragDC = new TOleClientDC(*this);
  895.  
  896.     DragDC->DrawFocusRect(DragRect);
  897.     SetCapture();
  898.     return true;
  899.   }
  900.   else
  901.     // Select OLE object, if any
  902.     return TOleView::Select(modKeys, point);
  903.  
  904. }
  905.  
  906. void
  907. TDrawView::EvLButtonDown(uint modKeys, TPoint& point)
  908. {
  909.   TOleView::EvLButtonDown(modKeys, point);
  910.   if (SelectEmbedded() || !DragDC)
  911.     return;
  912.  
  913.   if (Tool == DrawSelect) { // selection
  914. //    Select(modKeys, point);
  915.   }
  916.   else if (Tool == DrawPen) {
  917.     SetCapture();
  918.     Pen = new TPen(Line->QueryColor(), Line->QueryPenSize());
  919.     DragDC->SelectObject(*Pen);
  920.     DragRect.SetNull();
  921.     DragDC->MoveTo(point);
  922.     Line->Add(point);
  923.   }
  924. }
  925.  
  926. void
  927. TDrawView::EvMouseMove(uint modKeys, TPoint& point)
  928. {
  929.   TOleView::EvMouseMove(modKeys, point);
  930.   if (SelectEmbedded() || !DragDC)
  931.     return;
  932.  
  933.   if (Tool == DrawPen) {
  934.     DragDC->LineTo(point);
  935.     Line->Add(point);
  936.   }
  937.   else if (Selected && DragHit == TUIHandle::MidCenter &&
  938.     !InClient(*DragDC, point)) { // selection
  939.     DragDC->DrawFocusRect(DragRect);   // erase old rect
  940.  
  941.     // Start drag & drop
  942.     //
  943.     TOcDropAction outAction;
  944.     TOcDataProvider* ocData = new TOcDataProvider(*OcView, &DocReg, 0,
  945.                                                   (void*)Selected, CleanUp);
  946.     OcApp->Drag(ocData, daDropCopy | daDropMove | daDropLink, outAction);
  947.  
  948.     if (outAction == daDropMove) {
  949.       DrawDoc->DeleteLine(DrawDoc->GetLines()->Find(*Selected));
  950.       SetLineSelection(0);
  951.     }
  952.     ocData->Release();
  953.     DragHit = TUIHandle::Outside;
  954.   }
  955. }
  956.  
  957. void
  958. TDrawView::SetLineSelection(TLine *Line)
  959. {
  960.   if (Selected) {
  961.     Selected->Invalidate(*this);
  962.     Selected->Select(false);
  963.   }
  964.   Selected = Line;
  965.   if (Selected) {
  966.     Selected->Select(true);
  967.     Selected->Invalidate(*this);
  968.   }
  969. }
  970.  
  971. void
  972. TDrawView::SetLineSelection(int index)
  973. {
  974.   SetLineSelection(DrawDoc->GetLine(index));
  975. }
  976.  
  977. void TDrawView::EvLButtonUp(uint modKeys, TPoint& point)
  978. {
  979.   TPoint oldPoint = point;
  980.  
  981.   if (!DragDC)
  982.     return;
  983.  
  984.   if ((Tool == DrawSelect) && !SelectEmbedded()) {
  985.     if (Selected && DragHit == TUIHandle::MidCenter) {
  986.       Selected->Invalidate(*this);
  987.       DragDC->DPtoLP(&point);
  988.       TPoint newPos = point - DragStart;
  989.       Selected->UpdatePosition(newPos);
  990.       Selected->Invalidate(*this);
  991.       InvalidatePart(invView);
  992.       DragHit = TUIHandle::Outside;
  993.       ReleaseCapture();
  994.     }
  995.   } else if ((Tool == DrawPen) && !SelectEmbedded()) {
  996.     ReleaseCapture();
  997.     if (Line->GetItemsInContainer() > 1) {
  998.       Line->UpdateBound();
  999.       DrawDoc->AddLine(*Line);
  1000.     }
  1001.  
  1002.     Line->Flush();
  1003.     delete Pen;
  1004.   }
  1005.  
  1006.   TOleView::EvLButtonUp(modKeys, oldPoint);
  1007. }
  1008.  
  1009. void
  1010. TDrawView::CePen(TCommandEnabler& ce)
  1011. {
  1012.   ce.SetCheck(Tool == DrawPen);
  1013. }
  1014.  
  1015. void
  1016. TDrawView::CeSelect(TCommandEnabler& ce)
  1017. {
  1018.   ce.SetCheck(Tool == DrawSelect);
  1019. }
  1020.  
  1021. void
  1022. TDrawView::CmPen()
  1023. {
  1024.   Tool = DrawPen;
  1025. }
  1026.  
  1027. void
  1028. TDrawView::CmSelect()
  1029. {
  1030.   Tool = DrawSelect;
  1031. }
  1032.  
  1033. void
  1034. TDrawView::CmPenSize()
  1035. {
  1036.   if (Selected) {
  1037.     GetPenSize(this, *Selected);
  1038.     Selected->UpdateBound();
  1039.     DrawDoc->ModifyLine(*Selected, DrawDoc->GetLines()->Find(*Selected));
  1040.   }
  1041.   else
  1042.     GetPenSize(this, *Line);
  1043. }
  1044.  
  1045. void
  1046. TDrawView::CmPenColor()
  1047. {
  1048.   if (Selected) {
  1049.     GetPenColor(this, *Selected);
  1050.     DrawDoc->ModifyLine(*Selected, DrawDoc->GetLines()->Find(*Selected));
  1051.   }
  1052.   else
  1053.     GetPenColor(this, *Line);
  1054. }
  1055.  
  1056. void
  1057. TDrawView::CmOrgSize()
  1058. {
  1059.   SetScale(100);
  1060. }
  1061.  
  1062. void
  1063. TDrawView::CmDoubleSize()
  1064. {
  1065.   SetScale(200);
  1066. }
  1067.  
  1068. void
  1069. TDrawView::CmHalfSize()
  1070. {
  1071.   SetScale(50);
  1072. }
  1073.  
  1074. void
  1075. TDrawView::CeOrgSize(TCommandEnabler& ce)
  1076. {
  1077.   ce.SetCheck(!Scale.IsZoomed());
  1078. }
  1079.  
  1080. void
  1081. TDrawView::CeDoubleSize(TCommandEnabler& ce)
  1082. {
  1083.   ce.SetCheck(Scale.GetScale() == 200);
  1084. }
  1085.  
  1086. void
  1087. TDrawView::CeHalfSize(TCommandEnabler& ce)
  1088. {
  1089.   ce.SetCheck(Scale.GetScale() == 50);
  1090. }
  1091.  
  1092. void
  1093. TDrawView::CmClear()
  1094. {
  1095.   DrawDoc->Clear();
  1096. }
  1097.  
  1098. void
  1099. TDrawView::CmUndo()
  1100. {
  1101.   DrawDoc->Undo();
  1102. }
  1103.  
  1104. void
  1105. TDrawView::CeEditCut(TCommandEnabler& ce)
  1106. {
  1107.   ce.Enable(Selected != 0 || SelectEmbedded());
  1108. }
  1109.  
  1110. void
  1111. TDrawView::CeEditCopy(TCommandEnabler& ce)
  1112. {
  1113.   ce.Enable(Selected != 0 || SelectEmbedded());
  1114. }
  1115.  
  1116. //
  1117. // method to clean up the userdata passed to TOcDataProvider
  1118. //
  1119. void
  1120. TDrawView::CleanUp(void* /*userData*/)
  1121. {
  1122.   // No data clean up to do here
  1123. }
  1124.  
  1125. void
  1126. TDrawView::CmEditCut()
  1127. {
  1128.   if (Selected) {
  1129.     // Create a TOcDataProvider with current selection
  1130.     //
  1131.     TOcDataProvider* ocData = new TOcDataProvider(*OcView, &DocReg, 0,
  1132.                                                   (void*)Selected, CleanUp);
  1133.     OcApp->Copy(ocData);
  1134.  
  1135.     // Ask server to render its data before it's deleted
  1136.     //
  1137.     ocData->Disconnect();
  1138.     ocData->Release();
  1139.  
  1140.     // Delete the line
  1141.     //
  1142.     DrawDoc->DeleteLine(DrawDoc->GetLines()->Find(*Selected));
  1143.     SetLineSelection(0);
  1144.   }
  1145.   else
  1146.     TOleView::CmEditCut();
  1147. }
  1148.  
  1149. void
  1150. TDrawView::CmEditCopy()
  1151. {
  1152.   if (Selected) {
  1153.     // Create a TOcDataProvider with current selection
  1154.     //
  1155.     TOcDataProvider* ocData = new TOcDataProvider(*OcView, &DocReg, 0,
  1156.                                                   (void*)Selected, CleanUp);
  1157.     OcApp->Copy(ocData);
  1158.     ocData->Release();
  1159.   }
  1160.   else
  1161.     TOleView::CmEditCopy();
  1162. }
  1163.  
  1164. void
  1165. TDrawView::Paint(TDC& dc, bool /*erase*/, TRect& /*rect*/)
  1166. {
  1167.   bool metafile = (dc.GetDeviceCaps(TECHNOLOGY) == DT_METAFILE);
  1168.  
  1169.   // Iterates through the array of line objects.
  1170.   int j = 0;
  1171.   TLine* line;
  1172.   while ((line = const_cast<TLine *>(DrawDoc->GetLine(j++))) != 0) {
  1173.     line->Draw(dc);
  1174.     if (line->IsSelected() && !metafile)
  1175.       line->DrawSelection(dc);
  1176.   }
  1177. }
  1178.  
  1179. bool
  1180. TDrawView::PaintSelection(TDC& dc, bool /*erase*/, TRect& /*rect*/, void* userData)
  1181. {
  1182.   TLine* line = (TLine*) userData;
  1183.   if (!line)
  1184.     return false;
  1185.  
  1186.   TPoint newPos(Margin, Margin);
  1187.   newPos -= line->GetBound().TopLeft();
  1188.   line->UpdatePosition(newPos);
  1189.   line->Draw(dc);
  1190.   line->UpdatePosition(-newPos);
  1191.  
  1192.   return true;
  1193. }
  1194.  
  1195. // Establish link with whole doc or selection
  1196. //
  1197. bool
  1198. TDrawView::EvOcViewSetLink(TOcLinkView& view)
  1199. {
  1200.   // Attach a linked view to this document
  1201.   //
  1202.   new TDrawLinkView(GetDocument(), view);
  1203.   return true;
  1204. }
  1205.  
  1206. bool
  1207. TDrawView::PaintLink(TDC& dc, bool erase, TRect& rect, TString& moniker)
  1208. {
  1209.   TLine* line = 0;
  1210.   //Draw the whole document if linking to the whole doc
  1211.   //
  1212.   if (strcmp(moniker, OleStr(DocContent)) == 0) {
  1213.     Paint(dc, erase, rect);
  1214.     return true;
  1215.   }
  1216.  
  1217.   // Find the selection with the corresponding moniker
  1218.   //
  1219.   line = DrawDoc->GetLine(moniker);
  1220.  
  1221.   if (!line)
  1222.     return false;
  1223.  
  1224.   TPoint newPos(Margin, Margin);
  1225.   newPos -= rect.TopLeft();
  1226.   line->UpdatePosition(newPos);
  1227.   line->Draw(dc);
  1228.   line->UpdatePosition(-newPos);
  1229.   return true;
  1230. }
  1231.  
  1232. bool
  1233. TDrawView::VnCommit(bool /*force*/)
  1234. {
  1235.   // nothing to do here, no data held in view
  1236.   return true;
  1237. }
  1238.  
  1239. bool
  1240. TDrawView::VnRevert(bool /*clear*/)
  1241. {
  1242.   Invalidate();  // force full repaint
  1243.   InvalidatePart(invView);
  1244.   return true;
  1245. }
  1246.  
  1247. bool
  1248. TDrawView::VnAppend(uint index)
  1249. {
  1250.   TLine* line = DrawDoc->GetLine(index);
  1251.   line->UpdateBound();
  1252.   line->Invalidate(*this);
  1253.   InvalidatePart(invView);
  1254.   return true;
  1255. }
  1256.  
  1257. bool
  1258. TDrawView::VnModify(uint /*index*/)
  1259. {
  1260.   Invalidate();  // force full repaint
  1261.   InvalidatePart(invView);
  1262.   return true;
  1263. }
  1264.  
  1265. bool
  1266. TDrawView::VnDelete(uint /*index*/)
  1267. {
  1268.   Invalidate();  // force full repaint
  1269.   InvalidatePart(invView);
  1270.   return true;
  1271. }
  1272.  
  1273. DEFINE_RESPONSE_TABLE1(TDrawListView, TListBox)
  1274.   EV_COMMAND(CM_PENSIZE, CmPenSize),
  1275.   EV_COMMAND(CM_PENCOLOR, CmPenColor),
  1276.   EV_COMMAND(CM_EDITCLEAR, CmClear),
  1277.   EV_COMMAND(CM_EDITUNDO, CmUndo),
  1278.   EV_COMMAND(CM_EDITDELETE, CmDelete),
  1279.   EV_VN_ISWINDOW,
  1280.   EV_VN_COMMIT,
  1281.   EV_VN_REVERT,
  1282.   EV_VN_DRAWAPPEND,
  1283.   EV_VN_DRAWDELETE,
  1284.   EV_VN_DRAWMODIFY,
  1285. END_RESPONSE_TABLE;
  1286.  
  1287. TDrawListView::TDrawListView(TDrawDocument& doc,TWindow *parent)
  1288.        : TView(doc), TListBox(parent, GetNextViewId(), 0,0,0,0), DrawDoc(&doc)
  1289. {
  1290.   Attr.Style &= ~(WS_BORDER | LBS_SORT);
  1291.   Attr.Style |= LBS_NOINTEGRALHEIGHT;
  1292.   Attr.AccelTable = IDA_DRAWLISTVIEW;
  1293.   SetViewMenu(new TMenuDescr(IDM_DRAWLISTVIEW));
  1294. }
  1295.  
  1296. bool
  1297. TDrawListView::CanClose()
  1298. {
  1299.   TView* curView = Doc->GetViewList();
  1300.   while (curView) {
  1301.     if (curView != this)
  1302.       return true;
  1303.  
  1304.     curView = curView->GetNextView();
  1305.   }
  1306.  
  1307.   return Doc->CanClose();
  1308. }
  1309.  
  1310. bool
  1311. TDrawListView::Create()
  1312. {
  1313.   TListBox::Create();
  1314.   LoadData();
  1315.   return true;
  1316. }
  1317.  
  1318. void
  1319. TDrawListView::LoadData()
  1320. {
  1321.   ClearList();
  1322.   int i = 0;
  1323.   const TLine* line;
  1324.   while ((line = DrawDoc->GetLine(i)) != 0)
  1325.     FormatData(line, i++);
  1326.  
  1327.   SetSelIndex(0);
  1328. }
  1329.  
  1330. void
  1331. TDrawListView::FormatData(const TLine* line, int unsigned index)
  1332. {
  1333.   char buf[80];
  1334.   TColor color(line->QueryColor());
  1335.   wsprintf(buf, "Color = R%d G%d B%d, Size = %d, Points = %d",
  1336.            color.Red(), color.Green(), color.Blue(),
  1337.            line->QueryPenSize(), line->GetItemsInContainer());
  1338.   DeleteString(index);
  1339.   InsertString(buf, index);
  1340.   SetSelIndex(index);
  1341. }
  1342.  
  1343. void
  1344. TDrawListView::CmPenSize()
  1345. {
  1346.   int index = GetSelIndex();
  1347.   const TLine* line = DrawDoc->GetLine(index);
  1348.   if (line) {
  1349.     TLine* newline = new TLine(*line);
  1350.     if (GetPenSize(this, *newline))
  1351.       DrawDoc->ModifyLine(*newline, index);
  1352.     delete newline;
  1353.   }
  1354. }
  1355.  
  1356. void
  1357. TDrawListView::CmPenColor()
  1358. {
  1359.   int index = GetSelIndex();
  1360.   const TLine* line = DrawDoc->GetLine(index);
  1361.   if (line) {
  1362.     TLine* newline = new TLine(*line);
  1363.     if (GetPenColor(this, *newline))
  1364.       DrawDoc->ModifyLine(*newline, index);
  1365.     delete newline;
  1366.   }
  1367. }
  1368.  
  1369. void
  1370. TDrawListView::CmClear()
  1371. {
  1372.   DrawDoc->Clear();
  1373. }
  1374.  
  1375. void
  1376. TDrawListView::CmUndo()
  1377. {
  1378.   DrawDoc->Undo();
  1379. }
  1380.  
  1381. void
  1382. TDrawListView::CmDelete()
  1383. {
  1384.   DrawDoc->DeleteLine(GetSelIndex());
  1385. }
  1386.  
  1387. bool
  1388. TDrawListView::VnCommit(bool /*force*/)
  1389. {
  1390.   return true;
  1391. }
  1392.  
  1393. bool
  1394. TDrawListView::VnRevert(bool /*clear*/)
  1395. {
  1396.   LoadData();
  1397.   return true;
  1398. }
  1399.  
  1400. bool
  1401. TDrawListView::VnAppend(uint index)
  1402. {
  1403.   const TLine* line = DrawDoc->GetLine(index);
  1404.   FormatData(line, index);
  1405.   SetSelIndex(index);
  1406.   return true;
  1407. }
  1408.  
  1409. bool
  1410. TDrawListView::VnDelete(uint index)
  1411. {
  1412.   DeleteString(index);
  1413.   HandleMessage(WM_KEYDOWN,VK_DOWN); // force selection
  1414.   return true;
  1415. }
  1416.  
  1417. bool
  1418. TDrawListView::VnModify(uint index)
  1419. {
  1420.   const TLine* line = DrawDoc->GetLine(index);
  1421.   FormatData(line, index);
  1422.   return true;
  1423. }
  1424.  
  1425. static char* PropNames[] = {
  1426.   "Line Count",      // LineCount
  1427.   "Description",       // Description
  1428. };
  1429.  
  1430. static int PropFlags[] = {
  1431.   pfGetBinary|pfGetText, // LineCount
  1432.   pfGetText,             // Description
  1433. };
  1434.  
  1435. const char*
  1436. TDrawDocument::PropertyName(int index)
  1437. {
  1438.   if (index <= PrevProperty)
  1439.     return TStorageDocument::PropertyName(index);  // OC server change
  1440.   else if (index < NextProperty)
  1441.     return PropNames[index-PrevProperty-1];
  1442.   else
  1443.     return 0;
  1444. }
  1445.  
  1446. int
  1447. TDrawDocument::PropertyFlags(int index)
  1448. {
  1449.   if (index <= PrevProperty)
  1450.     return TStorageDocument::PropertyFlags(index); // OC server change
  1451.   else if (index < NextProperty)
  1452.     return PropFlags[index-PrevProperty-1];
  1453.   else
  1454.     return 0;
  1455. }
  1456.  
  1457. int
  1458. TDrawDocument::FindProperty(const char far* name)
  1459. {
  1460.   for (int i=0; i < NextProperty-PrevProperty-1; i++)
  1461.     if (strcmp(PropNames[i], name) == 0)
  1462.       return i+PrevProperty+1;
  1463.   return 0;
  1464. }
  1465.  
  1466. int
  1467. TDrawDocument::GetProperty(int prop, void far* dest, int textlen)
  1468. {
  1469.   switch(prop) {
  1470.     case LineCount: {
  1471.       int count = Lines->GetItemsInContainer();
  1472.       if (!textlen) {
  1473.         *(int far*)dest = count;
  1474.         return sizeof(int);
  1475.       }
  1476.       return wsprintf((char far*)dest, "%d", count);
  1477.     }
  1478.     case Description:
  1479.       char* temp = new char[textlen]; // need local copy for medium model
  1480.       int len = FileInfo.copy(temp, textlen);
  1481.       strcpy((char far*)dest, temp);
  1482.       return len;
  1483.   }
  1484.   return TStorageDocument::GetProperty(prop, dest, textlen); // OC server change
  1485. }
  1486.