home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / quot210s.zip / src / qdlg.c < prev    next >
C/C++ Source or Header  |  1998-12-03  |  22KB  |  676 lines

  1. /*
  2.  * qdlg.c
  3.  *
  4.  * Routines for quote menu options and dialogue boxes.
  5.  *
  6.  *      Created: 16th July, 1997 (split from quoter.c)
  7.  * Version 2.00: 21st December, 1997
  8.  * Version 2.10: 3rd November, 1998
  9.  *
  10.  * (C) 1997-1998 Nicholas Paul Sheppard
  11.  *
  12.  * This file is distributed under the GNU General Public License. See the
  13.  * file copying.txt for details.
  14.  */
  15.  
  16. #define INCL_DOSPROCESS
  17. #define INCL_WIN
  18. #include <os2.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include "quoter.h"
  22. #include "quotes.h"
  23. #include "threads.h"
  24. #include "types.h"
  25. #include "html.h"
  26. #include "general.h"
  27. #include "pmutil.h"
  28.  
  29. #define QDLG_MAX_QUOTE    60
  30.  
  31. MRESULT EXPENTRY EditQuoteBox(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2)
  32. /*
  33.  * Window procedure for the edit quote box. If mp2 is Q_ADD when the dialogue is
  34.  * initialised, add the quote to the database. If mp2 is Q_EDIT, edit a quote
  35.  * already existing in the database.
  36.  */
  37. {
  38.     static char    szTempFileName[L_tmpnam];
  39.     static char    szOrigCode[20];
  40.     static int    iMode;
  41.     static HAPP    happEditor = NULLHANDLE;
  42.     char         szString[100], szMessage[200], szTitle[20];
  43.     int        k, m, n;
  44.     FILE        *f;
  45.     BOOL        bNewCode;
  46.     SEARCHINFO    si;
  47.  
  48.     switch (message) {
  49.         case WM_INITDLG:
  50.             happEditor = NULLHANDLE;
  51.             tmpnam(szTempFileName);
  52.             WinSendDlgItemMsg(hwnd, IDC_EDITQ_CODE, EM_SETTEXTLIMIT, MPFROMSHORT(QUOTE_MAX_CODE), 0);
  53.             WinSendDlgItemMsg(hwnd, IDC_EDITQ_SOURCE, EM_SETTEXTLIMIT, MPFROMSHORT(QUOTE_MAX_SOURCE), 0);
  54.             WinSendDlgItemMsg(hwnd, IDC_EDITQ_ACODE, EM_SETTEXTLIMIT, MPFROMSHORT(AUTHOR_MAX_CODE), 0);
  55.             WinSendDlgItemMsg(hwnd, IDC_EDITQ_KEYWORDS, EM_SETTEXTLIMIT, MPFROMSHORT(QUOTE_MAX_KEYWORD * QUOTE_NUM_KEYWORD), 0);
  56.             iMode = (int)LONGFROMMP(mp2);
  57.             if (iMode == Q_EDIT) {
  58.                 WinLoadString(hab, 0, IDS_TITLE_EDITQ, sizeof(szTitle), szTitle);
  59.                 strcpy(szOrigCode, ps.szQuoteCode);
  60.                 WinSetDlgItemText(hwnd, IDC_EDITQ_CODE, ps.szQuoteCode);
  61.                 WinSetDlgItemText(hwnd, IDC_EDITQ_SOURCE, ps.pqi->szSource);
  62.                 WinSetDlgItemText(hwnd, IDC_EDITQ_ACODE, ps.pqi->szAuthorCode);
  63.                 szString[0] = '\0';
  64.                 k = 0;
  65.                 while ((ps.pqi->aszKeyword[k][0] != '\0') && (k < 5)) {
  66.                     strcat(szString, ps.pqi->aszKeyword[k]);
  67.                     strcat(szString, " ");
  68.                     k++;
  69.                 }
  70.                 WinSetDlgItemText(hwnd, IDC_EDITQ_KEYWORDS, szString);
  71.                 if ((f = fopen(szTempFileName, "w")) == NULL) {
  72.                     WinLoadString(hab, 0, IDS_OPENFAILED, sizeof(szString), szString);
  73.                     sprintf(szMessage, szString, szTempFileName);
  74.                     WinLoadString(hab, 0, IDS_ERROR, sizeof(szTitle), szTitle);
  75.                     WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  76.                     WinDismissDlg(hwnd, TRUE);
  77.                 } else {
  78.                     if (ps.pszText != NULL)
  79.                         fputs(ps.pszText, f);
  80.                     fclose(f);
  81.                 }
  82.             } else {
  83.                 WinLoadString(hab, 0, IDS_TITLE_ADDQ, sizeof(szTitle), szTitle);
  84.                 if ((ps.pqi = (QUOTEINFO *)malloc(sizeof(QUOTEINFO))) == NULL) {
  85.                     WinLoadString(hab, 0, IDS_NOMEM, sizeof(szMessage), szMessage);
  86.                     WinLoadString(hab, 0, IDS_ERROR, sizeof(szTitle), szTitle);
  87.                     WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  88.                     WinDismissDlg(hwnd, TRUE);
  89.                 }
  90.             }
  91.             WinSetWindowText(hwnd, szTitle);
  92.             WinEnableControl(hwnd, IDC_EDITQ_ABROWSE, ps.adb.dbfInfo != NULL);
  93.             return (FALSE);
  94.  
  95.         case WM_APPTERMINATENOTIFY:
  96.             happEditor = NULLHANDLE;
  97.             WinEnableControl(hwnd, IDC_EDITQ_TEXT, TRUE);
  98.             return (FALSE);
  99.  
  100.         case WM_COMMAND:
  101.             switch (SHORT1FROMMP(mp1)) {
  102.                 case IDC_EDITQ_ABROWSE:
  103.                     ps.szAuthorCode[0] = '\0';
  104.                     si.iType = Q_FULL;
  105.                     si.pszString = NULL;
  106.                     WinDlgBox(HWND_DESKTOP, hwnd, ChooseAuthorBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  107.                     if (ps.szAuthorCode[0] != '\0')
  108.                         WinSetDlgItemText(hwnd, IDC_EDITQ_ACODE, ps.szAuthorCode);
  109.                     return (FALSE);
  110.  
  111.                 case IDC_EDITQ_TEXT:
  112.                     strreplace(prf.szEditorParams, "%", szTempFileName, szMessage);
  113.                     if ((happEditor = SpawnPM(hwnd, prf.szEditor, szMessage)) != NULLHANDLE)
  114.                         WinEnableControl(hwnd, IDC_EDITQ_TEXT, FALSE);
  115.                     return (FALSE);
  116.  
  117.                 case IDC_EDITQ_OKAY:
  118.                     WinQueryDlgItemText(hwnd, IDC_EDITQ_CODE, sizeof(ps.szQuoteCode), ps.szQuoteCode);
  119.  
  120.                     /* make sure the quote code is non-trivial */
  121.                     if (ps.szQuoteCode[0] == '\0') {
  122.                         WinLoadString(hab, 0, IDS_NOCODE, sizeof(szMessage), szMessage);
  123.                         WinLoadString(hab, 0, IDS_RETRY, sizeof(szTitle), szTitle);
  124.                         WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  125.                         return (FALSE);
  126.                     }
  127.  
  128.                     /* see if code already exists in the database */
  129.                     bNewCode = iMode == Q_ADD;
  130.                     bNewCode = bNewCode || ((iMode == Q_EDIT) && (strcmp(ps.szQuoteCode, szOrigCode) != 0));
  131.                     if (bNewCode) {
  132.                         if (QuoteExists(&(ps.qdb), ps.szQuoteCode)) {
  133.                             WinLoadString(hab, 0, IDS_REPLACECODE, sizeof(szString), szString);
  134.                             sprintf(szMessage, szString, ps.szQuoteCode);
  135.                             WinLoadString(hab, 0, IDS_CONFIRM, sizeof(szTitle), szTitle);
  136.                             if (WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_YESNO | MB_QUERY) != MBID_YES)
  137.                                        return (FALSE);
  138.                         }
  139.                     }
  140.  
  141.  
  142.                     /* read information from the dialogue */
  143.                     WinQueryDlgItemText(hwnd, IDC_EDITQ_SOURCE, sizeof(ps.pqi->szSource), ps.pqi->szSource);
  144.                     WinQueryDlgItemText(hwnd, IDC_EDITQ_ACODE, sizeof(ps.pqi->szAuthorCode), ps.pqi->szAuthorCode);
  145.                     WinQueryDlgItemText(hwnd, IDC_EDITQ_KEYWORDS, sizeof(szString), szString);
  146.                     k = 0;
  147.                     n = 0;
  148.                     while ((sscanf(szString + n, "%s%n", ps.pqi->aszKeyword[k], &m) == 1) && (k < QUOTE_NUM_KEYWORD)) {
  149.                         if (strlen(ps.pqi->aszKeyword[k]) == 0)
  150.                             break;
  151.                         n += m;
  152.                         k++;
  153.                     }
  154.                     for (; k < QUOTE_NUM_KEYWORD; k++)
  155.                         ps.pqi->aszKeyword[k][0] = '\0';
  156.                     if ((f = fopen(szTempFileName, "r")) != NULL) {
  157.                         ps.pszText = strfromf(f);
  158.                         fclose(f);
  159.                         DosDelete(szTempFileName);
  160.                     } else {
  161.                         WinLoadString(hab, 0, IDS_NOTEXT, sizeof(szMessage), szMessage);
  162.                         WinLoadString(hab, 0, IDS_RETRY, sizeof(szTitle), szTitle);
  163.                         WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  164.                         return (FALSE);
  165.                     }
  166.                     DosDelete(szTempFileName);
  167.                     if (happEditor != NULLHANDLE)
  168.                         WinTerminateApp(happEditor);
  169.  
  170.                     /* commit to database */
  171.                     if (bNewCode && (iMode == Q_EDIT))
  172.                         QuoteDeleteQuote(&(ps.qdb), szOrigCode);
  173.                     QuoteAddQuote(&(ps.qdb), ps.szQuoteCode, ps.pqi, ps.pszText);
  174.                     WinDismissDlg(hwnd, TRUE);
  175.                     return (FALSE);
  176.  
  177.                 case IDC_EDITQ_CANCEL:
  178.                     if (iMode == Q_ADD)
  179.                         QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  180.                     if (happEditor != NULLHANDLE)
  181.                         WinTerminateApp(happEditor);
  182.                     DosDelete(szTempFileName);
  183.                     WinDismissDlg(hwnd, TRUE);
  184.                     return (FALSE);
  185.             }
  186.  
  187.         default:
  188.             return (WinDefDlgProc(hwnd, message, mp1, mp2));
  189.     }
  190.  
  191.     return (FALSE);
  192. }
  193.  
  194.  
  195. MRESULT EXPENTRY ChooseQuoteBox(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2)
  196. /*
  197.  * Window procedure for the choose quote box. This allows the user to select a
  198.  * quote from a list of codes. The codes to display are determined by the
  199.  * SEARCHINFO structure pointed to by mp2 passed with the WM_INITDLG. Depending
  200.  * on the iType field:
  201.  *
  202.  * Q_FULL    - all quotes
  203.  * Q_KEY    - quotes with the keyword in the pszString field
  204.  * Q_TEXT    - quotes containing the text in the pszString field
  205.  * Q_NAME    - quotes from the author with the code in the pszString field
  206.  */
  207. {
  208.     static THREADINFO    ti;
  209.     static HWND        hwndList, hwndCounter;
  210.     static int        iCount;
  211.     static char        szSearch[QUOTE_MAX_SEARCH];
  212.     static TID        tidSearch;
  213.     char            szMessage[200], szTitle[20];
  214.     int            iIndex;
  215.     SEARCHINFO        *psi;
  216.     char            *pszText;
  217.  
  218.     switch (message) {
  219.         case WM_INITDLG:
  220.             WinLoadString(hab, 0, IDS_TITLE_QCODE, sizeof(szMessage), szMessage);
  221.             WinSetWindowText(hwnd, szMessage);
  222.             hwndList = WinWindowFromID(hwnd, IDC_CODE_CODE);
  223.             hwndCounter = WinWindowFromID(hwnd, IDC_CODE_COUNT);
  224.             WinSendMsg(hwndList, LM_DELETEALL, 0, 0);
  225.             WinEnableControl(hwnd, IDC_CODE_OKAY, FALSE);
  226.             WinEnableControl(hwnd, IDC_CODE_CANCEL, TRUE);
  227.             psi = (SEARCHINFO *)PVOIDFROMMP(mp2);
  228.             ti.hwndCaller = hwnd;
  229.             if (psi->pszString != NULL)
  230.                 ti.pData = (void *)strcpy(szSearch, psi->pszString);
  231.             else
  232.                 ti.pData = NULL;
  233.             ti.pps = &ps;
  234.             tidSearch = -1;
  235.             switch (psi->iType) {
  236.                 case Q_FULL:
  237.                     tidSearch = _beginthread((THREADPROC)ThreadFindAllQuotes, NULL, THREADSTACK, (void *)&ti);
  238.                     break;
  239.  
  240.                 case Q_KEY:
  241.                     tidSearch = _beginthread((THREADPROC)ThreadFindKeywords, NULL, THREADSTACK, (void *)&ti);
  242.                     break;
  243.  
  244.                 case Q_TEXT:
  245.                     tidSearch = _beginthread((THREADPROC)ThreadFindQuoteText, NULL, THREADSTACK, (void *)&ti);
  246.                     break;
  247.  
  248.                 case Q_NAME:
  249.                     tidSearch = _beginthread((THREADPROC)ThreadFindAuthorsQuotes, NULL, THREADSTACK, (void *)&ti);
  250.                     break;
  251.             }
  252.  
  253.             if (tidSearch == -1) {
  254.                 WinLoadString(hab, 0, IDS_THREADFAILED, sizeof(szMessage), szMessage);
  255.                 WinLoadString(hab, 0, IDS_ERROR, sizeof(szTitle), szTitle);
  256.                 WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  257.                 WinDismissDlg(hwnd, TRUE);
  258.             }
  259.             iCount = 0;
  260.             return (FALSE);
  261.  
  262.         case QM_FOUND:
  263.             QuoteGetQuote(&(ps.qdb), (char *)PVOIDFROMMP(mp1), NULL, &pszText);
  264.             strabbrev(HTMLMakePlain(pszText), szMessage, QDLG_MAX_QUOTE);
  265.             strcat(szMessage, " (");
  266.             strcat(szMessage, (char *)PVOIDFROMMP(mp1));
  267.             strcat(szMessage, ")");
  268.             WinInsertLboxItem(hwndList, LIT_SORTASCENDING, szMessage);
  269.             sprintf(szMessage, "%d", ++iCount);
  270.             WinSetWindowText(hwndCounter, szMessage);
  271.             return (FALSE);
  272.  
  273.         case QM_DONE:
  274.             if (WinQueryLboxCount(hwndList) == 0) {
  275.                 WinLoadString(hab, 0, IDS_NOQUOTES, sizeof(szMessage), szMessage);
  276.                 WinLoadString(hab, 0, IDS_RETRY, sizeof(szTitle), szTitle);
  277.                 WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_INFORMATION);
  278.                 WinDismissDlg(hwnd, TRUE);
  279.                 return (FALSE);
  280.             }
  281.             tidSearch = -1;
  282.             WinEnableControl(hwnd, IDC_CODE_OKAY, TRUE);
  283.             WinEnableControl(hwnd, IDC_CODE_CANCEL, TRUE);
  284.             return (FALSE);
  285.  
  286.         case QM_ERROR:
  287.             WinLoadString(hab, 0, IDS_BADRX, sizeof(szMessage), szMessage);
  288.             WinLoadString(hab, 0, IDS_RETRY, sizeof(szTitle), szTitle);
  289.             WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  290.             WinDismissDlg(hwnd, TRUE);
  291.             return (FALSE);
  292.  
  293.         case WM_COMMAND:
  294.             switch (SHORT1FROMMP(mp1)) {
  295.                 case IDC_CODE_OKAY:
  296.                     iIndex = (int)WinQueryLboxSelectedItem(hwndList);
  297.                     if (iIndex != LIT_NONE) {
  298.                         WinQueryLboxItemText(hwndList, iIndex, szMessage, sizeof(szMessage));
  299.                         strencl(szMessage, ps.szQuoteCode, '(', ')');
  300.                     } else {
  301.                         ps.szQuoteCode[0] = '\0';
  302.                         ps.pszText = NULL;
  303.                     }
  304.                     WinDismissDlg(hwnd, TRUE);
  305.                     return (FALSE);
  306.  
  307.                 case IDC_CODE_CANCEL:
  308.                     if (tidSearch != -1) {
  309.                         /* cancel searching */
  310.                         DosKillThread(tidSearch);
  311.                         WinPostMsg(hwnd, QM_DONE, NULL, NULL);
  312.                     } else {
  313.                         /* cancel selection */
  314.                         ps.szQuoteCode[0] = '\0';
  315.                         ps.pszText = NULL;
  316.                         WinDismissDlg(hwnd, TRUE);
  317.                     }
  318.                     return (FALSE);
  319.             }
  320.  
  321.         default:
  322.             return (WinDefDlgProc(hwnd, message, mp1, mp2));
  323.     }
  324.  
  325.     return (FALSE);
  326. }
  327.  
  328.  
  329. MRESULT EXPENTRY ImportQuotesBox(HWND hwnd, ULONG message, MPARAM mp1, MPARAM mp2)
  330. /*
  331.  * Window procedure for the import quote database box.
  332.  */
  333. {
  334.     static THREADINFO    ti;
  335.     static IMPORTINFO    ii;
  336.     static QUOTEDB        qdb;
  337.     FILEDLG            fd;
  338.     char            szString[CCHMAXPATH], szMessage[CCHMAXPATH], szTitle[20];
  339.  
  340.     switch (message) {
  341.         case WM_INITDLG:
  342.             WinCheckButton(hwnd, IDC_IMPORT_REPLACE_ASK, TRUE);
  343.             WinSendDlgItemMsg(hwnd, IDC_IMPORT_SOURCE, EM_SETTEXTLIMIT, MPFROMSHORT(CCHMAXPATH), 0);
  344.             return (FALSE);
  345.  
  346.         case QM_DONE:
  347.             WinDismissDlg(hwnd, TRUE);
  348.             return (FALSE);
  349.  
  350.         case WM_COMMAND:
  351.             switch (SHORT1FROMMP(mp1)) {
  352.                 case IDC_IMPORT_BROWSE:
  353.                     memset(&fd, 0, sizeof(FILEDLG));
  354.                     fd.cbSize = sizeof(FILEDLG);
  355.                     fd.fl = FDS_OPEN_DIALOG | FDS_CENTER;
  356.                     dircat(strcpy(fd.szFullFile, prf.szDataPath), szQuoteExt);
  357.                     WinLoadString(hab, 0, IDS_TITLE_BROWSE, sizeof(szTitle), szTitle);
  358.                     fd.pszTitle = szTitle;
  359.                     WinFileDlg(HWND_DESKTOP, hwnd, &fd);
  360.                     if (fd.lReturn == DID_OK)
  361.                         WinSetDlgItemText(hwnd, IDC_IMPORT_SOURCE, dirnoext(fd.szFullFile));
  362.                     return (FALSE);
  363.  
  364.                 case IDC_IMPORT_OKAY:
  365.                     WinQueryDlgItemText(hwnd, IDC_IMPORT_SOURCE, sizeof(fd.szFullFile), fd.szFullFile);
  366.                     if (QuoteOpenDB(fd.szFullFile, &qdb, S_IREAD)) {
  367.                         ti.hwndCaller = hwnd;
  368.                         ii.pdb = &qdb;
  369.                         ii.bAsk = WinQueryButtonCheckstate(hwnd, IDC_IMPORT_REPLACE_ASK);
  370.                         ii.bReplace = WinQueryButtonCheckstate(hwnd, IDC_IMPORT_REPLACE_ALL);
  371.                         ti.pData = ⅈ
  372.                         ti.pps = &ps;
  373.                         if (_beginthread((THREADPROC)ThreadImportQuotes, NULL, THREADSTACK, (void *)&ti) == -1) {
  374.                             WinLoadString(hab, 0, IDS_THREADFAILED, sizeof(szString), szString);
  375.                             WinLoadString(hab, 0, IDS_ERROR, sizeof(szTitle), szTitle);
  376.                             WinMessageBox(HWND_DESKTOP, hwnd, szString, szTitle, 0, MB_ERROR);
  377.                             WinDismissDlg(hwnd, TRUE);
  378.                         }
  379.                     } else {
  380.                         WinLoadString(hab, 0, IDS_OPENFAILED, sizeof(szString), szString);
  381.                         sprintf(szMessage, szString, fd.szFullFile);
  382.                         WinLoadString(hab, 0, IDS_ERROR, sizeof(szTitle), szTitle);
  383.                         WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  384.                     }
  385.                     return (FALSE);
  386.  
  387.                 case IDC_IMPORT_CANCEL:
  388.                     WinDismissDlg(hwnd, TRUE);
  389.                     return (FALSE);
  390.             }
  391.  
  392.         default:
  393.             return (WinDefDlgProc(hwnd, message, mp1, mp2));
  394.     }
  395.  
  396.     return (FALSE);
  397. }
  398.  
  399.  
  400. BOOL MenuOpenQuotes(HWND hwnd, char *pszDBName)
  401. /*
  402.  * Open a quote database.
  403.  *
  404.  * HWND hwnd        - the window handle we're running in
  405.  * char *pszDBName    - database name to open; NULL to ask the user.
  406.  *
  407.  * Returns:        - TRUE if sucessful
  408.  *              FALSE otherwise.
  409.  */
  410. {
  411.     FILEDLG        fd;
  412.     BOOL        bCont, bRet;
  413.     char        szString[200], szMessage[200], szTitle[20];
  414.     QDBINFO        qdbinfo;
  415.  
  416.     bRet = FALSE;
  417.     if (pszDBName == NULL) {
  418.         memset(&fd, 0, sizeof(FILEDLG));
  419.         fd.cbSize = sizeof(FILEDLG);
  420.         fd.fl = FDS_OPEN_DIALOG | FDS_CENTER;
  421.         dircat(strcpy(fd.szFullFile, prf.szDataPath), szQuoteExt);
  422.         WinLoadString(hab, 0, IDS_TITLE_OPEN, sizeof(szTitle), szTitle);
  423.         fd.pszTitle = szTitle;
  424.         WinFileDlg(HWND_DESKTOP, hwnd, &fd);
  425.     } else
  426.         strcpy(fd.szFullFile, pszDBName);
  427.     if ((pszDBName != NULL) || (fd.lReturn == DID_OK)) {
  428.         bCont = TRUE;
  429.         dirnoext(fd.szFullFile);
  430.         if (!QuoteDBStat(fd.szFullFile, &qdbinfo)) {
  431.             WinLoadString(hab, 0, IDS_MAKENEWDB, sizeof(szString), szString);
  432.             sprintf(szMessage, szString, fd.szFullFile);
  433.             WinLoadString(hab, 0, IDS_CONFIRM, sizeof(szTitle), szTitle);
  434.             bCont = WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_QUERY | MB_YESNO) == MBID_YES;
  435.             qdbinfo.flMode = S_IWRITE | S_IREAD;
  436.         }
  437.         if (bCont) {
  438.             if (QuoteOpenDB(fd.szFullFile, &(ps.qdb), ps.iQdbMode = qdbinfo.flMode)) {
  439.                 strcpy(prf.szQuoteDB1, fd.szFullFile);
  440.                 dirfname(strcpy(ps.szQuoteDB, fd.szFullFile));
  441.                 bRet = TRUE;
  442.             } else {
  443.                 WinLoadString(hab, 0, IDS_OPENFAILED, sizeof(szString), szString);
  444.                 sprintf(szMessage, szString, fd.szFullFile);
  445.                 WinLoadString(hab, 0, IDS_ERROR, sizeof(szTitle), szTitle);
  446.                 WinMessageBox(HWND_DESKTOP, hwnd, szMessage, szTitle, 0, MB_ERROR);
  447.             }
  448.         }
  449.     }
  450.  
  451.     return (bRet);
  452. }
  453.  
  454.  
  455. BOOL MenuAddQuote(HWND hwnd)
  456. /*
  457.  * Allow the user to add a quote. Returns TRUE if the quote was successfully added.
  458.  */
  459. {
  460.     BOOL         bRet;
  461.  
  462.     bRet = FALSE;
  463.     ps.szQuoteCode[0] = '\0';
  464.     ps.szAuthorCode[0] = '\0';
  465.     QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  466.     AuthorFreeAuthor(&(ps.pai), &(ps.pszDesc));
  467.     WinDlgBox(HWND_DESKTOP, hwnd, EditQuoteBox, NULLHANDLE, IDD_EDITQUOTE, MPFROMLONG(Q_ADD));
  468.     if (ps.pqi != NULL) {
  469.         if (ps.adb.dbfInfo != NULL) {
  470.             /* try to find the author in the current author database */
  471.             if (AuthorGetAuthor(&(ps.adb), ps.pqi->szAuthorCode, &(ps.pai), &(ps.pszDesc)))
  472.                 strcpy(ps.szAuthorCode, ps.pqi->szAuthorCode);
  473.         }
  474.         bRet = TRUE;
  475.     }
  476.  
  477.     return (bRet);
  478. }
  479.  
  480. BOOL MenuEditQuote(HWND hwnd, int bCurrent)
  481. /*
  482.  * Allow the user to edit a pre-existing quote. Returns TRUE if the quote was
  483.  * edited.
  484.  *
  485.  * int bCurrent    - edit the current quote (or provide a list)?
  486.  */
  487. {
  488.     BOOL        bRet;
  489.     SEARCHINFO    si;
  490.  
  491.     bRet = FALSE;
  492.     if (!bCurrent) {
  493.         si.iType = Q_FULL;
  494.         si.pszString = NULL;
  495.         WinDlgBox(HWND_DESKTOP, hwnd, ChooseQuoteBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  496.     }
  497.     if (ps.szQuoteCode[0] != '\0') {
  498.         QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  499.         AuthorFreeAuthor(&(ps.pai), &(ps.pszDesc));
  500.         QuoteGetQuote(&(ps.qdb), ps.szQuoteCode, &(ps.pqi), &(ps.pszText));
  501.         WinDlgBox(HWND_DESKTOP, hwnd, EditQuoteBox, NULLHANDLE, IDD_EDITQUOTE, MPFROMLONG(Q_EDIT));
  502.         ps.szAuthorCode[0] = '\0';
  503.         if (ps.adb.dbfInfo != NULL) {
  504.             /* try to find the author in the current author database */
  505.             if (AuthorGetAuthor(&(ps.adb), ps.pqi->szAuthorCode, &(ps.pai), &(ps.pszDesc)))
  506.                 strcpy(ps.szAuthorCode, ps.pqi->szAuthorCode);
  507.         }
  508.         bRet = TRUE;
  509.     }
  510.  
  511.     return (bRet);
  512. }
  513.  
  514.  
  515. void MenuDelQuote(HWND hwnd, int bCurrent)
  516. /*
  517.  * Allow the user to delete a quote.
  518.  *
  519.  * int bCurrent    - delete the current quote (or provide a list)?
  520.  */
  521. {
  522.     SEARCHINFO    si;
  523.  
  524.     ps.szAuthorCode[0] = '\0';
  525.     if (!bCurrent) {
  526.         si.iType = Q_FULL;
  527.         si.pszString = NULL;
  528.         WinDlgBox(HWND_DESKTOP, hwnd, ChooseQuoteBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  529.     }
  530.     if (ps.szQuoteCode[0] != '\0') {
  531.         QuoteDeleteQuote(&(ps.qdb), ps.szQuoteCode);
  532.         ps.szQuoteCode[0] = '\0';
  533.         QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  534.     }
  535. }
  536.  
  537.  
  538. BOOL MenuGetQuoteAll(HWND hwnd)
  539. /*
  540.  * Allow the user to select a quote from all quotes.
  541.  */
  542. {
  543.     BOOL        bRet;
  544.     SEARCHINFO    si;
  545.  
  546.     bRet = FALSE;
  547.     si.iType = Q_FULL;
  548.     si.pszString = NULL;
  549.     WinDlgBox(HWND_DESKTOP, hwnd, ChooseQuoteBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  550.     if (ps.szQuoteCode[0] != '\0') {
  551.         QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  552.         AuthorFreeAuthor(&(ps.pai), &(ps.pszDesc));
  553.         ps.szAuthorCode[0] = '\0';
  554.         QuoteGetQuote(&(ps.qdb), ps.szQuoteCode, &(ps.pqi), &(ps.pszText));
  555.         bRet = TRUE;
  556.         if (ps.adb.dbfInfo != NULL) {
  557.             /* try to find the author in the current author database */
  558.             if (AuthorGetAuthor(&(ps.adb), ps.pqi->szAuthorCode, &(ps.pai), &(ps.pszDesc)))
  559.                 strcpy(ps.szAuthorCode, ps.pqi->szAuthorCode);
  560.             else
  561.                 ps.szAuthorCode[0] = '\0';
  562.         } else
  563.             ps.szAuthorCode[0] = '\0';
  564.     }
  565.  
  566.     return (bRet);
  567. }
  568.  
  569.  
  570. BOOL MenuGetQuoteKeyword(HWND hwnd)
  571. /*
  572.  * Allow the user to search for quotes associated with a given keyword.
  573.  */
  574. {
  575.     BOOL        bRet;
  576.     SEARCHINFO    si;
  577.     GETTEXT        gt;
  578.     char        szString[QUOTE_MAX_SEARCH + 1], szTitle[100];
  579.  
  580.     bRet = FALSE;
  581.     szString[0] = '\0';
  582.     gt.iMaxLength = QUOTE_MAX_SEARCH;
  583.     gt.pszString = szString;
  584.     WinLoadString(hab, 0, IDS_TITLE_QS_KEY, sizeof(szTitle), szTitle);
  585.     gt.pszTitle = szTitle;
  586.     WinDlgBox(HWND_DESKTOP, hwnd, GetTextBox, NULLHANDLE, IDD_GETTEXT, MPFROMP(>));
  587.     if (szString[0] != '\0') {
  588.         si.iType = Q_KEY;
  589.         si.pszString = szString;
  590.         WinDlgBox(HWND_DESKTOP, hwnd, ChooseQuoteBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  591.         if (ps.szQuoteCode[0] != '\0') {
  592.             QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  593.             AuthorFreeAuthor(&(ps.pai), &(ps.pszDesc));
  594.             ps.szAuthorCode[0] = '\0';
  595.             QuoteGetQuote(&(ps.qdb), ps.szQuoteCode, &(ps.pqi), &(ps.pszText));
  596.             bRet = TRUE;
  597.             if (ps.adb.dbfInfo != NULL) {
  598.                 /* try to find the author in the current author database */
  599.                 if (AuthorGetAuthor(&(ps.adb), ps.pqi->szAuthorCode, &(ps.pai), &(ps.pszDesc)))
  600.                     strcpy(ps.szAuthorCode, ps.pqi->szAuthorCode);
  601.             }
  602.         }
  603.     }
  604.  
  605.     return (bRet);
  606. }
  607.  
  608.  
  609. BOOL MenuGetQuoteText(HWND hwnd)
  610. /*
  611.  * Allow the user to search for a quote containing some given text.
  612.  */
  613. {
  614.     BOOL        bRet;
  615.     SEARCHINFO    si;
  616.     GETTEXT        gt;
  617.     char        szString[QUOTE_MAX_SEARCH + 1], szTitle[100];
  618.  
  619.     bRet = FALSE;
  620.     szString[0] = '\0';
  621.     gt.iMaxLength = QUOTE_MAX_SEARCH;
  622.     gt.pszString = szString;
  623.     WinLoadString(hab, 0, IDS_TITLE_QS_TEXT, sizeof(szTitle), szTitle);
  624.     gt.pszTitle = szTitle;
  625.     WinDlgBox(HWND_DESKTOP, hwnd, GetTextBox, NULLHANDLE, IDD_GETTEXT, MPFROMP(>));
  626.     if (szString[0] != '\0') {
  627.         si.iType = Q_TEXT;
  628.         si.pszString = szString;
  629.         WinDlgBox(HWND_DESKTOP, hwnd, ChooseQuoteBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  630.         if (ps.szQuoteCode[0] != '\0') {
  631.             QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  632.             AuthorFreeAuthor(&(ps.pai), &(ps.pszDesc));
  633.             ps.szAuthorCode[0] = '\0';
  634.             QuoteGetQuote(&(ps.qdb), ps.szQuoteCode, &(ps.pqi), &(ps.pszText));
  635.             bRet = TRUE;
  636.             if (ps.adb.dbfInfo != NULL) {
  637.                 /* try to find the author in the current author database */
  638.                 if (AuthorGetAuthor(&(ps.adb), ps.pqi->szAuthorCode, &(ps.pai), &(ps.pszDesc)))
  639.                     strcpy(ps.szAuthorCode, ps.pqi->szAuthorCode);
  640.             }
  641.         }
  642.     }
  643.  
  644.     return (bRet);
  645. }
  646.  
  647.  
  648. BOOL MenuGetQuoteName(HWND hwnd)
  649. /*
  650.  * Allow the user to search for all quotes from a given author.
  651.  */
  652. {
  653.     BOOL        bRet;
  654.     SEARCHINFO    si;
  655.  
  656.     bRet = FALSE;
  657.     si.iType = Q_FULL;
  658.     si.pszString = NULL;
  659.     WinDlgBox(HWND_DESKTOP, hwnd, ChooseAuthorBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  660.     if (ps.szAuthorCode[0] != '\0') {
  661.         si.iType = Q_NAME;
  662.         si.pszString = ps.szAuthorCode;
  663.         WinDlgBox(HWND_DESKTOP, hwnd, ChooseQuoteBox, NULLHANDLE, IDD_CHOOSECODE, MPFROMP(&si));
  664.         if (ps.szQuoteCode[0] != '\0') {
  665.             QuoteFreeQuote(&(ps.pqi), &(ps.pszText));
  666.             QuoteGetQuote(&(ps.qdb), ps.szQuoteCode, &(ps.pqi), &(ps.pszText));
  667.             AuthorGetAuthor(&(ps.adb), ps.szAuthorCode, &(ps.pai), &(ps.pszDesc));
  668.             bRet = TRUE;
  669.         } else {
  670.             ps.szAuthorCode[0] = '\0';
  671.         }
  672.     }
  673.  
  674.     return (bRet);
  675. }
  676.