home *** CD-ROM | disk | FTP | other *** search
/ C Programming Starter Kit 2.0 / SamsPublishing-CProgrammingStarterKit-v2.0-Win31.iso / bc45 / step15.pak / STEP15DV.CPP < prev    next >
C/C++ Source or Header  |  1997-07-23  |  21KB  |  909 lines

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