home *** CD-ROM | disk | FTP | other *** search
- /*
- * File: wxhelp.cc
- * Purpose: wxWindows help system
- *
- * wxWindows 1.40
- * Copyright (c) 1993 Artificial Intelligence Applications Institute,
- * The University of Edinburgh
- *
- * Author: Julian Smart
- * Date: 18-4-93
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose is hereby granted without fee, provided
- * that the above copyright notice, author statement and this permission
- * notice appear in all copies of this software and related documentation.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
- * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
- * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
- * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
- * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
- * THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
- #include <windows.h> // Included only for using MS C/C++ precompiled headers
- #include <ctype.h>
- #include <stdlib.h>
- #include "wx.h"
- #include "wx_help.h"
- #include "wx_hash.h"
- #include "hytext.h"
- #include "wxhelp.h"
- #include "wxhlpblk.h"
-
- float helpVersion = 1.3;
-
- #define HELP_SERVER_ID -1
-
- #ifdef wx_x
- #define DEFAULT_EDITOR "emacs"
- #endif
- #ifdef wx_msw
- #define DEFAULT_EDITOR "notepad"
- #endif
-
- #ifdef wx_x
- short icon_bits[] = {
- #include "hlp_icn"
- };
- #endif
-
- MyFrame *MainFrame = NULL;
- SearchBox *TheSearchBox = NULL;
- wxHyperTextMapping *mapping = NULL;
- wxFont *swiss_font_12 = NULL;
- char *hyFilename = NULL;
- Bool hyEditMode = FALSE;
-
- int SearchWindowX = 10;
- int SearchWindowY = 10;
-
- wxList hyHistory;
- HypertextItem *hySelection = NULL;
- wxNode *hyHistoryPointer = NULL;
-
- // Communication
- HelpConnection *TheHelpConnection = NULL;
- HelpServer *TheHelpServer = NULL;
-
- #ifdef wx_msw // Only one instance in Windows 3 so make it a server ALWAYS
- int TheHelpServerId = 4000;
- #endif
- #ifdef wx_x
- int TheHelpServerId = -1;
- #endif
-
- // wxHelp also has help!!
- wxHelpInstance *HelpInstance = NULL;
- wxPathList HelpPathList;
-
- #ifdef wx_xview
- #define HELP_PANEL_HEIGHT 30
- #endif
- #ifdef wx_motif
- #define HELP_PANEL_HEIGHT 40
- #endif
- #ifdef wx_msw
- #define HELP_PANEL_HEIGHT 40
- #endif
-
- // This statement initialises the whole application
- MyApp myApp;
-
- void hyHelpPrevious(wxButton& but, wxEvent& ev)
- {
- MainFrame->window->DisplayPreviousSection();
- MainFrame->window->DisplaySection();
- long block_id = MainFrame->window->FindBlockForSection(MainFrame->window->current_section);
- MainFrame->window->StoreHypertextItem(block_id);
- }
-
- void hyHelpNext(wxButton& but, wxEvent& ev)
- {
- MainFrame->window->DisplayNextSection();
- MainFrame->window->DisplaySection();
- long block_id = MainFrame->window->FindBlockForSection(MainFrame->window->current_section);
- MainFrame->window->StoreHypertextItem(block_id);
- }
-
- void hyHelpBack(wxButton& but, wxEvent& ev)
- {
- MainFrame->window->HistoryBack();
- }
-
- void hyHelpHistory(wxButton& but, wxEvent& ev)
- {
- }
-
- void hyHelpContents(wxButton& but, wxEvent& ev)
- {
- MainFrame->window->DisplayFileAtTop();
- long block_id = MainFrame->window->FindBlockForSection(MainFrame->window->current_section);
- MainFrame->window->StoreHypertextItem(block_id);
- }
-
- void hyHelpSearch(wxButton& but, wxEvent& ev)
- {
- HelpSearch();
- }
-
- // The `main program' equivalent, creating the windows and returning the
- // main frame
- wxFrame *MyApp::OnInit(void)
- {
- int i = 1;
- while (i < argc)
- {
- if (strcmp(argv[i], "-f") == 0)
- {
- i ++;
- if (i == argc)
- hyErrorMsg("-f must take a filename!");
- else
- {
- hyFilename = copystring(argv[i]);
- i ++;
- }
- }
- else if (strcmp(argv[i], "-edit") == 0)
- {
- i ++;
- hyEditMode = TRUE;
- }
- else if (strcmp(argv[i], "-server") == 0)
- {
- i ++;
- TheHelpServerId = atoi(argv[i]);
- i ++;
- }
- else i++;
- }
-
- HelpPathList.AddEnvList("WXHELPFILES");
- HelpPathList.AddEnvList("PATH");
-
- // Create the main frame window
- MainFrame = new MyFrame(NULL, "wxHelp", 0, 0, 500, 400);
-
- if (hyEditMode)
- MainFrame->CreateStatusLine();
-
- // Give it an icon
- #ifdef wx_msw
- wxIcon *icon = new wxIcon("hlp_icn");
- #endif
- #ifdef wx_x
- wxIcon *icon = new wxIcon(icon_bits, 64, 64);
- #endif
-
- MainFrame->SetIcon(icon);
-
- // Make a menubar
- wxMenu *file_menu = new wxMenu;
-
- file_menu->Append(HELP_OPEN, "&Open File");
- if (hyEditMode)
- file_menu->Append(HELP_SAVE, "&Save File");
-
- file_menu->AppendSeparator();
- file_menu->Append(HELP_EXIT, "&Exit");
-
- wxMenu *edit_menu = NULL;
- wxMenu *block_menu = NULL;
- if (hyEditMode)
- {
- block_menu = new wxMenu;
- edit_menu = new wxMenu;
- edit_menu->Append(HELP_RUN_EDITOR, "Run &Editor");
- edit_menu->Append(HELP_CLEAR_SELECTION, "&Clear selection");
- edit_menu->Append(HELP_CLEAR_BLOCK, "Clear &block");
- edit_menu->AppendSeparator();
- edit_menu->Append(HELP_SET_TITLE, "&Set title");
-
- block_menu->Append(HELP_MARK_LARGE_HEADING, "Mark &large heading");
- block_menu->Append(HELP_MARK_SMALL_HEADING, "Mark &small heading");
- block_menu->Append(HELP_MARK_LARGE_VISIBLE_SECTION, "Mark large &visible section");
- block_menu->Append(HELP_MARK_SMALL_VISIBLE_SECTION, "Mark small visible §ion");
- block_menu->Append(HELP_MARK_INVISIBLE_SECTION, "Mark &invisible section");
- block_menu->AppendSeparator();
-
- block_menu->Append(HELP_MARK_RED, "Mark &red");
- block_menu->Append(HELP_MARK_BLUE, "Mark &blue");
- block_menu->Append(HELP_MARK_GREEN, "Mark &green");
- block_menu->AppendSeparator();
- block_menu->Append(HELP_MARK_BOLD, "Mark &bold");
- block_menu->Append(HELP_MARK_ITALIC, "Mark &italics");
- block_menu->Append(HELP_MARK_RED_ITALIC, "Mark red i&talics");
- block_menu->Append(HELP_MARK_SMALL_TEXT, "Mark small te&xt");
- }
-
- wxMenu *help_menu = new wxMenu;
- help_menu->Append(HELP_HELP_CONTENTS, "&Help on wxHelp");
- help_menu->AppendSeparator();
- help_menu->Append(HELP_ABOUT, "&About wxHelp");
-
- wxMenuBar *menu_bar = new wxMenuBar;
-
- menu_bar->Append(file_menu, "&File");
-
- if (hyEditMode)
- {
- menu_bar->Append(edit_menu, "&Edit");
- menu_bar->Append(block_menu, "&Blocks");
- }
-
- menu_bar->Append(help_menu, "&Help");
-
- // Associate the menu bar with the frame
- MainFrame->SetMenuBar(menu_bar);
-
- // Make a button bar, a la Windows Help
- MainFrame->panel = new wxPanel(MainFrame, 0, 0, 400, HELP_PANEL_HEIGHT);
-
- (void)new wxButton(MainFrame->panel, (wxFunction)hyHelpContents, "Contents");
- (void)new wxButton(MainFrame->panel, (wxFunction)hyHelpSearch, "Search");
- // (void)new wxButton(MainFrame->panel, (wxFunction)hyHelpHistory, "History");
- (void)new wxButton(MainFrame->panel, (wxFunction)hyHelpBack, "Back");
- (void)new wxButton(MainFrame->panel, (wxFunction)hyHelpPrevious, "<<");
- (void)new wxButton(MainFrame->panel, (wxFunction)hyHelpNext, ">>");
-
- // Make a hypertext window
- MainFrame->window = new HelpWindow(MainFrame, 0, 0, 400, 400, 0);
- MainFrame->window->SetEditMode(hyEditMode);
- MainFrame->window->SetIndexWriting(TRUE);
-
- mapping = new wxHyperTextMapping;
- // This recognized by library as the default text
- mapping->AddMapping(500, 12, wxSWISS, wxNORMAL, wxNORMAL, "BLACK", "Default");
-
- mapping->AddMapping(hyBLOCK_NORMAL, -1, -1, -1, -1, NULL, "Normal text");
- mapping->AddMapping(hyBLOCK_RED, -1, -1, -1, -1, "RED", "Red");
- mapping->AddMapping(hyBLOCK_BLUE, -1, -1, -1, -1, "BLUE", "Blue");
- mapping->AddMapping(hyBLOCK_GREEN, -1, -1, -1, -1, "FOREST GREEN", "Green");
- mapping->AddMapping(hyBLOCK_LARGE_HEADING, 20, wxSWISS, wxNORMAL, wxBOLD, "BLACK", "Large heading");
- mapping->AddMapping(hyBLOCK_SMALL_HEADING, 14, wxSWISS, wxNORMAL, wxBOLD, "BLACK", "Small heading");
- mapping->AddMapping(hyBLOCK_ITALIC, -1, -1, wxITALIC, -1, NULL, "Italic");
- mapping->AddMapping(hyBLOCK_BOLD, -1, -1, -1, wxBOLD, NULL, "Bold");
- mapping->AddMapping(hyBLOCK_ITALIC, -1, -1, wxITALIC, -1, NULL, "Italic");
- mapping->AddMapping(hyBLOCK_RED_ITALIC, -1, -1, wxITALIC, -1, "RED", "Red italic");
- mapping->AddMapping(hyBLOCK_INVISIBLE_SECTION, -1, -1, -1, wxITALIC, "RED", "Invisible Section Marker", wxHYPER_SECTION, FALSE);
- mapping->AddMapping(hyBLOCK_LARGE_VISIBLE_SECTION, 20, -1, -1, wxBOLD, "BLACK", "Large visible section", wxHYPER_SECTION, TRUE);
- mapping->AddMapping(hyBLOCK_SMALL_VISIBLE_SECTION, 14, -1, -1, wxBOLD, "BLACK", "Small visible section", wxHYPER_SECTION, TRUE);
- mapping->AddMapping(hyBLOCK_SMALL_TEXT, 10, -1, -1, -1, NULL, "Small text");
- mapping->AddMapping(hyBLOCK_TELETYPE, -1, wxMODERN, -1, -1, NULL, "Teletype");
-
- MainFrame->window->SetMapping(mapping);
-
- if (hyFilename)
- {
- char *s = HelpPathList.FindValidPath(hyFilename);
- if (!s)
- {
- MainFrame->SetTitle("wxHelp (no title)");
- char buf[500];
- sprintf(buf, "Cannot find file %s.\nTrying editing the WXHELPFILES environment variable.", hyFilename);
- #ifdef wx_x
- cerr << buf << "\n";
- #endif
- #ifdef wx_msw
- wxMessageBox(buf);
- #endif
- }
- else
- {
- MainFrame->window->LoadFile(s);
- if (MainFrame->window->GetTitle())
- MainFrame->SetTitle(MainFrame->window->GetTitle());
- else
- MainFrame->SetTitle("wxHelp (no title)");
-
- MainFrame->window->DisplayFileAtTop();
- MainFrame->window->StoreHypertextItem(-1);
- MainFrame->window->DisplaySection();
- }
- }
-
- if (TheHelpServerId > 0)
- {
- wxIPCInitialize();
-
- TheHelpServer = new HelpServer;
- char buf[50];
- sprintf(buf, "%d", TheHelpServerId);
- TheHelpServer->Create(buf);
- }
-
- HelpInstance = new wxHelpInstance;
- HelpInstance->Initialize("help.xlp", HELP_SERVER_ID);
-
- MainFrame->Centre();
- MainFrame->Show(TRUE);
-
- return MainFrame;
- }
-
- // Define my frame constructor
- MyFrame::MyFrame(wxFrame *frame, char *title, int x, int y, int w, int h):
- wxFrame(frame, title, x, y, w, h)
- {
- window = NULL;
- panel = NULL;
- }
-
- // Intercept menu commands
- void MyFrame::OnMenuCommand(int id)
- {
- switch (id)
- {
- case HELP_SET_TITLE:
- {
- char *def = "";
- if (window->GetTitle())
- def = window->GetTitle();
- char *title = wxGetTextFromUser("Enter help file title", "Text input",
- def);
- if (title)
- {
- window->SetTitle(title);
- SetTitle(title);
- window->modified = TRUE;
- }
- break;
- }
- case HELP_OPEN:
- {
- // First save any edits in the current text window
- if (window->Modified())
- {
- int choice = wxMessageBox("Save edits (Yes), Discard edits (No)?",
- "Message", wxYES_NO, this);
- if (choice == wxYES)
- {
- char *file = wxFileSelector("Select a help file to save to", PathOnly(hyFilename), FileNameFromPath(hyFilename), "xlp", "*.xlp");
- if (file)
- {
- hyFilename = copystring(file);
- window->SaveFile(hyFilename);
- }
- }
- }
- char *s = wxFileSelector("Load hypertext file", NULL, NULL, NULL, "*.xlp");
- if (s)
- {
- hyFilename = copystring(s);
- window->LoadFile(HelpPathList.FindValidPath(s));
- if (window->GetTitle())
- SetTitle(window->GetTitle());
- else
- SetTitle("wxHelp (no title)");
- window->DisplayFileAtTop();
- window->StoreHypertextItem(-1);
- window->DisplaySection();
- }
- break;
- }
- case HELP_SAVE:
- {
- char *s = wxFileSelector("Save hypertext file", PathOnly(hyFilename), FileNameFromPath(hyFilename), "txt", "*.xlp");
- if (s)
- window->SaveFile(s);
- break;
- }
-
- case HELP_RUN_EDITOR:
- {
- // First save any edits in the current text window
- if (window->Modified())
- {
- int choice = wxMessageBox("Save edits (Yes), Discard edits (No)?",
- "Message", wxYES_NO, this);
- if (choice == wxYES)
- {
- char *file = wxFileSelector("Select a help file to save to", PathOnly(hyFilename), FileNameFromPath(hyFilename), "xlp", "*.xlp");
- if (file)
- {
- hyFilename = copystring(file);
- window->SaveFile(hyFilename);
- }
- }
- }
-
- char *editor = getenv("EDITOR");
- if (!editor)
- editor = DEFAULT_EDITOR;
-
- char buf[300];
- if (!hyFilename)
- hyFilename = wxFileSelector("Select a help file to edit", NULL, NULL, "xlp", "*.xlp");
- if (hyFilename)
- {
- window->SaveSection();
- strcpy(buf, editor);
- strcat(buf, " ");
- strcat(buf, hyFilename);
- wxExecute(buf);
-
- // In Windows, it returns immediately so we can't automatically
- // redisplay the file
- #ifdef wx_x
- window->LoadFile(HelpPathList.FindValidPath(hyFilename));
- if (window->GetTitle())
- SetTitle(window->GetTitle());
- else
- SetTitle("wxHelp (no title)");
- window->RestoreSection();
- window->DisplaySection();
- #endif
- }
- break;
- }
-
- case HELP_EXIT:
- {
- OnClose();
- delete this;
- break;
- }
-
- case HELP_MARK_RED:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_RED);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
- case HELP_MARK_BLUE:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_BLUE);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
-
- case HELP_MARK_ITALIC:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_ITALIC);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
-
- case HELP_MARK_RED_ITALIC:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_RED_ITALIC);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
-
- case HELP_MARK_BOLD:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_BOLD);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
- case HELP_MARK_SMALL_TEXT:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_SMALL_TEXT);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
-
- case HELP_MARK_LARGE_HEADING:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_LARGE_HEADING);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
- case HELP_MARK_SMALL_HEADING:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_SMALL_HEADING);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
- case HELP_MARK_INVISIBLE_SECTION:
- {
- window->SaveSection();
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_INVISIBLE_SECTION);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
- case HELP_MARK_LARGE_VISIBLE_SECTION:
- {
- window->SaveSection();
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_LARGE_VISIBLE_SECTION);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
- case HELP_MARK_SMALL_VISIBLE_SECTION:
- {
- window->SaveSection();
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SetBlockType(id, hyBLOCK_SMALL_VISIBLE_SECTION);
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
- case HELP_CLEAR_SELECTION:
- {
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SelectBlock(id, FALSE);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
-
- case HELP_CLEAR_BLOCK:
- {
- window->SaveSection();
- long id = window->GetFirstSelection();
- while (id != -1)
- {
- window->SelectBlock(id, FALSE);
-
- window->ClearBlock(id);
- id = window->GetNextSelection();
- }
- window->SaveSection();
- window->Compile();
- window->RestoreSection();
- window->DisplaySection();
- break;
- }
-
- /*
- case HELP_TEST:
- {
- wxDC *dc = MainFrame->window->GetDC();
- dc->SetFont(swiss_font_12);
-
- char **choices = new char*[wxTheColourDatabase->Number()];
- wxNode *node = wxTheColourDatabase->First();
- int i = 0;
- while (node)
- {
- choices[i] = node->key.string;
- node = node->Next();
- i ++;
- }
- char *col = wxGetSingleChoice("Choose a colour", "Choice",
- wxTheColourDatabase->Number(), choices);
- if (col)
- {
- dc->SetTextBackground(wxWHITE);
- dc->SetTextForeground(wxTheColourDatabase->FindColour(col));
- dc->DrawText("Hello, some test text", 30, 30);
- }
- break;
- }
- */
- case HELP_HELP_CONTENTS:
- {
- HelpInstance->LoadFile();
- HelpInstance->DisplayContents();
- break;
- }
-
- case HELP_ABOUT:
- {
- char buf[400];
- sprintf(buf, "wxHelp version %.2f\n", helpVersion);
- strcat(buf, "by Julian Smart, AIAI (c) April 1993\n");
- strcat(buf, "J.Smart@ed.ac.uk");
- wxMessageBox(buf, "About wxHelp");
- break;
- }
- }
- }
-
- // Define the behaviour for the frame closing
- // - must delete all frames except for the main one.
- Bool MyFrame::OnClose(void)
- {
- // First save any edits in the current text window
- if (window->Modified())
- {
- int choice = wxMessageBox("Save edits (Yes), Discard edits (No)?",
- "Message", wxYES_NO | wxCANCEL, this);
- if (choice == wxYES)
- {
- char *file = wxFileSelector("Select a help file to save to", PathOnly(hyFilename), FileNameFromPath(hyFilename), "xlp", "*.xlp");
- if (file)
- {
- hyFilename = copystring(file);
- window->SaveFile(hyFilename);
- } else return FALSE;
- } else if (choice == wxCANCEL) return FALSE;
- }
- if (TheSearchBox)
- delete TheSearchBox;
-
- if (TheHelpConnection)
- TheHelpConnection->Disconnect();
-
- HelpInstance->Quit();
-
- return TRUE;
- }
-
- void MyFrame::OnSize(int w, int h)
- {
- if (panel && window)
- {
- int width, height;
- GetClientSize(&width, &height);
- panel->SetSize(0, 0, width, HELP_PANEL_HEIGHT);
- window->SetSize(0, HELP_PANEL_HEIGHT, width, height - HELP_PANEL_HEIGHT);
- }
- }
-
- HelpWindow::HelpWindow(wxFrame *frame, int x, int y, int w, int h, int style):
- wxHyperTextWindow(frame, x, y, w, h, style)
- {
- }
-
- HelpWindow::~HelpWindow(void)
- {
- }
-
- void HelpWindow::OnSelectBlock(long block_id, Bool select)
- {
- if (select)
- {
- if (hySelection)
- delete hySelection;
- hySelection = new HypertextItem(hyFilename, block_id);
- }
- else
- {
- if (hySelection && (hySelection->block_id == block_id))
- {
- delete hySelection;
- hySelection = NULL;
- }
- }
- }
-
- void HelpWindow::ClearBlock(long block_id)
- {
- wxHyperTextWindow::ClearBlock(block_id);
- HypertextItem *item = (HypertextItem *)GetLinkTable()->Get(block_id);
- if (item)
- {
- long other_block = item->block_id;
- if (other_block != 0)
- {
- (void)GetLinkTable()->Delete(block_id);
- delete item;
- }
- }
- }
-
- // Select/deselect block if SHIFT held down (default behaviour),
- // or traverse a link otherwise.
- void HelpWindow::OnLeftClick(float x, float y, int char_pos, int line, long block_id, int keys)
- {
- if (keys & KEY_SHIFT)
- {
- wxHyperTextWindow::OnLeftClick(x, y, char_pos, line, block_id, keys);
- return;
- }
- else if ((keys & KEY_CTRL) && block_id > -1 && hyEditMode)
- {
- // Display some useful info
- int type = GetBlockType(block_id);
-
- wxNode *node = mapping->Find(type);
- wxHTMappingStructure *struc = (wxHTMappingStructure *)node->Data();
-
- char *linked = " (not linked)";
- if (GetLinkTable()->Get(block_id))
- linked = " (linked)";
- char buf[300];
-
- sprintf(buf, "%s %s", struc->name, linked);
- MainFrame->SetStatusText(buf);
- }
- else if (block_id > -1)
- {
- HypertextItem *item = (HypertextItem *)GetLinkTable()->Get(block_id);
- if (!item)
- return;
-
- long other_block = item->block_id;
- if (other_block > 0)
- {
- if (item->filename)
- {
- char *s = HelpPathList.FindValidPath(item->filename);
- if (s)
- {
- if (!hyFilename || (strcmp(hyFilename, s) != 0))
- {
- if (hyFilename)
- delete hyFilename;
- hyFilename = copystring(s);
- LoadFile(hyFilename);
- if (GetTitle())
- MainFrame->SetTitle(GetTitle());
- else
- MainFrame->SetTitle("wxHelp (no title)");
- }
- }
- else
- {
- char buf[500];
- sprintf(buf, "Could not find file %s.\nTry editing the WXHELPFILES environment variable", item->filename);
- (void)wxMessageBox(buf, "wxHelp Error");
- return;
- }
- }
- DisplayFileAt(other_block);
- StoreHypertextItem(other_block);
- DisplaySection();
- }
- }
- }
-
- // Popup a menu for deleting block, linking with other items,
- // etc.
- void HelpWindow::OnRightClick(float x, float y, int char_pos, int line, long block_id, int keys)
- {
- int block_type = GetBlockType(block_id);
- if (block_type == BLOCK_TYPE_SELECTION)
- return;
-
- int x1, y1, x2, y2;
- MainFrame->GetPosition(&x2, &y2);
-
- ViewStart(&x1, &y1);
- int mouse_x = (int)(GetDC()->LogicalToDeviceX(x - x1) + x2);
- int mouse_y = (int)(GetDC()->LogicalToDeviceY(y - y1) + y2);
-
- char **choices = new char *[10];
- int no_choices = 0;
-
- choices[no_choices] = "Link block to selection";
- no_choices ++;
- choices[no_choices] = "Unlink block";
- no_choices ++;
- choices[no_choices] = "Clear block";
- no_choices ++;
-
- char *choice = wxGetSingleChoice("Pick a block action", "Menu",
- no_choices, choices, MainFrame, mouse_x, mouse_y);
- if (!choice)
- {
- delete choices;
- return;
- }
-
- if (strcmp(choice, "Link block to selection") == 0)
- {
- if (hySelection)
- {
- if (GetLinkTable()->Get(block_id))
- MainFrame->SetStatusText("This block already linked!");
- else if (hySelection->block_id > -1)
- {
- GetLinkTable()->Put(block_id,
- new HypertextItem(hySelection->filename, hySelection->block_id));
- modified = TRUE;
- SelectBlock(hySelection->block_id, FALSE);
- Compile();
- DisplayFile();
- }
- }
- }
- else if (strcmp(choice, "Unlink block") == 0)
- {
- HypertextItem *item = (HypertextItem *)GetLinkTable()->Get(block_id);
- if (!item)
- MainFrame->SetStatusText("Nothing to unlink.");
- else
- {
- (void)GetLinkTable()->Delete(block_id);
- delete item;
- modified = TRUE;
- MainFrame->SetStatusText("Unlinked block.");
- }
- }
- else if (strcmp(choice, "Clear block") == 0)
- {
- SaveSection();
- HypertextItem *item = (HypertextItem *)GetLinkTable()->Get(block_id);
- if (item)
- {
- (void)GetLinkTable()->Delete(block_id);
- delete item;
- }
-
- SelectBlock(block_id, FALSE);
- ClearBlock(block_id);
- modified = TRUE;
- Compile();
- RestoreSection();
- }
-
- delete choices;
- }
-
- void HelpWindow::DisplaySection(void)
- {
- if (hyEditMode)
- {
- char buf[300];
- int sect = GetCurrentSectionNumber();
- sprintf(buf, "Section %d", sect);
- MainFrame->SetStatusText(buf);
- }
- }
-
- void HelpWindow::StoreHypertextItem(long block_id)
- {
- wxNode *last = hyHistory.Last();
- // Don't store if the same as last time!
- if (last)
- {
- HypertextItem *ep = (HypertextItem *)last->Data();
- if (ep->filename && hyFilename &&
- ((strcmp(ep->filename, hyFilename) == 0) && ep->block_id == block_id))
- return;
- }
- hyHistory.Append(new HypertextItem(hyFilename, block_id));
- hyHistoryPointer = hyHistory.Last();
- }
-
- void HelpWindow::HistoryBack(void)
- {
- if (!hyHistoryPointer)
- hyHistoryPointer = hyHistory.First();
-
- hyHistoryPointer = hyHistoryPointer->Previous();
- if (!hyHistoryPointer)
- hyHistoryPointer = hyHistory.First();
-
- HypertextItem *ep = (HypertextItem *)hyHistoryPointer->Data();
- char *s = ep->filename;
- if (s && strcmp(s, hyFilename) != 0)
- {
- LoadFile(HelpPathList.FindValidPath(s));
- if (GetTitle())
- MainFrame->SetTitle(GetTitle());
- else
- MainFrame->SetTitle("wxHelp (no title)");
- hyFilename = copystring(s);
- }
- DisplayFileAt(ep->block_id);
- }
-
- void HelpWindow::DisplayHistory(void)
- {
- }
-
-
- void hyErrorMsg(char *msg)
- {
- #ifdef wx_x
- if (myApp.Initialized())
- (void)wxMessageBox(msg, "Error", wxOK);
- else
- cerr << "Error: " << msg << "\n";
- #endif
- #ifdef wx_msw
- (void)wxMessageBox(msg, "Error", wxOK);
- #endif
- }
-
- /* Searching
- */
-
- class StringData: public wxObject
- {
- public:
- char *s;
- wxObject *data;
- StringData(char *s, wxObject *data);
- };
-
- StringData::StringData(char *the_s, wxObject *the_data)
- {
- s = the_s;
- data = the_data;
- }
-
- int wxCompareStringData(const void *arg1, const void *arg2)
- {
- StringData **one = (StringData **)arg1;
- StringData **two = (StringData **)arg2;
-
- return strcmp((*one)->s, (*two)->s);
- }
-
- void SortStringDataList(wxList *list)
- {
- int n = list->Number();
- StringData **array = new StringData *[list->Number()];
- int i = 0;
- wxNode *node = list->First();
- while (node)
- {
- array[i] = (StringData *)node->Data();
- i ++;
- node = node->Next();
- }
- qsort(array, n, sizeof(StringData *), wxCompareStringData);
- list->Clear();
-
- for (i = 0; i < n; i++)
- list->Append((StringData *)(array[i]));
-
- delete array;
- }
-
-
- void hyDoSearch(wxButton& button, wxEvent& event)
- {
- SearchBox *box = (SearchBox *)button.GetParent();
- box->DoSearch();
- }
-
- void hySearchQuit(wxButton& button, wxEvent& event)
- {
- SearchBox *box = (SearchBox *)button.GetParent();
- // box->GetPosition(&SearchWindowX, &SearchWindowY);
- TheSearchBox = NULL;
- delete box;
- }
-
- void hySearchSelection(wxListBox& listbox, wxEvent& event)
- {
- int sel = listbox.GetSelection();
- long block_id = (long)listbox.GetClientData(sel);
- MainFrame->window->DisplayFileAt(block_id);
- MainFrame->window->StoreHypertextItem(block_id);
- MainFrame->window->DisplaySection();
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
- }
-
- // Search window
- SearchBox::SearchBox(wxFrame *parent):
- wxDialogBox(parent, "Search", FALSE, SearchWindowX, SearchWindowY, 500, 300)
- {
- SetClientSize(500, 300);
-
- (void)new wxButton(this, (wxFunction)&hySearchQuit, "Quit");
-
- search_item = new wxText(this, (wxFunction)NULL, "Search string", "*", -1, -1, 400, -1);
- NewLine();
-
- (void)new wxButton(this, (wxFunction)&hyDoSearch, "Do Search");
- NewLine();
-
- titles_item = new wxListBox(this, (wxFunction)&hySearchSelection,
- "Items", wxSINGLE, -1, -1, 400, 200);
-
- Fit();
- }
-
- wxList *FindMatchingStrings(char *search_string1)
- {
- wxCursor *old_cursor = MainFrame->window->SetCursor(wxHOURGLASS_CURSOR);
- ::wxSetCursor(wxHOURGLASS_CURSOR);
-
- char buffer[300];
- char *search_string = copystring(search_string1);
-
- int i;
- for (i = 0; i < strlen(search_string); i ++)
- search_string[i] = toupper(search_string[i]);
-
- wxList *string_list = new wxList;
-
- wxNode *node = MainFrame->window->text_chunks.First();
- while (node)
- {
- wxTextChunk *chunk = (wxTextChunk *)node->Data();
- if ((chunk->special_attribute == wxHYPER_SECTION) && chunk->visibility)
- {
- MainFrame->window->GetBlockText(buffer, 300, node, chunk->block_id);
- char *text = copystring(buffer);
-
- for (i = 0; i < strlen(buffer); i ++)
- buffer[i] = toupper(buffer[i]);
-
- if (search_string && (search_string[0] == '*' || StringMatch(search_string, buffer)))
- string_list->Append(new StringData(text, (wxObject *)chunk->block_id));
- }
- node = node->Next();
- }
-
- SortStringDataList(string_list);
- delete search_string;
-
- MainFrame->window->SetCursor(old_cursor);
- ::wxSetCursor(wxSTANDARD_CURSOR);
-
- return string_list;
- }
-
- void DeleteMatchingStrings(wxList *string_list)
- {
- wxNode *node = string_list->First();
- while (node)
- {
- StringData *sd = (StringData *)node->Data();
-
- delete sd;
- delete node;
- node = string_list->First();
- }
- delete string_list;
- }
-
- void SearchBox::DoSearch(wxList *string_list)
- {
- char *search_string = copystring(search_item->GetValue());
- if (!search_string)
- return;
-
- wxCursor *old_cursor = MainFrame->window->SetCursor(wxHOURGLASS_CURSOR);
- ::wxSetCursor(wxHOURGLASS_CURSOR);
-
- titles_item->Show(FALSE);
- titles_item->Clear();
-
- if (!string_list)
- string_list = FindMatchingStrings(search_string);
-
- wxNode *node = string_list->First();
- while (node)
- {
- StringData *sd = (StringData *)node->Data();
- titles_item->Append(sd->s, (char *)sd->data);
-
- node = node->Next();
- }
- DeleteMatchingStrings(string_list);
-
- titles_item->Show(TRUE);
- delete search_string;
-
- MainFrame->window->SetCursor(old_cursor);
- ::wxSetCursor(wxSTANDARD_CURSOR);
- }
-
- void HelpSearch(void)
- {
- if (TheSearchBox)
- {
- TheSearchBox->Show(TRUE);
- return;
- }
- TheSearchBox = new SearchBox(NULL);
- TheSearchBox->DoSearch();
-
- TheSearchBox->Show(TRUE);
- }
-
- /*
- * Communication with applications
- *
- */
-
- Bool HelpConnection::OnExecute(char *topic, char *data, int size, int format)
- {
- if (strcmp(topic, "WXHELP") == 0)
- {
- switch (data[0])
- {
- case 's': // Display at section (-1 for top)
- {
- int section_no = atoi(data + 2);
- if (section_no == -1)
- {
- MainFrame->window->DisplayFileAtTop();
- MainFrame->window->StoreHypertextItem(-1);
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
- return TRUE;
- }
- else
- {
- // Find section for block
- wxNode *sectionNode = MainFrame->window->sections.Nth(section_no - 1);
- if (sectionNode)
- {
- wxTextChunk *chunk = (wxTextChunk *)sectionNode->Data();
- MainFrame->window->DisplayFileAt(chunk->block_id);
- MainFrame->window->StoreHypertextItem(chunk->block_id);
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
- return TRUE;
- }
- else return TRUE;
- }
- break;
- }
- case 'b': // Display at block
- {
- long block_no = atol(data + 2);
- MainFrame->window->DisplayFileAt(block_no);
- MainFrame->window->StoreHypertextItem(block_no);
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
- return TRUE;
- break;
- }
- case 'f': // Load file
- {
- char *s = HelpPathList.FindValidPath(data + 2);
- if (!s)
- {
- MainFrame->SetTitle("wxHelp (no title)");
- char buf[500];
- sprintf(buf, "Cannot find file %s.\nTrying editing the WXHELPFILES environment variable.", hyFilename);
- wxMessageBox(buf);
- return FALSE;
- }
-
- if (!hyFilename || (strcmp(s, hyFilename) != 0))
- {
- if (hyFilename) delete hyFilename;
- hyFilename = copystring(s);
- Bool succ = MainFrame->window->LoadFile(hyFilename);
- MainFrame->window->StoreHypertextItem(-1);
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
- return succ;
- }
- else
- {
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
- return TRUE;
- }
- break;
- }
- case 'k': // Search for string
- {
- char *str = data + 2;
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
-
- wxList *string_list = FindMatchingStrings(str);
- int n = string_list->Number();
- if (n == 0)
- {
- delete string_list;
- return FALSE;
- }
- else if (n == 1)
- {
- StringData *sd = (StringData *)string_list->First()->Data();
- long block_id = (long)sd->data;
- DeleteMatchingStrings(string_list);
-
- MainFrame->window->DisplayFileAt(block_id);
- MainFrame->window->StoreHypertextItem(block_id);
- MainFrame->window->DisplaySection();
- return TRUE;
- }
- else
- {
- MainFrame->Iconize(FALSE);
- MainFrame->Show(TRUE);
- if (TheSearchBox)
- TheSearchBox->Show(TRUE);
- else
- TheSearchBox = new SearchBox(NULL);
- TheSearchBox->search_item->SetValue(str);
- TheSearchBox->DoSearch(string_list);
-
- TheSearchBox->Show(TRUE);
- return TRUE;
- }
- break;
- }
- default:
- return FALSE;
- }
- } else return FALSE;
- }
-
- Bool HelpConnection::OnDisconnect(void)
- {
- TheHelpConnection = NULL;
- MainFrame->OnClose();
- delete MainFrame;
- delete this;
- return TRUE;
- }
-