home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ocl150a.zip / OCL / Source / OBook.cpp < prev    next >
C/C++ Source or Header  |  1996-08-12  |  13KB  |  494 lines

  1.  
  2. // (c) Cubus 1995
  3. // All Rights Reserved
  4. // OBook.cpp
  5.  
  6. /*
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 2. Neither the name Cubus nor the name Team OCL may be used to
  13.  *    endorse or promote products derived from this software
  14.  *    without specific prior written permission.
  15.  * 3. See OCL.INF for a detailed copyright notice.
  16.  *
  17.  *              THIS SOFTWARE IS PROVIDED ``AS IS'' AND
  18.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  21.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27.  * SUCH DAMAGE.
  28.  */
  29.  
  30. // $Header: W:/Projects/OCL/Source/rcs/OBook.cpp 1.50 1996/08/11 23:49:08 B.STEIN Release $
  31.  
  32. #define __OCL_SOURCE__
  33.  
  34. #define OINCL_OSTRING
  35. #define OINCL_BASE
  36.  
  37. #include <ocl.hpp>
  38. #include <OMsgs.hpp>
  39. #include <OBook.hpp>
  40. #include <OMessage.hpp>
  41.  
  42. #if defined(__EMX__)
  43.   template class OList<OBookPage>;
  44. #endif
  45.  
  46.  
  47. // definitions
  48.  
  49. #define TAB_WIDTH_MARGIN      10
  50. #define TAB_HEIGHT_MARGIN     6
  51. #define DEFAULT_NB_TAB_HEIGHT 16
  52.  
  53.  
  54. OBook::OBook(const ULONG id, 
  55.              const HWND Parent, 
  56.              const ULONG frameStyle)
  57.    : OFrame(id, frameStyle, CS_SIZEREDRAW),
  58.      book(NULLHANDLE),
  59.      bStyle(0),
  60.      dimCX(0),
  61.      dimCY(0)
  62. {
  63.  parent = Parent;
  64.  owner  = Parent;
  65. }
  66.  
  67. OBook::OBook(const ULONG id,
  68.              const OFrame& Parent,
  69.              const ULONG frameStyle)
  70.    : OFrame(id, frameStyle, CS_SIZEREDRAW),
  71.      book(NULLHANDLE),
  72.      bStyle(0),
  73.      dimCX(0),
  74.      dimCY(0)
  75. {
  76.  parent = Parent.hwnd;
  77.  owner  = Parent.hwnd;
  78. }
  79.  
  80.  
  81. OBook::OBook(const ULONG id,
  82.              const pOFrame Parent,
  83.              const ULONG frameStyle)
  84.    : OFrame(id, frameStyle, CS_SIZEREDRAW),
  85.      book(NULLHANDLE),
  86.      bStyle(0),
  87.      dimCX(0),
  88.      dimCY(0)
  89. {
  90.  parent = Parent->hwnd;
  91.  owner  = Parent->hwnd;
  92. }
  93.  
  94.  
  95. OBook::~OBook() {}
  96.  
  97.  
  98. PSZ OBook::isOfType() const
  99.  return("OBook"); 
  100. }
  101.  
  102.  
  103.  
  104. OBook& OBook::createBook(PSZ Text,
  105.                          const ULONG cx,
  106.                          const ULONG cy,
  107.                          const ULONG bookStyle)
  108. {
  109.  dimCX         = cx;
  110.  dimCY         = cy;
  111.  bStyle        = bookStyle;
  112.  pOBookPage pP = Pages.getFirst();
  113.  
  114.  winText << (PSZ) Text;
  115.  
  116.  createFrame("OBook");
  117.  
  118.  if (!pP)
  119.    throw OPMException(OCL::error(148), 0); 
  120.  
  121.  cNbk();
  122.  
  123.  if (!(BOOL) WinSendMsg(book, BKM_TURNTOPAGE,
  124.              MPFROMLONG(pP->ulPageID), NULL))
  125.    throw OPMException(OCL::error(141), 0); 
  126.  
  127.  return(setFramePos());
  128. }
  129.  
  130.  
  131.  
  132. OBook& OBook::setFramePos()
  133. {
  134.  setSizePosFrame(HWND_TOP, sizepos, 0);
  135.  return(*this);
  136. }
  137.  
  138.  
  139. // Set Frame of the Book Window
  140.  
  141. OBook& OBook::setSizePosFrame(const HWND behind, SWP dimensions, const ULONG flag)
  142. {
  143.  POINTL aptl[2];
  144.  SWP    swpScreen;
  145.  
  146.  aptl[0].x = 0;
  147.  aptl[0].y = 0;
  148.  aptl[1].x = dimCX;
  149.  aptl[1].y = dimCY;
  150.  
  151.  swpScreen.cx=WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  152.  swpScreen.cy=WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  153.  
  154.  WinMapDlgPoints(HWND_DESKTOP, aptl, 2, TRUE);
  155.  WinSetWindowPos(frame, behind, (swpScreen.cx-(aptl[1].x))/2,
  156.                 (swpScreen.cy-(aptl[1].y))/2, aptl[1].x, aptl[1].y,
  157.                  SWP_SIZE | SWP_MOVE | SWP_RESTORE | SWP_ACTIVATE);
  158.  
  159.  return(*this);
  160. #ifdef __BCPLUSPLUS__
  161.   #pragma warn -par
  162. #endif
  163. }
  164. #ifdef __BCPLUSPLUS__
  165.   #pragma warn .par
  166. #endif
  167.  
  168.  
  169.  
  170.  
  171. // set dimensions of the tabs
  172.  
  173. OBook& OBook::setTabDimensions()
  174. {
  175.  FONTMETRICS  fm;
  176.  INT          iSize, iLongestMajText = 0, iLongestMinText = 0;
  177.  pOBookPage   pP = Pages.getFirst();
  178.  BOOL         Majors=FALSE, Minors=FALSE;
  179.  
  180.  hps = WinGetPS(book);
  181.  
  182.  memset(&fm, 0, sizeof(FONTMETRICS));
  183.  if(GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm))
  184.     fm.lMaxBaselineExt += (TAB_HEIGHT_MARGIN * 2);
  185.  else
  186.     fm.lMaxBaselineExt = DEFAULT_NB_TAB_HEIGHT + (TAB_HEIGHT_MARGIN * 2);
  187.  
  188.  while(pP)
  189.   {
  190.    iSize = gSS(pP->szTabText);
  191.    if(pP->usTabType == BKA_MAJOR)
  192.     {
  193.      Majors=TRUE;
  194.      if(iSize > iLongestMajText)
  195.        iLongestMajText = iSize;
  196.     }
  197.    else
  198.     {
  199.      Minors=TRUE;
  200.      if(iSize > iLongestMinText)
  201.        iLongestMinText = iSize;
  202.     }
  203.    pP = Pages.getNext();
  204.   }
  205.  
  206.  WinReleasePS(hps);
  207.  
  208.  if(iLongestMajText)
  209.    iLongestMajText += TAB_WIDTH_MARGIN;
  210.  
  211.  if(iLongestMinText)
  212.    iLongestMinText += TAB_WIDTH_MARGIN;
  213.  
  214.  if (Majors)
  215.    Majors = (BOOL) WinSendMsg(book, BKM_SETDIMENSIONS,
  216.                               MPFROM2SHORT(iLongestMajText, (SHORT)fm.lMaxBaselineExt),
  217.                               MPFROMSHORT(BKA_MAJORTAB));
  218.  else Majors=TRUE;
  219.  
  220.  if (Minors)
  221.    Minors =(BOOL) WinSendMsg(book, BKM_SETDIMENSIONS,
  222.                              MPFROM2SHORT(iLongestMinText, (SHORT)fm.lMaxBaselineExt),
  223.                              MPFROMSHORT(BKA_MINORTAB));
  224.  else
  225.    Minors=TRUE;
  226.  
  227.  if (!(Majors && Minors))
  228.    throw OPMException(OCL::error(140), 0);
  229.  
  230.  return(*this);
  231. }
  232.  
  233.  
  234.  
  235. // add pages to the book
  236.  
  237. OBook& OBook::addPages(ppageList pagesList)
  238. {
  239.  pOBookPage pP = pagesList->getFirst();
  240.  
  241.  while(pP)
  242.    {
  243.     sP(pP);
  244.     Pages.addLast(pP);
  245.     pP = pagesList->getNext();
  246.    }
  247.  
  248.  setTabDimensions();
  249.  
  250.  pP = Pages.getFirst();
  251.  
  252.  if (pP)
  253.    WinSendMsg(book, BKM_TURNTOPAGE, MPFROMLONG(pP->ulPageID), NULL);
  254.  
  255.  return(*this);
  256. }
  257.  
  258.  
  259.  
  260.  
  261.  
  262. BOOL OBook::OCommand(ULONG msg, MPARAM mp1, MPARAM mp2)
  263. {
  264.  switch(msg)
  265.     {
  266.      case WM_SIZE:
  267.        WinSetWindowPos(book, 0, 0, 0,
  268.                        SHORT1FROMMP(mp2),
  269.                        SHORT2FROMMP(mp2), SWP_SIZE | SWP_SHOW );
  270.        break;
  271.  
  272.      case WM_CONTROL:
  273.        if(SHORT1FROMMP(mp1) == FID_CLIENT)
  274.         {
  275.          switch(SHORT2FROMMP(mp1))
  276.           {
  277.            case BKN_PAGESELECTED:
  278.              sNBP((PPAGESELECTNOTIFY) mp2);
  279.              return(TRUE);
  280.           }
  281.         }
  282.        break;
  283.  
  284.      case WM_DESTROY:
  285.      case WM_CLOSE: {
  286.        pOBookPage temp = Pages.getFirst();
  287.  
  288.        hideFrame();
  289.        while(temp) {
  290.          if ((temp->hwnd))
  291.            WinSendMsg(temp->hwnd, msg, NULL, NULL);
  292.          temp = Pages.getNext(); }
  293.        break; }
  294.  
  295.      default:
  296.        return(OFrame::OCommand(msg, mp1, mp2));
  297.     }
  298.  return(TRUE);
  299. }
  300.  
  301.  
  302. /*********************************************************************************************************/
  303.  
  304. // internals
  305.  
  306.  
  307. // Create the Book
  308.  
  309. OBook& OBook::cNbk()
  310. {
  311.  pOBookPage pP = NULL;
  312.  
  313.  if ((book = WinCreateWindow(client, WC_NOTEBOOK, NULL,
  314.                              bStyle, 0, 0, 0, 0,
  315.                              frame, HWND_BOTTOM,
  316.                              FID_CLIENT, NULL, NULL)) == NULLHANDLE)
  317.    throw OPMException(OCL::error(142), 0);
  318.  
  319.  if(!WinSendMsg(book, BKM_SETNOTEBOOKCOLORS,
  320.                 MPFROMLONG(SYSCLR_FIELDBACKGROUND),
  321.                 MPFROMSHORT(BKA_BACKGROUNDPAGECOLORINDEX)))
  322.    throw OPMException(OCL::error(143), 0);
  323.  
  324.  setTabDimensions();
  325.  
  326.  pP = Pages.getFirst();
  327.  
  328.  while(pP)
  329.   {
  330.    sP(pP);
  331.    pP = Pages.getNext();
  332.   }
  333.  
  334.  return(*this);
  335. }
  336.  
  337.  
  338. // Load a dialog and associate to a page
  339.  
  340. HWND OBook::Assoc(pOBookPage pnbp, PPAGESELECTNOTIFY ppsn)
  341. {
  342.  HWND hwndDlg = WinLoadDlg(book, book, OWinDefDlgProc,
  343.                            NULLHANDLE, pnbp->idDlg, pnbp);
  344.  
  345.  if(hwndDlg)
  346.     {
  347.      if(!WinSendMsg(ppsn->hwndBook, BKM_SETPAGEWINDOWHWND,
  348.                     MPFROMP(ppsn->ulPageIdNew), MPFROMLONG(hwndDlg)))
  349.        {
  350.         WinDestroyWindow(hwndDlg);
  351.         hwndDlg = NULLHANDLE;
  352.        }
  353.     }
  354.  else
  355.     NBError("Error loading page dialog.");
  356.  
  357.  return(hwndDlg);
  358. }
  359.  
  360.  
  361. // get a string size
  362.  
  363. ULONG OBook::gSS(PCSZ szString)
  364. {
  365.  POINTL aptl[TXTBOX_COUNT];
  366.  
  367.  if(!GpiQueryTextBox(hps, strlen((PCH)szString), (PCH) szString, TXTBOX_COUNT, aptl))
  368.    return 0;
  369.  else
  370.    return aptl[TXTBOX_CONCAT].x;
  371. }
  372.  
  373.  
  374. // setup a book page
  375.  
  376. OBook& OBook::sNBP(PPAGESELECTNOTIFY ppsn)
  377. {
  378.  HWND       hwndDlg = NULLHANDLE; 
  379.  pOBookPage pnbp    = (pOBookPage) WinSendMsg(ppsn->hwndBook, BKM_QUERYPAGEDATA,
  380.                                               MPFROMLONG(ppsn->ulPageIdNew), NULL);
  381.  
  382.  if (!pnbp)
  383.    return(*this);
  384.  
  385.  if (pnbp == (pOBookPage) BOOKERR_INVALID_PARAMETERS)
  386.    throw OPMException(OCL::error(149), 0);
  387.  
  388.  // If this is a BKA_MAJOR page and it is what this app terms a 'parent'
  389.  // page, that means when the user selects this page we actually want to go
  390.  // to its first MINOR page. So in effect the MAJOR page is just a dummy page
  391.  // that has a tab that acts as a placeholder for its MINOR pages. If the
  392.  // user is using the left arrow to scroll thru the pages and they hit this
  393.  // dummy MAJOR page, that means they have already been to its MINOR pages in
  394.  // reverse order. They would now expect to see the page before the dummy
  395.  // MAJOR page, so we skip the dummy page. Otherwise the user is going the
  396.  // other way and wants to see the first MINOR page associated with this
  397.  // 'parent' page so we skip the dummy page and show its first MINOR page.
  398.  
  399.  if(pnbp->fParent)
  400.   {
  401.    ULONG ulPageFwd, ulPageNew;
  402.  
  403.    ulPageFwd = (ULONG) WinSendMsg(ppsn->hwndBook, BKM_QUERYPAGEID,
  404.                                   MPFROMLONG(ppsn->ulPageIdNew),
  405.                                   MPFROM2SHORT(BKA_NEXT, BKA_MINOR));
  406.  
  407.    // If this is true, the user is going in reverse order
  408.  
  409.    if((ulPageFwd == ppsn->ulPageIdCur) && (pnbp != Pages.getFirst()))
  410.       ulPageNew = (ULONG) WinSendMsg(ppsn->hwndBook, BKM_QUERYPAGEID,
  411.                                      MPFROMLONG(ppsn->ulPageIdNew),
  412.                                      MPFROM2SHORT(BKA_PREV, BKA_MAJOR));
  413.    else
  414.       ulPageNew = ulPageFwd;
  415.  
  416.    if(ulPageNew == (ULONG) BOOKERR_INVALID_PARAMETERS)
  417.       NBError("Invalid page specified");
  418.    else if(ulPageNew)
  419.       if(!WinSendMsg(ppsn->hwndBook, BKM_TURNTOPAGE,
  420.                      MPFROMLONG(ulPageNew), NULL))
  421.         NBError(OCL::error(10));
  422.   }
  423.  else
  424.   {
  425.    hwndDlg = (HWND) WinSendMsg(ppsn->hwndBook, BKM_QUERYPAGEWINDOWHWND,
  426.                                MPFROMLONG(ppsn->ulPageIdNew), NULL);
  427.    if(hwndDlg == (HWND) BOOKERR_INVALID_PARAMETERS )
  428.     {
  429.      hwndDlg = NULLHANDLE;
  430.      NBError(OCL::error(11));
  431.     }
  432.    else if(!hwndDlg)
  433.             // It is time to load this dialog because the user has flipped pages
  434.             // to a page that hasn't yet had the dialog associated with it.
  435.      hwndDlg = Assoc(pnbp, ppsn);
  436.   }
  437.  
  438.     // Set focus to the first control in the dialog. This is not automatically
  439.     // done by the notebook.
  440.  
  441.  if(!pnbp->fParent && hwndDlg)
  442.    WinSetFocus(HWND_DESKTOP, WinWindowFromID(hwndDlg, pnbp->idFocus));
  443.  
  444.  return(*this);
  445. }
  446.  
  447.  
  448. // set up a particular page
  449.  
  450. OBook& OBook::sP(pOBookPage pP)
  451. {
  452.  ULONG ulPageId;
  453.  
  454.  if ((ulPageId = (ULONG) WinSendMsg(book, BKM_INSERTPAGE, NULL,
  455.                          MPFROM2SHORT(pP->usTabType | BKA_STATUSTEXTON | BKA_AUTOPAGESIZE,
  456.                          BKA_LAST))) == 0)
  457.    throw OPMException(OCL::error(144), 0);
  458.  
  459.  pP->ulPageID = ulPageId;
  460.  
  461.  if (!(BOOL) WinSendMsg(book, BKM_SETPAGEDATA,
  462.              MPFROMLONG(ulPageId),
  463.              MPFROMP(pP)))
  464.    throw OPMException(OCL::error(145), 0);
  465.  
  466.  if (!(BOOL) WinSendMsg(book, BKM_SETSTATUSLINETEXT,
  467.              MPFROMP(ulPageId),
  468.              MPFROMP(pP->szStatusLineText)))
  469.    throw OPMException(OCL::error(146), 0);
  470.  
  471.  if (!(BOOL) WinSendMsg(book, BKM_SETTABTEXT,
  472.              MPFROMP(ulPageId),
  473.              MPFROMP(pP->szTabText)))
  474.    throw OPMException(OCL::error(147), 0);
  475.  
  476.  return(*this);
  477. }
  478.  
  479.  
  480. OBook& OBook::NBError(PCH Msg)
  481. {
  482.  WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, (PCH) Msg,
  483.                OCL::error(12), 0,
  484.                MB_OK | MB_APPLMODAL | MB_MOVEABLE | MB_CUAWARNING);
  485.  return(*this);
  486. }
  487.  
  488.  
  489. /********************************************************************************************************/
  490.  
  491.  
  492. // end of source
  493.