home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / C / BC_502 / STEP15.PAK / STEP15DV.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  20.9 KB  |  910 lines

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