3 Star 2 Fork 1

PureBasic/PureBASIC

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
HelpViewer.pb 19.38 KB
一键复制 编辑 原始数据 按行查看 历史
Fred Laboureur 提交于 2024-09-12 22:38 +08:00 . - Remove all Carbon related code
; --------------------------------------------------------------------------------------------
; Copyright (c) Fantaisie Software. All rights reserved.
; Dual licensed under the GPL and Fantaisie Software licenses.
; See LICENSE and LICENSE-FANTAISIE in the project root for license information.
; --------------------------------------------------------------------------------------------
;
; Crossplatform help viewer that uses the WebGadget for html display
; and a contsnts/index file in xml (generated by docmaker)
;
; Used only on Mac for now
;
CompilerIf #CompileMac
; stores the urls for the index and contents table and search results
Global NewList Help_Index.s()
Global NewList Help_Contents.s()
Global NewList Help_Search.s()
Global HelpDirectory$
Global HelpLanguage$
Procedure SetHelpDirectory()
CompilerIf #SpiderBasic
; For now, we ship only english doc
HelpDirectory$ = PureBasicPath$+"help/"+LCase(#ProductName$)+"/"
CompilerElse
Select UCase(CurrentLanguage$)
Case "FRANCAIS"
HelpDirectory$ = PureBasicPath$+"help/"+LCase(#ProductName$)+"_french/"
Case "DEUTSCH"
HelpDirectory$ = PureBasicPath$+"help/"+LCase(#ProductName$)+"_german/"
Default
HelpDirectory$ = PureBasicPath$+"help/"+LCase(#ProductName$)+"/"
EndSelect
CompilerEndIf
EndProcedure
Procedure LoadHelpPage(Url$)
Debug "current: " + GetGadgetText(#GADGET_Help_Viewer)
Debug "setting: " + Url$
SetGadgetText(#GADGET_Help_Viewer, "file://" + ReplaceString(HelpDirectory$, " ", "%20") + Url$) ; we need escaped space as it's a web path
EndProcedure
Procedure AddXMLHelpEntries(*Node, Sublevel)
; add all subitems of a contents entry to the help
*Child = ChildXMLNode(*Node)
While *Child
If XMLNodeType(*Child) = #PB_XML_Normal And GetXMLNodeName(*Child) = "entry"
; add gadget entry
AddGadgetItem(#GADGET_Help_Tree, -1, GetXMLAttribute(*Child, "title"), 0, Sublevel)
; add url entry
AddElement(Help_Contents())
Help_Contents() = GetXMLAttribute(*Child, "url")
; add any child entries
AddXMLHelpEntries(*Child, Sublevel+1)
EndIf
*Child = NextXMLNode(*Child)
Wend
EndProcedure
Procedure LoadHelpIndex()
; Load the contents tree
;
ClearList(Help_Contents())
ClearGadgetItems(#GADGET_Help_Tree)
If LoadXML(#XML_Help, HelpDirectory$ + "contents.xml")
; do not check XMLStatus, just use whatever got loaded correctly in any case
*Contents = MainXMLNode(#XML_Help)
If *Contents And GetXMLNodeName(*Contents) = "contents"
AddXMLHelpEntries(*Contents, 0)
EndIf
FreeXML(#XML_Help)
EndIf
; Load the index file
;
ClearList(Help_Index())
ClearGadgetItems(#GADGET_Help_Index)
If LoadXML(#XML_Help, HelpDirectory$ + "index.xml")
*Index = MainXMLNode(#XML_Help)
If *Index And GetXMLNodeName(*Index) = "index"
*Child = ChildXMLNode(*Index)
While *Child
If XMLNodeType(*Child) = #PB_XML_Normal And GetXMLNodeName(*Child) = "entry"
; add gadget entry
AddGadgetItem(#GADGET_Help_Index, -1, GetXMLAttribute(*Child, "title"))
; add url entry
AddElement(Help_Index())
Help_Index() = GetXMLAttribute(*Child, "url")
EndIf
*Child = NextXMLNode(*Child)
Wend
EndIf
FreeXML(#XML_Help)
EndIf
EndProcedure
Procedure OpenHelpWindow()
HelpLanguage$ = CurrentLanguage$
SetHelpDirectory()
If IsWindow(#WINDOW_Help) = 0
Flags = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_Invisible
If HelpWindowX = -1 And HelpWindowY = -1
Flags | #PB_Window_ScreenCentered
EndIf
If HelpWindowMaximized
Flags | #PB_Window_Maximize
EndIf
If OpenWindow(#WINDOW_Help, HelpWindowX, HelpWindowY, HelpWindowWidth, HelpWindowHeight, Language("Help","Title"), Flags)
ContainerGadget(#GADGET_Help_Container, 0, 0, 0, 0, #PB_Container_BorderLess)
ButtonImageGadget(#GADGET_Help_Back, 0, 0, 0, 0, ImageID(#IMAGE_Help_Back))
ButtonImageGadget(#GADGET_Help_Forward, 0, 0, 0, 0, ImageID(#IMAGE_Help_Forward))
ButtonImageGadget(#GADGET_Help_Home, 0, 0, 0, 0, ImageID(#IMAGE_Help_Home))
ButtonImageGadget(#GADGET_Help_Previous,0, 0, 0, 0, ImageID(#IMAGE_Help_Previous))
ButtonImageGadget(#GADGET_Help_Next, 0, 0, 0, 0, ImageID(#IMAGE_Help_Next))
WebGadget(#GADGET_Help_Viewer, 0, 0, 0, 0, "file://" + ReplaceString(HelpDirectory$, " ", "%20") + "reference/reference.html") ; we need escaped space as it's a web path
CloseGadgetList()
GadgetToolTip(#GADGET_Help_Back, Language("Help","Back"))
GadgetToolTip(#GADGET_Help_Forward, Language("Help","Forward"))
GadgetToolTip(#GADGET_Help_Home, Language("Help","Home"))
GadgetToolTip(#GADGET_Help_Previous,Language("Help","Previous"))
GadgetToolTip(#GADGET_Help_Next, Language("Help","Next"))
PanelGadget(#GADGET_Help_Panel, 0, 0, 0, 0)
AddGadgetItem(#GADGET_Help_Panel, -1, Language("Help", "Contents"))
TreeGadget(#GADGET_Help_Tree, 0, 0, 0, 0)
AddGadgetItem(#GADGET_Help_Panel, -1, Language("Help", "Index"))
ListViewGadget(#GADGET_Help_Index, 0, 0, 0, 0)
AddGadgetItem(#GADGET_Help_Panel, -1, Language("Help", "Search"))
StringGadget(#GADGET_Help_SearchValue, 10, 10, 0, 25, "")
ButtonGadget(#GADGET_Help_SearchGo, 0, 45, 100, 25, Language("Help", "StartSearch"))
ListViewGadget(#GADGET_Help_SearchResults, 0, 80, 0, 0)
CloseGadgetList()
SplitterGadget(#GADGET_Help_Splitter, 5, 10+HelpButtonHeight, HelpWindowWidth-10, HelpWindowHeight-15-HelpButtonHeight, #GADGET_Help_Panel, #GADGET_Help_Container, #PB_Splitter_Vertical)
LoadHelpIndex() ; load the index/contents and fill the gadgets
AddKeyboardShortcut(#WINDOW_Help, #PB_Shortcut_Return, #MENU_Help_Enter)
EnsureWindowOnDesktop(#WINDOW_Help)
HideWindow(#WINDOW_Help, 0)
ResizeGadget(#GADGET_Help_Splitter, 5, 10+HelpButtonHeight, WindowWidth(#WINDOW_Help)-10, WindowHeight(#WINDOW_Help)-15-HelpButtonHeight)
SetGadgetState(#GADGET_Help_Splitter, HelpWindowSplitter)
HelpWindowEvents(#PB_Event_SizeWindow)
EndIf
Else
SetWindowForeground(#WINDOW_Help)
EndIf
EndProcedure
Procedure SearchHelpFile(Url$, Text$)
Length = Len(Text$)
match = 0
title = 0
Title$ = ""
; The html files are small. We can load them fully into memory for a fast search
;
If ReadFile(#FILE_HelpSearch, HelpDirectory$+Url$)
Size = Lof(#FILE_HelpSearch)
If Size > 0 ; just a sanity check
*Buffer = AllocateMemory(Size+SizeOf(Character)) ; null char at the end for for simple CompareMEmoryString
If *Buffer
ReadData(#FILE_HelpSearch, *Buffer, Size)
; Note: this assumes that the IDE is compiled in ascii (as the html file is ascii too)
*Cursor.Ascii = *Buffer
Size - Length
While Size > 0 And (match = 0 Or title = 0) ; need to find a matching word and a title tag
If CompareMemoryString(*Cursor, ToAscii(Text$), #PB_String_NoCase, Length, #PB_Ascii) = #PB_String_Equal
; match
match = 1
*Cursor + Length
Size - Length
ElseIf CompareMemoryString(*Cursor, ToAscii("<title>"), #PB_String_NoCase, 7, #PB_Ascii) = #PB_String_Equal
; title tag
title = 1
*TitleEnd = *Cursor + 7
While Size > (*TitleEnd - *Cursor) And CompareMemoryString(*TitleEnd, ToAscii("</title>"), #PB_String_NoCase, 8, #PB_Ascii) <> #PB_String_Equal
*TitleEnd + 1
Wend
Title$ = Trim(PeekS(*Cursor+7, *TitleEnd - *Cursor - 7, #PB_Ascii))
*Cursor + 7 ; just jump over the <title> so the title text is searched too!
Size - 7
ElseIf *Cursor\a = '<'
; other tag (do not search in tags)
*Cursor + 1
Size - 1
While Size > 0 And *Cursor\a <> '>'
*Cursor + 1
Size - 1
Wend
*Cursor + 1 ; skip >
Size - 1
Else
Size - 1
*Cursor + 1
EndIf
Wend
FreeMemory(*Buffer)
EndIf
EndIf
CloseFile(#FILE_HelpSearch)
EndIf
If match
AddGadgetItem(#GADGET_Help_SearchResults, -1, Title$)
AddElement(Help_Search())
Help_Search() = Url$
EndIf
EndProcedure
Procedure ResizeHelpSplitterContent()
; Panel part
PanelWidth = GetGadgetAttribute(#GADGET_Help_Panel, #PB_Panel_ItemWidth)
PanelHeight = GetGadgetAttribute(#GADGET_Help_Panel, #PB_Panel_ItemHeight)
GetRequiredSize(#GADGET_Help_SearchGo, @ButtonWidth, @ButtonHeight)
ButtonWidth = Max(ButtonWidth, 100)
StringHeight = GetRequiredHeight(#GADGET_Help_SearchValue)
ResizeGadget(#GADGET_Help_Tree , 0, 0, PanelWidth, PanelHeight)
ResizeGadget(#GADGET_Help_Index , 0, 0, PanelWidth, PanelHeight)
ResizeGadget(#GADGET_Help_SearchValue , 10, 10, PanelWidth-20, StringHeight)
ResizeGadget(#GADGET_Help_SearchGo , (PanelWidth-ButtonWidth)/2, 20+StringHeight, ButtonWidth, ButtonHeight)
ResizeGadget(#GADGET_Help_SearchResults, 0, 30+StringHeight+ButtonHeight, PanelWidth, PanelHeight-30-StringHeight-ButtonHeight)
; Viewer part
Width = GadgetWidth(#GADGET_Help_Container)
Height = GadgetHeight(#GADGET_Help_Container)
GetRequiredSize(#GADGET_Help_Back, @ButtonWidth, @ButtonHeight)
ResizeGadget(#GADGET_Help_Back, 2, 0, ButtonWidth, ButtonHeight) ; Don't use 0 as x axis, as on OS X the splitter do some artefacts
ResizeGadget(#GADGET_Help_Forward, 10+ButtonWidth, 0, ButtonWidth, ButtonHeight)
ResizeGadget(#GADGET_Help_Home, 18+ButtonWidth*2, 0, ButtonWidth, ButtonHeight)
ResizeGadget(#GADGET_Help_Previous, Width-13-ButtonWidth*2, 0, ButtonWidth, ButtonHeight)
ResizeGadget(#GADGET_Help_Next, Width-5-ButtonWidth, 0, ButtonWidth, ButtonHeight)
ResizeGadget(#GADGET_Help_Viewer, 2, 10+ButtonHeight, Width-4, Height-10-ButtonHeight)
EndProcedure
Procedure ResizeHelpWindow()
ResizeGadget(#GADGET_Help_Splitter, 5, 10+HelpButtonHeight, WindowWidth(#WINDOW_Help)-10, WindowHeight(#WINDOW_Help)-15-HelpButtonHeight)
EndProcedure
Procedure HelpWindowEvents(EventID)
If EventID = #PB_Event_Gadget
EventGadget = EventGadget()
ElseIf EventID = #PB_Event_Menu
If EventMenu() = #MENU_Help_Enter And GetActiveGadget() = #GADGET_Help_SearchValue
EventID = #PB_Event_Gadget
EventGadget = #GADGET_Help_SearchGo
EndIf
EndIf
Select EventID
Case #PB_Event_CloseWindow
If MemorizeWindow And IsWindowMinimized(#WINDOW_Help) = 0
HelpWindowMaximized = IsWindowMaximized(#WINDOW_Help)
If HelpWindowMaximized = 0
HelpWindowX = WindowX(#WINDOW_Help)
HelpWindowY = WindowY(#WINDOW_Help)
HelpWindowWidth = WindowWidth(#WINDOW_Help)
HelpWindowHeight = WindowHeight(#WINDOW_Help)
EndIf
HelpWindowSplitter = GetGadgetState(#GADGET_Help_Splitter)
EndIf
CloseWindow(#WINDOW_Help)
Case #PB_Event_Gadget
Select EventGadget
Case #GADGET_Help_Tree
index = GetGadgetState(#GADGET_Help_Tree)
If index <> -1
SelectElement(Help_Contents(), index)
LoadHelpPage(Help_Contents())
EndIf
Case #GADGET_Help_Index
index = GetGadgetState(#GADGET_Help_Index)
If index <> -1
SelectElement(Help_Index(), index)
LoadHelpPage(Help_Index())
EndIf
Case #GADGET_Help_Home
LoadHelpPage("reference/reference.html")
Case #GADGET_Help_Back
SetGadgetState(#GADGET_Help_Viewer, #PB_Web_Back)
Case #GADGET_Help_Forward
SetGadgetState(#GADGET_Help_Viewer, #PB_Web_Forward)
Case #GADGET_Help_Previous, #GADGET_Help_Next
Url$ = GetGadgetText(#GADGET_Help_Viewer)
Url$ = ReplaceString(Right(Url$, Len(Url$)-Len(HelpDirectory$)-7), "%20", " ") ; cut the base and "file://", and unescape the URL
; find this url in the contents to get the next/previous chapter entry
ForEach Help_Contents()
If IsEqualFile(Url$, Help_Contents()) ; do not use simple compare, as GetGadgetText on WebGadget/OSX changes the casing of the names
Sublevel = GetGadgetItemAttribute(#GADGET_Help_Tree, ListIndex(Help_Contents()), #PB_Tree_SubLevel)
; the next/previous entry in the chapter is the next/previous in the list, but only
; if it has the same sublevel in the contents tree
;
If EventGadget = #GADGET_Help_Previous
Result = PreviousElement(Help_Contents())
Else
Result = NextElement(Help_Contents())
EndIf
If Result And GetGadgetItemAttribute(#GADGET_Help_Tree, ListIndex(Help_Contents()), #PB_Tree_SubLevel) = Sublevel
LoadHelpPage(Help_Contents())
EndIf
Break
EndIf
Next Help_Contents()
Case #GADGET_Help_SearchGo
ClearGadgetItems(#GADGET_Help_SearchResults)
ClearList(Help_Search())
Search$ = Trim(GetGadgetText(#GADGET_Help_SearchValue))
; The html help is organized in one level of directories with html files inside
;
If Search$ <> ""
If ExamineDirectory(0, HelpDirectory$, "*")
While NextDirectoryEntry(0)
If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
Directory$ = DirectoryEntryName(0)
If Directory$ <> "." And Directory$ <> ".."
; search directory content
If ExamineDirectory(1, HelpDirectory$ + Directory$, "*.html")
While NextDirectoryEntry(1)
If DirectoryEntryType(1) = #PB_DirectoryEntry_File
; search the file content
SearchHelpFile(Directory$ + "/" + DirectoryEntryName(1), Search$)
EndIf
Wend
FinishDirectory(1)
EndIf
EndIf
EndIf
Wend
FinishDirectory(0)
EndIf
EndIf
If ListSize(Help_Search()) = 0 ; no results found
AddGadgetItem(#GADGET_Help_SearchResults, 0, Language("Help", "NoResults"))
AddElement(Help_Search())
Help_Search() = "reference/reference.html" ; in case the user clicks this
EndIf
Case #GADGET_Help_SearchResults
index = GetGadgetState(#GADGET_Help_SearchResults)
If index <> -1
SelectElement(Help_Search(), index)
LoadHelpPage(Help_Search())
EndIf
Case #GADGET_Help_Splitter
ResizeHelpSplitterContent()
EndSelect
Case #PB_Event_SizeWindow
ResizeHelpWindow()
EndSelect
EndProcedure
Procedure UpdateHelpWindow()
SetWindowTitle(#WINDOW_Help, Language("Help","Title"))
SetGadgetAttribute(#GADGET_Help_Back, #PB_Button_Image, ImageID(#IMAGE_Help_Back)) ; possible theme change
SetGadgetAttribute(#GADGET_Help_Forward, #PB_Button_Image, ImageID(#IMAGE_Help_Forward))
SetGadgetAttribute(#GADGET_Help_Home, #PB_Button_Image, ImageID(#IMAGE_Help_Home))
SetGadgetAttribute(#GADGET_Help_Previous, #PB_Button_Image, ImageID(#IMAGE_Help_Previous))
SetGadgetAttribute(#GADGET_Help_Next, #PB_Button_Image, ImageID(#IMAGE_Help_Next))
GadgetToolTip(#GADGET_Help_Back, Language("Help","Back"))
GadgetToolTip(#GADGET_Help_Forward, Language("Help","Forward"))
GadgetToolTip(#GADGET_Help_Home, Language("Help","Home"))
GadgetToolTip(#GADGET_Help_Previous,Language("Help","Previous"))
GadgetToolTip(#GADGET_Help_Next, Language("Help","Next"))
SetGadgetText(#GADGET_Help_SearchGo, Language("Help", "StartSearch"))
SetGadgetItemText(#GADGET_Help_Panel, 0, Language("Help", "Contents"), 0)
SetGadgetItemText(#GADGET_Help_Panel, 1, Language("Help", "Index"), 0)
SetGadgetItemText(#GADGET_Help_Panel, 2, Language("Help", "Search"), 0)
HelpWindowEvents(#PB_Event_SizeWindow)
; Reload the index, content and show the reference page if the language changed
;
If HelpLanguage$ <> CurrentLanguage$
HelpLanguage$ = CurrentLanguage$
SetHelpDirectory()
LoadHelpIndex()
LoadHelpPage("reference/reference.html")
ClearGadgetItems(#GADGET_Help_SearchResults)
ClearList(Help_Search())
EndIf
EndProcedure
Procedure DisplayHelp(CurrentWord$)
SetHelpDirectory()
If CheckPureBasicKeyWords(CurrentWord$) <> ""
HelpFile$ = CheckPureBasicKeyWords(CurrentWord$)+".html"
Else
CurrentWord$ = LCase(CurrentWord$)
For k=0 To NbBasicFunctions-1
If CurrentWord$ = LCase(BasicFunctions(k)\Name$)
; We don't have the matching table for a function, so scan every directories to find the file
;
DirID = ExamineDirectory(#PB_Any, HelpDirectory$, "*")
If DirID
While NextDirectoryEntry(DirID)
If DirectoryEntryType(DirID) = #PB_DirectoryEntry_Directory
If FileSize(HelpDirectory$+DirectoryEntryName(DirID)+"/"+CurrentWord$+".html") > 0
HelpFile$ = DirectoryEntryName(DirID)+"/"+CurrentWord$+".html"
EndIf
EndIf
Wend
FinishDirectory(DirID)
EndIf
Break
EndIf
Next
EndIf
If HelpFile$ = ""
HelpFile$ = "reference/reference.html"
EndIf
If UseHelpToolF1 And HelpToolOpen
SetGadgetText(#GADGET_HelpTool_Viewer, "file://"+ReplaceString(HelpDirectory$, " ", "%20")+HelpFile$) ; we need escaped space as it's a web path
ActivateTool("HelpTool") ; switches to the tool
Else
OpenHelpWindow()
LoadHelpPage(HelpFile$)
EndIf
EndProcedure
CompilerEndIf
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/PureBasic/purebasic.git
git@gitee.com:PureBasic/purebasic.git
PureBasic
purebasic
PureBASIC
devel

搜索帮助