Merge branches/MarkieB/gtkmain to trunk.
svn path=/trunk/netsurf/; revision=9729
20
!NetSurf/Resources/SearchEngines
Normal file
@ -0,0 +1,20 @@
|
||||
Google|www.google.com|http://www.google.com/search?q=%s|http://www.google.com/favicon.ico|
|
||||
Yahoo|search.yahoo.com|http://search.yahoo.com/search?p=%s|http://www.yahoo.com/favicon.ico|
|
||||
Bing|www.bing.com|http://www.bing.com/search?q=%s|http://www.bing.com/favicon.ico|
|
||||
Business.com|www.business.com|http://www.business.com/search/rslt_default.asp?query=%s|http://www.business.com/favicon.ico|
|
||||
Omgili|www.omgili.com|http://www.omgili.com/AAAAA/%s.html|http://www.omgili.com/favicon.ico|
|
||||
BBC News|search.bbc.co.uk|http://search.bbc.co.uk/search?q=%s&tab=ns|http://news.bbc.co.uk/favicon.ico|
|
||||
Ubuntu Packages|packages.ubuntu.com|http://packages.ubuntu.com/search?keywords=%s|http://packages.ubuntu.com/favicon.ico|
|
||||
Creative Commons|creativecommons.org|http://creativecommons.org/?s=%s|http://creativecommons.org/favicon.ico|
|
||||
Ask.com|www.ask.com|http://www.ask.com/web?q=%s|http://www.ask.com/favicon.ico|
|
||||
Answers.com|www.answers.com|http://www.answers.com/%s|http://www.answers.com/favicon.ico|
|
||||
Dictionary.com|dictionary.reference.com|http://dictionary.reference.com/browse/%s?jss=0|http://dictionary.reference.com/favicon.ico|
|
||||
Youtube|www.youtube.com|http://www.youtube.com/results?search_query=%s|http://www.youtube.com/favicon.ico|
|
||||
AeroMp3|www.aeromp3.com|http://www.aeromp3.com/search?q=%s|http://www.aeromp3.com/favicon.ico|
|
||||
AOL|search.aol.com|http://search.aol.com/aol/search?query=%s|http://www.aol.com/favicon.ico|
|
||||
Baidu|www.baidu.com|http://www.baidu.com/s?wd=%s|http://www.baidu.com/favicon.ico|
|
||||
Amazon|www.amazon.com|http://www.amazon.com/s/ref=nb_ss_gw?field-keywords=%s|http://www.amazon.com/favicon.ico|
|
||||
Ebay|shop.ebay.com|http://shop.ebay.com/items/%s|http://www.ebay.com/favicon.ico|
|
||||
IMDB|www.imdb.com|http://www.imdb.com/find?q=%s|http://www.imdb.com/favicon.ico|
|
||||
ESPN|search.espn.go.com|http://search.espn.go.com/%s/|http://www.espn.go.com/favicon.ico|
|
||||
Wikipedia|en.wikipedia.org|http://en.wikipedia.org/w/index.php?title=Special%%3ASearch&search=%s|http://en.wikipedia.org/favicon.ico|
|
@ -432,10 +432,118 @@ gtkFailed:Download failed
|
||||
gtkFileError:File error: %s
|
||||
gtkInfo:%s from %s is %s in size
|
||||
gtkSave:Save file as...
|
||||
gtkSourceSave:Save Source
|
||||
gtkPlainSave:Save as text
|
||||
gtkFullSave:Save webpage complete - select an empty directory
|
||||
gtkUnknownHost:an unknown host
|
||||
gtkUnknownFile:
|
||||
gtkUnknownSize:unknown
|
||||
|
||||
# gtk Menu / Button labels
|
||||
#
|
||||
|
||||
gtkNewTab:New _Tab
|
||||
gtkNewTabAccel:<ctrl>t
|
||||
gtkNewWindow:_New Window
|
||||
gtkNewWindowAccel:<ctrl>n
|
||||
gtkOpenFile:_Open File
|
||||
gtkOpenFileAccel:<ctrl>o
|
||||
gtkCloseWindow:_Close Window
|
||||
gtkCloseWindowAccel:<ctrl><shift>w
|
||||
gtkSavePage:Save Page..
|
||||
gtkSavePageAccel:<ctrl>s
|
||||
gtkExport:Export
|
||||
gtkPlainText:Plain Text..
|
||||
gtkDrawFile:Drawfile..
|
||||
gtkPostScript:PostScript..
|
||||
gtkPDF:PDF..
|
||||
gtkPrintPreview:Print Preview..
|
||||
gtkPrintPreviewAccel:<ctrl><shift>p
|
||||
gtkPrint:Print..
|
||||
gtkPrintAccel:<ctrl>p
|
||||
gtkQuit:_Quit
|
||||
gtkQuitAccel:<ctrl>q
|
||||
|
||||
gtkCut:Cu_t
|
||||
gtkCutAccel:<ctrl>x
|
||||
gtkCopy:_Copy
|
||||
gtkCopyAccel:<ctrl>c
|
||||
gtkPaste:_Paste
|
||||
gtkPasteAccel:<ctrl>v
|
||||
gtkDelete:_Delete
|
||||
gtkSelectAll:Select _All
|
||||
gtkSelectAllAccel:<ctrl>a
|
||||
gtkFind:_Find..
|
||||
gtkFindAccel:<ctrl>f
|
||||
gtkPreferences:P_references
|
||||
|
||||
gtkStop:_Stop
|
||||
gtkStopAccel:Escape
|
||||
gtkReload:_Reload
|
||||
gtkReloadAccel:F5
|
||||
gtkScaleView:_Scale View
|
||||
gtkZoomPlus:Zoom _in
|
||||
gtkZoomPlusAccel:<ctrl>plus
|
||||
gtkZoomMinus:Zoom _out
|
||||
gtkZoomMinusAccel:<ctrl>minus
|
||||
gtkZoomNormal:_Normal size
|
||||
gtkZoomNormalAccel:<ctrl>0
|
||||
gtkFullScreen:_Fullscreen
|
||||
gtkFullScreenAccel:F11
|
||||
gtkViewSource:View S_ource
|
||||
gtkViewSourceAccel:F8
|
||||
gtkImages:_Images
|
||||
gtkForegroundImages:_Foreground Images
|
||||
gtkBackgroundImages:_Background Images
|
||||
gtkToolbars:_Toolbars
|
||||
gtkMenuBar:_Menu Bar
|
||||
gtkToolBar:_Button Bar
|
||||
gtkStatusBar:_Status Bar
|
||||
gtkDownloads:_Downloads
|
||||
gtkDownloadsAccel:<ctrl>d
|
||||
gtkSaveWindowSize:S_ave Window Size
|
||||
gtkDebugging:De_bugging
|
||||
gtkToggleDebugging:T_oggle debug rendering
|
||||
gtkSaveBoxTree:_Save box tree
|
||||
gtkSaveDomTree:Save DOM tree
|
||||
|
||||
gtkBack:_Back
|
||||
gtkBackAccel:<alt>Left
|
||||
gtkForward:_Forward
|
||||
gtkForwardAccel:<alt>Right
|
||||
gtkHome:_Home
|
||||
gtkHomeAccel:<alt>Down
|
||||
gtkLocalHistory:_Local History
|
||||
gtkLocalHistoryAccel:<ctrl>h
|
||||
gtkGlobalHistory:_Global History
|
||||
gtkGlobalHistoryAccel:<ctrl><shift>h
|
||||
gtkAddBookMarks:_Add to Bookmarks..
|
||||
gtkShowBookMarks:_Show Bookmarks..
|
||||
gtkShowBookMarksAccel:F6
|
||||
gtkOpenLocation:_Open Location..
|
||||
gtkOpenLocationAccel:<ctrl>l
|
||||
|
||||
gtkNextTab:_Next tab
|
||||
gtkNextTabAccel:<ctrl>Right
|
||||
gtkPrevTab:_Previous tab
|
||||
gtkPrevTabAccel:<ctrl>Left
|
||||
gtkCloseTab:_Close tab
|
||||
gtkCloseTabAccel:<ctrl>w
|
||||
|
||||
gtkContents:_Contents
|
||||
gtkGuide:User _guide
|
||||
gtkUserInformation:User _information
|
||||
gtkAbout:_About
|
||||
|
||||
|
||||
gtkToolBarTitle:Toolbar custom button store
|
||||
gtkAddThemeTitle:Select folder containing theme images
|
||||
|
||||
gtkThemeFolderInstructions:To Install a theme, create a directory full of appropriately-named images as a subdirectory of gtk/res/themes/
|
||||
gtkThemeFolderSub:Select a subdirectory of the themes folder
|
||||
gtkThemeDup:Theme is already included
|
||||
gtkThemeAdd:Theme added successfully
|
||||
|
||||
# Printing user interface tokens
|
||||
# ==============================
|
||||
#
|
||||
@ -459,6 +567,8 @@ Printing:Printing page
|
||||
NotFound:nichts
|
||||
Next:Next
|
||||
Prev:Previous
|
||||
ShowAll:Show All
|
||||
CaseSens:Case Sensitive
|
||||
|
||||
|
||||
# 401 login user interface tokens
|
||||
@ -578,6 +688,9 @@ MiscError:Unerwarteter Fehler:
|
||||
FileError:Datei existiert nicht:
|
||||
PrintError:Ein Fehler trat während des Druckens auf:
|
||||
AWNotSeen:Das Programm AWViewer wurde nicht gefunden.
|
||||
EncNotRec:Encoding type not recognised.
|
||||
FileOpenError:could not open file '%s'
|
||||
DirectoryError:directory '%s' already exists
|
||||
|
||||
# Specific errors - displayed in a dialog box
|
||||
#
|
||||
@ -589,11 +702,13 @@ NoDiscSpace:Nicht genug Speicherplatz auf dem Medium vorhanden.
|
||||
Template:Ein Template für ein Fenster fehlt in der Datei Templates. Bitte NetSurf neu installieren.
|
||||
HotlistSaveError:Hotlist konnte nicht korrekt gespeichert werden.
|
||||
HotlistLoadError:Hotlist konnte nicht korrekt geladen werden.
|
||||
NoDirError:%s is not a directory
|
||||
NoPathError:Symbol in ein Verzeichnisfenster ziehen um zu Speichern.
|
||||
NoNameError:Bitte einen Namen eingeben.
|
||||
NoURLError:Bitte eine URL Adresse eingeben.
|
||||
URIError:NetSurf konnte die URI Datei nicht lesen. Syntax Fehler.
|
||||
EmptyError:Die Datei ist leer.
|
||||
SearchError:Invalid Search.
|
||||
PrintErrorRO2:Der Drucker scheint beschäftigt zu sein.
|
||||
AWNotSeen:Please locate the AWViewer application and try again.
|
||||
|
||||
@ -636,6 +751,7 @@ Done:Dokument fertiggestellt
|
||||
BadRedirect:Falsche URL für Redirect
|
||||
FetchFailed:Kann Dokument nicht fetchen
|
||||
NotCSS:Warnung: Stylesheet ist kein CSS
|
||||
NotFavIco:Favicon not supported
|
||||
BadObject:Warnung: falscher Objekttyp
|
||||
ObjError:Fehler beim Laden des Objektes: %s
|
||||
ParsingFail:Dokumentparsing ist fehlgeschlagen.
|
||||
|
BIN
!NetSurf/Resources/default.ico
Normal file
After Width: | Height: | Size: 1.4 KiB |
@ -434,12 +434,119 @@ gtkFileError:File error: %s
|
||||
gtkInfo:%s from %s is %s in size
|
||||
gtkSave:Save file as...
|
||||
gtkSourceSave:Save source
|
||||
gtkplainSave:Save plain text
|
||||
gtkcompleteSave:Save webpage complete - select an empty directory
|
||||
gtkSaveConfirm:File saved
|
||||
gtkSaveCancelled:File not saved
|
||||
gtkUnknownHost:an unknown host
|
||||
gtkUnknownFile:
|
||||
gtkUnknownSize:unknown
|
||||
|
||||
# gtk Menu / Button labels
|
||||
#
|
||||
|
||||
gtkNewTab:New _Tab
|
||||
gtkNewTabAccel:<ctrl>t
|
||||
gtkNewWindow:_New Window
|
||||
gtkNewWindowAccel:<ctrl>n
|
||||
gtkOpenFile:_Open File
|
||||
gtkOpenFileAccel:<ctrl>o
|
||||
gtkCloseWindow:_Close Window
|
||||
gtkCloseWindowAccel:<ctrl><shift>w
|
||||
gtkSavePage:Save Page..
|
||||
gtkSavePageAccel:<ctrl>s
|
||||
gtkExport:Export
|
||||
gtkPlainText:Plain Text..
|
||||
gtkDrawFile:Drawfile..
|
||||
gtkPostScript:PostScript..
|
||||
gtkPDF:PDF..
|
||||
gtkPrintPreview:Print Preview..
|
||||
gtkPrintPreviewAccel:<ctrl><shift>p
|
||||
gtkPrint:Print..
|
||||
gtkPrintAccel:<ctrl>p
|
||||
gtkQuitMenu:_Quit
|
||||
gtkQuitMenuAccel:<ctrl>q
|
||||
|
||||
gtkCut:Cu_t
|
||||
gtkCutAccel:<ctrl>x
|
||||
gtkCopy:_Copy
|
||||
gtkCopyAccel:<ctrl>c
|
||||
gtkPaste:_Paste
|
||||
gtkPasteAccel:<ctrl>v
|
||||
gtkDelete:_Delete
|
||||
gtkSelectAll:Select _All
|
||||
gtkSelectAllAccel:<ctrl>a
|
||||
gtkFind:_Find..
|
||||
gtkFindAccel:<ctrl>f
|
||||
gtkPreferences:P_references
|
||||
|
||||
gtkStop:_Stop
|
||||
gtkStopAccel:Escape
|
||||
gtkReload:_Reload
|
||||
gtkReloadAccel:F5
|
||||
gtkScaleView:_Scale View
|
||||
gtkZoomPlus:Zoom _in
|
||||
gtkZoomPlusAccel:<ctrl>plus
|
||||
gtkZoomMinus:Zoom _out
|
||||
gtkZoomMinusAccel:<ctrl>minus
|
||||
gtkZoomNormal:_Normal size
|
||||
gtkZoomNormalAccel:<ctrl>0
|
||||
gtkFullScreen:_Fullscreen
|
||||
gtkFullScreenAccel:F11
|
||||
gtkViewSource:View S_ource
|
||||
gtkViewSourceAccel:F8
|
||||
gtkImages:_Images
|
||||
gtkForegroundImages:_Foreground Images
|
||||
gtkBackgroundImages:_Background Images
|
||||
gtkToolbars:_Toolbars
|
||||
gtkMenuBar:_Menu Bar
|
||||
gtkToolBar:_Button Bar
|
||||
gtkStatusBar:_Status Bar
|
||||
gtkDownloads:_Downloads
|
||||
gtkDownloadsAccel:<ctrl>d
|
||||
gtkSaveWindowSize:S_ave Window Size
|
||||
gtkDebugging:De_bugging
|
||||
gtkToggleDebugging:T_oggle debug rendering
|
||||
gtkSaveBoxTree:_Save box tree
|
||||
gtkSaveDomTree:Save DOM tree
|
||||
|
||||
gtkBack:_Back
|
||||
gtkBackAccel:<alt>Left
|
||||
gtkForward:_Forward
|
||||
gtkForwardAccel:<alt>Right
|
||||
gtkHome:_Home
|
||||
gtkHomeAccel:<alt>Down
|
||||
gtkLocalHistory:_Local History
|
||||
gtkLocalHistoryAccel:<ctrl>h
|
||||
gtkGlobalHistory:_Global History
|
||||
gtkGlobalHistoryAccel:<ctrl><shift>h
|
||||
gtkAddBookMarks:_Add to Bookmarks..
|
||||
gtkShowBookMarks:_Show Bookmarks..
|
||||
gtkShowBookMarksAccel:F6
|
||||
gtkOpenLocation:_Open Location..
|
||||
gtkOpenLocationAccel:<ctrl>l
|
||||
|
||||
gtkNextTab:_Next tab
|
||||
gtkNextTabAccel:<ctrl>Right
|
||||
gtkPrevTab:_Previous tab
|
||||
gtkPrevTabAccel:<ctrl>Left
|
||||
gtkCloseTab:_Close tab
|
||||
gtkCloseTabAccel:<ctrl>w
|
||||
|
||||
gtkContents:_Contents
|
||||
gtkGuide:User _guide
|
||||
gtkUserInformation:User _information
|
||||
gtkAbout:_About
|
||||
|
||||
|
||||
gtkToolBarTitle:Toolbar custom button store
|
||||
gtkAddThemeTitle:Select folder containing theme images
|
||||
|
||||
gtkThemeFolderInstructions:To Install a theme, create a directory full of appropriately-named images as a subdirectory of gtk/res/themes/
|
||||
gtkThemeFolderSub:Select a subdirectory of the themes folder
|
||||
gtkThemeDup:Theme is already included
|
||||
gtkThemeAdd:Theme added successfully
|
||||
|
||||
# Printing user interface tokens
|
||||
# ==============================
|
||||
#
|
||||
@ -463,6 +570,8 @@ Printing:Printing page
|
||||
NotFound:Not found
|
||||
Next:Next
|
||||
Prev:Previous
|
||||
ShowAll:Show All
|
||||
CaseSens:Case Sensitive
|
||||
|
||||
|
||||
# 401 login user interface tokens
|
||||
@ -593,14 +702,18 @@ NoDiscSpace:Not enough space available on disc.
|
||||
Template:A window template is missing from the Templates file. Please reinstall NetSurf.
|
||||
HotlistSaveError:The hotlist was unable to be correctly saved.
|
||||
HotlistLoadError:The hotlist was unable to be correctly loaded.
|
||||
NoDirError:%s is not a directory
|
||||
NoPathError:To save, drag the icon to a directory display
|
||||
NoNameError:Please enter a name
|
||||
NoURLError:Please enter a URL
|
||||
URIError:NetSurf was unable to parse this URI file due to a syntax error.
|
||||
EmptyError:file is empty.
|
||||
SearchError:Invalid Search.
|
||||
PrintErrorRO2:It appears that the printer is busy.
|
||||
AWNotSeen:Please locate the AWViewer application and try again.
|
||||
EncNotRec:Encoding type not recognised.
|
||||
FileOpenError:could not open file '%s'
|
||||
DirectoryError:directory '%s' already exists
|
||||
|
||||
# Error messages for Amiga version only
|
||||
CompError:Unable to open
|
||||
@ -641,6 +754,7 @@ Done:Document done
|
||||
BadRedirect:Bad redirect URL
|
||||
FetchFailed:Unable to fetch document
|
||||
NotCSS:Warning: stylesheet is not CSS
|
||||
NotFavIco:Favicon not supported
|
||||
BadObject:Warning: bad object type
|
||||
ObjError:Error loading object: %s
|
||||
ParsingFail:Parsing the document failed.
|
||||
|
@ -432,10 +432,118 @@ gtkFailed:Download failed
|
||||
gtkFileError:File error: %s
|
||||
gtkInfo:%s from %s is %s in size
|
||||
gtkSave:Save file as...
|
||||
gtkSourceSave:Save Source
|
||||
gtkPlainSave:Save as text
|
||||
gtkFullSave:Save webpage complete - select an empty directory
|
||||
gtkUnknownHost:an unknown host
|
||||
gtkUnknownFile:
|
||||
gtkUnknownSize:unknown
|
||||
|
||||
# gtk Menu / Button labels
|
||||
#
|
||||
|
||||
gtkNewTab:New _Tab
|
||||
gtkNewTabAccel:<ctrl>t
|
||||
gtkNewWindow:_New Window
|
||||
gtkNewWindowAccel:<ctrl>n
|
||||
gtkOpenFile:_Open File
|
||||
gtkOpenFileAccel:<ctrl>o
|
||||
gtkCloseWindow:_Close Window
|
||||
gtkCloseWindowAccel:<ctrl><shift>w
|
||||
gtkSavePage:Save Page..
|
||||
gtkSavePageAccel:<ctrl>s
|
||||
gtkExport:Export
|
||||
gtkPlainText:Plain Text..
|
||||
gtkDrawFile:Drawfile..
|
||||
gtkPostScript:PostScript..
|
||||
gtkPDF:PDF..
|
||||
gtkPrintPreview:Print Preview..
|
||||
gtkPrintPreviewAccel:<ctrl><shift>p
|
||||
gtkPrint:Print..
|
||||
gtkPrintAccel:<ctrl>p
|
||||
gtkQuit:_Quit
|
||||
gtkQuitAccel:<ctrl>q
|
||||
|
||||
gtkCut:Cu_t
|
||||
gtkCutAccel:<ctrl>x
|
||||
gtkCopy:_Copy
|
||||
gtkCopyAccel:<ctrl>c
|
||||
gtkPaste:_Paste
|
||||
gtkPasteAccel:<ctrl>v
|
||||
gtkDelete:_Delete
|
||||
gtkSelectAll:Select _All
|
||||
gtkSelectAllAccel:<ctrl>a
|
||||
gtkFind:_Find..
|
||||
gtkFindAccel:<ctrl>f
|
||||
gtkPreferences:P_references
|
||||
|
||||
gtkStop:_Stop
|
||||
gtkStopAccel:Escape
|
||||
gtkReload:_Reload
|
||||
gtkReloadAccel:F5
|
||||
gtkScaleView:_Scale View
|
||||
gtkZoomPlus:Zoom _in
|
||||
gtkZoomPlusAccel:<ctrl>plus
|
||||
gtkZoomMinus:Zoom _out
|
||||
gtkZoomMinusAccel:<ctrl>minus
|
||||
gtkZoomNormal:_Normal size
|
||||
gtkZoomNormalAccel:<ctrl>0
|
||||
gtkFullScreen:_Fullscreen
|
||||
gtkFullScreenAccel:F11
|
||||
gtkViewSource:View S_ource
|
||||
gtkViewSourceAccel:F8
|
||||
gtkImages:_Images
|
||||
gtkForegroundImages:_Foreground Images
|
||||
gtkBackgroundImages:_Background Images
|
||||
gtkToolbars:_Toolbars
|
||||
gtkMenuBar:_Menu Bar
|
||||
gtkToolBar:_Button Bar
|
||||
gtkStatusBar:_Status Bar
|
||||
gtkDownloads:_Downloads
|
||||
gtkDownloadsAccel:<ctrl>d
|
||||
gtkSaveWindowSize:S_ave Window Size
|
||||
gtkDebugging:De_bugging
|
||||
gtkToggleDebugging:T_oggle debug rendering
|
||||
gtkSaveBoxTree:_Save box tree
|
||||
gtkSaveDomTree:Save DOM tree
|
||||
|
||||
gtkBack:_Back
|
||||
gtkBackAccel:<alt>Left
|
||||
gtkForward:_Forward
|
||||
gtkForwardAccel:<alt>Right
|
||||
gtkHome:_Home
|
||||
gtkHomeAccel:<alt>Down
|
||||
gtkLocalHistory:_Local History
|
||||
gtkLocalHistoryAccel:<ctrl>h
|
||||
gtkGlobalHistory:_Global History
|
||||
gtkGlobalHistoryAccel:<ctrl><shift>h
|
||||
gtkAddBookMarks:_Add to Bookmarks..
|
||||
gtkShowBookMarks:_Show Bookmarks..
|
||||
gtkShowBookMarksAccel:F6
|
||||
gtkOpenLocation:_Open Location..
|
||||
gtkOpenLocationAccel:<ctrl>l
|
||||
|
||||
gtkNextTab:_Next tab
|
||||
gtkNextTabAccel:<ctrl>Right
|
||||
gtkPrevTab:_Previous tab
|
||||
gtkPrevTabAccel:<ctrl>Left
|
||||
gtkCloseTab:_Close tab
|
||||
gtkCloseTabAccel:<ctrl>w
|
||||
|
||||
gtkContents:_Contents
|
||||
gtkGuide:User _guide
|
||||
gtkUserInformation:User _information
|
||||
gtkAbout:_About
|
||||
|
||||
|
||||
gtkToolBarTitle:Toolbar custom button store
|
||||
gtkAddThemeTitle:Select folder containing theme images
|
||||
|
||||
gtkThemeFolderInstructions:To Install a theme, create a directory full of appropriately-named images as a subdirectory of gtk/res/themes/
|
||||
gtkThemeFolderSub:Select a subdirectory of the themes folder
|
||||
gtkThemeDup:Theme is already included
|
||||
gtkThemeAdd:Theme added successfully
|
||||
|
||||
# Printing user interface tokens
|
||||
# ==============================
|
||||
#
|
||||
@ -459,6 +567,8 @@ Printing:Printing page
|
||||
NotFound:Non trouvé
|
||||
Next:Next
|
||||
Prev:Previous
|
||||
ShowAll:Show All
|
||||
CaseSens:Case Sensitive
|
||||
|
||||
|
||||
# 401 login user interface tokens
|
||||
@ -578,6 +688,9 @@ MiscError:Une erreur inattendue s'est produite:
|
||||
FileError:Le fichier n'existe pas:
|
||||
PrintError:Une erreur s'est produite lors de l'impression:
|
||||
AWNotSeen:Localisez l'application AMViewer SVP puis réessayez.
|
||||
EncNotRec:Encoding type not recognised.
|
||||
FileOpenError:could not open file '%s'
|
||||
DirectoryError:directory '%s' already exists
|
||||
|
||||
# Specific errors - displayed in a dialog box
|
||||
#
|
||||
@ -589,11 +702,13 @@ NoDiscSpace:Pas assez d'espace disque disponible.
|
||||
Template:Un modèle de fenêtre est absent du fichier Templates. Réinstallez NetSurf SVP.
|
||||
HotlistSaveError:Les favoris n'ont pas pu être sauvés correctement.
|
||||
HotlistLoadError:Les favoris n'ont pas pu être chargés correctement.
|
||||
NoDirError:%s n'est pas un répertoire
|
||||
NoPathError:Pour sauver, lâcher cette icône dans une fenêtre de Filer
|
||||
NoNameError:Entrez un nom SVP
|
||||
NoURLError:Entrez une URL SVP
|
||||
URIError:NetSurf est incapable de traiter ce fichier URI à cause d'une erreur de syntaxe.
|
||||
EmptyError:Le fichier est vide.
|
||||
SearchError:Recherche Non-Valide.
|
||||
PrintErrorRO2:Il semble que l'imprimante soit occupée.
|
||||
AWNotSeen:Localisez l'application AMViewer SVP puis réessayez.
|
||||
|
||||
@ -636,6 +751,7 @@ Done:Document terminé
|
||||
BadRedirect:Mauvais URL de redirection
|
||||
FetchFailed:Récupération du fichier impossible
|
||||
NotCSS:Attention: feuille de style non CSS
|
||||
NotFavIco:Favicon non-soutenu
|
||||
BadObject:Attention: mauvais type d'objet
|
||||
ObjError:Erreur lors du chargement de: %s
|
||||
ParsingFail:L'analyse syntaxique du document a échoué.
|
||||
|
@ -214,7 +214,7 @@ URLSuggest:URL Recenti
|
||||
Languages:Lingua
|
||||
#
|
||||
# Network pane
|
||||
ProxyType:Tipo di proxy
|
||||
ProxyType:Tipo di Proxy
|
||||
ProxyNone:Nessun proxy
|
||||
ProxyNoAuth:Proxy semplice
|
||||
ProxyBasic:Autentificazione di Base
|
||||
@ -437,12 +437,119 @@ gtkFileError:Errore File: %s
|
||||
gtkInfo:%s da %s è %s come dimensione
|
||||
gtkSave:Salva file come...
|
||||
gtkSourceSave:Salva sorgente
|
||||
gtkPlainSave:Save as text
|
||||
gtkFullSave:Save webpage complete - select an empty directory
|
||||
gtkSaveConfirm:File salvato
|
||||
gtkSaveCancelled:File non salvato
|
||||
gtkUnknownHost:un Host sconosciuto
|
||||
gtkUnknownFile:
|
||||
gtkUnknownSize:sconosciuto
|
||||
|
||||
# gtk Menu / Button labels
|
||||
#
|
||||
|
||||
gtkNewTab:New _Tab
|
||||
gtkNewTabAccel:<ctrl>t
|
||||
gtkNewWindow:_New Window
|
||||
gtkNewWindowAccel:<ctrl>n
|
||||
gtkOpenFile:_Open File
|
||||
gtkOpenFileAccel:<ctrl>o
|
||||
gtkCloseWindow:_Close Window
|
||||
gtkCloseWindowAccel:<ctrl><shift>w
|
||||
gtkSavePage:Save Page..
|
||||
gtkSavePageAccel:<ctrl>s
|
||||
gtkExport:Export
|
||||
gtkPlainText:Plain Text..
|
||||
gtkDrawFile:Drawfile..
|
||||
gtkPostScript:PostScript..
|
||||
gtkPDF:PDF..
|
||||
gtkPrintPreview:Print Preview..
|
||||
gtkPrintPreviewAccel:<ctrl><shift>p
|
||||
gtkPrint:Print..
|
||||
gtkPrintAccel:<ctrl>p
|
||||
gtkQuit:_Quit
|
||||
gtkQuitAccel:<ctrl>q
|
||||
|
||||
gtkCut:Cu_t
|
||||
gtkCutAccel:<ctrl>x
|
||||
gtkCopy:_Copy
|
||||
gtkCopyAccel:<ctrl>c
|
||||
gtkPaste:_Paste
|
||||
gtkPasteAccel:<ctrl>v
|
||||
gtkDelete:_Delete
|
||||
gtkSelectAll:Select _All
|
||||
gtkSelectAllAccel:<ctrl>a
|
||||
gtkFind:_Find..
|
||||
gtkFindAccel:<ctrl>f
|
||||
gtkPreferences:P_references
|
||||
|
||||
gtkStop:_Stop
|
||||
gtkStopAccel:Escape
|
||||
gtkReload:_Reload
|
||||
gtkReloadAccel:F5
|
||||
gtkScaleView:_Scale View
|
||||
gtkZoomPlus:Zoom _in
|
||||
gtkZoomPlusAccel:<ctrl>plus
|
||||
gtkZoomMinus:Zoom _out
|
||||
gtkZoomMinusAccel:<ctrl>minus
|
||||
gtkZoomNormal:_Normal size
|
||||
gtkZoomNormalAccel:<ctrl>0
|
||||
gtkFullScreen:_Fullscreen
|
||||
gtkFullScreenAccel:F11
|
||||
gtkViewSource:View S_ource
|
||||
gtkViewSourceAccel:F8
|
||||
gtkImages:_Images
|
||||
gtkForegroundImages:_Foreground Images
|
||||
gtkBackgroundImages:_Background Images
|
||||
gtkToolbars:_Toolbars
|
||||
gtkMenuBar:_Menu Bar
|
||||
gtkToolBar:_Button Bar
|
||||
gtkStatusBar:_Status Bar
|
||||
gtkDownloads:_Downloads
|
||||
gtkDownloadsAccel:<ctrl>d
|
||||
gtkSaveWindowSize:S_ave Window Size
|
||||
gtkDebugging:De_bugging
|
||||
gtkToggleDebugging:T_oggle debug rendering
|
||||
gtkSaveBoxTree:_Save box tree
|
||||
gtkSaveDomTree:Save DOM tree
|
||||
|
||||
gtkBack:_Back
|
||||
gtkBackAccel:<alt>Left
|
||||
gtkForward:_Forward
|
||||
gtkForwardAccel:<alt>Right
|
||||
gtkHome:_Home
|
||||
gtkHomeAccel:<alt>Down
|
||||
gtkLocalHistory:_Local History
|
||||
gtkLocalHistoryAccel:<ctrl>h
|
||||
gtkGlobalHistory:_Global History
|
||||
gtkGlobalHistoryAccel:<ctrl><shift>h
|
||||
gtkAddBookMarks:_Add to Bookmarks..
|
||||
gtkShowBookMarks:_Show Bookmarks..
|
||||
gtkShowBookMarksAccel:F6
|
||||
gtkOpenLocation:_Open Location..
|
||||
gtkOpenLocationAccel:<ctrl>l
|
||||
|
||||
gtkNextTab:_Next tab
|
||||
gtkNextTabAccel:<ctrl>Right
|
||||
gtkPrevTab:_Previous tab
|
||||
gtkPrevTabAccel:<ctrl>Left
|
||||
gtkCloseTab:_Close tab
|
||||
gtkCloseTabAccel:<ctrl>w
|
||||
|
||||
gtkContents:_Contents
|
||||
gtkGuide:User _guide
|
||||
gtkUserInformation:User _information
|
||||
gtkAbout:_About
|
||||
|
||||
|
||||
gtkToolBarTitle:Toolbar custom button store
|
||||
gtkAddThemeTitle:Select folder containing theme images
|
||||
|
||||
gtkThemeFolderInstructions:To Install a theme, create a directory full of appropriately-named images as a subdirectory of gtk/res/themes/
|
||||
gtkThemeFolderSub:Select a subdirectory of the themes folder
|
||||
gtkThemeDup:Theme is already included
|
||||
gtkThemeAdd:Theme added successfully
|
||||
|
||||
# Printing user interface tokens
|
||||
# ==============================
|
||||
#
|
||||
@ -466,6 +573,8 @@ Printing:Stampa della pagina
|
||||
NotFound:Non trovato
|
||||
Next:Successivo
|
||||
Prev:Precedente
|
||||
ShowAll:Show All
|
||||
CaseSens:Case Sensitive
|
||||
|
||||
# 401 login user interface tokens
|
||||
# ===============================
|
||||
@ -487,17 +596,17 @@ Cancel:Annulla
|
||||
# This section contains tokens which are used in the
|
||||
# SSL certificate verification dialog box.
|
||||
#
|
||||
SSLCerts:Certificati SSL
|
||||
SSLError:NetSurf non è stato in grado di verificare l'autenticità del certificato SSL. Per favore verifica i dettagli qui sotto elencati.
|
||||
Subject:Oggetto
|
||||
Issuer:Depositario
|
||||
Version:Versione
|
||||
ValidFrom:Valido da
|
||||
ValidTo:Valido fino
|
||||
Type:Tipo
|
||||
Serial:Seriale
|
||||
Accept:Accetta
|
||||
Reject:Rifiuta
|
||||
SSLCerts:SSL certificates
|
||||
SSLError:NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below.
|
||||
Subject:Subject
|
||||
Issuer:Issuer
|
||||
Version:Version
|
||||
ValidFrom:Valid from
|
||||
ValidTo:Valid until
|
||||
Type:Type
|
||||
Serial:Serial
|
||||
Accept:Accept
|
||||
Reject:Reject
|
||||
|
||||
|
||||
# Content
|
||||
@ -584,6 +693,9 @@ MiscError:Si è verificato un errore inatteso:
|
||||
FileError:Il file è inesistente:
|
||||
PrintError:Si è verificato un errore durante la stampa:
|
||||
AWNotSeen:Per favore imposta l'applicazione AWViewer e riprova ancora.
|
||||
EncNotRec:Encoding type not recognised.
|
||||
FileOpenError:could not open file '%s'
|
||||
DirectoryError:directory '%s' already exists
|
||||
|
||||
# Specific errors - displayed in a dialog box
|
||||
#
|
||||
@ -595,10 +707,12 @@ NoDiscSpace:Spazio insufficiente nel disco.
|
||||
Template:Una finestra di template risulta mancante. Per favore reinstalla NetSurf.
|
||||
HotlistSaveError:Non è stato possibile salvare correttamente i segnalibri.
|
||||
HotlistLoadError:Non è stato possibile caricare correttamente i segnalibri.
|
||||
NoDirError:%s is not a directory
|
||||
NoPathError:Per salvare, trascinare l'icona in una directory di visualizzazione.
|
||||
NoNameError:Inserisci un nome
|
||||
NoURLError:Inserisci un URL
|
||||
URIError:NetSurf non è stato in grado di processare questo file URI a causa di un errore di sintassi.
|
||||
SearchError:Invalid Search.
|
||||
EmptyError:Il file è vuoto.
|
||||
PrintErrorRO2:Sembra che la stampante sia occupata.
|
||||
AWNotSeen:Per favore imposta l'applicazione AWViewer e riprova ancora.
|
||||
@ -642,7 +756,8 @@ Done:Documento completato
|
||||
#
|
||||
BadRedirect:Errata redirezione dell'URL
|
||||
FetchFailed:Impossibile ottenere il documento
|
||||
NotCSS:Attenzione: la dicitura "Foglio di stile" non ha nulla a che vedere con i CSS
|
||||
NotCSS:Attenzione: "Foglio di stile" non ha nulla a che spartire con i CSS
|
||||
NotFavIco:Favicon not supported
|
||||
BadObject:Attenzione: errato tipo di oggetto
|
||||
ObjError:Errore di caricamento dell'oggetto: %s
|
||||
ParsingFail:Analisi del documento fallita.
|
||||
@ -678,7 +793,7 @@ HTTP404:Non trovato
|
||||
HTTP405:Metodo non permesso
|
||||
HTTP406:Non accettabile
|
||||
HTTP407:Autentificazione Proxy necessaria
|
||||
HTTP408:Messaggio di TimeOut
|
||||
HTTP408:Richiesta TimeOut
|
||||
HTTP409:Conflitto
|
||||
HTTP410:Irraggiungibile
|
||||
HTTP411:Lunghezza richiesta
|
||||
|
@ -432,10 +432,118 @@ gtkFailed:Download failed
|
||||
gtkFileError:File error: %s
|
||||
gtkInfo:%s from %s is %s in size
|
||||
gtkSave:Save file as...
|
||||
gtkSourceSave:Save Source
|
||||
gtkPlainSave:Save as text
|
||||
gtkFullSave:Save webpage complete - select an empty directory
|
||||
gtkUnknownHost:an unknown host
|
||||
gtkUnknownFile:
|
||||
gtkUnknownSize:unknown
|
||||
|
||||
# gtk Menu / Button labels
|
||||
#
|
||||
|
||||
gtkNewTab:New _Tab
|
||||
gtkNewTabAccel:<ctrl>t
|
||||
gtkNewWindow:_New Window
|
||||
gtkNewWindowAccel:<ctrl>n
|
||||
gtkOpenFile:_Open File
|
||||
gtkOpenFileAccel:<ctrl>o
|
||||
gtkCloseWindow:_Close Window
|
||||
gtkCloseWindowAccel:<ctrl><shift>w
|
||||
gtkSavePage:Save Page..
|
||||
gtkSavePageAccel:<ctrl>s
|
||||
gtkExport:Export
|
||||
gtkPlainText:Plain Text..
|
||||
gtkDrawFile:Drawfile..
|
||||
gtkPostScript:PostScript..
|
||||
gtkPDF:PDF..
|
||||
gtkPrintPreview:Print Preview..
|
||||
gtkPrintPreviewAccel:<ctrl><shift>p
|
||||
gtkPrint:Print..
|
||||
gtkPrintAccel:<ctrl>p
|
||||
gtkQuit:_Quit
|
||||
gtkQuitAccel:<ctrl>q
|
||||
|
||||
gtkCut:Cu_t
|
||||
gtkCutAccel:<ctrl>x
|
||||
gtkCopy:_Copy
|
||||
gtkCopyAccel:<ctrl>c
|
||||
gtkPaste:_Paste
|
||||
gtkPasteAccel:<ctrl>v
|
||||
gtkDelete:_Delete
|
||||
gtkSelectAll:Select _All
|
||||
gtkSelectAllAccel:<ctrl>a
|
||||
gtkFind:_Find..
|
||||
gtkFindAccel:<ctrl>f
|
||||
gtkPreferences:P_references
|
||||
|
||||
gtkStop:_Stop
|
||||
gtkStopAccel:Escape
|
||||
gtkReload:_Reload
|
||||
gtkReloadAccel:F5
|
||||
gtkScaleView:_Scale View
|
||||
gtkZoomPlus:Zoom _in
|
||||
gtkZoomPlusAccel:<ctrl>plus
|
||||
gtkZoomMinus:Zoom _out
|
||||
gtkZoomMinusAccel:<ctrl>minus
|
||||
gtkZoomNormal:_Normal size
|
||||
gtkZoomNormalAccel:<ctrl>0
|
||||
gtkFullScreen:_Fullscreen
|
||||
gtkFullScreenAccel:F11
|
||||
gtkViewSource:View S_ource
|
||||
gtkViewSourceAccel:F8
|
||||
gtkImages:_Images
|
||||
gtkForegroundImages:_Foreground Images
|
||||
gtkBackgroundImages:_Background Images
|
||||
gtkToolbars:_Toolbars
|
||||
gtkMenuBar:_Menu Bar
|
||||
gtkToolBar:_Button Bar
|
||||
gtkStatusBar:_Status Bar
|
||||
gtkDownloads:_Downloads
|
||||
gtkDownloadsAccel:<ctrl>d
|
||||
gtkSaveWindowSize:S_ave Window Size
|
||||
gtkDebugging:De_bugging
|
||||
gtkToggleDebugging:T_oggle debug rendering
|
||||
gtkSaveBoxTree:_Save box tree
|
||||
gtkSaveDomTree:Save DOM tree
|
||||
|
||||
gtkBack:_Back
|
||||
gtkBackAccel:<alt>Left
|
||||
gtkForward:_Forward
|
||||
gtkForwardAccel:<alt>Right
|
||||
gtkHome:_Home
|
||||
gtkHomeAccel:<alt>Down
|
||||
gtkLocalHistory:_Local History
|
||||
gtkLocalHistoryAccel:<ctrl>h
|
||||
gtkGlobalHistory:_Global History
|
||||
gtkGlobalHistoryAccel:<ctrl><shift>h
|
||||
gtkAddBookMarks:_Add to Bookmarks..
|
||||
gtkShowBookMarks:_Show Bookmarks..
|
||||
gtkShowBookMarksAccel:F6
|
||||
gtkOpenLocation:_Open Location..
|
||||
gtkOpenLocationAccel:<ctrl>l
|
||||
|
||||
gtkNextTab:_Next tab
|
||||
gtkNextTabAccel:<ctrl>Right
|
||||
gtkPrevTab:_Previous tab
|
||||
gtkPrevTabAccel:<ctrl>Left
|
||||
gtkCloseTab:_Close tab
|
||||
gtkCloseTabAccel:<ctrl>w
|
||||
|
||||
gtkContents:_Contents
|
||||
gtkGuide:User _guide
|
||||
gtkUserInformation:User _information
|
||||
gtkAbout:_About
|
||||
|
||||
|
||||
gtkToolBarTitle:Toolbar custom button store
|
||||
gtkAddThemeTitle:Select folder containing theme images
|
||||
|
||||
gtkThemeFolderInstructions:To Install a theme, create a directory full of appropriately-named images as a subdirectory of gtk/res/themes/
|
||||
gtkThemeFolderSub:Select a subdirectory of the themes folder
|
||||
gtkThemeDup:Theme is already included
|
||||
gtkThemeAdd:Theme added successfully
|
||||
|
||||
# Printing user interface tokens
|
||||
# ==============================
|
||||
#
|
||||
@ -459,6 +567,8 @@ Printing:Printing page
|
||||
NotFound:Niet gevonden
|
||||
Next:Next
|
||||
Prev:Previous
|
||||
ShowAll:Show All
|
||||
CaseSens:Case Sensitive
|
||||
|
||||
|
||||
# 401 login user interface tokens
|
||||
@ -578,6 +688,9 @@ MiscError:Er trad een onverwachtte fout op:
|
||||
FileError:Bestand bestaat niet:
|
||||
PrintError:Fout tijdens printen:
|
||||
AWNotSeen:Zoek eerst de AWViewer applicatie en probeer het dan nog eens.
|
||||
EncNotRec:Encoding type not recognised.
|
||||
FileOpenError:could not open file '%s'
|
||||
DirectoryError:directory '%s' already exists
|
||||
|
||||
# Specific errors - displayed in a dialog box
|
||||
#
|
||||
@ -589,10 +702,12 @@ NoDiscSpace:Niet genoeg ruimte beschikbaar op disk.
|
||||
Template:Er ontbreekt een venster sjabloon in het Templates bestand. Installeer NetSurf opnieuw.
|
||||
HotlistSaveError:The hotlist was unable to be correctly saved.
|
||||
HotlistLoadError:The hotlist was unable to be correctly loaded.
|
||||
NoDirError:%s is not a directory
|
||||
NoPathError:Sleep het icoon naar een bestandsvenster om het op te slaan.
|
||||
NoNameError:Geef een naam op
|
||||
NoURLError:Geef een URL op
|
||||
URIError:NetSurf was unable to parse this URI file due to a syntax error.
|
||||
SearchError:Invalid Search.
|
||||
EmptyError:bestand is leeg.
|
||||
PrintErrorRO2:De printer lijkt al bezig te zijn.
|
||||
AWNotSeen:Please locate the AWViewer application and try again.
|
||||
@ -636,6 +751,7 @@ Done:klaar
|
||||
BadRedirect:foutief doorverwijzen naar URL
|
||||
FetchFailed:kan dit document niet ophalen
|
||||
NotCSS:melding: stylesheet is geen CSS
|
||||
NotFavIco:Favicon not supported
|
||||
BadObject:melding: fout object type
|
||||
ObjError:fout bij laden object: %s
|
||||
ParsingFail:fout bij ontleden van dit document.
|
||||
|
102
Docs/BUILDING-AmigaCross
Normal file
@ -0,0 +1,102 @@
|
||||
to install an Amiga cross-compiler in a Linux distribution, there are instructions at
|
||||
|
||||
http://utilitybase.com/article/show/2007/06/23/231/Installing+an+AmigaOS+4+cross+compiler
|
||||
|
||||
a more Mac-oriented article [though of potentially general utility] is at
|
||||
http://utilitybase.com/article/show/2006/05/21/188/Building+Amiga+OS+4+GCC+Cross+Compiler+for+UNIX%252FMAC
|
||||
|
||||
more background at
|
||||
http://cross.zerohero.se/os4.html
|
||||
|
||||
cross-compile additional libs/tools
|
||||
SDK
|
||||
http://www.hyperion-entertainment.biz/
|
||||
|
||||
newlib
|
||||
http://sources.redhat.com/newlib/
|
||||
|
||||
clib2
|
||||
http://sourceforge.net/projects/clib2/
|
||||
|
||||
ixemul
|
||||
http://strohmayer.org/sfs/
|
||||
|
||||
libnix
|
||||
http://sourceforge.net/projects/libnix/
|
||||
|
||||
though newlib / clib2 are apparently already included in the ppc-amigaos-gcc tarball
|
||||
|
||||
lha utility is debian package lha
|
||||
|
||||
then install linked libs in the correct place
|
||||
|
||||
[normally /usr/local/amiga]
|
||||
so
|
||||
sudo chmod --recursive 775 /usr/local/amiga
|
||||
sudo chmod --recursive +s /usr/local/amiga
|
||||
sudo chown --recursive `whoami` /usr/local/amiga
|
||||
sudo chgrp --recursive root /usr/local/amiga
|
||||
[mkdir /usr/local/amiga/include]
|
||||
|
||||
[may need to set ppc-amigaos-gcc libpaths]
|
||||
|
||||
zlib
|
||||
download tarball from project homepage, untar in a storage directory /
|
||||
download source from your distribution's repository [zlib1g in Ubuntu]
|
||||
[cd to top-level directory of zlib containing configure script]
|
||||
CC=ppc-amigaos-gcc AR=ppc-amigaos-ar RANLIB=ppc-amigaos-ranlib \
|
||||
CFLAGS="-DNO_FSEEKO" ./configure --prefix=/usr/local/amiga
|
||||
make
|
||||
make install
|
||||
|
||||
libxml
|
||||
download the tarball from the project's homepage, untar in a storage directory /
|
||||
download source from your distribution's repository
|
||||
download the tarball from the project's homepage, untar in a storage directory /
|
||||
download source from your distribution's repository
|
||||
cd into the directory containing the configure file
|
||||
$ ./configure --prefix=/usr/local/amiga --host=ppc-amigaos
|
||||
$ make
|
||||
[need glob.h / change logic in runtest.c]
|
||||
$ make install
|
||||
|
||||
alternative
|
||||
http://www.aminet.net/dev/lib/libxml.lha
|
||||
|
||||
|
||||
regex [pre-compiled]
|
||||
http://aminet.net/dev/lib/libregex-4.4.3.lha
|
||||
|
||||
libcurl
|
||||
download the tarball from the project's homepage, untar in a storage directory /
|
||||
download source from your distribution's repository
|
||||
cd into the directory containing the configure file
|
||||
./configure --prefix=/usr/local/amiga --host=ppc-amigaos
|
||||
$ make
|
||||
[you MUST have either POSIX or glibc strerror_r if strerror_r is found]
|
||||
$ make install
|
||||
|
||||
alternative
|
||||
http://www.aminet.net/dev/lib/libcurl.lha
|
||||
|
||||
libiconv [unnecessary as a non-overridable limited version is included in newlib]
|
||||
|
||||
openssl
|
||||
|
||||
libpng
|
||||
|
||||
libmng
|
||||
http://www.aminet.net/dev/lib/libmng_so.lha
|
||||
http://www.aminet.net/dev/lib/libmng.lha
|
||||
|
||||
liblcms
|
||||
http://www.aminet.net/dev/lib/liblcms_so.lha
|
||||
http://www.aminet.net/dev/lib/liblcms_so.lha
|
||||
|
||||
libjpeg
|
||||
|
||||
libparserutils
|
||||
libhubbub
|
||||
libcss
|
||||
libnsbmp
|
||||
libnsgif
|
@ -896,6 +896,8 @@ INCLUDE_FILE_PATTERNS =
|
||||
|
||||
PREDEFINED = riscos CSS_INTERNALS WITH_ARTWORKS WITH_BMP WITH_DRAW WITH_DRAW_EXPORT WITH_GIF WITH_JPEG WITH_MMAP WITH_MNG WITH_NSSPRITE WITH_NS_SVG WITH_PLUGIN WITH_RSVG WITH_SAVE_COMPLETE WITH_SPRITE WITH_THEME_INSTALL WITH_PDF_EXPORT
|
||||
|
||||
PREDEFINED = gtk WITH_THEME_INSTALL
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
# The macro definition that is found in the sources will be used.
|
||||
|
11
Makefile
@ -109,6 +109,11 @@ STRIP=strip
|
||||
|
||||
# Override this only if the host compiler is called something different
|
||||
HOST_CC := gcc
|
||||
ifeq ($(TARGET),amiga)
|
||||
ifneq ($(HOST),amiga)
|
||||
CC := ppc-amigaos-gcc
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET),riscos)
|
||||
ifeq ($(HOST),riscos)
|
||||
@ -550,6 +555,9 @@ else
|
||||
$(Q)$(ELF2AIF) $(EXETARGET:,ff8=,e1f) $(EXETARGET)
|
||||
$(Q)$(RM) $(EXETARGET:,ff8=,e1f)
|
||||
endif
|
||||
ifeq ($(TARGET),gtk)
|
||||
$(Q)$(TOUCH) gtk/res/toolbarIndices
|
||||
endif
|
||||
ifeq ($(NETSURF_STRIP_BINARY),YES)
|
||||
$(VQ)echo " STRIP: $(EXETARGET)"
|
||||
$(Q)$(STRIP) $(EXETARGET)
|
||||
@ -749,10 +757,13 @@ install-gtk: nsgtk
|
||||
@cp -vRL gtk/res/Aliases $(DESTDIR)$(NETSURF_GTK_RESOURCES)
|
||||
@cp -vrL gtk/res/docs $(DESTDIR)/$(NETSURF_GTK_RESOURCES)
|
||||
gzip -9v < gtk/res/messages > $(DESTDIR)$(NETSURF_GTK_RESOURCES)messages
|
||||
gzip -9v < gtk/res/SearchEngines > $(DESTDIR)$(NETSURF_GTK_RESOURCES)SearchEngines
|
||||
gzip -9v < gtk/res/downloads.glade > $(DESTDIR)$(NETSURF_GTK_RESOURCES)downloads.glade
|
||||
gzip -9v < gtk/res/netsurf.glade > $(DESTDIR)$(NETSURF_GTK_RESOURCES)netsurf.glade
|
||||
gzip -9v < gtk/res/options.glade > $(DESTDIR)$(NETSURF_GTK_RESOURCES)options.glade
|
||||
gzip -9v < gtk/res/history.glade > $(DESTDIR)$(NETSURF_GTK_RESOURCES)history.glade
|
||||
gzip -9v < gtk/res/toolbar.glade >
|
||||
$(DESTDIR)$(NETSURF_GTK_RESOURCES)toolbar.glade
|
||||
gzip -9v < gtk/res/source.glade > $(DESTDIR)$(NETSURF_GTK_RESOURCES)source.glade
|
||||
|
||||
install-beos: NetSurf
|
||||
|
@ -8,13 +8,13 @@
|
||||
S_CONTENT := content.c fetch.c fetchcache.c urldb.c \
|
||||
fetchers/fetch_curl.c fetchers/fetch_data.c
|
||||
S_CSS := css.c dump.c internal.c select.c utils.c
|
||||
S_RENDER := box.c box_construct.c box_normalise.c directory.c \
|
||||
S_RENDER := box.c box_construct.c box_normalise.c directory.c favicon.c \
|
||||
font.c form.c html.c html_redraw.c hubbub_binding.c imagemap.c \
|
||||
layout.c list.c table.c textplain.c
|
||||
S_UTILS := base64.c filename.c hashtable.c locale.c messages.c talloc.c \
|
||||
url.c utf8.c utils.c useragent.c
|
||||
S_DESKTOP := knockout.c options.c print.c tree.c version.c textarea.c \
|
||||
plot_style.c scroll.c
|
||||
S_UTILS := base64.c filename.c hashtable.c locale.c \
|
||||
messages.c talloc.c url.c utf8.c utils.c useragent.c
|
||||
S_DESKTOP := knockout.c options.c plot_style.c print.c search.c \
|
||||
searchweb.c scroll.c textarea.c tree.c version.c
|
||||
|
||||
# S_COMMON are sources common to all builds
|
||||
S_COMMON := $(addprefix content/,$(S_CONTENT)) \
|
||||
@ -33,8 +33,8 @@ S_PDF := $(addprefix desktop/save_pdf/,$(S_PDF))
|
||||
|
||||
# S_BROWSER are sources related to full browsers but are common
|
||||
# between RISC OS, GTK, BeOS and AmigaOS builds
|
||||
S_BROWSER := browser.c frames.c history_core.c netsurf.c save_text.c \
|
||||
selection.c textinput.c
|
||||
S_BROWSER := browser.c frames.c history_core.c netsurf.c save_complete.c \
|
||||
save_text.c selection.c textinput.c
|
||||
S_BROWSER := $(addprefix desktop/,$(S_BROWSER))
|
||||
|
||||
# S_RISCOS are sources purely for the RISC OS build
|
||||
@ -42,9 +42,9 @@ S_RISCOS := 401login.c artworks.c assert.c awrender.s bitmap.c buffer.c \
|
||||
cookies.c configure.c debugwin.c dialog.c download.c draw.c \
|
||||
filetype.c font.c global_history.c gui.c help.c history.c \
|
||||
hotlist.c image.c menus.c message.c palettes.c plotters.c \
|
||||
plugin.c print.c query.c save.c save_complete.c save_draw.c \
|
||||
save_pdf.c schedule.c search.c sprite.c sslcert.c textarea.c \
|
||||
textselection.c theme.c theme_install.c thumbnail.c \
|
||||
plugin.c print.c query.c save.c save_draw.c save_pdf.c \
|
||||
schedule.c search.c searchweb.c sprite.c sslcert.c \
|
||||
textarea.c textselection.c theme.c theme_install.c thumbnail.c \
|
||||
treeview.c ucstables.c uri.c url_complete.c url_protocol.c \
|
||||
wimp.c wimp_event.c window.c gui/progress_bar.c \
|
||||
gui/status_bar.c \
|
||||
@ -60,16 +60,19 @@ S_GTK := font_pango.c gtk_bitmap.c gtk_gui.c gtk_schedule.c \
|
||||
gtk_thumbnail.c gtk_plotters.c gtk_treeview.c gtk_scaffolding.c \
|
||||
gtk_completion.c gtk_login.c gtk_throbber.c gtk_selection.c \
|
||||
gtk_history.c gtk_window.c gtk_filetype.c gtk_download.c \
|
||||
gtk_print.c gtk_tabs.c \
|
||||
gtk_menu.c gtk_print.c gtk_save.c gtk_search.c gtk_tabs.c \
|
||||
gtk_theme.c gtk_toolbar.c sexy_icon_entry.c \
|
||||
$(addprefix dialogs/,gtk_options.c gtk_about.c gtk_source.c)
|
||||
S_GTK := $(addprefix gtk/,$(S_GTK))
|
||||
S_GTK := $(addprefix gtk/,$(S_GTK)) $(addprefix utils/,container.c)
|
||||
# code in utils/container.ch is non-universal it seems
|
||||
|
||||
# S_BEOS are sources purely for the BeOS build
|
||||
S_BEOS := beos_about.cpp beos_bitmap.cpp beos_fetch_rsrc.cpp \
|
||||
beos_filetype.cpp beos_font.cpp beos_gui.cpp beos_history.cpp \
|
||||
beos_login.cpp beos_options.cpp beos_plotters.cpp \
|
||||
beos_scaffolding.cpp beos_schedule.cpp beos_thumbnail.cpp \
|
||||
beos_treeview.cpp beos_throbber.cpp beos_window.cpp
|
||||
beos_scaffolding.cpp beos_search.cpp beos_schedule.cpp \
|
||||
beos_thumbnail.cpp beos_treeview.cpp beos_throbber.cpp \
|
||||
beos_window.cpp
|
||||
S_BEOS := $(addprefix beos/,$(S_BEOS))
|
||||
RDEF_BEOS := beos_res.rdef
|
||||
RDEF_BEOS := $(addprefix beos/,$(RDEF_BEOS))
|
||||
|
@ -29,13 +29,13 @@
|
||||
#include "amiga/download.h"
|
||||
#include "amiga/object.h"
|
||||
#include "amiga/options.h"
|
||||
#include "amiga/save_complete.h"
|
||||
#include "amiga/bitmap.h"
|
||||
#include "amiga/iff_dr2d.h"
|
||||
|
||||
#include "content/fetch.h"
|
||||
|
||||
#include "desktop/selection.h"
|
||||
#include "desktop/save_complete.h"
|
||||
|
||||
#include "utils/messages.h"
|
||||
#include "utils/utils.h"
|
||||
|
@ -215,11 +215,11 @@ void ami_fetch_file_free(void *vf)
|
||||
|
||||
static void ami_fetch_file_send_callback(fetch_msg msg,
|
||||
struct ami_file_fetch_info *fetch, const void *data,
|
||||
unsigned long size)
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
{
|
||||
fetch->locked = true;
|
||||
/* LOG(("ami file fetcher callback %ld",msg)); */
|
||||
fetch_send_callback(msg,fetch->fetch_handle,data,size);
|
||||
fetch_send_callback(msg,fetch->fetch_handle,data,size,errorcode);
|
||||
fetch->locked = false;
|
||||
}
|
||||
|
||||
@ -234,6 +234,7 @@ void ami_fetch_file_poll(const char *scheme_ignored)
|
||||
struct nsObject *node;
|
||||
struct nsObject *nnode;
|
||||
struct ami_file_fetch_info *fetch;
|
||||
fetch_error_code errorcode;
|
||||
|
||||
if(IsMinListEmpty(ami_file_fetcher_list)) return;
|
||||
|
||||
@ -241,6 +242,7 @@ void ami_fetch_file_poll(const char *scheme_ignored)
|
||||
|
||||
do
|
||||
{
|
||||
errorcode = FETCH_ERROR_NO_ERROR;
|
||||
nnode=(struct nsObject *)GetSucc((struct Node *)node);
|
||||
|
||||
fetch = (struct ami_file_fetch_info *)node->objstruct;
|
||||
@ -255,13 +257,19 @@ void ami_fetch_file_poll(const char *scheme_ignored)
|
||||
|
||||
len = FRead(fetch->fh,ami_file_fetcher_buffer,1,1024);
|
||||
|
||||
ami_fetch_file_send_callback(FETCH_DATA,
|
||||
fetch,ami_file_fetcher_buffer,len);
|
||||
if (len == (ULONG)-1)
|
||||
errorcode = FETCH_ERROR_MISC;
|
||||
else if (len > 0)
|
||||
ami_fetch_file_send_callback(
|
||||
FETCH_DATA, fetch,
|
||||
ami_file_fetcher_buffer,
|
||||
len, errorcode);
|
||||
|
||||
if((len<1024) && (!fetch->aborted))
|
||||
{
|
||||
ami_fetch_file_send_callback(FETCH_FINISHED,
|
||||
fetch, &fetch->cachedata, 0);
|
||||
fetch, &fetch->cachedata, 0,
|
||||
errorcode);
|
||||
|
||||
fetch->aborted = true;
|
||||
}
|
||||
@ -284,7 +292,8 @@ void ami_fetch_file_poll(const char *scheme_ignored)
|
||||
LOG(("mimetype %s len %ld",fetch->mimetype,fetch->len));
|
||||
|
||||
ami_fetch_file_send_callback(FETCH_TYPE,
|
||||
fetch, fetch->mimetype, (ULONG)fetch->len);
|
||||
fetch, fetch->mimetype, (ULONG)fetch->len,
|
||||
errorcode);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -292,8 +301,11 @@ void ami_fetch_file_poll(const char *scheme_ignored)
|
||||
|
||||
errorstring = ASPrintf("%s %s",messages_get("FileError"),fetch->path);
|
||||
fetch_set_http_code(fetch->fetch_handle,404);
|
||||
|
||||
errorcode = FETCH_ERROR_HTTP_NOT2;
|
||||
ami_fetch_file_send_callback(FETCH_ERROR, fetch,
|
||||
errorstring, 0);
|
||||
errorstring, 0,
|
||||
errorcode);
|
||||
fetch->aborted = true;
|
||||
FreeVec(errorstring);
|
||||
}
|
||||
|
19
amiga/gui.c
@ -47,6 +47,7 @@
|
||||
#include "amiga/menu.h"
|
||||
#include "amiga/options.h"
|
||||
#include <libraries/keymap.h>
|
||||
#include "desktop/save_complete.h"
|
||||
#include "desktop/textinput.h"
|
||||
#include <intuition/pointerclass.h>
|
||||
#include <math.h>
|
||||
@ -66,7 +67,6 @@
|
||||
#include "amiga/cookies.h"
|
||||
#include "amiga/clipboard.h"
|
||||
#include <proto/keymap.h>
|
||||
#include "amiga/save_complete.h"
|
||||
#include "amiga/fetch_file.h"
|
||||
#include "amiga/fetch_mailto.h"
|
||||
#include "amiga/search.h"
|
||||
@ -3410,6 +3410,23 @@ void gui_window_stop_throbber(struct gui_window *g)
|
||||
// g->shared->throbber_frame = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* function to add retrieved favicon to gui
|
||||
*/
|
||||
void gui_window_set_icon(struct gui_window *g, struct content *icon)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* set gui display of a retrieved favicon representing the search
|
||||
* provider
|
||||
* \param ico may be NULL for local calls; then access current cache from
|
||||
* search_web_ico()
|
||||
*/
|
||||
void gui_window_set_search_ico(struct content *ico)
|
||||
{
|
||||
}
|
||||
|
||||
void ami_update_throbber(struct gui_window_2 *g,bool redraw)
|
||||
{
|
||||
struct IBox *bbox;
|
||||
|
@ -56,6 +56,8 @@ enum
|
||||
GID_NEXT,
|
||||
GID_PREV,
|
||||
GID_SEARCHSTRING,
|
||||
GID_SHOWALL,
|
||||
GID_CASE,
|
||||
GID_HSCROLL,
|
||||
GID_LAST
|
||||
};
|
||||
|
@ -30,13 +30,13 @@
|
||||
#include "amiga/save_pdf.h"
|
||||
#include "desktop/save_text.h"
|
||||
#include "desktop/save_pdf/pdf_plotters.h"
|
||||
#include "desktop/save_complete.h"
|
||||
#include <string.h>
|
||||
#include "amiga/tree.h"
|
||||
#include "amiga/history.h"
|
||||
#include "amiga/cookies.h"
|
||||
#include <proto/exec.h>
|
||||
#include "amiga/arexx.h"
|
||||
#include "amiga/save_complete.h"
|
||||
#include "utils/url.h"
|
||||
#include <dos/anchorpath.h>
|
||||
#include "desktop/textinput.h"
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||
* Copyright 2004-2007 James Bursa <bursa@users.sourceforge.net>
|
||||
* Copyright 2008 Chris Young <chris@unsatisfactorysoftware.co.uk>
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
@ -18,807 +19,97 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Save HTML document with dependencies (implementation).
|
||||
*/
|
||||
|
||||
#include "utils/config.h"
|
||||
//#define _GNU_SOURCE /* for strndup */
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
#include <libxml/HTMLtree.h>
|
||||
#include <libxml/parserInternals.h>
|
||||
#include "utils/config.h"
|
||||
#include "css/css.h"
|
||||
#include "render/box.h"
|
||||
#include "amiga/save_complete.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/url.h"
|
||||
#include "desktop/save_complete.h"
|
||||
#include "utils/utils.h"
|
||||
#include <proto/dos.h>
|
||||
#include <proto/icon.h>
|
||||
#include <workbench/icon.h>
|
||||
|
||||
regex_t save_complete_import_re;
|
||||
|
||||
/** An entry in save_complete_list. */
|
||||
struct save_complete_entry {
|
||||
struct content *content;
|
||||
struct save_complete_entry *next; /**< Next entry in list */
|
||||
};
|
||||
|
||||
/** List of urls seen and saved so far. */
|
||||
static struct save_complete_entry *save_complete_list = 0;
|
||||
|
||||
static bool save_complete_html(struct content *c, const char *path,
|
||||
bool index);
|
||||
static bool save_imported_sheets(struct content *c, const char *path);
|
||||
static char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
int *osize, const char *base);
|
||||
static bool rewrite_document_urls(xmlDoc *doc, const char *base);
|
||||
static bool rewrite_urls(xmlNode *n, const char *base);
|
||||
static bool rewrite_url(xmlNode *n, const char *attr, const char *base);
|
||||
static bool save_complete_list_add(struct content *content);
|
||||
static struct content * save_complete_list_find(const char *url);
|
||||
static bool save_complete_list_check(struct content *content);
|
||||
/* static void save_complete_list_dump(void); */
|
||||
static bool save_complete_inventory(const char *path);
|
||||
#include "content/content.h"
|
||||
|
||||
/**
|
||||
* Save an HTML page with all dependencies.
|
||||
*
|
||||
* \param c CONTENT_HTML to save
|
||||
* \param path directory to save to (must exist)
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
* conducts the filesystem save appropriate to the gui
|
||||
* \param path save path
|
||||
* \param filename name of file to save
|
||||
* \param len data length
|
||||
* \param sourcedata pointer to data to save, NULL when all data in c
|
||||
* \param type content type
|
||||
* \return true for success
|
||||
*/
|
||||
|
||||
bool save_complete(struct content *c, const char *path)
|
||||
bool save_complete_gui_save(const char *path, const char *filename, size_t len,
|
||||
const char *sourcedata, content_type type)
|
||||
{
|
||||
bool result;
|
||||
|
||||
result = save_complete_html(c, path, true);
|
||||
|
||||
if (result)
|
||||
result = save_complete_inventory(path);
|
||||
|
||||
/* free save_complete_list */
|
||||
while (save_complete_list) {
|
||||
struct save_complete_entry *next = save_complete_list->next;
|
||||
free(save_complete_list);
|
||||
save_complete_list = next;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save an HTML page with all dependencies, recursing through imported pages.
|
||||
*
|
||||
* \param c CONTENT_HTML to save
|
||||
* \param path directory to save to (must exist)
|
||||
* \param index true to save as "index"
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
|
||||
bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
{
|
||||
char spath[256];
|
||||
unsigned int i;
|
||||
htmlParserCtxtPtr parser;
|
||||
BPTR fh = 0;
|
||||
|
||||
if (c->type != CONTENT_HTML)
|
||||
return false;
|
||||
|
||||
if (save_complete_list_check(c))
|
||||
return true;
|
||||
|
||||
/* save stylesheets, ignoring the base and adblocking sheets */
|
||||
for (i = STYLESHEET_START; i != c->data.html.stylesheet_count; i++) {
|
||||
struct content *css = c->data.html.stylesheets[i].c;
|
||||
char *source;
|
||||
int source_len;
|
||||
bool is_style;
|
||||
|
||||
if (!css)
|
||||
continue;
|
||||
if (save_complete_list_check(css))
|
||||
continue;
|
||||
|
||||
is_style = (strcmp(css->url, c->data.html.base_url) == 0);
|
||||
|
||||
if (is_style == false) {
|
||||
if (!save_complete_list_add(css)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!save_imported_sheets(css, path))
|
||||
return false;
|
||||
|
||||
if (is_style)
|
||||
continue; /* don't save <style> elements */
|
||||
|
||||
snprintf(spath, sizeof spath, "%s/%x", path,
|
||||
(unsigned int) css);
|
||||
source = rewrite_stylesheet_urls(css->source_data,
|
||||
css->source_size, &source_len, css->url);
|
||||
if (!source) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
error = xosfile_save_stamped(spath, 0xf79, source,
|
||||
source + source_len);
|
||||
*/
|
||||
|
||||
if(fh = FOpen(spath,MODE_NEWFILE,0))
|
||||
{
|
||||
FWrite(fh,source,1,source_len);
|
||||
FClose(fh);
|
||||
SetComment(spath,c->url);
|
||||
}
|
||||
|
||||
free(source);
|
||||
/*
|
||||
if (error) {
|
||||
LOG(("xosfile_save_stamped: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/* save objects */
|
||||
for (i = 0; i != c->data.html.object_count; i++) {
|
||||
struct content *obj = c->data.html.object[i].content;
|
||||
|
||||
/* skip difficult content types */
|
||||
if (!obj || obj->type >= CONTENT_OTHER || !obj->source_data)
|
||||
continue;
|
||||
if (save_complete_list_check(obj))
|
||||
continue;
|
||||
|
||||
if (!save_complete_list_add(obj)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj->type == CONTENT_HTML) {
|
||||
if (!save_complete_html(obj, path, false))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(spath, sizeof spath, "%s/%x", path,
|
||||
(unsigned int) obj);
|
||||
/*
|
||||
error = xosfile_save_stamped(spath,
|
||||
ro_content_filetype(obj),
|
||||
obj->source_data,
|
||||
obj->source_data + obj->source_size);
|
||||
if (error) {
|
||||
LOG(("xosfile_save_stamped: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
if(fh = FOpen(spath,MODE_NEWFILE,0))
|
||||
{
|
||||
FWrite(fh,obj->source_data,1,obj->source_size);
|
||||
FClose(fh);
|
||||
SetComment(spath,obj->url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*save_complete_list_dump();*/
|
||||
|
||||
/* make a copy of the document tree */
|
||||
parser = htmlCreateMemoryParserCtxt(c->source_data, c->source_size);
|
||||
if (!parser) {
|
||||
int res;
|
||||
int namelen;
|
||||
char deftype[5];
|
||||
struct DiskObject *dobj = NULL;
|
||||
namelen = strlen(path) + strlen(filename) + 2;
|
||||
char *fullpath = malloc(namelen);
|
||||
if (!fullpath) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
/* set parser charset */
|
||||
if (c->data.html.encoding) {
|
||||
xmlCharEncodingHandler *enc_handler;
|
||||
enc_handler =
|
||||
xmlFindCharEncodingHandler(c->data.html.encoding);
|
||||
if (enc_handler) {
|
||||
xmlCtxtResetLastError(parser);
|
||||
if (xmlSwitchToEncoding(parser, enc_handler)) {
|
||||
xmlFreeDoc(parser->myDoc);
|
||||
htmlFreeParserCtxt(parser);
|
||||
warn_user("MiscError",
|
||||
"Encoding switch failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
htmlParseDocument(parser);
|
||||
|
||||
/* rewrite all urls we know about */
|
||||
if (!rewrite_document_urls(parser->myDoc, c->data.html.base_url)) {
|
||||
xmlFreeDoc(parser->myDoc);
|
||||
htmlFreeParserCtxt(parser);
|
||||
warn_user("NoMemory", 0);
|
||||
snprintf(fullpath, namelen, "%s/%s", path, filename);
|
||||
FILE *f = fopen(fullpath, "w");
|
||||
if (f == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
/* save the html file out last of all */
|
||||
if (index)
|
||||
res = fwrite(sourcedata, len, 1, f);
|
||||
fclose(f);
|
||||
switch(type)
|
||||
{
|
||||
struct DiskObject *dobj = NULL;
|
||||
|
||||
snprintf(spath, sizeof spath, "%s/index", path);
|
||||
|
||||
dobj = GetIconTags(NULL,ICONGETA_GetDefaultName,"html",
|
||||
ICONGETA_GetDefaultType,WBPROJECT,
|
||||
TAG_DONE);
|
||||
|
||||
PutIconTags(spath,dobj,
|
||||
ICONPUTA_NotifyWorkbench,TRUE,
|
||||
TAG_DONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(spath, sizeof spath, "%s/%x", path, (unsigned int)c);
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (htmlSaveFileFormat(spath, parser->myDoc, 0, 0) == -1) {
|
||||
if (errno)
|
||||
warn_user("SaveError", strerror(errno));
|
||||
else
|
||||
warn_user("SaveError", "htmlSaveFileFormat failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
error = xosfile_set_type(spath, 0xfaf);
|
||||
if (error) {
|
||||
LOG(("xosfile_set_type: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
|
||||
xmlFreeDoc(parser->myDoc);
|
||||
htmlFreeParserCtxt(parser);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save stylesheets imported by a CONTENT_CSS.
|
||||
*
|
||||
* \param c a CONTENT_CSS
|
||||
* \param path path to save to
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
|
||||
bool save_imported_sheets(struct content *c, const char *path)
|
||||
{
|
||||
char spath[256];
|
||||
unsigned int j;
|
||||
char *source;
|
||||
int source_len;
|
||||
BPTR fh = 0;
|
||||
|
||||
for (j = 0; j != c->data.css.import_count; j++) {
|
||||
struct content *css = c->data.css.imports[j].c;
|
||||
|
||||
if (!css)
|
||||
continue;
|
||||
if (save_complete_list_check(css))
|
||||
continue;
|
||||
|
||||
if (!save_complete_list_add(css)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!save_imported_sheets(css, path))
|
||||
return false;
|
||||
|
||||
snprintf(spath, sizeof spath, "%s/%x", path,
|
||||
(unsigned int) css);
|
||||
source = rewrite_stylesheet_urls(css->source_data,
|
||||
css->source_size, &source_len, css->url);
|
||||
if (!source) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(fh = FOpen(spath,MODE_NEWFILE,0))
|
||||
{
|
||||
FWrite(fh,source,1,source_len);
|
||||
FClose(fh);
|
||||
SetComment(spath,c->url);
|
||||
}
|
||||
/*
|
||||
error = xosfile_save_stamped(spath, 0xf79, source,
|
||||
source + source_len);
|
||||
*/
|
||||
free(source);
|
||||
/*
|
||||
if (error) {
|
||||
LOG(("xosfile_save_stamped: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the save_complete module.
|
||||
*/
|
||||
|
||||
void save_complete_init(void)
|
||||
{
|
||||
/* Match an @import rule - see CSS 2.1 G.1. */
|
||||
regcomp_wrapper(&save_complete_import_re,
|
||||
"@import" /* IMPORT_SYM */
|
||||
"[ \t\r\n\f]*" /* S* */
|
||||
/* 1 */
|
||||
"(" /* [ */
|
||||
/* 2 3 */
|
||||
"\"(([^\"]|[\\]\")*)\"" /* STRING (approximated) */
|
||||
"|"
|
||||
/* 4 5 */
|
||||
"'(([^']|[\\]')*)'"
|
||||
"|" /* | */
|
||||
"url\\([ \t\r\n\f]*" /* URI (approximated) */
|
||||
/* 6 7 */
|
||||
"\"(([^\"]|[\\]\")*)\""
|
||||
"[ \t\r\n\f]*\\)"
|
||||
"|"
|
||||
"url\\([ \t\r\n\f]*"
|
||||
/* 8 9 */
|
||||
"'(([^']|[\\]')*)'"
|
||||
"[ \t\r\n\f]*\\)"
|
||||
"|"
|
||||
"url\\([ \t\r\n\f]*"
|
||||
/* 10 */
|
||||
"([^) \t\r\n\f]*)"
|
||||
"[ \t\r\n\f]*\\)"
|
||||
")", /* ] */
|
||||
REG_EXTENDED | REG_ICASE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rewrite stylesheet \@import rules for save complete.
|
||||
*
|
||||
* @param source stylesheet source
|
||||
* @param size size of source
|
||||
* @param osize updated with the size of the result
|
||||
* @param base url of stylesheet
|
||||
* @return converted source, or 0 on out of memory
|
||||
*/
|
||||
|
||||
char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
int *osize, const char *base)
|
||||
{
|
||||
char *res;
|
||||
const char *url;
|
||||
char *url2;
|
||||
char buf[20];
|
||||
unsigned int offset = 0;
|
||||
int url_len = 0;
|
||||
struct content *content;
|
||||
int m;
|
||||
unsigned int i;
|
||||
unsigned int imports = 0;
|
||||
regmatch_t match[11];
|
||||
url_func_result result;
|
||||
|
||||
/* count number occurences of @import to (over)estimate result size */
|
||||
/* can't use strstr because source is not 0-terminated string */
|
||||
for (i = 0; 7 < size && i != size - 7; i++) {
|
||||
if (source[i] == '@' &&
|
||||
tolower(source[i + 1]) == 'i' &&
|
||||
tolower(source[i + 2]) == 'm' &&
|
||||
tolower(source[i + 3]) == 'p' &&
|
||||
tolower(source[i + 4]) == 'o' &&
|
||||
tolower(source[i + 5]) == 'r' &&
|
||||
tolower(source[i + 6]) == 't')
|
||||
imports++;
|
||||
}
|
||||
|
||||
res = malloc(size + imports * 20);
|
||||
if (!res)
|
||||
return 0;
|
||||
*osize = 0;
|
||||
|
||||
while (offset < size) {
|
||||
m = regexec(&save_complete_import_re, source + offset,
|
||||
11, match, 0);
|
||||
if (m)
|
||||
case CONTENT_HTML:
|
||||
strcpy(deftype,"html");
|
||||
break;
|
||||
|
||||
/*for (unsigned int i = 0; i != 11; i++) {
|
||||
if (match[i].rm_so == -1)
|
||||
continue;
|
||||
fprintf(stderr, "%i: '%.*s'\n", i,
|
||||
match[i].rm_eo - match[i].rm_so,
|
||||
source + offset + match[i].rm_so);
|
||||
}*/
|
||||
|
||||
url = 0;
|
||||
if (match[2].rm_so != -1) {
|
||||
url = source + offset + match[2].rm_so;
|
||||
url_len = match[2].rm_eo - match[2].rm_so;
|
||||
} else if (match[4].rm_so != -1) {
|
||||
url = source + offset + match[4].rm_so;
|
||||
url_len = match[4].rm_eo - match[4].rm_so;
|
||||
} else if (match[6].rm_so != -1) {
|
||||
url = source + offset + match[6].rm_so;
|
||||
url_len = match[6].rm_eo - match[6].rm_so;
|
||||
} else if (match[8].rm_so != -1) {
|
||||
url = source + offset + match[8].rm_so;
|
||||
url_len = match[8].rm_eo - match[8].rm_so;
|
||||
} else if (match[10].rm_so != -1) {
|
||||
url = source + offset + match[10].rm_so;
|
||||
url_len = match[10].rm_eo - match[10].rm_so;
|
||||
}
|
||||
assert(url);
|
||||
|
||||
url2 = strndup(url, url_len);
|
||||
if (!url2) {
|
||||
free(res);
|
||||
return 0;
|
||||
}
|
||||
result = url_join(url2, base, (char**)&url);
|
||||
free(url2);
|
||||
if (result == URL_FUNC_NOMEM) {
|
||||
free(res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* copy data before match */
|
||||
memcpy(res + *osize, source + offset, match[0].rm_so);
|
||||
*osize += match[0].rm_so;
|
||||
|
||||
if (result == URL_FUNC_OK) {
|
||||
content = save_complete_list_find(url);
|
||||
if (content) {
|
||||
/* replace import */
|
||||
snprintf(buf, sizeof buf, "@import '%x'",
|
||||
(unsigned int) content);
|
||||
memcpy(res + *osize, buf, strlen(buf));
|
||||
*osize += strlen(buf);
|
||||
} else {
|
||||
/* copy import */
|
||||
memcpy(res + *osize, source + offset + match[0].rm_so,
|
||||
match[0].rm_eo - match[0].rm_so);
|
||||
*osize += match[0].rm_eo - match[0].rm_so;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* copy import */
|
||||
memcpy(res + *osize, source + offset + match[0].rm_so,
|
||||
match[0].rm_eo - match[0].rm_so);
|
||||
*osize += match[0].rm_eo - match[0].rm_so;
|
||||
}
|
||||
|
||||
assert(0 < match[0].rm_eo);
|
||||
offset += match[0].rm_eo;
|
||||
}
|
||||
|
||||
/* copy rest of source */
|
||||
if (offset < size) {
|
||||
memcpy(res + *osize, source + offset, size - offset);
|
||||
*osize += size - offset;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rewrite URLs in a HTML document to be relative.
|
||||
*
|
||||
* \param doc root of the document tree
|
||||
* \param base base url of document
|
||||
* \return true on success, false on out of memory
|
||||
*/
|
||||
|
||||
bool rewrite_document_urls(xmlDoc *doc, const char *base)
|
||||
{
|
||||
xmlNode *node;
|
||||
|
||||
for (node = doc->children; node; node = node->next)
|
||||
if (node->type == XML_ELEMENT_NODE)
|
||||
if (!rewrite_urls(node, base))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Traverse tree, rewriting URLs as we go.
|
||||
*
|
||||
* \param n xmlNode of type XML_ELEMENT_NODE to rewrite
|
||||
* \param base base url of document
|
||||
* \return true on success, false on out of memory
|
||||
*
|
||||
* URLs in the tree rooted at element n are rewritten.
|
||||
*/
|
||||
|
||||
bool rewrite_urls(xmlNode *n, const char *base)
|
||||
{
|
||||
xmlNode *child;
|
||||
|
||||
assert(n->type == XML_ELEMENT_NODE);
|
||||
|
||||
/**
|
||||
* We only need to consider the following cases:
|
||||
*
|
||||
* Attribute: Elements:
|
||||
*
|
||||
* 1) data <object>
|
||||
* 2) href <a> <area> <link>
|
||||
* 3) src <script> <input> <frame> <iframe> <img>
|
||||
* 4) n/a <style>
|
||||
* 5) n/a any <base> tag
|
||||
* 6) background any (except those above)
|
||||
*/
|
||||
if (!n->name) {
|
||||
/* ignore */
|
||||
}
|
||||
/* 1 */
|
||||
else if (strcmp(n->name, "object") == 0) {
|
||||
if (!rewrite_url(n, "data", base))
|
||||
case CONTENT_CSS:
|
||||
strcpy(deftype,"css");
|
||||
break;
|
||||
default:
|
||||
free(fullpath);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
/* 2 */
|
||||
else if (strcmp(n->name, "a") == 0 ||
|
||||
strcmp(n->name, "area") == 0 ||
|
||||
strcmp(n->name, "link") == 0) {
|
||||
if (!rewrite_url(n, "href", base))
|
||||
return false;
|
||||
}
|
||||
/* 3 */
|
||||
else if (strcmp(n->name, "frame") == 0 ||
|
||||
strcmp(n->name, "iframe") == 0 ||
|
||||
strcmp(n->name, "input") == 0 ||
|
||||
strcmp(n->name, "img") == 0 ||
|
||||
strcmp(n->name, "script") == 0) {
|
||||
if (!rewrite_url(n, "src", base))
|
||||
return false;
|
||||
}
|
||||
/* 4 */
|
||||
else if (strcmp(n->name, "style") == 0) {
|
||||
unsigned int len;
|
||||
xmlChar *content;
|
||||
|
||||
for (child = n->children; child != 0; child = child->next) {
|
||||
/* Get current content */
|
||||
content = xmlNodeGetContent(child);
|
||||
if (!content)
|
||||
/* unfortunately we don't know if this is
|
||||
* due to memory exhaustion, or because
|
||||
* there is no content for this node */
|
||||
continue;
|
||||
|
||||
/* Rewrite @import rules */
|
||||
char *rewritten = rewrite_stylesheet_urls(
|
||||
content,
|
||||
strlen((char*)content),
|
||||
&len, base);
|
||||
xmlFree(content);
|
||||
if (!rewritten)
|
||||
return false;
|
||||
|
||||
/* set new content */
|
||||
xmlNodeSetContentLen(child,
|
||||
(const xmlChar*)rewritten,
|
||||
len);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
/* 5 */
|
||||
else if (strcmp(n->name, "base") == 0) {
|
||||
/* simply remove any <base> tags from the document */
|
||||
xmlUnlinkNode(n);
|
||||
xmlFreeNode(n);
|
||||
/* base tags have no content, so there's no point recursing
|
||||
* additionally, we've just destroyed this node, so trying
|
||||
* to recurse would result in bad things happening */
|
||||
return true;
|
||||
}
|
||||
/* 6 */
|
||||
else {
|
||||
if (!rewrite_url(n, "background", base))
|
||||
return false;
|
||||
}
|
||||
|
||||
/* now recurse */
|
||||
for (child = n->children; child;) {
|
||||
/* we must extract the next child now, as if the current
|
||||
* child is a <base> element, it will be removed from the
|
||||
* tree (see 5, above), thus preventing extraction of the
|
||||
* next child */
|
||||
xmlNode *next = child->next;
|
||||
if (child->type == XML_ELEMENT_NODE) {
|
||||
if (!rewrite_urls(child, base))
|
||||
return false;
|
||||
}
|
||||
child = next;
|
||||
}
|
||||
|
||||
|
||||
dobj = GetIconTags(NULL,ICONGETA_GetDefaultName,deftype,
|
||||
ICONGETA_GetDefaultType,WBPROJECT,
|
||||
TAG_DONE);
|
||||
|
||||
PutIconTags(fullpath, dobj,
|
||||
ICONPUTA_NotifyWorkbench, TRUE, TAG_DONE);
|
||||
free(fullpath);
|
||||
if (res != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rewrite an URL in a HTML document.
|
||||
*
|
||||
* \param n The node to modify
|
||||
* \param attr The html attribute to modify
|
||||
* \param base base url of document
|
||||
* \return true on success, false on out of memory
|
||||
*/
|
||||
* wrapper for lib function htmlSaveFileFormat; front sets path from
|
||||
* path + filename in a filesystem-specific way
|
||||
*/
|
||||
|
||||
bool rewrite_url(xmlNode *n, const char *attr, const char *base)
|
||||
int save_complete_htmlSaveFileFormat(const char *path, const char *filename,
|
||||
xmlDocPtr cur, const char *encoding, int format)
|
||||
{
|
||||
char *url, *data;
|
||||
char rel[20];
|
||||
struct content *content;
|
||||
url_func_result res;
|
||||
|
||||
if (!xmlHasProp(n, (const xmlChar *) attr))
|
||||
return true;
|
||||
|
||||
data = xmlGetProp(n, (const xmlChar *) attr);
|
||||
if (!data)
|
||||
return false;
|
||||
|
||||
res = url_join(data, base, &url);
|
||||
xmlFree(data);
|
||||
if (res == URL_FUNC_NOMEM)
|
||||
return false;
|
||||
else if (res == URL_FUNC_OK) {
|
||||
content = save_complete_list_find(url);
|
||||
if (content) {
|
||||
/* found a match */
|
||||
free(url);
|
||||
snprintf(rel, sizeof rel, "%x",
|
||||
(unsigned int) content);
|
||||
if (!xmlSetProp(n, (const xmlChar *) attr,
|
||||
(xmlChar *) rel))
|
||||
return false;
|
||||
} else {
|
||||
/* no match found */
|
||||
if (!xmlSetProp(n, (const xmlChar *) attr,
|
||||
(xmlChar *) url)) {
|
||||
free(url);
|
||||
return false;
|
||||
}
|
||||
free(url);
|
||||
}
|
||||
int ret;
|
||||
int len = strlen(path) + strlen(filename) + 2;
|
||||
struct DiskObject *dobj = NULL;
|
||||
char *fullpath = malloc(len);
|
||||
if (!fullpath){
|
||||
warn_user("NoMemory", 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a content to the save_complete_list.
|
||||
*
|
||||
* \param content content to add
|
||||
* \return true on success, false on out of memory
|
||||
*/
|
||||
|
||||
bool save_complete_list_add(struct content *content)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
entry = malloc(sizeof (*entry));
|
||||
if (!entry)
|
||||
return false;
|
||||
entry->content = content;
|
||||
entry->next = save_complete_list;
|
||||
save_complete_list = entry;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look up a url in the save_complete_list.
|
||||
*
|
||||
* \param url url to find
|
||||
* \return content if found, 0 otherwise
|
||||
*/
|
||||
|
||||
struct content * save_complete_list_find(const char *url)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = save_complete_list; entry; entry = entry->next)
|
||||
if (strcmp(url, entry->content->url) == 0)
|
||||
return entry->content;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Look up a content in the save_complete_list.
|
||||
*
|
||||
* \param content pointer to content
|
||||
* \return true if the content is in the save_complete_list
|
||||
*/
|
||||
|
||||
bool save_complete_list_check(struct content *content)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = save_complete_list; entry; entry = entry->next)
|
||||
if (entry->content == content)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Dump save complete list to stderr
|
||||
*/
|
||||
void save_complete_list_dump(void)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = save_complete_list; entry; entry = entry->next)
|
||||
fprintf(stderr, "%p : %s\n", entry->content,
|
||||
entry->content->url);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* Create the inventory file listing original URLs.
|
||||
*/
|
||||
|
||||
bool save_complete_inventory(const char *path)
|
||||
{
|
||||
char spath[256];
|
||||
FILE *fp;
|
||||
|
||||
snprintf(spath, sizeof spath, "%s/Inventory", path);
|
||||
|
||||
fp = fopen(spath, "w");
|
||||
if (!fp) {
|
||||
LOG(("fopen(): errno = %i", errno));
|
||||
warn_user("SaveError", strerror(errno));
|
||||
return false;
|
||||
}
|
||||
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = save_complete_list; entry; entry = entry->next)
|
||||
fprintf(fp, "%x %s\n",
|
||||
(unsigned int) entry->content,
|
||||
entry->content->url);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return true;
|
||||
snprintf(fullpath, len, "%s/%s", path, filename);
|
||||
ret = htmlSaveFileFormat(fullpath, cur, encoding, format);
|
||||
dobj = GetIconTags(NULL,ICONGETA_GetDefaultName, "html",
|
||||
ICONGETA_GetDefaultType,WBPROJECT,
|
||||
TAG_DONE);
|
||||
|
||||
PutIconTags(fullpath, dobj,
|
||||
ICONPUTA_NotifyWorkbench, TRUE, TAG_DONE);
|
||||
|
||||
free(fullpath);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
803
amiga/search.c
@ -28,6 +28,7 @@
|
||||
#include "content/content.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/search.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "render/box.h"
|
||||
#include "render/html.h"
|
||||
@ -44,10 +45,12 @@
|
||||
#include <proto/string.h>
|
||||
#include <proto/button.h>
|
||||
#include <proto/label.h>
|
||||
#include <proto/checkbox.h>
|
||||
#include <classes/window.h>
|
||||
#include <gadgets/layout.h>
|
||||
#include <gadgets/string.h>
|
||||
#include <gadgets/button.h>
|
||||
#include <gadgets/checkbox.h>
|
||||
#include <images/label.h>
|
||||
#include <reaction/reaction_macros.h>
|
||||
|
||||
@ -68,580 +71,25 @@ struct list_entry {
|
||||
struct list_entry *next;
|
||||
};
|
||||
|
||||
struct gui_window *search_current_window = NULL;
|
||||
static bool search_insert;
|
||||
|
||||
static char *search_string = NULL;
|
||||
static struct list_entry search_head = { 0, 0, NULL, NULL, NULL, NULL, NULL };
|
||||
static struct list_entry *search_found = &search_head;
|
||||
static struct list_entry *search_current = NULL;
|
||||
static struct content *search_content = NULL;
|
||||
static bool search_prev_case_sens = false;
|
||||
static struct find_window *fwin = NULL;
|
||||
#define RECENT_SEARCHES 8
|
||||
bool search_insert;
|
||||
static char *recent_search[RECENT_SEARCHES];
|
||||
|
||||
static void start_search(bool forwards,char *search_string);
|
||||
static void do_search(char *string, int string_len, bool case_sens,
|
||||
bool forwards);
|
||||
static const char *find_pattern(const char *string, int s_len,
|
||||
const char *pattern, int p_len, bool case_sens, int *m_len);
|
||||
static bool find_occurrences_html(const char *pattern, int p_len,
|
||||
struct box *cur, bool case_sens);
|
||||
static bool find_occurrences_text(const char *pattern, int p_len,
|
||||
struct content *c, bool case_sens);
|
||||
static struct list_entry *add_entry(unsigned start_idx, unsigned end_idx);
|
||||
static void free_matches(void);
|
||||
static void show_all(bool all);
|
||||
static void show_status(bool found);
|
||||
|
||||
/**
|
||||
* Begins/continues the search process
|
||||
* Note that this may be called many times for a single search.
|
||||
*
|
||||
* \param forwards search forwards from start/current position
|
||||
*/
|
||||
|
||||
void start_search(bool forwards,char *string)
|
||||
{
|
||||
int string_len;
|
||||
int i = 0;
|
||||
|
||||
string_len = strlen(string);
|
||||
for(i = 0; i < string_len; i++)
|
||||
if (string[i] != '#' && string[i] != '*') break;
|
||||
if (i >= string_len) {
|
||||
free_matches();
|
||||
show_status(true);
|
||||
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_PREV],fwin->win,NULL,
|
||||
GA_Disabled,TRUE,
|
||||
TAG_DONE);
|
||||
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_NEXT],fwin->win,NULL,
|
||||
GA_Disabled,TRUE,
|
||||
TAG_DONE);
|
||||
|
||||
gui_window_set_scroll(search_current_window, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
do_search(string, string_len,
|
||||
false, // case sensitivity
|
||||
forwards);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the search process, invalidating all global state and
|
||||
* freeing the list of found boxes
|
||||
*
|
||||
* \param w the search window handle (not used)
|
||||
*/
|
||||
void ami_gui_search_end(void)
|
||||
{
|
||||
search_current_window = 0;
|
||||
|
||||
if (search_string) {
|
||||
//ro_gui_search_add_recent(search_string);
|
||||
free(search_string);
|
||||
}
|
||||
search_string = 0;
|
||||
|
||||
free_matches();
|
||||
|
||||
search_current = 0;
|
||||
|
||||
search_content = 0;
|
||||
|
||||
search_prev_case_sens = false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Release the memory used by the list of matches,
|
||||
* deleting selection objects too
|
||||
*/
|
||||
|
||||
void free_matches(void)
|
||||
{
|
||||
struct list_entry *a = search_found->next;
|
||||
struct list_entry *b;
|
||||
|
||||
/* empty the list before clearing and deleting the
|
||||
selections because the the clearing updates the
|
||||
screen immediately, causing nested accesses to the list */
|
||||
|
||||
search_found->prev = 0;
|
||||
search_found->next = 0;
|
||||
|
||||
for (; a; a = b) {
|
||||
b = a->next;
|
||||
if (a->sel) {
|
||||
selection_clear(a->sel, true);
|
||||
selection_destroy(a->sel);
|
||||
}
|
||||
free(a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search for a string in the box tree
|
||||
*
|
||||
* \param string the string to search for
|
||||
* \param string_len length of search string
|
||||
* \param case_sens whether to perform a case sensitive search
|
||||
* \param forwards direction to search in
|
||||
*/
|
||||
void do_search(char *string, int string_len, bool case_sens, bool forwards)
|
||||
{
|
||||
struct rect bounds;
|
||||
struct content *c;
|
||||
struct box *box;
|
||||
bool new = false;
|
||||
|
||||
if (!search_current_window)
|
||||
return;
|
||||
|
||||
c = search_current_window->shared->bw->current_content;
|
||||
|
||||
/* only handle html contents */
|
||||
if ((!c) || (c->type != CONTENT_HTML &&
|
||||
c->type != CONTENT_TEXTPLAIN))
|
||||
return;
|
||||
|
||||
box = c->data.html.layout;
|
||||
|
||||
if (!box)
|
||||
return;
|
||||
|
||||
// LOG(("do_search '%s' - '%s' (%p, %p) %p (%d, %d) %d",
|
||||
// search_string, string, search_content, c, search_found->next,
|
||||
// search_prev_case_sens, case_sens, forwards));
|
||||
|
||||
/* check if we need to start a new search or continue an old one */
|
||||
if (!search_string || c != search_content || !search_found->next ||
|
||||
search_prev_case_sens != case_sens ||
|
||||
(case_sens && strcmp(string, search_string) != 0) ||
|
||||
(!case_sens && strcasecmp(string, search_string) != 0)) {
|
||||
bool res;
|
||||
|
||||
if (search_string)
|
||||
free(search_string);
|
||||
search_current = 0;
|
||||
free_matches();
|
||||
|
||||
search_string = malloc(string_len + 1);
|
||||
if (search_string) {
|
||||
memcpy(search_string, string, string_len);
|
||||
search_string[string_len] = '\0';
|
||||
}
|
||||
|
||||
// xhourglass_on();
|
||||
|
||||
if (c->type == CONTENT_HTML)
|
||||
res = find_occurrences_html(string, string_len,
|
||||
box, case_sens);
|
||||
else {
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
res = find_occurrences_text(string, string_len,
|
||||
c, case_sens);
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
free_matches();
|
||||
//xhourglass_off();
|
||||
return;
|
||||
}
|
||||
//xhourglass_off();
|
||||
|
||||
new = true;
|
||||
search_content = c;
|
||||
search_prev_case_sens = case_sens;
|
||||
}
|
||||
|
||||
// LOG(("%d %p %p (%p, %p)", new, search_found->next, search_current, search_current->prev, search_current->next));
|
||||
|
||||
if (new) {
|
||||
/* new search, beginning at the top of the page */
|
||||
search_current = search_found->next;
|
||||
}
|
||||
else if (search_current) {
|
||||
/* continued search in the direction specified */
|
||||
if (forwards) {
|
||||
if (search_current->next)
|
||||
search_current = search_current->next;
|
||||
}
|
||||
else {
|
||||
if (search_current->prev)
|
||||
search_current = search_current->prev;
|
||||
}
|
||||
}
|
||||
|
||||
show_status(search_current != NULL);
|
||||
show_all(false);
|
||||
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_PREV],fwin->win,NULL,
|
||||
GA_Disabled,(!search_current || !search_current->prev),
|
||||
TAG_DONE);
|
||||
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_NEXT],fwin->win,NULL,
|
||||
GA_Disabled,(!search_current || !search_current->next),
|
||||
TAG_DONE);
|
||||
|
||||
if (!search_current)
|
||||
return;
|
||||
|
||||
switch (c->type) {
|
||||
case CONTENT_HTML:
|
||||
/* get box position and jump to it */
|
||||
box_coords(search_current->start_box,
|
||||
&bounds.x0, &bounds.y0);
|
||||
/* \todo: move x0 in by correct idx */
|
||||
box_coords(search_current->end_box,
|
||||
&bounds.x1, &bounds.y1);
|
||||
/* \todo: move x1 in by correct idx */
|
||||
bounds.x1 += search_current->end_box->width;
|
||||
bounds.y1 += search_current->end_box->height;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
textplain_coords_from_range(c,
|
||||
search_current->start_idx,
|
||||
search_current->end_idx, &bounds);
|
||||
break;
|
||||
}
|
||||
|
||||
gui_window_scroll_visible(search_current_window,
|
||||
bounds.x0, bounds.y0, bounds.x1, bounds.y1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find the first occurrence of 'match' in 'string' and return its index
|
||||
*
|
||||
* /param string the string to be searched (unterminated)
|
||||
* /param s_len length of the string to be searched
|
||||
* /param pattern the pattern for which we are searching (unterminated)
|
||||
* /param p_len length of pattern
|
||||
* /param case_sens true iff case sensitive match required
|
||||
* /param m_len accepts length of match in bytes
|
||||
* /return pointer to first match, NULL if none
|
||||
*/
|
||||
|
||||
const char *find_pattern(const char *string, int s_len, const char *pattern,
|
||||
int p_len, bool case_sens, int *m_len)
|
||||
{
|
||||
struct { const char *ss, *s, *p; bool first; } context[16];
|
||||
const char *ep = pattern + p_len;
|
||||
const char *es = string + s_len;
|
||||
const char *p = pattern - 1; /* a virtual '*' before the pattern */
|
||||
const char *ss = string;
|
||||
const char *s = string;
|
||||
bool first = true;
|
||||
int top = 0;
|
||||
|
||||
while (p < ep) {
|
||||
bool matches;
|
||||
if (p < pattern || *p == '*') {
|
||||
char ch;
|
||||
|
||||
/* skip any further asterisks; one is the same as many */
|
||||
do p++; while (p < ep && *p == '*');
|
||||
|
||||
/* if we're at the end of the pattern, yes, it matches */
|
||||
if (p >= ep) break;
|
||||
|
||||
/* anything matches a # so continue matching from
|
||||
here, and stack a context that will try to match
|
||||
the wildcard against the next character */
|
||||
|
||||
ch = *p;
|
||||
if (ch != '#') {
|
||||
/* scan forwards until we find a match for this char */
|
||||
if (!case_sens) ch = toupper(ch);
|
||||
while (s < es) {
|
||||
if (case_sens) {
|
||||
if (*s == ch) break;
|
||||
} else if (toupper(*s) == ch)
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
if (s < es) {
|
||||
/* remember where we are in case the match fails;
|
||||
we can then resume */
|
||||
if (top < (int)NOF_ELEMENTS(context)) {
|
||||
context[top].ss = ss;
|
||||
context[top].s = s + 1;
|
||||
context[top].p = p - 1; /* ptr to last asterisk */
|
||||
context[top].first = first;
|
||||
top++;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
ss = s; /* remember first non-'*' char */
|
||||
first = false;
|
||||
}
|
||||
|
||||
matches = true;
|
||||
}
|
||||
else
|
||||
matches = false;
|
||||
}
|
||||
else if (s < es) {
|
||||
char ch = *p;
|
||||
if (ch == '#')
|
||||
matches = true;
|
||||
else {
|
||||
if (case_sens)
|
||||
matches = (*s == ch);
|
||||
else
|
||||
matches = (toupper(*s) == toupper(ch));
|
||||
}
|
||||
if (matches && first) {
|
||||
ss = s; /* remember first non-'*' char */
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
matches = false;
|
||||
|
||||
if (matches) {
|
||||
p++; s++;
|
||||
}
|
||||
else {
|
||||
/* doesn't match, resume with stacked context if we have one */
|
||||
if (--top < 0) return NULL; /* no match, give up */
|
||||
|
||||
ss = context[top].ss;
|
||||
s = context[top].s;
|
||||
p = context[top].p;
|
||||
first = context[top].first;
|
||||
}
|
||||
}
|
||||
|
||||
/* end of pattern reached */
|
||||
*m_len = max(s - ss, 1);
|
||||
return ss;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds all occurrences of a given string in the html box tree
|
||||
*
|
||||
* \param pattern the string pattern to search for
|
||||
* \param p_len pattern length
|
||||
* \param cur pointer to the current box
|
||||
* \param case_sens whether to perform a case sensitive search
|
||||
* \return true on success, false on memory allocation failure
|
||||
*/
|
||||
bool find_occurrences_html(const char *pattern, int p_len, struct box *cur,
|
||||
bool case_sens)
|
||||
{
|
||||
struct box *a;
|
||||
|
||||
/* ignore this box, if there's no visible text */
|
||||
if (!cur->object && cur->text) {
|
||||
const char *text = cur->text;
|
||||
unsigned length = cur->length;
|
||||
|
||||
while (length > 0) {
|
||||
struct list_entry *entry;
|
||||
unsigned match_length;
|
||||
unsigned match_offset;
|
||||
const char *new_text;
|
||||
const char *pos = find_pattern(text, length,
|
||||
pattern, p_len, case_sens,
|
||||
&match_length);
|
||||
if (!pos) break;
|
||||
|
||||
/* found string in box => add to list */
|
||||
match_offset = pos - cur->text;
|
||||
|
||||
entry = add_entry(cur->byte_offset + match_offset,
|
||||
cur->byte_offset +
|
||||
match_offset +
|
||||
match_length);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
entry->start_box = cur;
|
||||
entry->end_box = cur;
|
||||
|
||||
new_text = pos + match_length;
|
||||
length -= (new_text - text);
|
||||
text = new_text;
|
||||
}
|
||||
}
|
||||
|
||||
/* and recurse */
|
||||
for (a = cur->children; a; a = a->next) {
|
||||
if (!find_occurrences_html(pattern, p_len, a, case_sens))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Finds all occurrences of a given string in a textplain content
|
||||
*
|
||||
* \param pattern the string pattern to search for
|
||||
* \param p_len pattern length
|
||||
* \param c the content to be searched
|
||||
* \param case_sens wheteher to perform a case sensitive search
|
||||
* \return true on success, false on memory allocation failure
|
||||
*/
|
||||
|
||||
bool find_occurrences_text(const char *pattern, int p_len,
|
||||
struct content *c, bool case_sens)
|
||||
{
|
||||
int nlines = textplain_line_count(c);
|
||||
int line;
|
||||
|
||||
for(line = 0; line < nlines; line++) {
|
||||
size_t offset, length;
|
||||
const char *text = textplain_get_line(c, line,
|
||||
&offset, &length);
|
||||
if (text) {
|
||||
while (length > 0) {
|
||||
struct list_entry *entry;
|
||||
unsigned match_length;
|
||||
size_t start_idx;
|
||||
const char *new_text;
|
||||
const char *pos = find_pattern(text, length,
|
||||
pattern, p_len, case_sens,
|
||||
&match_length);
|
||||
if (!pos) break;
|
||||
|
||||
/* found string in line => add to list */
|
||||
start_idx = offset + (pos - text);
|
||||
entry = add_entry(start_idx, start_idx +
|
||||
match_length);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
new_text = pos + match_length;
|
||||
offset += (new_text - text);
|
||||
length -= (new_text - text);
|
||||
text = new_text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add a new entry to the list of matches
|
||||
*
|
||||
* \param start_idx offset of match start within textual representation
|
||||
* \param end_idx offset of match end
|
||||
* \return pointer to added entry, NULL iff failed
|
||||
*/
|
||||
|
||||
struct list_entry *add_entry(unsigned start_idx, unsigned end_idx)
|
||||
{
|
||||
struct list_entry *entry;
|
||||
|
||||
/* found string in box => add to list */
|
||||
entry = calloc(1, sizeof(*entry));
|
||||
if (!entry) {
|
||||
warn_user("NoMemory", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry->start_idx = start_idx;
|
||||
entry->end_idx = end_idx;
|
||||
entry->sel = NULL;
|
||||
|
||||
entry->next = 0;
|
||||
entry->prev = search_found->prev;
|
||||
if (!search_found->prev)
|
||||
search_found->next = entry;
|
||||
else
|
||||
search_found->prev->next = entry;
|
||||
search_found->prev = entry;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines whether any portion of the given text box should be
|
||||
* selected because it matches the current search string.
|
||||
*
|
||||
* \param g gui window
|
||||
* \param start_offset byte offset within text of string to be checked
|
||||
* \param end_offset byte offset within text
|
||||
* \param start_idx byte offset within string of highlight start
|
||||
* \param end_idx byte offset of highlight end
|
||||
* \return true iff part of the box should be highlighted
|
||||
*/
|
||||
|
||||
bool gui_search_term_highlighted(struct gui_window *g,
|
||||
unsigned start_offset, unsigned end_offset,
|
||||
unsigned *start_idx, unsigned *end_idx)
|
||||
{
|
||||
if (g == search_current_window) {
|
||||
struct list_entry *a;
|
||||
for(a = search_found->next; a; a = a->next)
|
||||
if (a->sel && selection_defined(a->sel) &&
|
||||
selection_highlighted(a->sel,
|
||||
start_offset, end_offset,
|
||||
start_idx, end_idx))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies whether all matches or just the current match should
|
||||
* be highlighted in the search text.
|
||||
*/
|
||||
|
||||
void show_all(bool all)
|
||||
{
|
||||
struct list_entry *a;
|
||||
|
||||
for (a = search_found->next; a; a = a->next) {
|
||||
bool add = true;
|
||||
if (!all && a != search_current) {
|
||||
add = false;
|
||||
if (a->sel) {
|
||||
selection_clear(a->sel, true);
|
||||
selection_destroy(a->sel);
|
||||
a->sel = NULL;
|
||||
}
|
||||
}
|
||||
if (add && !a->sel) {
|
||||
a->sel = selection_create(search_current_window->shared->bw);
|
||||
if (a->sel) {
|
||||
struct content *c = search_current_window->shared->bw->current_content;
|
||||
switch (c->type) {
|
||||
case CONTENT_HTML:
|
||||
selection_init(a->sel,
|
||||
c->data.html.layout);
|
||||
break;
|
||||
default:
|
||||
assert(c->type ==
|
||||
CONTENT_TEXTPLAIN);
|
||||
selection_init(a->sel, NULL);
|
||||
break;
|
||||
}
|
||||
selection_set_start(a->sel, a->start_idx);
|
||||
selection_set_end(a->sel, a->end_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
search_flags_t ami_search_flags(void);
|
||||
char *ami_search_string(void);
|
||||
static void ami_search_set_status(bool found, void *p);
|
||||
static void ami_search_set_hourglass(bool active, void *p);
|
||||
static void ami_search_add_recent(const char *string, void *p);
|
||||
static void ami_search_set_forward_state(bool active, void *p);
|
||||
static void ami_search_set_back_state(bool active, void *p);
|
||||
|
||||
static struct search_callbacks ami_search_callbacks = {
|
||||
ami_search_set_forward_state,
|
||||
ami_search_set_back_state,
|
||||
ami_search_set_status,
|
||||
ami_search_set_hourglass,
|
||||
ami_search_add_recent
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
@ -649,15 +97,6 @@ void show_all(bool all)
|
||||
*
|
||||
* \param found search pattern matched in text
|
||||
*/
|
||||
|
||||
void show_status(bool found)
|
||||
{
|
||||
/*
|
||||
ro_gui_set_icon_string(dialog_search, ICON_SEARCH_STATUS,
|
||||
found ? "" : messages_get("NotFound"), true);
|
||||
*/
|
||||
}
|
||||
|
||||
void ami_search_open(struct gui_window *gwin)
|
||||
{
|
||||
struct content *c = gwin->shared->bw->current_content;
|
||||
@ -667,12 +106,18 @@ void ami_search_open(struct gui_window *gwin)
|
||||
c->type != CONTENT_TEXTPLAIN))
|
||||
return;
|
||||
|
||||
search_current_window = gwin;
|
||||
if (gwin->shared->bw->search_context == NULL)
|
||||
search_create_context(gwin->shared->bw,
|
||||
&ami_search_callbacks, NULL);
|
||||
search_insert = true;
|
||||
|
||||
if(fwin)
|
||||
{
|
||||
ami_gui_search_end();
|
||||
if(fwin->gwin->shared->bw->search_context != NULL)
|
||||
search_destroy_context(fwin->gwin->shared->bw->
|
||||
search_context);
|
||||
ami_search_set_forward_state(true, NULL);
|
||||
ami_search_set_back_state(true, NULL);
|
||||
fwin->gwin->shared->searchwin = NULL;
|
||||
fwin->gwin = gwin;
|
||||
gwin->shared->searchwin = fwin;
|
||||
@ -709,6 +154,21 @@ void ami_search_open(struct gui_window *gwin)
|
||||
LabelEnd,
|
||||
*/
|
||||
CHILD_WeightedHeight,0,
|
||||
LAYOUT_AddChild, fwin->gadgets[GID_CASE] = CheckBoxObject,
|
||||
GA_ID,GID_CASE,
|
||||
GA_Text,messages_get("CaseSens"),
|
||||
GA_Selected,FALSE,
|
||||
GA_TabCycle,TRUE,
|
||||
GA_RelVerify,TRUE,
|
||||
CheckBoxEnd,
|
||||
LAYOUT_AddChild, fwin->gadgets[GID_SHOWALL] = CheckBoxObject,
|
||||
GA_ID,GID_SHOWALL,
|
||||
GA_Text,messages_get("ShowAll"),
|
||||
GA_Selected,FALSE,
|
||||
GA_TabCycle,TRUE,
|
||||
GA_RelVerify,TRUE,
|
||||
CheckBoxEnd,
|
||||
|
||||
LAYOUT_AddChild, HGroupObject,
|
||||
LAYOUT_AddChild, fwin->gadgets[GID_PREV] = ButtonObject,
|
||||
GA_ID,GID_PREV,
|
||||
@ -739,7 +199,10 @@ void ami_search_open(struct gui_window *gwin)
|
||||
|
||||
void ami_search_close(void)
|
||||
{
|
||||
ami_gui_search_end();
|
||||
if (fwin->gwin->shared->bw->search_context != NULL)
|
||||
search_destroy_context(fwin->gwin->shared->bw->search_context);
|
||||
ami_search_set_forward_state(true, NULL);
|
||||
ami_search_set_back_state(true, NULL);
|
||||
fwin->gwin->shared->searchwin = NULL;
|
||||
DisposeObject(fwin->objects[OID_MAIN]);
|
||||
DelObject(fwin->node);
|
||||
@ -752,44 +215,158 @@ BOOL ami_search_event(void)
|
||||
ULONG class,result,relevent = 0;
|
||||
ULONG column;
|
||||
uint16 code;
|
||||
char *text;
|
||||
search_flags_t flags;
|
||||
|
||||
while((result = RA_HandleInput(fwin->objects[OID_MAIN],&code)) != WMHI_LASTMSG)
|
||||
{
|
||||
switch(result & WMHI_CLASSMASK) // class
|
||||
{
|
||||
case WMHI_GADGETUP:
|
||||
switch(result & WMHI_GADGETMASK)
|
||||
{
|
||||
case GID_NEXT:
|
||||
search_insert = true;
|
||||
GetAttr(STRINGA_TextVal,fwin->gadgets[GID_SEARCHSTRING],(ULONG *)&text);
|
||||
start_search(true,text);
|
||||
break;
|
||||
|
||||
case GID_PREV:
|
||||
search_insert = true;
|
||||
GetAttr(STRINGA_TextVal,fwin->gadgets[GID_SEARCHSTRING],(ULONG *)&text);
|
||||
start_search(false,text);
|
||||
break;
|
||||
|
||||
case GID_SEARCHSTRING:
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_PREV],fwin->win,NULL,
|
||||
GA_Disabled,FALSE,
|
||||
TAG_DONE);
|
||||
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_NEXT],fwin->win,NULL,
|
||||
GA_Disabled,FALSE,
|
||||
TAG_DONE);
|
||||
break;
|
||||
}
|
||||
{
|
||||
case WMHI_GADGETUP:
|
||||
switch(result & WMHI_GADGETMASK)
|
||||
{
|
||||
case GID_NEXT:
|
||||
search_insert = true;
|
||||
flags = SEARCH_FLAG_FORWARDS |
|
||||
ami_search_flags();
|
||||
if (search_verify_new(
|
||||
search_data.search_window,
|
||||
&ami_search_callbacks, NULL))
|
||||
search_step(fwin->gwin->shared->bw,
|
||||
flags,
|
||||
ami_search_string());
|
||||
break;
|
||||
|
||||
case WMHI_CLOSEWINDOW:
|
||||
ami_search_close();
|
||||
return TRUE;
|
||||
case GID_PREV:
|
||||
search_insert = true;
|
||||
flags = ~SEARCH_FLAG_FORWARDS &
|
||||
ami_search_flags();
|
||||
if (search_verify_new(
|
||||
search_data.search_window,
|
||||
&ami_search_callbacks, NULL))
|
||||
search_step(fwin->gwin->shared->bw,
|
||||
flags,
|
||||
ami_search_string());
|
||||
break;
|
||||
|
||||
case GID_SEARCHSTRING:
|
||||
if (fwin->gwin->shared->
|
||||
bw->search_context
|
||||
!= NULL)
|
||||
search_destroy_context(
|
||||
fwin->gwin->
|
||||
shared->bw->
|
||||
search_context);
|
||||
ami_search_set_forward_state(
|
||||
true, NULL);
|
||||
ami_search_set_back_state(
|
||||
true, NULL);
|
||||
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_PREV],fwin->win,NULL,
|
||||
GA_Disabled,FALSE,
|
||||
TAG_DONE);
|
||||
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_NEXT],fwin->win,NULL,
|
||||
GA_Disabled,FALSE,
|
||||
TAG_DONE);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case WMHI_CLOSEWINDOW:
|
||||
ami_search_close();
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the displayed search status.
|
||||
* \param found search pattern matched in text
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void ami_search_set_status(bool found, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* display hourglass while searching
|
||||
* \param active start/stop indicator
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void ami_search_set_hourglass(bool active, void *p)
|
||||
{
|
||||
SetWindowPointer(fwin->win,
|
||||
WA_BusyPointer,active,
|
||||
WA_PointerDelay,active,
|
||||
TAG_DONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve string being searched for from gui
|
||||
*/
|
||||
|
||||
char *ami_search_string(void)
|
||||
{
|
||||
char *text;
|
||||
GetAttr(STRINGA_TextVal,fwin->gadgets[GID_SEARCHSTRING],(ULONG *)&text);
|
||||
return text;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* add search string to recent searches list
|
||||
* front is at liberty how to implement the bare notification
|
||||
* should normally store a strdup() of the string;
|
||||
* core gives no guarantee of the integrity of the const char *
|
||||
* \param string search pattern
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void ami_search_add_recent(const char *string, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void ami_search_set_forward_state(bool active, void *p)
|
||||
{
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_NEXT],fwin->win,NULL,
|
||||
GA_Disabled, active ? FALSE : TRUE, TAG_DONE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void ami_search_set_back_state(bool active, void *p)
|
||||
{
|
||||
RefreshSetGadgetAttrs(fwin->gadgets[GID_PREV],fwin->win,NULL,
|
||||
GA_Disabled, active ? FALSE : TRUE, TAG_DONE);
|
||||
}
|
||||
|
||||
/**
|
||||
* retrieve state of 'case sensitive', 'show all' checks in gui
|
||||
*/
|
||||
|
||||
search_flags_t ami_search_flags(void)
|
||||
{
|
||||
ULONG case_sensitive, showall;
|
||||
search_flags_t flags;
|
||||
GetAttr(GA_Selected,fwin->gadgets[GID_CASE],(ULONG *)&case_sensitive);
|
||||
GetAttr(GA_Selected,fwin->gadgets[GID_SHOWALL],(ULONG *)&showall);
|
||||
flags = 0 | (case_sensitive ? SEARCH_FLAG_CASE_SENSITIVE : 0) |
|
||||
(showall ? SEARCH_FLAG_SHOWALL : 0);
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -2311,6 +2311,22 @@ void gui_window_stop_throbber(struct gui_window* _g)
|
||||
g->top_view->UnlockLooper();
|
||||
}
|
||||
|
||||
/**
|
||||
* add retrieved favicon to the gui
|
||||
*/
|
||||
void gui_window_set_icon(struct gui_window *g, struct content *icon)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* set gui display of a retrieved favicon representing the search provider
|
||||
* \param ico may be NULL for local calls; then access current cache from
|
||||
* search_web_ico()
|
||||
*/
|
||||
void gui_window_set_search_ico(struct content *ico)
|
||||
{
|
||||
}
|
||||
|
||||
#warning XXX
|
||||
#if 0 /* GTK */
|
||||
gboolean nsbeos_scaffolding_is_busy(nsbeos_scaffolding *scaffold)
|
||||
|
75
beos/beos_search.cpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
#include "utils/log.h"
|
||||
}
|
||||
/* callback functions for search implementation */
|
||||
static void gui_search_set_status(bool found, void *p);
|
||||
static void gui_search_set_hourglass(bool active, void *p);
|
||||
static void gui_search_add_recent(const char *string, void *p);
|
||||
static void gui_search_set_forward_state(bool active, void *p);
|
||||
static void gui_search_set_back_state(bool active, void *p);
|
||||
|
||||
/**
|
||||
* Change the displayed search status.
|
||||
* \param found search pattern matched in text
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_status(bool found, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* display hourglass while searching
|
||||
* \param active start/stop indicator
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_hourglass(bool active, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* add search string to recent searches list
|
||||
* \param string search pattern
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_add_recent(const char *string, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_forward_state(bool active, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_back_state(bool active, void *p)
|
||||
{
|
||||
}
|
@ -155,6 +155,9 @@ static const struct mime_entry mime_map[] = {
|
||||
{"image/svg", CONTENT_SVG},
|
||||
{"image/svg+xml", CONTENT_SVG},
|
||||
#endif
|
||||
#ifdef WITH_BMP
|
||||
{"image/vnd.microsoft.icon", CONTENT_ICO},
|
||||
#endif
|
||||
#ifdef WITH_ARTWORKS
|
||||
{"image/x-artworks", CONTENT_ARTWORKS},
|
||||
#endif
|
||||
|
@ -601,11 +601,11 @@ bool fetch_get_verifiable(struct fetch *fetch)
|
||||
|
||||
void
|
||||
fetch_send_callback(fetch_msg msg, struct fetch *fetch, const void *data,
|
||||
unsigned long size)
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
{
|
||||
/*LOG(("Fetcher sending callback. Fetch %p, fetcher %p data %p size %lu",
|
||||
fetch, fetch->fetcher_handle, data, size)); */
|
||||
fetch->callback(msg, fetch->p, data, size);
|
||||
fetch->callback(msg, fetch->p, data, size, errorcode);
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,6 +40,19 @@ typedef enum {
|
||||
FETCH_CERT_ERR,
|
||||
} fetch_msg;
|
||||
|
||||
typedef enum {
|
||||
FETCH_ERROR_NO_ERROR,
|
||||
FETCH_ERROR_CERT,
|
||||
FETCH_ERROR_AUTHENTICATION,
|
||||
FETCH_ERROR_HTTP_NOT2,
|
||||
FETCH_ERROR_COULDNT_RESOLVE_HOST,
|
||||
FETCH_ERROR_PARTIAL_FILE,
|
||||
FETCH_ERROR_MEMORY,
|
||||
FETCH_ERROR_URL,
|
||||
FETCH_ERROR_ENCODING,
|
||||
FETCH_ERROR_MISC
|
||||
} fetch_error_code;
|
||||
|
||||
struct content;
|
||||
struct fetch;
|
||||
struct form_successful_control;
|
||||
@ -58,7 +71,7 @@ struct ssl_cert_info {
|
||||
extern bool fetch_active;
|
||||
|
||||
typedef void (*fetch_callback)(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
unsigned long size, fetch_error_code errorcode);
|
||||
|
||||
|
||||
void fetch_init(void);
|
||||
@ -105,7 +118,8 @@ bool fetch_add_fetcher(const char *scheme,
|
||||
fetcher_finalise finaliser);
|
||||
|
||||
void fetch_send_callback(fetch_msg msg, struct fetch *fetch,
|
||||
const void *data, unsigned long size);
|
||||
const void *data, unsigned long size,
|
||||
fetch_error_code errorcode);
|
||||
void fetch_remove_from_queues(struct fetch *fetch);
|
||||
void fetch_free(struct fetch *f);
|
||||
void fetch_set_http_code(struct fetch *fetch, long http_code);
|
||||
|
@ -38,6 +38,8 @@
|
||||
#include "content/content.h"
|
||||
#include "content/fetchcache.h"
|
||||
#include "content/fetch.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/searchweb.h"
|
||||
#include "content/urldb.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
@ -49,17 +51,23 @@
|
||||
static char error_page[1000];
|
||||
static regex_t re_content_type;
|
||||
static void fetchcache_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
unsigned long size, fetch_error_code errorcode);
|
||||
static char *fetchcache_parse_type(const char *s, char **params[]);
|
||||
static void fetchcache_parse_header(struct content *c, const char *data,
|
||||
size_t size);
|
||||
static void fetchcache_error_page(struct content *c, const char *error);
|
||||
static void fetchcache_error_page(struct content *c, const char *error,
|
||||
fetch_error_code errorcode);
|
||||
static void fetchcache_search_redirect(struct content *c, const char *error);
|
||||
static void fetchcache_cache_update(struct content *c);
|
||||
static void fetchcache_cache_clone(struct content *c,
|
||||
const struct cache_data *data);
|
||||
static void fetchcache_notmodified(struct content *c, const void *data);
|
||||
static void fetchcache_redirect(struct content *c, const void *data,
|
||||
unsigned long size);
|
||||
static void fetchcache_redirect_common(struct content *c, bool verifiable,
|
||||
const char *url, const char *referer,
|
||||
struct content *parent);
|
||||
|
||||
static void fetchcache_auth(struct content *c, const char *realm);
|
||||
|
||||
|
||||
@ -276,7 +284,8 @@ void fetchcache_go(struct content *content, const char *referer,
|
||||
callback(CONTENT_MSG_ERROR,
|
||||
content, p1, p2, msg_data);
|
||||
} else {
|
||||
fetchcache_error_page(content, error_message);
|
||||
fetchcache_error_page(content, error_message,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -366,7 +375,8 @@ void fetchcache_go(struct content *content, const char *referer,
|
||||
content_broadcast(content, CONTENT_MSG_ERROR,
|
||||
msg_data);
|
||||
} else {
|
||||
fetchcache_error_page(content, error_message);
|
||||
fetchcache_error_page(content, error_message,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@ -405,7 +415,7 @@ void fetchcache_go(struct content *content, const char *referer,
|
||||
*/
|
||||
|
||||
void fetchcache_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size)
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
{
|
||||
bool res;
|
||||
struct content *c = p;
|
||||
@ -506,7 +516,7 @@ void fetchcache_callback(fetch_msg msg, void *p, const void *data,
|
||||
msg_data);
|
||||
} else {
|
||||
content_reset(c);
|
||||
fetchcache_error_page(c, data);
|
||||
fetchcache_error_page(c, data, errorcode);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -721,17 +731,29 @@ void fetchcache_parse_header(struct content *c, const char *data,
|
||||
|
||||
|
||||
/**
|
||||
* Generate an error page.
|
||||
*
|
||||
* Generate an error page. Optionally redirect to web search provider
|
||||
* \param c empty content to generate the page in
|
||||
* \param error message to display
|
||||
*/
|
||||
|
||||
void fetchcache_error_page(struct content *c, const char *error)
|
||||
void fetchcache_error_page(struct content *c, const char *error,
|
||||
fetch_error_code errorcode)
|
||||
{
|
||||
const char *params[] = { 0 };
|
||||
int length;
|
||||
char *host;
|
||||
|
||||
if (option_search_url_bar) {
|
||||
if (url_host(c->url, &host) != URL_FUNC_OK) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
} else if ((strcasecmp(host, search_web_provider_host())
|
||||
!= 0) && (errorcode ==
|
||||
FETCH_ERROR_COULDNT_RESOLVE_HOST)) {
|
||||
fetchcache_search_redirect(c, error);
|
||||
free(host);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((length = snprintf(error_page, sizeof(error_page),
|
||||
messages_get("ErrorPage"), error)) < 0)
|
||||
length = 0;
|
||||
@ -746,6 +768,27 @@ void fetchcache_error_page(struct content *c, const char *error)
|
||||
c->fresh = false;
|
||||
}
|
||||
|
||||
void fetchcache_search_redirect(struct content *c, const char *error)
|
||||
{
|
||||
char *redirurl, *temp;
|
||||
|
||||
/* clear http:// plus trailing / from url, it is already escaped */
|
||||
temp = strdup(c->url + SLEN("http://"));
|
||||
if (temp == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
temp[strlen(temp)-1] = '\0';
|
||||
redirurl = search_web_get_url(temp);
|
||||
if (redirurl == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchcache_redirect_common(c, false, redirurl, NULL, c);
|
||||
free(redirurl);
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a content's cache state
|
||||
@ -930,7 +973,6 @@ void fetchcache_redirect(struct content *c, const void *data,
|
||||
long http_code;
|
||||
const char *ref;
|
||||
struct content *parent;
|
||||
bool can_fetch;
|
||||
bool parent_was_verifiable;
|
||||
union content_msg_data msg_data;
|
||||
url_func_result result;
|
||||
@ -1056,32 +1098,50 @@ void fetchcache_redirect(struct content *c, const void *data,
|
||||
}
|
||||
|
||||
free(scheme);
|
||||
|
||||
/* Determine if we've got a fetch handler for this url */
|
||||
can_fetch = fetch_can_fetch(url);
|
||||
fetchcache_redirect_common(c, parent_was_verifiable, url, referer, parent);
|
||||
free(url);
|
||||
free(referer);
|
||||
}
|
||||
|
||||
/**
|
||||
* common logic from fetchcache_redirect() / fetchcache_search_redirect()
|
||||
* \param c the content param from the original function
|
||||
* \param verifiable parent_was_verifiable [false for search_redirect]
|
||||
* \param url the url being considered; caller retains ownership
|
||||
* \param referer referer [ / NULL particularly for search_redirect]
|
||||
* \param parent parent content [ / c for search_redirect]
|
||||
*/
|
||||
|
||||
void fetchcache_redirect_common(struct content *c, bool verifiable,
|
||||
const char *url, const char *referer, struct content *parent)
|
||||
{
|
||||
union content_msg_data msg_data;
|
||||
bool can_fetch;
|
||||
/* check there's a fetch handler */
|
||||
can_fetch = fetch_can_fetch(url);
|
||||
|
||||
/* Process users of this content */
|
||||
while (c->user_list->next) {
|
||||
intptr_t p1, p2;
|
||||
void (*callback)(content_msg msg,
|
||||
struct content *c, intptr_t p1,
|
||||
intptr_t p2,
|
||||
union content_msg_data data);
|
||||
struct content *c, intptr_t p1,
|
||||
intptr_t p2,
|
||||
union content_msg_data data);
|
||||
struct content *replacement;
|
||||
|
||||
|
||||
p1 = c->user_list->next->p1;
|
||||
p2 = c->user_list->next->p2;
|
||||
callback = c->user_list->next->callback;
|
||||
|
||||
|
||||
/* If we can't fetch this url, attempt to launch it */
|
||||
if (!can_fetch) {
|
||||
msg_data.launch_url = url;
|
||||
callback(CONTENT_MSG_LAUNCH, c, p1, p2, msg_data);
|
||||
}
|
||||
|
||||
|
||||
/* Remove user */
|
||||
content_remove_user(c, callback, p1, p2);
|
||||
|
||||
|
||||
if (can_fetch) {
|
||||
/* Get replacement content -- HTTP GET request */
|
||||
|
||||
@ -1101,37 +1161,29 @@ void fetchcache_redirect(struct content *c, const void *data,
|
||||
*/
|
||||
replacement = fetchcache(url, callback, p1, p2,
|
||||
c->width, c->height, c->no_error_pages,
|
||||
NULL, NULL, parent_was_verifiable,
|
||||
NULL, NULL, verifiable,
|
||||
c->download);
|
||||
if (!replacement) {
|
||||
msg_data.error = messages_get("BadRedirect");
|
||||
content_broadcast(c, CONTENT_MSG_ERROR,
|
||||
msg_data);
|
||||
|
||||
free(url);
|
||||
free(referer);
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
/* Set replacement's redirect count to 1 greater
|
||||
* than ours */
|
||||
replacement->redirect_count = c->redirect_count + 1;
|
||||
|
||||
|
||||
/* Notify user that content has changed */
|
||||
msg_data.new_url = url;
|
||||
callback(CONTENT_MSG_NEWPTR, replacement,
|
||||
p1, p2, msg_data);
|
||||
|
||||
p1, p2, msg_data);
|
||||
|
||||
/* Start fetching the replacement content */
|
||||
fetchcache_go(replacement, referer, callback, p1, p2,
|
||||
c->width, c->height, NULL, NULL,
|
||||
parent_was_verifiable, parent);
|
||||
c->width, c->height, NULL, NULL,
|
||||
verifiable, parent);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
free(url);
|
||||
free(referer);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1218,7 +1270,8 @@ void fetchcache_auth(struct content *c, const char *realm)
|
||||
msg_data.error = error_message;
|
||||
content_broadcast(c, CONTENT_MSG_ERROR, msg_data);
|
||||
} else {
|
||||
fetchcache_error_page(c, error_message);
|
||||
fetchcache_error_page(c, error_message,
|
||||
FETCH_ERROR_URL);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -748,6 +748,7 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
{
|
||||
bool finished = false;
|
||||
bool error = false;
|
||||
fetch_error_code errorcode = FETCH_ERROR_NO_ERROR;
|
||||
bool cert = false;
|
||||
bool abort_fetch;
|
||||
struct curl_fetch_info *f;
|
||||
@ -778,8 +779,10 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
* Content-Length header. */
|
||||
if (!f->had_headers && fetch_curl_process_headers(f))
|
||||
; /* redirect with partial body, or similar */
|
||||
else
|
||||
else {
|
||||
error = true;
|
||||
errorcode = FETCH_ERROR_PARTIAL_FILE;
|
||||
}
|
||||
} else if (result == CURLE_WRITE_ERROR && f->stopped)
|
||||
/* CURLE_WRITE_ERROR occurs when fetch_curl_data
|
||||
* returns 0, which we use to abort intentionally */
|
||||
@ -790,9 +793,14 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
memset(f->cert_data, 0, sizeof(f->cert_data));
|
||||
cert = true;
|
||||
}
|
||||
else if (result == CURLE_COULDNT_RESOLVE_HOST) {
|
||||
error = true;
|
||||
errorcode = FETCH_ERROR_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else {
|
||||
LOG(("Unknown cURL response code %d", result));
|
||||
error = true;
|
||||
errorcode = FETCH_ERROR_MISC;
|
||||
}
|
||||
|
||||
fetch_curl_stop(f);
|
||||
@ -800,7 +808,7 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
if (abort_fetch)
|
||||
; /* fetch was aborted: no callback */
|
||||
else if (finished)
|
||||
fetch_send_callback(FETCH_FINISHED, f->fetch_handle, 0, 0);
|
||||
fetch_send_callback(FETCH_FINISHED, f->fetch_handle, 0, 0, errorcode);
|
||||
else if (cert) {
|
||||
int i;
|
||||
BIO *mem;
|
||||
@ -877,14 +885,14 @@ void fetch_curl_done(CURL *curl_handle, CURLcode result)
|
||||
if (certs[i].cert->references == 0)
|
||||
X509_free(certs[i].cert);
|
||||
}
|
||||
|
||||
errorcode = FETCH_ERROR_CERT;
|
||||
fetch_send_callback(FETCH_CERT_ERR, f->fetch_handle,
|
||||
&ssl_certs, i);
|
||||
&ssl_certs, i, errorcode);
|
||||
|
||||
}
|
||||
else if (error)
|
||||
fetch_send_callback(FETCH_ERROR, f->fetch_handle,
|
||||
fetch_error_buffer, 0);
|
||||
fetch_error_buffer, 0, errorcode);
|
||||
|
||||
fetch_free(f->fetch_handle);
|
||||
}
|
||||
@ -910,14 +918,16 @@ int fetch_curl_progress(void *clientp, double dltotal, double dlnow,
|
||||
human_friendly_bytesize(dlnow),
|
||||
human_friendly_bytesize(dltotal));
|
||||
fetch_send_callback(FETCH_PROGRESS, f->fetch_handle,
|
||||
fetch_progress_buffer,
|
||||
(unsigned long) percent);
|
||||
fetch_progress_buffer,
|
||||
(unsigned long) percent,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
} else {
|
||||
snprintf(fetch_progress_buffer, 255,
|
||||
messages_get("ProgressU"),
|
||||
human_friendly_bytesize(dlnow));
|
||||
fetch_send_callback(FETCH_PROGRESS, f->fetch_handle,
|
||||
fetch_progress_buffer, 0);
|
||||
fetch_progress_buffer, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -977,7 +987,8 @@ size_t fetch_curl_data(char *data, size_t size, size_t nmemb,
|
||||
|
||||
/* send data to the caller */
|
||||
/*LOG(("FETCH_DATA"));*/
|
||||
fetch_send_callback(FETCH_DATA, f->fetch_handle, data, size * nmemb);
|
||||
fetch_send_callback(FETCH_DATA, f->fetch_handle, data, size * nmemb,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
|
||||
if (f->abort) {
|
||||
f->stopped = true;
|
||||
@ -1006,7 +1017,8 @@ size_t fetch_curl_header(char *data, size_t size, size_t nmemb,
|
||||
return 0;
|
||||
}
|
||||
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle, data, size);
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle, data, size,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
|
||||
#define SKIP_ST(o) for (i = (o); i < (int) size && (data[i] == ' ' || data[i] == '\t'); i++)
|
||||
|
||||
@ -1100,20 +1112,23 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
|
||||
if (http_code == 304 && !f->post_urlenc && !f->post_multipart) {
|
||||
/* Not Modified && GET request */
|
||||
fetch_send_callback(FETCH_NOTMODIFIED, f->fetch_handle, 0, 0);
|
||||
fetch_send_callback(FETCH_NOTMODIFIED, f->fetch_handle, 0, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* handle HTTP redirects (3xx response codes) */
|
||||
if (300 <= http_code && http_code < 400 && f->location != 0) {
|
||||
LOG(("FETCH_REDIRECT, '%s'", f->location));
|
||||
fetch_send_callback(FETCH_REDIRECT, f->fetch_handle, f->location, 0);
|
||||
fetch_send_callback(FETCH_REDIRECT, f->fetch_handle,
|
||||
f->location, 0, FETCH_ERROR_NO_ERROR);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* handle HTTP 401 (Authentication errors) */
|
||||
if (http_code == 401) {
|
||||
fetch_send_callback(FETCH_AUTH, f->fetch_handle, f->realm,0);
|
||||
fetch_send_callback(FETCH_AUTH, f->fetch_handle, f->realm,0,
|
||||
FETCH_ERROR_AUTHENTICATION);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1121,7 +1136,8 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
if (f->only_2xx && strncmp(f->url, "http", 4) == 0 &&
|
||||
(http_code < 200 || 299 < http_code)) {
|
||||
fetch_send_callback(FETCH_ERROR, f->fetch_handle,
|
||||
messages_get("Not2xx"), 0);
|
||||
messages_get("Not2xx"), 0,
|
||||
FETCH_ERROR_HTTP_NOT2);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1141,7 +1157,7 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
"ETag: \"%10d\"", (int) s.st_mtime);
|
||||
/* And send it to the header handler */
|
||||
fetch_send_callback(FETCH_HEADER, f->fetch_handle, etag_buf,
|
||||
strlen(etag_buf));
|
||||
strlen(etag_buf), FETCH_ERROR_NO_ERROR);
|
||||
|
||||
/* don't set last modified time so as to ensure that local
|
||||
* files are revalidated at all times. */
|
||||
@ -1151,7 +1167,7 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
f->last_modified > s.st_mtime &&
|
||||
f->file_etag == s.st_mtime) {
|
||||
fetch_send_callback(FETCH_NOTMODIFIED, f->fetch_handle,
|
||||
0, 0);
|
||||
0, 0, FETCH_ERROR_NO_ERROR);
|
||||
curl_free(url_path);
|
||||
return true;
|
||||
}
|
||||
@ -1167,7 +1183,7 @@ bool fetch_curl_process_headers(struct curl_fetch_info *f)
|
||||
curl_free(url_path);
|
||||
|
||||
LOG(("FETCH_TYPE, '%s'", type));
|
||||
fetch_send_callback(FETCH_TYPE, f->fetch_handle, type, f->content_length);
|
||||
fetch_send_callback(FETCH_TYPE, f->fetch_handle, type, f->content_length, FETCH_ERROR_NO_ERROR);
|
||||
if (f->abort)
|
||||
return true;
|
||||
|
||||
|
@ -129,10 +129,10 @@ static void fetch_data_abort(void *ctx)
|
||||
|
||||
static void fetch_data_send_callback(fetch_msg msg,
|
||||
struct fetch_data_context *c, const void *data,
|
||||
unsigned long size)
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
{
|
||||
c->locked = true;
|
||||
fetch_send_callback(msg, c->parent_fetch, data, size);
|
||||
fetch_send_callback(msg, c->parent_fetch, data, size, errorcode);
|
||||
c->locked = false;
|
||||
}
|
||||
|
||||
@ -154,7 +154,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
if (strlen(c->url) < 6) {
|
||||
/* 6 is the minimum possible length (data:,) */
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Malformed data: URL", 0);
|
||||
"Malformed data: URL", 0, FETCH_ERROR_URL);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -164,7 +164,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
/* find the comma */
|
||||
if ( (comma = strchr(params, ',')) == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Malformed data: URL", 0);
|
||||
"Malformed data: URL", 0, FETCH_ERROR_URL);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -179,7 +179,7 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
if (c->mimetype == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to allocate memory for mimetype in data: URL",
|
||||
0);
|
||||
0, FETCH_ERROR_MEMORY);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -198,7 +198,8 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
c->datalen = templen;
|
||||
if (unescaped == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to URL decode data: URL", 0);
|
||||
"Unable to URL decode data: URL", 0,
|
||||
FETCH_ERROR_ENCODING);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -207,7 +208,8 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
if (base64_decode(unescaped, c->datalen, c->data,
|
||||
&(c->datalen)) == false) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to Base64 decode data: URL", 0);
|
||||
"Unable to Base64 decode data: URL", 0,
|
||||
FETCH_ERROR_ENCODING);
|
||||
curl_free(unescaped);
|
||||
return false;
|
||||
}
|
||||
@ -215,7 +217,8 @@ static bool fetch_data_process(struct fetch_data_context *c)
|
||||
c->data = malloc(c->datalen);
|
||||
if (c->data == NULL) {
|
||||
fetch_data_send_callback(FETCH_ERROR, c,
|
||||
"Unable to allocate memory for data: URL", 0);
|
||||
"Unable to allocate memory for data: URL", 0,
|
||||
FETCH_ERROR_MEMORY);
|
||||
curl_free(unescaped);
|
||||
return false;
|
||||
}
|
||||
@ -271,14 +274,17 @@ static void fetch_data_poll(const char *scheme)
|
||||
* call to fetch_data_send_callback().
|
||||
*/
|
||||
fetch_data_send_callback(FETCH_TYPE,
|
||||
c, c->mimetype, c->datalen);
|
||||
c, c->mimetype, c->datalen,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
if (!c->aborted) {
|
||||
fetch_data_send_callback(FETCH_DATA,
|
||||
c, c->data, c->datalen);
|
||||
c, c->data, c->datalen,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
}
|
||||
if (!c->aborted) {
|
||||
fetch_data_send_callback(FETCH_FINISHED,
|
||||
c, &cachedata, 0);
|
||||
c, &cachedata, 0,
|
||||
FETCH_ERROR_NO_ERROR);
|
||||
}
|
||||
} else {
|
||||
LOG(("Processing of %s failed!", c->url));
|
||||
|
@ -87,12 +87,13 @@ static bool browser_window_check_throbber(struct browser_window *bw);
|
||||
static void browser_window_convert_to_download(struct browser_window *bw);
|
||||
static void browser_window_start_throbber(struct browser_window *bw);
|
||||
static void browser_window_stop_throbber(struct browser_window *bw);
|
||||
static void browser_window_set_icon(struct browser_window *bw);
|
||||
static void browser_window_set_status(struct browser_window *bw,
|
||||
const char *text);
|
||||
static void browser_window_set_pointer(struct gui_window *g,
|
||||
gui_pointer_shape shape);
|
||||
static void download_window_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size);
|
||||
unsigned long size, fetch_error_code errorcode);
|
||||
static void browser_window_destroy_children(struct browser_window *bw);
|
||||
static void browser_window_destroy_internal(struct browser_window *bw);
|
||||
static void browser_window_set_scale_internal(struct browser_window *bw,
|
||||
@ -167,6 +168,7 @@ struct browser_window *browser_window_create(const char *url,
|
||||
if (url)
|
||||
browser_window_go(bw, url, referer, history_add);
|
||||
|
||||
|
||||
return bw;
|
||||
}
|
||||
|
||||
@ -418,8 +420,6 @@ void browser_window_callback(content_msg msg, struct content *c,
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
browser_window_refresh_url_bar(bw, c->url, bw->frag_id);
|
||||
|
||||
bw->refresh_interval = -1;
|
||||
browser_window_set_status(bw, c->status_message);
|
||||
}
|
||||
@ -491,6 +491,7 @@ void browser_window_callback(content_msg msg, struct content *c,
|
||||
browser_window_update(bw, false);
|
||||
browser_window_set_status(bw, c->status_message);
|
||||
browser_window_stop_throbber(bw);
|
||||
browser_window_set_icon(bw);
|
||||
history_update(bw->history, c);
|
||||
hotlist_visited(c);
|
||||
free(bw->referer);
|
||||
@ -764,6 +765,21 @@ bool browser_window_check_throbber(struct browser_window *bw)
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* when ready, set icon at top level
|
||||
* \param bw browser_window
|
||||
* current implementation ignores lower-levels' link rels completely
|
||||
*/
|
||||
void browser_window_set_icon(struct browser_window *bw)
|
||||
{
|
||||
while (bw->parent)
|
||||
bw = bw->parent;
|
||||
if ((bw->current_content != NULL) && (bw->current_content->type == CONTENT_HTML))
|
||||
gui_window_set_icon(bw->window,
|
||||
bw->current_content->data.html.favicon);
|
||||
else
|
||||
gui_window_set_icon(bw->window, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redraw browser window, set extent to content, and update title.
|
||||
@ -1298,7 +1314,7 @@ void browser_window_find_target_internal(struct browser_window *bw,
|
||||
*/
|
||||
|
||||
void download_window_callback(fetch_msg msg, void *p, const void *data,
|
||||
unsigned long size)
|
||||
unsigned long size, fetch_error_code errorcode)
|
||||
{
|
||||
struct gui_download_window *download_window = p;
|
||||
|
||||
|
@ -170,6 +170,9 @@ struct browser_window {
|
||||
|
||||
/** Last time a link was followed in this window */
|
||||
unsigned int last_action;
|
||||
|
||||
/** search context for free text search */
|
||||
struct search_context *search_context;
|
||||
|
||||
struct form_control *visible_select_menu;
|
||||
};
|
||||
|
@ -56,8 +56,7 @@ typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET,
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "desktop/browser.h"
|
||||
|
||||
extern struct gui_window *search_current_window;
|
||||
#include "desktop/search.h"
|
||||
|
||||
void gui_init(int argc, char** argv);
|
||||
void gui_init2(int argc, char** argv);
|
||||
@ -67,6 +66,7 @@ void gui_quit(void);
|
||||
|
||||
struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||
struct browser_window *clone, bool new_tab);
|
||||
struct browser_window *gui_window_get_browser_window(struct gui_window *g);
|
||||
void gui_window_destroy(struct gui_window *g);
|
||||
void gui_window_set_title(struct gui_window *g, const char *title);
|
||||
void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1);
|
||||
@ -88,6 +88,8 @@ void gui_window_hide_pointer(struct gui_window *g);
|
||||
void gui_window_set_url(struct gui_window *g, const char *url);
|
||||
void gui_window_start_throbber(struct gui_window *g);
|
||||
void gui_window_stop_throbber(struct gui_window *g);
|
||||
void gui_window_set_icon(struct gui_window *g, struct content *icon);
|
||||
void gui_window_set_search_ico(struct content *ico);
|
||||
void gui_window_place_caret(struct gui_window *g, int x, int y, int height);
|
||||
void gui_window_remove_caret(struct gui_window *g);
|
||||
void gui_window_new_content(struct gui_window *g);
|
||||
@ -125,7 +127,8 @@ void gui_launch_url(const char *url);
|
||||
|
||||
bool gui_search_term_highlighted(struct gui_window *g,
|
||||
unsigned start_offset, unsigned end_offset,
|
||||
unsigned *start_idx, unsigned *end_idx);
|
||||
unsigned *start_idx, unsigned *end_idx,
|
||||
struct search_context *context);
|
||||
|
||||
struct ssl_cert_info;
|
||||
|
||||
|
@ -111,12 +111,16 @@ char *option_ca_bundle = 0;
|
||||
char *option_ca_path = 0;
|
||||
/** Cookie file location */
|
||||
char *option_cookie_file = 0;
|
||||
/** Cookie jar loaction */
|
||||
/** Cookie jar location */
|
||||
char *option_cookie_jar = 0;
|
||||
/** Home page location */
|
||||
char *option_homepage_url = 0;
|
||||
/** search web from url bar */
|
||||
bool option_search_url_bar = false;
|
||||
/** URL completion in url bar */
|
||||
bool option_url_suggestion = true;
|
||||
/** default web search provider */
|
||||
int option_search_provider = 0;
|
||||
/** default x position of new windows */
|
||||
int option_window_x = 0;
|
||||
/** default y position of new windows */
|
||||
@ -231,6 +235,8 @@ struct {
|
||||
{ "cookie_file", OPTION_STRING, &option_cookie_file },
|
||||
{ "cookie_jar", OPTION_STRING, &option_cookie_jar },
|
||||
{ "homepage_url", OPTION_STRING, &option_homepage_url },
|
||||
{ "search_url_bar", OPTION_BOOL, &option_search_url_bar},
|
||||
{ "search_provider", OPTION_INTEGER, &option_search_provider},
|
||||
{ "url_suggestion", OPTION_BOOL, &option_url_suggestion },
|
||||
{ "window_x", OPTION_INTEGER, &option_window_x },
|
||||
{ "window_y", OPTION_INTEGER, &option_window_y },
|
||||
|
@ -70,6 +70,8 @@ extern char *option_ca_path;
|
||||
extern char *option_cookie_file;
|
||||
extern char *option_cookie_jar;
|
||||
extern char *option_homepage_url;
|
||||
extern bool option_search_url_bar;
|
||||
extern int option_search_provider;
|
||||
extern bool option_target_blank;
|
||||
extern bool option_button_2_tab;
|
||||
extern bool option_url_suggestion;
|
||||
|
@ -33,13 +33,11 @@
|
||||
#include <regex.h>
|
||||
#include <libxml/HTMLtree.h>
|
||||
#include <libxml/parserInternals.h>
|
||||
#include "oslib/osfile.h"
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "css/css.h"
|
||||
#include "render/box.h"
|
||||
#include "riscos/gui.h"
|
||||
#include "riscos/save_complete.h"
|
||||
#include "desktop/save_complete.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/url.h"
|
||||
#include "utils/utils.h"
|
||||
@ -52,22 +50,28 @@ struct save_complete_entry {
|
||||
struct save_complete_entry *next; /**< Next entry in list */
|
||||
};
|
||||
|
||||
/** List of urls seen and saved so far. */
|
||||
static struct save_complete_entry *save_complete_list = 0;
|
||||
|
||||
static bool save_complete_html(struct content *c, const char *path,
|
||||
bool index);
|
||||
static bool save_imported_sheets(struct content *c, const char *path);
|
||||
bool index, struct save_complete_entry **list);
|
||||
static bool save_imported_sheets(struct content *c, const char *path,
|
||||
struct save_complete_entry **list);
|
||||
static char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
int *osize, const char *base);
|
||||
static bool rewrite_document_urls(xmlDoc *doc, const char *base);
|
||||
static bool rewrite_urls(xmlNode *n, const char *base);
|
||||
static bool rewrite_url(xmlNode *n, const char *attr, const char *base);
|
||||
static bool save_complete_list_add(struct content *content);
|
||||
static struct content * save_complete_list_find(const char *url);
|
||||
static bool save_complete_list_check(struct content *content);
|
||||
int *osize, const char *base,
|
||||
struct save_complete_entry *list);
|
||||
static bool rewrite_document_urls(xmlDoc *doc, const char *base,
|
||||
struct save_complete_entry *list);
|
||||
static bool rewrite_urls(xmlNode *n, const char *base,
|
||||
struct save_complete_entry *list);
|
||||
static bool rewrite_url(xmlNode *n, const char *attr, const char *base,
|
||||
struct save_complete_entry *list);
|
||||
static bool save_complete_list_add(struct content *content,
|
||||
struct save_complete_entry **list);
|
||||
static struct content * save_complete_list_find(const char *url,
|
||||
struct save_complete_entry *list);
|
||||
static bool save_complete_list_check(struct content *content,
|
||||
struct save_complete_entry *list);
|
||||
/* static void save_complete_list_dump(void); */
|
||||
static bool save_complete_inventory(const char *path);
|
||||
static bool save_complete_inventory(const char *path,
|
||||
struct save_complete_entry *list);
|
||||
|
||||
/**
|
||||
* Save an HTML page with all dependencies.
|
||||
@ -80,17 +84,18 @@ static bool save_complete_inventory(const char *path);
|
||||
bool save_complete(struct content *c, const char *path)
|
||||
{
|
||||
bool result;
|
||||
|
||||
result = save_complete_html(c, path, true);
|
||||
struct save_complete_entry *list = NULL;
|
||||
|
||||
result = save_complete_html(c, path, true, &list);
|
||||
|
||||
if (result)
|
||||
result = save_complete_inventory(path);
|
||||
result = save_complete_inventory(path, list);
|
||||
|
||||
/* free save_complete_list */
|
||||
while (save_complete_list) {
|
||||
struct save_complete_entry *next = save_complete_list->next;
|
||||
free(save_complete_list);
|
||||
save_complete_list = next;
|
||||
while (list) {
|
||||
struct save_complete_entry *next = list->next;
|
||||
free(list);
|
||||
list = next;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -106,19 +111,20 @@ bool save_complete(struct content *c, const char *path)
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
|
||||
bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
bool save_complete_html(struct content *c, const char *path, bool index,
|
||||
struct save_complete_entry **list)
|
||||
{
|
||||
char spath[256];
|
||||
char filename[256];
|
||||
unsigned int i;
|
||||
xmlDocPtr doc;
|
||||
os_error *error;
|
||||
bool res;
|
||||
|
||||
if (c->type != CONTENT_HTML)
|
||||
return false;
|
||||
|
||||
if (save_complete_list_check(c))
|
||||
if (save_complete_list_check(c, *list))
|
||||
return true;
|
||||
|
||||
|
||||
/* save stylesheets, ignoring the base and adblocking sheets */
|
||||
for (i = STYLESHEET_START; i != c->data.html.stylesheet_count; i++) {
|
||||
struct content *css = c->data.html.stylesheets[i].c;
|
||||
@ -128,44 +134,39 @@ bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
|
||||
if (!css)
|
||||
continue;
|
||||
if (save_complete_list_check(css))
|
||||
if (save_complete_list_check(css, *list))
|
||||
continue;
|
||||
|
||||
is_style = (strcmp(css->url, c->data.html.base_url) == 0);
|
||||
|
||||
if (is_style == false) {
|
||||
if (!save_complete_list_add(css)) {
|
||||
if (!save_complete_list_add(css, list)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!save_imported_sheets(css, path))
|
||||
if (!save_imported_sheets(css, path, list))
|
||||
return false;
|
||||
|
||||
if (is_style)
|
||||
continue; /* don't save <style> elements */
|
||||
|
||||
snprintf(spath, sizeof spath, "%s.%x", path,
|
||||
(unsigned int) css);
|
||||
snprintf(filename, sizeof filename, "%p", css);
|
||||
source = rewrite_stylesheet_urls(css->source_data,
|
||||
css->source_size, &source_len, css->url);
|
||||
css->source_size, &source_len, css->url,
|
||||
*list);
|
||||
if (!source) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
error = xosfile_save_stamped(spath, 0xf79,
|
||||
(byte *) source, (byte *) source + source_len);
|
||||
res = save_complete_gui_save(path, filename, source_len,
|
||||
source, CONTENT_CSS);
|
||||
free(source);
|
||||
if (error) {
|
||||
LOG(("xosfile_save_stamped: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
if (res == false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* save objects */
|
||||
for (i = 0; i != c->data.html.object_count; i++) {
|
||||
struct content *obj = c->data.html.object[i].content;
|
||||
@ -173,32 +174,25 @@ bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
/* skip difficult content types */
|
||||
if (!obj || obj->type >= CONTENT_OTHER || !obj->source_data)
|
||||
continue;
|
||||
if (save_complete_list_check(obj))
|
||||
if (save_complete_list_check(obj, *list))
|
||||
continue;
|
||||
|
||||
if (!save_complete_list_add(obj)) {
|
||||
if (!save_complete_list_add(obj, list)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (obj->type == CONTENT_HTML) {
|
||||
if (!save_complete_html(obj, path, false))
|
||||
if (!save_complete_html(obj, path, false, list))
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(spath, sizeof spath, "%s.%x", path,
|
||||
(unsigned int) obj);
|
||||
error = xosfile_save_stamped(spath,
|
||||
ro_content_filetype(obj),
|
||||
(byte *) obj->source_data,
|
||||
(byte *) obj->source_data + obj->source_size);
|
||||
if (error) {
|
||||
LOG(("xosfile_save_stamped: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
snprintf(filename, sizeof filename, "%p", obj);
|
||||
res = save_complete_gui_save(path, filename,
|
||||
obj->source_size, obj->source_data, obj->type);
|
||||
if(res == false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*save_complete_list_dump();*/
|
||||
@ -211,7 +205,7 @@ bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
}
|
||||
|
||||
/* rewrite all urls we know about */
|
||||
if (!rewrite_document_urls(doc, c->data.html.base_url)) {
|
||||
if (!rewrite_document_urls(doc, c->data.html.base_url, *list)) {
|
||||
xmlFreeDoc(doc);
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
@ -219,12 +213,12 @@ bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
|
||||
/* save the html file out last of all */
|
||||
if (index)
|
||||
snprintf(spath, sizeof spath, "%s.index", path);
|
||||
else
|
||||
snprintf(spath, sizeof spath, "%s.%x", path, (unsigned int)c);
|
||||
snprintf(filename, sizeof filename, "index");
|
||||
else
|
||||
snprintf(filename, sizeof filename, "%p", c);
|
||||
|
||||
errno = 0;
|
||||
if (htmlSaveFileFormat(spath, doc, 0, 0) == -1) {
|
||||
if (save_complete_htmlSaveFileFormat(path, filename, doc, 0, 0) == -1) {
|
||||
if (errno)
|
||||
warn_user("SaveError", strerror(errno));
|
||||
else
|
||||
@ -232,18 +226,10 @@ bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
|
||||
error = xosfile_set_type(spath, 0xfaf);
|
||||
if (error) {
|
||||
LOG(("xosfile_set_type: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -256,48 +242,45 @@ bool save_complete_html(struct content *c, const char *path, bool index)
|
||||
* \return true on success, false on error and error reported
|
||||
*/
|
||||
|
||||
bool save_imported_sheets(struct content *c, const char *path)
|
||||
bool save_imported_sheets(struct content *c, const char *path,
|
||||
struct save_complete_entry **list)
|
||||
{
|
||||
char spath[256];
|
||||
char filename[256];
|
||||
unsigned int j;
|
||||
char *source;
|
||||
int source_len;
|
||||
os_error *error;
|
||||
bool res;
|
||||
|
||||
for (j = 0; j != c->data.css.import_count; j++) {
|
||||
struct content *css = c->data.css.imports[j].c;
|
||||
|
||||
if (!css)
|
||||
continue;
|
||||
if (save_complete_list_check(css))
|
||||
if (save_complete_list_check(css, *list))
|
||||
continue;
|
||||
|
||||
if (!save_complete_list_add(css)) {
|
||||
if (!save_complete_list_add(css, list)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!save_imported_sheets(css, path))
|
||||
if (!save_imported_sheets(css, path, list))
|
||||
return false;
|
||||
|
||||
snprintf(spath, sizeof spath, "%s.%x", path,
|
||||
(unsigned int) css);
|
||||
snprintf(filename, sizeof filename, "%p", css);
|
||||
source = rewrite_stylesheet_urls(css->source_data,
|
||||
css->source_size, &source_len, css->url);
|
||||
css->source_size, &source_len, css->url,
|
||||
*list);
|
||||
if (!source) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
error = xosfile_save_stamped(spath, 0xf79,
|
||||
(byte *) source, (byte *) source + source_len);
|
||||
res = save_complete_gui_save(path, filename, source_len,
|
||||
source, CONTENT_CSS);
|
||||
free(source);
|
||||
if (error) {
|
||||
LOG(("xosfile_save_stamped: 0x%x: %s",
|
||||
error->errnum, error->errmess));
|
||||
warn_user("SaveError", error->errmess);
|
||||
if (res == false)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -352,7 +335,8 @@ void save_complete_init(void)
|
||||
*/
|
||||
|
||||
char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
int *osize, const char *base)
|
||||
int *osize, const char *base,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
char *res;
|
||||
const char *url;
|
||||
@ -435,11 +419,11 @@ char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
*osize += match[0].rm_so;
|
||||
|
||||
if (result == URL_FUNC_OK) {
|
||||
content = save_complete_list_find(url);
|
||||
content = save_complete_list_find(url, list);
|
||||
if (content) {
|
||||
/* replace import */
|
||||
snprintf(buf, sizeof buf, "@import '%x'",
|
||||
(unsigned int) content);
|
||||
snprintf(buf, sizeof buf, "@import '%p'",
|
||||
content);
|
||||
memcpy(res + *osize, buf, strlen(buf));
|
||||
*osize += strlen(buf);
|
||||
} else {
|
||||
@ -478,13 +462,14 @@ char * rewrite_stylesheet_urls(const char *source, unsigned int size,
|
||||
* \return true on success, false on out of memory
|
||||
*/
|
||||
|
||||
bool rewrite_document_urls(xmlDoc *doc, const char *base)
|
||||
bool rewrite_document_urls(xmlDoc *doc, const char *base,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
xmlNode *node;
|
||||
|
||||
for (node = doc->children; node; node = node->next)
|
||||
if (node->type == XML_ELEMENT_NODE)
|
||||
if (!rewrite_urls(node, base))
|
||||
if (!rewrite_urls(node, base, list))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@ -501,7 +486,8 @@ bool rewrite_document_urls(xmlDoc *doc, const char *base)
|
||||
* URLs in the tree rooted at element n are rewritten.
|
||||
*/
|
||||
|
||||
bool rewrite_urls(xmlNode *n, const char *base)
|
||||
bool rewrite_urls(xmlNode *n, const char *base,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
xmlNode *child;
|
||||
|
||||
@ -524,14 +510,14 @@ bool rewrite_urls(xmlNode *n, const char *base)
|
||||
}
|
||||
/* 1 */
|
||||
else if (strcmp((const char *) n->name, "object") == 0) {
|
||||
if (!rewrite_url(n, "data", base))
|
||||
if (!rewrite_url(n, "data", base, list))
|
||||
return false;
|
||||
}
|
||||
/* 2 */
|
||||
else if (strcmp((const char *) n->name, "a") == 0 ||
|
||||
strcmp((const char *) n->name, "area") == 0 ||
|
||||
strcmp((const char *) n->name, "link") == 0) {
|
||||
if (!rewrite_url(n, "href", base))
|
||||
if (!rewrite_url(n, "href", base, list))
|
||||
return false;
|
||||
}
|
||||
/* 3 */
|
||||
@ -540,7 +526,7 @@ bool rewrite_urls(xmlNode *n, const char *base)
|
||||
strcmp((const char *) n->name, "input") == 0 ||
|
||||
strcmp((const char *) n->name, "img") == 0 ||
|
||||
strcmp((const char *) n->name, "script") == 0) {
|
||||
if (!rewrite_url(n, "src", base))
|
||||
if (!rewrite_url(n, "src", base, list))
|
||||
return false;
|
||||
}
|
||||
/* 4 */
|
||||
@ -561,7 +547,7 @@ bool rewrite_urls(xmlNode *n, const char *base)
|
||||
char *rewritten = rewrite_stylesheet_urls(
|
||||
(const char *) content,
|
||||
strlen((const char *) content),
|
||||
(int *) &len, base);
|
||||
(int *) &len, base, list);
|
||||
xmlFree(content);
|
||||
if (!rewritten)
|
||||
return false;
|
||||
@ -586,7 +572,7 @@ bool rewrite_urls(xmlNode *n, const char *base)
|
||||
}
|
||||
/* 6 */
|
||||
else {
|
||||
if (!rewrite_url(n, "background", base))
|
||||
if (!rewrite_url(n, "background", base, list))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -598,7 +584,7 @@ bool rewrite_urls(xmlNode *n, const char *base)
|
||||
* next child */
|
||||
xmlNode *next = child->next;
|
||||
if (child->type == XML_ELEMENT_NODE) {
|
||||
if (!rewrite_urls(child, base))
|
||||
if (!rewrite_urls(child, base, list))
|
||||
return false;
|
||||
}
|
||||
child = next;
|
||||
@ -617,7 +603,8 @@ bool rewrite_urls(xmlNode *n, const char *base)
|
||||
* \return true on success, false on out of memory
|
||||
*/
|
||||
|
||||
bool rewrite_url(xmlNode *n, const char *attr, const char *base)
|
||||
bool rewrite_url(xmlNode *n, const char *attr, const char *base,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
char *url, *data;
|
||||
char rel[20];
|
||||
@ -636,12 +623,11 @@ bool rewrite_url(xmlNode *n, const char *attr, const char *base)
|
||||
if (res == URL_FUNC_NOMEM)
|
||||
return false;
|
||||
else if (res == URL_FUNC_OK) {
|
||||
content = save_complete_list_find(url);
|
||||
content = save_complete_list_find(url, list);
|
||||
if (content) {
|
||||
/* found a match */
|
||||
free(url);
|
||||
snprintf(rel, sizeof rel, "%x",
|
||||
(unsigned int) content);
|
||||
snprintf(rel, sizeof rel, "%p", content);
|
||||
if (!xmlSetProp(n, (const xmlChar *) attr,
|
||||
(xmlChar *) rel))
|
||||
return false;
|
||||
@ -667,15 +653,16 @@ bool rewrite_url(xmlNode *n, const char *attr, const char *base)
|
||||
* \return true on success, false on out of memory
|
||||
*/
|
||||
|
||||
bool save_complete_list_add(struct content *content)
|
||||
bool save_complete_list_add(struct content *content,
|
||||
struct save_complete_entry **list)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
entry = malloc(sizeof (*entry));
|
||||
if (!entry)
|
||||
return false;
|
||||
entry->content = content;
|
||||
entry->next = save_complete_list;
|
||||
save_complete_list = entry;
|
||||
entry->next = *list;
|
||||
*list = entry;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -687,10 +674,11 @@ bool save_complete_list_add(struct content *content)
|
||||
* \return content if found, 0 otherwise
|
||||
*/
|
||||
|
||||
struct content * save_complete_list_find(const char *url)
|
||||
struct content * save_complete_list_find(const char *url,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = save_complete_list; entry; entry = entry->next)
|
||||
for (entry = list; entry; entry = entry->next)
|
||||
if (strcmp(url, entry->content->url) == 0)
|
||||
return entry->content;
|
||||
return 0;
|
||||
@ -704,10 +692,11 @@ struct content * save_complete_list_find(const char *url)
|
||||
* \return true if the content is in the save_complete_list
|
||||
*/
|
||||
|
||||
bool save_complete_list_check(struct content *content)
|
||||
bool save_complete_list_check(struct content *content,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = save_complete_list; entry; entry = entry->next)
|
||||
for (entry = list; entry; entry = entry->next)
|
||||
if (entry->content == content)
|
||||
return true;
|
||||
return false;
|
||||
@ -732,14 +721,23 @@ void save_complete_list_dump(void)
|
||||
* Create the inventory file listing original URLs.
|
||||
*/
|
||||
|
||||
bool save_complete_inventory(const char *path)
|
||||
bool save_complete_inventory(const char *path,
|
||||
struct save_complete_entry *list)
|
||||
{
|
||||
char spath[256];
|
||||
char urlpath[256];
|
||||
FILE *fp;
|
||||
char *pathstring, *standardpath = (path[0] == '/') ?
|
||||
(char *)(path + 1) : (char *)path;
|
||||
|
||||
snprintf(spath, sizeof spath, "%s.Inventory", path);
|
||||
|
||||
fp = fopen(spath, "w");
|
||||
snprintf(urlpath, sizeof urlpath, "file:///%s/Inventory",
|
||||
standardpath);
|
||||
pathstring = url_to_path(urlpath);
|
||||
if (pathstring == NULL) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
fp = fopen(pathstring, "w");
|
||||
free(pathstring);
|
||||
if (!fp) {
|
||||
LOG(("fopen(): errno = %i", errno));
|
||||
warn_user("SaveError", strerror(errno));
|
||||
@ -747,10 +745,8 @@ bool save_complete_inventory(const char *path)
|
||||
}
|
||||
|
||||
struct save_complete_entry *entry;
|
||||
for (entry = save_complete_list; entry; entry = entry->next)
|
||||
fprintf(fp, "%x %s\n",
|
||||
(unsigned int) entry->content,
|
||||
entry->content->url);
|
||||
for (entry = list; entry; entry = entry->next)
|
||||
fprintf(fp, "%p %s\n", entry->content, entry->content->url);
|
||||
|
||||
fclose(fp);
|
||||
|
42
desktop/save_complete.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Save HTML document with dependencies (interface).
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_DESKTOP_SAVE_COMPLETE_H_
|
||||
#define _NETSURF_DESKTOP_SAVE_COMPLETE_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <libxml/HTMLtree.h>
|
||||
#include "content/content.h"
|
||||
|
||||
struct content;
|
||||
|
||||
void save_complete_init(void);
|
||||
bool save_complete(struct content *c, const char *path);
|
||||
|
||||
bool save_complete_gui_save(const char *path, const char *filename,
|
||||
size_t len, const char *sourcedata, content_type type);
|
||||
|
||||
int save_complete_htmlSaveFileFormat(const char *path, const char *filename,
|
||||
xmlDocPtr cur, const char *encoding, int format);
|
||||
|
||||
#endif
|
705
desktop/search.c
Normal file
@ -0,0 +1,705 @@
|
||||
/*
|
||||
* Copyright 2004 John M Bell <jmb202@ecs.soton.ac.uk>
|
||||
* Copyright 2005 Adrian Lees <adrianl@users.sourceforge.net>
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* Free text search (core)
|
||||
*/
|
||||
#include "utils/config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "content/content.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/search.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "render/box.h"
|
||||
#include "render/html.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
|
||||
#ifndef NOF_ELEMENTS
|
||||
#define NOF_ELEMENTS(array) (sizeof(array)/sizeof(*(array)))
|
||||
#endif
|
||||
|
||||
|
||||
struct list_entry {
|
||||
unsigned start_idx; /* start position of match */
|
||||
unsigned end_idx; /* end of match */
|
||||
|
||||
struct box *start_box; /* used only for html contents */
|
||||
struct box *end_box;
|
||||
|
||||
struct selection *sel;
|
||||
|
||||
struct list_entry *prev;
|
||||
struct list_entry *next;
|
||||
};
|
||||
|
||||
struct search_context {
|
||||
struct browser_window *bw;
|
||||
struct content *content;
|
||||
char *string;
|
||||
bool prev_case_sens;
|
||||
bool newsearch;
|
||||
bool insert;
|
||||
void *p; /* front-specific data */
|
||||
struct search_callbacks *callbacks;
|
||||
struct list_entry *found;
|
||||
struct list_entry *current; /* first for select all */
|
||||
};
|
||||
|
||||
static void search_text(const char *string, int string_len,
|
||||
struct search_context *context, search_flags_t flags);
|
||||
static const char *find_pattern(const char *string, int s_len,
|
||||
const char *pattern, int p_len, bool case_sens,
|
||||
unsigned int *m_len);
|
||||
static bool find_occurrences_html(const char *pattern, int p_len,
|
||||
struct box *cur, bool case_sens,
|
||||
struct search_context *context);
|
||||
static bool find_occurrences_text(const char *pattern, int p_len,
|
||||
struct content *c, bool case_sens,
|
||||
struct search_context *context);
|
||||
static struct list_entry *add_entry(unsigned start_idx, unsigned end_idx,
|
||||
struct search_context *context);
|
||||
static void free_matches(struct search_context *context);
|
||||
|
||||
|
||||
/**
|
||||
* create a search_context
|
||||
* \param bw the browser_window the search_context is connected to
|
||||
* \param callbacks the callbacks to modify appearance according to results
|
||||
* \param p the pointer to send to the callbacks
|
||||
* \return true for success
|
||||
*/
|
||||
bool search_create_context(struct browser_window *bw,
|
||||
struct search_callbacks *callbacks, void *p)
|
||||
{
|
||||
struct search_context *context = malloc(sizeof(struct search_context));
|
||||
struct list_entry *search_head = malloc(sizeof(struct list_entry));
|
||||
|
||||
if ((context == NULL) || (search_head == NULL)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
if (bw->search_context != NULL)
|
||||
search_destroy_context(bw->search_context);
|
||||
|
||||
search_head->start_idx = 0;
|
||||
search_head->end_idx = 0;
|
||||
search_head->start_box = NULL;
|
||||
search_head->end_box = NULL;
|
||||
search_head->sel = NULL;
|
||||
search_head->prev = NULL;
|
||||
search_head->next = NULL;
|
||||
|
||||
context->found = search_head;
|
||||
context->current = NULL;
|
||||
context->content = NULL;
|
||||
context->string = NULL;
|
||||
context->prev_case_sens = false;
|
||||
context->newsearch = true;
|
||||
context->insert = true;
|
||||
context->bw = bw;
|
||||
context->callbacks = callbacks;
|
||||
context->p = p;
|
||||
|
||||
bw->search_context = context;
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* to simplify calls to search_step(); checks that the browser_window is
|
||||
* non-NULL, creates a new search_context in case of a new search
|
||||
* \param bw the browser_window the search refers to
|
||||
* \param callbacks the callbacks to modify appearance according to results
|
||||
* \param p a pointer returned to the callbacks
|
||||
* \return true for success
|
||||
*/
|
||||
bool search_verify_new(struct browser_window *bw,
|
||||
struct search_callbacks *callbacks, void *p)
|
||||
{
|
||||
if (bw == NULL)
|
||||
return false;
|
||||
if (bw->search_context == NULL)
|
||||
return search_create_context(bw, callbacks, p);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Begins/continues the search process
|
||||
* Note that this may be called many times for a single search.
|
||||
*
|
||||
* \param bw the browser_window to search in
|
||||
* \param flags the flags forward/back etc
|
||||
* \param string the string to match
|
||||
*/
|
||||
|
||||
void search_step(struct search_context *context, search_flags_t flags,
|
||||
const char *string)
|
||||
{
|
||||
int string_len;
|
||||
int i = 0;
|
||||
|
||||
if ((context == NULL) || (context->callbacks == NULL)) {
|
||||
warn_user("SearchError", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (context->callbacks->add_recent != NULL)
|
||||
context->callbacks->add_recent(string, context->p);
|
||||
|
||||
string_len = strlen(string);
|
||||
for(i = 0; i < string_len; i++)
|
||||
if (string[i] != '#' && string[i] != '*') break;
|
||||
if (i >= string_len) {
|
||||
free_matches(context);
|
||||
if (context->callbacks->status != NULL)
|
||||
context->callbacks->status(true, context->p);
|
||||
if (context->callbacks->back_state != NULL)
|
||||
context->callbacks->back_state(false, context->p);
|
||||
if (context->callbacks->forward_state != NULL)
|
||||
context->callbacks->forward_state(false, context->p);
|
||||
gui_window_set_scroll(context->bw->window, 0, 0);
|
||||
return;
|
||||
}
|
||||
search_text(string, string_len, context, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the memory used by the list of matches,
|
||||
* deleting selection objects too
|
||||
*/
|
||||
|
||||
void free_matches(struct search_context *context)
|
||||
{
|
||||
struct list_entry *a = context->found->next;
|
||||
struct list_entry *b;
|
||||
|
||||
/* empty the list before clearing and deleting the
|
||||
selections because the the clearing updates the
|
||||
screen immediately, causing nested accesses to the list */
|
||||
|
||||
context->found->prev = NULL;
|
||||
context->found->next = NULL;
|
||||
|
||||
for (; a; a = b) {
|
||||
b = a->next;
|
||||
if (a->sel) {
|
||||
selection_clear(a->sel, true);
|
||||
selection_destroy(a->sel);
|
||||
}
|
||||
free(a);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for a string in the box tree
|
||||
*
|
||||
* \param string the string to search for
|
||||
* \param string_len length of search string
|
||||
*/
|
||||
void search_text(const char *string, int string_len,
|
||||
struct search_context *context, search_flags_t flags)
|
||||
{
|
||||
struct rect bounds;
|
||||
struct content *c;
|
||||
struct box *box;
|
||||
bool case_sensitive, forwards, showall;
|
||||
|
||||
case_sensitive = ((flags & SEARCH_FLAG_CASE_SENSITIVE) != 0) ?
|
||||
true : false;
|
||||
forwards = ((flags & SEARCH_FLAG_FORWARDS) != 0) ? true : false;
|
||||
showall = ((flags & SEARCH_FLAG_SHOWALL) != 0) ? true : false;
|
||||
|
||||
if (context->bw == NULL)
|
||||
return;
|
||||
c = context->bw->current_content;
|
||||
|
||||
/* only handle html contents */
|
||||
if ((!c) || (c->type != CONTENT_HTML &&
|
||||
c->type != CONTENT_TEXTPLAIN))
|
||||
return;
|
||||
|
||||
box = c->data.html.layout;
|
||||
|
||||
if (!box)
|
||||
return;
|
||||
|
||||
/* LOG(("do_search '%s' - '%s' (%p, %p) %p (%d, %d) %d",
|
||||
search_data.string, string, search_data.content, c, search_data.found->next,
|
||||
search_data.prev_case_sens, case_sens, forwards)); */
|
||||
|
||||
/* check if we need to start a new search or continue an old one */
|
||||
if (context->newsearch) {
|
||||
bool res;
|
||||
|
||||
if (context->string != NULL)
|
||||
free(context->string);
|
||||
context->current = NULL;
|
||||
free_matches(context);
|
||||
|
||||
context->string = malloc(string_len + 1);
|
||||
if (context->string != NULL) {
|
||||
memcpy(context->string, string, string_len);
|
||||
context->string[string_len] = '\0';
|
||||
}
|
||||
|
||||
if ((context->callbacks != NULL) &&
|
||||
(context->callbacks->hourglass != NULL))
|
||||
context->callbacks->hourglass(true, context->p);
|
||||
|
||||
if (c->type == CONTENT_HTML)
|
||||
res = find_occurrences_html(string, string_len,
|
||||
box, case_sensitive, context);
|
||||
else {
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
res = find_occurrences_text(string, string_len,
|
||||
c, case_sensitive, context);
|
||||
}
|
||||
|
||||
if (!res) {
|
||||
free_matches(context);
|
||||
if ((context->callbacks != NULL) &&
|
||||
(context->callbacks->hourglass !=
|
||||
NULL))
|
||||
context->callbacks->hourglass(false,
|
||||
context->p);
|
||||
return;
|
||||
}
|
||||
if ((context->callbacks != NULL) &&
|
||||
(context->callbacks->hourglass != NULL))
|
||||
context->callbacks->hourglass(false, context->p);
|
||||
|
||||
context->content = c;
|
||||
context->prev_case_sens = case_sensitive;
|
||||
/* LOG(("%d %p %p (%p, %p)", new, search_data.found->next, search_data.current,
|
||||
search_data.current->prev, search_data.current->next)); */
|
||||
/* new search, beginning at the top of the page */
|
||||
context->current = context->found->next;
|
||||
context->newsearch = false;
|
||||
}
|
||||
else if (context->current != NULL) {
|
||||
/* continued search in the direction specified */
|
||||
if (forwards) {
|
||||
if (context->current->next)
|
||||
context->current = context->current->next;
|
||||
}
|
||||
else {
|
||||
if (context->current->prev)
|
||||
context->current = context->current->prev;
|
||||
}
|
||||
}
|
||||
|
||||
if (context->callbacks == NULL)
|
||||
return;
|
||||
if (context->callbacks->status != NULL)
|
||||
context->callbacks->status((context->current != NULL),
|
||||
context->p);
|
||||
search_show_all(showall, context);
|
||||
|
||||
if (context->callbacks->back_state != NULL)
|
||||
context->callbacks->back_state((context->current != NULL) &&
|
||||
(context->current->prev != NULL),
|
||||
context->p);
|
||||
if (context->callbacks->forward_state != NULL)
|
||||
context->callbacks->forward_state((context->current != NULL) &&
|
||||
(context->current->next != NULL), context->p);
|
||||
|
||||
if (context->current == NULL)
|
||||
return;
|
||||
|
||||
switch (c->type) {
|
||||
case CONTENT_HTML:
|
||||
/* get box position and jump to it */
|
||||
box_coords(context->current->start_box,
|
||||
&bounds.x0, &bounds.y0);
|
||||
/* \todo: move x0 in by correct idx */
|
||||
box_coords(context->current->end_box,
|
||||
&bounds.x1, &bounds.y1);
|
||||
/* \todo: move x1 in by correct idx */
|
||||
bounds.x1 += context->current->end_box->width;
|
||||
bounds.y1 += context->current->end_box->height;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(c->type == CONTENT_TEXTPLAIN);
|
||||
textplain_coords_from_range(c,
|
||||
context->current->start_idx,
|
||||
context->current->end_idx, &bounds);
|
||||
break;
|
||||
}
|
||||
|
||||
gui_window_scroll_visible(context->bw->window,
|
||||
bounds.x0, bounds.y0, bounds.x1, bounds.y1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the first occurrence of 'match' in 'string' and return its index
|
||||
*
|
||||
* \param string the string to be searched (unterminated)
|
||||
* \param s_len length of the string to be searched
|
||||
* \param pattern the pattern for which we are searching (unterminated)
|
||||
* \param p_len length of pattern
|
||||
* \param case_sens true iff case sensitive match required
|
||||
* \param m_len accepts length of match in bytes
|
||||
* \return pointer to first match, NULL if none
|
||||
*/
|
||||
|
||||
const char *find_pattern(const char *string, int s_len, const char *pattern,
|
||||
int p_len, bool case_sens, unsigned int *m_len)
|
||||
{
|
||||
struct { const char *ss, *s, *p; bool first; } context[16];
|
||||
const char *ep = pattern + p_len;
|
||||
const char *es = string + s_len;
|
||||
const char *p = pattern - 1; /* a virtual '*' before the pattern */
|
||||
const char *ss = string;
|
||||
const char *s = string;
|
||||
bool first = true;
|
||||
int top = 0;
|
||||
|
||||
while (p < ep) {
|
||||
bool matches;
|
||||
if (p < pattern || *p == '*') {
|
||||
char ch;
|
||||
|
||||
/* skip any further asterisks; one is the same as many
|
||||
*/
|
||||
do p++; while (p < ep && *p == '*');
|
||||
|
||||
/* if we're at the end of the pattern, yes, it matches
|
||||
*/
|
||||
if (p >= ep) break;
|
||||
|
||||
/* anything matches a # so continue matching from
|
||||
here, and stack a context that will try to match
|
||||
the wildcard against the next character */
|
||||
|
||||
ch = *p;
|
||||
if (ch != '#') {
|
||||
/* scan forwards until we find a match for
|
||||
this char */
|
||||
if (!case_sens) ch = toupper(ch);
|
||||
while (s < es) {
|
||||
if (case_sens) {
|
||||
if (*s == ch) break;
|
||||
} else if (toupper(*s) == ch)
|
||||
break;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
if (s < es) {
|
||||
/* remember where we are in case the match
|
||||
fails; we may then resume */
|
||||
if (top < (int)NOF_ELEMENTS(context)) {
|
||||
context[top].ss = ss;
|
||||
context[top].s = s + 1;
|
||||
context[top].p = p - 1;
|
||||
/* ptr to last asterisk */
|
||||
context[top].first = first;
|
||||
top++;
|
||||
}
|
||||
|
||||
if (first) {
|
||||
ss = s;
|
||||
/* remember first non-'*' char */
|
||||
first = false;
|
||||
}
|
||||
|
||||
matches = true;
|
||||
}
|
||||
else
|
||||
matches = false;
|
||||
}
|
||||
else if (s < es) {
|
||||
char ch = *p;
|
||||
if (ch == '#')
|
||||
matches = true;
|
||||
else {
|
||||
if (case_sens)
|
||||
matches = (*s == ch);
|
||||
else
|
||||
matches = (toupper(*s) == toupper(ch));
|
||||
}
|
||||
if (matches && first) {
|
||||
ss = s; /* remember first non-'*' char */
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
matches = false;
|
||||
|
||||
if (matches) {
|
||||
p++; s++;
|
||||
}
|
||||
else {
|
||||
/* doesn't match, resume with stacked context if we have one */
|
||||
if (--top < 0) return NULL; /* no match, give up */
|
||||
|
||||
ss = context[top].ss;
|
||||
s = context[top].s;
|
||||
p = context[top].p;
|
||||
first = context[top].first;
|
||||
}
|
||||
}
|
||||
|
||||
/* end of pattern reached */
|
||||
*m_len = max(s - ss, 1);
|
||||
return ss;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all occurrences of a given string in the html box tree
|
||||
*
|
||||
* \param pattern the string pattern to search for
|
||||
* \param p_len pattern length
|
||||
* \param cur pointer to the current box
|
||||
* \param case_sens whether to perform a case sensitive search
|
||||
* \return true on success, false on memory allocation failure
|
||||
*/
|
||||
bool find_occurrences_html(const char *pattern, int p_len, struct box *cur,
|
||||
bool case_sens, struct search_context *context)
|
||||
{
|
||||
struct box *a;
|
||||
|
||||
/* ignore this box, if there's no visible text */
|
||||
if (!cur->object && cur->text) {
|
||||
const char *text = cur->text;
|
||||
unsigned length = cur->length;
|
||||
|
||||
while (length > 0) {
|
||||
struct list_entry *entry;
|
||||
unsigned match_length;
|
||||
unsigned match_offset;
|
||||
const char *new_text;
|
||||
const char *pos = find_pattern(text, length,
|
||||
pattern, p_len, case_sens,
|
||||
&match_length);
|
||||
if (!pos) break;
|
||||
|
||||
/* found string in box => add to list */
|
||||
match_offset = pos - cur->text;
|
||||
|
||||
entry = add_entry(cur->byte_offset + match_offset,
|
||||
cur->byte_offset +
|
||||
match_offset +
|
||||
match_length, context);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
entry->start_box = cur;
|
||||
entry->end_box = cur;
|
||||
|
||||
new_text = pos + match_length;
|
||||
length -= (new_text - text);
|
||||
text = new_text;
|
||||
}
|
||||
}
|
||||
|
||||
/* and recurse */
|
||||
for (a = cur->children; a; a = a->next) {
|
||||
if (!find_occurrences_html(pattern, p_len, a, case_sens,
|
||||
context))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all occurrences of a given string in a textplain content
|
||||
*
|
||||
* \param pattern the string pattern to search for
|
||||
* \param p_len pattern length
|
||||
* \param c the content to be searched
|
||||
* \param case_sens wheteher to perform a case sensitive search
|
||||
* \return true on success, false on memory allocation failure
|
||||
*/
|
||||
|
||||
bool find_occurrences_text(const char *pattern, int p_len,
|
||||
struct content *c, bool case_sens,
|
||||
struct search_context *context)
|
||||
{
|
||||
int nlines = textplain_line_count(c);
|
||||
int line;
|
||||
|
||||
for(line = 0; line < nlines; line++) {
|
||||
size_t offset, length;
|
||||
const char *text = textplain_get_line(c, line,
|
||||
&offset, &length);
|
||||
if (text) {
|
||||
while (length > 0) {
|
||||
struct list_entry *entry;
|
||||
unsigned match_length;
|
||||
size_t start_idx;
|
||||
const char *new_text;
|
||||
const char *pos = find_pattern(text, length,
|
||||
pattern, p_len, case_sens,
|
||||
&match_length);
|
||||
if (!pos) break;
|
||||
|
||||
/* found string in line => add to list */
|
||||
start_idx = offset + (pos - text);
|
||||
entry = add_entry(start_idx, start_idx +
|
||||
match_length, context);
|
||||
if (!entry)
|
||||
return false;
|
||||
|
||||
new_text = pos + match_length;
|
||||
offset += (new_text - text);
|
||||
length -= (new_text - text);
|
||||
text = new_text;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether any portion of the given text box should be
|
||||
* selected because it matches the current search string.
|
||||
*
|
||||
* \param g gui window
|
||||
* \param start_offset byte offset within text of string to be checked
|
||||
* \param end_offset byte offset within text
|
||||
* \param start_idx byte offset within string of highlight start
|
||||
* \param end_idx byte offset of highlight end
|
||||
* \return true iff part of the box should be highlighted
|
||||
*/
|
||||
|
||||
bool gui_search_term_highlighted(struct gui_window *g,
|
||||
unsigned start_offset, unsigned end_offset,
|
||||
unsigned *start_idx, unsigned *end_idx,
|
||||
struct search_context *context)
|
||||
{
|
||||
if (g == context->bw->window) {
|
||||
struct list_entry *a;
|
||||
for(a = context->found->next; a; a = a->next)
|
||||
if (a->sel && selection_defined(a->sel) &&
|
||||
selection_highlighted(a->sel,
|
||||
start_offset, end_offset,
|
||||
start_idx, end_idx))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether all matches or just the current match should
|
||||
* be highlighted in the search text.
|
||||
*/
|
||||
|
||||
void search_show_all(bool all, struct search_context *context)
|
||||
{
|
||||
struct list_entry *a;
|
||||
|
||||
for (a = context->found->next; a; a = a->next) {
|
||||
bool add = true;
|
||||
if (!all && a != context->current) {
|
||||
add = false;
|
||||
if (a->sel) {
|
||||
selection_clear(a->sel, true);
|
||||
selection_destroy(a->sel);
|
||||
a->sel = NULL;
|
||||
}
|
||||
}
|
||||
if (add && !a->sel) {
|
||||
a->sel = selection_create(context->bw);
|
||||
if (a->sel) {
|
||||
struct content *c = context->bw->
|
||||
current_content;
|
||||
switch (c->type) {
|
||||
case CONTENT_HTML:
|
||||
selection_init(a->sel,
|
||||
c->data.html.layout);
|
||||
break;
|
||||
default:
|
||||
assert(c->type ==
|
||||
CONTENT_TEXTPLAIN);
|
||||
selection_init(a->sel, NULL);
|
||||
break;
|
||||
}
|
||||
selection_set_start(a->sel, a->start_idx);
|
||||
selection_set_end(a->sel, a->end_idx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new entry to the list of matches
|
||||
*
|
||||
* \param start_idx offset of match start within textual representation
|
||||
* \param end_idx offset of match end
|
||||
* \return pointer to added entry, NULL iff failed
|
||||
*/
|
||||
|
||||
struct list_entry *add_entry(unsigned start_idx, unsigned end_idx,
|
||||
struct search_context *context)
|
||||
{
|
||||
struct list_entry *entry;
|
||||
|
||||
/* found string in box => add to list */
|
||||
entry = calloc(1, sizeof(*entry));
|
||||
if (!entry) {
|
||||
warn_user("NoMemory", 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
entry->start_idx = start_idx;
|
||||
entry->end_idx = end_idx;
|
||||
entry->sel = NULL;
|
||||
|
||||
entry->next = 0;
|
||||
entry->prev = context->found->prev;
|
||||
if (context->found->prev == NULL)
|
||||
context->found->next = entry;
|
||||
else
|
||||
context->found->prev->next = entry;
|
||||
context->found->prev = entry;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ends the search process, invalidating all state
|
||||
* freeing the list of found boxes
|
||||
*/
|
||||
void search_destroy_context(struct search_context *context)
|
||||
{
|
||||
if (context->bw != NULL)
|
||||
context->bw->search_context = NULL;
|
||||
if ((context->string != NULL) && (context->callbacks != NULL) &&
|
||||
(context->callbacks->add_recent != NULL)) {
|
||||
context->callbacks->add_recent(context->string, context->p);
|
||||
free(context->string);
|
||||
}
|
||||
free_matches(context);
|
||||
free(context);
|
||||
}
|
||||
|
91
desktop/search.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_DESKTOP_SEARCH_H_
|
||||
#define _NETSURF_DESKTOP_SEARCH_H_
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
struct search_context;
|
||||
|
||||
typedef enum {
|
||||
SEARCH_FLAG_CASE_SENSITIVE = (1 << 0),
|
||||
SEARCH_FLAG_FORWARDS = (1 << 1),
|
||||
SEARCH_FLAG_SHOWALL = (1 << 2)
|
||||
} search_flags_t;
|
||||
|
||||
/**
|
||||
* called to clear the context; 'renews' the search too
|
||||
*/
|
||||
void search_destroy_context(struct search_context *context);
|
||||
|
||||
/**
|
||||
* Change the displayed search status.
|
||||
* \param found search pattern matched in text
|
||||
* \param p the pointer sent to search_step() / search_create_context()
|
||||
*/
|
||||
typedef void (*search_status_callback)(bool found, void *p);
|
||||
|
||||
/**
|
||||
* display hourglass while searching
|
||||
* \param active start/stop indicator
|
||||
* \param p the pointer sent to search_step() / search_create_context()
|
||||
*/
|
||||
typedef void (*search_hourglass_callback)(bool active, void *p);
|
||||
|
||||
/**
|
||||
* add search string to recent searches list
|
||||
* front has full liberty how to implement the bare notification;
|
||||
* core gives no guarantee of the integrity of the const char *
|
||||
* \param string search pattern
|
||||
* \param p the pointer sent to search_step() / search_create_context()
|
||||
*/
|
||||
typedef void (*search_add_recent_callback)(const char *string, void *p);
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_step() / search_create_context()
|
||||
*/
|
||||
typedef void (*search_forward_state_callback)(bool active, void *p);
|
||||
|
||||
/**
|
||||
* activate search back button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_step() / search_create_context()
|
||||
*/
|
||||
typedef void (*search_back_state_callback)(bool active, void *p);
|
||||
|
||||
struct search_callbacks {
|
||||
search_forward_state_callback forward_state;
|
||||
search_back_state_callback back_state;
|
||||
search_status_callback status;
|
||||
search_hourglass_callback hourglass;
|
||||
search_add_recent_callback add_recent;
|
||||
};
|
||||
|
||||
bool search_verify_new(struct browser_window *bw,
|
||||
struct search_callbacks *callbacks, void *p);
|
||||
void search_step(struct search_context *context, search_flags_t flags,
|
||||
const char * string);
|
||||
bool search_create_context(struct browser_window *bw,
|
||||
struct search_callbacks *callbacks, void *p);
|
||||
void search_show_all(bool all, struct search_context *context);
|
||||
|
||||
#endif
|
292
desktop/searchweb.c
Normal file
@ -0,0 +1,292 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* web search (core)
|
||||
*/
|
||||
#include "utils/config.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "content/content.h"
|
||||
#include "content/fetchcache.h"
|
||||
#include "content/fetch.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/searchweb.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
static struct search_provider {
|
||||
char *name; /**< readable name such as 'google', 'yahoo', etc */
|
||||
char *hostname; /**< host address such as www.google.com */
|
||||
char *searchstring; /** < such as "www.google.com?search=%s" */
|
||||
char *ico; /** < location of domain's favicon */
|
||||
} current_search_provider;
|
||||
|
||||
static struct content *search_ico = NULL;
|
||||
char *search_engines_file_location;
|
||||
char *search_default_ico_location;
|
||||
|
||||
/**
|
||||
* creates a new browser window according to the search term
|
||||
* \param searchterm such as "my search term"
|
||||
*/
|
||||
|
||||
bool search_web_new_window(struct browser_window *bw, const char *searchterm)
|
||||
{
|
||||
char *encsearchterm;
|
||||
char *url;
|
||||
if (url_escape(searchterm,0, true, NULL, &encsearchterm) !=
|
||||
URL_FUNC_OK)
|
||||
return false;
|
||||
url = search_web_get_url(encsearchterm);
|
||||
free(encsearchterm);
|
||||
browser_window_create(url, bw, NULL, false, true);
|
||||
free(url);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** simplistic way of checking whether an entry from the url bar is an
|
||||
* url / a search; could be improved to properly test terms
|
||||
*/
|
||||
|
||||
bool search_is_url(const char *url)
|
||||
{
|
||||
char *url2, *host;
|
||||
|
||||
if (url_normalize(url, &url2) != URL_FUNC_OK)
|
||||
return false;
|
||||
|
||||
if (url_host(url2, &host) != URL_FUNC_OK)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* caches the details of the current web search provider
|
||||
* \param reference the enum value of the provider
|
||||
* browser init code [as well as changing preferences code] should call
|
||||
* search_web_provider_details(option_search_provider)
|
||||
*/
|
||||
|
||||
void search_web_provider_details(int reference)
|
||||
{
|
||||
char buf[300];
|
||||
int ref = 0;
|
||||
if (search_engines_file_location == NULL)
|
||||
return;
|
||||
FILE *f = fopen(search_engines_file_location, "r");
|
||||
if (f == NULL)
|
||||
return;
|
||||
while (fgets(buf, sizeof(buf), f) != NULL) {
|
||||
if (buf[0] == '\0')
|
||||
continue;
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
if (ref++ == (int)reference)
|
||||
break;
|
||||
}
|
||||
if (current_search_provider.name != NULL)
|
||||
free(current_search_provider.name);
|
||||
current_search_provider.name = strdup(strtok(buf, "|"));
|
||||
if (current_search_provider.hostname != NULL)
|
||||
free(current_search_provider.hostname);
|
||||
current_search_provider.hostname = strdup(strtok(NULL, "|"));
|
||||
if (current_search_provider.searchstring != NULL)
|
||||
free(current_search_provider.searchstring);
|
||||
current_search_provider.searchstring = strdup(strtok(NULL, "|"));
|
||||
if (current_search_provider.ico != NULL)
|
||||
free(current_search_provider.ico);
|
||||
current_search_provider.ico = strdup(strtok(NULL, "|"));
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* escapes a search term then creates the appropriate url from it
|
||||
*/
|
||||
|
||||
char *search_web_from_term(const char *searchterm)
|
||||
{
|
||||
char *encsearchterm, *url;
|
||||
if (url_escape(searchterm, 0, true, NULL, &encsearchterm)
|
||||
!= URL_FUNC_OK)
|
||||
return strdup(searchterm);
|
||||
url = search_web_get_url(encsearchterm);
|
||||
free(encsearchterm);
|
||||
return url;
|
||||
}
|
||||
|
||||
/** accessor for global search provider name */
|
||||
|
||||
char *search_web_provider_name(void)
|
||||
{
|
||||
if (current_search_provider.name)
|
||||
return strdup(current_search_provider.name);
|
||||
return strdup("google");
|
||||
}
|
||||
|
||||
/** accessor for global search provider hostname */
|
||||
|
||||
char *search_web_provider_host(void)
|
||||
{
|
||||
if (current_search_provider.hostname)
|
||||
return strdup(current_search_provider.hostname);
|
||||
return strdup("www.google.com");
|
||||
}
|
||||
|
||||
/** accessor for global search provider ico name */
|
||||
|
||||
char *search_web_ico_name(void)
|
||||
{
|
||||
if (current_search_provider.ico)
|
||||
return strdup(current_search_provider.ico);
|
||||
return strdup("http://www.google.com/favicon.ico");
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a full url from an encoded search term
|
||||
*/
|
||||
|
||||
char *search_web_get_url(const char *encsearchterm)
|
||||
{
|
||||
char *pref, *ret;
|
||||
int len;
|
||||
if (current_search_provider.searchstring)
|
||||
pref = strdup(current_search_provider.searchstring);
|
||||
else
|
||||
pref = strdup("http://www.google.com/search?q=%s");
|
||||
if (pref == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
len = strlen(encsearchterm) + strlen(pref);
|
||||
ret = malloc(len -1); /* + '\0' - "%s" */
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(pref);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(ret, len-1, pref, encsearchterm);
|
||||
free(pref);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* function to retrieve the search web ico, from cache / from local
|
||||
* filesystem / from the web
|
||||
* \param localdefault true when there is no appropriate favicon
|
||||
* update the search_ico cache else delay until fetcher callback
|
||||
*/
|
||||
|
||||
void search_web_retrieve_ico(bool localdefault)
|
||||
{
|
||||
char *url;
|
||||
if (localdefault) {
|
||||
if (search_default_ico_location == NULL)
|
||||
return;
|
||||
url = malloc(SLEN("file://") + strlen(
|
||||
search_default_ico_location) + 1);
|
||||
if (url == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
strcpy(url, "file://");
|
||||
strcat(url, search_default_ico_location);
|
||||
} else {
|
||||
url = search_web_ico_name();
|
||||
}
|
||||
|
||||
struct content *icocontent = NULL;
|
||||
if (url == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
icocontent = fetchcache(url, search_web_ico_callback,
|
||||
0, 0, 20, 20, true, 0,
|
||||
0, false, false);
|
||||
free(url);
|
||||
if (icocontent == NULL)
|
||||
return;
|
||||
|
||||
fetchcache_go(icocontent, 0, search_web_ico_callback,
|
||||
0, 0, 20, 20,
|
||||
0, 0, false, 0);
|
||||
|
||||
if (icocontent == NULL)
|
||||
LOG(("web search ico loading delayed"));
|
||||
else
|
||||
search_ico = icocontent;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a reference to the static global search_ico [ / NULL]
|
||||
* caller may adjust ico's settings; clearing / free()ing is the core's
|
||||
* responsibility
|
||||
*/
|
||||
|
||||
struct content *search_web_ico(void)
|
||||
{
|
||||
return search_ico;
|
||||
}
|
||||
|
||||
/**
|
||||
* callback function to cache ico then notify front when successful
|
||||
* else retry default from local file system
|
||||
*/
|
||||
|
||||
void search_web_ico_callback(content_msg msg, struct content *ico,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data)
|
||||
{
|
||||
|
||||
switch (msg) {
|
||||
case CONTENT_MSG_LOADING:
|
||||
case CONTENT_MSG_READY:
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_DONE:
|
||||
LOG(("got favicon '%s'", ico->url));
|
||||
if (ico->type == CONTENT_ICO) {
|
||||
search_ico = ico; /* cache */
|
||||
gui_window_set_search_ico(search_ico);
|
||||
} else {
|
||||
search_web_retrieve_ico(true);
|
||||
}
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_LAUNCH:
|
||||
case CONTENT_MSG_ERROR:
|
||||
LOG(("favicon %s error: %s", ico->url, data.error));
|
||||
ico = 0;
|
||||
search_web_retrieve_ico(true);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_STATUS:
|
||||
case CONTENT_MSG_NEWPTR:
|
||||
case CONTENT_MSG_AUTH:
|
||||
case CONTENT_MSG_SSL:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
79
desktop/searchweb.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_DESKTOP_SEARCH_WEB_H_
|
||||
#define _NETSURF_DESKTOP_SEARCH_WEB_H_
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "content/content.h"
|
||||
#include "desktop/browser.h"
|
||||
|
||||
extern char *search_engines_file_location;
|
||||
extern char *search_default_ico_location;
|
||||
|
||||
/**
|
||||
* open new tab/window for web search term
|
||||
*/
|
||||
bool search_web_new_window(struct browser_window *bw, const char *searchterm);
|
||||
|
||||
/**
|
||||
* retrieve full search url from unencoded search term
|
||||
*/
|
||||
char *search_web_from_term(const char *searchterm);
|
||||
|
||||
/**
|
||||
* retrieve full search url from encoded web search term
|
||||
*/
|
||||
char *search_web_get_url(const char *encsearchterm);
|
||||
|
||||
/**
|
||||
* cache details of web search provider from file
|
||||
*/
|
||||
void search_web_provider_details(int reference);
|
||||
|
||||
/**
|
||||
* retrieve name of web search provider
|
||||
*/
|
||||
char *search_web_provider_name(void);
|
||||
|
||||
/**
|
||||
* retrieve hostname of web search provider
|
||||
*/
|
||||
char *search_web_provider_host(void);
|
||||
|
||||
/**
|
||||
* retrieve name of .ico for search bar
|
||||
*/
|
||||
char *search_web_ico_name(void);
|
||||
|
||||
/**
|
||||
* check whether an URL is in fact a search term
|
||||
* \param url the url being checked
|
||||
* \return true for url, false for search
|
||||
*/
|
||||
bool search_is_url(const char *url);
|
||||
|
||||
void search_web_retrieve_ico(bool localdefault);
|
||||
|
||||
struct content *search_web_ico(void);
|
||||
|
||||
void search_web_ico_callback(content_msg msg, struct content *ico,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data);
|
||||
|
||||
#endif
|
74
framebuffer/fb_search.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils/log.h"
|
||||
|
||||
/* callback functions for search implementation */
|
||||
static void gui_search_set_status(bool found, void *p);
|
||||
static void gui_search_set_hourglass(bool active, void *p);
|
||||
static void gui_search_add_recent(const char *string, void *p);
|
||||
static void gui_search_set_forward_state(bool active, void *p);
|
||||
static void gui_search_set_back_state(bool active, void *p);
|
||||
|
||||
/**
|
||||
* Change the displayed search status.
|
||||
* \param found search pattern matched in text
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_status(bool found, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* display hourglass while searching
|
||||
* \param active start/stop indicator
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_hourglass(bool active, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* add search string to recent searches list
|
||||
* \param string search pattern
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_add_recent(const char *string, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_forward_state(bool active, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
void gui_search_set_back_state(bool active, void *p)
|
||||
{
|
||||
}
|
@ -30,8 +30,9 @@ static const gchar *authors[] = {
|
||||
"Matthew Hambley", "Rob Jackson", "Jeffrey Lee", "Phil Mellor",
|
||||
"Philip Pemberton", "Darren Salt", "Andrew Timmins",
|
||||
"John Tytgat", "Chris Williams",
|
||||
"\nGoogle Summer of Code Contributors:", "Adam Blokus",
|
||||
"Sean Fox", "Michael Lester", "Andrew Sidwell", NULL
|
||||
"\nGoogle Summer of Code Contributors:", "Mark Benjamin",
|
||||
"Adam Blokus", "Paul Blokus", "Sean Fox",
|
||||
"Michael Lester", "Andrew Sidwell", "Bo Yang", NULL
|
||||
};
|
||||
|
||||
static const gchar *translators = "Sebastian Barthel\nBruno D'Arcangeli\n"
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
|
||||
* Copyright 2008 Mike Lester <element3260@gmail.com>
|
||||
* Copyright 2009 Daniel Silverstone <dsilvers@netsurf-browser.org>
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
@ -27,17 +28,20 @@
|
||||
#include <glade/glade.h>
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/print.h"
|
||||
#include "desktop/searchweb.h"
|
||||
#include "gtk/options.h"
|
||||
#include "gtk/gtk_gui.h"
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
#include "gtk/gtk_theme.h"
|
||||
#include "gtk/dialogs/gtk_options.h"
|
||||
#include "gtk/gtk_window.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/utils.h"
|
||||
#include "utils/messages.h"
|
||||
|
||||
GtkDialog *wndPreferences;
|
||||
GtkDialog *wndPreferences = NULL;
|
||||
static GladeXML *gladeFile;
|
||||
static gchar *glade_location;
|
||||
|
||||
static struct browser_window *current_browser;
|
||||
|
||||
static int proxy_type;
|
||||
@ -45,6 +49,7 @@ static float animation_delay;
|
||||
|
||||
static void dialog_response_handler (GtkDialog *dlg, gint res_id);
|
||||
static gboolean on_dialog_close (GtkDialog *dlg, gboolean stay_alive);
|
||||
static void nsgtk_options_theme_combo(void);
|
||||
|
||||
/* Declares both widget and callback */
|
||||
#define DECLARE(x) \
|
||||
@ -97,6 +102,12 @@ DECLARE(checkRequestOverwrite);
|
||||
DECLARE(fileChooserDownloads);
|
||||
DECLARE(checkFocusNew);
|
||||
DECLARE(checkNewBlank);
|
||||
DECLARE(checkUrlSearch);
|
||||
DECLARE(comboSearch);
|
||||
DECLARE(combotheme);
|
||||
DECLARE(buttonaddtheme);
|
||||
DECLARE(sourceButtonTab);
|
||||
static GtkWidget *sourceButtonWindow;
|
||||
|
||||
DECLARE(spinMarginTop);
|
||||
DECLARE(spinMarginBottom);
|
||||
@ -125,7 +136,9 @@ DECLARE(setDefaultExportOptions);
|
||||
|
||||
GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent)
|
||||
{
|
||||
glade_location = g_strconcat(res_dir_location, "options.glade", NULL);
|
||||
char glade_location[strlen(res_dir_location) + SLEN("options.glade")
|
||||
+ 1];
|
||||
sprintf(glade_location, "%soptions.glade", res_dir_location);
|
||||
LOG(("Using '%s' as Glade template file", glade_location));
|
||||
gladeFile = glade_xml_new(glade_location, NULL, NULL);
|
||||
|
||||
@ -133,7 +146,13 @@ GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent)
|
||||
wndPreferences = GTK_DIALOG(glade_xml_get_widget(gladeFile,
|
||||
"dlgPreferences"));
|
||||
gtk_window_set_transient_for (GTK_WINDOW(wndPreferences), parent);
|
||||
|
||||
|
||||
FIND_WIDGET(sourceButtonTab);
|
||||
FIND_WIDGET(sourceButtonWindow);
|
||||
GSList *group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(
|
||||
sourceButtonWindow));
|
||||
gtk_radio_button_set_group(GTK_RADIO_BUTTON(sourceButtonTab), group);
|
||||
|
||||
/* set the widgets to reflect the current options */
|
||||
nsgtk_options_load();
|
||||
|
||||
@ -188,6 +207,12 @@ GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent)
|
||||
|
||||
CONNECT(checkFocusNew, "toggled");
|
||||
CONNECT(checkNewBlank, "toggled");
|
||||
CONNECT(checkUrlSearch, "toggled");
|
||||
CONNECT(comboSearch, "changed");
|
||||
|
||||
CONNECT(combotheme, "changed");
|
||||
CONNECT(buttonaddtheme, "clicked");
|
||||
CONNECT(sourceButtonTab, "toggled");
|
||||
|
||||
CONNECT(spinMarginTop, "value-changed");
|
||||
CONNECT(spinMarginBottom, "value-changed");
|
||||
@ -247,11 +272,11 @@ GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent)
|
||||
(value)); \
|
||||
} while (0)
|
||||
|
||||
#define SET_FILE_CHOOSER(widgt, value) \
|
||||
#define SET_FILE_CHOOSER(widget, value) \
|
||||
do { \
|
||||
(widgt) = glade_xml_get_widget(gladeFile, #widgt); \
|
||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER((widgt)), \
|
||||
(value)); \
|
||||
(widget) = glade_xml_get_widget(gladeFile, #widget); \
|
||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(\
|
||||
(widget)), (value)); \
|
||||
} while (0)
|
||||
|
||||
#define SET_BUTTON(widget) \
|
||||
@ -262,22 +287,21 @@ GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent)
|
||||
|
||||
void nsgtk_options_load(void)
|
||||
{
|
||||
GtkVBox *combolanguagevbox;
|
||||
gchar *languagefile;
|
||||
GtkBox *box;
|
||||
char languagefile[strlen(res_dir_location) + SLEN("languages") + 1];
|
||||
const char *default_accept_language =
|
||||
option_accept_language ? option_accept_language : "en";
|
||||
int combo_row_count = 0;
|
||||
int active_language = 0;
|
||||
int proxytype = 0;
|
||||
FILE *fp;
|
||||
char buf[20];
|
||||
char buf[50];
|
||||
|
||||
/* Create combobox */
|
||||
combolanguagevbox =
|
||||
GTK_VBOX(glade_xml_get_widget(gladeFile, "combolanguagevbox"));
|
||||
box = GTK_BOX(glade_xml_get_widget(gladeFile, "combolanguagevbox"));
|
||||
comboLanguage = gtk_combo_box_new_text();
|
||||
|
||||
languagefile = g_strconcat(res_dir_location, "languages", NULL);
|
||||
sprintf(languagefile, "%slanguages", res_dir_location);
|
||||
|
||||
/* Populate combobox from languages file */
|
||||
fp = fopen((const char *) languagefile, "r");
|
||||
@ -309,10 +333,11 @@ void nsgtk_options_load(void)
|
||||
/** \todo localisation */
|
||||
gtk_widget_set_tooltip_text(GTK_WIDGET(comboLanguage),
|
||||
"set preferred language for web pages");
|
||||
gtk_box_pack_start(GTK_BOX(combolanguagevbox),
|
||||
comboLanguage, FALSE, FALSE, 0);
|
||||
gtk_box_pack_start(box, comboLanguage, FALSE, FALSE, 0);
|
||||
gtk_widget_show(comboLanguage);
|
||||
|
||||
|
||||
nsgtk_options_theme_combo();
|
||||
|
||||
SET_ENTRY(entryHomePageURL,
|
||||
option_homepage_url ? option_homepage_url : "");
|
||||
SET_BUTTON(setCurrentPage);
|
||||
@ -380,7 +405,12 @@ void nsgtk_options_load(void)
|
||||
|
||||
SET_CHECK(checkFocusNew, option_focus_new);
|
||||
SET_CHECK(checkNewBlank, option_new_blank);
|
||||
SET_CHECK(checkUrlSearch, option_search_url_bar);
|
||||
SET_COMBO(comboSearch, option_search_provider);
|
||||
|
||||
SET_BUTTON(buttonaddtheme);
|
||||
SET_CHECK(sourceButtonTab, option_source_tab);
|
||||
|
||||
SET_SPIN(spinMarginTop, option_margin_top);
|
||||
SET_SPIN(spinMarginBottom, option_margin_bottom);
|
||||
SET_SPIN(spinMarginLeft, option_margin_left);
|
||||
@ -417,6 +447,48 @@ static gboolean on_dialog_close (GtkDialog *dlg, gboolean stay_alive)
|
||||
}
|
||||
return stay_alive;
|
||||
}
|
||||
|
||||
static void nsgtk_options_theme_combo(void) {
|
||||
/* populate theme combo from themelist file */
|
||||
GtkBox *box = GTK_BOX(glade_xml_get_widget(gladeFile, "themehbox"));
|
||||
char buf[50];
|
||||
combotheme = gtk_combo_box_new_text();
|
||||
size_t len = SLEN("themelist") + strlen(res_dir_location) + 1;
|
||||
char themefile[len];
|
||||
if ((combotheme == NULL) || (box == NULL)) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
snprintf(themefile, len, "%sthemelist", res_dir_location);
|
||||
FILE *fp = fopen((const char *)themefile, "r");
|
||||
if (fp == NULL) {
|
||||
LOG(("Failed opening themes file"));
|
||||
warn_user("FileError", (const char *) themefile);
|
||||
return;
|
||||
}
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
/* Ignore blank lines */
|
||||
if (buf[0] == '\0')
|
||||
continue;
|
||||
|
||||
/* Remove trailing \n */
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(combotheme), buf);
|
||||
}
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(combotheme),
|
||||
option_current_theme);
|
||||
gtk_box_pack_start(box, combotheme, FALSE, TRUE, 0);
|
||||
gtk_widget_show(combotheme);
|
||||
}
|
||||
|
||||
bool nsgtk_options_combo_theme_add(const char *themename)
|
||||
{
|
||||
if (wndPreferences == NULL)
|
||||
return false;
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(combotheme), themename);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Defines the callback functions for all widgets and specifies
|
||||
@ -642,42 +714,44 @@ BUTTON_CLICKED(fontPreview)
|
||||
END_HANDLER
|
||||
|
||||
COMBO_CHANGED(comboButtonType, option_button_type)
|
||||
struct gui_window *current = window_list;
|
||||
|
||||
nsgtk_scaffolding *current = scaf_list;
|
||||
option_button_type++;
|
||||
/* value of 0 is reserved for 'unset' */
|
||||
while (current) {
|
||||
nsgtk_scaffolding_reset_offset(current);
|
||||
switch(option_button_type) {
|
||||
case 0:
|
||||
gtk_toolbar_set_style(
|
||||
GTK_TOOLBAR(current->scaffold->tool_bar),
|
||||
GTK_TOOLBAR_ICONS);
|
||||
gtk_toolbar_set_icon_size(
|
||||
GTK_TOOLBAR(current->scaffold->tool_bar),
|
||||
GTK_ICON_SIZE_SMALL_TOOLBAR);
|
||||
break;
|
||||
case 1:
|
||||
gtk_toolbar_set_style(
|
||||
GTK_TOOLBAR(current->scaffold->tool_bar),
|
||||
GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)),
|
||||
GTK_TOOLBAR_ICONS);
|
||||
gtk_toolbar_set_icon_size(
|
||||
GTK_TOOLBAR(current->scaffold->tool_bar),
|
||||
GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||
GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)),
|
||||
GTK_ICON_SIZE_SMALL_TOOLBAR);
|
||||
break;
|
||||
case 2:
|
||||
gtk_toolbar_set_style(
|
||||
GTK_TOOLBAR(current->scaffold->tool_bar),
|
||||
GTK_TOOLBAR_BOTH);
|
||||
GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)),
|
||||
GTK_TOOLBAR_ICONS);
|
||||
gtk_toolbar_set_icon_size(
|
||||
GTK_TOOLBAR(current->scaffold->tool_bar),
|
||||
GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)),
|
||||
GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||
break;
|
||||
case 3:
|
||||
gtk_toolbar_set_style(
|
||||
GTK_TOOLBAR(current->scaffold->tool_bar),
|
||||
GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)),
|
||||
GTK_TOOLBAR_BOTH);
|
||||
gtk_toolbar_set_icon_size(
|
||||
GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)),
|
||||
GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||
break;
|
||||
case 4:
|
||||
gtk_toolbar_set_style(
|
||||
GTK_TOOLBAR(nsgtk_scaffolding_toolbar(current)),
|
||||
GTK_TOOLBAR_TEXT);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
current = current->next;
|
||||
current = nsgtk_scaffolding_iterate(current);
|
||||
}
|
||||
END_HANDLER
|
||||
|
||||
@ -703,6 +777,114 @@ END_HANDLER
|
||||
CHECK_CHANGED(checkNewBlank, option_new_blank)
|
||||
END_HANDLER
|
||||
|
||||
CHECK_CHANGED(checkUrlSearch, option_search_url_bar)
|
||||
END_HANDLER
|
||||
|
||||
COMBO_CHANGED(comboSearch, option_search_provider)
|
||||
nsgtk_scaffolding *current = scaf_list;
|
||||
char *name;
|
||||
/* refresh web search prefs from file */
|
||||
search_web_provider_details(option_search_provider);
|
||||
/* retrieve ico */
|
||||
search_web_retrieve_ico(false);
|
||||
/* callback may handle changing gui */
|
||||
if (search_web_ico() != NULL)
|
||||
gui_window_set_search_ico(search_web_ico());
|
||||
/* set entry */
|
||||
name = search_web_provider_name();
|
||||
if (name == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
continue;
|
||||
}
|
||||
char content[strlen(name) + SLEN("Search ") + 1];
|
||||
sprintf(content, "Search %s", name);
|
||||
free(name);
|
||||
while (current) {
|
||||
nsgtk_scaffolding_set_websearch(current, content);
|
||||
current = nsgtk_scaffolding_iterate(current);
|
||||
}
|
||||
END_HANDLER
|
||||
|
||||
COMBO_CHANGED(combotheme, option_current_theme)
|
||||
nsgtk_scaffolding *current = scaf_list;
|
||||
char *name;
|
||||
if (option_current_theme != 0) {
|
||||
if (nsgtk_theme_name() != NULL)
|
||||
free(nsgtk_theme_name());
|
||||
name = strdup(gtk_combo_box_get_active_text(
|
||||
GTK_COMBO_BOX(combotheme)));
|
||||
if (name == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
continue;
|
||||
}
|
||||
nsgtk_theme_set_name(name);
|
||||
nsgtk_theme_prepare();
|
||||
} else if (nsgtk_theme_name() != NULL) {
|
||||
free(nsgtk_theme_name());
|
||||
nsgtk_theme_set_name(NULL);
|
||||
}
|
||||
while (current) {
|
||||
nsgtk_theme_implement(current);
|
||||
current = nsgtk_scaffolding_iterate(current);
|
||||
}
|
||||
END_HANDLER
|
||||
|
||||
BUTTON_CLICKED(buttonaddtheme)
|
||||
char *filename, *directory;
|
||||
size_t len;
|
||||
GtkWidget *fc = gtk_file_chooser_dialog_new(
|
||||
messages_get("gtkAddThemeTitle"),
|
||||
GTK_WINDOW(wndPreferences),
|
||||
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
|
||||
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, NULL);
|
||||
len = SLEN("themes") + strlen(res_dir_location) + 1;
|
||||
char themesfolder[len];
|
||||
snprintf(themesfolder, len, "%sthemes", res_dir_location);
|
||||
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(fc),
|
||||
themesfolder);
|
||||
gint res = gtk_dialog_run(GTK_DIALOG(fc));
|
||||
if (res == GTK_RESPONSE_ACCEPT) {
|
||||
filename = gtk_file_chooser_get_current_folder(
|
||||
GTK_FILE_CHOOSER(fc));
|
||||
if (strcmp(filename, themesfolder) != 0) {
|
||||
directory = strrchr(filename, '/');
|
||||
*directory = '\0';
|
||||
if (strcmp(filename, themesfolder) != 0) {
|
||||
warn_user(messages_get(
|
||||
"gtkThemeFolderInstructions"),
|
||||
0);
|
||||
gtk_widget_destroy(GTK_WIDGET(fc));
|
||||
free(filename);
|
||||
free(themesfolder);
|
||||
return FALSE;
|
||||
} else {
|
||||
directory++;
|
||||
}
|
||||
} else {
|
||||
free(filename);
|
||||
filename = gtk_file_chooser_get_filename(
|
||||
GTK_FILE_CHOOSER(fc));
|
||||
if (strcmp(filename, themesfolder) == 0) {
|
||||
warn_user(messages_get("gtkThemeFolderSub"),
|
||||
0);
|
||||
gtk_widget_destroy(GTK_WIDGET(fc));
|
||||
free(filename);
|
||||
free(themesfolder);
|
||||
return FALSE;
|
||||
}
|
||||
directory = strrchr(filename, '/') + 1;
|
||||
}
|
||||
gtk_widget_destroy(GTK_WIDGET(fc));
|
||||
nsgtk_theme_add(directory);
|
||||
free(filename);
|
||||
}
|
||||
|
||||
END_HANDLER
|
||||
|
||||
CHECK_CHANGED(sourceButtonTab, option_source_tab)
|
||||
END_HANDLER
|
||||
|
||||
SPIN_CHANGED(spinMarginTop, option_margin_top)
|
||||
END_HANDLER
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright 2006 Rob Kendrick <rjek@rjek.com>
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
@ -23,8 +24,11 @@
|
||||
|
||||
extern GtkDialog *wndPreferences;
|
||||
|
||||
GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent); /** Init options and load window */
|
||||
GtkDialog* nsgtk_options_init(struct browser_window *bw, GtkWindow *parent);
|
||||
/** Init options and load window */
|
||||
void nsgtk_options_load(void); /** Load current options into window */
|
||||
void nsgtk_options_save(void); /** Save options from window */
|
||||
bool nsgtk_options_combo_theme_add(const char *themename);
|
||||
/** add new theme name to combo */
|
||||
|
||||
#endif
|
||||
|
@ -28,8 +28,10 @@
|
||||
#include "gtk/gtk_gui.h"
|
||||
#include "gtk/gtk_print.h"
|
||||
#include "gtk/gtk_selection.h"
|
||||
#include "gtk/options.h"
|
||||
#include "desktop/netsurf.h"
|
||||
#include "desktop/print.h"
|
||||
#include "desktop/options.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/url.h"
|
||||
#include "utils/utils.h"
|
||||
@ -57,10 +59,10 @@ struct menu_events {
|
||||
};
|
||||
|
||||
static GladeXML *glade_File;
|
||||
static gchar *glade_Location;
|
||||
static struct nsgtk_source_window *nsgtk_source_list = 0;
|
||||
static char source_zoomlevel = 10;
|
||||
|
||||
void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw);
|
||||
static void nsgtk_attach_source_menu_handlers(GladeXML *xml, gpointer g);
|
||||
static gboolean nsgtk_source_delete_event(GtkWindow *window, gpointer g);
|
||||
static gboolean nsgtk_source_destroy_event(GtkWindow *window, gpointer g);
|
||||
@ -102,112 +104,153 @@ MENUEVENT(source_about),
|
||||
};
|
||||
|
||||
void nsgtk_source_dialog_init(GtkWindow *parent, struct browser_window *bw)
|
||||
{
|
||||
if (bw->current_content->type == CONTENT_HTML) {
|
||||
glade_Location = g_strconcat(res_dir_location, "source.glade",
|
||||
NULL);
|
||||
glade_File = glade_xml_new(glade_Location, NULL, NULL);
|
||||
if (glade_File == NULL) {
|
||||
LOG(("error loading glade tree"));
|
||||
}
|
||||
|
||||
char *data = NULL;
|
||||
|
||||
utf8_convert_ret r = utf8_from_enc(
|
||||
bw->current_content->source_data,
|
||||
bw->current_content->data.html.encoding,
|
||||
bw->current_content->source_size,
|
||||
&data);
|
||||
if (r == UTF8_CONVERT_NOMEM) {
|
||||
warn_user("NoMemory",0);
|
||||
return;
|
||||
} else if (r == UTF8_CONVERT_BADENC) {
|
||||
warn_user("EncNotRec",0);
|
||||
return;
|
||||
}
|
||||
|
||||
GtkWindow *wndSource = GTK_WINDOW(glade_xml_get_widget(
|
||||
glade_File, "wndSource"));
|
||||
GtkWidget *cutbutton = glade_xml_get_widget(
|
||||
glade_File, "source_cut");
|
||||
GtkWidget *pastebutton = glade_xml_get_widget(
|
||||
glade_File, "source_paste");
|
||||
GtkWidget *deletebutton = glade_xml_get_widget(
|
||||
glade_File, "source_delete");
|
||||
GtkWidget *printbutton = glade_xml_get_widget(
|
||||
glade_File, "source_print");
|
||||
gtk_widget_set_sensitive(cutbutton, FALSE);
|
||||
gtk_widget_set_sensitive(pastebutton, FALSE);
|
||||
gtk_widget_set_sensitive(deletebutton, FALSE);
|
||||
/* for now */
|
||||
gtk_widget_set_sensitive(printbutton, FALSE);
|
||||
|
||||
struct nsgtk_source_window *thiswindow =
|
||||
malloc(sizeof(struct nsgtk_source_window));
|
||||
if (thiswindow == NULL) {
|
||||
free(data);
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
thiswindow->url = strdup(bw->current_content->url);
|
||||
if (thiswindow->url == NULL) {
|
||||
free(thiswindow);
|
||||
free(data);
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
thiswindow->data = data;
|
||||
|
||||
thiswindow->sourcewindow = wndSource;
|
||||
thiswindow->bw = bw;
|
||||
{
|
||||
char glade_Location[strlen(res_dir_location) + SLEN("source.glade")
|
||||
+ 1];
|
||||
if (bw->current_content->type != CONTENT_HTML)
|
||||
return;
|
||||
|
||||
char *title = malloc(strlen(bw->current_content->url)
|
||||
+ SLEN("Source of ") + 1);
|
||||
if (title == NULL) {
|
||||
free(thiswindow->url);
|
||||
free(thiswindow);
|
||||
free(data);
|
||||
warn_user("NoMemory", 0);
|
||||
if (option_source_tab) {
|
||||
nsgtk_source_tab_init(parent, bw);
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(glade_Location, "%ssource.glade", res_dir_location);
|
||||
glade_File = glade_xml_new(glade_Location, NULL, NULL);
|
||||
if (glade_File == NULL) {
|
||||
LOG(("error loading glade tree"));
|
||||
}
|
||||
|
||||
char *data = NULL;
|
||||
|
||||
utf8_convert_ret r = utf8_from_enc(
|
||||
bw->current_content->source_data,
|
||||
bw->current_content->data.html.encoding,
|
||||
bw->current_content->source_size,
|
||||
&data);
|
||||
if (r == UTF8_CONVERT_NOMEM) {
|
||||
warn_user("NoMemory",0);
|
||||
return;
|
||||
} else if (r == UTF8_CONVERT_BADENC) {
|
||||
warn_user("EncNotRec",0);
|
||||
return;
|
||||
}
|
||||
|
||||
GtkWindow *wndSource = GTK_WINDOW(glade_xml_get_widget(
|
||||
glade_File, "wndSource"));
|
||||
GtkWidget *cutbutton = glade_xml_get_widget(
|
||||
glade_File, "source_cut");
|
||||
GtkWidget *pastebutton = glade_xml_get_widget(
|
||||
glade_File, "source_paste");
|
||||
GtkWidget *deletebutton = glade_xml_get_widget(
|
||||
glade_File, "source_delete");
|
||||
GtkWidget *printbutton = glade_xml_get_widget(
|
||||
glade_File, "source_print");
|
||||
gtk_widget_set_sensitive(cutbutton, FALSE);
|
||||
gtk_widget_set_sensitive(pastebutton, FALSE);
|
||||
gtk_widget_set_sensitive(deletebutton, FALSE);
|
||||
/* for now */
|
||||
gtk_widget_set_sensitive(printbutton, FALSE);
|
||||
|
||||
struct nsgtk_source_window *thiswindow =
|
||||
malloc(sizeof(struct nsgtk_source_window));
|
||||
if (thiswindow == NULL) {
|
||||
free(data);
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
thiswindow->url = strdup(bw->current_content->url);
|
||||
if (thiswindow->url == NULL) {
|
||||
free(thiswindow);
|
||||
free(data);
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
thiswindow->data = data;
|
||||
|
||||
thiswindow->sourcewindow = wndSource;
|
||||
thiswindow->bw = bw;
|
||||
|
||||
char title[strlen(bw->current_content->url) + SLEN("Source of ") + 1];
|
||||
sprintf(title, "Source of %s", bw->current_content->url);
|
||||
|
||||
thiswindow->next = nsgtk_source_list;
|
||||
thiswindow->prev = NULL;
|
||||
if (nsgtk_source_list != NULL)
|
||||
nsgtk_source_list->prev = thiswindow;
|
||||
nsgtk_source_list = thiswindow;
|
||||
|
||||
nsgtk_attach_source_menu_handlers(glade_File, thiswindow);
|
||||
|
||||
gtk_window_set_title(wndSource, title);
|
||||
|
||||
g_signal_connect(G_OBJECT(wndSource), "destroy",
|
||||
G_CALLBACK(nsgtk_source_destroy_event),
|
||||
thiswindow);
|
||||
g_signal_connect(G_OBJECT(wndSource), "delete-event",
|
||||
G_CALLBACK(nsgtk_source_delete_event),
|
||||
thiswindow);
|
||||
|
||||
GtkTextView *sourceview = GTK_TEXT_VIEW(
|
||||
glade_xml_get_widget(glade_File,
|
||||
"source_view"));
|
||||
PangoFontDescription *fontdesc =
|
||||
pango_font_description_from_string("Monospace 8");
|
||||
|
||||
thiswindow->gv = sourceview;
|
||||
gtk_widget_modify_font(GTK_WIDGET(sourceview), fontdesc);
|
||||
GtkTextBuffer *tb = gtk_text_view_get_buffer(sourceview);
|
||||
gtk_text_buffer_set_text(tb, thiswindow->data, -1);
|
||||
|
||||
gtk_widget_show(GTK_WIDGET(wndSource));
|
||||
|
||||
}
|
||||
void nsgtk_source_tab_init(GtkWindow *parent, struct browser_window *bw)
|
||||
{
|
||||
char *ndata = 0;
|
||||
utf8_convert_ret r = utf8_from_enc(
|
||||
bw->current_content->source_data,
|
||||
bw->current_content->data.html.encoding,
|
||||
bw->current_content->source_size,
|
||||
&ndata);
|
||||
if (r == UTF8_CONVERT_NOMEM) {
|
||||
warn_user("NoMemory",0);
|
||||
return;
|
||||
} else if (r == UTF8_CONVERT_BADENC) {
|
||||
warn_user("EncNotRec",0);
|
||||
return;
|
||||
}
|
||||
gchar *filename;
|
||||
char *fileurl;
|
||||
gint handle = g_file_open_tmp("nsgtksourceXXXXXX", &filename, NULL);
|
||||
close (handle); /* in case it was binary mode */
|
||||
FILE *f = fopen(filename, "w");
|
||||
fprintf(f, "%s", ndata);
|
||||
fclose(f);
|
||||
free(ndata);
|
||||
fileurl = path_to_url(filename);
|
||||
g_free(filename);
|
||||
if (fileurl == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
struct browser_window *newbw = browser_window_create(fileurl, bw,
|
||||
NULL, false, true);
|
||||
free(fileurl);
|
||||
if (newbw->current_content) {
|
||||
newbw->current_content->title = malloc(
|
||||
strlen(bw->current_content->url) +
|
||||
SLEN("source of ") + 1);
|
||||
if (newbw->current_content->title == NULL)
|
||||
return;
|
||||
}
|
||||
sprintf(title, "Source of %s", bw->current_content->url);
|
||||
|
||||
thiswindow->next = nsgtk_source_list;
|
||||
thiswindow->prev = NULL;
|
||||
if (nsgtk_source_list != NULL)
|
||||
nsgtk_source_list->prev = thiswindow;
|
||||
nsgtk_source_list = thiswindow;
|
||||
|
||||
nsgtk_attach_source_menu_handlers(glade_File, thiswindow);
|
||||
|
||||
gtk_window_set_title(wndSource, title);
|
||||
|
||||
g_signal_connect(G_OBJECT(wndSource), "destroy",
|
||||
G_CALLBACK(nsgtk_source_destroy_event),
|
||||
thiswindow);
|
||||
g_signal_connect(G_OBJECT(wndSource), "delete-event",
|
||||
G_CALLBACK(nsgtk_source_delete_event),
|
||||
thiswindow);
|
||||
|
||||
GtkTextView *sourceview = GTK_TEXT_VIEW(
|
||||
glade_xml_get_widget(glade_File,
|
||||
"source_view"));
|
||||
PangoFontDescription *fontdesc =
|
||||
pango_font_description_from_string("Monospace 8");
|
||||
|
||||
thiswindow->gv = sourceview;
|
||||
gtk_widget_modify_font(GTK_WIDGET(sourceview), fontdesc);
|
||||
GtkTextBuffer *tb = gtk_text_view_get_buffer(sourceview);
|
||||
gtk_text_buffer_set_text(tb, thiswindow->data, -1);
|
||||
|
||||
gtk_widget_show(GTK_WIDGET(wndSource));
|
||||
|
||||
free(title);
|
||||
sprintf(newbw->current_content->title, "source of %s",
|
||||
bw->current_content->url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nsgtk_attach_source_menu_handlers(GladeXML *xml, gpointer g)
|
||||
{
|
||||
struct menu_events *event = source_menu_events;
|
||||
@ -264,7 +307,7 @@ void nsgtk_source_file_save(GtkWindow *parent, const char *filename,
|
||||
{
|
||||
FILE *f;
|
||||
bool auth = true;
|
||||
char temp[15];
|
||||
char temp[255];
|
||||
GtkWidget *notif, *label;
|
||||
|
||||
if (!(access(filename, F_OK))) {
|
||||
@ -277,21 +320,18 @@ void nsgtk_source_file_save(GtkWindow *parent, const char *filename,
|
||||
GTK_STOCK_CANCEL,
|
||||
GTK_RESPONSE_REJECT,
|
||||
NULL);
|
||||
char *warn;
|
||||
const char *format = messages_get("gtkOverwrite");
|
||||
int len = strlen(filename) + strlen(format);
|
||||
|
||||
int len = strlen(filename) + strlen(format) + SLEN("\n\n") + 1;
|
||||
char warn[len];
|
||||
auth = false;
|
||||
|
||||
warn = malloc(len);
|
||||
if (warn == NULL) {
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
warn[0] = '\n';
|
||||
snprintf(warn + 1, len - 2, format, filename);
|
||||
len = strlen(warn);
|
||||
warn[len - 1] = '\n';
|
||||
warn[len] = '\0';
|
||||
|
||||
snprintf(warn, len, format, filename);
|
||||
|
||||
label = gtk_label_new(g_strconcat("\n",warn,"\n", NULL));
|
||||
label = gtk_label_new(warn);
|
||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(confd)->vbox),
|
||||
label);
|
||||
gtk_widget_show(label);
|
||||
@ -299,16 +339,19 @@ void nsgtk_source_file_save(GtkWindow *parent, const char *filename,
|
||||
auth = true;
|
||||
}
|
||||
gtk_widget_destroy(confd);
|
||||
free(warn);
|
||||
}
|
||||
|
||||
if (auth) {
|
||||
f = fopen(filename, "w+");
|
||||
fprintf(f, "%s", data);
|
||||
fclose(f);
|
||||
strcpy(temp, messages_get("gtkSaveConfirm"));
|
||||
snprintf(temp, sizeof(temp), "\n %s"
|
||||
" \n",
|
||||
messages_get("gtkSaveConfirm"));
|
||||
} else {
|
||||
strcpy(temp, messages_get("gtkSaveCancelled"));
|
||||
snprintf(temp, sizeof(temp), "\n %s"
|
||||
" \n",
|
||||
messages_get("gtkSaveCancelled"));
|
||||
}
|
||||
|
||||
notif = gtk_dialog_new_with_buttons(temp,
|
||||
@ -316,8 +359,7 @@ void nsgtk_source_file_save(GtkWindow *parent, const char *filename,
|
||||
GTK_RESPONSE_NONE, NULL);
|
||||
g_signal_connect_swapped(notif, "response",
|
||||
G_CALLBACK(gtk_widget_destroy), notif);
|
||||
label = gtk_label_new(g_strconcat("\n ", temp,
|
||||
" \n", NULL));
|
||||
label = gtk_label_new(temp);
|
||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(notif)->vbox), label);
|
||||
gtk_widget_show_all(notif);
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
#include "gtk/options.h"
|
||||
#include "gtk/gtk_download.h"
|
||||
#include "gtk/gtk_window.h"
|
||||
|
||||
#define UPDATE_RATE 500 /* In milliseconds */
|
||||
#define GLADE_NAME "downloads.glade"
|
||||
@ -86,9 +87,9 @@ static gboolean nsgtk_download_handle_error (GError *error);
|
||||
|
||||
void nsgtk_download_init()
|
||||
{
|
||||
gchar *glade_location = g_strconcat(res_dir_location, GLADE_NAME, NULL);
|
||||
char glade_location[strlen(res_dir_location) + SLEN(GLADE_NAME) + 1];
|
||||
sprintf(glade_location, "%s" GLADE_NAME, res_dir_location);
|
||||
GladeXML *gladeFile = glade_xml_new(glade_location, NULL, NULL);
|
||||
g_free(glade_location);
|
||||
|
||||
nsgtk_download_buttons =
|
||||
glade_xml_get_widget_prefix(gladeFile, "button");
|
||||
@ -202,11 +203,12 @@ struct gui_download_window *gui_download_window_create(const char *url,
|
||||
gchar *filename;
|
||||
gchar *destination;
|
||||
gboolean unknown_size = total_size == 0;
|
||||
const gchar *size = (total_size == 0 ?
|
||||
const char *size = (total_size == 0 ?
|
||||
messages_get("gtkUnknownSize") :
|
||||
human_friendly_bytesize(total_size));
|
||||
|
||||
nsgtk_download_parent = nsgtk_scaffolding_get_window(gui);
|
||||
nsgtk_download_parent = nsgtk_scaffolding_window(nsgtk_get_scaffold(
|
||||
gui));
|
||||
struct gui_download_window *download = malloc(sizeof *download);
|
||||
|
||||
if (url_nice(url, &filename, false) != URL_FUNC_OK)
|
||||
@ -488,8 +490,9 @@ gboolean nsgtk_download_update(gboolean force_update)
|
||||
void nsgtk_download_store_update_item (struct gui_download_window *dl)
|
||||
{
|
||||
gchar *info = nsgtk_download_info_to_string(dl);
|
||||
gchar *speed = g_strconcat(human_friendly_bytesize(dl->speed), "/s",
|
||||
NULL);
|
||||
char *human = human_friendly_bytesize(dl->speed);
|
||||
char speed[strlen(human) + SLEN("/s") + 1];
|
||||
sprintf(speed, "%s/s", human);
|
||||
gchar *time = nsgtk_download_time_to_string(dl->time_remaining);
|
||||
gboolean pulse = dl->status == NSGTK_DOWNLOAD_WORKING;
|
||||
|
||||
@ -508,7 +511,6 @@ void nsgtk_download_store_update_item (struct gui_download_window *dl)
|
||||
-1);
|
||||
|
||||
g_free(info);
|
||||
g_free(speed);
|
||||
g_free(time);
|
||||
}
|
||||
|
||||
@ -634,7 +636,7 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain,
|
||||
{
|
||||
enum { GTK_RESPONSE_DOWNLOAD, GTK_RESPONSE_SAVE_AS };
|
||||
GtkWidget *dialog;
|
||||
gchar *destination = NULL;
|
||||
char *destination = NULL;
|
||||
gchar *message = g_strdup(messages_get("gtkStartDownload"));
|
||||
gchar *info = g_strdup_printf(messages_get("gtkInfo"), filename,
|
||||
domain, size);
|
||||
@ -682,9 +684,15 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain,
|
||||
break;
|
||||
}
|
||||
case GTK_RESPONSE_DOWNLOAD: {
|
||||
destination = g_strconcat(option_downloads_directory,
|
||||
"/", filename, NULL);
|
||||
/* Test if file already exists and display overwrite
|
||||
destination = malloc(strlen(option_downloads_directory)
|
||||
+ strlen(filename) + SLEN("/") + 1);
|
||||
if (destination == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
break;
|
||||
}
|
||||
sprintf(destination, "%s/%s",
|
||||
option_downloads_directory, filename);
|
||||
/* Test if file already exists and display overwrite
|
||||
* confirmation if needed */
|
||||
if (g_file_test(destination, G_FILE_TEST_EXISTS)
|
||||
&& option_request_overwrite) {
|
||||
@ -711,7 +719,7 @@ gchar* nsgtk_download_dialog_show (gchar *filename, gchar *domain,
|
||||
gtk_button_set_image(GTK_BUTTON(button),
|
||||
gtk_image_new_from_stock(
|
||||
"gtk-save",
|
||||
GTK_ICON_SIZE_BUTTON));
|
||||
GTK_ICON_SIZE_BUTTON));
|
||||
|
||||
gint result = gtk_dialog_run(GTK_DIALOG(
|
||||
dialog));
|
||||
|
115
gtk/gtk_gui.c
@ -43,6 +43,7 @@
|
||||
#include "desktop/netsurf.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/save_pdf/pdf_plotters.h"
|
||||
#include "desktop/searchweb.h"
|
||||
#include "desktop/textinput.h"
|
||||
#include "gtk/gtk_gui.h"
|
||||
#include "gtk/dialogs/gtk_options.h"
|
||||
@ -68,15 +69,23 @@ char *default_stylesheet_url;
|
||||
char *quirks_stylesheet_url;
|
||||
char *adblock_stylesheet_url;
|
||||
char *options_file_location;
|
||||
char *glade_file_location;
|
||||
char *glade_netsurf_file_location;
|
||||
char *glade_password_file_location;
|
||||
char *glade_warning_file_location;
|
||||
char *glade_login_file_location;
|
||||
char *glade_ssl_file_location;
|
||||
char *glade_toolbar_file_location;
|
||||
char *toolbar_indices_file_location;
|
||||
char *res_dir_location;
|
||||
char *print_options_file_location;
|
||||
|
||||
struct gui_window *search_current_window = 0;
|
||||
|
||||
GtkWindow *wndAbout;
|
||||
GtkWindow *wndWarning;
|
||||
GladeXML *gladeWindows;
|
||||
GladeXML *gladeNetsurf;
|
||||
GladeXML *gladePassword;
|
||||
GladeXML *gladeWarning;
|
||||
GladeXML *gladeLogin;
|
||||
GladeXML *gladeSsl;
|
||||
GtkWindow *wndTooltip;
|
||||
GtkLabel *labelTooltip;
|
||||
|
||||
@ -195,12 +204,28 @@ void gui_init(int argc, char** argv)
|
||||
check_homedir();
|
||||
|
||||
find_resource(buf, "netsurf.glade", "./gtk/res/netsurf.glade");
|
||||
LOG(("Using '%s' as Glade template file", buf));
|
||||
glade_file_location = strdup(buf);
|
||||
LOG(("Using '%s' as Netsurf glade template file", buf));
|
||||
glade_netsurf_file_location = strdup(buf);
|
||||
|
||||
buf[strlen(buf)- 13] = 0;
|
||||
LOG(("Using '%s' as Resources directory", buf));
|
||||
res_dir_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "password.glade", "./gtk/res/password.glade");
|
||||
LOG(("Using '%s' as password glade template file", buf));
|
||||
glade_password_file_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "warning.glade", "./gtk/res/warning.glade");
|
||||
LOG(("Using '%s' as warning glade template file", buf));
|
||||
glade_warning_file_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "login.glade", "./gtk/res/login.glade");
|
||||
LOG(("Using '%s' as login glade template file", buf));
|
||||
glade_login_file_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "ssl.glade", "./gtk/res/ssl.glade");
|
||||
LOG(("Using '%s' as ssl glade template file", buf));
|
||||
glade_ssl_file_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "Aliases", "./gtk/res/Aliases");
|
||||
LOG(("Using '%s' as Aliases file", buf));
|
||||
@ -208,17 +233,42 @@ void gui_init(int argc, char** argv)
|
||||
die("Unable to initialise HTML parsing library.\n");
|
||||
|
||||
glade_init();
|
||||
gladeWindows = glade_xml_new(glade_file_location, NULL, NULL);
|
||||
if (gladeWindows == NULL)
|
||||
die("Unable to load Glade window definitions.\n");
|
||||
glade_xml_signal_autoconnect(gladeWindows);
|
||||
gladeWarning = glade_xml_new(glade_warning_file_location, NULL, NULL);
|
||||
if (gladeWarning == NULL)
|
||||
die("Unable to load glade warning window definitions.\n");
|
||||
glade_xml_signal_autoconnect(gladeWarning);
|
||||
|
||||
gladeNetsurf = glade_xml_new(glade_netsurf_file_location, NULL, NULL);
|
||||
if (gladeNetsurf == NULL)
|
||||
die("Unable to load glade Netsurf window definitions.\n");
|
||||
glade_xml_signal_autoconnect(gladeNetsurf);
|
||||
|
||||
gladePassword = glade_xml_new(glade_password_file_location, NULL, NULL);
|
||||
if (gladePassword == NULL)
|
||||
die("Unable to load glade password window definitions.\n");
|
||||
glade_xml_signal_autoconnect(gladePassword);
|
||||
|
||||
gladeLogin = glade_xml_new(glade_login_file_location, NULL, NULL);
|
||||
if (gladeLogin == NULL)
|
||||
die("Unable to load glade login window definitions.\n");
|
||||
glade_xml_signal_autoconnect(gladeLogin);
|
||||
|
||||
gladeSsl = glade_xml_new(glade_ssl_file_location, NULL, NULL);
|
||||
if (gladeSsl == NULL)
|
||||
die("Unable to load glade ssl window definitions.\n");
|
||||
glade_xml_signal_autoconnect(gladeSsl);
|
||||
|
||||
find_resource(buf, "toolbar.glade", "./gtk/res/toolbar.glade");
|
||||
LOG(("Using '%s' as glade toolbar file", buf));
|
||||
glade_toolbar_file_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "netsurf.xpm", "./gtk/res/netsurf.xpm");
|
||||
gtk_window_set_default_icon_from_file(buf, NULL);
|
||||
|
||||
wndTooltip = GTK_WINDOW(glade_xml_get_widget(gladeWindows, "wndTooltip"));
|
||||
labelTooltip = GTK_LABEL(glade_xml_get_widget(gladeWindows, "tooltip"));
|
||||
|
||||
/* superfluous ? */
|
||||
wndTooltip = GTK_WINDOW(glade_xml_get_widget(gladeNetsurf, "wndTooltip"));
|
||||
labelTooltip = GTK_LABEL(glade_xml_get_widget(gladeNetsurf, "tooltip"));
|
||||
|
||||
nsgtk_completion_init();
|
||||
|
||||
/* This is an ugly hack to just get the new-style throbber going.
|
||||
@ -321,12 +371,25 @@ void gui_init(int argc, char** argv)
|
||||
LOG(("Using '%s' as Print Settings file", buf));
|
||||
print_options_file_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "SearchEngines", "./gtk/res/SearchEngines");
|
||||
LOG(("Using '%s' as Search Engines file", buf));
|
||||
search_engines_file_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "default.ico", "./gtk/res/default.ico");
|
||||
LOG(("Using '%s' as default search ico", buf));
|
||||
search_default_ico_location = strdup(buf);
|
||||
|
||||
find_resource(buf, "toolbarIndices", "./gtk/res/toolbarIndices");
|
||||
LOG(("Using '%s' as custom toolbar settings file", buf));
|
||||
toolbar_indices_file_location = strdup(buf);
|
||||
|
||||
urldb_load(option_url_file);
|
||||
urldb_load_cookies(option_cookie_file);
|
||||
|
||||
/* superfluous ? */
|
||||
wndAbout = GTK_WINDOW(glade_xml_get_widget(gladeNetsurf, "wndAbout"));
|
||||
|
||||
wndAbout = GTK_WINDOW(glade_xml_get_widget(gladeWindows, "wndAbout"));
|
||||
|
||||
wndWarning = GTK_WINDOW(glade_xml_get_widget(gladeWindows, "wndWarning"));
|
||||
wndWarning = GTK_WINDOW(glade_xml_get_widget(gladeWarning, "wndWarning"));
|
||||
|
||||
nsgtk_history_init();
|
||||
nsgtk_download_init();
|
||||
@ -428,6 +491,9 @@ void gui_quit(void)
|
||||
free(option_cookie_file);
|
||||
free(option_cookie_jar);
|
||||
free(print_options_file_location);
|
||||
free(search_engines_file_location);
|
||||
free(search_default_ico_location);
|
||||
free(toolbar_indices_file_location);
|
||||
gtk_fetch_filetype_fin();
|
||||
/* We don't care if this fails as we're about to die, anyway */
|
||||
hubbub_finalise(myrealloc, NULL);
|
||||
@ -490,15 +556,6 @@ void gui_launch_url(const char *url)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool gui_search_term_highlighted(struct gui_window *g,
|
||||
unsigned start_offset, unsigned end_offset,
|
||||
unsigned *start_idx, unsigned *end_idx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void warn_user(const char *warning, const char *detail)
|
||||
{
|
||||
char buf[300]; /* 300 is the size the RISC OS GUI uses */
|
||||
@ -510,7 +567,7 @@ void warn_user(const char *warning, const char *detail)
|
||||
detail ? detail : "");
|
||||
buf[sizeof(buf) - 1] = 0;
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWindows, "labelWarning")), buf);
|
||||
gtk_label_set_text(GTK_LABEL(glade_xml_get_widget(gladeWarning, "labelWarning")), buf);
|
||||
|
||||
gtk_widget_show_all(GTK_WIDGET(wndWarning));
|
||||
}
|
||||
@ -536,7 +593,7 @@ static void nsgtk_create_ssl_verify_window(struct browser_window *bw,
|
||||
struct content *c, const struct ssl_cert_info *certs,
|
||||
unsigned long num)
|
||||
{
|
||||
GladeXML *x = glade_xml_new(glade_file_location, NULL, NULL);
|
||||
GladeXML *x = glade_xml_new(glade_ssl_file_location, NULL, NULL);
|
||||
GtkWindow *wnd = GTK_WINDOW(glade_xml_get_widget(x, "wndSSLProblem"));
|
||||
GtkButton *accept, *reject;
|
||||
void **session = calloc(sizeof(void *), 4);
|
||||
@ -618,7 +675,7 @@ utf8_convert_ret utf8_from_local_encoding(const char *string, size_t len,
|
||||
|
||||
char *path_to_url(const char *path)
|
||||
{
|
||||
char *r = malloc(strlen(path) + 7 + 1);
|
||||
char *r = malloc(strlen(path) + SLEN("file://") + 1);
|
||||
|
||||
strcpy(r, "file://");
|
||||
strcat(r, path);
|
||||
@ -640,7 +697,7 @@ bool cookies_update(const char *domain, const struct cookie_data *data)
|
||||
|
||||
void PDF_Password(char **owner_pass, char **user_pass, char *path)
|
||||
{
|
||||
GladeXML *x = glade_xml_new(glade_file_location, NULL, NULL);
|
||||
GladeXML *x = glade_xml_new(glade_password_file_location, NULL, NULL);
|
||||
GtkWindow *wnd = GTK_WINDOW(glade_xml_get_widget(x, "wndPDFPassword"));
|
||||
GtkButton *ok, *no;
|
||||
void **data = malloc(5 * sizeof(void *));
|
||||
|
@ -25,8 +25,18 @@
|
||||
#include <glade/glade.h>
|
||||
|
||||
extern bool gui_in_multitask;
|
||||
extern GladeXML *gladeWindows;
|
||||
extern char *glade_file_location;
|
||||
extern GladeXML *gladeNetsurf;
|
||||
extern GladeXML *gladePassword;
|
||||
extern GladeXML *gladeWarning;
|
||||
extern GladeXML *gladeLogin;
|
||||
extern GladeXML *gladeSsl;
|
||||
extern char *glade_netsurf_file_location;
|
||||
extern char *glade_password_file_location;
|
||||
extern char *glade_warning_file_location;
|
||||
extern char *glade_login_file_location;
|
||||
extern char *glade_ssl_file_location;
|
||||
extern char *glade_toolbar_file_location;
|
||||
extern char *toolbar_indices_file_location;
|
||||
extern char *options_file_location;
|
||||
extern char *res_dir_location;
|
||||
extern char *print_options_file_location;
|
||||
|
@ -107,9 +107,9 @@ void nsgtk_history_init(void)
|
||||
dateAt = messages_get("DateAt");
|
||||
domainAll = messages_get("DomainAll");
|
||||
|
||||
gchar *glade_location = g_strconcat(res_dir_location, GLADE_NAME, NULL);
|
||||
char glade_location[strlen(res_dir_location) + SLEN(GLADE_NAME) + 1];
|
||||
sprintf(glade_location, "%s" GLADE_NAME, res_dir_location);
|
||||
gladeFile = glade_xml_new(glade_location, NULL, NULL);
|
||||
g_free(glade_location);
|
||||
|
||||
glade_xml_signal_autoconnect(gladeFile);
|
||||
wndHistory = GTK_WINDOW(glade_xml_get_widget(gladeFile,
|
||||
@ -500,23 +500,23 @@ void nsgtk_history_search_clear (GtkEntry *entry)
|
||||
|
||||
gchar *nsgtk_history_date_parse(time_t visit_time)
|
||||
{
|
||||
gchar *date_string = malloc(30);
|
||||
gchar format[30];
|
||||
char *date_string = malloc(30);
|
||||
char format[30];
|
||||
time_t current_time = time(NULL);
|
||||
gint current_day = localtime(¤t_time)->tm_yday;
|
||||
int current_day = localtime(¤t_time)->tm_yday;
|
||||
struct tm *visit_date = localtime(&visit_time);
|
||||
|
||||
if (visit_date->tm_yday == current_day)
|
||||
g_snprintf(format, 30, "%s %s %%I:%%M %%p",
|
||||
snprintf(format, 30, "%s %s %%I:%%M %%p",
|
||||
dateToday, dateAt);
|
||||
else if (current_day - visit_date->tm_yday == 1)
|
||||
g_snprintf(format, 30, "%s %s %%I:%%M %%p",
|
||||
snprintf(format, 30, "%s %s %%I:%%M %%p",
|
||||
dateYesterday, dateAt);
|
||||
else if (current_day - visit_date->tm_yday < 7)
|
||||
g_snprintf(format, 30, "%%A %s %%I:%%M %%p",
|
||||
snprintf(format, 30, "%%A %s %%I:%%M %%p",
|
||||
dateAt);
|
||||
else
|
||||
g_snprintf(format, 30, "%%B %%d, %%Y");
|
||||
snprintf(format, 30, "%%B %%d, %%Y");
|
||||
|
||||
strftime(date_string, 30, format, visit_date);
|
||||
|
||||
|
@ -74,7 +74,7 @@ void create_login_window(struct browser_window *bw, const char *host,
|
||||
* the widgets we're interested in.
|
||||
*/
|
||||
|
||||
GladeXML *x = glade_xml_new(glade_file_location, NULL, NULL);
|
||||
GladeXML *x = glade_xml_new(glade_login_file_location, NULL, NULL);
|
||||
GtkWindow *wnd = GTK_WINDOW(glade_xml_get_widget(x, "wndLogin"));
|
||||
GtkLabel *lhost, *lrealm;
|
||||
GtkEntry *euser, *epass;
|
||||
|
422
gtk/gtk_menu.c
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdlib.h>
|
||||
#include "gtk/gtk_menu.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
static struct nsgtk_export_submenu *nsgtk_menu_export_submenu(GtkAccelGroup *);
|
||||
static struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu(
|
||||
GtkAccelGroup *);
|
||||
static struct nsgtk_images_submenu *nsgtk_menu_images_submenu(GtkAccelGroup *);
|
||||
static struct nsgtk_toolbars_submenu *nsgtk_menu_toolbars_submenu(
|
||||
GtkAccelGroup *);
|
||||
static struct nsgtk_debugging_submenu *nsgtk_menu_debugging_submenu(
|
||||
GtkAccelGroup *);
|
||||
static bool nsgtk_menu_add_image_item(GtkMenu *menu,
|
||||
GtkImageMenuItem **item, const char *message,
|
||||
const char *messageAccel, GtkAccelGroup *group);
|
||||
|
||||
/**
|
||||
* adds image menu item to specified menu
|
||||
* \param menu the menu to add the item to
|
||||
* \param item a pointer to the item's location in the menu struct
|
||||
* \param message the menu item I18n lookup value
|
||||
* \param messageAccel the menu item accelerator I18n lookup value
|
||||
* \param group the 'global' in a gtk sense accelerator group
|
||||
*/
|
||||
|
||||
bool nsgtk_menu_add_image_item(GtkMenu *menu,
|
||||
GtkImageMenuItem **item, const char *message,
|
||||
const char *messageAccel, GtkAccelGroup *group)
|
||||
{
|
||||
unsigned int key;
|
||||
GdkModifierType mod;
|
||||
*item = GTK_IMAGE_MENU_ITEM(gtk_image_menu_item_new_with_mnemonic(
|
||||
messages_get(message)));
|
||||
if (*item == NULL)
|
||||
return false;
|
||||
gtk_accelerator_parse(messages_get(messageAccel), &key, &mod);
|
||||
if (key > 0)
|
||||
gtk_widget_add_accelerator(GTK_WIDGET(*item), "activate",
|
||||
group, key, mod, GTK_ACCEL_VISIBLE);
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(menu), GTK_WIDGET(*item));
|
||||
gtk_widget_show(GTK_WIDGET(*item));
|
||||
return true;
|
||||
}
|
||||
|
||||
#define IMAGE_ITEM(p, q, r, s, t)\
|
||||
nsgtk_menu_add_image_item(s->p##_menu, &(s->q##_menuitem), #r,\
|
||||
#r "Accel", t);
|
||||
|
||||
#define CHECK_ITEM(p, q, r, s)\
|
||||
s->q##_menuitem = GTK_CHECK_MENU_ITEM(\
|
||||
gtk_check_menu_item_new_with_mnemonic(\
|
||||
messages_get(#r)));\
|
||||
if ((s->q##_menuitem != NULL) && (s->p##_menu != NULL)) {\
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(s->p##_menu),\
|
||||
GTK_WIDGET(s->q##_menuitem));\
|
||||
gtk_widget_show(GTK_WIDGET(s->q##_menuitem));\
|
||||
}
|
||||
|
||||
#define SET_SUBMENU(q, r)\
|
||||
r->q##_submenu = nsgtk_menu_##q##_submenu(group);\
|
||||
if ((r->q##_submenu != NULL) && (r->q##_submenu->q##_menu != NULL) && \
|
||||
(r->q##_menuitem != NULL)) {\
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(r->q##_menuitem),\
|
||||
GTK_WIDGET(r->q##_submenu->q##_menu));\
|
||||
}
|
||||
|
||||
#define ADD_SEP(q, r)\
|
||||
w = gtk_separator_menu_item_new();\
|
||||
if ((w != NULL) && (r->q##_menu != NULL)) {\
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(r->q##_menu), w);\
|
||||
gtk_widget_show(w);\
|
||||
}
|
||||
|
||||
/**
|
||||
* creates the a file menu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
struct nsgtk_file_menu *nsgtk_menu_file_menu(GtkAccelGroup *group)
|
||||
{
|
||||
GtkWidget *w;
|
||||
struct nsgtk_file_menu *ret = malloc(sizeof(struct nsgtk_file_menu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->file_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->file_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(file, newwindow, gtkNewWindow, ret, group)
|
||||
IMAGE_ITEM(file, newtab, gtkNewTab, ret, group)
|
||||
IMAGE_ITEM(file, openfile, gtkOpenFile, ret, group)
|
||||
IMAGE_ITEM(file, closewindow, gtkCloseWindow, ret, group)
|
||||
ADD_SEP(file, ret)
|
||||
IMAGE_ITEM(file, savepage, gtkSavePage, ret, group)
|
||||
IMAGE_ITEM(file, export, gtkExport, ret, group)
|
||||
ADD_SEP(file, ret)
|
||||
IMAGE_ITEM(file, printpreview, gtkPrintPreview, ret, group)
|
||||
IMAGE_ITEM(file, print, gtkPrint, ret, group)
|
||||
ADD_SEP(file, ret)
|
||||
IMAGE_ITEM(file, quit, gtkQuitMenu, ret, group)
|
||||
SET_SUBMENU(export, ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an edit menu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_edit_menu *nsgtk_menu_edit_menu(GtkAccelGroup *group)
|
||||
{
|
||||
GtkWidget *w;
|
||||
struct nsgtk_edit_menu *ret = malloc(sizeof(struct nsgtk_edit_menu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->edit_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->edit_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(edit, cut, gtkCut, ret, group)
|
||||
IMAGE_ITEM(edit, copy, gtkCopy, ret, group)
|
||||
IMAGE_ITEM(edit, paste, gtkPaste, ret, group)
|
||||
IMAGE_ITEM(edit, delete, gtkDelete, ret, group)
|
||||
ADD_SEP(edit, ret)
|
||||
IMAGE_ITEM(edit, selectall, gtkSelectAll, ret, group)
|
||||
ADD_SEP(edit, ret)
|
||||
IMAGE_ITEM(edit, find, gtkFind, ret, group)
|
||||
ADD_SEP(edit, ret)
|
||||
IMAGE_ITEM(edit, preferences, gtkPreferences, ret, group)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a view menu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_view_menu *nsgtk_menu_view_menu(GtkAccelGroup *group)
|
||||
{
|
||||
GtkWidget *w;
|
||||
struct nsgtk_view_menu *ret = malloc(sizeof(struct nsgtk_view_menu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->view_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->view_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(view, stop, gtkStop, ret, group)
|
||||
IMAGE_ITEM(view, reload, gtkReload, ret, group)
|
||||
ADD_SEP(view, ret)
|
||||
IMAGE_ITEM(view, scaleview, gtkScaleView, ret, group)
|
||||
IMAGE_ITEM(view, fullscreen, gtkFullScreen, ret, group)
|
||||
IMAGE_ITEM(view, viewsource, gtkViewSource, ret, group)
|
||||
ADD_SEP(view, ret)
|
||||
IMAGE_ITEM(view, images, gtkImages, ret, group)
|
||||
IMAGE_ITEM(view, toolbars, gtkToolbars, ret, group)
|
||||
ADD_SEP(view, ret)
|
||||
IMAGE_ITEM(view, downloads, gtkDownloads, ret, group)
|
||||
IMAGE_ITEM(view, savewindowsize, gtkSaveWindowSize, ret, group)
|
||||
IMAGE_ITEM(view, debugging, gtkDebugging, ret, group)
|
||||
SET_SUBMENU(scaleview, ret)
|
||||
SET_SUBMENU(images, ret)
|
||||
SET_SUBMENU(toolbars, ret)
|
||||
SET_SUBMENU(debugging, ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a nav menu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_nav_menu *nsgtk_menu_nav_menu(GtkAccelGroup *group)
|
||||
{
|
||||
GtkWidget *w;
|
||||
struct nsgtk_nav_menu *ret = malloc(sizeof(struct nsgtk_nav_menu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->nav_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->nav_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(nav, back, gtkBack, ret, group)
|
||||
IMAGE_ITEM(nav, forward, gtkForward, ret, group)
|
||||
IMAGE_ITEM(nav, home, gtkHome, ret, group)
|
||||
ADD_SEP(nav, ret)
|
||||
IMAGE_ITEM(nav, localhistory, gtkLocalHistory, ret, group)
|
||||
IMAGE_ITEM(nav, globalhistory, gtkGlobalHistory, ret, group)
|
||||
ADD_SEP(nav, ret)
|
||||
IMAGE_ITEM(nav, addbookmarks, gtkAddBookMarks, ret, group)
|
||||
IMAGE_ITEM(nav, showbookmarks, gtkShowBookMarks, ret, group)
|
||||
ADD_SEP(nav, ret)
|
||||
IMAGE_ITEM(nav, openlocation, gtkOpenLocation, ret, group)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a tabs menu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_tabs_menu *nsgtk_menu_tabs_menu(GtkAccelGroup *group)
|
||||
{
|
||||
struct nsgtk_tabs_menu *ret = malloc(sizeof(struct nsgtk_tabs_menu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->tabs_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->tabs_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(tabs, nexttab, gtkNextTab, ret, group)
|
||||
IMAGE_ITEM(tabs, prevtab, gtkPrevTab, ret, group)
|
||||
IMAGE_ITEM(tabs, closetab, gtkCloseTab, ret, group)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a help menu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_help_menu *nsgtk_menu_help_menu(GtkAccelGroup *group)
|
||||
{
|
||||
GtkWidget *w;
|
||||
struct nsgtk_help_menu *ret = malloc(sizeof(struct nsgtk_help_menu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->help_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->help_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(help, contents, gtkContents, ret, group)
|
||||
IMAGE_ITEM(help, guide, gtkGuide, ret, group)
|
||||
IMAGE_ITEM(help, info, gtkUserInformation, ret, group)
|
||||
ADD_SEP(help, ret)
|
||||
IMAGE_ITEM(help, about, gtkAbout, ret, group)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an export submenu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_export_submenu *nsgtk_menu_export_submenu(GtkAccelGroup *group)
|
||||
{
|
||||
struct nsgtk_export_submenu *ret = malloc(sizeof(struct
|
||||
nsgtk_export_submenu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->export_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->export_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(export, plaintext, gtkPlainText, ret, group)
|
||||
IMAGE_ITEM(export, drawfile, gtkDrawFile, ret, group)
|
||||
IMAGE_ITEM(export, postscript, gtkPostScript, ret, group)
|
||||
IMAGE_ITEM(export, pdf, gtkPDF, ret, group)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a scaleview submenu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_scaleview_submenu *nsgtk_menu_scaleview_submenu(
|
||||
GtkAccelGroup *group)
|
||||
{
|
||||
struct nsgtk_scaleview_submenu *ret =
|
||||
malloc(sizeof(struct nsgtk_scaleview_submenu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->scaleview_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->scaleview_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(scaleview, zoomplus, gtkZoomPlus, ret, group)
|
||||
IMAGE_ITEM(scaleview, zoomnormal, gtkZoomNormal, ret, group)
|
||||
IMAGE_ITEM(scaleview, zoomminus, gtkZoomMinus, ret, group)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates an images submenu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_images_submenu *nsgtk_menu_images_submenu(GtkAccelGroup *group)
|
||||
{
|
||||
struct nsgtk_images_submenu *ret =
|
||||
malloc(sizeof(struct nsgtk_images_submenu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->images_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->images_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
CHECK_ITEM(images, foregroundimages, gtkForegroundImages, ret)
|
||||
CHECK_ITEM(images, backgroundimages, gtkBackgroundImages, ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a toolbars submenu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_toolbars_submenu *nsgtk_menu_toolbars_submenu(
|
||||
GtkAccelGroup *group)
|
||||
{
|
||||
struct nsgtk_toolbars_submenu *ret =
|
||||
malloc(sizeof(struct nsgtk_toolbars_submenu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->toolbars_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->toolbars_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
CHECK_ITEM(toolbars, menubar, gtkMenuBar, ret)
|
||||
if (ret->menubar_menuitem != NULL)
|
||||
gtk_check_menu_item_set_active(ret->menubar_menuitem, TRUE);
|
||||
CHECK_ITEM(toolbars, toolbar, gtkToolBar, ret)
|
||||
if (ret->toolbar_menuitem != NULL)
|
||||
gtk_check_menu_item_set_active(ret->toolbar_menuitem, TRUE);
|
||||
CHECK_ITEM(toolbars, statusbar, gtkStatusBar, ret)
|
||||
if (ret->statusbar_menuitem != NULL)
|
||||
gtk_check_menu_item_set_active(ret->statusbar_menuitem, TRUE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a debugging submenu
|
||||
* \param group the 'global' in a gtk sense accelerator reference
|
||||
*/
|
||||
|
||||
struct nsgtk_debugging_submenu *nsgtk_menu_debugging_submenu(
|
||||
GtkAccelGroup *group)
|
||||
{
|
||||
struct nsgtk_debugging_submenu *ret =
|
||||
malloc(sizeof(struct nsgtk_debugging_submenu));
|
||||
if (ret == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
ret->debugging_menu = GTK_MENU(gtk_menu_new());
|
||||
if (ret->debugging_menu == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
IMAGE_ITEM(debugging, toggledebugging, gtkToggleDebugging, ret, group)
|
||||
IMAGE_ITEM(debugging, saveboxtree, gtkSaveBoxTree, ret, group)
|
||||
IMAGE_ITEM(debugging, savedomtree, gtkSaveDomTree, ret, group)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef CHECK_ITEM
|
||||
#undef IMAGE_ITEM
|
||||
#undef SET_SUBMENU
|
||||
#undef ADD_SEP
|
||||
|
135
gtk/gtk_menu.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef _NETSURF_GTK_MENU_H_
|
||||
#define _NETSURF_GTK_MENU_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
struct nsgtk_file_menu {
|
||||
GtkMenu *file_menu;
|
||||
GtkImageMenuItem *newwindow_menuitem;
|
||||
GtkImageMenuItem *newtab_menuitem;
|
||||
GtkImageMenuItem *openfile_menuitem;
|
||||
GtkImageMenuItem *closewindow_menuitem;
|
||||
GtkImageMenuItem *savepage_menuitem;
|
||||
GtkImageMenuItem *export_menuitem;
|
||||
struct nsgtk_export_submenu *export_submenu;
|
||||
GtkImageMenuItem *printpreview_menuitem;
|
||||
GtkImageMenuItem *print_menuitem;
|
||||
GtkImageMenuItem *quit_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_edit_menu {
|
||||
GtkMenu *edit_menu;
|
||||
GtkImageMenuItem *cut_menuitem;
|
||||
GtkImageMenuItem *copy_menuitem;
|
||||
GtkImageMenuItem *paste_menuitem;
|
||||
GtkImageMenuItem *delete_menuitem;
|
||||
GtkImageMenuItem *selectall_menuitem;
|
||||
GtkImageMenuItem *find_menuitem;
|
||||
GtkImageMenuItem *preferences_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_view_menu {
|
||||
GtkMenu *view_menu;
|
||||
GtkImageMenuItem *stop_menuitem;
|
||||
GtkImageMenuItem *reload_menuitem;
|
||||
GtkImageMenuItem *scaleview_menuitem;
|
||||
struct nsgtk_scaleview_submenu *scaleview_submenu;
|
||||
GtkImageMenuItem *fullscreen_menuitem;
|
||||
GtkImageMenuItem *viewsource_menuitem;
|
||||
GtkImageMenuItem *images_menuitem;
|
||||
struct nsgtk_images_submenu *images_submenu;
|
||||
GtkImageMenuItem *toolbars_menuitem;
|
||||
struct nsgtk_toolbars_submenu *toolbars_submenu;
|
||||
GtkImageMenuItem *downloads_menuitem;
|
||||
GtkImageMenuItem *savewindowsize_menuitem;
|
||||
GtkImageMenuItem *debugging_menuitem;
|
||||
struct nsgtk_debugging_submenu *debugging_submenu;
|
||||
};
|
||||
|
||||
struct nsgtk_nav_menu {
|
||||
GtkMenu *nav_menu;
|
||||
GtkImageMenuItem *back_menuitem;
|
||||
GtkImageMenuItem *forward_menuitem;
|
||||
GtkImageMenuItem *home_menuitem;
|
||||
GtkImageMenuItem *localhistory_menuitem;
|
||||
GtkImageMenuItem *globalhistory_menuitem;
|
||||
GtkImageMenuItem *addbookmarks_menuitem;
|
||||
GtkImageMenuItem *showbookmarks_menuitem;
|
||||
GtkImageMenuItem *openlocation_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_tabs_menu {
|
||||
GtkMenu *tabs_menu;
|
||||
GtkImageMenuItem *nexttab_menuitem;
|
||||
GtkImageMenuItem *prevtab_menuitem;
|
||||
GtkImageMenuItem *closetab_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_help_menu {
|
||||
GtkMenu *help_menu;
|
||||
GtkImageMenuItem *contents_menuitem;
|
||||
GtkImageMenuItem *guide_menuitem;
|
||||
GtkImageMenuItem *info_menuitem;
|
||||
GtkImageMenuItem *about_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_export_submenu {
|
||||
GtkMenu *export_menu;
|
||||
GtkImageMenuItem *plaintext_menuitem;
|
||||
GtkImageMenuItem *drawfile_menuitem;
|
||||
GtkImageMenuItem *postscript_menuitem;
|
||||
GtkImageMenuItem *pdf_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_scaleview_submenu {
|
||||
GtkMenu *scaleview_menu;
|
||||
GtkImageMenuItem *zoomplus_menuitem;
|
||||
GtkImageMenuItem *zoomminus_menuitem;
|
||||
GtkImageMenuItem *zoomnormal_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_images_submenu {
|
||||
GtkMenu *images_menu;
|
||||
GtkCheckMenuItem *foregroundimages_menuitem;
|
||||
GtkCheckMenuItem *backgroundimages_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_toolbars_submenu {
|
||||
GtkMenu *toolbars_menu;
|
||||
GtkCheckMenuItem *menubar_menuitem;
|
||||
GtkCheckMenuItem *toolbar_menuitem;
|
||||
GtkCheckMenuItem *statusbar_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_debugging_submenu {
|
||||
GtkMenu *debugging_menu;
|
||||
GtkImageMenuItem *toggledebugging_menuitem;
|
||||
GtkImageMenuItem *saveboxtree_menuitem;
|
||||
GtkImageMenuItem *savedomtree_menuitem;
|
||||
};
|
||||
|
||||
struct nsgtk_file_menu *nsgtk_menu_file_menu(GtkAccelGroup *group);
|
||||
struct nsgtk_edit_menu *nsgtk_menu_edit_menu(GtkAccelGroup *group);
|
||||
struct nsgtk_view_menu *nsgtk_menu_view_menu(GtkAccelGroup *group);
|
||||
struct nsgtk_nav_menu *nsgtk_menu_nav_menu(GtkAccelGroup *group);
|
||||
struct nsgtk_tabs_menu *nsgtk_menu_tabs_menu(GtkAccelGroup *group);
|
||||
struct nsgtk_help_menu *nsgtk_menu_help_menu(GtkAccelGroup *group);
|
||||
|
||||
#endif
|
81
gtk/gtk_save.c
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libxml/HTMLtree.h>
|
||||
#include "content/content.h"
|
||||
#include "desktop/save_complete.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
/**
|
||||
* conducts the filesystem save appropriate to the gui
|
||||
* \param path save path
|
||||
* \param filename name of file to save
|
||||
* \param len data length
|
||||
* \param sourcedata pointer to data to save
|
||||
* \param type content type
|
||||
* \return true for success
|
||||
*/
|
||||
|
||||
bool save_complete_gui_save(const char *path, const char *filename,
|
||||
size_t len, const char *sourcedata, content_type type)
|
||||
{
|
||||
int res;
|
||||
int namelen;
|
||||
namelen = strlen(path) + strlen(filename) + 2; /* '/', '\0' */
|
||||
char *fullpath = malloc(namelen);
|
||||
if (!fullpath) {
|
||||
warn_user("NoMemory", 0);
|
||||
return false;
|
||||
}
|
||||
snprintf(fullpath, namelen, "%s/%s", path, filename);
|
||||
FILE *f;
|
||||
f = fopen(fullpath, "wb");
|
||||
free(fullpath);
|
||||
if (f == NULL)
|
||||
return false;
|
||||
res = fwrite(sourcedata, len, 1, f);
|
||||
fclose(f);
|
||||
if (res != 1)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* wrapper for lib function htmlSaveFileFormat; front sets path from path
|
||||
* + filename in a filesystem-specific way
|
||||
*/
|
||||
|
||||
int save_complete_htmlSaveFileFormat(const char *path, const char *filename,
|
||||
xmlDocPtr cur, const char *encoding, int format)
|
||||
{
|
||||
int ret;
|
||||
int len = strlen(path) + strlen(filename) + 2;
|
||||
char *fullpath = malloc(len);
|
||||
if (fullpath == NULL) {
|
||||
warn_user("NoMemory", 0);
|
||||
return -1;
|
||||
}
|
||||
snprintf(fullpath, len, "%s/%s", path, filename);
|
||||
ret = htmlSaveFileFormat(fullpath, cur, encoding, format);
|
||||
free(fullpath);
|
||||
return ret;
|
||||
}
|
||||
|
@ -21,63 +21,219 @@
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <glade/glade.h>
|
||||
#include <glib.h>
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/plotters.h"
|
||||
#include "gtk/gtk_menu.h"
|
||||
#include "gtk/sexy_icon_entry.h"
|
||||
|
||||
typedef struct gtk_scaffolding nsgtk_scaffolding;
|
||||
|
||||
struct gtk_scaffolding {
|
||||
typedef enum {
|
||||
BACK_BUTTON = 0,
|
||||
HISTORY_BUTTON,
|
||||
FORWARD_BUTTON,
|
||||
STOP_BUTTON,
|
||||
RELOAD_BUTTON,
|
||||
HOME_BUTTON,
|
||||
URL_BAR_ITEM,
|
||||
WEBSEARCH_ITEM,
|
||||
THROBBER_ITEM,
|
||||
NEWWINDOW_BUTTON,
|
||||
NEWTAB_BUTTON,
|
||||
OPENFILE_BUTTON,
|
||||
CLOSETAB_BUTTON,
|
||||
CLOSEWINDOW_BUTTON,
|
||||
SAVEPAGE_BUTTON,
|
||||
PDF_BUTTON,
|
||||
PLAINTEXT_BUTTON,
|
||||
DRAWFILE_BUTTON,
|
||||
POSTSCRIPT_BUTTON,
|
||||
PRINTPREVIEW_BUTTON,
|
||||
PRINT_BUTTON,
|
||||
QUIT_BUTTON,
|
||||
CUT_BUTTON,
|
||||
COPY_BUTTON,
|
||||
PASTE_BUTTON,
|
||||
DELETE_BUTTON,
|
||||
SELECTALL_BUTTON,
|
||||
FIND_BUTTON,
|
||||
PREFERENCES_BUTTON,
|
||||
ZOOMPLUS_BUTTON,
|
||||
ZOOMMINUS_BUTTON,
|
||||
ZOOMNORMAL_BUTTON,
|
||||
FULLSCREEN_BUTTON,
|
||||
VIEWSOURCE_BUTTON,
|
||||
DOWNLOADS_BUTTON,
|
||||
SAVEWINDOWSIZE_BUTTON,
|
||||
TOGGLEDEBUGGING_BUTTON,
|
||||
SAVEBOXTREE_BUTTON,
|
||||
SAVEDOMTREE_BUTTON,
|
||||
LOCALHISTORY_BUTTON,
|
||||
GLOBALHISTORY_BUTTON,
|
||||
ADDBOOKMARKS_BUTTON,
|
||||
SHOWBOOKMARKS_BUTTON,
|
||||
OPENLOCATION_BUTTON,
|
||||
NEXTTAB_BUTTON,
|
||||
PREVTAB_BUTTON,
|
||||
CONTENTS_BUTTON,
|
||||
GUIDE_BUTTON,
|
||||
INFO_BUTTON,
|
||||
ABOUT_BUTTON,
|
||||
PLACEHOLDER_BUTTON /* size indicator; array maximum indices */
|
||||
} nsgtk_toolbar_button; /* PLACEHOLDER_BUTTON - 1 */
|
||||
|
||||
struct gtk_history_window {
|
||||
struct gtk_scaffolding *g;
|
||||
GtkWindow *window;
|
||||
GtkNotebook *notebook;
|
||||
GtkEntry *url_bar;
|
||||
GtkEntryCompletion *url_bar_completion;
|
||||
GtkStatusbar *status_bar;
|
||||
GtkMenuItem *edit_menu;
|
||||
GtkMenuItem *tabs_menu;
|
||||
GtkToolbar *tool_bar;
|
||||
GtkToolButton *back_button;
|
||||
GtkToolButton *history_button;
|
||||
GtkToolButton *forward_button;
|
||||
GtkToolButton *stop_button;
|
||||
GtkToolButton *reload_button;
|
||||
GtkMenuBar *menu_bar;
|
||||
GtkMenuItem *back_menu;
|
||||
GtkMenuItem *forward_menu;
|
||||
GtkMenuItem *stop_menu;
|
||||
GtkMenuItem *reload_menu;
|
||||
GtkImage *throbber;
|
||||
GtkPaned *status_pane;
|
||||
|
||||
GladeXML *xml;
|
||||
|
||||
GladeXML *popup_xml;
|
||||
GtkMenu *popup_menu;
|
||||
|
||||
struct gtk_history_window *history_window;
|
||||
GtkDialog *preferences_dialog;
|
||||
|
||||
int throb_frame;
|
||||
struct gui_window *top_level;
|
||||
int being_destroyed;
|
||||
|
||||
bool fullscreen;
|
||||
GtkScrolledWindow *scrolled;
|
||||
GtkDrawingArea *drawing_area;
|
||||
};
|
||||
|
||||
GtkWindow *nsgtk_get_window_for_scaffold(struct gtk_scaffolding *g);
|
||||
struct gtk_search {
|
||||
GtkToolbar *bar;
|
||||
GtkEntry *entry;
|
||||
GtkToolButton *buttons[3]; /* back, forward, */
|
||||
GtkCheckButton *checkAll; /* close */
|
||||
GtkCheckButton *caseSens;
|
||||
};
|
||||
|
||||
struct nsgtk_button_connect {
|
||||
GtkToolItem *button;
|
||||
int location; /* in toolbar */
|
||||
bool sensitivity;
|
||||
GtkImageMenuItem *main;
|
||||
GtkImageMenuItem *rclick;
|
||||
GtkImageMenuItem *popup;
|
||||
void *mhandler; /* menu item clicked */
|
||||
void *bhandler; /* button clicked */
|
||||
void *dataplus; /* customization -> toolbar */
|
||||
void *dataminus; /* customization -> store */
|
||||
};
|
||||
|
||||
extern nsgtk_scaffolding *scaf_list;
|
||||
|
||||
nsgtk_scaffolding *nsgtk_new_scaffolding(struct gui_window *toplevel);
|
||||
|
||||
gboolean nsgtk_scaffolding_is_busy(nsgtk_scaffolding *scaffold);
|
||||
bool nsgtk_scaffolding_is_busy(nsgtk_scaffolding *g);
|
||||
|
||||
GtkWindow* nsgtk_scaffolding_get_window (struct gui_window *g);
|
||||
GtkWindow *nsgtk_scaffolding_window(nsgtk_scaffolding *g);
|
||||
GtkNotebook *nsgtk_scaffolding_notebook(nsgtk_scaffolding *g);
|
||||
GtkWidget *nsgtk_scaffolding_urlbar(nsgtk_scaffolding *g);
|
||||
GtkWidget *nsgtk_scaffolding_websearch(nsgtk_scaffolding *g);
|
||||
GtkToolbar *nsgtk_scaffolding_toolbar(nsgtk_scaffolding *g);
|
||||
struct nsgtk_button_connect *nsgtk_scaffolding_button(nsgtk_scaffolding *g,
|
||||
int i);
|
||||
struct gtk_search *nsgtk_scaffolding_search(nsgtk_scaffolding *g);
|
||||
GtkMenuBar *nsgtk_scaffolding_menu_bar(nsgtk_scaffolding *g);
|
||||
struct gtk_history_window *nsgtk_scaffolding_history_window(nsgtk_scaffolding
|
||||
*g);
|
||||
struct gui_window *nsgtk_scaffolding_top_level(nsgtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_reset_offset(nsgtk_scaffolding *g);
|
||||
nsgtk_scaffolding *nsgtk_scaffolding_iterate(nsgtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_toolbar_init(struct gtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_update_url_bar_ref(nsgtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_update_throbber_ref(nsgtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_update_websearch_ref(nsgtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_set_websearch(nsgtk_scaffolding *g, const char
|
||||
*content);
|
||||
void nsgtk_scaffolding_toggle_search_bar_visibility(nsgtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_set_top_level(struct gui_window *g);
|
||||
|
||||
GtkNotebook* nsgtk_scaffolding_get_notebook (struct gui_window *g);
|
||||
|
||||
void nsgtk_scaffolding_set_top_level (struct gui_window *gw);
|
||||
|
||||
void nsgtk_scaffolding_destroy(nsgtk_scaffolding *scaffold);
|
||||
void nsgtk_scaffolding_destroy(nsgtk_scaffolding *g);
|
||||
|
||||
void nsgtk_scaffolding_set_sensitivity(struct gtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_initial_sensitivity(struct gtk_scaffolding *g);
|
||||
void nsgtk_scaffolding_popup_menu(struct gtk_scaffolding *g, gdouble x,
|
||||
gdouble y);
|
||||
void nsgtk_scaffolding_toolbar_size_allocate(GtkWidget *widget,
|
||||
GtkAllocation *alloc, gpointer data);
|
||||
|
||||
gboolean nsgtk_window_url_activate_event(GtkWidget *, gpointer);
|
||||
gboolean nsgtk_window_url_changed(GtkWidget *, GdkEventKey *, gpointer);
|
||||
|
||||
#define MULTIPROTO(q)\
|
||||
gboolean nsgtk_on_##q##_activate(struct gtk_scaffolding *);\
|
||||
gboolean nsgtk_on_##q##_activate_menu(GtkMenuItem *, gpointer);\
|
||||
gboolean nsgtk_on_##q##_activate_button(GtkButton *, gpointer)
|
||||
#define MENUPROTO(q)\
|
||||
gboolean nsgtk_on_##q##_activate(GtkMenuItem *, gpointer)
|
||||
#define BUTTONPROTO(q)\
|
||||
gboolean nsgtk_on_##q##_activate(GtkButton *, gpointer)
|
||||
/* prototypes for handlers */
|
||||
/* file menu */
|
||||
MULTIPROTO(newwindow);
|
||||
MULTIPROTO(newtab);
|
||||
MULTIPROTO(open_location);
|
||||
MULTIPROTO(openfile);
|
||||
MULTIPROTO(savepage);
|
||||
MULTIPROTO(pdf);
|
||||
MULTIPROTO(plaintext);
|
||||
MULTIPROTO(drawfile);
|
||||
MULTIPROTO(postscript);
|
||||
MULTIPROTO(printpreview);
|
||||
MULTIPROTO(print);
|
||||
MULTIPROTO(closewindow);
|
||||
MULTIPROTO(quit);
|
||||
|
||||
/* edit menu */
|
||||
MULTIPROTO(cut);
|
||||
MULTIPROTO(copy);
|
||||
MULTIPROTO(paste);
|
||||
MULTIPROTO(delete);
|
||||
MULTIPROTO(selectall);
|
||||
MULTIPROTO(find);
|
||||
MULTIPROTO(preferences);
|
||||
|
||||
/* view menu */
|
||||
MULTIPROTO(stop);
|
||||
MULTIPROTO(reload);
|
||||
MULTIPROTO(zoomplus);
|
||||
MULTIPROTO(zoomnormal);
|
||||
MULTIPROTO(zoomminus);
|
||||
MULTIPROTO(fullscreen);
|
||||
MULTIPROTO(viewsource);
|
||||
MENUPROTO(menubar);
|
||||
MENUPROTO(toolbar);
|
||||
MENUPROTO(statusbar);
|
||||
MULTIPROTO(downloads);
|
||||
MULTIPROTO(savewindowsize);
|
||||
MULTIPROTO(toggledebugging);
|
||||
MULTIPROTO(saveboxtree);
|
||||
MULTIPROTO(savedomtree);
|
||||
|
||||
/* navigate menu */
|
||||
MULTIPROTO(back);
|
||||
MULTIPROTO(forward);
|
||||
MULTIPROTO(home);
|
||||
MULTIPROTO(localhistory);
|
||||
MULTIPROTO(globalhistory);
|
||||
MULTIPROTO(addbookmarks);
|
||||
MULTIPROTO(showbookmarks);
|
||||
MULTIPROTO(openlocation);
|
||||
|
||||
/* tabs menu */
|
||||
MULTIPROTO(nexttab);
|
||||
MULTIPROTO(prevtab);
|
||||
MULTIPROTO(closetab);
|
||||
|
||||
/* help menu */
|
||||
MULTIPROTO(contents);
|
||||
MULTIPROTO(guide);
|
||||
MULTIPROTO(info);
|
||||
MULTIPROTO(about);
|
||||
|
||||
/* popup menu */
|
||||
MENUPROTO(customize);
|
||||
MENUPROTO(savelink);
|
||||
MENUPROTO(linkfocused);
|
||||
MENUPROTO(linkbackground);
|
||||
|
||||
/* non-menu */
|
||||
BUTTONPROTO(history);
|
||||
|
||||
#undef MULTIPROTO
|
||||
#undef MENUPROTO
|
||||
#undef BUTTONPROTO
|
||||
|
||||
#endif /* NETSURF_GTK_SCAFFOLDING_H */
|
||||
|
263
gtk/gtk_search.c
Normal file
@ -0,0 +1,263 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
/** \file
|
||||
* Free text search (front component)
|
||||
*/
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include "gtk/gtk_search.h"
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
#include "gtk/gtk_window.h"
|
||||
#include "utils/config.h"
|
||||
#include "content/content.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/gui.h"
|
||||
#include "desktop/search.h"
|
||||
#include "desktop/searchweb.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "render/box.h"
|
||||
#include "render/html.h"
|
||||
#include "utils/config.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
static void nsgtk_search_init(struct gtk_scaffolding *g);
|
||||
static void nsgtk_search_set_status(bool found, void *p);
|
||||
static void nsgtk_search_set_hourglass(bool active, void *p);
|
||||
static void nsgtk_search_add_recent(const char *string, void *p);
|
||||
|
||||
static struct search_callbacks nsgtk_search_callbacks = {
|
||||
nsgtk_search_set_forward_state,
|
||||
nsgtk_search_set_back_state,
|
||||
nsgtk_search_set_status,
|
||||
nsgtk_search_set_hourglass,
|
||||
nsgtk_search_add_recent
|
||||
};
|
||||
|
||||
/** connected to the search forward button */
|
||||
|
||||
gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;
|
||||
struct browser_window *bw = gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(g));
|
||||
nsgtk_search_init(g);
|
||||
search_flags_t flags = SEARCH_FLAG_FORWARDS |
|
||||
(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
|
||||
nsgtk_scaffolding_search(g)->caseSens)) ?
|
||||
SEARCH_FLAG_CASE_SENSITIVE : 0) |
|
||||
(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
|
||||
nsgtk_scaffolding_search(g)->checkAll)) ?
|
||||
SEARCH_FLAG_SHOWALL : 0);
|
||||
if (search_verify_new(bw, &nsgtk_search_callbacks, (void *)bw))
|
||||
search_step(bw->search_context, flags, gtk_entry_get_text(
|
||||
nsgtk_scaffolding_search(g)->entry));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** connected to the search back button */
|
||||
|
||||
gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;
|
||||
struct browser_window *bw = gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(g));
|
||||
nsgtk_search_init(g);
|
||||
search_flags_t flags = 0 |(gtk_toggle_button_get_active(
|
||||
GTK_TOGGLE_BUTTON(
|
||||
nsgtk_scaffolding_search(g)->caseSens)) ?
|
||||
SEARCH_FLAG_CASE_SENSITIVE : 0) |
|
||||
(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
|
||||
nsgtk_scaffolding_search(g)->checkAll)) ?
|
||||
SEARCH_FLAG_SHOWALL : 0);
|
||||
if (search_verify_new(bw, &nsgtk_search_callbacks, (void *)bw))
|
||||
search_step(bw->search_context, flags, gtk_entry_get_text(
|
||||
nsgtk_scaffolding_search(g)->entry));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** preparatory code when the search bar is made visible initially */
|
||||
|
||||
void nsgtk_search_init(struct gtk_scaffolding *g)
|
||||
{
|
||||
struct content *c;
|
||||
|
||||
assert(gui_window_get_browser_window(nsgtk_scaffolding_top_level(g))
|
||||
!= NULL);
|
||||
|
||||
c = gui_window_get_browser_window(nsgtk_scaffolding_top_level(g))->
|
||||
current_content;
|
||||
|
||||
if ((!c) || (c->type != CONTENT_HTML && c->type != CONTENT_TEXTPLAIN))
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
/** connected to the search close button */
|
||||
|
||||
gboolean nsgtk_search_close_button_clicked(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;
|
||||
nsgtk_scaffolding_toggle_search_bar_visibility(g);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** connected to the search entry [typing] */
|
||||
|
||||
gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
nsgtk_scaffolding *g = (nsgtk_scaffolding *)data;
|
||||
struct browser_window *bw = gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(g));
|
||||
if ((bw != NULL) && (bw->search_context != NULL))
|
||||
search_destroy_context(bw->search_context);
|
||||
nsgtk_search_set_forward_state(true, (void *)bw);
|
||||
nsgtk_search_set_back_state(true, (void *)bw);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/** connected to the search entry [return key] */
|
||||
|
||||
gboolean nsgtk_search_entry_activate(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
nsgtk_scaffolding *g = (nsgtk_scaffolding *)data;
|
||||
struct browser_window *bw = gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(g));
|
||||
nsgtk_search_init(g);
|
||||
search_flags_t flags = SEARCH_FLAG_FORWARDS |
|
||||
(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
|
||||
nsgtk_scaffolding_search(g)->caseSens)) ?
|
||||
SEARCH_FLAG_CASE_SENSITIVE : 0) |
|
||||
(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(
|
||||
nsgtk_scaffolding_search(g)->checkAll)) ?
|
||||
SEARCH_FLAG_SHOWALL : 0);
|
||||
if (search_verify_new(bw, &nsgtk_search_callbacks, (void *)bw))
|
||||
search_step(bw->search_context, flags, gtk_entry_get_text(
|
||||
nsgtk_scaffolding_search(g)->entry));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** allows escape key to close search bar too */
|
||||
|
||||
gboolean nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event,
|
||||
gpointer data)
|
||||
{
|
||||
if (event->keyval == GDK_Escape) {
|
||||
struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;
|
||||
nsgtk_scaffolding_toggle_search_bar_visibility(g);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/** connected to the websearch entry [return key] */
|
||||
|
||||
gboolean nsgtk_websearch_activate(GtkWidget *widget, gpointer data)
|
||||
{
|
||||
struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;
|
||||
temp_open_background = 0;
|
||||
search_web_new_window(gui_window_get_browser_window(
|
||||
nsgtk_scaffolding_top_level(g)),
|
||||
(char *)gtk_entry_get_text(GTK_ENTRY(
|
||||
nsgtk_scaffolding_websearch(g))));
|
||||
temp_open_background = -1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* allows a click in the websearch entry field to clear the name of the
|
||||
* provider
|
||||
*/
|
||||
|
||||
gboolean nsgtk_websearch_clear(GtkWidget *widget, GdkEventFocus *f,
|
||||
gpointer data)
|
||||
{
|
||||
struct gtk_scaffolding *g = (struct gtk_scaffolding *)data;
|
||||
gtk_editable_select_region(GTK_EDITABLE(
|
||||
nsgtk_scaffolding_websearch(g)), 0, -1);
|
||||
gtk_widget_grab_focus(GTK_WIDGET(nsgtk_scaffolding_websearch(g)));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the displayed search status.
|
||||
* \param found search pattern matched in text
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void nsgtk_search_set_status(bool found, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* display hourglass while searching
|
||||
* \param active start/stop indicator
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void nsgtk_search_set_hourglass(bool active, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* add search string to recent searches list
|
||||
* front is at liberty how to implement the bare notification
|
||||
* should normally store a strdup() of the string;
|
||||
* core gives no guarantee of the integrity of the const char *
|
||||
* \param string search pattern
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void nsgtk_search_add_recent(const char *string, void *p)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search forwards button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void nsgtk_search_set_forward_state(bool active, void *p)
|
||||
{
|
||||
struct browser_window *bw = (struct browser_window *)p;
|
||||
if ((bw != NULL) && (bw->window != NULL)) {
|
||||
struct gtk_scaffolding *g = nsgtk_get_scaffold(bw->window);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_search(
|
||||
g)->buttons[1]), active);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* activate search back button in gui
|
||||
* \param active activate/inactivate
|
||||
* \param p the pointer sent to search_verify_new() / search_create_context()
|
||||
*/
|
||||
|
||||
void nsgtk_search_set_back_state(bool active, void *p)
|
||||
{
|
||||
struct browser_window *bw = (struct browser_window *)p;
|
||||
if ((bw != NULL) && (bw->window != NULL)) {
|
||||
struct gtk_scaffolding *g = nsgtk_get_scaffold(bw->window);
|
||||
gtk_widget_set_sensitive(GTK_WIDGET(nsgtk_scaffolding_search(
|
||||
g)->buttons[0]), active);
|
||||
}
|
||||
}
|
39
gtk/gtk_search.h
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_GTK_SEARCH_H_
|
||||
#define _NETSURF_GTK_SEARCH_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
|
||||
void nsgtk_search_bar_toggle_visibility(struct gtk_scaffolding * g);
|
||||
gboolean nsgtk_search_entry_changed(GtkWidget *widget, gpointer data);
|
||||
gboolean nsgtk_search_entry_activate(GtkWidget *widget, gpointer data);
|
||||
gboolean nsgtk_search_entry_key(GtkWidget *widget, GdkEventKey *event,
|
||||
gpointer data);
|
||||
gboolean nsgtk_search_forward_button_clicked(GtkWidget *widget, gpointer data);
|
||||
gboolean nsgtk_search_back_button_clicked(GtkWidget *widget, gpointer data);
|
||||
gboolean nsgtk_search_close_button_clicked(GtkWidget *widget, gpointer data);
|
||||
gboolean nsgtk_websearch_activate(GtkWidget *widget, gpointer data);
|
||||
gboolean nsgtk_websearch_clear(GtkWidget *widget, GdkEventFocus *f,
|
||||
gpointer data);
|
||||
void nsgtk_search_set_forward_state(bool active, void *p);
|
||||
void nsgtk_search_set_back_state(bool active, void *p);
|
||||
|
||||
#endif
|
@ -79,7 +79,7 @@ void gui_start_selection(struct gui_window *g)
|
||||
else
|
||||
g_string_set_size(current_selection, 0);
|
||||
|
||||
gtk_widget_grab_focus(GTK_WIDGET(g->drawing_area));
|
||||
gtk_widget_grab_focus(GTK_WIDGET(nsgtk_window_get_drawing_area(g)));
|
||||
}
|
||||
|
||||
void gui_paste_from_clipboard(struct gui_window *g, int x, int y)
|
||||
@ -89,7 +89,8 @@ void gui_paste_from_clipboard(struct gui_window *g, int x, int y)
|
||||
text = gtk_clipboard_wait_for_text (clipboard);
|
||||
/* clipboard_wait... converts the string to utf8 for us */
|
||||
if (text != NULL)
|
||||
browser_window_paste_text(g->bw, text, strlen(text), true);
|
||||
browser_window_paste_text(gui_window_get_browser_window(g),
|
||||
text, strlen(text), true);
|
||||
g_free(text);
|
||||
}
|
||||
|
||||
|
@ -23,12 +23,14 @@
|
||||
#include "desktop/browser.h"
|
||||
#include "content/content.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/search.h"
|
||||
#include "utils/utils.h"
|
||||
#include "gtk/options.h"
|
||||
#include "gtk/gtk_search.h"
|
||||
#include "gtk/gtk_tabs.h"
|
||||
|
||||
#define TAB_WIDTH_N_CHARS 15
|
||||
#define GET_WIDGET(x) glade_xml_get_widget(gladeWindows, (x))
|
||||
#define GET_WIDGET(x) glade_xml_get_widget(gladeNetsurf, (x))
|
||||
|
||||
static GtkWidget *nsgtk_tab_label_setup(struct gui_window *window);
|
||||
static void nsgtk_tab_visibility_update(GtkNotebook *notebook, GtkWidget *child,
|
||||
@ -58,15 +60,19 @@ void nsgtk_tab_init(GtkWidget *tabs)
|
||||
|
||||
void nsgtk_tab_add(struct gui_window *window, bool background)
|
||||
{
|
||||
GtkWidget *tabs = GTK_WIDGET(nsgtk_scaffolding_get_notebook(window));
|
||||
GtkWidget *tabs = GTK_WIDGET(nsgtk_scaffolding_notebook(
|
||||
nsgtk_get_scaffold(window)));
|
||||
GtkWidget *tabBox = nsgtk_tab_label_setup(window);
|
||||
gint remember = gtk_notebook_get_current_page(GTK_NOTEBOOK(tabs));
|
||||
gtk_notebook_append_page(GTK_NOTEBOOK(tabs),
|
||||
GTK_WIDGET(window->scrolledwindow), tabBox);
|
||||
/*causes gtk errors can't set a parent
|
||||
GTK_WIDGET(nsgtk_window_get_scrolledwindow(window)),
|
||||
tabBox);
|
||||
/*causes gtk errors can't set a parent */
|
||||
gtk_notebook_set_tab_reorderable(GTK_NOTEBOOK(tabs),
|
||||
GTK_WIDGET(window->scrolledwindow), true); */
|
||||
gtk_widget_show_all(GTK_WIDGET(window->scrolledwindow));
|
||||
GTK_WIDGET(nsgtk_window_get_scrolledwindow(window)),
|
||||
true);
|
||||
gtk_widget_show_all(GTK_WIDGET(nsgtk_window_get_scrolledwindow(
|
||||
window)));
|
||||
gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs),
|
||||
gtk_notebook_get_n_pages(GTK_NOTEBOOK(tabs)) - 1);
|
||||
if (option_new_blank) {
|
||||
@ -75,13 +81,15 @@ void nsgtk_tab_add(struct gui_window *window, bool background)
|
||||
blankpage = g_strconcat("file:///", res_dir_location,
|
||||
"blankpage", NULL); */
|
||||
/* segfaults
|
||||
struct browser_window *bw = nsgtk_get_browser_for_gui(window);
|
||||
struct browser_window *bw =
|
||||
gui_window_get_browser_window(window);
|
||||
browser_window_go(bw, blankpage, 0, true); */
|
||||
/* free(blankpage); */
|
||||
}
|
||||
if (background)
|
||||
gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs), remember);
|
||||
gtk_widget_grab_focus(GTK_WIDGET(window->scaffold->url_bar));
|
||||
gtk_widget_grab_focus(GTK_WIDGET(nsgtk_scaffolding_urlbar(
|
||||
nsgtk_get_scaffold(window))));
|
||||
}
|
||||
|
||||
void nsgtk_tab_visibility_update(GtkNotebook *notebook, GtkWidget *child,
|
||||
@ -97,12 +105,14 @@ void nsgtk_tab_visibility_update(GtkNotebook *notebook, GtkWidget *child,
|
||||
void nsgtk_tab_set_title(struct gui_window *g, const char *title)
|
||||
{
|
||||
GtkWidget *label;
|
||||
gboolean is_top_level = (g->tab != NULL);
|
||||
GtkWidget *tab;
|
||||
tab = nsgtk_window_get_tab(g);
|
||||
gboolean is_top_level = (tab != NULL);
|
||||
|
||||
if (is_top_level) {
|
||||
label = g_object_get_data(G_OBJECT(g->tab), "label");
|
||||
label = g_object_get_data(G_OBJECT(tab), "label");
|
||||
gtk_label_set_text(GTK_LABEL(label), title);
|
||||
gtk_widget_set_tooltip_text(g->tab, title);
|
||||
gtk_widget_set_tooltip_text(tab, title);
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,7 +157,7 @@ GtkWidget *nsgtk_tab_label_setup(struct gui_window *window)
|
||||
g_object_set_data(G_OBJECT(hbox), "label", label);
|
||||
g_object_set_data(G_OBJECT(hbox), "close-button", button);
|
||||
|
||||
window->tab = hbox;
|
||||
nsgtk_window_set_tab(window, hbox);
|
||||
|
||||
gtk_widget_show_all(hbox);
|
||||
return hbox;
|
||||
@ -183,6 +193,11 @@ void nsgtk_tab_page_changed(GtkNotebook *notebook, GtkNotebookPage *page,
|
||||
GtkWidget *window = gtk_notebook_get_nth_page(notebook, page_num);
|
||||
struct gui_window *gw = g_object_get_data(G_OBJECT(window),
|
||||
"gui_window");
|
||||
struct browser_window *bw = gui_window_get_browser_window(gw);
|
||||
if ((bw != NULL) && (bw->search_context != NULL))
|
||||
search_destroy_context(bw->search_context);
|
||||
nsgtk_search_set_forward_state(true, bw);
|
||||
nsgtk_search_set_back_state(true, bw);
|
||||
if (gw)
|
||||
nsgtk_scaffolding_set_top_level(gw);
|
||||
}
|
||||
|
773
gtk/gtk_theme.c
Normal file
@ -0,0 +1,773 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include "content/content.h"
|
||||
#include "content/content_type.h"
|
||||
#include "gtk/gtk_gui.h"
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
#include "gtk/gtk_menu.h"
|
||||
#include "gtk/gtk_theme.h"
|
||||
#include "gtk/gtk_window.h"
|
||||
#include "gtk/options.h"
|
||||
#include "gtk/dialogs/gtk_options.h"
|
||||
#include "utils/container.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/messages.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
enum image_sets {
|
||||
IMAGE_SET_MAIN_MENU = 0,
|
||||
IMAGE_SET_RCLICK_MENU,
|
||||
IMAGE_SET_POPUP_MENU,
|
||||
IMAGE_SET_BUTTONS,
|
||||
IMAGE_SET_COUNT
|
||||
};
|
||||
|
||||
struct nsgtk_theme_cache {
|
||||
GdkPixbuf *image[PLACEHOLDER_BUTTON];
|
||||
GdkPixbuf *searchimage[SEARCH_BUTTONS_COUNT];
|
||||
/* apng throbber image */
|
||||
};
|
||||
|
||||
static char *current_theme_name = NULL;
|
||||
static struct nsgtk_theme_cache *theme_cache_menu = NULL;
|
||||
static struct nsgtk_theme_cache *theme_cache_toolbar = NULL;
|
||||
|
||||
static struct nsgtk_theme *nsgtk_theme_default(GtkIconSize s);
|
||||
static GtkImage *nsgtk_theme_image_default(nsgtk_toolbar_button i,
|
||||
GtkIconSize s);
|
||||
static bool nsgtk_theme_verify(const char *themename);
|
||||
static void nsgtk_theme_cache_image(nsgtk_toolbar_button i,
|
||||
const char *filename, const char *path);
|
||||
static void nsgtk_theme_cache_searchimage(nsgtk_search_buttons i,
|
||||
const char *filename, const char *path);
|
||||
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
static struct content *theme_install_content = NULL;
|
||||
|
||||
static void theme_install_callback(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data);
|
||||
static bool theme_install_read(const char *data, unsigned long len);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* called during gui init phase to retrieve theme name from file then
|
||||
* implement
|
||||
*/
|
||||
|
||||
void nsgtk_theme_init(void)
|
||||
{
|
||||
size_t len;
|
||||
if (option_current_theme == 0)
|
||||
return;
|
||||
len = SLEN("themelist") + strlen(res_dir_location) + 1;
|
||||
char themefile[len];
|
||||
snprintf(themefile, len, "%s%s", res_dir_location, "themelist");
|
||||
nsgtk_scaffolding *list = scaf_list;
|
||||
nsgtk_theme_verify(NULL);
|
||||
FILE *fp = fopen(themefile, "r");
|
||||
if (fp == NULL)
|
||||
return;
|
||||
char buf[50];
|
||||
int row_count = 0;
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
if (buf[0] == '\0')
|
||||
continue;
|
||||
|
||||
if (row_count++ == option_current_theme) {
|
||||
if (current_theme_name != NULL)
|
||||
free(current_theme_name);
|
||||
/* clear the '\n' ["\n\0"->"\0\0"] */
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
current_theme_name = strdup(buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
while (list != NULL) {
|
||||
nsgtk_theme_implement(list);
|
||||
list = nsgtk_scaffolding_iterate(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* return reference to static global current_theme_name; caller then has
|
||||
* responsibility for global reference
|
||||
*/
|
||||
|
||||
char *nsgtk_theme_name(void)
|
||||
{
|
||||
return current_theme_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* set static global current_theme_name from param; caller is responsible
|
||||
* for the integrity of the global reference
|
||||
*/
|
||||
|
||||
void nsgtk_theme_set_name(char *name)
|
||||
{
|
||||
current_theme_name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a theme name to the list of themes
|
||||
*/
|
||||
|
||||
void nsgtk_theme_add(const char *themename)
|
||||
{
|
||||
size_t len;
|
||||
GtkWidget *notification, *label;
|
||||
len = SLEN("themelist") + strlen(res_dir_location) + 1;
|
||||
char themefile[len];
|
||||
snprintf(themefile, len, "%s%s", res_dir_location, "themelist");
|
||||
/* conduct verification here; no adding duplicates to list */
|
||||
if (nsgtk_theme_verify(themename) == false) {
|
||||
warn_user(messages_get("gtkThemeDup"), 0);
|
||||
return;
|
||||
}
|
||||
FILE *fp = fopen(themefile, "a");
|
||||
if (fp == NULL) {
|
||||
warn_user(messages_get("gtkFileError"), themefile);
|
||||
return;
|
||||
}
|
||||
fprintf(fp, "%s\n", themename);
|
||||
fclose(fp);
|
||||
|
||||
/* notification that theme was added successfully */
|
||||
notification = gtk_dialog_new_with_buttons(messages_get("gtkThemeAdd"),
|
||||
NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_OK,
|
||||
GTK_RESPONSE_NONE, NULL);
|
||||
if (notification == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
len = SLEN("\t\t\t\t\t\t") + strlen(messages_get("gtkThemeAdd")) + 1;
|
||||
char labelcontent[len];
|
||||
snprintf(labelcontent, len, "\t\t\t%s\t\t\t",
|
||||
messages_get("gtkThemeAdd"));
|
||||
label = gtk_label_new(labelcontent);
|
||||
if (label == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return;
|
||||
}
|
||||
g_signal_connect_swapped(notification, "response",
|
||||
G_CALLBACK(gtk_widget_destroy), notification);
|
||||
gtk_container_add(GTK_CONTAINER(GTK_DIALOG(notification)->vbox), label);
|
||||
gtk_widget_show_all(notification);
|
||||
|
||||
/* update combo */
|
||||
if (wndPreferences == NULL)
|
||||
return;
|
||||
nsgtk_options_combo_theme_add(themename);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* \param themename contains a name of theme to check whether it may
|
||||
* properly be added to the list; alternatively NULL to check the integrity
|
||||
* of the list
|
||||
* \return true for themename may be added / every item in the list is
|
||||
* a valid directory
|
||||
*/
|
||||
|
||||
bool nsgtk_theme_verify(const char *themename)
|
||||
{
|
||||
long filelength;
|
||||
FILE *fp;
|
||||
size_t val = SLEN("themelist") + strlen(res_dir_location) + 1;
|
||||
char buf[50];
|
||||
char themefile[val];
|
||||
snprintf(themefile, val, "%s%s", res_dir_location, "themelist");
|
||||
if (themename == NULL) {
|
||||
char *filecontent, *testfile;
|
||||
struct stat sta;
|
||||
fp = fopen(themefile, "r+");
|
||||
if (fp == NULL) {
|
||||
warn_user(messages_get("gtkFileError"), themefile);
|
||||
return true;
|
||||
}
|
||||
fseek(fp, 0L, SEEK_END);
|
||||
filelength = ftell(fp);
|
||||
filecontent = malloc(filelength +
|
||||
SLEN("gtk default theme\n") + SLEN("\n")
|
||||
+ 1);
|
||||
if (filecontent == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return true;
|
||||
}
|
||||
strcpy(filecontent, "gtk default theme\n");
|
||||
fseek(fp, 0L, SEEK_SET);
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
/* iterate list */
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
/* "\n\0" -> "\0\0" */
|
||||
testfile = malloc(strlen(res_dir_location) +
|
||||
SLEN("themes/") + strlen(buf) + 1);
|
||||
if (testfile == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
free(filecontent);
|
||||
return false;
|
||||
}
|
||||
sprintf(testfile, "%sthemes/%s", res_dir_location,
|
||||
buf);
|
||||
/* check every directory */
|
||||
if (access(testfile, R_OK) == 0) {
|
||||
stat(testfile, &sta);
|
||||
if (S_ISDIR(sta.st_mode)) {
|
||||
buf[strlen(buf)] = '\n';
|
||||
/* "\0\0" -> "\n\0" */
|
||||
strcat(filecontent, buf);
|
||||
}
|
||||
}
|
||||
free(testfile);
|
||||
}
|
||||
fclose(fp);
|
||||
fp = fopen(themefile, "w");
|
||||
if (fp == NULL) {
|
||||
warn_user(messages_get("gtkFileError"), themefile);
|
||||
free(filecontent);
|
||||
return true;
|
||||
}
|
||||
val = fwrite(filecontent, strlen(filecontent), 1, fp);
|
||||
if (val == 0)
|
||||
LOG(("empty write themelist"));
|
||||
fclose(fp);
|
||||
free(filecontent);
|
||||
return true;
|
||||
} else {
|
||||
fp = fopen(themefile, "r");
|
||||
if (fp == NULL) {
|
||||
warn_user(messages_get("gtkFileError"), themefile);
|
||||
return false;
|
||||
}
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
buf[strlen(buf) - 1] = '\0';
|
||||
/* "\n\0" -> "\0\0" */
|
||||
if (strcmp(buf, themename) == 0) {
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the images for a particular scaffolding according to the current theme
|
||||
*/
|
||||
|
||||
void nsgtk_theme_implement(struct gtk_scaffolding *g)
|
||||
{
|
||||
struct nsgtk_theme *theme[IMAGE_SET_COUNT];
|
||||
int i;
|
||||
struct nsgtk_button_connect *button;
|
||||
struct gtk_search *search;
|
||||
|
||||
for (i = 0; i <= IMAGE_SET_POPUP_MENU; i++)
|
||||
theme[i] = nsgtk_theme_load(GTK_ICON_SIZE_MENU);
|
||||
|
||||
theme[IMAGE_SET_BUTTONS] =
|
||||
nsgtk_theme_load(GTK_ICON_SIZE_LARGE_TOOLBAR);
|
||||
|
||||
for (i = BACK_BUTTON; i < PLACEHOLDER_BUTTON; i++) {
|
||||
if ((i == URL_BAR_ITEM) || (i == THROBBER_ITEM) ||
|
||||
(i == WEBSEARCH_ITEM))
|
||||
continue;
|
||||
button = nsgtk_scaffolding_button(g, i);
|
||||
if (button == NULL)
|
||||
continue;
|
||||
/* gtk_image_menu_item_set_image accepts NULL image */
|
||||
if ((button->main != NULL) &&
|
||||
(theme[IMAGE_SET_MAIN_MENU] != NULL)) {
|
||||
gtk_image_menu_item_set_image(button->main,
|
||||
GTK_WIDGET(
|
||||
theme[IMAGE_SET_MAIN_MENU]->
|
||||
image[i]));
|
||||
gtk_widget_show_all(GTK_WIDGET(button->main));
|
||||
}
|
||||
if ((button->rclick != NULL) &&
|
||||
(theme[IMAGE_SET_RCLICK_MENU] != NULL)) {
|
||||
gtk_image_menu_item_set_image(button->rclick,
|
||||
GTK_WIDGET(
|
||||
theme[IMAGE_SET_RCLICK_MENU]->
|
||||
image[i]));
|
||||
gtk_widget_show_all(GTK_WIDGET(button->rclick));
|
||||
}
|
||||
if ((button->popup != NULL) &&
|
||||
(theme[IMAGE_SET_POPUP_MENU] != NULL)) {
|
||||
gtk_image_menu_item_set_image(button->popup,
|
||||
GTK_WIDGET(
|
||||
theme[IMAGE_SET_POPUP_MENU]->
|
||||
image[i]));
|
||||
gtk_widget_show_all(GTK_WIDGET(button->popup));
|
||||
}
|
||||
if ((button->location != -1) && (button->button != NULL) &&
|
||||
(theme[IMAGE_SET_BUTTONS] != NULL)) {
|
||||
gtk_tool_button_set_icon_widget(
|
||||
GTK_TOOL_BUTTON(button->button),
|
||||
GTK_WIDGET(
|
||||
theme[IMAGE_SET_BUTTONS]->
|
||||
image[i]));
|
||||
gtk_widget_show_all(GTK_WIDGET(button->button));
|
||||
}
|
||||
}
|
||||
|
||||
/* set search bar images */
|
||||
search = nsgtk_scaffolding_search(g);
|
||||
if ((search != NULL) && (theme[IMAGE_SET_MAIN_MENU] != NULL)) {
|
||||
/* gtk_tool_button_set_icon_widget accepts NULL image */
|
||||
if (search->buttons[SEARCH_BACK_BUTTON] != NULL) {
|
||||
gtk_tool_button_set_icon_widget(
|
||||
search->buttons[SEARCH_BACK_BUTTON],
|
||||
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
|
||||
searchimage[SEARCH_BACK_BUTTON]));
|
||||
gtk_widget_show_all(GTK_WIDGET(
|
||||
search->buttons[SEARCH_BACK_BUTTON]));
|
||||
}
|
||||
if (search->buttons[SEARCH_FORWARD_BUTTON] != NULL) {
|
||||
gtk_tool_button_set_icon_widget(
|
||||
search->buttons[SEARCH_FORWARD_BUTTON],
|
||||
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
|
||||
searchimage[SEARCH_FORWARD_BUTTON]));
|
||||
gtk_widget_show_all(GTK_WIDGET(
|
||||
search->buttons[
|
||||
SEARCH_FORWARD_BUTTON]));
|
||||
}
|
||||
if (search->buttons[SEARCH_CLOSE_BUTTON] != NULL) {
|
||||
gtk_tool_button_set_icon_widget(
|
||||
search->buttons[SEARCH_CLOSE_BUTTON],
|
||||
GTK_WIDGET(theme[IMAGE_SET_MAIN_MENU]->
|
||||
searchimage[SEARCH_CLOSE_BUTTON]));
|
||||
gtk_widget_show_all(GTK_WIDGET(
|
||||
search->buttons[SEARCH_CLOSE_BUTTON]));
|
||||
}
|
||||
}
|
||||
for (i = 0; i < IMAGE_SET_COUNT; i++)
|
||||
if (theme[i] != NULL)
|
||||
free(theme[i]);
|
||||
}
|
||||
|
||||
/**
|
||||
* creates a set of images to add to buttons / menus
|
||||
* loads images from cache, calling an update to the cache when necessary
|
||||
* \return a struct nsgtk_theme is an array of images
|
||||
*/
|
||||
|
||||
struct nsgtk_theme *nsgtk_theme_load(GtkIconSize s)
|
||||
{
|
||||
if (current_theme_name == NULL)
|
||||
return nsgtk_theme_default(s);
|
||||
|
||||
struct nsgtk_theme *theme = malloc(sizeof(struct nsgtk_theme));
|
||||
if (theme == NULL)
|
||||
return theme;
|
||||
|
||||
if ((theme_cache_menu == NULL) || (theme_cache_toolbar == NULL))
|
||||
nsgtk_theme_prepare();
|
||||
|
||||
/* load theme from cache */
|
||||
struct nsgtk_theme_cache *cachetheme = (s == GTK_ICON_SIZE_MENU) ?
|
||||
theme_cache_menu : theme_cache_toolbar;
|
||||
if (cachetheme == NULL)
|
||||
return NULL;
|
||||
|
||||
#define SET_BUTTON_IMAGE(p, q, r)\
|
||||
if (p->image[q##_BUTTON] != NULL)\
|
||||
r->image[q##_BUTTON] = GTK_IMAGE(gtk_image_new_from_pixbuf(\
|
||||
p->image[q##_BUTTON]));\
|
||||
else\
|
||||
r->image[q##_BUTTON] = nsgtk_theme_image_default(\
|
||||
q##_BUTTON, s);
|
||||
|
||||
SET_BUTTON_IMAGE(cachetheme, BACK, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, HISTORY, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, FORWARD, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, STOP, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, RELOAD, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, HOME, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, NEWWINDOW, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, NEWTAB, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, OPENFILE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, CLOSETAB, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, CLOSEWINDOW, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, SAVEPAGE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, PRINTPREVIEW, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, PRINT, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, QUIT, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, CUT, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, COPY, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, PASTE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, DELETE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, SELECTALL, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, PREFERENCES, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, ZOOMPLUS, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, ZOOMMINUS, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, ZOOMNORMAL, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, FULLSCREEN, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, VIEWSOURCE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, CONTENTS, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, ABOUT, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, PDF, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, PLAINTEXT, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, DRAWFILE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, POSTSCRIPT, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, FIND, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, DOWNLOADS, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, SAVEWINDOWSIZE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, TOGGLEDEBUGGING, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, SAVEBOXTREE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, SAVEDOMTREE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, LOCALHISTORY, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, GLOBALHISTORY, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, ADDBOOKMARKS, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, SHOWBOOKMARKS, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, OPENLOCATION, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, NEXTTAB, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, PREVTAB, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, GUIDE, theme)
|
||||
SET_BUTTON_IMAGE(cachetheme, INFO, theme)
|
||||
#undef SET_BUTTON_IMAGE
|
||||
#define SET_BUTTON_IMAGE(p, q, qq, r)\
|
||||
if (qq->searchimage[SEARCH_##p##_BUTTON] != NULL)\
|
||||
r->searchimage[SEARCH_##p##_BUTTON] =\
|
||||
GTK_IMAGE(gtk_image_new_from_pixbuf(\
|
||||
qq->searchimage[\
|
||||
SEARCH_##p##_BUTTON]));\
|
||||
else if (qq->image[q##_BUTTON] != NULL)\
|
||||
r->searchimage[SEARCH_##p##_BUTTON] =\
|
||||
GTK_IMAGE(gtk_image_new_from_pixbuf(\
|
||||
qq->image[q##_BUTTON]));\
|
||||
else\
|
||||
r->searchimage[SEARCH_##p##_BUTTON] =\
|
||||
nsgtk_theme_image_default(\
|
||||
PLACEHOLDER_BUTTON + SEARCH_##p##_BUTTON, s);
|
||||
|
||||
SET_BUTTON_IMAGE(BACK, BACK, cachetheme, theme)
|
||||
SET_BUTTON_IMAGE(FORWARD, FORWARD, cachetheme, theme)
|
||||
SET_BUTTON_IMAGE(CLOSE, CLOSEWINDOW, cachetheme, theme)
|
||||
#undef SET_BUTTON_IMAGE
|
||||
return theme;
|
||||
}
|
||||
|
||||
/**
|
||||
* caches individual theme images from file
|
||||
* \param i the toolbar button reference
|
||||
* \param filename the image file name
|
||||
* \param path the path to the theme folder
|
||||
*/
|
||||
void nsgtk_theme_cache_image(nsgtk_toolbar_button i, const char *filename,
|
||||
const char *path)
|
||||
{
|
||||
char fullpath[strlen(filename) + strlen(path) + 1];
|
||||
sprintf(fullpath, "%s%s", path, filename);
|
||||
if (theme_cache_toolbar != NULL)
|
||||
theme_cache_toolbar->image[i] =
|
||||
gdk_pixbuf_new_from_file_at_size(fullpath,
|
||||
24, 24, NULL);
|
||||
if (theme_cache_menu != NULL)
|
||||
theme_cache_menu->image[i] = gdk_pixbuf_new_from_file_at_size(
|
||||
fullpath, 16, 16, NULL);
|
||||
}
|
||||
|
||||
void nsgtk_theme_cache_searchimage(nsgtk_search_buttons i,
|
||||
const char *filename, const char *path)
|
||||
{
|
||||
char fullpath[strlen(filename) + strlen(path) + 1];
|
||||
sprintf(fullpath, "%s%s", path, filename);
|
||||
if (theme_cache_toolbar != NULL)
|
||||
theme_cache_toolbar->searchimage[i] =
|
||||
gdk_pixbuf_new_from_file_at_size(fullpath,
|
||||
24, 24, NULL);
|
||||
if (theme_cache_menu != NULL)
|
||||
theme_cache_menu->searchimage[i] =
|
||||
gdk_pixbuf_new_from_file_at_size(fullpath,
|
||||
16, 16, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* caches theme images from file as pixbufs
|
||||
*/
|
||||
void nsgtk_theme_prepare(void)
|
||||
{
|
||||
if (current_theme_name == NULL)
|
||||
return;
|
||||
if (theme_cache_menu == NULL)
|
||||
theme_cache_menu = malloc(sizeof(struct nsgtk_theme_cache));
|
||||
if (theme_cache_toolbar == NULL)
|
||||
theme_cache_toolbar = malloc(sizeof(struct nsgtk_theme_cache));
|
||||
size_t len = strlen(res_dir_location) + SLEN("/themes/") +
|
||||
strlen(current_theme_name) + 1;
|
||||
char path[len];
|
||||
snprintf(path, len, "%sthemes/%s/", res_dir_location,
|
||||
current_theme_name);
|
||||
#define CACHE_IMAGE(p, q, r)\
|
||||
nsgtk_theme_cache_image(p##_BUTTON, #q ".png", r)
|
||||
|
||||
CACHE_IMAGE(BACK, back, path);
|
||||
CACHE_IMAGE(HISTORY, history, path);
|
||||
CACHE_IMAGE(FORWARD, forward, path);
|
||||
CACHE_IMAGE(STOP, stop, path);
|
||||
CACHE_IMAGE(RELOAD, reload, path);
|
||||
CACHE_IMAGE(HOME, home, path);
|
||||
CACHE_IMAGE(NEWWINDOW, newwindow, path);
|
||||
CACHE_IMAGE(NEWTAB, newtab, path);
|
||||
CACHE_IMAGE(OPENFILE, openfile, path);
|
||||
CACHE_IMAGE(CLOSETAB, closetab, path);
|
||||
CACHE_IMAGE(CLOSEWINDOW, closewindow, path);
|
||||
CACHE_IMAGE(SAVEPAGE, savepage, path);
|
||||
CACHE_IMAGE(PRINTPREVIEW, printpreview, path);
|
||||
CACHE_IMAGE(PRINT, print, path);
|
||||
CACHE_IMAGE(QUIT, quit, path);
|
||||
CACHE_IMAGE(CUT, cut, path);
|
||||
CACHE_IMAGE(COPY, copy, path);
|
||||
CACHE_IMAGE(PASTE, paste, path);
|
||||
CACHE_IMAGE(DELETE, delete, path);
|
||||
CACHE_IMAGE(SELECTALL, selectall, path);
|
||||
CACHE_IMAGE(PREFERENCES, preferences, path);
|
||||
CACHE_IMAGE(ZOOMPLUS, zoomplus, path);
|
||||
CACHE_IMAGE(ZOOMMINUS, zoomminus, path);
|
||||
CACHE_IMAGE(ZOOMNORMAL, zoomnormal, path);
|
||||
CACHE_IMAGE(FULLSCREEN, fullscreen, path);
|
||||
CACHE_IMAGE(VIEWSOURCE, viewsource, path);
|
||||
CACHE_IMAGE(CONTENTS, helpcontents, path);
|
||||
CACHE_IMAGE(ABOUT, helpabout, path);
|
||||
CACHE_IMAGE(PDF, pdf, path);
|
||||
CACHE_IMAGE(PLAINTEXT, plaintext, path);
|
||||
CACHE_IMAGE(DRAWFILE, drawfile, path);
|
||||
CACHE_IMAGE(POSTSCRIPT, postscript, path);
|
||||
CACHE_IMAGE(FIND, find, path);
|
||||
CACHE_IMAGE(DOWNLOADS, downloads, path);
|
||||
CACHE_IMAGE(SAVEWINDOWSIZE, savewindowsize, path);
|
||||
CACHE_IMAGE(TOGGLEDEBUGGING, toggledebugging, path);
|
||||
CACHE_IMAGE(SAVEBOXTREE, boxtree, path);
|
||||
CACHE_IMAGE(SAVEDOMTREE, domtree, path);
|
||||
CACHE_IMAGE(LOCALHISTORY, localhistory, path);
|
||||
CACHE_IMAGE(GLOBALHISTORY, globalhistory, path);
|
||||
CACHE_IMAGE(ADDBOOKMARKS, addbookmarks, path);
|
||||
CACHE_IMAGE(SHOWBOOKMARKS, showbookmarks, path);
|
||||
CACHE_IMAGE(OPENLOCATION, openlocation, path);
|
||||
CACHE_IMAGE(NEXTTAB, nexttab, path);
|
||||
CACHE_IMAGE(PREVTAB, prevtab, path);
|
||||
CACHE_IMAGE(GUIDE, helpguide, path);
|
||||
CACHE_IMAGE(INFO, helpinfo, path);
|
||||
#undef CACHE_IMAGE
|
||||
#define CACHE_IMAGE(p, q, r)\
|
||||
nsgtk_theme_cache_searchimage(p, #q ".png", r);
|
||||
|
||||
CACHE_IMAGE(SEARCH_BACK_BUTTON, searchback, path);
|
||||
CACHE_IMAGE(SEARCH_FORWARD_BUTTON, searchforward, path);
|
||||
CACHE_IMAGE(SEARCH_CLOSE_BUTTON, searchclose, path);
|
||||
#undef CACHE_IMAGE
|
||||
}
|
||||
|
||||
/**
|
||||
* returns default image for buttons / menu items from gtk stock items
|
||||
* \param i button reference
|
||||
*/
|
||||
|
||||
GtkImage *nsgtk_theme_image_default(nsgtk_toolbar_button i, GtkIconSize s)
|
||||
{
|
||||
char *imagefile;
|
||||
GtkImage *image;
|
||||
switch(i) {
|
||||
#define BUTTON_IMAGE(p, q)\
|
||||
case p##_BUTTON:\
|
||||
return GTK_IMAGE(gtk_image_new_from_stock(#q, s))
|
||||
|
||||
BUTTON_IMAGE(BACK, gtk-go-back);
|
||||
case HISTORY_BUTTON: {
|
||||
size_t len = SLEN("arrow_down_8x32.png") +
|
||||
strlen(res_dir_location) + 1;
|
||||
imagefile = malloc(len);
|
||||
if (imagefile == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(imagefile, len, "%sarrow_down_8x32.png",
|
||||
res_dir_location);
|
||||
image = GTK_IMAGE(gtk_image_new_from_file(imagefile));
|
||||
free(imagefile);
|
||||
return image;
|
||||
}
|
||||
BUTTON_IMAGE(FORWARD, gtk-go-forward);
|
||||
BUTTON_IMAGE(STOP, gtk-stop);
|
||||
BUTTON_IMAGE(RELOAD, gtk-refresh);
|
||||
BUTTON_IMAGE(HOME, gtk-home);
|
||||
BUTTON_IMAGE(NEWWINDOW, gtk-new);
|
||||
BUTTON_IMAGE(NEWTAB, gtk-new);
|
||||
BUTTON_IMAGE(OPENFILE, gtk-open);
|
||||
BUTTON_IMAGE(CLOSETAB, gtk-close);
|
||||
BUTTON_IMAGE(CLOSEWINDOW, gtk-close);
|
||||
BUTTON_IMAGE(SAVEPAGE, gtk-save-as);
|
||||
BUTTON_IMAGE(PRINTPREVIEW, gtk-print-preview);
|
||||
BUTTON_IMAGE(PRINT, gtk-print);
|
||||
BUTTON_IMAGE(QUIT, gtk-quit);
|
||||
BUTTON_IMAGE(CUT, gtk-cut);
|
||||
BUTTON_IMAGE(COPY, gtk-copy);
|
||||
BUTTON_IMAGE(PASTE, gtk-paste);
|
||||
BUTTON_IMAGE(DELETE, gtk-delete);
|
||||
BUTTON_IMAGE(SELECTALL, gtk-select-all);
|
||||
BUTTON_IMAGE(FIND, gtk-find);
|
||||
BUTTON_IMAGE(PREFERENCES, gtk-preferences);
|
||||
BUTTON_IMAGE(ZOOMPLUS, gtk-zoom-in);
|
||||
BUTTON_IMAGE(ZOOMMINUS, gtk-zoom-out);
|
||||
BUTTON_IMAGE(ZOOMNORMAL, gtk-zoom-100);
|
||||
BUTTON_IMAGE(FULLSCREEN, gtk-fullscreen);
|
||||
BUTTON_IMAGE(VIEWSOURCE, gtk-index);
|
||||
BUTTON_IMAGE(CONTENTS, gtk-help);
|
||||
BUTTON_IMAGE(ABOUT, gtk-about);
|
||||
#undef BUTTON_IMAGE
|
||||
case (PLACEHOLDER_BUTTON + SEARCH_BACK_BUTTON):
|
||||
return GTK_IMAGE(gtk_image_new_from_stock("gtk-go-back", s));
|
||||
case (PLACEHOLDER_BUTTON + SEARCH_FORWARD_BUTTON):
|
||||
return GTK_IMAGE(gtk_image_new_from_stock("gtk-go-forward",
|
||||
s));
|
||||
case (PLACEHOLDER_BUTTON + SEARCH_CLOSE_BUTTON):
|
||||
return GTK_IMAGE(gtk_image_new_from_stock("gtk-close", s));
|
||||
default: {
|
||||
size_t len = SLEN("themes/Alpha.png") +
|
||||
strlen(res_dir_location) + 1;
|
||||
imagefile = malloc(len);
|
||||
if (imagefile == NULL) {
|
||||
warn_user(messages_get("NoMemory"), 0);
|
||||
return NULL;
|
||||
}
|
||||
snprintf(imagefile, len, "%sthemes/Alpha.png",
|
||||
res_dir_location);
|
||||
image = GTK_IMAGE(
|
||||
gtk_image_new_from_file(imagefile));
|
||||
free(imagefile);
|
||||
return image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_THEME_INSTALL
|
||||
/**
|
||||
* when CONTENT_THEME needs handling call this function
|
||||
*/
|
||||
void theme_install_start(struct content *c)
|
||||
{
|
||||
assert(c);
|
||||
assert(c->type == CONTENT_THEME);
|
||||
|
||||
/* stop theme sitting in memory cache */
|
||||
c->fresh = false;
|
||||
if (!content_add_user(c, theme_install_callback, 0, 0)) {
|
||||
warn_user("NoMemory", 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Callback for fetchcache() for theme install fetches.
|
||||
*/
|
||||
|
||||
void theme_install_callback(content_msg msg, struct content *c,
|
||||
intptr_t p1, intptr_t p2, union content_msg_data data)
|
||||
{
|
||||
switch (msg) {
|
||||
case CONTENT_MSG_READY:
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_DONE:
|
||||
theme_install_content = c;
|
||||
if (!theme_install_read(c->source_data, c->source_size))
|
||||
warn_user("ThemeInvalid", 0);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_ERROR:
|
||||
warn_user(data.error, 0);
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_STATUS:
|
||||
break;
|
||||
|
||||
case CONTENT_MSG_LOADING:
|
||||
case CONTENT_MSG_REFORMAT:
|
||||
case CONTENT_MSG_REDRAW:
|
||||
case CONTENT_MSG_NEWPTR:
|
||||
case CONTENT_MSG_LAUNCH:
|
||||
case CONTENT_MSG_AUTH:
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handler saves theme data content as a local theme
|
||||
*/
|
||||
|
||||
bool theme_install_read(const char *data, unsigned long len)
|
||||
{
|
||||
char *filename, *newfilename;
|
||||
size_t namelen;
|
||||
int handle = g_file_open_tmp("nsgtkthemeXXXXXX", &filename, NULL);
|
||||
if (handle == -1) {
|
||||
warn_user(messages_get("gtkFileError"),
|
||||
"temporary theme file");
|
||||
}
|
||||
ssize_t written = write(handle, data, len);
|
||||
close(handle);
|
||||
if ((unsigned)written != len)
|
||||
return false;
|
||||
|
||||
/* get name of theme; set as dirname */
|
||||
namelen = SLEN("themes/") + strlen(res_dir_location) + 1;
|
||||
char dirname[namelen];
|
||||
snprintf(dirname, namelen, "%sthemes/", res_dir_location);
|
||||
|
||||
/* save individual files in theme */
|
||||
newfilename = container_extract_theme(filename, dirname);
|
||||
g_free(filename);
|
||||
if (newfilename == NULL)
|
||||
return false;
|
||||
nsgtk_theme_add(newfilename);
|
||||
free(newfilename);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* loads the set of default images for the toolbar / menus
|
||||
*/
|
||||
|
||||
struct nsgtk_theme *nsgtk_theme_default(GtkIconSize s)
|
||||
{
|
||||
struct nsgtk_theme *theme = malloc(sizeof(struct nsgtk_theme));
|
||||
if (theme == NULL) {
|
||||
warn_user("NoMemory", 0);
|
||||
return NULL;
|
||||
}
|
||||
for (int i = BACK_BUTTON; i < PLACEHOLDER_BUTTON +
|
||||
SEARCH_BUTTONS_COUNT; i++)
|
||||
theme->image[i] = nsgtk_theme_image_default(i, s);
|
||||
return theme;
|
||||
}
|
||||
|
46
gtk/gtk_theme.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_GTK_THEME_H_
|
||||
#define _NETSURF_GTK_THEME_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
|
||||
typedef enum search_buttons {
|
||||
SEARCH_BACK_BUTTON = 0,
|
||||
SEARCH_FORWARD_BUTTON,
|
||||
SEARCH_CLOSE_BUTTON,
|
||||
SEARCH_BUTTONS_COUNT
|
||||
} nsgtk_search_buttons;
|
||||
|
||||
struct nsgtk_theme {
|
||||
GtkImage *image[PLACEHOLDER_BUTTON];
|
||||
GtkImage *searchimage[SEARCH_BUTTONS_COUNT];
|
||||
/* apng throbber element */
|
||||
};
|
||||
|
||||
struct nsgtk_theme *nsgtk_theme_load(GtkIconSize s);
|
||||
void nsgtk_theme_add(const char *themename);
|
||||
void nsgtk_theme_init(void);
|
||||
void nsgtk_theme_prepare(void);
|
||||
void nsgtk_theme_implement(struct gtk_scaffolding *g);
|
||||
char *nsgtk_theme_name(void);
|
||||
void nsgtk_theme_set_name(char *name);
|
||||
|
||||
#endif
|
1102
gtk/gtk_toolbar.c
Normal file
90
gtk/gtk_toolbar.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
*
|
||||
* NetSurf is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* NetSurf is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _NETSURF_GTK_TOOLBAR_H_
|
||||
#define _NETSURF_GTK_TOOLBAR_H_
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
|
||||
void nsgtk_toolbar_customization_init(nsgtk_scaffolding *g);
|
||||
void nsgtk_toolbar_init(nsgtk_scaffolding *g);
|
||||
void nsgtk_toolbar_customization_load(nsgtk_scaffolding *g);
|
||||
void nsgtk_toolbar_set_physical(nsgtk_scaffolding *g);
|
||||
void nsgtk_toolbar_connect_all(nsgtk_scaffolding *g);
|
||||
int nsgtk_toolbar_get_id_from_widget(GtkWidget *widget, nsgtk_scaffolding
|
||||
*g);
|
||||
|
||||
#define TOOLPROTO(q) gboolean nsgtk_toolbar_##q##_button_data(\
|
||||
GtkWidget *widget, GdkDragContext *cont, GtkSelectionData\
|
||||
*selection, guint info, guint time, gpointer data);\
|
||||
gboolean nsgtk_toolbar_##q##_toolbar_button_data(GtkWidget *widget,\
|
||||
GdkDragContext *cont, GtkSelectionData *selection, guint info,\
|
||||
guint time, gpointer data)
|
||||
TOOLPROTO(home);
|
||||
TOOLPROTO(back);
|
||||
TOOLPROTO(forward);
|
||||
TOOLPROTO(reload);
|
||||
TOOLPROTO(stop);
|
||||
TOOLPROTO(throbber);
|
||||
TOOLPROTO(websearch);
|
||||
TOOLPROTO(history);
|
||||
TOOLPROTO(newwindow);
|
||||
TOOLPROTO(newtab);
|
||||
TOOLPROTO(openfile);
|
||||
TOOLPROTO(closetab);
|
||||
TOOLPROTO(closewindow);
|
||||
TOOLPROTO(savepage);
|
||||
TOOLPROTO(pdf);
|
||||
TOOLPROTO(plaintext);
|
||||
TOOLPROTO(drawfile);
|
||||
TOOLPROTO(postscript);
|
||||
TOOLPROTO(printpreview);
|
||||
TOOLPROTO(print);
|
||||
TOOLPROTO(quit);
|
||||
TOOLPROTO(cut);
|
||||
TOOLPROTO(copy);
|
||||
TOOLPROTO(paste);
|
||||
TOOLPROTO(delete);
|
||||
TOOLPROTO(selectall);
|
||||
TOOLPROTO(find);
|
||||
TOOLPROTO(preferences);
|
||||
TOOLPROTO(zoomplus);
|
||||
TOOLPROTO(zoomminus);
|
||||
TOOLPROTO(zoomnormal);
|
||||
TOOLPROTO(fullscreen);
|
||||
TOOLPROTO(viewsource);
|
||||
TOOLPROTO(downloads);
|
||||
TOOLPROTO(localhistory);
|
||||
TOOLPROTO(globalhistory);
|
||||
TOOLPROTO(addbookmarks);
|
||||
TOOLPROTO(showbookmarks);
|
||||
TOOLPROTO(openlocation);
|
||||
TOOLPROTO(nexttab);
|
||||
TOOLPROTO(prevtab);
|
||||
TOOLPROTO(savewindowsize);
|
||||
TOOLPROTO(toggledebugging);
|
||||
TOOLPROTO(saveboxtree);
|
||||
TOOLPROTO(savedomtree);
|
||||
TOOLPROTO(contents);
|
||||
TOOLPROTO(guide);
|
||||
TOOLPROTO(info);
|
||||
TOOLPROTO(about);
|
||||
#undef TOOLPROTO
|
||||
|
||||
#endif
|
155
gtk/gtk_window.c
@ -22,6 +22,7 @@
|
||||
#include "gtk/gtk_window.h"
|
||||
#include "desktop/browser.h"
|
||||
#include "desktop/options.h"
|
||||
#include "desktop/searchweb.h"
|
||||
#include "desktop/textinput.h"
|
||||
#include "desktop/selection.h"
|
||||
#include "gtk/gtk_gui.h"
|
||||
@ -35,7 +36,36 @@
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct gui_window *window_list = 0; /**< first entry in win list*/
|
||||
struct gui_window {
|
||||
/* All gui_window objects have an ultimate scaffold */
|
||||
nsgtk_scaffolding *scaffold;
|
||||
/**< the gtk object containing menu, buttons, url bar, [tabs],
|
||||
* drawing area, etc that may contain 1 -> several gui_windows */
|
||||
struct browser_window *bw;
|
||||
/**< the 'content' window that is rendered in the gui_window*/
|
||||
struct browser_mouse *mouse; /**< contains mouse state / events */
|
||||
|
||||
int caretx, carety, careth;
|
||||
/**< storage caret dimension / location for rendering */
|
||||
gui_pointer_shape current_pointer;
|
||||
/**< storage caret shape for rendering */
|
||||
int last_x, last_y;
|
||||
/**< storage caret location for rendering */
|
||||
|
||||
GtkScrolledWindow *scrolledwindow;
|
||||
/**< optional; for frames that need it; top level of gtk structure of
|
||||
* gui_window */
|
||||
GtkViewport *viewport;
|
||||
/**< contained in a scrolled window */
|
||||
GtkFixed *fixed; /**< contained in a viewport */
|
||||
GtkDrawingArea *drawing_area; /**< contained in a gtkfixed */
|
||||
GtkWidget *tab; /** the visible tab */
|
||||
gulong signalhandler[NSGTK_WINDOW_SIGNAL_COUNT];
|
||||
/**< to allow disactivation / resume of normal window behaviour */
|
||||
struct gui_window *next, *prev; /**< list for eventual cleanup */
|
||||
};
|
||||
|
||||
struct gui_window *window_list = NULL; /**< first entry in win list*/
|
||||
int temp_open_background = -1;
|
||||
|
||||
|
||||
@ -60,19 +90,45 @@ static void nsgtk_redraw_caret(struct gui_window *g);
|
||||
|
||||
static GdkCursor *nsgtk_create_menu_cursor(void);
|
||||
|
||||
struct browser_window *nsgtk_get_browser_window(struct gui_window *g)
|
||||
{
|
||||
return g->bw;
|
||||
}
|
||||
|
||||
nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g)
|
||||
{
|
||||
return g->scaffold;
|
||||
}
|
||||
|
||||
struct browser_window *nsgtk_get_browser_for_gui(struct gui_window *g)
|
||||
struct browser_window *gui_window_get_browser_window(struct gui_window *g)
|
||||
{
|
||||
return g->bw;
|
||||
return g->bw;
|
||||
}
|
||||
|
||||
unsigned long nsgtk_window_get_signalhandler(struct gui_window *g, int i)
|
||||
{
|
||||
return g->signalhandler[i];
|
||||
}
|
||||
|
||||
GtkDrawingArea *nsgtk_window_get_drawing_area(struct gui_window *g)
|
||||
{
|
||||
return g->drawing_area;
|
||||
}
|
||||
|
||||
GtkScrolledWindow *nsgtk_window_get_scrolledwindow(struct gui_window *g)
|
||||
{
|
||||
return g->scrolledwindow;
|
||||
}
|
||||
|
||||
GtkWidget *nsgtk_window_get_tab(struct gui_window *g)
|
||||
{
|
||||
return g->tab;
|
||||
}
|
||||
|
||||
void nsgtk_window_set_tab(struct gui_window *g, GtkWidget *w)
|
||||
{
|
||||
g->tab = w;
|
||||
}
|
||||
|
||||
|
||||
struct gui_window *nsgtk_window_iterate(struct gui_window *g)
|
||||
{
|
||||
return g->next;
|
||||
}
|
||||
|
||||
float nsgtk_get_scale_for_gui(struct gui_window *g)
|
||||
@ -111,13 +167,6 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||
|
||||
g->careth = 0;
|
||||
|
||||
/* Attach ourselves to the list (push_top) */
|
||||
if (window_list)
|
||||
window_list->prev = g;
|
||||
g->next = window_list;
|
||||
g->prev = NULL;
|
||||
window_list = g;
|
||||
|
||||
if (bw->parent != NULL)
|
||||
/* Find our parent's scaffolding */
|
||||
g->scaffold = bw->parent->window->scaffold;
|
||||
@ -127,9 +176,20 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||
else
|
||||
/* Now construct and attach a scaffold */
|
||||
g->scaffold = nsgtk_new_scaffolding(g);
|
||||
if (g->scaffold == NULL) {
|
||||
free(g);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Construct our primary elements */
|
||||
g->fixed = GTK_FIXED(gtk_fixed_new());
|
||||
/* Attach ourselves to the list (push_top) */
|
||||
if (window_list)
|
||||
window_list->prev = g;
|
||||
g->next = window_list;
|
||||
g->prev = NULL;
|
||||
window_list = g;
|
||||
|
||||
/* Construct our primary elements */
|
||||
g->fixed = GTK_FIXED(gtk_fixed_new());
|
||||
g->drawing_area = GTK_DRAWING_AREA(gtk_drawing_area_new());
|
||||
gtk_fixed_put(g->fixed, GTK_WIDGET(g->drawing_area), 0, 0);
|
||||
gtk_container_set_border_width(GTK_CONTAINER(g->fixed), 0);
|
||||
@ -219,6 +279,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||
GDK_BUTTON_PRESS_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK |
|
||||
GDK_POINTER_MOTION_MASK |
|
||||
GDK_POINTER_MOTION_HINT_MASK |
|
||||
GDK_KEY_PRESS_MASK |
|
||||
GDK_KEY_RELEASE_MASK);
|
||||
GTK_WIDGET_SET_FLAGS(GTK_WIDGET(g->drawing_area), GTK_CAN_FOCUS);
|
||||
@ -229,17 +290,20 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
|
||||
|
||||
#define CONNECT(obj, sig, callback, ptr) \
|
||||
g_signal_connect(G_OBJECT(obj), (sig), G_CALLBACK(callback), (ptr))
|
||||
CONNECT(g->drawing_area, "expose_event", nsgtk_window_expose_event, g);
|
||||
g->signalhandler[NSGTK_WINDOW_SIGNAL_REDRAW] =
|
||||
CONNECT(g->drawing_area, "expose_event",
|
||||
nsgtk_window_expose_event, g);
|
||||
CONNECT(g->drawing_area, "motion_notify_event",
|
||||
nsgtk_window_motion_notify_event, g);
|
||||
CONNECT(g->drawing_area, "button_press_event",
|
||||
nsgtk_window_button_press_event, g);
|
||||
nsgtk_window_motion_notify_event, g);
|
||||
g->signalhandler[NSGTK_WINDOW_SIGNAL_CLICK] =
|
||||
CONNECT(g->drawing_area, "button_press_event",
|
||||
nsgtk_window_button_press_event, g);
|
||||
CONNECT(g->drawing_area, "button_release_event",
|
||||
nsgtk_window_button_release_event, g);
|
||||
nsgtk_window_button_release_event, g);
|
||||
CONNECT(g->drawing_area, "key_press_event",
|
||||
nsgtk_window_keypress_event, g);
|
||||
nsgtk_window_keypress_event, g);
|
||||
CONNECT(g->viewport, "size_allocate",
|
||||
nsgtk_window_size_allocate_event, g);
|
||||
nsgtk_window_size_allocate_event, g);
|
||||
|
||||
return g;
|
||||
}
|
||||
@ -344,7 +408,9 @@ gboolean nsgtk_window_motion_notify_event(GtkWidget *widget,
|
||||
struct gui_window *g = data;
|
||||
bool shift = event->state & GDK_SHIFT_MASK;
|
||||
bool ctrl = event->state & GDK_CONTROL_MASK;
|
||||
|
||||
if ((abs(event->x - g->last_x) < 5) && (abs(event->y - g->last_y) < 5))
|
||||
/* necessary for touch screens */
|
||||
return FALSE;
|
||||
if (g->mouse->state & BROWSER_MOUSE_PRESS_1){
|
||||
/* Start button 1 drag */
|
||||
browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG_1,
|
||||
@ -384,29 +450,24 @@ gboolean nsgtk_window_button_press_event(GtkWidget *widget,
|
||||
struct gui_window *g = data;
|
||||
|
||||
gtk_widget_grab_focus(GTK_WIDGET(g->drawing_area));
|
||||
gtk_widget_hide(GTK_WIDGET(nsgtk_scaffolding_history_window(
|
||||
g->scaffold)->window));
|
||||
|
||||
g->mouse->pressed_x = event->x / g->bw->scale;
|
||||
g->mouse->pressed_y = event->y / g->bw->scale;
|
||||
|
||||
if (event->button == 3) {
|
||||
/** \todo
|
||||
* Firstly, MOUSE_PRESS_2 on GTK is a middle click, which doesn't
|
||||
* appear correct to me. Secondly, right-clicks are not passed to
|
||||
* browser_window_mouse_click() at all, which also seems incorrect
|
||||
* since they should result in browser_window_remove_caret().
|
||||
*
|
||||
* I would surmise we need a MOUSE_PRESS_3, unless right-clicking is
|
||||
* supposed to be mapped to MOUSE_PRESS_2, but that doesn't appear
|
||||
* correct either.
|
||||
*/
|
||||
browser_window_remove_caret(g->bw);
|
||||
nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse->pressed_x, g->mouse->pressed_y);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
switch (event->button) {
|
||||
case 1: g->mouse->state = BROWSER_MOUSE_PRESS_1; break;
|
||||
case 2: g->mouse->state = BROWSER_MOUSE_PRESS_2; break;
|
||||
case 1:
|
||||
g->mouse->state = BROWSER_MOUSE_PRESS_1;
|
||||
break;
|
||||
case 3:
|
||||
browser_window_remove_caret(g->bw);
|
||||
nsgtk_scaffolding_popup_menu(g->scaffold, g->mouse->pressed_x,
|
||||
g->mouse->pressed_y);
|
||||
g->mouse->state = BROWSER_MOUSE_PRESS_2;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
/* Handle the modifiers too */
|
||||
if (event->state & GDK_SHIFT_MASK)
|
||||
@ -565,7 +626,7 @@ void nsgtk_reflow_all_windows(void)
|
||||
{
|
||||
for (struct gui_window *g = window_list; g; g = g->next) {
|
||||
nsgtk_tab_options_changed(GTK_WIDGET(
|
||||
nsgtk_scaffolding_get_notebook(g)));
|
||||
nsgtk_scaffolding_notebook(g->scaffold)));
|
||||
g->bw->reformat_pending = true;
|
||||
}
|
||||
|
||||
@ -702,6 +763,12 @@ void gui_window_set_scroll(struct gui_window *g, int sx, int sy)
|
||||
gtk_adjustment_set_value(hadj, x);
|
||||
}
|
||||
|
||||
void gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
|
||||
int x1, int y1)
|
||||
{
|
||||
gui_window_set_scroll(g,x0,y0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the scale setting of a window
|
||||
|
@ -23,36 +23,6 @@
|
||||
#include "desktop/browser.h"
|
||||
#include "gtk/gtk_scaffolding.h"
|
||||
|
||||
struct gui_window {
|
||||
/* All gui_window objects have an ultimate scaffold */
|
||||
nsgtk_scaffolding *scaffold;
|
||||
/* A gui_window is the rendering of a browser_window */
|
||||
struct browser_window *bw;
|
||||
struct browser_mouse *mouse;
|
||||
|
||||
/* These are the storage for the rendering */
|
||||
int caretx, carety, careth;
|
||||
gui_pointer_shape current_pointer;
|
||||
int last_x, last_y;
|
||||
|
||||
/* Within GTK, a gui_window is a scrolled window
|
||||
* with a viewport inside
|
||||
* with a gtkfixed in that
|
||||
* with a drawing area in that
|
||||
* The scrolled window is optional and only chosen
|
||||
* for frames which need it. Otherwise we just use
|
||||
* a viewport.
|
||||
*/
|
||||
GtkWidget *tab;
|
||||
GtkScrolledWindow *scrolledwindow;
|
||||
GtkViewport *viewport;
|
||||
GtkFixed *fixed;
|
||||
GtkDrawingArea *drawing_area;
|
||||
|
||||
/* Keep gui_windows in a list for cleanup later */
|
||||
struct gui_window *next, *prev;
|
||||
};
|
||||
|
||||
struct browser_mouse {
|
||||
struct gui_window *gui;
|
||||
struct box *box;
|
||||
@ -63,19 +33,29 @@ struct browser_mouse {
|
||||
browser_mouse_state state;
|
||||
};
|
||||
|
||||
extern struct gui_window * window_list;
|
||||
typedef enum nsgtk_window_signals {
|
||||
NSGTK_WINDOW_SIGNAL_CLICK,
|
||||
NSGTK_WINDOW_SIGNAL_REDRAW,
|
||||
NSGTK_WINDOW_SIGNAL_COUNT
|
||||
} nsgtk_window_signal;
|
||||
|
||||
extern struct gui_window *window_list;
|
||||
extern int temp_open_background;
|
||||
|
||||
void nsgtk_reflow_all_windows(void);
|
||||
void nsgtk_window_process_reformats(void);
|
||||
|
||||
nsgtk_scaffolding *nsgtk_get_scaffold(struct gui_window *g);
|
||||
struct browser_window *nsgtk_get_browser_for_gui(struct gui_window *g);
|
||||
|
||||
float nsgtk_get_scale_for_gui(struct gui_window *g);
|
||||
int nsgtk_gui_window_update_targets(struct gui_window *g);
|
||||
void nsgtk_window_destroy_browser(struct gui_window *g);
|
||||
unsigned long nsgtk_window_get_signalhandler(struct gui_window *g, int i);
|
||||
GtkDrawingArea *nsgtk_window_get_drawing_area(struct gui_window *g);
|
||||
struct gui_window *nsgtk_window_iterate(struct gui_window *g);
|
||||
GtkScrolledWindow *nsgtk_window_get_scrolledwindow(struct gui_window *g);
|
||||
GtkWidget *nsgtk_window_get_tab(struct gui_window *g);
|
||||
void nsgtk_window_set_tab(struct gui_window *g, GtkWidget *w);
|
||||
|
||||
struct browser_window *nsgtk_get_browser_window(struct gui_window *g);
|
||||
|
||||
#endif /* NETSURF_GTK_WINDOW_H */
|
||||
|
@ -34,6 +34,8 @@ extern int option_history_age;
|
||||
extern bool option_hover_urls;
|
||||
extern bool option_focus_new;
|
||||
extern bool option_new_blank;
|
||||
extern bool option_source_tab;
|
||||
extern int option_current_theme;
|
||||
|
||||
#define EXTRA_OPTION_DEFINE \
|
||||
bool option_render_resample = false; \
|
||||
@ -48,7 +50,9 @@ bool option_disable_plugins = false; \
|
||||
int option_history_age = 0; \
|
||||
bool option_hover_urls = false; \
|
||||
bool option_focus_new = false; \
|
||||
bool option_new_blank = false;
|
||||
bool option_new_blank = false; \
|
||||
bool option_source_tab = false;\
|
||||
int option_current_theme = 0;
|
||||
|
||||
#define EXTRA_OPTION_TABLE \
|
||||
{ "render_resample", OPTION_BOOL, &option_render_resample }, \
|
||||
@ -63,6 +67,8 @@ bool option_new_blank = false;
|
||||
{ "history_age", OPTION_INTEGER, &option_history_age}, \
|
||||
{ "hover_urls", OPTION_BOOL, &option_hover_urls}, \
|
||||
{ "focus_new", OPTION_BOOL, &option_focus_new}, \
|
||||
{ "new_blank", OPTION_BOOL, &option_new_blank}
|
||||
{ "new_blank", OPTION_BOOL, &option_new_blank}, \
|
||||
{ "source_tab", OPTION_BOOL, &option_source_tab},\
|
||||
{ "current_theme", OPTION_INTEGER, &option_current_theme}
|
||||
|
||||
#endif
|
||||
|
20
gtk/res/SearchEngines
Normal file
@ -0,0 +1,20 @@
|
||||
Google|www.google.com|http://www.google.com/search?q=%s|http://www.google.com/favicon.ico|
|
||||
Yahoo|search.yahoo.com|http://search.yahoo.com/search?p=%s|http://www.yahoo.com/favicon.ico|
|
||||
Bing|www.bing.com|http://www.bing.com/search?q=%s|http://www.bing.com/favicon.ico|
|
||||
Business.com|www.business.com|http://www.business.com/search/rslt_default.asp?query=%s|http://www.business.com/favicon.ico|
|
||||
Omgili|www.omgili.com|http://www.omgili.com/AAAAA/%s.html|http://www.omgili.com/favicon.ico|
|
||||
BBC News|search.bbc.co.uk|http://search.bbc.co.uk/search?q=%s&tab=ns|http://news.bbc.co.uk/favicon.ico|
|
||||
Ubuntu Packages|packages.ubuntu.com|http://packages.ubuntu.com/search?keywords=%s|http://packages.ubuntu.com/favicon.ico|
|
||||
Creative Commons|creativecommons.org|http://creativecommons.org/?s=%s|http://creativecommons.org/favicon.ico|
|
||||
Ask.com|www.ask.com|http://www.ask.com/web?q=%s|http://www.ask.com/favicon.ico|
|
||||
Answers.com|www.answers.com|http://www.answers.com/%s|http://www.answers.com/favicon.ico|
|
||||
Dictionary.com|dictionary.reference.com|http://dictionary.reference.com/browse/%s?jss=0|http://dictionary.reference.com/favicon.ico|
|
||||
Youtube|www.youtube.com|http://www.youtube.com/results?search_query=%s|http://www.youtube.com/favicon.ico|
|
||||
AeroMp3|www.aeromp3.com|http://www.aeromp3.com/search?q=%s|http://www.aeromp3.com/favicon.ico|
|
||||
AOL|search.aol.com|http://search.aol.com/aol/search?query=%s|http://www.aol.com/favicon.ico|
|
||||
Baidu|www.baidu.com|http://www.baidu.com/s?wd=%s|http://www.baidu.com/favicon.ico|
|
||||
Amazon|www.amazon.com|http://www.amazon.com/s/ref=nb_ss_gw?field-keywords=%s|http://www.amazon.com/favicon.ico|
|
||||
Ebay|shop.ebay.com|http://shop.ebay.com/items/%s|http://www.ebay.com/favicon.ico|
|
||||
IMDB|www.imdb.com|http://www.imdb.com/find?q=%s|http://www.imdb.com/favicon.ico|
|
||||
ESPN|search.espn.go.com|http://search.espn.go.com/%s/|http://www.espn.go.com/favicon.ico|
|
||||
Wikipedia|en.wikipedia.org|http://en.wikipedia.org/w/index.php?title=Special%%3ASearch&search=%s|http://en.wikipedia.org/favicon.ico|
|
BIN
gtk/res/default.ico
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
gtk/res/html.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
222
gtk/res/login.glade
Normal file
@ -0,0 +1,222 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<glade-interface>
|
||||
<widget class="GtkDialog" id="wndLogin">
|
||||
<property name="title" translatable="yes">Site Authentication</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER_ALWAYS</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox2">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox12">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">3</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image3">
|
||||
<property name="visible">True</property>
|
||||
<property name="yalign">0.10000000149011612</property>
|
||||
<property name="xpad">12</property>
|
||||
<property name="icon_size">6</property>
|
||||
<property name="icon_name">gtk-dialog-authentication</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkTable" id="table5">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">1</property>
|
||||
<property name="n_rows">4</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="column_spacing">11</property>
|
||||
<property name="row_spacing">10</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="labelLoginHost">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">moo.yoo.com</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label57">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Password</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label56">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Username</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label54">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Host</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label55">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Realm</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="labelLoginRealm">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">my sekr3t area</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entryLoginPass">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="activates_default">True</property>
|
||||
<property name="text" translatable="yes">opensesame</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">3</property>
|
||||
<property name="bottom_attach">4</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entryLoginUser">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="has_focus">True</property>
|
||||
<property name="text" translatable="yes">sesame</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">1</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area2">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="buttonLoginCan">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="buttonLoginOK">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment14">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox11">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image2">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-ok</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label49">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Login</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
274
gtk/res/password.glade
Normal file
@ -0,0 +1,274 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<glade-interface>
|
||||
<widget class="GtkWindow" id="wndPDFPassword">
|
||||
<property name="title" translatable="yes">PDF Password</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="window_position">GTK_WIN_POS_CENTER</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image1">
|
||||
<property name="visible">True</property>
|
||||
<property name="yalign">0.10000000149011612</property>
|
||||
<property name="xpad">12</property>
|
||||
<property name="icon_size">6</property>
|
||||
<property name="icon_name">gtk-dialog-authentication</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="labelInfo">
|
||||
<property name="visible">True</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="label" translatable="yes">Write and confirm passwords:</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox2">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label4">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Owner password:</property>
|
||||
<property name="width_chars">15</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entryPDFOwnerPassword">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_length">20</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="width_chars">20</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label5">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Repeat password:</property>
|
||||
<property name="width_chars">15</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entryPDFOwnerPassword1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_length">20</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="width_chars">20</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox4">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label6">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">User password:</property>
|
||||
<property name="width_chars">15</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entryPDFUserPassword">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_length">20</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="width_chars">20</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox5">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label7">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Repeat password:</property>
|
||||
<property name="width_chars">15</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkEntry" id="entryPDFUserPassword1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="max_length">20</property>
|
||||
<property name="visibility">False</property>
|
||||
<property name="width_chars">20</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">4</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkHButtonBox" id="hbuttonbox1">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="spacing">10</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="buttonPDFSetPassword">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox7">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image7">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-ok</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label8">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Set password</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="buttonPDFNoPassword">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="response_id">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment1">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox6">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image8">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-cancel</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label9">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">No password</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">5</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
197
gtk/res/ssl.glade
Normal file
@ -0,0 +1,197 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
||||
<!--*- mode: xml -*-->
|
||||
<glade-interface>
|
||||
<widget class="GtkDialog" id="wndSSLProblem">
|
||||
<property name="border_width">1</property>
|
||||
<property name="title" translatable="yes">SSL certificate problem</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox3">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox15">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image6">
|
||||
<property name="visible">True</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="icon_size">6</property>
|
||||
<property name="icon_name">gtk-dialog-warning</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkVBox" id="vbox13">
|
||||
<property name="visible">True</property>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label62">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">NetSurf failed to verify the authenticity of an SSL certificate. Please verify the details presented below.</property>
|
||||
<property name="justify">GTK_JUSTIFY_CENTER</property>
|
||||
<property name="wrap">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkFrame" id="frame13">
|
||||
<property name="visible">True</property>
|
||||
<property name="border_width">5</property>
|
||||
<property name="label_xalign">0</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment17">
|
||||
<property name="visible">True</property>
|
||||
<property name="left_padding">12</property>
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow1">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<child>
|
||||
<widget class="GtkTextView" id="textview1">
|
||||
<property name="height_request">200</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">False</property>
|
||||
<property name="text" translatable="yes">(not implemented)</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label63">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes"><b>Certificate chain</b></property>
|
||||
<property name="use_markup">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="type">label_item</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area3">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
<child>
|
||||
<widget class="GtkButton" id="sslreject">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment16">
|
||||
<property name="visible">True</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox14">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image5">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-cancel</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label61">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Reject</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="sslaccept">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
<child>
|
||||
<widget class="GtkAlignment" id="alignment15">
|
||||
<property name="visible">True</property>
|
||||
<property name="xscale">0</property>
|
||||
<property name="yscale">0</property>
|
||||
<child>
|
||||
<widget class="GtkHBox" id="hbox13">
|
||||
<property name="visible">True</property>
|
||||
<property name="spacing">2</property>
|
||||
<child>
|
||||
<widget class="GtkImage" id="image4">
|
||||
<property name="visible">True</property>
|
||||
<property name="stock">gtk-apply</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label60">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">Accept</property>
|
||||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">False</property>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="expand">False</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
2
gtk/res/themelist
Normal file
@ -0,0 +1,2 @@
|
||||
gtk default theme
|
||||
gtk+
|
BIN
gtk/res/themes/Alpha.png
Normal file
After Width: | Height: | Size: 156 B |
BIN
gtk/res/themes/gtk+/back.png
Normal file
After Width: | Height: | Size: 915 B |
BIN
gtk/res/themes/gtk+/closetab.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
gtk/res/themes/gtk+/closewindow.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
gtk/res/themes/gtk+/copy.png
Normal file
After Width: | Height: | Size: 697 B |
BIN
gtk/res/themes/gtk+/cut.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
gtk/res/themes/gtk+/delete.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
gtk/res/themes/gtk+/forward.png
Normal file
After Width: | Height: | Size: 906 B |
BIN
gtk/res/themes/gtk+/fullscreen.png
Normal file
After Width: | Height: | Size: 606 B |
BIN
gtk/res/themes/gtk+/helpabout.png
Normal file
After Width: | Height: | Size: 982 B |
BIN
gtk/res/themes/gtk+/helpcontents.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
gtk/res/themes/gtk+/history.png
Normal file
After Width: | Height: | Size: 285 B |
BIN
gtk/res/themes/gtk+/home.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
81
gtk/res/themes/gtk+/info
Normal file
@ -0,0 +1,81 @@
|
||||
This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
|
||||
The images in this theme folder 'gtk+' are from the gtk stock image set
|
||||
http://library.gnome.org/devel/gtk/unstable/gtk-Stock-Items.html
|
||||
|
||||
the image history.png is [for what it's worth!] Copyright 2009 Mark Benjamin
|
||||
<netsurf-browser.org.MarkBenjamin@dfgh.net>
|
||||
|
||||
NetSurf is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
NetSurf is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*** Instructions for theming ***
|
||||
|
||||
to create a theme, make a folder, whose name is the name of the theme;
|
||||
put in the folder, a set of png images for the toolbuttons;
|
||||
the names of the images should be a subset of the list
|
||||
|
||||
back.png,
|
||||
history.png,
|
||||
forward.png,
|
||||
stop.png,
|
||||
reload.png,
|
||||
home.png,
|
||||
newwindow.png,
|
||||
newtab.png,
|
||||
openfile.png,
|
||||
closetab.png,
|
||||
closewindow.png,
|
||||
savepage.png,
|
||||
pdf.png,
|
||||
plaintext.png,
|
||||
drawfile.png,
|
||||
postscript.png,
|
||||
printpreview.png,
|
||||
print.png,
|
||||
quit.png,
|
||||
cut.png,
|
||||
copy.png,
|
||||
paste.png,
|
||||
delete.png,
|
||||
selectall.png,
|
||||
find.png,
|
||||
preferences.png,
|
||||
zoomplus.png,
|
||||
zoomminus.png,
|
||||
zoomnormal.png,
|
||||
fullscreen.png,
|
||||
viewsource.png,
|
||||
downloads.png,
|
||||
savewindowsize.png,
|
||||
toggledebugging.png,
|
||||
saveboxtree.png,
|
||||
savedomtree.png,
|
||||
localhistory.png,
|
||||
globalhistory.png,
|
||||
addbookmarks.png,
|
||||
showbookmarks.png,
|
||||
openlocation.png,
|
||||
nexttab.png,
|
||||
prevtab.png,
|
||||
contents.png,
|
||||
guide.png,
|
||||
info.png,
|
||||
about.png,
|
||||
searchback.png,
|
||||
searchforward.png,
|
||||
searchclose.png
|
||||
|
||||
for local theming, the folder may be placed directly [as a subfolder] into the netsurf/gtk/res/themes folder; then 'add theme' from the preferences->advanced tab;
|
||||
|
||||
for downloadable themes, compile netsurf/utils/container.c according to the instructions in the header of that file; make a netsurf container of the folder, serve it as content-type "application/x-netsurf-theme"; browse to it in NetSurf, then NetSurf should automatically install it
|
||||
|
BIN
gtk/res/themes/gtk+/newtab.png
Normal file
After Width: | Height: | Size: 736 B |
BIN
gtk/res/themes/gtk+/newwindow.png
Normal file
After Width: | Height: | Size: 736 B |
BIN
gtk/res/themes/gtk+/openfile.png
Normal file
After Width: | Height: | Size: 612 B |
BIN
gtk/res/themes/gtk+/paste.png
Normal file
After Width: | Height: | Size: 893 B |
BIN
gtk/res/themes/gtk+/preferences.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
gtk/res/themes/gtk+/print.png
Normal file
After Width: | Height: | Size: 818 B |
BIN
gtk/res/themes/gtk+/printpreview.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
gtk/res/themes/gtk+/quit.png
Normal file
After Width: | Height: | Size: 967 B |
BIN
gtk/res/themes/gtk+/reload.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
gtk/res/themes/gtk+/savepage.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
gtk/res/themes/gtk+/selectall.png
Normal file
After Width: | Height: | Size: 717 B |
BIN
gtk/res/themes/gtk+/stop.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
gtk/res/themes/gtk+/viewsource.png
Normal file
After Width: | Height: | Size: 960 B |
BIN
gtk/res/themes/gtk+/zoomminus.png
Normal file
After Width: | Height: | Size: 941 B |