diff --git a/.gitignore b/.gitignore index 353adde5..3768f765 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ arora Arora.app -Makefile +arora.exe +Makefile* .DS_Store .ui .moc @@ -8,23 +9,13 @@ Makefile .rcc .qm .gdb_history - -autotests/addbookmarkdialog/addbookmarkdialog -autotests/autosaver/autosaver -autotests/downloadmanager/downloadmanager -autotests/edittreeview/edittreeview -autotests/history/history -autotests/historyfiltermodel/historyfiltermodel -autotests/searchlineedit/searchlineedit -autotests/tabbar/tabbar -autotests/tabwidget/tabwidget -autotests/webactionmapper/webactionmapper -autotests/xbel/xbel - -manualtests/bookmarks/bookmarks -manualtests/downloadmanager/downloadmanager -manualtests/history/history -manualtests/searchlineedit/searchlineedit -manualtests/urllineedit/urllineedit -manualtests/webviewsearch/webviewsearch +ui_ +*.exe +*.swp +*~ +*.pdb +*.ilk +massif.out.* +ms_print.* +doc/ diff --git a/AUTHORS b/AUTHORS index 7feb4e6e..017073a9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,10 +1,61 @@ Benjamin C Meyer ben@meyerhome.net -Jason A. Donenfeld Jason@zx2c4.com -Matvey Kozhev sikon@ubuntu.com +Jakub Wieczorek faw217@gmail.com +Diego Iastrubni elcuco@kde.org Jakub Lužný limoto94@gmail.com -Daniel Albuschat d.albuschat@gmail.com -Ariya Hidayat ariya.hidayat@trolltech.com +Christopher Eby kreed@kreed.org +Jason A. Donenfeld Jason@zx2c4.com +Christian Franke cfchris6@ts2server.com +Benjamin K. Stuhl bks24@cornell.edu +Zsombor Gegesy gzsombor@gmail.com +Vincenzo Reale smart2128@baslug.org +Kristof Bal kristof.bal@gmail.com +Maia Kozheva sikon@ubuntu.com +axasia axasia@gmail.com +Tor Arne Vestbø tor.arne.vestbo@nokia.com +Tom Gundersen teg@jklm.no +John Wimer john@god.vtic.net +Ariya Hidayat ariya.hidayat@gmail.com Adam Treat treat@kde.org -Tor Arne Vestbø tavestbo@trolltech.com -Chris Lee clee@mg8.org +Mark Reiche porphyr@gmx.de +Guillaume Martres smarter@ubuntu.com +Josef Kufner jk@myserver.cz +Janusz Lewandowski lew21st@gmail.com +Daniel Albuschat d.albuschat@gmail.com +Alexandre Dupas alexandre.dupas@gmail.com +Simon Hausmann simon@lst.de +Robert Hogan robhogan@gmail.com +Raphael Kubo da Costa kubito@gmail.com +Paul Olav Tvete paul@trolltech.com John Schember john@nachtimwald.com +Elrond elrond+arora.git.commit@samba-tng.org +Chris Lee clee@mg8.org +Benjamin Poulain benjamin.poulain@nokia.com +Alexandre Bique bique.alexandre@gmail.com +ABuus amb@lafnet.dk +ondrejcernos cernoso@gmail.com +mwenge robert@roberthogan.net +jreznik jreznik@redhat.com +Zack Rusin zack@kde.org +William Witt unamanic@gimli.tolkien +Slim Amamou slim.amamou@gmail.com +Richard Moore rich@beast.needcoffee.co.uk +Popa Marius Adrian mapopa@gmail.com +Pavol Rusnak stick@gk2.sk +Oscar Blumberg o.blumberg@robertlan.eu.org +Michael Burger linuxman2k1@yahoo.com +Max Kueng me@maxkueng.com +Markus Goetz Markus.Goetz@nokia.com +Marius Bugge Monsen mariusbu@pvv.org +Kenneth Rohde Christiansen kenneth.christiansen@openbossa.org +João Abecasis joao@abecasis.name +Jonas Gehring jonas.gehring@boolsoft.org +Jocelyn Turcotte jocelyn.turcotte@nokia.com +Henri Valta cg@jakorasia.info +Gergely Nagy gergely.nagy@interware.co.hu +Gegesy Zsombor gzsombor@gmail.com +Dominik Riebeling bluebrother@gmx.de +Darryl Kacher darrylkacher@gmail.com +Chris Hills chaz@chaz6.com +Carlos Júnior carlos@milk-it.net +Aurélien Gâteau agateau@kde.org +Andreas Kling andreas.kling@nokia.com diff --git a/ChangeLog b/ChangeLog index 6d0f2e07..0ebf1e9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,2 +1,539 @@ +0.11.0 +Interface: + When the privacy indicator is visible clicking on it will result in private mode being turned off. + Add a way to modify the user agent string from within the application. + Support arguments for the external download program + Tweak the adblock dialog spacing and size. + Change the AdBlock dialog to use a simple check box instead of a group box. + Replace Stopped with Download Complete (like in ffx it's less confusing ) + Update the copyright year in the about dialog to include 2010 + Issue: 768: Fix spelling mistake + Issue: 821: Sort columns in cookie dialog by data values instead of string value. This fixes the dates being alphanumerically sorted. + +Behind the scene: + Issue: 891: Fix Text Encoding to work correctly + Issue: 826: Correctly save the history state of a tab when using Qt 4.6 + Fix build breakage with QtWebKit 2.0. + Remove remnant of delayed QWebView creation. Fixes tab restore again. + Style fix: convert tabs to spaces. + +Build system: + Add an application icon for os2. + For finding the locale tools on os2 behave like win32 + When building in debug mode on OS2 just like with Windows enable the console. + Move Arora's hooks to the git-hooks format to utilize git-hooks (See: http://github.com/icefox/git-hooks) + Default to lrelease and not lrelease-qt4 on non unix platforms. + QMAKE_EXTRA_UNIX_TARGETS is deprecated; use QMAKE_EXTRA_TARGETS instead. + Enable the raster graphics system by default for X11 + +Translation: + Make "Show Hidden Files" translatable. + Issue: 811: Fix typos in the German translation + Replaced "leichtgewichtiger" with "schlanker" in translation with source "Lightweight WebKit-based wen browser" + Fixed capitalization typo whare the word "Tab" began with a lowercase "t" + Renamed Dutch translation file from nl_BE to nl. + + +0.10.2 +The major issues: + - When compiling with Qt 4.6 Arora had been using some API that changes + shortly before the release of Qt 4.6.0 after an API review was done for + the new API in QtWebKit. This release changes the code to build with the + final API that is found in Qt 4.6.0 + - A segfault that could occur when opening a URL on a new window from the command-line. + + +0.10.1 +The major issues: + Issue: 666 Sites were showing a "SSL handshake failure". With the new NetworkAccessManagerProxy the signals were being sent to the proxy and not the primary networkaccessmanager. + Issue: 683: Arora crashes when using privacy mode. + When switching to private mode the primary networkaccessmanagers swaps cookiejar's which caused a segfault. Introduce a CookieJarProxy class which will pass the cookie requests to the primary networkaccessmanager's cookiejar. + +Translations: + Add Portuguese translation from Américo Monteiro + Updated Turkish translation from Mehmet Nur Olcay + Issue: 682,677 Fix several FR spelling mistakes. + +Fixed Issues: + Issue: 79 Only tab down the completer when the popup is visible. + Issue: 221 When using Qt 4.6 hardcode a webpage to have a white background even when using a dark theme. + Issue: 472 Set the url on the location bar that matches the webview that we are loading the url in, not in the current location bar which might not be the correct one. + Issue: 637 Startup Crash with Qt 4.5.0 (not with any other version) + Issue: 679 Selecting Show only one close button instead of one for each tab requires an application restart to be applied. + Issue: 676 Fix openstreetmap.org's login saving and improve the Wallet password dialog when finding the login name. + Rather than using the document.form[0].name use document.form[0].elements["name"] this allows the name to contain things such as []'s without causing a problem. + +Other issues / changes + Add support for the home, favorites, search, and openurl multimedia keys found on some keyboards + Turn on AutoFill by default + Remove the accidental 100MB limit on the disk cache size in the settings dialog. + Make source viewer remember the window size and not block access to the main window + +0.10.0 +Interface +- Issue #24: Add support for AdBlock +- Issue #40: Support several common modifiers in the location bar for modifying the typed in url. + ctrl-enter - append .com + ctrl-shift-enter - append .org + shift-enter - append .net +- Issue #79: Trap tab key to cycle through potential URLs in the location bar. +- Issue #85: Alt+Enter on the location bar opens the url in a new tab. +- Issue #119: Add Password Management / AutoFill +- Issue #411: Save and restore the tab back/forward history +- Issue #630: Limit download progress updates to 5 per second to reduces CPU use from 18% to 3% when downloading. +- Issue #650: Save the toolbar location allowing the toolbars to be next to each other +- Add ctrl-z shortcut to undo the closing of the last tab. +- Behave better when access keys are enabled by adding a slight delay to make sure that the ctrl is actually for access keys and not for another shortcut such as ctrl-tab or ctrl-a +- When arora crashed on the previous startup give the user a way to bypass the failsafe and restore their session if they really want. +- Add the ability to set the length of a session cookie +- Enable DNS prefetching and WebKit version in the about dialog when building against Qt 4.6. +- Remember what tab you were on when you close the settings dialog +- Add a browse button next to the style sheet line edit to help users find files and automatically translate them into url's. +- Add icons to the menu actions on freedesktop systems. +- Show the configure search engines action in the tools menu +- Change default bookmarks to only have a link to htpp://arora-browser.org + Removed all of Qt development type entries + From discussion on http://arorabrowser.blogspot.com/2009/08/arora-090.html and also the Kubuntu guys strip the bookmarks in their release so it make sense. +- Move the Preferences menu item to Tools|Options +- Set placeholder text for the start page search box +- Add a checkbox to hide/show hidden files in the directory listing. +- Change the about dialog text so it can be selected with a mouse so users can copy the application version. +- Allow urls to be dropped on the bookmark bar and bookmark menu + +Behind the scenes +- Force the history completer to be LTR: same as the url line. +- Create a new stills class, NetworkAcessManagerProxy that is useful for tracking what QWebPage a QWebReply came from. +- Load QWebView settings when the View is created so m_enableAccessKeys will be read from settings +- Rename lineedit -> locationbar functions & variables +- Enhance SingleApplication so that the host can send messages back to the second application. + On Windows this is used to send the window id back to the application that was just started + so it can raise the arora window to the front. +- Fix some old MSVC compile warnings +- Make it possible to retranslate the bookmarks toolbar title +- Set the maximumPagesInCache to 3 (default is 0) and provide a way for users to set this value through QSettings. +- Add a path from the users directory to the locale search path +- Added RTL support for the start page +- Add support for multiple directories to LanguageManager. +- Fix the naming of the QAction m_toolsEnableInspector to m_toolsEnableInspectorAction to be consistent with the rest of the code +- Add new TreeSortFilterProxyModel class to utils that will only filter child nodes in a QAbstractItemModel. (under the BSD license) +- Rename getConfigFile to dataFilePath +- Rename dataDirectory to installedDataDirectory to give a much better description of what it does +- Add missing drop functionality to the ModelMenu class. The implementation is symetric to the ModelToolBar class. +- ModelMenu can now accept drops (both moving and copying) and can apply them to the underlying model. +- Refactor BookmarksToolBar by making it inherit from ModelToolBar. +- Add new ModelToolBar class, that is a subclass of QToolBar and an equivalent of ModelMenu for toolbars. It can be used to populate a toolbar with actions based on a given model. +- Fix character encoding in directory listing. +- Clean up the private browsing message box to make it easier to translate. + +Build system +- Allow building against a shadow-built WebKit trunk +- Ignore more misc generated build files on windows +- Add Git hook to check commits for the proper copyright year +- Ignore the doc directory which is generated by doxygen +- Check for spaces at the start and end of an expression +- Re-enable sharing the temporary compilation objects for all subprojects. Use the 'ordered' configuration to make sure that we walk through the subdirectories one by one and not all simultaneously when building in parallel. + + +0.9.0 +Drop support for Qt 4.4. + +Interface +FEATURES: +- Add support for search keywords in the location bar. +- POST support for OpenSearch suggestion requests. +- Add WebKit version to the About dialog [WebKit trunk only]. +- Use HTTP pipelining for all network requests [Qt 4.6 only]. + +IMPROVEMENTS: +- Remember last used save directory. +- Added file dialog to download location settings. +- Restrict drag and drop to the same page unless a QWebView accepts it. +- Open an URL dropped on the tab bar as new tab or replace existing tab. +- Allow url to be dropped on the tab bar from other applications. +- Add a Select All action. +- Rather than not allowing setting or getting of any cookies in private mode create a blank cookie jar. +- Significantly speed up the cookie dialog by keeping a cached copy of all the cookies. +- Enhance the language manager to fallback to the country file if the country_language file doesn't exists. +- Add drag support for downloaded item in the download manager. +- Add Planet Qt to the default set of bookmarks. +- Remove the text wrapping option from the source viewer's menu and instead enable it by default. + +BUGFIXES: +- Avoid duplicated and contradictory rules on the cookie rule list. +- Change the shortcut for showing the bookmark toolbar as it was conflicting with the show bookmark dialog shortcut. +- Encode the user input before inserting it into an URL template. +- Fix a crash when cloning a blank tab. +- When the widget losses focus hide the access keys. +- Fix detection of flash on various websites when ClickToFlash is used. +- Avoid an infinite recursion when asking the desktop to open an URL. +- When the download manager prevents the application from closing add a new tab when there are none. +- Only show the url completer if the user is typing a url. +- Always add the Inspect Element Action to the context menu when the developer extra tools are enabled. +- Bookmarklets were not working properly. +- Work around for a segfault in Qt 4.5.2 where you go into privacy mode while a QNetworkReply is still working. +- Clarify the networkdisk cache behavior in the messagebox. +- Start page: Reduce the top margin to 100px from so it fits on a netbook screen. +- Hide the bookmarks toolbar by default. +- Turn off cookie tracking filtering by default because it breaks sites like StackOverflow.com. +- Before clearing the cookie jar, load it so the exceptions and other settings are loaded. +- When removing cookies from the cookie jar via the cookie dialog notify the autosaver. +- When receiving a drop event on a bookmark folder, make sure that we don't drop a child bookmark. +- Avoid overwriting the user agent string in the WebPage autotest. +- Fix non-ASCII characters displayed garbled for Authors. + +Behind the scenes +- Merge two blocks of code that deals with oneCloseButton policy. +- Make parentWindow() prettier. +- Simplify updates of actions in view menu. +- Save the window state when toggling the menu bar. +- Save UI changes in the active window before creating a new one. +- Move all network related files into one directory. + +Build system +- When building on osx use qmake -r. +- Ignore generated files built on windows. + + +0.8.0 +Interface +FEATURES: +- When the ctrl key is pressed show keyboard accelerators on the screen. [Qt 4.6 only]. +- Location bar: implement full text search and more accurate sorting. +- Add a simple start page with a search box pointing at the active search engine. +- Allow to create new open search engines from any input forms displayed in websites [Qt 4.6 only]. +- Add a menu to set the default text encoding for all rendering [Qt 4.6 only]. +- Implement directory listing when accessing file:/// URLs that point to directories. +- When a POST request is about to be resent, warn user about that fact to make sure that the operation is intended. +- Add a checkable push button to the search bar that allows to highlight a specific string in a website [Qt 4.6 only]. +- Add a setting that specifies if the url supplied by the user should be forwarded to the default search engine if it isn't valid. + +IMPROVEMENTS: +- Show a more verbose message when the htmlToXBel tool is not installed. +- Show the complete tab title as tool tip to improve GUI usability for long website titles. +- Download manager: Create the download directory as needed. +- Location bar: If escape is pressed on location bar revert to the original URL, this emulates the firefox behaviour. +- Add Google "I'm Feeling Lucky" search engine to the default set. +- Drag & Drop: Add the ability to drop an url on the tab bar which will open it in a new tab. +- Drag & Drop: Allow dropping URLs on the location bar. +- When creating new windows, use the startup setting to decide if the homepage should be loaded. +- Remove the network monitor tool as the current Inspector now lets you see request headers and response headers. + +BUGFIXES: +- Fix several memory leaks: set the Qt::WA_DeleteOnClose flag on dialogs that are executed asynchronously. +- Download manager: Fix displaying file size when downloading huge files. +- Download manager: Give correct name to downloaded files with no suffix. +- Location bar: Fix background color when using Oxygen style. +- Bookmarks manager: Don't allow to edit the url in any nodes but normal bookmarks. +- Private browsing now disables the disk cache. + +Behind the scenes +- Added custom network scheme handlers, i.e. a single one for listing local directories. +- Add a setting so the user can swap the location of the new and close tab buttons. +- Add the ability for a user to specify the userAgent through QSettings. +- Split up the bookmarks classes into separate files. +- Remake the bookmarks toolbar. +- Clean up the AddBookmarkDialog class. +- OpenSearch: Implement the Referrer extension. +- Implement the WebPage::linkedResources() method using the DOM API. +- Tweak the certToFormattedString() function. +- OpenSearch: localization improvements. + +Build system +- Include an additional XML file in the installation, which will make Arora appear in Gnome Control Center on the list of available web browsers that can be set as default. +- Add man pages for the tools. +- webkit.pri now supports building QtWebKit as a framework on mac. + + +0.7.1 +Fix Windows build. +Fix building in parallel (make -jX). + + +0.7.0 +Interface +- Add support for OpenSearch to the toolbar search +- Add the ability to search from the webpage context menu +- Remember the boxes checked in the Clear Private Data dialog +- Support Back, Forward, Reload and Stop keys on multimedia keyboards +- Add the ability to click a button before loading flash (clickToFlash) +- Allow to enable/disable the cache +- Allow to specify the maximum cache size +- Add a setting specifying if the application should quit when last tab is closed. +- Revert the check for the Oxygen style so when under KDE4 Oxygen will be +used even if it has issues. +- Fix mid click to paste urls into Arora to have them be loaded +- Fix crash in Clear Privacy Dialog when cache is disabled +- In the download manager change the "Ok" Button to "Close" +- Fix the positioning of new tab and close tab buttons. Comparing to 0.6 they are just swapped now. +- Only set a git version if the string is not empty +- Update the tab bar visibility action when retranslating. +- Make refresh be both F5 and Ctrl+R +- Update year in copyright +- Fixed some spelling mistakes +- Ctrl+L does not function when the toolbar is hidden. +- Fix a typo in Info_mac.plist. +- Enable multiple selection in the history tree view. +- Respect the setting to hide confirmation of closing multiple tabs when quitting too +- Fix a problem with cookie rule deletion +- Improve handling of unreachable sites. +- Create a new tab only when left button is double-clicked. +- Improve XBel importing +- Don't fill the history with error pages. +- Improve the site icon when dragging. When the mouse is over it show the arrow cursor, Set the drag icon to the site icon, and set the drag text to the page title and not the url. (Example drag to the toolbar you want to get the title not the url) +- Only save the cookie exception rules if the dialog is accepted. +- Set cookies to 'session only' if new rule introduced that would only allow them for the session. +- Add ability to filter out tracking cookies, eg Google Analytics. +- Add 'Add Rule' button to the cookie dialog to create an exception on the current cookie. +- When a cookie is a session cookie show the string 'Session Cookie' +- Improve the cooking blocking implementation +- Add subdomain checking, eg when the policy says 'block def.com', then it will block cookies from 'def.com', 'www.def.com' but not from 'abcdef.com' +- Handle cookie rules with starting dot correctly + +Behind the scenes +- Add a subclass of QWebPluginFactory that can be used for managing QWebPlugin's +- Add a static BrowserMainWindow::parentWindow(QWidget *) method that returns a main window being one of the passed widget's parents. +- Move QTRY functions into their own header file as it has no dependency on Arora and can be used by tests that don't require BrowserApplication +- Mark strings as not translatable where it doesn't make sense +- Move location bar site icon class into its own file +- Move the privacy indicator out into its own class and file +- Move the location bar classes into a location bar folder +- Add api to get the clear button and search button in the SearchWidget +- Remove the word 'slot' from the functions that are slots to be consistent with the reset of the source code. +- Don't translate dummy strings in the ui file +- Move HistoryManager into its own file and move the history classes into their own folder. +- Conserve memory by atomizing history strings +- Code style: Add m_ prefix before private variables +- Improvements & cleanup to the about dialog +- Improve the three editviews +- Add manualtest for the three edit views and an autotest for the editlistview. +- Change placesimport to correctly use SingleApplication +- Add WebPage::linkedResources(const QString&) method that returns a list of resources attached to the main document +- BrowserApplication::mainWindow() returns the currently active window + +Build system +- Remove one second punishment because it didn't work and I didn't make autotests when I was punished +- Add foreach() style error to look for and fix existing occurences. +- When building by default don't have lrelase be verbose as it du/mps a lot of junk on the console +- Add commit hook to do basic style checking on the files being commited +- unset GIT_DIR to fix warnings that are printed to the console +- When building Arora also don't allow casts to ascii to detect bugs. +- Share compiled object files with the main arora binary to reduce build times + + +0.6.1 +When using Arora with Qt 4.5.1 after a little while pages will stop rendering. +This is because of a bug in 4.5.1 where renaming a file will cause the file +descriptor to not be closed. QNetworkDiskCache is a simple cache and uses +QTemporaryFile's for each new cached file and eventually the kernel +wont let QNetworkDiskCache open a cache file because all of the previous files were not +closed. When running against Qt 4.5.1 Arora will now disable the disk cache. + + +0.6 +Interface +- Save more of the main window state, window's fullscreen status, maximized status, menu bar visibility, normal size, and ensure that the menu bar and status bar are returned to their proper states if saving while the window is fullscreen. +- Open a downloaded file instead of the containing directory +- Add check for the Oxygen style and switch to Plastique unless the user specifies oxygen on the command line +- The action to show the status bar isn't updated when entering/exiting fullscreen. +- slow down the loading animation to use less X11 resources +- Add Google suggestions to the search widget +- Ctrl-0 is now zoom-reset, only support jumping to the first 9 tabs rather then 10 +- Add action to add a bookmark folder to the bookmark menu +- Display more loading information in the status bar. +- Make 'Url' and 'Title' string translatable in Add Bookmark dialog. +- Making SSL warnings more verbose Especially show the Certs a bit +- If there is any active download on quit, warn user and ask for confirmation. +- Add "Open in Tabs" action to all bookmark menu's. +- Add "Save all Tabs" action to the bookmark menu and the tabbar context menu. +- Support preferred web content language +- Add common location bar shortcuts such as Alt-D +- Allow to close the browser with more than one window opened, which was previously impossible (it might be useful when you restore session on startup). +- Revert to the default tab selection behavior after closing a tab to match other browsers +- Middle button role should be inverted when "Select tabs and windows as they created" is selected +- Add support for MidClick/Ctrl-Click/Shift-Ctrl-Click to all urls in Arora. Be it in menus, toolbars, links and javascript links. +- Add support for XButton1 and XButton2 to be back/forward on the webview +- Add the ability to turn pop-up blocking off +- More control to the users! Added a possibility to control where target="_blank" links will be opened and default to a new tab. +- When opening a url from history include the old title which can populate the tab title. +- Clearing the cache should only be enabled by default when compiled with Qt 4.5 +- Set bookmarks bar as default folder when executing Add Bookmark Dialog from bookmarks toolbar. +- Fixed typo that had clear cookies set checked twice instead of checking cookies once and cache once. +- Force selected window to be on top of the windows stack (previous solution was only activating the window on the taskbar, at least on some desktop environments). +- One tab close button option should not affect tab open button appearance. +- Set Open action disabled in the download manager until the download is finished. +- Add the ability to import html bookmarks using the existing htmlToXBel tool +- Fix issue where shortcuts where not working +- Fix issue where actions in the menus were not being translated when you change the language. +- Add support for caching HTTP proxies when using Qt 4.5 +- Add full page zooming +- Added a new tool 'placesimport' to import Firefox 3+ history. +- Fix the download manager SqueezeLabel class so that doesn't use 100% cpu, also now under the BSD +- Tweak html error message to make more sense +- Several spelling errors in the interface and code. + + +Behind the scenes +-Upgrade the SearchLineEdit class + - Rather then using a QMenu use QCompleter now that LineEdit can let you set the text margin and the completer popup takes up the whole width. + - Re-code searchlineedit to just be a LineEdit subclass that has a search button and a clear button and nothing more. + - Re-code the SearchButton to use the QCompleter, take up less width when there isn't one and use a QImage. + - Update the toolbar search widget to use the completer rather then the old QMenu +- Significantly improve the startup time of Arora. +- Add new access functions to the DownloadItem data. +- Move the ClearButton and SearchButton class into its own file +- Fix searchbar for special chars such as '+'. This seems a bug in Qt's addQueryItem. Workaround is to use addEncodedQueryItem. +- delete the root bookmark node on exit to not generate errors in valgrind +- fix memory leaks in the autotest to confirm that Arora's xbel doesn't have any leaks +- Only clear the cookies if we have loaded them +- In ModelMenu rather then all submenu's being QMenu let them be specified by the implementation and as the default use ModelMenu. +- Add new menumodel manualtest +- Set the default max rows of the model menu to -1 and put the special case of 7 in the history menu code +- In 4.5 and beyond store the icon database in the cache directory +- Add a few more mimetypes and match the Firefox desktop file +- Only guess a url string is for a file if it is an absolute path. +- Improve the overall design and implimentation of url loading especially when dealing with a startin +- Several improvements to SingleApplication to make it more robust. +- Improve the git hooks and add a hook to spell check commits +- Don't hard code the location of tmp as it could easily not be /tmp as it is on OS X +- Remove executable bit from html not found file +- Be more vigilant about always using encoded urls when storing them in QString + +Build system +- Ignore generated files on Windows +- Add a common way to install binaries and install the tools +- Add commit hook commit-msg with support for aspell to check the spelling of the commit message +- In a source tarball and there is no .git hard code the version and change number so a message doesn't goto the console complaining about no git +- Windows needs to link to advapi32 for GetUserName call, so add it to LIBS. +- Don't force the binary to be re-build every time make is called because of the locale.pri +- Install tools +- Improve the build times of the manualtests by sharing object files and simplifying the includes + + +0.5 +Interface +- Add new Network Access Monitor tool that shows each network request as it passes. +- Added option for showing only one close Button +- Don't add empty tabs if closed to recently closed tabs menu. +- Support HTTP proxies which listen in ports higher than 10000 +- Save more space in full screen mode - hide menu and status bars. +- Added an option in source viewer menu for wrapping code lines. +- Open pages from autocompletion list directly instead of filling the bar with their addresses. + +- Don't show Open actions if the item is a Folder in the Bookmark Manager +- Allow filtering bookmarks and histories by URLs as well. +- Add drag functionality to Bookmark and History menu's +- Allow selecting multiple bookmarks when ctrl is pressed. +- Added support for renaming bookmarks through their context menus. +- Expanded bookmark menu - added Change URL and made Rename displayed also on folders. +- Allow for unlimited bookmarks in a folder on bookmark bar + +- Added privacy indicator to the location bar +- Uncheck the privacy action when user aborts initial private browsing dialog. +- When enabling or disabling private browsing only the checkbox on the current window is updated + +- Display missing Copy action in context menu if a link is selected. +- Make tab reload action in the context menu work +- Fix Middleclick on open tab to not have inconsistent behavior. +- On some web pages, middle-clicking a link opened it in the same window. +- Refined drag & drop handling in bookmarks toolbar. Fixed a bug, when page was assigned to inappropriate folder due to more than one folder having same name. +- Implement simple context menu in bookmarks toolbar. Let user change bookmark URL in Add Bookmark dialog. + +Behind the scenes +- Brand new more compliant, faster cookie jar +- Brand new Language Manager which selects the correct language on start and lets you choose a different language via the Help menu. +- Separate the cookie classes into separate files. +- Fix a memory leak when creating the context menu under Qt 4.5+ +- LineEdit utility class is now under the BSD license +- The error web pages are now translatable. +- Encode urls rather then use toString in various places to prevent loss of url data. +- When using foreach try to use a const reference so a copy isn't made (slower) compared to the reference (faster). +- Add a new tool to convert bookmarks that are in the html format into the XBel format (not used in Arora yet). +- Various code style and general keeping the code clean fixes +- Add Implementation to get the current username on Windows for the single application + +Build system +- Add script to build OS X package using the new macdeployqt tool in Qt 4.5 +- Building with QT_STRICT_ITERATORS to catch errors. +- Enhance support for building with multiple WebKit trunk branches +- Adds the ability to generate code documentation with doxygen + +0.4 +Interface +- New source viewer with search and syntax highlighting. +- Make middle click on bookmarks menus open the user in a new tab. +- Added the ability to change the language from the Help menu. +- Double left click location bar selects all of the text. +- Incorporate Jens Explorer style into Arora on Window for a better look and feel on XP and Vista. http://labs.trolltech.com/blogs/2007/06/08/explorer-style-toolbars/ +- Change the "icon" on the next/prev search for RTL desktops: next points to the right, and previous points to the right +- Various RightToLeft fixes for for Mozilla's bug https://bugzilla.mozilla.org/show_bug.cgi?id=219070 +- When the url scheme is https make the location bar background turn yellow. +- When the history is cleared also clear the recently closed tabs list +- Always populate the location bar with the completer +- Only shrink the toolbar icons on OS X. +- Only offset the search widget text when using Qt 4.5 +- When clicking on a bookmark in a folder in the toolbar emit the proper signals to the url is opened. +- When dropping text on the webpage load the url +- When the location bar has focus don't change the text. + +Behind the scenes +- Make a dedicated SingleApplication class +- Tweak HistoryManager API to be easier to read. +- Improvements to the code style to be more consistent +- Move the binaries for autotests and manual tests into the .gitignore in that directory rather then all in one file at the top. +- Update manualtest for the location bar now that the urllineedit class has become the new location bar class and add a new git hook to make sure manual tests build. + +Build system +- Move locale build instructions to its own pri file in the locale directory +- Correctly detect qt3's qmake on Debian +- Enhance support for building with WebKit trunk + + +0.3 +- With Qt 4.5 use movable tabs +- With Qt 4.5 use disk cache +- Created a new LineEdit that handles adding side widgets in a clean, simple and elegant way. +- Add a way to set the minimum font size in the settings. +- When you ctrl-click on a bookmark item in the bookmark toolbar open it in a new tab +- Fix possible crash on startup; Initialize htmls resource +- When making the text larger or smaller, use predefined zoom levels. +- Mouse button 4 and 5 connected to action back and forward. like firefox and ie +- Clear history: Added confirm dialog +- Shortcuts in the Edit menu like in Firefox. +- Save the state of inspector across sessions. +- When only a hostname and port are entered in the url prepend http:// +- Base the width of the tab on a font rather then a hard coded value +- Tweak the main window look better on OS X and less out of place +- Add support for javascript bookmarklets +- Add option to automatically restore the session on startup. +- Fix segfault caused by the clear private data dialog. +- Save the location of the toolbars +- Improve a number of the strings (feedback from MentalMaelstrom) +- Tweak action accelerators (the same ones were being used) + +Build system +- Allow building Arora with both Debug/Release of WebKit trunk +- Only include the sha1 and change number in the version when using git. +- Create utils directory to contain non-Arora specific classes +- Run desktop file through desktop-file-validate and correct the errors + +Autotests +- Add QTRY_COMPARE and QTRY_VERIFY for the autotests to use. +- add AUTOTESTS define when running autotests to prevent accessing running arora's and sending url's to it +- Fix autotest failures (test related, not arora) +- Detect which version of qmake to use when building the autotests +- Give a 1 second punishment if there is no autotest for the source file that was changed +- Emit a warning of a file doesn't have a matching autotest +- Update modeltest code to match Trolltech's svn + + 0.2 - - Branch from the Qt demo browser + - Many Bug fixes and improvements. + - Add make install on unix + - Improved tabs + - Translations + - New reset dialog + - New about dialog + - Add search banner + - Rename to Arora and a new application icon + - Project specific git hooks + - Branch from the Qt demo browser with new autotests and manualtests diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 00000000..c3bf8a8a --- /dev/null +++ b/Doxyfile @@ -0,0 +1,1473 @@ +# Doxyfile 1.5.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Arora + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, +# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), +# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, +# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene, +# Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed by +# doxygen. The layout file controls the global structure of the generated output files +# in an output format independent way. The create the layout file that represents +# doxygen's defaults, run doxygen with the -l option. You can optionally specify a +# file name after the option, if omitted DoxygenLayout.xml will be used as the name +# of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = src + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = src/.moc src/.rcc + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = YES + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = NO + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and QHP_VIRTUAL_FOLDER +# are set, an additional index file will be generated that can be used as input for +# Qt's qhelpgenerator to generate a Qt Compressed Help (.qch) of the generated +# HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# Qt Help Project / Namespace. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# Qt Help Project / Virtual Folders. + +QHP_VIRTUAL_FOLDER = doc + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file . + +QHG_LOCATION = + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to FRAME, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. Other possible values +# for this tag are: HIERARCHIES, which will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list; +# ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which +# disables this behavior completely. For backwards compatibility with previous +# releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE +# respectively. + +GENERATE_TREEVIEW = FRAME + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# 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. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = NO + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = YES diff --git a/README b/README index 13de8681..1f2bd210 100644 --- a/README +++ b/README @@ -1,5 +1,7 @@ Arora web browser -http://www.arora-browser.org +Arora is a cross platform web browser built using Qt and WebKit. -Arora is a cross platform web browser built using Qt and WebKit. \ No newline at end of file +Building: +Arora uses the qmake build system. If you already have Qt 4.5 or newer on your system building is as easy as running the command 'qmake' and then 'make' or 'nmake' on Windows. +For more detailed information see https://github.com/Arora/arora/wiki/BeginnerStepByStepInstructions diff --git a/arora.pro b/arora.pro index d97061d7..f4db8e27 100644 --- a/arora.pro +++ b/arora.pro @@ -1,8 +1,15 @@ -QMAKEVERSION = $$[QMAKE_VERSION] -ISQT4 = $$find(QMAKEVERSION, ^[2-9]) -isEmpty( ISQT4 ) { -error("Use the qmake include with Qt4.4 or greater, on Debian that is qmake-qt4"); +lessThan(QT_VERSION, 4.5) { + error("Arora requires Qt 4.5 or greater") } TEMPLATE = subdirs -SUBDIRS = src +SUBDIRS = src tools +CONFIG += ordered + +unix { + # this is an ugly work around to do .PHONY: doc + doxygen.target = doc dox + doxygen.commands = doxygen Doxyfile + doxygen.depends = Doxyfile + QMAKE_EXTRA_TARGETS += doxygen +} diff --git a/autotests/adblock/adblock.pro b/autotests/adblock/adblock.pro new file mode 100644 index 00000000..e00136d1 --- /dev/null +++ b/autotests/adblock/adblock.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs +SUBDIRS = \ + adblockmanager \ + adblocknetwork \ + adblockpage \ + adblockrule \ + adblocksubscription + +CONFIG += ordered diff --git a/autotests/adblock/adblockmanager/.gitignore b/autotests/adblock/adblockmanager/.gitignore new file mode 100644 index 00000000..956108dc --- /dev/null +++ b/autotests/adblock/adblockmanager/.gitignore @@ -0,0 +1 @@ +adblockmanager diff --git a/autotests/adblock/adblockmanager/adblockmanager.pro b/autotests/adblock/adblockmanager/adblockmanager.pro new file mode 100644 index 00000000..025c3a5a --- /dev/null +++ b/autotests/adblock/adblockmanager/adblockmanager.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES += tst_adblockmanager.cpp +HEADERS += diff --git a/autotests/adblock/adblockmanager/tst_adblockmanager.cpp b/autotests/adblock/adblockmanager/tst_adblockmanager.cpp new file mode 100644 index 00000000..f27d9179 --- /dev/null +++ b/autotests/adblock/adblockmanager/tst_adblockmanager.cpp @@ -0,0 +1,238 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "adblockdialog.h" +#include "adblockmanager.h" +#include "adblocksubscription.h" + +#include + +class tst_AdBlockManager : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void adblockmanager_data(); + void adblockmanager(); + + void addSubscription(); + void customRules(); + void isEnabled_data(); + void isEnabled(); + void load(); + void removeSubscription(); + void showDialog(); + void rulesChanged(); +}; + +// Subclass that exposes the protected functions. +class SubAdBlockManager : public AdBlockManager +{ +public: + ~SubAdBlockManager() { + QList list = subscriptions(); + foreach (AdBlockSubscription *s, list) + removeSubscription(s); + setEnabled(false); + } + + void call_rulesChanged() + { return SubAdBlockManager::rulesChanged(); } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_AdBlockManager::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_AdBlockManager::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_AdBlockManager::init() +{ +} + +// This will be called after every test function. +void tst_AdBlockManager::cleanup() +{ +} + +void tst_AdBlockManager::adblockmanager_data() +{ +} + +void tst_AdBlockManager::adblockmanager() +{ + SubAdBlockManager manager; + manager.addSubscription((AdBlockSubscription*)0); + QVERIFY(manager.customRules()); + QVERIFY(manager.instance() != (AdBlockManager*)0); + QCOMPARE(manager.isEnabled(), true); + manager.load(); + QVERIFY(manager.network()); + QVERIFY(manager.page()); + manager.removeSubscription((AdBlockSubscription*)0); + manager.setEnabled(false); + QVERIFY(manager.showDialog()); + QList list; + list.append(manager.customRules()); + QCOMPARE(manager.subscriptions(), list); +} + +// public void addSubscription(AdBlockSubscription *subscription) +void tst_AdBlockManager::addSubscription() +{ + SubAdBlockManager manager; + + QList list = manager.subscriptions(); + + QSignalSpy spy0(&manager, SIGNAL(rulesChanged())); + + AdBlockSubscription *subscription = new AdBlockSubscription(QUrl(), &manager); + manager.addSubscription(subscription); + QCOMPARE(manager.subscriptions(), (list += subscription)); + + QCOMPARE(spy0.count(), 1); +} + +// public AdBlockSubscription *customRules() +void tst_AdBlockManager::customRules() +{ + SubAdBlockManager manager; + QSignalSpy spy0(&manager, SIGNAL(rulesChanged())); + + AdBlockSubscription *subscription = manager.customRules(); + QVERIFY(subscription); + QVERIFY(!subscription->title().isEmpty()); + QVERIFY(subscription->allRules().isEmpty()); + + QCOMPARE(spy0.count(), 1); + + subscription = manager.customRules(); + QCOMPARE(spy0.count(), 1); +} + +void tst_AdBlockManager::isEnabled_data() +{ + QTest::addColumn("isEnabled"); + QTest::newRow("true") << true; + QTest::newRow("false") << false; +} + +// public bool isEnabled() const +void tst_AdBlockManager::isEnabled() +{ + QFETCH(bool, isEnabled); + + SubAdBlockManager manager; + + QSignalSpy spy0(&manager, SIGNAL(rulesChanged())); + + bool before = manager.isEnabled(); + + manager.setEnabled(isEnabled); + manager.setEnabled(isEnabled); + QCOMPARE(manager.isEnabled(), isEnabled); + + QCOMPARE(spy0.count(), before == isEnabled ? 0 : 1); +} + +// public void load() +void tst_AdBlockManager::load() +{ + SubAdBlockManager manager; + + QSignalSpy spy0(&manager, SIGNAL(rulesChanged())); + + manager.load(); + + QCOMPARE(spy0.count(), 0); +} + +// public void removeSubscription(AdBlockSubscription *subscription) +void tst_AdBlockManager::removeSubscription() +{ + SubAdBlockManager manager; + + QSignalSpy spy0(&manager, SIGNAL(rulesChanged())); + + QList list = manager.subscriptions(); + AdBlockSubscription *subscription = new AdBlockSubscription(QUrl(), &manager); + manager.addSubscription(subscription); + manager.removeSubscription(subscription); + QCOMPARE(manager.subscriptions(), list); + + QCOMPARE(spy0.count(), 2); +} + + +// public AdBlockDialog *showDialog() +void tst_AdBlockManager::showDialog() +{ + SubAdBlockManager manager; + + QSignalSpy spy0(&manager, SIGNAL(rulesChanged())); + + AdBlockDialog *dialog = manager.showDialog(); + QVERIFY(dialog); + QTRY_VERIFY(dialog->isVisible()); +} + +void tst_AdBlockManager::rulesChanged() +{ + SubAdBlockManager manager; + + QSignalSpy spy0(&manager, SIGNAL(rulesChanged())); + + + AdBlockSubscription *subscription = new AdBlockSubscription(QUrl(), &manager); + manager.addSubscription(subscription); + subscription->setEnabled(true); + subscription->addRule(AdBlockRule()); + + QCOMPARE(spy0.count(), 3); +} + +QTEST_MAIN(tst_AdBlockManager) +#include "tst_adblockmanager.moc" + diff --git a/autotests/adblock/adblocknetwork/.gitignore b/autotests/adblock/adblocknetwork/.gitignore new file mode 100644 index 00000000..dcb473fd --- /dev/null +++ b/autotests/adblock/adblocknetwork/.gitignore @@ -0,0 +1 @@ +adblocknetwork diff --git a/autotests/adblock/adblocknetwork/adblocknetwork.pro b/autotests/adblock/adblocknetwork/adblocknetwork.pro new file mode 100644 index 00000000..2ae14cc2 --- /dev/null +++ b/autotests/adblock/adblocknetwork/adblocknetwork.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES += tst_adblocknetwork.cpp +HEADERS += diff --git a/autotests/adblock/adblocknetwork/tst_adblocknetwork.cpp b/autotests/adblock/adblocknetwork/tst_adblocknetwork.cpp new file mode 100644 index 00000000..90b2ea6e --- /dev/null +++ b/autotests/adblock/adblocknetwork/tst_adblocknetwork.cpp @@ -0,0 +1,224 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +#include "adblocknetwork.h" +#include "adblockmanager.h" +#include "adblocksubscription.h" +#include "adblockrule.h" + +#include + +class tst_AdBlockNetwork : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void adblocknetwork_data(); + void adblocknetwork(); + + void data(); + + void enabled_data(); + void enabled(); + + void block_data(); + void block(); +}; + +// Subclass that exposes the protected functions. +class SubAdBlockNetwork : public AdBlockNetwork +{ +public: + +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_AdBlockNetwork::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_AdBlockNetwork::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_AdBlockNetwork::init() +{ +} + +// This will be called after every test function. +void tst_AdBlockNetwork::cleanup() +{ + AdBlockManager *manager = AdBlockManager::instance(); + QList list = manager->subscriptions(); + foreach (AdBlockSubscription *s, list) + manager->removeSubscription(s); +} + +void tst_AdBlockNetwork::adblocknetwork_data() +{ +} + +void tst_AdBlockNetwork::adblocknetwork() +{ + SubAdBlockNetwork network; + QCOMPARE(network.block(QNetworkRequest()), (QNetworkReply*)0); +} + +void tst_AdBlockNetwork::data() +{ + SubAdBlockNetwork network; + + AdBlockManager *manager = AdBlockManager::instance(); + manager->setEnabled(true); + + AdBlockSubscription *subscription = new AdBlockSubscription(QUrl(), manager); + subscription->setEnabled(true); + manager->addSubscription(subscription); + + AdBlockRule rule("/"); + rule.setEnabled(true); + subscription->addRule(rule); + + QNetworkReply *reply = 0; + QNetworkRequest request = QNetworkRequest(QUrl("data://foobar")); + + reply = network.block(request); + QVERIFY(!reply); +} + +void tst_AdBlockNetwork::enabled_data() +{ + QTest::addColumn("enableManager"); + QTest::addColumn("enableSubscription"); + QTest::addColumn("enableRule"); + QTest::addColumn("block"); + QTest::newRow("null") << true << true << true << true; + QTest::newRow("m") << false << true << true << false; + QTest::newRow("s") << true << false << true << false; + QTest::newRow("r") << true << true << false << false; +} + +void tst_AdBlockNetwork::enabled() +{ + QFETCH(bool, enableManager); + QFETCH(bool, enableSubscription); + QFETCH(bool, enableRule); + QFETCH(bool, block); + + SubAdBlockNetwork network; + + AdBlockManager *manager = AdBlockManager::instance(); + manager->setEnabled(enableManager); + + AdBlockSubscription *subscription = new AdBlockSubscription(QUrl(), manager); + subscription->setEnabled(enableSubscription); + manager->addSubscription(subscription); + + AdBlockRule rule("/"); + rule.setEnabled(enableRule); + subscription->addRule(rule); + + QNetworkReply *reply = 0; + QNetworkRequest grequest = QNetworkRequest(QUrl("http://www.google.com")); + + reply = network.block(grequest); + QCOMPARE((reply != 0), block); +} + +// check that block block and !block blocks other sites +void tst_AdBlockNetwork::block_data() +{ + QTest::addColumn("ruleList"); + QTest::addColumn("url"); + QTest::addColumn("block"); + + QTest::newRow("null") << QString() + << QUrl() + << false; + + QUrl google("http://www.google.com"); + QTest::newRow("google") << QString("/") + << google + << true; + + // defining exception rules + QTest::newRow("exception0") << QString("@@advice,advice") + << QUrl("http://example.com/advice.html") + << false; + QTest::newRow("exception1") << QString("@@|http://example.com") + << QUrl("http://example.com/advice.html") + << false; + QTest::newRow("exception2") << QString("@@http://example.com") + << QUrl("http://example.com/advice.html") + << false; + + QTest::newRow("order0") << QString("advice,@@advice") + << QUrl("http://example.com/advice.html") + << false; +} + +// public QNetworkReply *block(QNetworkRequest const &request) +void tst_AdBlockNetwork::block() +{ + QFETCH(QString, ruleList); + QFETCH(QUrl, url); + QFETCH(bool, block); + + SubAdBlockNetwork network; + + AdBlockManager *manager = AdBlockManager::instance(); + manager->setEnabled(true); + + AdBlockSubscription *subscription = new AdBlockSubscription(QUrl(), manager); + subscription->setEnabled(true); + manager->addSubscription(subscription); + + QStringList rules = ruleList.split(","); + foreach (const QString &rule, rules) + subscription->addRule(AdBlockRule(rule)); + + QNetworkReply *reply = network.block(QNetworkRequest(url)); + bool blocked = (reply != 0); + QCOMPARE(blocked, block); +} + +QTEST_MAIN(tst_AdBlockNetwork) +#include "tst_adblocknetwork.moc" + diff --git a/autotests/adblock/adblockpage/.gitignore b/autotests/adblock/adblockpage/.gitignore new file mode 100644 index 00000000..ed880152 --- /dev/null +++ b/autotests/adblock/adblockpage/.gitignore @@ -0,0 +1 @@ +adblockpage diff --git a/autotests/adblock/adblockpage/adblockpage.pro b/autotests/adblock/adblockpage/adblockpage.pro new file mode 100644 index 00000000..a6a6b207 --- /dev/null +++ b/autotests/adblock/adblockpage/adblockpage.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES += tst_adblockpage.cpp +HEADERS += diff --git a/autotests/adblock/adblockpage/test.html b/autotests/adblock/adblockpage/test.html new file mode 100644 index 00000000..39cb99d1 --- /dev/null +++ b/autotests/adblock/adblockpage/test.html @@ -0,0 +1,8 @@ + +
Cheapest tofu, only here and now!
+
Really cheap tofu, click here!
+Only here you get the best tofu! +
tofu!
+
Cheapest tofu, only here and now!
+
Cheapest tofu, only here and now!
+
tofu!
diff --git a/autotests/adblock/adblockpage/tst_adblockpage.cpp b/autotests/adblock/adblockpage/tst_adblockpage.cpp new file mode 100644 index 00000000..ee8d16ac --- /dev/null +++ b/autotests/adblock/adblockpage/tst_adblockpage.cpp @@ -0,0 +1,160 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "adblockpage.h" + +#include "adblockmanager.h" +#include "adblocksubscription.h" +#include "adblockrule.h" + +#include +#include +#include +#include + +class tst_AdBlockPage : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void adblockpage_data(); + void adblockpage(); + + void applyRulesToPage_data(); + void applyRulesToPage(); +}; + +// Subclass that exposes the protected functions. +class SubAdBlockPage : public AdBlockPage +{ +public: + +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_AdBlockPage::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_AdBlockPage::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_AdBlockPage::init() +{ +} + +// This will be called after every test function. +void tst_AdBlockPage::cleanup() +{ + AdBlockManager *manager = AdBlockManager::instance(); + QList list = manager->subscriptions(); + foreach (AdBlockSubscription *s, list) + manager->removeSubscription(s); +} + +void tst_AdBlockPage::adblockpage_data() +{ +} + +void tst_AdBlockPage::adblockpage() +{ + SubAdBlockPage page; + page.applyRulesToPage((QWebPage*)0); +} + +void tst_AdBlockPage::applyRulesToPage_data() +{ + QTest::addColumn("ruleList"); + QTest::addColumn("count"); + + int start = 7; + QTest::newRow("null") << QString() << start; + + //Examples taken from http://adblockplus.org/en/filters + + QTest::newRow("basic-0") << QString("##div.textad") << start - 1; + QTest::newRow("basic-1") << QString("##div#sponsorad") << start - 1; + QTest::newRow("basic-2") << QString("##*#sponsorad") << start - 1; + QTest::newRow("basic-3") << QString("##textad") << start -1; + + // Attribute selectors + QTest::newRow("attribute-0") << QString("##table[width=\"80%\"]") << start - 2; + QTest::newRow("attribute-1") << QString("##table[width=\"80%\"][bgcolor=\"white\"]") << start - 1; + QTest::newRow("attribute-2") << QString("##div[title*=\"adv\"]") << start - 2; + QTest::newRow("attribute-3") << QString("##div[title^=\"adv\"][title$=\"ert\"]") << start - 1; + + // Advanced selectors +} + +// public void applyRulesToPage(QWebPage *page) +void tst_AdBlockPage::applyRulesToPage() +{ + QFETCH(QString, ruleList); + QFETCH(int, count); + + AdBlockManager *manager = AdBlockManager::instance(); + manager->setEnabled(true); + + AdBlockSubscription *subscription = new AdBlockSubscription(QUrl(), manager); + subscription->setEnabled(true); + manager->addSubscription(subscription); + + QStringList rules = ruleList.split(","); + foreach (const QString &rule, rules) + subscription->addRule(AdBlockRule(rule)); + + QWebView view; + QSignalSpy spy1(view.page(), SIGNAL(loadFinished(bool))); + view.load(QUrl::fromLocalFile(QDir::currentPath() + "/test.html")); + QTRY_COMPARE(spy1.count(), 1); + + SubAdBlockPage page; + page.applyRulesToPage(view.page()); + if (view.page()->mainFrame()->toHtml().count("tofu") != count) + qDebug() << view.page()->mainFrame()->toHtml(); + QCOMPARE(view.page()->mainFrame()->toHtml().count("tofu"), count); +} + +QTEST_MAIN(tst_AdBlockPage) +#include "tst_adblockpage.moc" + diff --git a/autotests/adblock/adblockrule/.gitignore b/autotests/adblock/adblockrule/.gitignore new file mode 100644 index 00000000..3b9e3229 --- /dev/null +++ b/autotests/adblock/adblockrule/.gitignore @@ -0,0 +1 @@ +adblockrule diff --git a/autotests/adblock/adblockrule/adblockrule.pro b/autotests/adblock/adblockrule/adblockrule.pro new file mode 100644 index 00000000..52435394 --- /dev/null +++ b/autotests/adblock/adblockrule/adblockrule.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES += tst_adblockrule.cpp +HEADERS += diff --git a/autotests/adblock/adblockrule/tst_adblockrule.cpp b/autotests/adblock/adblockrule/tst_adblockrule.cpp new file mode 100644 index 00000000..1ba1a046 --- /dev/null +++ b/autotests/adblock/adblockrule/tst_adblockrule.cpp @@ -0,0 +1,385 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * Copyright 2009 Zsombor Gegesy + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include "adblockrule.h" + +#include +#include + +class tst_AdBlockRule : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void regexpCreation_data(); + void regexpCreation(); + void networkMatch_data(); + void networkMatch(); + +}; + +// Subclass that exposes the protected functions. +class SubAdBlockRule : public AdBlockRule +{ +public: + SubAdBlockRule(const QString &filter); +}; + +SubAdBlockRule::SubAdBlockRule(const QString &filter) + : AdBlockRule(filter) +{ +} + +// This will be called before the first test function is executed. +// It is only called once. +void tst_AdBlockRule::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_AdBlockRule::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_AdBlockRule::init() +{ +} + +// This will be called after every test function. +void tst_AdBlockRule::cleanup() +{ +} + +void tst_AdBlockRule::networkMatch_data() +{ + QTest::addColumn("filter"); + QTest::addColumn("url"); + QTest::addColumn("networkMatch"); + QTest::newRow("null") << QString() << QUrl() << false; + + //Examples taken from http://adblockplus.org/en/filters + + // Basic filter rules + QTest::newRow("basic0") << QString("http://example.com/ads/banner123.gif") + << QUrl("http://example.com/ads/banner123.gif") + << true; + QTest::newRow("basic1") << QString("http://example.com/ads/banner*.gif") + << QUrl("http://example.com/ads/banner123.gif") + << true; + QTest::newRow("basic2") << QString("http://example.com/ads/*") + << QUrl("http://example.com/ads/banner123.gif") + << true; + QTest::newRow("basic3") << QString("http://example.com/*") + << QUrl("http://example.com/ads/banner123.gif") + << true; + + // defining exception rules + QTest::newRow("exception0") << QString("@@advice") + << QUrl("http://example.com/advice.html") + << true; + QTest::newRow("exception1") << QString("@@|http://example.com") + << QUrl("http://example.com/advice.html") + << true; + QTest::newRow("exception2") << QString("@@http://example.com") + << QUrl("http://example.com/advice.html") + << true; + + // matching at beginning/end of an address + QTest::newRow("m0") << QString("ad") + << QUrl("http://example.com/advice.html") + << true; + QTest::newRow("m1") << QString("*ad*") + << QUrl("http://example.com/advice.html") + << true; + QTest::newRow("m2") << QString("swf") + << QUrl("http://example.com/swf/index.html") + << true; + QTest::newRow("m3") << QString("swf|") + << QUrl("http://example.com/annoyingflash.swf") + << true; + QTest::newRow("m4") << QString("swf|") + << QUrl("http://example.com/swf/index.html") + << false; + + QTest::newRow("m5") << QString("http://baddomain.example/") + << QUrl("http://baddomain.example/banner.gif") + << true; + QTest::newRow("m6") << QString("http://baddomain.example/") + << QUrl("http://gooddomain.example/analyze?http://baddomain.example.") + << false; + + QTest::newRow("m7") << QString("||example.com/banner.gif") + << QUrl("http://example.com/banner.gif") + << true; + QTest::newRow("m8") << QString("||example.com/banner.gif") + << QUrl("https://example.com/banner.gif") + << true; + QTest::newRow("m9") << QString("||example.com/banner.gif") + << QUrl("http://www.example.com/banner.gif") + << true; + + QTest::newRow("m10") << QString("||example.com/banner.gif") + << QUrl("http://badexample.com/banner.gif") + << false; + QTest::newRow("m10") << QString("||example.com/banner.gif") + << QUrl("http://gooddomain.example/analyze?http://example.com/banner.gif") + << false; + + QTest::newRow("m11") << QString("/getad.php|") + << QUrl("http://adblockplus.mozdev.org/easylist/easylist.txt") + << false; + + // Matching separators + QTest::newRow("sep_1") << QString("a^") + << QUrl("a/") + << true; + QTest::newRow("sep_2") << QString("a^") + << QUrl("a:") + << true; + QTest::newRow("sep_3") << QString("a^") + << QUrl("a.") + << false; + QTest::newRow("sep_4") << QString("a^") + << QUrl("a?") + << true; + QTest::newRow("sep_5") << QString("a^") + << QUrl("a=") + << true; + QTest::newRow("sep_6") << QString("a^") + << QUrl("a&") + << true; + + QTest::newRow("s1_s") << QString("com^") + << QUrl("com:") + << true; + QTest::newRow("s2_s") << QString("ab^cd") + << QUrl("ab.cd") + << false; + + // Marking separate characters + QTest::newRow("s0") << QString("http://example.com^") + << QUrl("http://example.com/") + << true; + QTest::newRow("s1") << QString("http://example.com^") + << QUrl("http://example.com:8000/") + << true; + QTest::newRow("s2") << QString("http://example.com^") + << QUrl("http://example.com.ar/") + << false; + QTest::newRow("s3") << QString("^example.com^") + << QUrl("http://example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5%D1%81%D1%82") + << true; + QTest::newRow("s4") << QString("^%D1^") + << QUrl::fromEncoded("http://example.com:8000/foo.bar?a=12&b=%D1") + << true; + QTest::newRow("s5") << QString("^foo.bar^") + << QUrl("http://example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5%D1%81%D1%82") + << true; + QTest::newRow("s6") << QString("^%D1%82%D0%B5%D1%81%D1%82^") + << QUrl::fromEncoded("http://example.com:8000/foo.bar?a=12&b=%D1%82%D0%B5%D1%81%D1%82") + << true; + // Comments + QTest::newRow("c0") << QString("!foo.bar") + << QUrl("!foo.bar") + << false; + QTest::newRow("c1") << QString("!foo.bar") + << QUrl("foo.bar") + << false; + + // Specifying filter options + // type + QTest::newRow("o0") << QString("*/ads/*$script,image,background,stylesheet,object,xbl,ping,xmlhttprequest,object-subrequest,object-subrequest,dtd,subdocument,document,other") + << QUrl("foo.bar/ads/foo.jpg") + << false; + // Inverse type + QTest::newRow("o1") << QString("*/ads/*$~script, ~image, ~background, ~stylesheet, ~object, ~xbl, ~ping, ~xmlhttprequest, ~object-subrequest, ~dtd, ~subdocument, ~document, ~other") + << QUrl("foo.bar/ads/foo.jpg") + << false; + // Restriction to third-party/first-party requests + QTest::newRow("o2") << QString("*/ads/*$third-party") + << QUrl("foo.bar/ads/foo.jpg") + << false; + QTest::newRow("o3") << QString("*/ads/*$first-party") + << QUrl("foo.bar/ads/foo.jpg") + << false; + // Domain restrictions + QTest::newRow("o4") << QString("*/ads/*$domain=example.com|example.net") + << QUrl("http://example.com/ads/foo.jpg") + << true; + QTest::newRow("o5") << QString("*/ads/*$domain=example.com") + << QUrl("http://foo.com/ads/foo.jpg") + << false; + + QTest::newRow("o6") << QString("*/ads/*$domain=~example.com") + << QUrl("http://foo.com/ads/foo.jpg") + << true; + QTest::newRow("o7") << QString("*/ads/*$domain=~example.com") + << QUrl("http://example.com/ads/foo.jpg") + << false; + QTest::newRow("o8") << QString("*/ads/*$domain=example.com|~foo.example.com") + << QUrl("http://example.com/ads/foo.jpg") + << true; + QTest::newRow("o9") << QString("*/ads/*$domain=example.com|~foo.example.com") + << QUrl("http://foo.example.com/ads/foo.jpg") + << false; + QTest::newRow("o10") << QString("*/ads/*$domain=example.com|~foo.example.com") + << QUrl("http://bar.example.com/ads/foo.jpg") + << true; + // match-case + QTest::newRow("o11") << QString("*/BannerAd.gif$match-case") + << QUrl("http://example.com/BannerAd.gif") + << true; + QTest::newRow("o12") << QString("*/BannerAd.gif$match-case") + << QUrl("http://example.com/bannerad.gif") + << false; + // collapse + // TODO test collapse somehow + QTest::newRow("o13") << QString("*/BannerAd.gif$collapse") + << QUrl("http://example.com/bannerad.gif") + << false; + QTest::newRow("o14") << QString("*/BannerAd.gif$~collapse") + << QUrl("http://example.com/bannerad.gif") + << false; + // Regular expressions + QTest::newRow("r0") << QString("/banner\\d+/") + << QUrl("banner123") + << true; + QTest::newRow("r1") << QString("/banner\\d+/") + << QUrl("banner321") + << true; + QTest::newRow("r2") << QString("/banner\\d+/") + << QUrl("banners") + << false; + + // See the AdBlockPage autotest for CSS testing + // Basic Element hiding the network matching should never pass + QTest::newRow("e0") << QString("##div.textad") + << QUrl() + << false; + QTest::newRow("e1") << QString("##div#sponsorad") + << QUrl() + << false; + QTest::newRow("e1") << QString("##*#sponsorad") + << QUrl() + << false; + QTest::newRow("e1") << QString("##textad") + << QUrl() + << false; + QTest::newRow("e1") << QString("example.com##*.sponsor") + << QUrl("example.com") + << false; + QTest::newRow("e1") << QString("example.com,example.net##*.sponsor") + << QUrl("example.com") + << false; + + // Seen on the internet + QTest::newRow("i0") << QString("||snap.com^$third-party") + << QUrl("http://spa.snap.com/snap_preview_anywhere.js?ap=1&key=89743df349c6c38afc3094e9566cb98e&sb=1&link_icon=off&domain=pub-6332280-www.techcrunch.com") + << true; + + QTest::newRow("i1") << QString("|http://ads.") + << QUrl("http://ads.cnn.com/html.ng/site=cnn&cnn_pagetype=main&cnn_position=336x280_adlinks&cnn_rollup=homepage&page.allowcompete=yes¶ms.styles=fs&tile=8837285713521&domId=463050") + << true; + + QTest::newRow("i2") << QString("/adverti$~object_subrequest,~stylesheet,domain=~advertise4free.org|~amarillas.cl|~bnet.com|~catalysttelecom.com|~cod4central.com|~scansource.com|~scansourcecommunications.com|~scansourcesecurity.com") + << QUrl("http://i2.cdn.turner.com/cnn/.element/img/2.0/content/ads/advertisement.gif") + << true; + + QTest::newRow("i3") << QString("/adspace") + << QUrl("http://i.cdn.turner.com/cnn/cnn_adspaces/cnn_adspaces.js") + << false; +} + +// public bool networkMatch(const QUrl &url) const +void tst_AdBlockRule::networkMatch() +{ + QFETCH(QString, filter); + QFETCH(QUrl, url); + QFETCH(bool, networkMatch); + + SubAdBlockRule AdBlockRule(filter); + bool result = AdBlockRule.networkMatch(url.toEncoded()); + if (result != networkMatch) { + qDebug() << "Match error."; + qDebug() << "\tFilter:" << filter; + qDebug() << "\tUrl: " << url; + qDebug() << "\tResult : " << (result ? "match" : "NOT match"); + } + QCOMPARE(AdBlockRule.networkMatch(url.toEncoded()), networkMatch); +} + +void tst_AdBlockRule::regexpCreation_data() +{ + QTest::addColumn("input"); + QTest::addColumn("output"); + + QTest::newRow("null") << QString("test") << QString("test"); + QTest::newRow("m1") << QString("abc*") << QString("abc"); + QTest::newRow("m2") << QString("*abc*") << QString("abc"); + QTest::newRow("m3") << QString("abc**") << QString("abc"); + QTest::newRow("m4") << QString("abc***") << QString("abc"); + QTest::newRow("m5") << QString("**abc**") << QString("abc"); + QTest::newRow("m6") << QString("**a*bc**") << QString("a.*bc"); + QTest::newRow("h1") << QString("abc.com") << QString("abc\\.com"); + + QTest::newRow("a2") << QString("abc^|def") << QString("abc(?:[^\\w\\d\\-.%]|$)\\|def"); + QTest::newRow("a3") << QString("^|def") << QString("(?:[^\\w\\d\\-.%]|$)\\|def"); + + QTest::newRow("s1") << QString("de|f") << QString("de\\|f"); + + QTest::newRow("e1") << QString("|abc") << QString("^abc"); + QTest::newRow("e2") << QString("d|abc") << QString("d\\|abc"); + QTest::newRow("e3") << QString("abc|") << QString("abc$"); + + QTest::newRow("z1") << QString("^abc") << QString("(?:[^\\w\\d\\-.%]|$)abc"); + QTest::newRow("z2") << QString("a^bc") << QString("a(?:[^\\w\\d\\-.%]|$)bc"); + QTest::newRow("z3") << QString("abc^|") << QString("abc(?:[^\\w\\d\\-.%]|$)"); + QTest::newRow("z4") << QString("http://example.com^") + << QString("http\\:\\/\\/example\\.com(?:[^\\w\\d\\-.%]|$)"); + + + QTest::newRow("d0") << QString("||example.com") + << QString("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?example\\.com"); + QTest::newRow("d1") << QString("||example.com/banner.gif") + << QString("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?example\\.com\\/banner\\.gif"); +} + +void tst_AdBlockRule::regexpCreation() +{ + QFETCH(QString, input); + QFETCH(QString, output); + + SubAdBlockRule rule(input); + QCOMPARE(rule.regExpPattern(), output); +} + +QTEST_MAIN(tst_AdBlockRule) +#include "tst_adblockrule.moc" + diff --git a/autotests/adblock/adblocksubscription/.gitignore b/autotests/adblock/adblocksubscription/.gitignore new file mode 100644 index 00000000..aea23ae2 --- /dev/null +++ b/autotests/adblock/adblocksubscription/.gitignore @@ -0,0 +1,2 @@ +adblocksubscription +rules2.txt diff --git a/autotests/adblock/adblocksubscription/adblocksubscription.pro b/autotests/adblock/adblocksubscription/adblocksubscription.pro new file mode 100644 index 00000000..2ad5e053 --- /dev/null +++ b/autotests/adblock/adblocksubscription/adblocksubscription.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES += tst_adblocksubscription.cpp +HEADERS += diff --git a/autotests/adblock/adblocksubscription/rules.txt b/autotests/adblock/adblocksubscription/rules.txt new file mode 100644 index 00000000..6a13a94c --- /dev/null +++ b/autotests/adblock/adblocksubscription/rules.txt @@ -0,0 +1,3 @@ +[Adblock Plus 0.7.1] +http://example.com/ads/* +@@advice diff --git a/autotests/adblock/adblocksubscription/tst_adblocksubscription.cpp b/autotests/adblock/adblocksubscription/tst_adblocksubscription.cpp new file mode 100644 index 00000000..81decc53 --- /dev/null +++ b/autotests/adblock/adblocksubscription/tst_adblocksubscription.cpp @@ -0,0 +1,358 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include + +#include + +class tst_AdBlockSubscription : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void adblocksubscription_data(); + void adblocksubscription(); + + void isEnabled_data(); + void isEnabled(); + void location_data(); + void location(); + void saveRules_data(); + void saveRules(); + void title_data(); + void title(); + void updateNow_data(); + void updateNow(); + void allow_data(); + void allow(); + void block_data(); + void block(); + void addRule(); + void removeRule(); +}; + +// Subclass that exposes the protected functions. +class SubAdBlockSubscription : public AdBlockSubscription +{ +public: + SubAdBlockSubscription(const QUrl &url = QUrl()) : AdBlockSubscription(url) {} + +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_AdBlockSubscription::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_AdBlockSubscription::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_AdBlockSubscription::init() +{ +} + +// This will be called after every test function. +void tst_AdBlockSubscription::cleanup() +{ +} + +void tst_AdBlockSubscription::adblocksubscription_data() +{ + QTest::addColumn("url"); + QTest::addColumn("title"); + QTest::addColumn("location"); + QTest::addColumn("enabled"); + QTest::addColumn("lastUpdate"); + QTest::newRow("basic0") << QUrl::fromEncoded("abp:subscribe?location=http://easylist.adblockplus.org/easylist.txt&title=EasyList") + << "EasyList" + << QUrl("http://easylist.adblockplus.org/easylist.txt") + << true + << QDateTime(); + + + QTest::addColumn("url"); + QTest::addColumn("title"); + QTest::addColumn("location"); + QTest::addColumn("enabled"); + QTest::addColumn("lastUpdate"); + QTest::newRow("basic1") << QUrl::fromEncoded("abp:subscribe?location=http://easylist.adblockplus.org/easylist.txt&title=EasyList&enabled=false&lastUpdate=2009-01-16T12%3A10%3A55") + << "EasyList" + << QUrl("http://easylist.adblockplus.org/easylist.txt") + << false + << QDateTime(QDate(2009, 1, 16), QTime(12, 10, 55)); +} + +void tst_AdBlockSubscription::adblocksubscription() +{ + QFETCH(QUrl, url); + QFETCH(QString, title); + QFETCH(QUrl, location); + QFETCH(bool, enabled); + QFETCH(QDateTime, lastUpdate); + + SubAdBlockSubscription subscription(url); + QCOMPARE(subscription.title(), title); + QCOMPARE(subscription.location(), location); + QCOMPARE(subscription.isEnabled(), enabled); + QCOMPARE(subscription.lastUpdate(), lastUpdate); + QVERIFY(subscription.url().isValid()); + //QCOMPARE(subscription.url(), url); + QCOMPARE(subscription.block(QString()), (AdBlockRule const*)0); + subscription.saveRules(); + subscription.setEnabled(false); + subscription.setLocation(QUrl()); + subscription.setTitle(QString()); + subscription.updateNow(); + subscription.allRules(); + subscription.removeRule(-1); + subscription.removeRule(0); + subscription.removeRule(1); + subscription.addRule(AdBlockRule()); +} + +Q_DECLARE_METATYPE(AdBlockRule const*) +void tst_AdBlockSubscription::allow_data() +{ + QTest::addColumn("url"); + QTest::addColumn("allow"); + QTest::newRow("block") << QUrl("http://example.com/ads/banner123.gif") << false; + QTest::newRow("allow") << QUrl("http://example.com/ads/advice.html") << true; +} + +// public AdBlockRule const *block(QString const &urlString) const +void tst_AdBlockSubscription::allow() +{ + QFETCH(QUrl, url); + QFETCH(bool, allow); + + SubAdBlockSubscription subscription; + subscription.setLocation(QUrl::fromLocalFile(QDir::currentPath() + "/rules.txt")); + subscription.setEnabled(true); + subscription.updateNow(); + + const AdBlockRule *rule = subscription.allow(QString::fromUtf8(url.toEncoded())); + if (rule) + QVERIFY(rule->isException()); + QCOMPARE((0 != rule), allow); +} + +void tst_AdBlockSubscription::block_data() +{ + QTest::addColumn("url"); + QTest::addColumn("block"); + QTest::newRow("block") << QUrl("http://example.com/ads/banner123.gif") << true; + QTest::newRow("allow") << QUrl("http://example.com/ads/advice.html") << true; +} + +// public AdBlockRule const *block(QString const &urlString) const +void tst_AdBlockSubscription::block() +{ + QFETCH(QUrl, url); + QFETCH(bool, block); + + SubAdBlockSubscription subscription; + subscription.setLocation(QUrl::fromLocalFile(QDir::currentPath() + "/rules.txt")); + subscription.setEnabled(true); + subscription.updateNow(); + + const AdBlockRule *rule = subscription.block(QString::fromUtf8(url.toEncoded())); + if (rule) + QVERIFY(!rule->isException()); + QCOMPARE((0 != rule), block); +} + +void tst_AdBlockSubscription::isEnabled_data() +{ + QTest::addColumn("isEnabled"); + QTest::newRow("true") << true; + QTest::newRow("false") << false; +} + +// public bool isEnabled() const +void tst_AdBlockSubscription::isEnabled() +{ + QFETCH(bool, isEnabled); + + SubAdBlockSubscription subscription; + + QSignalSpy spy0(&subscription, SIGNAL(rulesChanged())); + QSignalSpy spy1(&subscription, SIGNAL(changed())); + + bool changed = subscription.isEnabled() != isEnabled; + subscription.setEnabled(isEnabled); + QCOMPARE(subscription.isEnabled(), isEnabled); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), changed ? 1 : 0); +} + +void tst_AdBlockSubscription::location_data() +{ + QTest::addColumn("location"); + QTest::newRow("null") << QUrl(); + QTest::newRow("x") << QUrl("x"); +} + +// public QUrl location() const +void tst_AdBlockSubscription::location() +{ + QFETCH(QUrl, location); + + SubAdBlockSubscription subscription(QUrl("abp:subscribe")); + + QSignalSpy spy0(&subscription, SIGNAL(rulesChanged())); + QSignalSpy spy1(&subscription, SIGNAL(changed())); + + bool changed = location != subscription.location(); + subscription.setLocation(location); + QCOMPARE(subscription.location(), location); + QCOMPARE(subscription.url(), QUrl(QString("abp:subscribe?location=%1&title=").arg(location.toString()))); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), changed ? 1 : 0); +} + +void tst_AdBlockSubscription::saveRules_data() +{ + QTest::addColumn("location"); + QTest::newRow("file") << QUrl::fromLocalFile(QDir::currentPath() + "/rules2.txt"); +} + +// public void saveRules() +void tst_AdBlockSubscription::saveRules() +{ + QFETCH(QUrl, location); + SubAdBlockSubscription subscription; + subscription.setLocation(location); + + subscription.addRule(AdBlockRule()); + subscription.saveRules(); + subscription.removeRule(0); + subscription.updateNow(); + QCOMPARE(subscription.allRules().count(), 1); +} + +void tst_AdBlockSubscription::title_data() +{ + QTest::addColumn("title"); + QTest::newRow("null") << QString(); + QTest::newRow("foo") << QString("foo"); +} + +// public QString title() const +void tst_AdBlockSubscription::title() +{ + QFETCH(QString, title); + + SubAdBlockSubscription subscription; + + QSignalSpy spy0(&subscription, SIGNAL(rulesChanged())); + QSignalSpy spy1(&subscription, SIGNAL(changed())); + + bool changed = title != subscription.title(); + subscription.setTitle(title); + QCOMPARE(subscription.title(), title); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), changed ? 1 : 0); +} + +void tst_AdBlockSubscription::updateNow_data() +{ + QTest::addColumn("location"); + QTest::newRow("file") << QUrl::fromLocalFile(QDir::currentPath() + "/rules.txt"); +} + +// public void updateNow() +void tst_AdBlockSubscription::updateNow() +{ + QFETCH(QUrl, location); + + SubAdBlockSubscription subscription; + subscription.setLocation(location); + + QSignalSpy spy0(&subscription, SIGNAL(rulesChanged())); + QSignalSpy spy1(&subscription, SIGNAL(changed())); + + subscription.updateNow(); + + QTRY_COMPARE(spy0.count(), 1); + QCOMPARE(spy1.count(), 1); + QVERIFY(subscription.lastUpdate() != QDateTime()); + QCOMPARE(subscription.allRules().count(), 2); +} + +void tst_AdBlockSubscription::addRule() +{ + SubAdBlockSubscription subscription; + + QSignalSpy spy0(&subscription, SIGNAL(rulesChanged())); + QSignalSpy spy1(&subscription, SIGNAL(changed())); + + subscription.addRule(AdBlockRule()); + subscription.addRule(AdBlockRule("/test")); + + QTRY_COMPARE(spy0.count(), 2); + QCOMPARE(spy1.count(), 0); + QCOMPARE(subscription.allRules().count(), 2); +} + +void tst_AdBlockSubscription::removeRule() +{ + SubAdBlockSubscription subscription; + + QSignalSpy spy0(&subscription, SIGNAL(rulesChanged())); + QSignalSpy spy1(&subscription, SIGNAL(changed())); + + subscription.addRule(AdBlockRule("/test")); + subscription.removeRule(0); + + QTRY_COMPARE(spy0.count(), 2); + QCOMPARE(spy1.count(), 0); + QCOMPARE(subscription.allRules().count(), 0); +} + + +QTEST_MAIN(tst_AdBlockSubscription) +#include "tst_adblocksubscription.moc" + diff --git a/autotests/addbookmarkdialog/.gitignore b/autotests/addbookmarkdialog/.gitignore new file mode 100644 index 00000000..71c2b861 --- /dev/null +++ b/autotests/addbookmarkdialog/.gitignore @@ -0,0 +1 @@ +addbookmarkdialog diff --git a/autotests/addbookmarkdialog/tst_addbookmarkdialog.cpp b/autotests/addbookmarkdialog/tst_addbookmarkdialog.cpp index 9242fd4a..4e4a9775 100644 --- a/autotests/addbookmarkdialog/tst_addbookmarkdialog.cpp +++ b/autotests/addbookmarkdialog/tst_addbookmarkdialog.cpp @@ -19,9 +19,13 @@ #include -#include -#include -#include +#include "addbookmarkdialog.h" +#include "bookmarksmanager.h" +#include "bookmarknode.h" +#include "browserapplication.h" + +#include +#include class tst_AddBookmarkDialog : public QObject { @@ -43,8 +47,8 @@ class SubAddBookmarkDialog : public AddBookmarkDialog { public: - SubAddBookmarkDialog(const QString &url, const QString &title, QWidget *parent, BookmarksManager *manager) - : AddBookmarkDialog(url, title, parent, manager){} + SubAddBookmarkDialog(QWidget *parent, BookmarksManager *manager) + : AddBookmarkDialog(parent, manager) {} }; @@ -92,7 +96,7 @@ void tst_AddBookmarkDialog::addbookmarkdialog_data() // select invalid, menu, toolbar, submenu QTest::newRow("cancel") << "url" << "title" << QDialogButtonBox::Cancel << 0 << 0 << -1; - QTest::newRow("ok default") << "url" << "title" << QDialogButtonBox::Ok << 1 << 0 << -1; + QTest::newRow("ok default") << "url" << "title" << QDialogButtonBox::Ok << 0 << 1 << -1; QTest::newRow("ok toolbar") << "url" << "title" << QDialogButtonBox::Ok << 0 << 1 << 0; QTest::newRow("ok menu") << "url" << "title" << QDialogButtonBox::Ok << 1 << 0 << 1; } @@ -107,14 +111,16 @@ void tst_AddBookmarkDialog::addbookmarkdialog() QFETCH(int, select); BookmarksManager *manager = BrowserApplication::bookmarksManager(); - qRegisterMetaType("BookmarkNode *"); + qRegisterMetaType("BookmarkNode *"); QSignalSpy spy(manager, SIGNAL(entryAdded(BookmarkNode *))); BookmarkNode *menu = manager->menu(); BookmarkNode *toolbar = manager->toolbar(); QCOMPARE(menu->children().count(), 0); QCOMPARE(toolbar->children().count(), 0); - SubAddBookmarkDialog dialog(url, title, 0, manager); + SubAddBookmarkDialog dialog(0, manager); + dialog.setUrl(url); + dialog.setTitle(title); QComboBox *combobox = dialog.findChild(); QVERIFY(combobox); if (select != -1) { @@ -136,6 +142,8 @@ void tst_AddBookmarkDialog::addbookmarkdialog() if (node) { QCOMPARE(node->title, title); QCOMPARE(node->url, url); + QVERIFY(dialog.addedNode()); + QVERIFY(*node == *dialog.addedNode()); } } diff --git a/autotests/autosaver/.gitignore b/autotests/autosaver/.gitignore new file mode 100644 index 00000000..c52085ad --- /dev/null +++ b/autotests/autosaver/.gitignore @@ -0,0 +1 @@ +autosaver diff --git a/autotests/autosaver/tst_autosaver.cpp b/autotests/autosaver/tst_autosaver.cpp index 9a6b6fb3..bec2f8c2 100644 --- a/autotests/autosaver/tst_autosaver.cpp +++ b/autotests/autosaver/tst_autosaver.cpp @@ -30,12 +30,13 @@ public slots: void init(); void cleanup(); + void save(); + private slots: void AutoSaver_data(); void AutoSaver(); void changeOccurred_data(); void changeOccurred(); - void deleted(); }; @@ -43,8 +44,8 @@ private slots: class SubAutoSaver : public AutoSaver { public: - SubAutoSaver(QObject *parent = 0) : AutoSaver(parent){} - void call_timerEvent(QTimerEvent* event) + SubAutoSaver(QObject *parent = 0) : AutoSaver(parent) {} + void call_timerEvent(QTimerEvent *event) { return SubAutoSaver::timerEvent(event); } }; @@ -103,6 +104,11 @@ void tst_AutoSaver::AutoSaver() { SubAutoSaver save(this); save.changeOccurred(); + save.saveIfNeccessary(); +} + +void tst_AutoSaver::save() +{ } typedef QList IntList; diff --git a/autotests/autotests.pri b/autotests/autotests.pri index e0e57d59..1befa6f5 100644 --- a/autotests/autotests.pri +++ b/autotests/autotests.pri @@ -8,6 +8,8 @@ include($$PWD/modeltest/modeltest.pri) HEADERS += qtest_arora.h +DEFINES += AUTOTESTS + INCLUDEPATH += $$PWD DEPENDPATH += $$PWD diff --git a/autotests/autotests.pro b/autotests/autotests.pro index c8af8534..fdd32901 100644 --- a/autotests/autotests.pro +++ b/autotests/autotests.pro @@ -1,12 +1,23 @@ TEMPLATE = subdirs -SUBDIRS = addbookmarkdialog \ - autosaver \ - downloadmanager \ - edittreeview \ - history \ - historyfiltermodel \ - searchlineedit \ - tabbar \ - tabwidget \ - webactionmapper \ - xbel +SUBDIRS = \ + adblock \ + addbookmarkdialog \ + autosaver \ + bookmarknode \ + cookiejar \ + historyfiltermodel \ + historymanager \ + modeltoolbar \ + opensearchengine \ + opensearchmanager \ + opensearchreader \ + opensearchwriter \ + searchlineedit \ + tabbar \ + tabwidget \ + utils \ + webactionmapper \ + webpage \ + xbel + +CONFIG += ordered diff --git a/autotests/bookmarknode/.gitignore b/autotests/bookmarknode/.gitignore new file mode 100644 index 00000000..e2f5b4ad --- /dev/null +++ b/autotests/bookmarknode/.gitignore @@ -0,0 +1 @@ +bookmarknode diff --git a/autotests/bookmarknode/bookmarknode.pro b/autotests/bookmarknode/bookmarknode.pro new file mode 100644 index 00000000..b796c019 --- /dev/null +++ b/autotests/bookmarknode/bookmarknode.pro @@ -0,0 +1,14 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . ../ + +include(../autotests.pri) + +QT = core + +# Input +SOURCES = bookmarknode.cpp tst_bookmarknode.cpp +HEADERS = bookmarknode.h +FORMS = +RESOURCE = diff --git a/autotests/bookmarknode/tst_bookmarknode.cpp b/autotests/bookmarknode/tst_bookmarknode.cpp new file mode 100644 index 00000000..a8307e7c --- /dev/null +++ b/autotests/bookmarknode/tst_bookmarknode.cpp @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2014 Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +class tst_BookmarkNode : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void bookmarknode_data(); + void bookmarknode(); + + void add_duplicate(); + void add_to_bookmark(); + void add_move(); + void add_data(); + void add(); + void equal(); + void remove(); + void deleteNode(); + void deleteChildren(); + void type_data(); + void type(); +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_BookmarkNode::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_BookmarkNode::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_BookmarkNode::init() +{ +} + +// This will be called after every test function. +void tst_BookmarkNode::cleanup() +{ +} + +void tst_BookmarkNode::bookmarknode_data() +{ +} + +void tst_BookmarkNode::bookmarknode() +{ + BookmarkNode node; + QCOMPARE(node.children(), QList()); + QCOMPARE(node.parent(), (BookmarkNode*)0); + QCOMPARE(node.type(), BookmarkNode::Root); + node.add((BookmarkNode*)0, -1); + node.remove((BookmarkNode*)0); +} + +void tst_BookmarkNode::add_to_bookmark() +{ + BookmarkNode node(BookmarkNode::Bookmark); + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node.add(child); + // qWarning()? + QCOMPARE(node.children().count(), 0); + QCOMPARE(child->parent(), (BookmarkNode*)0); + delete child; +} + +void tst_BookmarkNode::add_duplicate() +{ + BookmarkNode node; + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node.add(child); + node.add(child); + QCOMPARE(node.children().count(), 1); +} + +void tst_BookmarkNode::add_move() +{ + BookmarkNode node1; + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node1.add(child); + + BookmarkNode node2; + node2.add(child); + + QCOMPARE(child->parent(), &node2); + QVERIFY(node2.children().contains(child)); + QVERIFY(!node1.children().contains(child)); +} + +void tst_BookmarkNode::add_data() +{ + QTest::addColumn("startcount"); + QTest::addColumn("insertoffset"); + QTest::addColumn("resultingoffset"); + QTest::newRow("0,-1,0") << 0 << -1 << 0; + QTest::newRow("0,0,0") << 0 << 0 << 0; + QTest::newRow("0,1,0") << 0 << 1 << 0; + QTest::newRow("1,-1,1") << 1 << -1 << 1; + QTest::newRow("1,0,0") << 1 << 0 << 0; + QTest::newRow("1,1,0") << 1 << 1 << 1; +} + +// public void add(BookmarkNode *child, int offset = -1) +void tst_BookmarkNode::add() +{ + QFETCH(int, startcount); + QFETCH(int, insertoffset); + QFETCH(int, resultingoffset); + + BookmarkNode node; + + for (int i = 0; i < startcount; ++i) { + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node.add(child, -1); + } + + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node.add(child, insertoffset); + + QCOMPARE(child->parent(), &node); + QList children = node.children(); + QVERIFY(children.contains(child)); + QCOMPARE(children.at(resultingoffset), child); +} + +Q_DECLARE_METATYPE(BookmarkNode) +// public bool equal(BookmarkNode const &other) +void tst_BookmarkNode::equal() +{ + BookmarkNode null1; + BookmarkNode null2; + QCOMPARE(null1, null2); + + BookmarkNode b1(BookmarkNode::Bookmark); + BookmarkNode b2(BookmarkNode::Bookmark); + QCOMPARE(b1, b2); + + b1.title = "title"; + QVERIFY(!(b1 == b2)); + b2.title = "title"; + QCOMPARE(b1, b2); + + b1.url = "url"; + QVERIFY(!(b1 == b2)); + b2.url = "url"; + QCOMPARE(b1, b2); + + b1.desc = "description"; + QVERIFY(!(b1 == b2)); + b2.desc = "description"; + QCOMPARE(b1, b2); + + BookmarkNode f1(BookmarkNode::Folder); + BookmarkNode f2(BookmarkNode::Folder); + QCOMPARE(f1, f2); + + f1.expanded = true; + QVERIFY(!(f1 == f2)); + f2.expanded = true; + QCOMPARE(f1, f2); + + BookmarkNode *child1 = new BookmarkNode(BookmarkNode::Bookmark); + child1->title = "title"; + f1.add(child1); + QVERIFY(!(f1 == f2)); + + BookmarkNode *child2 = new BookmarkNode(BookmarkNode::Bookmark); + child2->title = "title"; + f2.add(child2); + QCOMPARE(f1, f2); +} + +// public void remove(BookmarkNode *child) +void tst_BookmarkNode::remove() +{ + BookmarkNode node; + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node.add(child); + node.remove(child); + QCOMPARE(node.children().count(), 0); + QCOMPARE(child->parent(), (BookmarkNode*)0); + delete child; +} + +void tst_BookmarkNode::deleteNode() +{ + BookmarkNode node; + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node.add(child); + + delete child; + + QCOMPARE(node.children().count(), 0); + QCOMPARE(child->parent(), (BookmarkNode*)0); +} + +void tst_BookmarkNode::deleteChildren() +{ + BookmarkNode *node = new BookmarkNode(); + for (int i = 0; i < 10; ++i) { + BookmarkNode *child = new BookmarkNode(BookmarkNode::Bookmark); + node->add(child, -1); + } + delete node; + // This shouldn't segfualt :) +} + +Q_DECLARE_METATYPE(BookmarkNode::Type) +void tst_BookmarkNode::type_data() +{ + QTest::addColumn("type"); + QTest::newRow("root") << BookmarkNode::Root; + QTest::newRow("folder") << BookmarkNode::Folder; + QTest::newRow("sep") << BookmarkNode::Separator; + QTest::newRow("bookmark") << BookmarkNode::Bookmark; +} + +// public BookmarkNode::Type type() const +void tst_BookmarkNode::type() +{ + QFETCH(BookmarkNode::Type, type); + + BookmarkNode node(type); + + QCOMPARE(node.type(), type); + if (node.type() == BookmarkNode::Root) + QVERIFY(!node.parent()); + if (node.type() == BookmarkNode::Bookmark) + QVERIFY(node.children().isEmpty()); +} + +QTEST_MAIN(tst_BookmarkNode) +#include "tst_bookmarknode.moc" diff --git a/autotests/cookiejar/.gitignore b/autotests/cookiejar/.gitignore new file mode 100644 index 00000000..b4440a70 --- /dev/null +++ b/autotests/cookiejar/.gitignore @@ -0,0 +1 @@ +cookiejar diff --git a/autotests/history/history.pro b/autotests/cookiejar/cookiejar.pro similarity index 78% rename from autotests/history/history.pro rename to autotests/cookiejar/cookiejar.pro index e993d5dc..bc4d22b0 100644 --- a/autotests/history/history.pro +++ b/autotests/cookiejar/cookiejar.pro @@ -6,5 +6,5 @@ INCLUDEPATH += . include(../autotests.pri) # Input -SOURCES += tst_history.cpp +SOURCES += tst_cookiejar.cpp HEADERS += diff --git a/autotests/cookiejar/tst_cookiejar.cpp b/autotests/cookiejar/tst_cookiejar.cpp new file mode 100644 index 00000000..b7f5219e --- /dev/null +++ b/autotests/cookiejar/tst_cookiejar.cpp @@ -0,0 +1,556 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include + +class tst_CookieJar : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void cookiejar_data(); + void cookiejar(); + + void acceptPolicy_data(); + void acceptPolicy(); + void allowedCookies_data(); + void allowedCookies(); + void allowForSessionCookies_data(); + void allowForSessionCookies(); + void blockedCookies_data(); + void blockedCookies(); + void clear_data(); + void clear(); + void cookiesForUrl_data(); + void cookiesForUrl(); + void keepPolicy_data(); + void keepPolicy(); + void loadSettings_data(); + void loadSettings(); + void setAcceptPolicy_data(); + void setAcceptPolicy(); + void setAllowedCookies_data(); + void setAllowedCookies(); + void setAllowForSessionCookies_data(); + void setAllowForSessionCookies(); + void setBlockedCookies_data(); + void setBlockedCookies(); + void setCookiesFromUrl_data(); + void setCookiesFromUrl(); + void setKeepPolicy_data(); + void setKeepPolicy(); + void cookiesChanged_data(); + void cookiesChanged(); + void isOnDomainList_data(); + void isOnDomainList(); +}; + +// Subclass that exposes the protected functions. +class SubCookieJar : public CookieJar +{ +public: + void call_cookiesChanged() + { return SubCookieJar::cookiesChanged(); } + + static bool call_isOnDomainList(QStringList const &list, QString const &domain) + { return SubCookieJar::isOnDomainList(list, domain); } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_CookieJar::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_CookieJar::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_CookieJar::init() +{ +} + +// This will be called after every test function. +void tst_CookieJar::cleanup() +{ +} + +void tst_CookieJar::cookiejar_data() +{ +} + +void tst_CookieJar::cookiejar() +{ + SubCookieJar jar; +#if 0 + QCOMPARE(jar.acceptPolicy(), CookieJar::AcceptPolicy); + QCOMPARE(jar.allowedCookies(), QStringList); + QCOMPARE(jar.allowForSessionCookies(), QStringList); + QCOMPARE(jar.blockedCookies(), QStringList); + jar.clear(); + QCOMPARE(jar.cookiesForUrl(QUrl()), QList()); + QCOMPARE(jar.keepPolicy(), CookieJar::KeepPolicy); + jar.loadSettings(); + jar.setAcceptPolicy(CookieJar::AcceptPolicy); + jar.setAllowedCookies(QStringList()); + jar.setAllowForSessionCookies(QStringList()); + jar.setBlockedCookies(QStringList()); + QCOMPARE(jar.setCookiesFromUrl(QList(), QUrl()), false); + jar.setKeepPolicy(CookieJar::KeepPolicy); + jar.call_cookiesChanged(); + QCOMPARE(jar.call_isOnDomainList(QStringList(), QString()), false); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +Q_DECLARE_METATYPE(CookieJar::AcceptPolicy) +void tst_CookieJar::acceptPolicy_data() +{ +#if 0 + QTest::addColumn("acceptPolicy"); + QTest::newRow("null") << CookieJar::AcceptPolicy(); +#endif +} + +// public CookieJar::AcceptPolicy acceptPolicy() const +void tst_CookieJar::acceptPolicy() +{ +#if 0 + QFETCH(CookieJar::AcceptPolicy, acceptPolicy); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + QCOMPARE(jar.acceptPolicy(), acceptPolicy); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::allowedCookies_data() +{ +#if 0 + QTest::addColumn("allowedCookies"); + QTest::newRow("null") << QStringList(); +#endif +} + +// public QStringList allowedCookies() const +void tst_CookieJar::allowedCookies() +{ +#if 0 + QFETCH(QStringList, allowedCookies); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + QCOMPARE(jar.allowedCookies(), allowedCookies); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::allowForSessionCookies_data() +{ +#if 0 + QTest::addColumn("allowForSessionCookies"); + QTest::newRow("null") << QStringList(); +#endif +} + +// public QStringList allowForSessionCookies() const +void tst_CookieJar::allowForSessionCookies() +{ +#if 0 + QFETCH(QStringList, allowForSessionCookies); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + QCOMPARE(jar.allowForSessionCookies(), allowForSessionCookies); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::blockedCookies_data() +{ +#if 0 + QTest::addColumn("blockedCookies"); + QTest::newRow("null") << QStringList(); +#endif +} + +// public QStringList blockedCookies() const +void tst_CookieJar::blockedCookies() +{ +#if 0 + QFETCH(QStringList, blockedCookies); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + QCOMPARE(jar.blockedCookies(), blockedCookies); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::clear_data() +{ + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +} + +// public void clear() +void tst_CookieJar::clear() +{ +#if 0 + QFETCH(int, foo); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.clear(); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::cookiesForUrl_data() +{ +#if 0 + QTest::addColumn("url"); + QTest::addColumn>("cookiesForUrl"); + QTest::newRow("null") << QUrl() << QList(); +#endif +} + +// public QList cookiesForUrl(QUrl const &url) const +void tst_CookieJar::cookiesForUrl() +{ +#if 0 + QFETCH(QUrl, url); + QFETCH(QList, cookiesForUrl); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + QCOMPARE(jar.cookiesForUrl(url), cookiesForUrl); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +Q_DECLARE_METATYPE(CookieJar::KeepPolicy) +void tst_CookieJar::keepPolicy_data() +{ +#if 0 + QTest::addColumn("keepPolicy"); + QTest::newRow("null") << CookieJar::KeepPolicy(); +#endif +} + +// public CookieJar::KeepPolicy keepPolicy() const +void tst_CookieJar::keepPolicy() +{ +#if 0 + QFETCH(CookieJar::KeepPolicy, keepPolicy); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + QCOMPARE(jar.keepPolicy(), keepPolicy); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::loadSettings_data() +{ + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +} + +// public void loadSettings() +void tst_CookieJar::loadSettings() +{ +#if 0 + QFETCH(int, foo); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.loadSettings(); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::setAcceptPolicy_data() +{ +#if 0 + QTest::addColumn("policy"); + QTest::newRow("null") << CookieJar::AcceptPolicy(); +#endif +} + +// public void setAcceptPolicy(CookieJar::AcceptPolicy policy) +void tst_CookieJar::setAcceptPolicy() +{ +#if 0 + QFETCH(CookieJar::AcceptPolicy, policy); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.setAcceptPolicy(policy); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::setAllowedCookies_data() +{ +#if 0 + QTest::addColumn("list"); + QTest::newRow("null") << QStringList(); +#endif +} + +// public void setAllowedCookies(QStringList const &list) +void tst_CookieJar::setAllowedCookies() +{ +#if 0 + QFETCH(QStringList, list); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.setAllowedCookies(list); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::setAllowForSessionCookies_data() +{ +#if 0 + QTest::addColumn("list"); + QTest::newRow("null") << QStringList(); +#endif +} + +// public void setAllowForSessionCookies(QStringList const &list) +void tst_CookieJar::setAllowForSessionCookies() +{ +#if 0 + QFETCH(QStringList, list); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.setAllowForSessionCookies(list); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::setBlockedCookies_data() +{ +#if 0 + QTest::addColumn("list"); + QTest::newRow("null") << QStringList(); +#endif +} + +// public void setBlockedCookies(QStringList const &list) +void tst_CookieJar::setBlockedCookies() +{ +#if 0 + QFETCH(QStringList, list); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.setBlockedCookies(list); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::setCookiesFromUrl_data() +{ +#if 0 + QTest::addColumn>("cookieList"); + QTest::addColumn("url"); + QTest::addColumn("setCookiesFromUrl"); + QTest::newRow("null") << QList() << QUrl() << false; +#endif +} + +// public bool setCookiesFromUrl(QList const &cookieList, QUrl const &url) +void tst_CookieJar::setCookiesFromUrl() +{ +#if 0 + QFETCH(QList, cookieList); + QFETCH(QUrl, url); + QFETCH(bool, setCookiesFromUrl); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + QCOMPARE(jar.setCookiesFromUrl(cookieList, url), setCookiesFromUrl); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::setKeepPolicy_data() +{ +#if 0 + QTest::addColumn("policy"); + QTest::newRow("null") << CookieJar::KeepPolicy(); +#endif +} + +// public void setKeepPolicy(CookieJar::KeepPolicy policy) +void tst_CookieJar::setKeepPolicy() +{ +#if 0 + QFETCH(CookieJar::KeepPolicy, policy); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.setKeepPolicy(policy); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::cookiesChanged_data() +{ + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +} + +// protected void cookiesChanged() +void tst_CookieJar::cookiesChanged() +{ +#if 0 + QFETCH(int, foo); + + SubCookieJar jar; + + QSignalSpy spy0(&jar, SIGNAL(cookiesChanged())); + + jar.call_cookiesChanged(); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_CookieJar::isOnDomainList_data() +{ + QTest::addColumn("list"); + QTest::addColumn("domain"); + QTest::addColumn("isOnDomainList"); + + QTest::newRow("null") << QStringList() << QString() << false; + QTest::newRow("exact-match") << (QStringList() << "foo.com") << "foo.com" << true; + + QTest::newRow("check-0") << (QStringList() << "foo.com") << "foo.com" << true; + QTest::newRow("check-1") << (QStringList() << "foo.com") << ".foo.com" << true; + QTest::newRow("check-2") << (QStringList() << ".foo.com") << "foo.com" << true; + QTest::newRow("check-3") << (QStringList() << ".foo.com") << ".foo.com" << true; + QTest::newRow("check-4") << (QStringList() << "foo.com") << "abcfoo.com" << false; + QTest::newRow("check-5") << (QStringList() << "foo.com") << "abc.foo.com" << true; + QTest::newRow("check-6") << (QStringList() << ".foo.com") << "abcfoo.com" << false; + QTest::newRow("check-7") << (QStringList() << ".foo.com") << "abc.foo.com" << true; + + QTest::newRow("check-4") << (QStringList() << "abc.foo.com") << "foo.com" << false; + QTest::newRow("check-5") << (QStringList() << "abc.foo.com") << ".foo.com" << false; + + + QTest::newRow("edgecheck-0") << (QStringList() << "") << ".foo.com" << false; + QTest::newRow("edgecheck-1") << (QStringList() << "") << "foo.com" << false; + QTest::newRow("edgecheck-2") << (QStringList() << ".") << ".foo.com" << false; + QTest::newRow("edgecheck-3") << (QStringList() << ".") << "foo.com" << false; + QTest::newRow("edgecheck-4") << (QStringList() << "abc.foo.com") << "" << false; + QTest::newRow("edgecheck-5") << (QStringList() << "a") << "ab" << false; +} + +// protected static bool isOnDomainList(QStringList const &list, QString const &domain) +void tst_CookieJar::isOnDomainList() +{ + QFETCH(QStringList, list); + QFETCH(QString, domain); + QFETCH(bool, isOnDomainList); + + SubCookieJar jar; + + QCOMPARE(jar.call_isOnDomainList(list, domain), isOnDomainList); +} + +QTEST_MAIN(tst_CookieJar) +#include "tst_cookiejar.moc" + diff --git a/autotests/downloadmanager/.gitignore b/autotests/downloadmanager/.gitignore new file mode 100644 index 00000000..45b3fddc --- /dev/null +++ b/autotests/downloadmanager/.gitignore @@ -0,0 +1 @@ +downloadmanager diff --git a/autotests/downloadmanager/tst_downloadmanager.cpp b/autotests/downloadmanager/tst_downloadmanager.cpp index b1fc785e..40e54407 100644 --- a/autotests/downloadmanager/tst_downloadmanager.cpp +++ b/autotests/downloadmanager/tst_downloadmanager.cpp @@ -123,7 +123,7 @@ void tst_DownloadManager::cleanupButton() QProgressBar *bar = manager.findChild(); QVERIFY(bar); - QListbuttons = manager.findChildren(); + QListbuttons = manager.findChildren(); QPushButton *tryAgainButton = 0; for (int i = 0; i < buttons.count(); ++i) if (buttons[i]->text().contains("Try")) @@ -164,7 +164,7 @@ void tst_DownloadManager::download_data() QTest::newRow("twofiles") << (QStringList() << BIGFILE << BIGFILE) << (QStringList() << BIGFILENAME << BIGFILENAME2) << 2 << true; } -// public void download(QNetworkRequest const& request) +// public void download(QNetworkRequest const &request) void tst_DownloadManager::download() { QFETCH(QStringList, request); @@ -181,7 +181,7 @@ void tst_DownloadManager::download() for (int i = 0; i < request.count(); ++i) manager.download(QUrl(request[i])); - QListbuttons = manager.findChildren(); + QListbuttons = manager.findChildren(); QPushButton *tryAgainButton = 0; for (int i = 0; i < buttons.count(); ++i) if (buttons[i]->text().contains("Try")) diff --git a/autotests/historyfiltermodel/.gitignore b/autotests/historyfiltermodel/.gitignore new file mode 100644 index 00000000..338a751c --- /dev/null +++ b/autotests/historyfiltermodel/.gitignore @@ -0,0 +1 @@ +historyfiltermodel diff --git a/autotests/historyfiltermodel/tst_historyfiltermodel.cpp b/autotests/historyfiltermodel/tst_historyfiltermodel.cpp index 26775e2e..c430ef73 100644 --- a/autotests/historyfiltermodel/tst_historyfiltermodel.cpp +++ b/autotests/historyfiltermodel/tst_historyfiltermodel.cpp @@ -19,6 +19,7 @@ #include #include +#include class tst_HistoryFilterModel : public QObject { @@ -59,7 +60,7 @@ class SubHistoryFilterModel : public HistoryFilterModel history = new HistoryManager(this); historyModel = new HistoryModel(history, this); setSourceModel(historyModel); - history->setHistoryLimit(-1); + history->setDaysToExpire(-1); } HistoryModel *historyModel; @@ -100,16 +101,16 @@ void tst_HistoryFilterModel::historyfiltermodel() model.historyLocation(QString()); } -typedef QList HistoryList; +typedef QList HistoryList; Q_DECLARE_METATYPE(HistoryList) -Q_DECLARE_METATYPE(HistoryItem) +Q_DECLARE_METATYPE(HistoryEntry) HistoryList makeHistoryList(int count) { HistoryList list; QDateTime dateTime = QDateTime::currentDateTime(); for (int i = 0; i < count; ++i) { - HistoryItem item; + HistoryEntry item; QString url = QString("http://%1host-%2.com/") .arg(qrand() % 2 ? "www." : "") .arg(QString::number(i)); @@ -140,7 +141,7 @@ void tst_HistoryFilterModel::historyContains_data() QTest::newRow("many-3") << list2 << QString("foo") << false; } -// public bool historyContains(QString const& url) const +// public bool historyContains(QString const &url) const void tst_HistoryFilterModel::historyContains() { QFETCH(HistoryList, list); @@ -153,7 +154,7 @@ void tst_HistoryFilterModel::historyContains() QCOMPARE(model.historyContains(url), historyContains); } -// public void setSourceModel(QAbstractItemModel* sourceModel) +// public void setSourceModel(QAbstractItemModel *sourceModel) void tst_HistoryFilterModel::setSourceModel() { SubHistoryFilterModel model; diff --git a/autotests/historymanager/.gitignore b/autotests/historymanager/.gitignore new file mode 100644 index 00000000..3d7b6d4d --- /dev/null +++ b/autotests/historymanager/.gitignore @@ -0,0 +1 @@ +historymanager diff --git a/autotests/historymanager/historymanager.pro b/autotests/historymanager/historymanager.pro new file mode 100644 index 00000000..92e9c624 --- /dev/null +++ b/autotests/historymanager/historymanager.pro @@ -0,0 +1,10 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../autotests.pri) + +# Input +SOURCES += tst_historymanager.cpp +HEADERS += diff --git a/autotests/history/myhistory.txt b/autotests/historymanager/myhistory.txt similarity index 100% rename from autotests/history/myhistory.txt rename to autotests/historymanager/myhistory.txt diff --git a/autotests/history/tst_history.cpp b/autotests/historymanager/tst_historymanager.cpp similarity index 67% rename from autotests/history/tst_history.cpp rename to autotests/historymanager/tst_historymanager.cpp index 5343733a..c1173f9d 100644 --- a/autotests/history/tst_history.cpp +++ b/autotests/historymanager/tst_historymanager.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2014 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,10 +19,15 @@ #include #include "qtest_arora.h" + +#include #include +#include #include -class tst_History : public QObject +#include + +class tst_HistoryManager : public QObject { Q_OBJECT @@ -35,12 +40,14 @@ public slots: private slots: void history_data(); void history(); - void addHistoryItem_data(); - void addHistoryItem(); - void updateHistoryItem_data(); - void updateHistoryItem(); - void historyLimit_data(); - void historyLimit(); + void addHistoryEntry_data(); + void addHistoryEntry(); + void addHistoryEntry_private(); + void addHistoryEntry_url(); + void updateHistoryEntry_data(); + void updateHistoryEntry(); + void daysToExpire_data(); + void daysToExpire(); void clear_data(); void clear(); void setHistory_data(); @@ -48,13 +55,14 @@ private slots: void saveload_data(); void saveload(); + // TODO move to their own tests void big(); void historyDialog_data(); void historyDialog(); private: - QList bigHistory; + QList bigHistory; }; // Subclass that exposes the protected functions. @@ -65,22 +73,22 @@ class SubHistory : public HistoryManager { QWidget w; setParent(&w); - if (QWebHistoryInterface::defaultInterface() == this); + if (QWebHistoryInterface::defaultInterface() == this) QWebHistoryInterface::setDefaultInterface(0); setParent(0); } ~SubHistory() { - setHistoryLimit(30); + setDaysToExpire(30); } - void addHistoryItem(const HistoryItem &item) - { HistoryManager::addHistoryItem(item); } + void prependHistoryEntry(const HistoryEntry &item) + { HistoryManager::prependHistoryEntry(item); } }; // This will be called before the first test function is executed. // It is only called once. -void tst_History::initTestCase() +void tst_HistoryManager::initTestCase() { QCoreApplication::setApplicationName("historytest"); @@ -91,14 +99,14 @@ void tst_History::initTestCase() } QTextStream stream(&file); - QList list; + QList list; do { QString url = stream.readLine(); QString title = stream.readLine(); QString date = stream.readLine(); QDateTime dateTime = QDateTime::fromString(date); - QCOMPARE(dateTime.toString(), date); - HistoryItem item(url, dateTime, title); + QVERIFY(dateTime.isValid()); + HistoryEntry item(url, dateTime, title); list.prepend(item); } while (!stream.atEnd()); bigHistory = list; @@ -107,44 +115,44 @@ void tst_History::initTestCase() // This will be called after the last test function is executed. // It is only called once. -void tst_History::cleanupTestCase() +void tst_HistoryManager::cleanupTestCase() { } // This will be called before each test function is executed. -void tst_History::init() +void tst_HistoryManager::init() { } // This will be called after every test function. -void tst_History::cleanup() +void tst_HistoryManager::cleanup() { } -void tst_History::history_data() +void tst_HistoryManager::history_data() { } -void tst_History::history() +void tst_HistoryManager::history() { SubHistory history; - history.addHistoryItem(HistoryItem()); + history.prependHistoryEntry(HistoryEntry()); history.clear(); - QCOMPARE(history.historyLimit(), 30); - history.setHistoryLimit(-1); - history.updateHistoryItem(QUrl(), QString()); + QCOMPARE(history.daysToExpire(), 30); + history.setDaysToExpire(-1); + history.updateHistoryEntry(QUrl(), QString()); } -typedef QList HistoryList; +typedef QList HistoryList; Q_DECLARE_METATYPE(HistoryList) -Q_DECLARE_METATYPE(HistoryItem) -void tst_History::addHistoryItem_data() +Q_DECLARE_METATYPE(HistoryEntry) +void tst_HistoryManager::addHistoryEntry_data() { QTest::addColumn("initial"); QTest::addColumn("items"); QTest::addColumn("expected"); HistoryList empty; - HistoryItem item1("http://foo.com", QDateTime::currentDateTime().addDays(-3)); + HistoryEntry item1("http://foo.com", QDateTime::currentDateTime().addDays(-3)); HistoryList one; one << item1; HistoryList one2; @@ -154,8 +162,8 @@ void tst_History::addHistoryItem_data() QTest::newRow("1-0") << one << HistoryList() << one; QTest::newRow("1-1") << one << (HistoryList() << item1) << one2; - HistoryItem item2("http://bar.com", QDateTime::currentDateTime().addDays(-2)); - HistoryItem item2n("http://bar.com", QDateTime::currentDateTime()); + HistoryEntry item2("http://bar.com", QDateTime::currentDateTime().addDays(-2)); + HistoryEntry item2n("http://bar.com", QDateTime::currentDateTime()); HistoryList two = one; two.prepend(item2); @@ -170,8 +178,8 @@ void tst_History::addHistoryItem_data() QTest::newRow("2-2,1") << one << (HistoryList() << item2) << swap; /* // move to test for the historyFilterModel - HistoryItem item3("http://baz.com", QDateTime::currentDateTime().addDays(-1)); - HistoryItem item3n("http://baz.com", QDateTime::currentDateTime()); + HistoryEntry item3("http://baz.com", QDateTime::currentDateTime().addDays(-1)); + HistoryEntry item3n("http://baz.com", QDateTime::currentDateTime()); QTest::newRow("move-1") << (HistoryList() << item3 << item2 << item1) << (HistoryList() << item3) << (HistoryList() << item3 << item2 << item1); @@ -186,8 +194,8 @@ void tst_History::addHistoryItem_data() */ } -// public void addHistoryItem(HistoryItem* item) -void tst_History::addHistoryItem() +// public void addHistoryEntry(HistoryEntry *item) +void tst_HistoryManager::addHistoryEntry() { QFETCH(HistoryList, initial); QFETCH(HistoryList, items); @@ -196,24 +204,44 @@ void tst_History::addHistoryItem() SubHistory history; history.setHistory(initial); for (int i = 0; i < items.count(); ++i) - history.addHistoryItem(items[i]); + history.prependHistoryEntry(items[i]); QCOMPARE(history.history().count(), expected.count()); QCOMPARE(history.history(), expected); } -void tst_History::updateHistoryItem_data() +void tst_HistoryManager::addHistoryEntry_private() +{ + SubHistory history; + history.setHistory(HistoryList()); + QWebSettings *globalSettings = QWebSettings::globalSettings(); + globalSettings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); + history.prependHistoryEntry(HistoryEntry()); + globalSettings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); + QVERIFY(history.history().isEmpty()); +} + +void tst_HistoryManager::addHistoryEntry_url() +{ + SubHistory history; + QString urlWithPassword("http://username:password@example.com"); + history.addHistoryEntry(urlWithPassword); + QString cleanedUrl = "http://username@example.com"; + QCOMPARE(history.history()[0].url, cleanedUrl); +} + +void tst_HistoryManager::updateHistoryEntry_data() { QTest::addColumn("list"); QTest::addColumn("url"); QTest::addColumn("title"); QTest::newRow("null") << HistoryList() << QUrl() << QString(); - QTest::newRow("one") << (HistoryList() << HistoryItem()) << QUrl() << QString("foo"); - QTest::newRow("two") << (HistoryList() << HistoryItem() << HistoryItem("http://foo.com")) << QUrl() << QString("foo"); + QTest::newRow("one") << (HistoryList() << HistoryEntry()) << QUrl() << QString("foo"); + QTest::newRow("two") << (HistoryList() << HistoryEntry() << HistoryEntry("http://foo.com")) << QUrl() << QString("foo"); } -// public void updateHistoryItem(QUrl const& url, QString const title) -void tst_History::updateHistoryItem() +// public void updateHistoryEntry(QUrl const &url, QString const title) +void tst_HistoryManager::updateHistoryEntry() { QFETCH(HistoryList, list); QFETCH(QUrl, url); @@ -221,17 +249,17 @@ void tst_History::updateHistoryItem() SubHistory history; history.setHistory(list); - history.updateHistoryItem(url, title); + history.updateHistoryEntry(url, title); if (list.isEmpty()) QVERIFY(history.history().isEmpty()); else QVERIFY(history.history() != list); } -void tst_History::historyLimit_data() +void tst_HistoryManager::daysToExpire_data() { QTest::addColumn("list"); - QTest::addColumn("historyLimit"); + QTest::addColumn("daysToExpire"); QTest::addColumn("wait_seconds"); QTest::addColumn("post"); @@ -240,21 +268,21 @@ void tst_History::historyLimit_data() yesterday.setDate(yesterday.date().addDays(-1)); yesterday.setTime(yesterday.time().addSecs(2)); - HistoryItem fooNow("http://foo.com", now); - HistoryItem barYesterday("http://bar.com", yesterday); + HistoryEntry fooNow("http://foo.com", now); + HistoryEntry barYesterday("http://bar.com", yesterday); QTest::newRow("two") << (HistoryList() << fooNow << barYesterday) << 1 << 3 << (HistoryList() << fooNow); yesterday.setTime(yesterday.time().addSecs(3)); barYesterday.dateTime = yesterday; - HistoryItem barYesterday2("http://bar2.com", yesterday); + HistoryEntry barYesterday2("http://bar2.com", yesterday); QTest::newRow("three") << (HistoryList() << fooNow << barYesterday << barYesterday2) << 1 << 3 << (HistoryList() << fooNow); } -// public int historyLimit() const -void tst_History::historyLimit() +// public int daysToExpire() const +void tst_HistoryManager::daysToExpire() { QFETCH(HistoryList, list); - QFETCH(int, historyLimit); + QFETCH(int, daysToExpire); QFETCH(int, wait_seconds); QFETCH(HistoryList, post); @@ -264,31 +292,31 @@ void tst_History::historyLimit() qSort(list.begin(), list.end()); QCOMPARE(history.history(), list); - history.setHistoryLimit(historyLimit); - QCOMPARE(history.historyLimit(), historyLimit); + history.setDaysToExpire(daysToExpire); + QCOMPARE(history.daysToExpire(), daysToExpire); - QTest::qWait(wait_seconds * 1000); + QTest::qWait(wait_seconds*1000); QCOMPARE(history.history(), post); // re-add the items that have probably expired to catch any cache issues for (int i = 0; i < list.count(); ++i) { - HistoryItem item = list.at(i); + HistoryEntry item = list.at(i); item.dateTime = QDateTime::currentDateTime(); - history.addHistoryItem(item); + history.prependHistoryEntry(item); } } -void tst_History::clear_data() +void tst_HistoryManager::clear_data() { QTest::addColumn("list"); QTest::newRow("null") << HistoryList(); - QTest::newRow("one") << (HistoryList() << HistoryItem()); - QTest::newRow("two") << (HistoryList() << HistoryItem() << HistoryItem("http://foo.com")); + QTest::newRow("one") << (HistoryList() << HistoryEntry()); + QTest::newRow("two") << (HistoryList() << HistoryEntry() << HistoryEntry("http://foo.com")); } // public void clear() -void tst_History::clear() +void tst_HistoryManager::clear() { QFETCH(HistoryList, list); { @@ -305,7 +333,7 @@ void tst_History::clear() } } -void tst_History::setHistory_data() +void tst_HistoryManager::setHistory_data() { QTest::addColumn("list"); QTest::addColumn("post"); @@ -316,8 +344,8 @@ void tst_History::setHistory_data() QTest::newRow("empty") << HistoryList() << HistoryList(); - HistoryItem foo("http://foo.com", now); - HistoryItem bar("http://bar.com", yesterday); + HistoryEntry foo("http://foo.com", now); + HistoryEntry bar("http://bar.com", yesterday); QTest::newRow("sort") << (HistoryList() << bar << foo) << (HistoryList() << foo << bar); // QTest::newRow("dupe-1") << (HistoryList() << bar << bar) << (HistoryList() << bar); @@ -325,12 +353,12 @@ void tst_History::setHistory_data() QDateTime longAgo = now; longAgo.setDate(longAgo.date().addYears(-1)); - HistoryItem expired("http://junk.com", longAgo); + HistoryEntry expired("http://junk.com", longAgo); QTest::newRow("removeExpired-1") << (HistoryList() << expired) << HistoryList(); QTest::newRow("removeExpired-2") << (HistoryList() << foo << expired) << (HistoryList() << foo); } -void tst_History::setHistory() +void tst_HistoryManager::setHistory() { QFETCH(HistoryList, list); QFETCH(HistoryList, post); @@ -341,7 +369,7 @@ void tst_History::setHistory() QCOMPARE(history.history(), post); } -void tst_History::saveload_data() +void tst_HistoryManager::saveload_data() { QTest::addColumn("list"); QTest::addColumn("post"); @@ -352,10 +380,10 @@ void tst_History::saveload_data() QTest::newRow("empty") << HistoryList() << HistoryList(); - HistoryItem foo("http://foo.com", now); + HistoryEntry foo("http://foo.com", now); QTest::newRow("one item") << (HistoryList() << foo) << (HistoryList() << foo); - HistoryItem bar("http://bar.com", yesterday); + HistoryEntry bar("http://bar.com", yesterday); QTest::newRow("two items") << (HistoryList() << bar << foo) << (HistoryList() << foo << bar); QTest::newRow("dupe-1") << (HistoryList() << bar << bar) << (HistoryList() << bar); @@ -363,12 +391,12 @@ void tst_History::saveload_data() QDateTime longAgo = now; longAgo.setDate(longAgo.date().addYears(-1)); - HistoryItem expired("http://junk.com", longAgo); + HistoryEntry expired("http://junk.com", longAgo); QTest::newRow("removeExpired-1") << (HistoryList() << expired) << HistoryList(); QTest::newRow("removeExpired-2") << (HistoryList() << foo << expired) << (HistoryList() << foo); } -void tst_History::saveload() +void tst_HistoryManager::saveload() { QFETCH(HistoryList, list); QFETCH(HistoryList, post); @@ -381,9 +409,9 @@ void tst_History::saveload() SubHistory history; QCOMPARE(history.history(), post); // add url - HistoryItem foo("http://new.com", QDateTime::currentDateTime().addDays(1)); + HistoryEntry foo("http://new.com", QDateTime::currentDateTime().addDays(1)); post.prepend(foo); - history.addHistoryItem(foo); + history.prependHistoryEntry(foo); } { @@ -392,54 +420,46 @@ void tst_History::saveload() } } -void tst_History::big() +void tst_HistoryManager::big() { SubHistory history; - history.setHistoryLimit(-1); + history.setDaysToExpire(-1); history.setHistory(bigHistory); - - qDebug() << "removed dups:" << history.history().count(); QCOMPARE(history.history().count(), bigHistory.count()); - qDebug() << "loaded, making menu"; HistoryMenu menu; - menu.show(); - qDebug() << "menu done, making model"; HistoryModel model(&history); ModelTest test(&model); - qDebug() << "model rowCount" << model.rowCount(); QCOMPARE(model.rowCount(), bigHistory.count()); - qDebug() << "making completion model"; HistoryCompletionModel completionModel; completionModel.setSourceModel(&model); ModelTest test2(&completionModel); - QCOMPARE(completionModel.rowCount(), bigHistory.count() * 2); + QCOMPARE(completionModel.rowCount(), bigHistory.count()); - qDebug() << "making history dialog model"; HistoryTreeModel dialogModel(&model); ModelTest test3(&dialogModel); - int r = 0; QDate d; - for (int i = 0; i < bigHistory.count(); ++i) + for (int i = 0; i < bigHistory.count(); ++i) { if (bigHistory[i].dateTime.date() != d) { d = bigHistory[i].dateTime.date(); QDate rowDate = dialogModel.index(r, 0).data(HistoryModel::DateRole).toDate(); QCOMPARE(d, rowDate); r++; } + } + QCOMPARE(dialogModel.rowCount(), 328); HistoryDialog dialog(0, &history); - dialog.show(); QTest::qWait(100); } -void tst_History::historyDialog_data() +void tst_HistoryManager::historyDialog_data() { QTest::addColumn("parentRow"); QTest::addColumn("parentColumn"); @@ -456,53 +476,62 @@ void tst_History::historyDialog_data() QTest::newRow("page-2") << 0 << 0 << 2 << 0 << 0 << -1; QTest::newRow("page-3") << 0 << 0 << 3 << 0 << 0 << -1; QTest::newRow("page-4") << 0 << 0 << 4 << 0 << 0 << -1; - QTest::newRow("page-last") << 0 << 0 << -2 << 0 << 0 << -1; - QTest::newRow("page-only") << 32 << 0 << 0 << 0 << -1 << -1; + QTest::newRow("page-last") << 0 << 0 << -2 << 0 << 0 << -1; + QTest::newRow("page-only") << 32 << 0 << 0 << 0 << -1 << -1; - QTest::newRow("date-c") << -1 << -1 << 0 << 1 << -1 << 0; - QTest::newRow("date-0") << -1 << -1 << 0 << 0 << -1 << 0; - QTest::newRow("date-1") << -1 << -1 << 1 << 0 << -1 << 0; - QTest::newRow("date-2") << -1 << -1 << 2 << 0 << -1 << 0; - QTest::newRow("date-3") << -1 << -1 << 3 << 0 << -1 << 0; - QTest::newRow("date-last") << -1 << -1 << -2 << 0 << -1 << 0; + QTest::newRow("date-c") << -1 << -1 << 0 << 1 << -1 << 0; + QTest::newRow("date-0") << -1 << -1 << 0 << 0 << -1 << 0; + QTest::newRow("date-1") << -1 << -1 << 1 << 0 << -1 << 0; + QTest::newRow("date-2") << -1 << -1 << 2 << 0 << -1 << 0; + QTest::newRow("date-3") << -1 << -1 << 3 << 0 << -1 << 0; + QTest::newRow("date-last") << -1 << -1 << -2 << 0 << -1 << 0; QTest::newRow("removeAll") << -1 << -1 << -3 << 0 << -1 << 0; } -void tst_History::historyDialog() +void tst_HistoryManager::historyDialog() { QFETCH(int, parentRow); QFETCH(int, parentColumn); + QFETCH(int, row); QFETCH(int, column); + QFETCH(int, datesDiff); QFETCH(int, parentRowsDiff); - qDebug() << "which one"; SubHistory history; - history.setHistoryLimit(-1); + history.setDaysToExpire(-1); history.setHistory(bigHistory); HistoryDialog dialog(0, &history); - dialog.show(); //QTest::qWait(300); QAbstractItemModel *model = dialog.tree->model(); + ModelTest test(model); /* for (int i = 0; i < model->rowCount(); ++i) if (model->rowCount(model->index(i, 0)) == 1) qDebug() << i; */ - ModelTest test(model); - if (parentRow == -2) parentRow = model->rowCount() - 1; + if (parentRow == -2) + parentRow = model->rowCount() - 1; QModelIndex parent = model->index(parentRow, parentColumn); - if (row < -1) row = model->rowCount(parent) - 1; + + if (row < -1) + row = model->rowCount(parent) - 1; QModelIndex child = model->index(row, column, parent); QVERIFY(child.isValid()); int topRowCount = model->rowCount(); int parentRowCount = model->rowCount(parent.sibling(parent.row(), 0)); int childRowCount = model->rowCount(child.sibling(child.row(), 0)); - dialog.tree->selectionModel()->select(child, QItemSelectionModel::SelectCurrent); + /* + qDebug() << "topRowCount" << topRowCount; + qDebug() << "parentRowCount" << parentRowCount; + qDebug() << "childRowCount" << childRowCount; + qDebug() << "selecting" << child; + */ + dialog.tree->selectionModel()->select(child, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); if (row == -3) { dialog.tree->removeAll(); QCOMPARE(model->rowCount(), 0); @@ -517,5 +546,6 @@ void tst_History::historyDialog() } } -QTEST_MAIN(tst_History) -#include "tst_history.moc" +QTEST_MAIN(tst_HistoryManager) +#include "tst_historymanager.moc" + diff --git a/autotests/modeltest/README b/autotests/modeltest/README index 6a612613..f13e2af4 100644 --- a/autotests/modeltest/README +++ b/autotests/modeltest/README @@ -20,7 +20,7 @@ To Use the model test do the following: include(../path/to/dir/modeltest.pri) -2) Then in your source include "modeltest.h" and instantiate ModelTest with your model so the test can live for the lifetime of your model. For example: +2) Then in your source include "modeltest.h" and instantiate ModelTest with your model so the test can live for the lifetime of your model. For example: #include diff --git a/autotests/modeltest/modeltest.cpp b/autotests/modeltest/modeltest.cpp index 4a0a5360..a107e661 100644 --- a/autotests/modeltest/modeltest.cpp +++ b/autotests/modeltest/modeltest.cpp @@ -214,7 +214,7 @@ void ModelTest::index() Q_ASSERT(model->index(rows, columns) == QModelIndex()); Q_ASSERT(model->index(0, 0).isValid() == true); - // Make sure that the same index is *always* returned + // Make sure that the same index is _always_ returned QModelIndex a = model->index(0, 0); QModelIndex b = model->index(0, 0); Q_ASSERT(a == b); @@ -357,7 +357,7 @@ void ModelTest::checkChildren(const QModelIndex &parent, int currentDepth) Q_ASSERT(model->parent(index) == parent); // recursively go down the children - if (model->hasChildren(index) && currentDepth < 10 ) { + if (model->hasChildren(index) && currentDepth < 10) { //qDebug() << r << c << "has children" << model->rowCount(index); checkChildren(index, ++currentDepth); }/* else { if (currentDepth >= 10) qDebug() << "checked 10 deep"; };*/ @@ -416,17 +416,7 @@ void ModelTest::data() QVariant textAlignmentVariant = model->data(model->index(0, 0), Qt::TextAlignmentRole); if (textAlignmentVariant.isValid()) { int alignment = textAlignmentVariant.toInt(); - Q_ASSERT(alignment == Qt::AlignLeft || - alignment == Qt::AlignRight || - alignment == Qt::AlignHCenter || - alignment == Qt::AlignJustify || - alignment == Qt::AlignTop || - alignment == Qt::AlignBottom || - alignment == Qt::AlignVCenter || - alignment == Qt::AlignCenter || - alignment == Qt::AlignAbsolute || - alignment == Qt::AlignLeading || - alignment == Qt::AlignTrailing); + Q_ASSERT(alignment == (alignment & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask))); } // General Purpose roles that should return a QColor diff --git a/autotests/modeltoolbar/.gitignore b/autotests/modeltoolbar/.gitignore new file mode 100644 index 00000000..2ef7dd6f --- /dev/null +++ b/autotests/modeltoolbar/.gitignore @@ -0,0 +1 @@ +modeltoolbar diff --git a/autotests/modeltoolbar/modeltoolbar.pro b/autotests/modeltoolbar/modeltoolbar.pro new file mode 100644 index 00000000..2a63be59 --- /dev/null +++ b/autotests/modeltoolbar/modeltoolbar.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../autotests.pri) + +SOURCES += \ + tst_modeltoolbar.cpp diff --git a/autotests/modeltoolbar/tst_modeltoolbar.cpp b/autotests/modeltoolbar/tst_modeltoolbar.cpp new file mode 100644 index 00000000..4682090c --- /dev/null +++ b/autotests/modeltoolbar/tst_modeltoolbar.cpp @@ -0,0 +1,337 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include "qtry.h" + +#include "browserapplication.h" +#include "modelmenu.h" + +#include +#include +#include +#include + +class tst_ModelToolBar : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void modeltoolbar(); + void index(); + void model(); + void rootIndex(); + void activated_data(); + void activated(); + void build_data(); + void build(); + void showHide(); +}; + +// Subclass that exposes the protected functions. +class SubModelToolBar : public ModelToolBar +{ +public: + void call_activated(QModelIndex const &index) + { return SubModelToolBar::activated(index); } + + void call_build() + { SubModelToolBar::build(); resize(sizeHint()); } + + ModelMenu *call_createMenu() + { return SubModelToolBar::createMenu(); } +}; + +class ColorModel : public QAbstractItemModel +{ +public: + ColorModel(QObject *parent = 0) + : QAbstractItemModel(parent) + { + m_colours = QColor::colorNames(); + } + + bool hasChildren(const QModelIndex &parent = QModelIndex()) const + { + Q_UNUSED(parent) + return false; + } + + int rowCount(const QModelIndex &parent = QModelIndex()) const + { + if (parent.isValid()) + return 0; + return m_colours.count(); + } + + int columnCount(const QModelIndex &parent = QModelIndex()) const + { + if (parent.isValid()) + return 0; + return 1; + } + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const + { + if (index.parent().isValid() || index.column() > 0) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + return m_colours.at(index.row()); + break; + default: + return QVariant(); + break; + } + } + + QModelIndex parent(const QModelIndex &index) const + { + Q_UNUSED(index); + return QModelIndex(); + } + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const + { + if (parent.isValid()) + return QModelIndex(); + return createIndex(row, column); + } + +private: + QStringList m_colours; +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_ModelToolBar::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_ModelToolBar::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_ModelToolBar::init() +{ +} + +// This will be called after every test function. +void tst_ModelToolBar::cleanup() +{ +} + +void tst_ModelToolBar::modeltoolbar() +{ + SubModelToolBar bar; + QCOMPARE(bar.model(), (QAbstractItemModel*)0); + QCOMPARE(bar.index(0), QModelIndex()); + QCOMPARE(bar.rootIndex(), QModelIndex()); + bar.setModel(new QStandardItemModel(&bar)); + QVERIFY(bar.model()); + bar.show(); + bar.hide(); + bar.call_build(); +} + +// public static QModelIndex index(QAction *action) +void tst_ModelToolBar::index() +{ + SubModelToolBar bar; + + ColorModel model; + bar.setModel(&model); + QCOMPARE(bar.model(), &model); + + bar.show(); + + QList actions = bar.actions(); + QVERIFY(!actions.isEmpty()); + + for (int i = 0; i < model.rowCount(); ++i) { + QModelIndex index = model.index(i, 0); + QAction *action = actions.at(i); + QVERIFY(action); + QVERIFY(bar.index(action).isValid()); + QCOMPARE(index.data(Qt::DisplayRole).toString(), action->text()); + QCOMPARE(index.data(Qt::DecorationRole).value(), action->icon()); + QCOMPARE(model.hasChildren(index), (bool)action->menu()); + + if (action->menu()) { + ModelMenu *menu = static_cast(action->menu()); + QVERIFY(menu); + QCOMPARE(bar.index(action), menu->rootIndex()); + QCOMPARE(bar.model(), menu->model()); + QCOMPARE(model.rowCount(bar.index(action)), menu->actions().count()); + } + } +} + +// public QAbstractItemModel *model() const +void tst_ModelToolBar::model() +{ + SubModelToolBar bar; + QCOMPARE(bar.model(), (QAbstractItemModel*)0); + bar.setModel(0); + QCOMPARE(bar.model(), (QAbstractItemModel*)0); + + ColorModel model; + bar.setModel(&model); + QCOMPARE(bar.model(), &model); +} + +// public QModelIndex rootIndex() const +void tst_ModelToolBar::rootIndex() +{ + SubModelToolBar bar; + QCOMPARE(bar.rootIndex(), QModelIndex()); + bar.setRootIndex(QModelIndex()); + QCOMPARE(bar.rootIndex(), QModelIndex()); + + ColorModel model; + bar.setModel(&model); + QCOMPARE(bar.model(), &model); + QVERIFY(model.rowCount(QModelIndex()) > 0); + bar.setRootIndex(model.index(0, 0, QModelIndex())); + QCOMPARE(bar.rootIndex(), model.index(0, 0, QModelIndex())); +} + +void tst_ModelToolBar::activated_data() +{ + QTest::addColumn("items"); + + QTest::newRow("null") << QStringList(); + QTest::newRow("foobarbaz") << (QStringList() << "foo" << "bar" << "baz" << "bar" << "foo"); + QTest::newRow("colors") << QColor::colorNames(); + QTest::newRow("environment") << QProcess::systemEnvironment(); +} + +// protected void activated(QModelIndex const &index) +void tst_ModelToolBar::activated() +{ + QFETCH(QStringList, items); + + SubModelToolBar bar; + + QStringListModel model(items); + bar.setModel(&model); + QCOMPARE(bar.model(), &model); + + bar.show(); + bar.call_build(); + QCOMPARE(bar.actions().isEmpty(), items.isEmpty()); + + QRect rect = bar.childrenRect(); + QPoint point = rect.topLeft(); + + QSignalSpy spy(&bar, SIGNAL(activated(QModelIndex const&))); + + while (rect.contains(point)) { + QAction *action = bar.actionAt(point); + QWidget *widget = bar.childAt(point); + if (action) { + QVERIFY(widget); + QVERIFY(bar.index(action).isValid()); + } else { + QVERIFY(!widget); + QVERIFY(!bar.index(action).isValid()); + } + + if (!widget) + widget = &bar; + + QTest::mouseClick(widget, Qt::LeftButton, Qt::NoModifier, bar.mapToGlobal(point)); + QTest::mouseClick(widget, Qt::MidButton, Qt::ShiftModifier, bar.mapToGlobal(point)); + QTRY_COMPARE(spy.count(), (bool)action * 2); + + if (spy.count()) + QCOMPARE(spy.at(0).at(0).value(), bar.index(action)); + + if (action) { + QCOMPARE(BrowserApplication::instance()->eventMouseButtons(), Qt::MidButton); + QCOMPARE(BrowserApplication::instance()->eventKeyboardModifiers(), Qt::ShiftModifier); + } + + spy.clear(); + + point.setX(point.x() + 50); + } +} + +void tst_ModelToolBar::build_data() +{ + QTest::addColumn("items"); + + QTest::newRow("null") << QStringList(); + QTest::newRow("foobarbaz") << (QStringList() << "foo" << "bar" << "baz" << "bar" << "foo"); + QTest::newRow("colors") << QColor::colorNames(); + QTest::newRow("environment") << QProcess::systemEnvironment(); +} + +// protected void build() +void tst_ModelToolBar::build() +{ + QFETCH(QStringList, items); + + SubModelToolBar bar; + + QStringListModel model(items); + bar.setModel(&model); + QCOMPARE(bar.model(), &model); + QCOMPARE(items.count(), model.rowCount()); + + QVERIFY(bar.actions().isEmpty()); + bar.call_build(); + QCOMPARE(bar.actions().count(), items.count()); + bar.call_build(); + QCOMPARE(bar.actions().count(), model.rowCount()); +} + +void tst_ModelToolBar::showHide() +{ + SubModelToolBar bar; + + ColorModel model; + bar.setModel(&model); + QCOMPARE(bar.model(), &model); + + QVERIFY(bar.actions().isEmpty()); + + bar.show(); + QCOMPARE(bar.actions().count(), model.rowCount()); + bar.hide(); + QVERIFY(bar.actions().isEmpty()); + bar.show(); + QCOMPARE(bar.actions().count(), model.rowCount()); +} + +QTEST_MAIN(tst_ModelToolBar) +#include "tst_modeltoolbar.moc" + diff --git a/autotests/opensearchengine/.gitignore b/autotests/opensearchengine/.gitignore new file mode 100644 index 00000000..b27a2d87 --- /dev/null +++ b/autotests/opensearchengine/.gitignore @@ -0,0 +1 @@ +opensearchengine diff --git a/autotests/opensearchengine/opensearchengine.pro b/autotests/opensearchengine/opensearchengine.pro new file mode 100644 index 00000000..9a5b215a --- /dev/null +++ b/autotests/opensearchengine/opensearchengine.pro @@ -0,0 +1,20 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../autotests.pri) + +SOURCES = \ + opensearchengine.cpp \ + opensearchenginedelegate.cpp \ + tst_opensearchengine.cpp + +HEADERS = \ + opensearchengine.h \ + opensearchenginedelegate.h + +FORMS = + +RESOURCES = \ + opensearchengine.qrc diff --git a/autotests/opensearchengine/opensearchengine.qrc b/autotests/opensearchengine/opensearchengine.qrc new file mode 100644 index 00000000..8d254e01 --- /dev/null +++ b/autotests/opensearchengine/opensearchengine.qrc @@ -0,0 +1,5 @@ + + + suggestions.txt + + diff --git a/autotests/opensearchengine/suggestions.txt b/autotests/opensearchengine/suggestions.txt new file mode 100644 index 00000000..73a1e67f --- /dev/null +++ b/autotests/opensearchengine/suggestions.txt @@ -0,0 +1 @@ +["sea", ["sears", "search engines", "search engine", "search", "sears.com", "seattle times"], ["7,390,000 results", "17,900,000 results", "25,700,000 results", "1,220,000,000 results", "1 result", "17,600,000 results"], ["http://example.com?q=sears", "http://example.com?q=search+engines", "http://example.com?q=search+engine", "http://example.com?q=search", "http://example.com?q=sears.com", "http://example.com?q=seattle+times"]] \ No newline at end of file diff --git a/autotests/opensearchengine/tst_opensearchengine.cpp b/autotests/opensearchengine/tst_opensearchengine.cpp new file mode 100644 index 00000000..0b383787 --- /dev/null +++ b/autotests/opensearchengine/tst_opensearchengine.cpp @@ -0,0 +1,907 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include "qtry.h" +#include "opensearchengine.h" +#include "opensearchenginedelegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef OpenSearchEngine::Parameters Parameters; +typedef OpenSearchEngine::Parameter Parameter; + +class tst_OpenSearchEngine : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void opensearchengine_data(); + void opensearchengine(); + + void description_data(); + void description(); + void image(); + void imageUrl_data(); + void imageUrl(); + void isValid_data(); + void isValid(); + void name_data(); + void name(); + void operatorlessthan(); + void operatorequal_data(); + void operatorequal(); + void providesSuggestions_data(); + void providesSuggestions(); + void requestSuggestions_data(); + void requestSuggestions(); + void requestSuggestionsCrash(); + void searchParameters_data(); + void searchParameters(); + void searchUrl_data(); + void searchUrl(); + void searchUrlTemplate_data(); + void searchUrlTemplate(); + void suggestionsParameters_data(); + void suggestionsParameters(); + void suggestionsUrl_data(); + void suggestionsUrl(); + void suggestionsUrlTemplate_data(); + void suggestionsUrlTemplate(); + void parseTemplate_data(); + void parseTemplate(); + void languageCodes_data(); + void languageCodes(); + void requestMethods(); + void delegate(); +}; + +// Subclass that exposes the protected functions. +class SubOpenSearchEngine : public OpenSearchEngine +{ +public: + void call_imageChanged() + { return SubOpenSearchEngine::imageChanged(); } + + void call_loadImage() const + { return SubOpenSearchEngine::loadImage(); } + + QString call_parseTemplate(QString const &searchTerm, QString const &searchTemplate) const + { return SubOpenSearchEngine::parseTemplate(searchTerm, searchTemplate); } + + void call_suggestions(QStringList const &suggestions) + { return SubOpenSearchEngine::suggestions(suggestions); } +}; + +class SuggestionsTestNetworkReply : public QNetworkReply +{ + Q_OBJECT + +public: + SuggestionsTestNetworkReply(const QNetworkRequest &request, QObject *parent = 0) + : QNetworkReply(parent) + { + setOperation(QNetworkAccessManager::GetOperation); + setRequest(request); + setUrl(request.url()); + setOpenMode(QIODevice::ReadOnly); + + expectedResult.setFileName(":/suggestions.txt"); + expectedResult.open(QIODevice::ReadOnly); + setError(QNetworkReply::NoError, tr("No Error")); + + QTimer::singleShot(50, this, SLOT(sendSuggestions())); + } + + ~SuggestionsTestNetworkReply() + { + close(); + } + + qint64 bytesAvailable() const + { + return expectedResult.bytesAvailable() + QNetworkReply::bytesAvailable(); + } + + void close() + { + expectedResult.close(); + } + + qint64 readData(char *data, qint64 maxSize) + { + return expectedResult.read(data, maxSize); + } + + void abort() + { + } + +private slots: + void sendSuggestions() + { + // Publish result + setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("text/html")); + setHeader(QNetworkRequest::ContentLengthHeader, expectedResult.bytesAvailable()); + setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200); + setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, QByteArray("Ok")); + + emit metaDataChanged(); + emit readyRead(); + emit downloadProgress(expectedResult.size(), expectedResult.size()); + emit finished(); + } + +private: + QFile expectedResult; +}; + +class SuggestionsTestNetworkAccessManager : public QNetworkAccessManager +{ +public: + SuggestionsTestNetworkAccessManager(QObject *parent = 0) + : QNetworkAccessManager(parent) + { + } + + QNetworkRequest lastRequest; + Operation lastOperation; + bool lastOutgoingData; + +protected: + QNetworkReply *createRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, QIODevice *outgoingData = 0) + { + lastOperation = operation; + lastRequest = request; + lastOutgoingData = (bool)outgoingData; + + return new SuggestionsTestNetworkReply(request, 0); + } +}; + +class Delegate : public OpenSearchEngineDelegate +{ + public: + Delegate() + : OpenSearchEngineDelegate() + , callsCount(0) + { + } + + ~Delegate() + { + } + + void performSearchRequest(const QNetworkRequest &request, + QNetworkAccessManager::Operation operation, + const QByteArray &data) + { + ++callsCount; + lastRequest = request; + lastOperation = operation; + lastData = data; + } + + QNetworkRequest lastRequest; + QNetworkAccessManager::Operation lastOperation; + QByteArray lastData; + int callsCount; +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_OpenSearchEngine::initTestCase() +{ + QCoreApplication::setApplicationName("tst_opensearchengine"); +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_OpenSearchEngine::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_OpenSearchEngine::init() +{ +} + +// This will be called after every test function. +void tst_OpenSearchEngine::cleanup() +{ +} + +void tst_OpenSearchEngine::opensearchengine_data() +{ +} + +void tst_OpenSearchEngine::opensearchengine() +{ + SubOpenSearchEngine engine; + QCOMPARE(engine.description(), QString()); + QCOMPARE(engine.image(), QImage()); + QCOMPARE(engine.imageUrl(), QString()); + QCOMPARE(engine.isValid(), false); + QCOMPARE(engine.name(), QString()); + OpenSearchEngine other; + QCOMPARE(engine.operator<(other), false); + QCOMPARE(engine.operator==(other), true); + QCOMPARE(engine.providesSuggestions(), false); + engine.requestSuggestions(QString()); + QCOMPARE(engine.searchParameters(), QList()); + QCOMPARE(engine.searchUrl(QString()), QUrl()); + QCOMPARE(engine.searchUrlTemplate(), QString()); + engine.setDescription(QString()); + engine.setImage(QImage()); + engine.setImageUrl(QString()); + engine.setName(QString()); + engine.setSearchParameters(QList()); + engine.setSearchUrlTemplate(QString()); + engine.setSuggestionsParameters(QList()); + engine.setSuggestionsUrlTemplate(QString()); + QCOMPARE(engine.suggestionsParameters(), QList()); + QCOMPARE(engine.suggestionsUrl(QString()), QUrl()); + QCOMPARE(engine.suggestionsUrlTemplate(), QString()); + engine.call_imageChanged(); + engine.call_loadImage(); + QVERIFY(!engine.networkAccessManager()); + QNetworkAccessManager manager; + engine.setNetworkAccessManager(&manager); + QCOMPARE(engine.networkAccessManager(), &manager); + QCOMPARE(engine.call_parseTemplate(QString(), QString()), QString()); + engine.call_suggestions(QStringList()); +} + +void tst_OpenSearchEngine::description_data() +{ + QTest::addColumn("description"); + QTest::newRow("null") << QString(); + QTest::newRow("foo") << QString("foo"); +} + +// public QString description() const +void tst_OpenSearchEngine::description() +{ + QFETCH(QString, description); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setDescription(description); + QCOMPARE(engine.description(), description); + QCOMPARE(engine.property("description").toString(), description); + engine.setProperty("description", QString()); + QCOMPARE(engine.property("description").toString(), QString()); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +// public QImage image() const +void tst_OpenSearchEngine::image() +{ + SubOpenSearchEngine engine; + + QNetworkAccessManager manager; + engine.setNetworkAccessManager(&manager); + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + QBuffer imageBuffer; + imageBuffer.open(QBuffer::ReadWrite); + QPixmap image(1, 1); + image.fill(); + image.save(&imageBuffer, "PNG"); + QString imageUrl = QString("data:image/png;base64,").append(imageBuffer.buffer().toBase64()); + engine.setImageUrl(imageUrl); + QCOMPARE(engine.image(), QImage()); + + QTRY_COMPARE(spy0.count(), 1); + QCOMPARE(spy1.count(), 0); + QVERIFY(engine.image() != QImage()); + + SubOpenSearchEngine engine2; + QSignalSpy spy2(&engine2, SIGNAL(imageChanged())); + + QVERIFY(engine2.imageUrl().isEmpty()); + engine2.setImage(engine.image()); + QCOMPARE(engine2.imageUrl(), imageUrl); + + QCOMPARE(spy2.count(), 1); +} + +void tst_OpenSearchEngine::imageUrl_data() +{ + QTest::addColumn("imageUrl"); + QTest::newRow("null") << QString(); + QTest::newRow("foo") << QString("foo"); +} + +// public QString imageUrl() const +void tst_OpenSearchEngine::imageUrl() +{ + QFETCH(QString, imageUrl); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setImageUrl(imageUrl); + QCOMPARE(engine.imageUrl(), imageUrl); + QCOMPARE(engine.property("imageUrl").toString(), imageUrl); + engine.setProperty("imageUrl", QString()); + QCOMPARE(engine.property("imageUrl").toString(), QString()); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +void tst_OpenSearchEngine::isValid_data() +{ + QTest::addColumn("name"); + QTest::addColumn("searchUrlTemplate"); + QTest::addColumn("isValid"); + QTest::newRow("false-0") << QString() << QString() << false; + QTest::newRow("false-1") << QString() << QString("x") << false; + QTest::newRow("false-2") << QString("x") << QString() << false; + QTest::newRow("true") << QString("x") << QString("y") << true; +} + +// public bool isValid() const +void tst_OpenSearchEngine::isValid() +{ + QFETCH(QString, name); + QFETCH(QString, searchUrlTemplate); + QFETCH(bool, isValid); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setName(name); + engine.setSearchUrlTemplate(searchUrlTemplate); + QCOMPARE(engine.isValid(), isValid); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +void tst_OpenSearchEngine::name_data() +{ + QTest::addColumn("name"); + QTest::newRow("null") << QString(); + QTest::newRow("foo") << QString("foo"); +} + +// public QString name() const +void tst_OpenSearchEngine::name() +{ + QFETCH(QString, name); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setName(name); + QCOMPARE(engine.name(), name); + QCOMPARE(engine.property("name").toString(), name); + engine.setProperty("name", QString()); + QCOMPARE(engine.property("name").toString(), QString()); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +// public bool operator<(OpenSearchEngine const &other) const +void tst_OpenSearchEngine::operatorlessthan() +{ + SubOpenSearchEngine engine1; + engine1.setName("a"); + SubOpenSearchEngine engine2; + engine2.setName("b"); + + QVERIFY(engine1 < engine2); +} + +Q_DECLARE_METATYPE(Parameters) +void tst_OpenSearchEngine::operatorequal_data() +{ + QTest::addColumn("name"); + QTest::addColumn("description"); + QTest::addColumn("imageUrl"); + QTest::addColumn("searchUrlTemplate"); + QTest::addColumn("suggestionsUrlTemplate"); + QTest::addColumn("searchParameters"); + QTest::addColumn("suggestionsParameters"); + QTest::addColumn("operatorequal"); + QTest::newRow("null") << QString() << QString() << QString() << QString() << QString() + << Parameters() << Parameters() + << true; + QTest::newRow("name") << QString("x") << QString() << QString() << QString() << QString() + << Parameters() << Parameters() + << false; + QTest::newRow("description") << QString() << QString("x") << QString() << QString() << QString() + << Parameters() << Parameters() + << false; + QTest::newRow("imageUrl") << QString() << QString() << QString("x") << QString() << QString() + << Parameters() << Parameters() + << false; + QTest::newRow("parameters") << QString() << QString() << QString() << QString() << QString() + << (Parameters() << Parameter("a", "b")) << Parameters() + << false; +} + +// public bool operator==(OpenSearchEngine const &other) const +void tst_OpenSearchEngine::operatorequal() +{ + QFETCH(QString, name); + QFETCH(QString, description); + QFETCH(QString, imageUrl); + QFETCH(QString, searchUrlTemplate); + QFETCH(QString, suggestionsUrlTemplate); + QFETCH(Parameters, searchParameters); + QFETCH(Parameters, suggestionsParameters); + QFETCH(bool, operatorequal); + + SubOpenSearchEngine engine; + SubOpenSearchEngine other; + other.setName(name); + other.setDescription(description); + other.setImageUrl(imageUrl); + other.setSearchUrlTemplate(searchUrlTemplate); + other.setSuggestionsUrlTemplate(suggestionsUrlTemplate); + other.setSearchParameters(searchParameters); + other.setSuggestionsParameters(suggestionsParameters); + + QCOMPARE(engine.operator==(other), operatorequal); +} + +void tst_OpenSearchEngine::providesSuggestions_data() +{ + QTest::addColumn("suggestionsUrlTemplate"); + QTest::addColumn("providesSuggestions"); + QTest::newRow("false") << QString() << false; + QTest::newRow("true") << QString("foo") << true; +} + +// public bool providesSuggestions() const +void tst_OpenSearchEngine::providesSuggestions() +{ + QFETCH(QString, suggestionsUrlTemplate); + QFETCH(bool, providesSuggestions); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setSuggestionsUrlTemplate(suggestionsUrlTemplate); + QCOMPARE(engine.providesSuggestions(), providesSuggestions); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +void tst_OpenSearchEngine::requestSuggestions_data() +{ + QTest::addColumn("searchTerm"); + QTest::addColumn("method"); + QTest::addColumn("lastOperation"); + QTest::newRow("null") << QString() << QString() << QNetworkAccessManager::GetOperation; + QTest::newRow("foo") << QString("foo") << QString("get") << QNetworkAccessManager::GetOperation; + QTest::newRow("bar") << QString("bar") << QString("post") << QNetworkAccessManager::PostOperation; + QTest::newRow("baz") << QString("baz") << QString("put") << QNetworkAccessManager::GetOperation; +} + +Q_DECLARE_METATYPE(QNetworkAccessManager::Operation) +// public void requestSuggestions(QString const &searchTerm) +void tst_OpenSearchEngine::requestSuggestions() +{ + QFETCH(QString, searchTerm); + QFETCH(QString, method); + QFETCH(QNetworkAccessManager::Operation, lastOperation); + + SuggestionsTestNetworkAccessManager manager; + SubOpenSearchEngine engine; + engine.setNetworkAccessManager(&manager); + engine.setSuggestionsMethod(method); + engine.setSuggestionsUrlTemplate("http://foobar.baz"); + engine.setSuggestionsParameters(Parameters() << Parameter("a", "b")); + + QVERIFY(engine.providesSuggestions()); + + QSignalSpy spy(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.requestSuggestions(searchTerm); + + if (searchTerm.isEmpty()) { + QTest::qWait(200); + QCOMPARE(spy.count(), 0); + } else { + QTRY_COMPARE(spy.count(), 1); + + QStringList suggestions; + suggestions << "sears" << "search engines" << "search engine" << "search" << "sears.com" << "seattle times"; + QCOMPARE(spy.at(0).at(0).toStringList(), suggestions); + + QCOMPARE(manager.lastOperation, lastOperation); + QCOMPARE(manager.lastOutgoingData, lastOperation == QNetworkAccessManager::PostOperation); + } +} + +void tst_OpenSearchEngine::requestSuggestionsCrash() +{ + SuggestionsTestNetworkAccessManager manager; + SubOpenSearchEngine engine; + engine.setNetworkAccessManager(&manager); + engine.setSuggestionsUrlTemplate("http://foobar.baz"); + + QVERIFY(engine.providesSuggestions()); + + QSignalSpy spy(&engine, SIGNAL(suggestions(QStringList const&))); + + QStringList colors = QColor::colorNames(); + + for (int i = 0; i < colors.count(); ++i) + engine.requestSuggestions(colors.at(i)); + + QTRY_COMPARE(spy.count(), 1); + + QStringList suggestions; + suggestions << "sears" << "search engines" << "search engine" << "search" << "sears.com" << "seattle times"; + QCOMPARE(spy.at(0).at(0).toStringList(), suggestions); +} + +void tst_OpenSearchEngine::searchParameters_data() +{ + QTest::addColumn("searchParameters"); + QTest::newRow("null") << QList(); + QTest::newRow("something") << (Parameters() << Parameter("a", "b")); +} + +// public QList searchParameters() const +void tst_OpenSearchEngine::searchParameters() +{ + QFETCH(Parameters, searchParameters); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setSearchParameters(searchParameters); + QCOMPARE(engine.searchParameters(), searchParameters); + QCOMPARE(qvariant_cast(engine.property("searchParameters")), searchParameters); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +void tst_OpenSearchEngine::searchUrl_data() +{ + QTest::addColumn("searchTerm"); + QTest::addColumn("searchUrlTemplate"); + QTest::addColumn("parameters"); + QTest::addColumn("searchUrl"); + QTest::newRow("null") << QString() << QString() << Parameters() << QUrl(); + QTest::newRow("foo") << QString("foo") << QString("http://foobar.baz/?q={searchTerms}") + << Parameters() << QUrl(QString("http://foobar.baz/?q=foo")); + QTest::newRow("empty") << QString() << QString("http://foobar.baz/?q={searchTerms}") + << Parameters() << QUrl(QString("http://foobar.baz/?q=")); + QTest::newRow("parameters") << QString("baz") << QString("http://foobar.baz/?q={searchTerms}") + << (Parameters() << Parameter("abc", "{searchTerms}") << Parameter("x", "yz")) + << QUrl(QString("http://foobar.baz/?q=baz&abc=baz&x=yz")); +} + +// public QUrl searchUrl(QString const &searchTerm) const +void tst_OpenSearchEngine::searchUrl() +{ + QFETCH(QString, searchTerm); + QFETCH(QString, searchUrlTemplate); + QFETCH(Parameters, parameters); + QFETCH(QUrl, searchUrl); + + SubOpenSearchEngine engine; + engine.setSearchParameters(parameters); + engine.setSearchUrlTemplate(searchUrlTemplate); + + QCOMPARE(engine.searchUrl(searchTerm), searchUrl); +} + +void tst_OpenSearchEngine::searchUrlTemplate_data() +{ + QTest::addColumn("searchUrlTemplate"); + QTest::newRow("null") << QString(); + QTest::newRow("foo") << QString("foo"); +} + +// public QString searchUrlTemplate() const +void tst_OpenSearchEngine::searchUrlTemplate() +{ + QFETCH(QString, searchUrlTemplate); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setSearchUrlTemplate(searchUrlTemplate); + QCOMPARE(engine.property("searchUrlTemplate").toString(), searchUrlTemplate); + engine.setProperty("searchUrlTemplate", QString()); + QCOMPARE(engine.property("searchUrlTemplate").toString(), QString()); + engine.setProperty("searchUrlTemplate", searchUrlTemplate); + QCOMPARE(engine.searchUrlTemplate(), searchUrlTemplate); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +void tst_OpenSearchEngine::suggestionsParameters_data() +{ + QTest::addColumn("suggestionsParameters"); + QTest::newRow("null") << QList(); + QTest::newRow("something") << (Parameters() << Parameter("a", "b")); +} + +// public QList suggestionsParameters() const +void tst_OpenSearchEngine::suggestionsParameters() +{ + QFETCH(Parameters, suggestionsParameters); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setSuggestionsParameters(suggestionsParameters); + QCOMPARE(engine.suggestionsParameters(), suggestionsParameters); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +void tst_OpenSearchEngine::suggestionsUrl_data() +{ + QTest::addColumn("searchTerm"); + QTest::addColumn("suggestionsUrlTemplate"); + QTest::addColumn("parameters"); + QTest::addColumn("suggestionsUrl"); + QTest::newRow("null") << QString() << QString() << Parameters() << QUrl(); + QTest::newRow("foo") << QString("foo") << QString("http://foobar.baz/?q={searchTerms}") + << Parameters() << QUrl(QString("http://foobar.baz/?q=foo")); + QTest::newRow("empty") << QString() << QString("http://foobar.baz/?q={searchTerms}") + << Parameters() << QUrl(QString("http://foobar.baz/?q=")); + QTest::newRow("parameters") << QString("baz") << QString("http://foobar.baz/?q={searchTerms}") + << (Parameters() << Parameter("a", "bc")) + << QUrl(QString("http://foobar.baz/?q=baz&a=bc")); +} + +// public QUrl suggestionsUrl(QString const &searchTerm) const +void tst_OpenSearchEngine::suggestionsUrl() +{ + QFETCH(QString, searchTerm); + QFETCH(QString, suggestionsUrlTemplate); + QFETCH(Parameters, parameters); + QFETCH(QUrl, suggestionsUrl); + + SubOpenSearchEngine engine; + engine.setSuggestionsParameters(parameters); + engine.setSuggestionsUrlTemplate(suggestionsUrlTemplate); + + QCOMPARE(engine.suggestionsUrl(searchTerm), suggestionsUrl); +} + +void tst_OpenSearchEngine::suggestionsUrlTemplate_data() +{ + QTest::addColumn("suggestionsUrlTemplate"); + QTest::newRow("null") << QString(); + QTest::newRow("foo") << QString("foo"); +} + +// public QString suggestionsUrlTemplate() const +void tst_OpenSearchEngine::suggestionsUrlTemplate() +{ + QFETCH(QString, suggestionsUrlTemplate); + + SubOpenSearchEngine engine; + + QSignalSpy spy0(&engine, SIGNAL(imageChanged())); + QSignalSpy spy1(&engine, SIGNAL(suggestions(QStringList const&))); + + engine.setSuggestionsUrlTemplate(suggestionsUrlTemplate); + QCOMPARE(engine.suggestionsUrlTemplate(), suggestionsUrlTemplate); + + QCOMPARE(spy0.count(), 0); + QCOMPARE(spy1.count(), 0); +} + +void tst_OpenSearchEngine::parseTemplate_data() +{ + QString lang = QLocale().name().replace(QLatin1Char('_'), QLatin1Char('-')); + + QTest::addColumn("searchTerm"); + QTest::addColumn("searchTemplate"); + QTest::addColumn("parseTemplate"); + QTest::addColumn("valid"); + QTest::newRow("null") << QString() << QString() << QString() << false; + QTest::newRow("foo") << QString("foo") << QString("http://foobar.baz/?q={searchTerms}") + << QString("http://foobar.baz/?q=foo") << true; + QTest::newRow("allParameters") << QString("bar") + << QString("http://foobar.baz/?st={searchTerms}&c={count}" + "&si={startIndex}&sp={startPage}&l={language}" + "&ie={inputEncoding}&oe={outputEncoding}") + << QString("http://foobar.baz/?st=bar&c=20&si=0&" + "sp=0&l=%1&ie=UTF-8&oe=UTF-8").arg(lang) + << true; + QTest::newRow("tricky") << QString("{count}") << QString("http://foobar.baz/q={searchTerms}&count={count}") + << QString("http://foobar.baz/q=%7Bcount%7D&count=20") << true; + QTest::newRow("multiple") << QString("abc") << QString("http://foobar.baz/?q={searchTerms}&x={searchTerms}") + << QString("http://foobar.baz/?q=abc&x=abc") << true; + QTest::newRow("referrer") << QString("foo") + << QString("http://foobar.baz/?q={searchTerms}&a={source}&b={ref:source}&c={referrer:source?}") + << QString("http://foobar.baz/?q=foo&a=tst_opensearchengine" + "&b=tst_opensearchengine&c=tst_opensearchengine") + << true; + QTest::newRow("inputEncoding") << QString("c++") << QString("http://foobar.baz/?q={searchTerms}") + << QString("http://foobar.baz/?q=c%2B%2B") << true; +} + +// protected QString parseTemplate(QString const &searchTerm, QString const &searchTemplate) const +void tst_OpenSearchEngine::parseTemplate() +{ + QFETCH(QString, searchTerm); + QFETCH(QString, searchTemplate); + QFETCH(QString, parseTemplate); + QFETCH(bool, valid); + + SubOpenSearchEngine engine; + QString url = engine.call_parseTemplate(searchTerm, searchTemplate); + QCOMPARE(url, parseTemplate); + QCOMPARE(QUrl(url).isValid(), valid); +} + +void tst_OpenSearchEngine::languageCodes_data() +{ + QTest::addColumn("languageCode"); + QTest::addColumn("url"); + + QTest::newRow("es") << QString("es") << QString("http://foobar.baz/?l=es-ES"); + QTest::newRow("pt_BR") << QString("pt_BR") << QString("http://foobar.baz/?l=pt-BR"); +} + +void tst_OpenSearchEngine::languageCodes() +{ + QFETCH(QString, languageCode); + QFETCH(QString, url); + + QLocale::setDefault(QLocale(languageCode)); + + SubOpenSearchEngine engine; + QCOMPARE(engine.call_parseTemplate(QString("foo"), QString("http://foobar.baz/?l={language}")), url); +} + +void tst_OpenSearchEngine::requestMethods() +{ + SubOpenSearchEngine engine; + + QCOMPARE(engine.searchMethod(), QString("get")); + QCOMPARE(engine.suggestionsMethod(), QString("get")); + + engine.setSearchMethod("post"); + QCOMPARE(engine.searchMethod(), QString("post")); + QCOMPARE(engine.suggestionsMethod(), QString("get")); + + engine.setSearchMethod("get"); + QCOMPARE(engine.searchMethod(), QString("get")); + QCOMPARE(engine.suggestionsMethod(), QString("get")); + + engine.setSuggestionsMethod("PoSt"); + QCOMPARE(engine.searchMethod(), QString("get")); + QCOMPARE(engine.suggestionsMethod(), QString("post")); + + engine.setSearchMethod("foo"); + QCOMPARE(engine.searchMethod(), QString("get")); + QCOMPARE(engine.suggestionsMethod(), QString("post")); + + engine.setSuggestionsMethod("bar"); + QCOMPARE(engine.searchMethod(), QString("get")); + QCOMPARE(engine.suggestionsMethod(), QString("post")); +} + +void tst_OpenSearchEngine::delegate() +{ + SubOpenSearchEngine engine; + engine.setName(QString("foo")); + engine.setDescription(QString("bar")); + engine.setSearchUrlTemplate(QString("http://foobar.baz/?q={searchTerms}")); + + QCOMPARE(engine.delegate(), (Delegate*)0); + engine.setDelegate(0); + QCOMPARE(engine.delegate(), (Delegate*)0); + engine.requestSearchResults(QString("baz")); + + Delegate delegate; + engine.setDelegate(&delegate); + QCOMPARE(engine.delegate(), &delegate); + engine.requestSearchResults(QString("baz")); + + QCOMPARE(delegate.callsCount, 1); + QCOMPARE(delegate.lastOperation, QNetworkAccessManager::GetOperation); + QCOMPARE(delegate.lastData, QByteArray()); + QNetworkRequest request(QUrl(engine.call_parseTemplate(QString("baz"), engine.searchUrlTemplate()))); + QCOMPARE(delegate.lastRequest, request); + QVERIFY(delegate.lastRequest.url().hasQueryItem("q")); + QCOMPARE(delegate.lastRequest.url().queryItemValue("q"), QString("baz")); + + engine.setSearchParameters(Parameters() << Parameter("a", "b") << Parameter("b", "c")); + engine.requestSearchResults(QString("baz")); + + QCOMPARE(delegate.callsCount, 2); + QCOMPARE(delegate.lastOperation, QNetworkAccessManager::GetOperation); + QCOMPARE(delegate.lastData, QByteArray()); + + QVERIFY(delegate.lastRequest.url().hasQueryItem("a")); + QCOMPARE(delegate.lastRequest.url().queryItemValue("a"), QString("b")); + QVERIFY(delegate.lastRequest.url().hasQueryItem("b")); + QCOMPARE(delegate.lastRequest.url().queryItemValue("b"), QString("c")); + QVERIFY(delegate.lastRequest.url().hasQueryItem("q")); + QCOMPARE(delegate.lastRequest.url().queryItemValue("q"), QString("baz")); + + QUrl url(engine.call_parseTemplate(QString("baz"), engine.searchUrlTemplate())); + QCOMPARE(delegate.lastRequest.url().toString(QUrl::RemoveQuery), url.toString(QUrl::RemoveQuery)); + + engine.setSearchMethod(QString("post")); + engine.requestSearchResults(QString("baz")); + + QCOMPARE(delegate.callsCount, 3); + QCOMPARE(delegate.lastOperation, QNetworkAccessManager::PostOperation); + request = QNetworkRequest(QUrl(engine.call_parseTemplate(QString("baz"), engine.searchUrlTemplate()))); + QCOMPARE(delegate.lastRequest, request); + QVERIFY(delegate.lastRequest.url().hasQueryItem("q")); + QCOMPARE(delegate.lastRequest.url().queryItemValue("q"), QString("baz")); + + QVERIFY(!delegate.lastData.isEmpty()); + QStringList query = QString(delegate.lastData).split('&'); + QCOMPARE(query.count(), 2); + QCOMPARE(query, QStringList() << "a=b" << "b=c"); +} + +QTEST_MAIN(tst_OpenSearchEngine) +#include "tst_opensearchengine.moc" + diff --git a/autotests/opensearchmanager/.gitignore b/autotests/opensearchmanager/.gitignore new file mode 100644 index 00000000..73667fbe --- /dev/null +++ b/autotests/opensearchmanager/.gitignore @@ -0,0 +1 @@ +opensearchmanager diff --git a/autotests/opensearchmanager/opensearchmanager.pro b/autotests/opensearchmanager/opensearchmanager.pro new file mode 100644 index 00000000..8ba76ebd --- /dev/null +++ b/autotests/opensearchmanager/opensearchmanager.pro @@ -0,0 +1,9 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../autotests.pri) + +SOURCES += \ + tst_opensearchmanager.cpp \ No newline at end of file diff --git a/autotests/opensearchmanager/tst_opensearchmanager.cpp b/autotests/opensearchmanager/tst_opensearchmanager.cpp new file mode 100644 index 00000000..bf56cc63 --- /dev/null +++ b/autotests/opensearchmanager/tst_opensearchmanager.cpp @@ -0,0 +1,343 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include "qtest_arora.h" + +#include "opensearchengine.h" +#include "opensearchmanager.h" + +class tst_OpenSearchManager : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void addRemoveEngine_data(); + void addRemoveEngine(); + void setCurrentEngine_data(); + void setCurrentEngine(); + void generateEngineFileName_data(); + void generateEngineFileName(); + void restoreDefaults(); + void keywords(); + void convertKeywordSearchToUrl(); + void convertKeywordSearchToUrl_data(); +}; + +class SubOpenSearchManager : public OpenSearchManager +{ +public: + QString generateEngineFileName(const QString &engineName) + { + return OpenSearchManager::generateEngineFileName(engineName); + } + + static int defaultCount() + { + return QDir(":/searchengines/").count(); + } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_OpenSearchManager::initTestCase() +{ + QCoreApplication::setApplicationName("opensearchtest"); + + SubOpenSearchManager manager; + foreach (const QString &name, manager.allEnginesNames()) + manager.removeEngine(name); + QCOMPARE(manager.enginesCount(), 1); +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_OpenSearchManager::cleanupTestCase() +{ + SubOpenSearchManager manager; + QCOMPARE(manager.enginesCount(), 1); +} + +// This will be called before each test function is executed. +void tst_OpenSearchManager::init() +{ + SubOpenSearchManager manager; + QCOMPARE(manager.enginesCount(), 1); +} + +// This will be called after every test function. +void tst_OpenSearchManager::cleanup() +{ + SubOpenSearchManager manager; + foreach (const QString &name, manager.allEnginesNames()) + manager.removeEngine(name); + QCOMPARE(manager.enginesCount(), 1); +} + +void tst_OpenSearchManager::addRemoveEngine_data() +{ + QTest::addColumn("name"); + QTest::addColumn("description"); + QTest::addColumn("searchUrlTemplate"); + QTest::addColumn("valid"); + + QTest::newRow("valid") << "Foo" << "Bar" << "http://foobaz.bar" << true; + QTest::newRow("invalid") << "Baz" << "Foo" << "" << false; +} + +void tst_OpenSearchManager::addRemoveEngine() +{ + QFETCH(QString, name); + QFETCH(QString, description); + QFETCH(QString, searchUrlTemplate); + QFETCH(bool, valid); + + SubOpenSearchManager manager; + + QSignalSpy signalSpy(&manager, SIGNAL(changed())); + + OpenSearchEngine *engine = new OpenSearchEngine(); + engine->setName(name); + engine->setDescription(description); + engine->setSearchUrlTemplate(searchUrlTemplate); + + QCOMPARE(manager.enginesCount(), 1); + QVERIFY(!manager.engineExists(name)); + + bool result = manager.addEngine(engine); + + QCOMPARE(result, valid); + QCOMPARE(manager.enginesCount(), (valid ? 2 : 1)); + QCOMPARE(manager.engineExists(name), valid); + QCOMPARE(signalSpy.count(), (valid ? 1 : 0)); + + manager.removeEngine(engine->name()); + + QCOMPARE(manager.enginesCount(), 1); + QVERIFY(!manager.engineExists(name)); + QCOMPARE(signalSpy.count(), (valid ? 2 : 0)); +} + +void tst_OpenSearchManager::setCurrentEngine_data() +{ + QTest::addColumn("name"); + QTest::addColumn("description"); + QTest::addColumn("searchUrlTemplate"); + QTest::addColumn("valid"); + + QTest::newRow("valid") << "Foo" << "Bar" << "http://foobaz.bar" << true; + QTest::newRow("invalid") << "Baz" << "Foo" << "" << false; +} + +void tst_OpenSearchManager::setCurrentEngine() +{ + QFETCH(QString, name); + QFETCH(QString, description); + QFETCH(QString, searchUrlTemplate); + QFETCH(bool, valid); + + SubOpenSearchManager manager; + + QCOMPARE(manager.enginesCount(), 1); + + QString oldCurrentEngineName = manager.currentEngineName(); + OpenSearchEngine *oldCurrentEngine = manager.currentEngine(); + + QSignalSpy signalSpy(&manager, SIGNAL(currentEngineChanged())); + + OpenSearchEngine *engine = new OpenSearchEngine(); + engine->setName(name); + engine->setDescription(description); + engine->setSearchUrlTemplate(searchUrlTemplate); + + bool result = manager.addEngine(engine); + QCOMPARE(result, valid); + + manager.setCurrentEngineName(name); + QCOMPARE(manager.currentEngineName(), (valid ? name : oldCurrentEngineName)); + QCOMPARE(*manager.currentEngine(), (valid ? *engine : *oldCurrentEngine)); + QCOMPARE(signalSpy.count(), (valid ? 1 : 0)); + + manager.removeEngine(engine->name()); + QCOMPARE(signalSpy.count(), (valid ? 2 : 0)); +} + +void tst_OpenSearchManager::generateEngineFileName_data() +{ + QTest::addColumn("name"); + QTest::addColumn("fileName"); + + QTest::newRow("simple") << "FooBar" << "FooBar.xml"; + QTest::newRow("with-spaces") << "Foo Bar" << "Foo_Bar.xml"; + QTest::newRow("with-special-chars") << ":Foo&Bar*Baz-" << "FooBarBaz.xml"; + QTest::newRow("with-special-chars-and-spaces") << ": Foo & Bar -" << "_Foo__Bar_.xml"; +} + +void tst_OpenSearchManager::generateEngineFileName() +{ + QFETCH(QString, name); + QFETCH(QString, fileName); + + SubOpenSearchManager manager; + + QCOMPARE(manager.generateEngineFileName(name), fileName); +} + +void tst_OpenSearchManager::restoreDefaults() +{ + SubOpenSearchManager manager; + + QCOMPARE(manager.enginesCount(), 1); + manager.restoreDefaults(); + QCOMPARE(manager.enginesCount(), manager.defaultCount()); + + foreach (const QString &name, manager.allEnginesNames()) + manager.removeEngine(name); + + // Never let the manager have no engines. + QCOMPARE(manager.enginesCount(), 1); + + OpenSearchEngine *engine = new OpenSearchEngine(); + engine->setName("Foobarbaz"); + engine->setSearchUrlTemplate("http://foobarbaz.baz"); + + manager.addEngine(engine); + manager.restoreDefaults(); + QCOMPARE(manager.enginesCount(), manager.defaultCount() + 1); + + manager.removeEngine(engine->name()); +} + +void tst_OpenSearchManager::keywords() +{ + { + SubOpenSearchManager manager; + + QVERIFY(!manager.engineForKeyword("foo")); + QVERIFY(!manager.engineForKeyword(QString())); + + manager.setEngineForKeyword("foo", 0); + manager.setEngineForKeyword(QString(), 0); + QVERIFY(!manager.engineForKeyword("foo")); + QVERIFY(!manager.engineForKeyword(QString())); + QCOMPARE(manager.keywordsForEngine(0), QStringList()); + + manager.setKeywordsForEngine(0, QStringList() << "foo"); + QCOMPARE(manager.keywordsForEngine(0), QStringList()); + + manager.restoreDefaults(); + + OpenSearchEngine *engine1 = manager.engine(manager.allEnginesNames().at(0)); + OpenSearchEngine *engine2 = manager.engine(manager.allEnginesNames().at(1)); + + QCOMPARE(manager.keywordsForEngine(engine1), QStringList()); + QCOMPARE(manager.keywordsForEngine(engine2), QStringList()); + + manager.setEngineForKeyword("foo", engine1); + manager.setEngineForKeyword("bar", engine1); + manager.setEngineForKeyword("baz", engine2); + + QCOMPARE(manager.engineForKeyword("foo"), engine1); + QCOMPARE(manager.engineForKeyword("bar"), engine1); + QCOMPARE(manager.engineForKeyword("baz"), engine2); + + QCOMPARE(manager.keywordsForEngine(engine1), QStringList() << "foo" << "bar"); + QCOMPARE(manager.keywordsForEngine(engine2), QStringList() << "baz"); + + manager.setKeywordsForEngine(engine1, QStringList() << "baz"); + manager.setKeywordsForEngine(engine2, QStringList() << "foo" << "bar"); + + QCOMPARE(manager.engineForKeyword("foo"), engine2); + QCOMPARE(manager.engineForKeyword("bar"), engine2); + QCOMPARE(manager.engineForKeyword("baz"), engine1); + + QCOMPARE(manager.keywordsForEngine(engine2), QStringList() << "foo" << "bar"); + QCOMPARE(manager.keywordsForEngine(engine1), QStringList() << "baz"); + } + + { + SubOpenSearchManager manager; + + manager.restoreDefaults(); + + OpenSearchEngine *engine1 = manager.engine(manager.allEnginesNames().at(0)); + OpenSearchEngine *engine2 = manager.engine(manager.allEnginesNames().at(1)); + + QCOMPARE(*manager.engineForKeyword("foo"), *engine2); + QCOMPARE(*manager.engineForKeyword("bar"), *engine2); + QCOMPARE(*manager.engineForKeyword("baz"), *engine1); + + QCOMPARE(manager.keywordsForEngine(engine2), QStringList() << "foo" << "bar"); + QCOMPARE(manager.keywordsForEngine(engine1), QStringList() << "baz"); + + manager.setEngineForKeyword("foo", 0); + + QVERIFY(!manager.engineForKeyword("foo")); + QCOMPARE(*manager.engineForKeyword("bar"), *engine2); + QCOMPARE(*manager.engineForKeyword("baz"), *engine1); + + QCOMPARE(manager.keywordsForEngine(engine2), QStringList() << "bar"); + QCOMPARE(manager.keywordsForEngine(engine1), QStringList() << "baz"); + + manager.setKeywordsForEngine(engine1, QStringList()); + manager.setKeywordsForEngine(engine2, QStringList()); + } +} + +void tst_OpenSearchManager::convertKeywordSearchToUrl_data() +{ + QTest::addColumn("string"); + QTest::addColumn("valid"); + + QTest::newRow("invalid-0") << "null" << false; + QTest::newRow("invalid-1") << "foo" << false; + QTest::newRow("invalid-2") << "bar" << false; + QTest::newRow("invalid-3") << "baz" << false; + QTest::newRow("invalid-4") << "foo " << false; + QTest::newRow("invalid-5") << "foobar" << false; + QTest::newRow("valid-0") << "foo searchstring" << true; +} + +void tst_OpenSearchManager::convertKeywordSearchToUrl() +{ + QFETCH(QString, string); + QFETCH(bool, valid); + + SubOpenSearchManager manager; + manager.restoreDefaults(); + OpenSearchEngine *engine1 = manager.engine(manager.allEnginesNames().at(0)); + manager.setEngineForKeyword("foo", engine1); + manager.setEngineForKeyword("bar", engine1); + OpenSearchEngine *engine2 = manager.engine(manager.allEnginesNames().at(1)); + manager.setEngineForKeyword("baz", engine2); + + QCOMPARE(manager.convertKeywordSearchToUrl(string).isValid(), valid); +} + +QTEST_MAIN(tst_OpenSearchManager) + +#include "tst_opensearchmanager.moc" + diff --git a/autotests/opensearchreader/.gitignore b/autotests/opensearchreader/.gitignore new file mode 100644 index 00000000..00956e3c --- /dev/null +++ b/autotests/opensearchreader/.gitignore @@ -0,0 +1 @@ +opensearchreader diff --git a/autotests/opensearchreader/opensearchreader.pro b/autotests/opensearchreader/opensearchreader.pro new file mode 100644 index 00000000..392567a3 --- /dev/null +++ b/autotests/opensearchreader/opensearchreader.pro @@ -0,0 +1,21 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../autotests.pri) + +SOURCES = \ + opensearchengine.cpp \ + opensearchreader.cpp \ + tst_opensearchreader.cpp + +HEADERS = \ + opensearchengine.h \ + opensearchreader.h + +FORMS = + +RESOURCES = \ + opensearchreader.qrc + diff --git a/autotests/opensearchreader/opensearchreader.qrc b/autotests/opensearchreader/opensearchreader.qrc new file mode 100644 index 00000000..a431f037 --- /dev/null +++ b/autotests/opensearchreader/opensearchreader.qrc @@ -0,0 +1,11 @@ + + + testfile1.xml + testfile2.xml + testfile3.xml + testfile4.xml + testfile5.xml + testfile6.xml + testfile7.xml + + diff --git a/autotests/opensearchreader/testfile1.xml b/autotests/opensearchreader/testfile1.xml new file mode 100644 index 00000000..ee1ed1c0 --- /dev/null +++ b/autotests/opensearchreader/testfile1.xml @@ -0,0 +1,10 @@ + + + Wikipedia (en) + Full text search in the English Wikipedia + + + + + http://en.wikipedia.org/favicon.ico + \ No newline at end of file diff --git a/autotests/opensearchreader/testfile2.xml b/autotests/opensearchreader/testfile2.xml new file mode 100644 index 00000000..0a620b4a --- /dev/null +++ b/autotests/opensearchreader/testfile2.xml @@ -0,0 +1,6 @@ + + + Wikipedia (en) + + http://en.wikipedia.org/favicon.ico + \ No newline at end of file diff --git a/autotests/opensearchreader/testfile3.xml b/autotests/opensearchreader/testfile3.xml new file mode 100644 index 00000000..c778e262 --- /dev/null +++ b/autotests/opensearchreader/testfile3.xml @@ -0,0 +1,12 @@ + + + GitHub + Search GitHub + + + + + + + + \ No newline at end of file diff --git a/autotests/opensearchreader/testfile4.xml b/autotests/opensearchreader/testfile4.xml new file mode 100644 index 00000000..9c484a21 --- /dev/null +++ b/autotests/opensearchreader/testfile4.xml @@ -0,0 +1,8 @@ + + + Google + Google Web Search + + + http://www.google.com/favicon.ico + \ No newline at end of file diff --git a/autotests/opensearchreader/testfile5.xml b/autotests/opensearchreader/testfile5.xml new file mode 100644 index 00000000..266e4b1f --- /dev/null +++ b/autotests/opensearchreader/testfile5.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/autotests/opensearchreader/testfile6.xml b/autotests/opensearchreader/testfile6.xml new file mode 100644 index 00000000..4495beb7 --- /dev/null +++ b/autotests/opensearchreader/testfile6.xml @@ -0,0 +1,5 @@ + + Google + Google Web Search + + \ No newline at end of file diff --git a/autotests/opensearchreader/testfile7.xml b/autotests/opensearchreader/testfile7.xml new file mode 100644 index 00000000..e69de29b diff --git a/autotests/opensearchreader/tst_opensearchreader.cpp b/autotests/opensearchreader/tst_opensearchreader.cpp new file mode 100644 index 00000000..21692a48 --- /dev/null +++ b/autotests/opensearchreader/tst_opensearchreader.cpp @@ -0,0 +1,147 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include "opensearchreader.h" +#include "opensearchengine.h" + +class tst_OpenSearchReader : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void read_data(); + void read(); +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_OpenSearchReader::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_OpenSearchReader::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_OpenSearchReader::init() +{ +} + +// This will be called after every test function. +void tst_OpenSearchReader::cleanup() +{ +} + +Q_DECLARE_METATYPE(OpenSearchEngine::Parameters) +void tst_OpenSearchReader::read_data() +{ + QTest::addColumn("fileName"); + QTest::addColumn("valid"); + QTest::addColumn("name"); + QTest::addColumn("description"); + QTest::addColumn("searchUrlTemplate"); + QTest::addColumn("suggestionsUrlTemplate"); + QTest::addColumn("imageUrl"); + QTest::addColumn("searchParameters"); + QTest::addColumn("suggestionsParameters"); + QTest::addColumn("searchMethod"); + QTest::addColumn("suggestionsMethod"); + + QTest::newRow("null") << QString(":/doesNotExist") << false << QString() << QString() << QString() << QString() + << QString() << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() << QString("get") << QString("get"); + + QTest::newRow("testfile1") << QString(":/testfile1.xml") << true << QString("Wikipedia (en)") + << QString("Full text search in the English Wikipedia") << QString("http://en.wikipedia.org/bar") + << QString("http://en.wikipedia.org/foo") << QString("http://en.wikipedia.org/favicon.ico") + << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() << QString("post") << QString("get"); + + QTest::newRow("testfile2") << QString(":/testfile2.xml") << false << QString("Wikipedia (en)") + << QString() << QString() << QString("http://en.wikipedia.org/foo") << QString("http://en.wikipedia.org/favicon.ico") + << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() << QString("get") << QString("get"); + + QTest::newRow("testfile3") << QString(":/testfile3.xml") << true << QString("GitHub") << QString("Search GitHub") + << QString("http://github.com/search") << QString("http://github.com/suggestions") << QString() + << (OpenSearchEngine::Parameters() << OpenSearchEngine::Parameter(QString("q"), QString("{searchTerms}")) + << OpenSearchEngine::Parameter(QString("b"), QString("foo"))) + << (OpenSearchEngine::Parameters() << OpenSearchEngine::Parameter(QString("bar"), QString("baz"))) + << QString("get") << QString("post"); + + QTest::newRow("testfile4") << QString(":/testfile4.xml") << true << QString("Google") << QString("Google Web Search") + << QString("http://www.google.com/search?bar") << QString("http://suggestqueries.google.com/complete/foo") + << QString("http://www.google.com/favicon.ico") << OpenSearchEngine::Parameters() + << OpenSearchEngine::Parameters() << QString("get") << QString("get"); + + QTest::newRow("testfile5") << QString(":/testfile5.xml") << false << QString() << QString() << QString() << QString() + << QString() << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() << QString("get") << QString("get"); + + QTest::newRow("testfile6") << QString(":/testfile6.xml") << false << QString() << QString() << QString() << QString() + << QString() << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() << QString("get") << QString("get"); + + QTest::newRow("testfile7") << QString(":/testfile7.xml") << false << QString() << QString() << QString() << QString() + << QString() << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() << QString("get") << QString("get"); +} + +void tst_OpenSearchReader::read() +{ + QFETCH(QString, fileName); + QFETCH(bool, valid); + QFETCH(QString, name); + QFETCH(QString, description); + QFETCH(QString, searchUrlTemplate); + QFETCH(QString, suggestionsUrlTemplate); + QFETCH(QString, imageUrl); + QFETCH(OpenSearchEngine::Parameters, searchParameters); + QFETCH(OpenSearchEngine::Parameters, suggestionsParameters); + QFETCH(QString, searchMethod); + QFETCH(QString, suggestionsMethod); + + QFile file(fileName); + file.open(QIODevice::ReadOnly); + OpenSearchReader reader; + OpenSearchEngine *engine = reader.read(&file); + + QCOMPARE(engine->isValid(), valid); + QCOMPARE(engine->name(), name); + QCOMPARE(engine->description(), description); + QCOMPARE(engine->searchUrlTemplate(), searchUrlTemplate); + QCOMPARE(engine->suggestionsUrlTemplate(), suggestionsUrlTemplate); + QCOMPARE(engine->searchParameters(), searchParameters); + QCOMPARE(engine->suggestionsParameters(), suggestionsParameters); + QCOMPARE(engine->imageUrl(), imageUrl); + QCOMPARE(engine->searchMethod(), searchMethod); + QCOMPARE(engine->suggestionsMethod(), suggestionsMethod); + + delete engine; +} + +QTEST_MAIN(tst_OpenSearchReader) + +#include "tst_opensearchreader.moc" + diff --git a/autotests/opensearchwriter/.gitignore b/autotests/opensearchwriter/.gitignore new file mode 100644 index 00000000..bf1390aa --- /dev/null +++ b/autotests/opensearchwriter/.gitignore @@ -0,0 +1 @@ +opensearchwriter diff --git a/autotests/opensearchwriter/opensearchwriter.pro b/autotests/opensearchwriter/opensearchwriter.pro new file mode 100644 index 00000000..13ffaff7 --- /dev/null +++ b/autotests/opensearchwriter/opensearchwriter.pro @@ -0,0 +1,21 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../autotests.pri) + +SOURCES = \ + opensearchengine.cpp \ + opensearchwriter.cpp \ + tst_opensearchwriter.cpp + +HEADERS = \ + opensearchengine.h \ + opensearchwriter.h + +FORMS = + +RESOURCES = \ + opensearchwriter.qrc + diff --git a/autotests/opensearchwriter/opensearchwriter.qrc b/autotests/opensearchwriter/opensearchwriter.qrc new file mode 100644 index 00000000..0c9fde03 --- /dev/null +++ b/autotests/opensearchwriter/opensearchwriter.qrc @@ -0,0 +1,7 @@ + + + testfile1.xml + testfile2.xml + testfile3.xml + + diff --git a/autotests/opensearchwriter/testfile1.xml b/autotests/opensearchwriter/testfile1.xml new file mode 100644 index 00000000..04c05a36 --- /dev/null +++ b/autotests/opensearchwriter/testfile1.xml @@ -0,0 +1,6 @@ + + + Foo Bar + Bar Foo + + diff --git a/autotests/opensearchwriter/testfile2.xml b/autotests/opensearchwriter/testfile2.xml new file mode 100644 index 00000000..9141cec1 --- /dev/null +++ b/autotests/opensearchwriter/testfile2.xml @@ -0,0 +1,7 @@ + + + Arora! + a cross platform web browser built using Qt and WebKit + + + diff --git a/autotests/opensearchwriter/testfile3.xml b/autotests/opensearchwriter/testfile3.xml new file mode 100644 index 00000000..058f5ea2 --- /dev/null +++ b/autotests/opensearchwriter/testfile3.xml @@ -0,0 +1,12 @@ + + + Foo Bar + Bar Foo + + + + + + + + diff --git a/autotests/opensearchwriter/tst_opensearchwriter.cpp b/autotests/opensearchwriter/tst_opensearchwriter.cpp new file mode 100644 index 00000000..26fc53be --- /dev/null +++ b/autotests/opensearchwriter/tst_opensearchwriter.cpp @@ -0,0 +1,131 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include "opensearchwriter.h" +#include "opensearchengine.h" + +class tst_OpenSearchWriter : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void write_data(); + void write(); +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_OpenSearchWriter::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_OpenSearchWriter::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_OpenSearchWriter::init() +{ +} + +// This will be called after every test function. +void tst_OpenSearchWriter::cleanup() +{ +} + +Q_DECLARE_METATYPE(OpenSearchEngine::Parameters) +void tst_OpenSearchWriter::write_data() +{ + QTest::addColumn("name"); + QTest::addColumn("description"); + QTest::addColumn("searchUrlTemplate"); + QTest::addColumn("suggestionsUrlTemplate"); + QTest::addColumn("imageUrl"); + QTest::addColumn("searchParameters"); + QTest::addColumn("suggestionsParameters"); + QTest::addColumn("searchMethod"); + QTest::addColumn("suggestionsMethod"); + QTest::addColumn("fileName"); + + QTest::newRow("testfile1") << QString("Foo Bar") << QString("Bar Foo") << QString("http://foobar.barfoo/search") << QString() + << QString() << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() + << QString() << QString("get") << QString(":/testfile1.xml"); + + QTest::newRow("testfile2") << QString("Arora!") << QString("a cross platform web browser built using Qt and WebKit") + << QString("http://foobar.barfoo/search") << QString("http://foobar.barfoo/suggest") << QString() + << OpenSearchEngine::Parameters() << OpenSearchEngine::Parameters() + << QString("get") << QString("post") << QString(":/testfile2.xml"); + + QTest::newRow("testile3") << QString("Foo Bar") << QString("Bar Foo") << QString("http://foobar.barfoo/search") + << QString("http://foobar.barfoo/suggest") << QString() + << (OpenSearchEngine::Parameters() << OpenSearchEngine::Parameter("q", "{searchTerms}") << OpenSearchEngine::Parameter("a", "foo")) + << (OpenSearchEngine::Parameters() << OpenSearchEngine::Parameter("q", "{searchTerms}")) + << QString("post") << QString("foo") << QString(":/testfile3.xml"); +} + +void tst_OpenSearchWriter::write() +{ + QFETCH(QString, name); + QFETCH(QString, description); + QFETCH(QString, searchUrlTemplate); + QFETCH(QString, suggestionsUrlTemplate); + QFETCH(QString, imageUrl); + QFETCH(OpenSearchEngine::Parameters, searchParameters); + QFETCH(OpenSearchEngine::Parameters, suggestionsParameters); + QFETCH(QString, searchMethod); + QFETCH(QString, suggestionsMethod); + QFETCH(QString, fileName); + + OpenSearchEngine engine; + OpenSearchWriter writer; + + engine.setName(name); + engine.setDescription(description); + engine.setSearchUrlTemplate(searchUrlTemplate); + engine.setSuggestionsUrlTemplate(suggestionsUrlTemplate); + engine.setImageUrl(imageUrl); + engine.setSearchParameters(searchParameters); + engine.setSuggestionsParameters(suggestionsParameters); + engine.setSearchMethod(searchMethod); + engine.setSuggestionsMethod(suggestionsMethod); + + QByteArray output; + QBuffer buffer(&output); + writer.write(&buffer, &engine); + + QFile expected(fileName); + expected.open(QIODevice::ReadOnly); + + QCOMPARE(output, expected.readAll()); +} + +QTEST_MAIN(tst_OpenSearchWriter) + +#include "tst_opensearchwriter.moc" + diff --git a/autotests/qtest_arora.h b/autotests/qtest_arora.h index f8757f80..b1b194db 100644 --- a/autotests/qtest_arora.h +++ b/autotests/qtest_arora.h @@ -20,14 +20,18 @@ #ifndef QTEST_ARORA_H #define QTEST_ARORA_H -#include -#include "browserapplication.h" +#include + +#include + +#include "qtry.h" #undef QTEST_MAIN #define QTEST_MAIN(TestObject) \ int main(int argc, char *argv[]) \ { \ + Q_INIT_RESOURCE(htmls); \ Q_INIT_RESOURCE(data); \ BrowserApplication app(argc, argv); \ TestObject tc; \ @@ -36,4 +40,3 @@ int main(int argc, char *argv[]) \ #endif - diff --git a/autotests/qtry.h b/autotests/qtry.h new file mode 100644 index 00000000..7c1f37cf --- /dev/null +++ b/autotests/qtry.h @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2008 - 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef QTRY_H +#define QTRY_H + +#include + +#ifndef QTRY_COMPARE + +#define __TRY_TIMEOUT__ 5000 +#define __TRY_STEP__ 50 + +#define __QTRY(__expression__, __functionToCall__) \ + do { \ + int __i = 0; \ + while (!(__expression__) && __i < __TRY_TIMEOUT__) { \ + QTest::qWait(__TRY_STEP__); \ + __i += __TRY_STEP__; \ + } \ + __functionToCall__; \ + } while (0) + +#define QTRY_COMPARE(__expression__, __expected__) \ + __QTRY((__expression__ == __expected__), QCOMPARE(__expression__, __expected__)); + +#define QTRY_VERIFY(__expression__) \ + __QTRY(__expression__, QVERIFY(__expression__)); + +#endif // QTRY_COMPARE + +#endif // QTRY_H + diff --git a/autotests/runTests.sh b/autotests/runTests.sh new file mode 100755 index 00000000..597d623d --- /dev/null +++ b/autotests/runTests.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +for directory in `ls -d */` +do + name=`basename $directory` + + if [ $name == "modeltest" ] + then + continue + fi + + if [ $name == "downloadmanager" ] + then + continue + fi + + cd $name + + if [ ! -f $name ] + then + printf "$name/$name is not compiled.\n" + else + ./$name -silent + fi + + printf "\n" + cd ../ +done \ No newline at end of file diff --git a/autotests/searchlineedit/.gitignore b/autotests/searchlineedit/.gitignore new file mode 100644 index 00000000..1713e66b --- /dev/null +++ b/autotests/searchlineedit/.gitignore @@ -0,0 +1 @@ +searchlineedit diff --git a/autotests/searchlineedit/tst_searchlineedit.cpp b/autotests/searchlineedit/tst_searchlineedit.cpp index 93e508e8..223b19c6 100644 --- a/autotests/searchlineedit/tst_searchlineedit.cpp +++ b/autotests/searchlineedit/tst_searchlineedit.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,7 +18,6 @@ */ #include -#include #include class tst_SearchLineEdit : public QObject @@ -34,25 +33,12 @@ public slots: private slots: void searchlineedit_data(); void searchlineedit(); - - void inactiveText_data(); - void inactiveText(); - - void menu(); - void setMenu(); - void resizeEvent(); }; // Subclass that exposes the protected functions. class SubSearchLineEdit : public SearchLineEdit { -public: - void call_paintEvent(QPaintEvent* event) - { return SubSearchLineEdit::paintEvent(event); } - - void call_resizeEvent(QResizeEvent* event) - { return SubSearchLineEdit::resizeEvent(event); } -}; +public:}; // This will be called before the first test function is executed. // It is only called once. @@ -83,81 +69,8 @@ void tst_SearchLineEdit::searchlineedit_data() void tst_SearchLineEdit::searchlineedit() { SubSearchLineEdit edit; - QCOMPARE(edit.inactiveText(), tr("Search")); - edit.setInactiveText(QString()); - edit.setMenu((QMenu*)0); - QVERIFY(edit.menu() != 0); -} - -void tst_SearchLineEdit::inactiveText_data() -{ - QTest::addColumn("inactiveText"); - QTest::newRow("foo") << QString("foo"); -} - -// public QString inactiveText() const -void tst_SearchLineEdit::inactiveText() -{ - QFETCH(QString, inactiveText); - - SubSearchLineEdit edit; - edit.setInactiveText(inactiveText); - QCOMPARE(edit.inactiveText(), inactiveText); -} - -// public QMenu* menu() const -void tst_SearchLineEdit::menu() -{ - SubSearchLineEdit edit; - edit.show(); - QList widgets = edit.findChildren(QString("SearchButton")); - QSize oldSize = widgets.at(0)->size(); - QMenu *menu = edit.menu(); - QSize newSize = widgets.at(0)->size(); - QCOMPARE(oldSize.height(), newSize.height()); - QVERIFY(oldSize.width() != newSize.width()); - - QCOMPARE(edit.menu(), menu); - oldSize = newSize; - newSize = widgets.at(0)->size(); - QCOMPARE(oldSize.height(), newSize.height()); - QCOMPARE(oldSize.width(), newSize.width()); -} - -// public void setMenu(QMenu* menu) -void tst_SearchLineEdit::setMenu() -{ - SubSearchLineEdit edit; - edit.menu(); - - QMenu *newMenu = new QMenu(&edit); - edit.setMenu(newMenu); - QCOMPARE(edit.menu(), newMenu); - - edit.show(); - QList widgets = edit.findChildren(QString("SearchButton")); - QSize oldSize = widgets.at(0)->size(); - edit.setMenu(0); - QSize newSize = widgets.at(0)->size(); - QCOMPARE(oldSize.height(), newSize.height()); - QVERIFY(oldSize.width() != newSize.width()); -} - -// protected void resizeEvent(QResizeEvent* event) -void tst_SearchLineEdit::resizeEvent() -{ - SubSearchLineEdit edit; - edit.resize(100, 100); - - QList widgets = edit.findChildren(QString("SearchButton")); - QSize oldSize = widgets.at(0)->size(); - - edit.show(); - edit.resize(200, 200); - - QSize newSize = widgets.at(0)->size(); - QVERIFY(oldSize.height() != newSize.height()); - QVERIFY(oldSize.width() != newSize.width()); + QVERIFY(edit.clearButton() != 0); + QVERIFY(edit.searchButton() != 0); } QTEST_MAIN(tst_SearchLineEdit) diff --git a/autotests/tabbar/.gitignore b/autotests/tabbar/.gitignore new file mode 100644 index 00000000..79360f37 --- /dev/null +++ b/autotests/tabbar/.gitignore @@ -0,0 +1 @@ +tabbar diff --git a/autotests/tabbar/tst_tabbar.cpp b/autotests/tabbar/tst_tabbar.cpp index a8629af2..5b13070b 100644 --- a/autotests/tabbar/tst_tabbar.cpp +++ b/autotests/tabbar/tst_tabbar.cpp @@ -55,16 +55,16 @@ class SubTabBar : public TabBar void call_closeTab(int index) { return SubTabBar::closeTab(index); } - void call_dragEnterEvent(QDragEnterEvent* event) + void call_dragEnterEvent(QDragEnterEvent *event) { return SubTabBar::dragEnterEvent(event); } - void call_dropEvent(QDropEvent* event) + void call_dropEvent(QDropEvent *event) { return SubTabBar::dropEvent(event); } - void call_mouseMoveEvent(QMouseEvent* event) + void call_mouseMoveEvent(QMouseEvent *event) { return SubTabBar::mouseMoveEvent(event); } - void call_mousePressEvent(QMouseEvent* event) + void call_mousePressEvent(QMouseEvent *event) { return SubTabBar::mousePressEvent(event); } void call_newTab() @@ -79,9 +79,6 @@ class SubTabBar : public TabBar void call_tabLayoutChange() { return SubTabBar::tabLayoutChange(); } - void call_tabMoveRequested(int fromIndex, int toIndex) - { return SubTabBar::tabMoveRequested(fromIndex, toIndex); } - QSize call_tabSizeHint(int index) const { return SubTabBar::tabSizeHint(index); } }; diff --git a/autotests/tabwidget/.gitignore b/autotests/tabwidget/.gitignore new file mode 100644 index 00000000..832b6d8b --- /dev/null +++ b/autotests/tabwidget/.gitignore @@ -0,0 +1 @@ +tabwidget diff --git a/autotests/tabwidget/tst_tabwidget.cpp b/autotests/tabwidget/tst_tabwidget.cpp index 4d386a50..9d90e6d4 100644 --- a/autotests/tabwidget/tst_tabwidget.cpp +++ b/autotests/tabwidget/tst_tabwidget.cpp @@ -41,12 +41,12 @@ private slots: void addWebAction(); void closeTab_data(); void closeTab(); - void currentLineEdit_data(); - void currentLineEdit(); + void currentLocationBar_data(); + void currentLocationBar(); void currentWebView_data(); void currentWebView(); - void lineEditStack_data(); - void lineEditStack(); + void locationBarStack_data(); + void locationBarStack(); void loadUrl_data(); void loadUrl(); void newTab_data(); @@ -59,8 +59,6 @@ private slots: void recentlyClosedTabsAction(); void linkHovered_data(); void linkHovered(const QString &); - void loadPage_data(); - void loadPage(const QString &); void loadProgress_data(); void loadProgress(int); void setCurrentTitle_data(); @@ -77,19 +75,16 @@ private slots: class SubTabWidget : public TabWidget { public: - void call_linkHovered(QString const& link) + void call_linkHovered(QString const &link) { return SubTabWidget::linkHovered(link); } - void call_loadPage(QString const& url) - { return SubTabWidget::loadPage(url); } - void call_loadProgress(int progress) { return SubTabWidget::loadProgress(progress); } - void call_setCurrentTitle(QString const& url) + void call_setCurrentTitle(QString const &url) { return SubTabWidget::setCurrentTitle(url); } - void call_showStatusBarMessage(QString const& message) + void call_showStatusBarMessage(QString const &message) { return SubTabWidget::showStatusBarMessage(message); } void call_tabsChanged() @@ -129,7 +124,7 @@ void tst_TabWidget::tabwidget() widget.closeTab(); QVERIFY(widget.closeTabAction()); widget.currentWebView(); - widget.lineEditStack(); + widget.locationBarStack(); widget.loadUrl(QUrl()); widget.newTab(); QVERIFY(widget.newTabAction()); @@ -138,7 +133,7 @@ void tst_TabWidget::tabwidget() widget.previousTab(); QVERIFY(widget.previousTabAction()); QVERIFY(widget.recentlyClosedTabsAction()); - QVERIFY(widget.currentLineEdit()); + QVERIFY(widget.currentLocationBar()); } Q_DECLARE_METATYPE(QWebPage::WebAction) @@ -148,7 +143,7 @@ void tst_TabWidget::addWebAction_data() QTest::newRow("back") << QWebPage::Back; } -// public void addWebAction(QAction* action, QWebPage::WebAction webAction) +// public void addWebAction(QAction *action, QWebPage::WebAction webAction) void tst_TabWidget::addWebAction() { QFETCH(QWebPage::WebAction, webAction); @@ -156,7 +151,6 @@ void tst_TabWidget::addWebAction() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -168,20 +162,22 @@ void tst_TabWidget::addWebAction() widget.newTab(); QVERIFY(!action->isEnabled()); + widget.loadUrl(QUrl("about:config")); - widget.loadUrl(QUrl("http://www.google.com/")); - widget.loadUrl(QUrl("http://www.yahoo.com/")); - QTest::qWait(3000); - QVERIFY(action->isEnabled()); + QUrl url1(":/notfound.html"); //QUrl("http://www.google.com/")); + QUrl url2(":/notfound2.html"); //QUrl("http://www.yahoo.com/")); + widget.loadUrl(url1); + widget.loadUrl(url2); + + QTRY_VERIFY(action->isEnabled()); widget.newTab(); QVERIFY(!action->isEnabled()); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QVERIFY(spy2.count() > 0); - QCOMPARE(spy3.count(), 6); + QCOMPARE(spy3.count(), 8); QVERIFY(spy4.count() > 0); - QCOMPARE(spy5.count(), 7); + QCOMPARE(spy5.count(), 6); QCOMPARE(spy6.count(), 0); } @@ -199,7 +195,6 @@ void tst_TabWidget::closeTab() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -215,7 +210,6 @@ void tst_TabWidget::closeTab() return; QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 4); QCOMPARE(spy3.count(), 2); QCOMPARE(spy4.count(), 4); @@ -224,34 +218,32 @@ void tst_TabWidget::closeTab() } Q_DECLARE_METATYPE(QLineEdit*) -void tst_TabWidget::currentLineEdit_data() +void tst_TabWidget::currentLocationBar_data() { /* - QTest::addColumn("currentLineEdit"); + QTest::addColumn("currentLocationBar"); QTest::newRow("null") << QLineEdit*(); */ } -// public QLineEdit* currentLineEdit() const -void tst_TabWidget::currentLineEdit() +// public QLineEdit *currentLocationBar() const +void tst_TabWidget::currentLocationBar() { /* - QFETCH(QLineEdit*, currentLineEdit); + QFETCH(QLineEdit*, currentLocationBar); SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); QSignalSpy spy5(&widget, SIGNAL(tabsChanged())); QSignalSpy spy6(&widget, SIGNAL(lastTabClosed())); - QCOMPARE(widget.currentLineEdit(), currentLineEdit); + QCOMPARE(widget.currentLocationBar(), currentLocationBar); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -270,7 +262,7 @@ void tst_TabWidget::currentWebView_data() */ } -// public WebView* currentWebView() const +// public WebView *currentWebView() const void tst_TabWidget::currentWebView() { /* @@ -279,7 +271,6 @@ void tst_TabWidget::currentWebView() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -289,7 +280,6 @@ void tst_TabWidget::currentWebView() QCOMPARE(widget.currentWebView(), currentWebView); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -300,34 +290,32 @@ void tst_TabWidget::currentWebView() } Q_DECLARE_METATYPE(QWidget*) -void tst_TabWidget::lineEditStack_data() +void tst_TabWidget::locationBarStack_data() { /* - QTest::addColumn("lineEditStack"); + QTest::addColumn("locationBarStack"); QTest::newRow("null") << QWidget*(); */ } -// public QWidget* lineEditStack() const -void tst_TabWidget::lineEditStack() +// public QWidget *locationBarStack() const +void tst_TabWidget::locationBarStack() { /* - QFETCH(QWidget*, lineEditStack); + QFETCH(QWidget*, locationBarStack); SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); QSignalSpy spy5(&widget, SIGNAL(tabsChanged())); QSignalSpy spy6(&widget, SIGNAL(lastTabClosed())); - QCOMPARE(widget.lineEditStack(), lineEditStack); + QCOMPARE(widget.locationBarStack(), locationBarStack); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -343,7 +331,7 @@ void tst_TabWidget::loadUrl_data() QTest::newRow("null") << QUrl(); } -// public void loadUrl(QUrl const& url) +// public void loadUrl(QUrl const &url) void tst_TabWidget::loadUrl() { /* @@ -352,7 +340,6 @@ void tst_TabWidget::loadUrl() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -362,7 +349,6 @@ void tst_TabWidget::loadUrl() widget.loadUrl(url); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -387,7 +373,6 @@ void tst_TabWidget::newTab() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -397,7 +382,6 @@ void tst_TabWidget::newTab() widget.newTab(); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -422,7 +406,6 @@ void tst_TabWidget::nextTab() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -432,7 +415,6 @@ void tst_TabWidget::nextTab() widget.nextTab(); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -457,7 +439,6 @@ void tst_TabWidget::previousTab() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -467,7 +448,6 @@ void tst_TabWidget::previousTab() widget.previousTab(); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -485,7 +465,7 @@ void tst_TabWidget::recentlyClosedTabsAction_data() */ } -// public QAction* recentlyClosedTabsAction() const +// public QAction *recentlyClosedTabsAction() const void tst_TabWidget::recentlyClosedTabsAction() { /* @@ -494,7 +474,6 @@ void tst_TabWidget::recentlyClosedTabsAction() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -504,7 +483,6 @@ void tst_TabWidget::recentlyClosedTabsAction() QCOMPARE(widget.recentlyClosedTabsAction(), recentlyClosedTabsAction); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -520,7 +498,7 @@ void tst_TabWidget::linkHovered_data() QTest::newRow("null") << QString("foo"); } -// protected void linkHovered(QString const& link) +// protected void linkHovered(QString const &link) void tst_TabWidget::linkHovered(const QString &) { /* @@ -529,7 +507,6 @@ void tst_TabWidget::linkHovered(const QString &) SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -539,42 +516,6 @@ void tst_TabWidget::linkHovered(const QString &) widget.call_linkHovered(link); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); - QCOMPARE(spy2.count(), 0); - QCOMPARE(spy3.count(), 0); - QCOMPARE(spy4.count(), 0); - QCOMPARE(spy5.count(), 0); - QCOMPARE(spy6.count(), 0); - */ - QSKIP("Test is not implemented.", SkipAll); -} - -void tst_TabWidget::loadPage_data() -{ - QTest::addColumn("url"); - QTest::newRow("null") << QString("foo"); -} - -// protected void loadPage(QString const& url) -void tst_TabWidget::loadPage(const QString &) -{ - /* - QFETCH(QString, url); - - SubTabWidget widget; - - QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); - QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); - QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); - QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); - QSignalSpy spy5(&widget, SIGNAL(tabsChanged())); - QSignalSpy spy6(&widget, SIGNAL(lastTabClosed())); - - widget.call_loadPage(url); - - QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -599,7 +540,6 @@ void tst_TabWidget::loadProgress(int) SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -609,7 +549,6 @@ void tst_TabWidget::loadProgress(int) widget.call_loadProgress(progress); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -625,7 +564,7 @@ void tst_TabWidget::setCurrentTitle_data() QTest::newRow("null") << QString("foo"); } -// protected void setCurrentTitle(QString const& url) +// protected void setCurrentTitle(QString const &url) void tst_TabWidget::setCurrentTitle(const QString &) { /* @@ -634,7 +573,6 @@ void tst_TabWidget::setCurrentTitle(const QString &) SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -644,7 +582,6 @@ void tst_TabWidget::setCurrentTitle(const QString &) widget.call_setCurrentTitle(url); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -660,7 +597,7 @@ void tst_TabWidget::showStatusBarMessage_data() QTest::newRow("null") << QString("foo"); } -// protected void showStatusBarMessage(QString const& message) +// protected void showStatusBarMessage(QString const &message) void tst_TabWidget::showStatusBarMessage(const QString &) { /* @@ -669,7 +606,6 @@ void tst_TabWidget::showStatusBarMessage(const QString &) SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -679,7 +615,6 @@ void tst_TabWidget::showStatusBarMessage(const QString &) widget.call_showStatusBarMessage(message); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); @@ -704,7 +639,6 @@ void tst_TabWidget::tabsChanged() SubTabWidget widget; QSignalSpy spy0(&widget, SIGNAL(linkHovered(const QString &))); - QSignalSpy spy1(&widget, SIGNAL(loadPage(const QString &))); QSignalSpy spy2(&widget, SIGNAL(loadProgress(int))); QSignalSpy spy3(&widget, SIGNAL(setCurrentTitle(const QString &))); QSignalSpy spy4(&widget, SIGNAL(showStatusBarMessage(const QString &))); @@ -714,7 +648,6 @@ void tst_TabWidget::tabsChanged() widget.call_tabsChanged(); QCOMPARE(spy0.count(), 0); - QCOMPARE(spy1.count(), 0); QCOMPARE(spy2.count(), 0); QCOMPARE(spy3.count(), 0); QCOMPARE(spy4.count(), 0); diff --git a/autotests/utils/editlistview/.gitignore b/autotests/utils/editlistview/.gitignore new file mode 100644 index 00000000..4c5abff0 --- /dev/null +++ b/autotests/utils/editlistview/.gitignore @@ -0,0 +1 @@ +editlistview diff --git a/autotests/utils/editlistview/editlistview.pro b/autotests/utils/editlistview/editlistview.pro new file mode 100644 index 00000000..f089b9c8 --- /dev/null +++ b/autotests/utils/editlistview/editlistview.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES = tst_editlistview.cpp editlistview.cpp +HEADERS = editlistview.h +FORMS = +RESOURCES = diff --git a/autotests/utils/editlistview/tst_editlistview.cpp b/autotests/utils/editlistview/tst_editlistview.cpp new file mode 100644 index 00000000..129d6909 --- /dev/null +++ b/autotests/utils/editlistview/tst_editlistview.cpp @@ -0,0 +1,163 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include + +#include + +class tst_EditListView : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void editlistview_data(); + void editlistview(); + + void keyPressEvent_data(); + void keyPressEvent(); + void removeAll_data(); + void removeAll(); + void removeSelected_data(); + void removeSelected(); +}; + +// Subclass that exposes the protected functions. +class SubEditListView : public EditListView +{ +public: + +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_EditListView::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_EditListView::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_EditListView::init() +{ +} + +// This will be called after every test function. +void tst_EditListView::cleanup() +{ +} + +void tst_EditListView::editlistview_data() +{ +} + +Q_DECLARE_METATYPE(Qt::Key) +void tst_EditListView::editlistview() +{ + SubEditListView view; + QTest::keyClick(&view, Qt::Key_Delete); + QTest::keyClick(&view, Qt::Key_R); + view.removeAll(); + view.removeSelected(); +} + +void tst_EditListView::keyPressEvent_data() +{ + QTest::addColumn("key"); + QTest::addColumn("predata"); + QTest::addColumn("postdata"); + QStringList predata; + predata << "a"; + QTest::newRow("R") << Qt::Key_R << predata << predata; + QTest::newRow("delete") << Qt::Key_Delete << predata << QStringList(); +} + +// public void keyPressEvent(QKeyEvent *event) +void tst_EditListView::keyPressEvent() +{ + QFETCH(Qt::Key, key); + QFETCH(QStringList, predata); + QFETCH(QStringList, postdata); + + SubEditListView view; + QStringListModel *model = new QStringListModel(predata); + view.setModel(model); + view.setCurrentIndex(model->index(0, 0)); + QTest::keyClick(&view, key); + QCOMPARE(model->stringList(), postdata); +} + +void tst_EditListView::removeAll_data() +{ + QTest::addColumn("data"); + QTest::newRow("0") << QStringList(); + QTest::newRow("3") << (QStringList() << "x" << "y" << "z"); +} + +// public void removeAll() +void tst_EditListView::removeAll() +{ + QFETCH(QStringList, data); + + SubEditListView view; + view.setModel(new QStringListModel(data)); + + view.removeAll(); + QCOMPARE(view.model()->rowCount(), 0); +} + +void tst_EditListView::removeSelected_data() +{ + QTest::addColumn("key"); + QTest::addColumn("predata"); + QTest::addColumn("postdata"); + QStringList predata; + predata << "a"; + QTest::newRow("R") << Qt::Key_R << predata << predata; + QTest::newRow("delete") << Qt::Key_Delete << predata << QStringList(); +} + +// public void removeSelected() +void tst_EditListView::removeSelected() +{ + QFETCH(Qt::Key, key); + QFETCH(QStringList, predata); + QFETCH(QStringList, postdata); + + SubEditListView view; + QStringListModel *model = new QStringListModel(predata); + view.setModel(model); + view.setCurrentIndex(model->index(0, 0)); + QTest::keyClick(&view, key); + QCOMPARE(model->stringList(), postdata); +} + +QTEST_MAIN(tst_EditListView) +#include "tst_editlistview.moc" + diff --git a/autotests/utils/edittreeview/.gitignore b/autotests/utils/edittreeview/.gitignore new file mode 100644 index 00000000..e4d4bcef --- /dev/null +++ b/autotests/utils/edittreeview/.gitignore @@ -0,0 +1 @@ +edittreeview diff --git a/autotests/utils/edittreeview/edittreeview.pro b/autotests/utils/edittreeview/edittreeview.pro new file mode 100644 index 00000000..00a4dea5 --- /dev/null +++ b/autotests/utils/edittreeview/edittreeview.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . ../ + +include(../../autotests.pri) + +# Input +SOURCES = tst_edittreeview.cpp edittreeview.cpp +HEADERS = edittreeview.h +FORMS = +RESOURCES = diff --git a/autotests/edittreeview/tst_edittreeview.cpp b/autotests/utils/edittreeview/tst_edittreeview.cpp similarity index 94% rename from autotests/edittreeview/tst_edittreeview.cpp rename to autotests/utils/edittreeview/tst_edittreeview.cpp index 7ace6a7c..b15a4593 100644 --- a/autotests/edittreeview/tst_edittreeview.cpp +++ b/autotests/utils/edittreeview/tst_edittreeview.cpp @@ -17,9 +17,10 @@ * Boston, MA 02110-1301 USA */ -#include -#include +#include + #include +#include class tst_EditTreeView : public QObject { @@ -96,7 +97,6 @@ void tst_EditTreeView::edittreeview() SubEditTreeView view; QTest::keyClick(&view, Qt::Key_Space); QTest::keyClick(&view, Qt::Key_Delete); - QTest::keyClick(&view, Qt::Key_Backspace); view.removeAll(); view.removeSelected(); } @@ -107,10 +107,9 @@ void tst_EditTreeView::keyPressEvent_data() QTest::addColumn("key"); QTest::newRow("space") << Qt::Key_Space; QTest::newRow("delete") << Qt::Key_Delete; - QTest::newRow("backspace") << Qt::Key_Backspace; } -// public void keyPressEvent(QKeyEvent* event) +// public void keyPressEvent(QKeyEvent *event) void tst_EditTreeView::keyPressEvent() { QFETCH(Qt::Key, key); @@ -122,7 +121,7 @@ void tst_EditTreeView::keyPressEvent() view.selectionModel()->select(idx, QItemSelectionModel::SelectCurrent); int oldCount = view.model()->rowCount(); QTest::keyClick(&view, key); - if (key == Qt::Key_Delete || key == Qt::Key_Backspace) + if (key == Qt::Key_Delete) QCOMPARE(oldCount - 1, view.model()->rowCount()); else QCOMPARE(oldCount, view.model()->rowCount()); @@ -163,10 +162,12 @@ void tst_EditTreeView::removeSelected() view.show(); view.addModel(); QAbstractItemModel *model = view.model(); + view.expandAll(); QModelIndex parent = model->index(selectParent, 0); while (!select.isEmpty()) { QModelIndex idx = model->index(select.takeLast(), 0, parent); - view.selectionModel()->select(idx, QItemSelectionModel::SelectCurrent); + view.selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + view.setCurrentIndex(idx); view.removeSelected(); } diff --git a/autotests/utils/languagemanager/.gitignore b/autotests/utils/languagemanager/.gitignore new file mode 100644 index 00000000..8d5dade7 --- /dev/null +++ b/autotests/utils/languagemanager/.gitignore @@ -0,0 +1 @@ +languagemanager diff --git a/autotests/utils/languagemanager/languagemanager.pro b/autotests/utils/languagemanager/languagemanager.pro new file mode 100644 index 00000000..9c0db47f --- /dev/null +++ b/autotests/utils/languagemanager/languagemanager.pro @@ -0,0 +1,13 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . ../ + +include(../../autotests.pri) +include(../../../src/locale/locale.pri) + +# Input +SOURCES = languagemanager.cpp tst_languagemanager.cpp +HEADERS = languagemanager.h +FORMS = +RESOURCES = diff --git a/autotests/utils/languagemanager/tst_languagemanager.cpp b/autotests/utils/languagemanager/tst_languagemanager.cpp new file mode 100644 index 00000000..f67b862d --- /dev/null +++ b/autotests/utils/languagemanager/tst_languagemanager.cpp @@ -0,0 +1,215 @@ +/** + * Copyright (c) 2008, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include +#include + +class tst_LanguageManager : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void languagemanager_data(); + void languagemanager(); + + void isLanguageAvailable_data(); + void isLanguageAvailable(); + void chooseNewLanguage_data(); + void chooseNewLanguage(); + void setCurrentLanguage_data(); + void setCurrentLanguage(); +}; + +// Subclass that exposes the protected functions. +class SubLanguageManager : public LanguageManager +{ +public: + SubLanguageManager() : LanguageManager() { + addLocaleDirectory(qApp->applicationDirPath() + QLatin1String("/.qm/locale")); + } + +}; + +class TestWidget : public QWidget +{ +public: + void changeEvent(QEvent *event) { + if (event->type() == QEvent::LanguageChange) + retranslate = true; + QWidget::changeEvent(event); + } + bool retranslate; +}; + + +// This will be called before the first test function is executed. +// It is only called once. +void tst_LanguageManager::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_LanguageManager::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_LanguageManager::init() +{ + SubLanguageManager manager; + manager.setCurrentLanguage(QString()); +} + +// This will be called after every test function. +void tst_LanguageManager::cleanup() +{ +} + +void tst_LanguageManager::languagemanager_data() +{ +} + +void tst_LanguageManager::languagemanager() +{ + SubLanguageManager manager; + manager.languages(); + // spawns an event loop... + // manager.chooseNewLanguage(); + + QString fallbackLanguage; + if (manager.isLanguageAvailable(QLocale::system().name())) + fallbackLanguage = QLocale::system().name(); + + QCOMPARE(manager.currentLanguage(), fallbackLanguage); + manager.setCurrentLanguage(QString()); +} + +void tst_LanguageManager::isLanguageAvailable_data() +{ + QTest::addColumn("language"); + QTest::addColumn("available"); + QTest::newRow("null") << QString() << true; + QTest::newRow("fallback0") << "ca_ES" << true; + QTest::newRow("fallback1") << "ca_ES.UTF-8" << true; + QTest::newRow("fallback2") << "de_AT" << true; +} + +void tst_LanguageManager::isLanguageAvailable() +{ + QFETCH(QString, language); + QFETCH(bool, available); + SubLanguageManager manager; + QCOMPARE(manager.isLanguageAvailable(language), available); +} + +void tst_LanguageManager::chooseNewLanguage_data() +{ + QTest::addColumn("foo"); + QTest::newRow("null") << 0; +} + +// public void chooseNewLanguage() +void tst_LanguageManager::chooseNewLanguage() +{ + // how do you test this? +#if 0 + QFETCH(int, foo); + + SubLanguageManager manager; + + manager.chooseNewLanguage(); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_LanguageManager::setCurrentLanguage_data() +{ + SubLanguageManager manager; + + QString fallbackLanguage; + if (manager.isLanguageAvailable(QLocale::system().name())) + fallbackLanguage = QLocale::system().name(); + + QTest::addColumn("language"); + QTest::addColumn("success"); + QTest::addColumn("result"); + QTest::newRow("null-foo") << QString("foo") << false << fallbackLanguage; + QTest::newRow("null-null") << QString() << false << fallbackLanguage; + + QString validLanguage = manager.languages().value(0); + if (validLanguage.isEmpty()) + QSKIP("no languages to test with", SkipAll); + QTest::newRow(validLanguage.toLatin1()) << validLanguage << true << validLanguage; + QTest::newRow("fallback") << "ca_ES" << true << "ca_ES"; +} + +// public void setCurrentLanguage(QString const &language) +void tst_LanguageManager::setCurrentLanguage() +{ + QFETCH(QString, language); + QFETCH(bool, success); + QFETCH(QString, result); + + SubLanguageManager manager; + QString initialLanguage = manager.currentLanguage(); + QSignalSpy spy(&manager, SIGNAL(languageChanged(const QString &))); + + TestWidget widget; + widget.retranslate = false; + QCOMPARE(manager.setCurrentLanguage(language), success); + QCOMPARE(manager.currentLanguage(), result); + + // test if we set the default locale properly + // this is essential for opensearch localization + QLocale currentLocale(manager.currentLanguage()); + if (manager.currentLanguage().isEmpty()) + currentLocale = QLocale(); + QCOMPARE(currentLocale, QLocale()); + + qApp->processEvents(); + QCOMPARE(widget.retranslate, success); + QCOMPARE(spy.count(), success ? 1 : 0); + if (success) { + QVERIFY(manager.setCurrentLanguage(QString())); + QCOMPARE(spy.count(), 2); + } +} + +QTEST_MAIN(tst_LanguageManager) +#include "tst_languagemanager.moc" + diff --git a/autotests/utils/lineedit/.gitignore b/autotests/utils/lineedit/.gitignore new file mode 100644 index 00000000..19f5a9a7 --- /dev/null +++ b/autotests/utils/lineedit/.gitignore @@ -0,0 +1 @@ +lineedit diff --git a/autotests/utils/lineedit/lineedit.pro b/autotests/utils/lineedit/lineedit.pro new file mode 100644 index 00000000..d829e9f4 --- /dev/null +++ b/autotests/utils/lineedit/lineedit.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES = tst_lineedit.cpp lineedit.cpp +HEADERS = lineedit.h lineedit_p.h +FORMS = +RESOURCES = diff --git a/autotests/utils/lineedit/tst_lineedit.cpp b/autotests/utils/lineedit/tst_lineedit.cpp new file mode 100644 index 00000000..f268550d --- /dev/null +++ b/autotests/utils/lineedit/tst_lineedit.cpp @@ -0,0 +1,200 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +class tst_LineEdit : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void lineedit_data(); + void lineedit(); + + void addWidget_data(); + void addWidget(); + void removeWidget(); + void setWidgetSpacing_data(); + void setWidgetSpacing(); + void textMargin_data(); + void textMargin(); + void inactiveText_data(); + void inactiveText(); +}; + +// Subclass that exposes the protected functions. +class SubLineEdit : public LineEdit +{ +public: + void call_resizeEvent(QResizeEvent *event) + { return SubLineEdit::resizeEvent(event); } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_LineEdit::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_LineEdit::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_LineEdit::init() +{ +} + +// This will be called after every test function. +void tst_LineEdit::cleanup() +{ +} + +void tst_LineEdit::lineedit_data() +{ +} + +void tst_LineEdit::lineedit() +{ + SubLineEdit edit; + edit.addWidget((QWidget*)0, LineEdit::LeftSide); + edit.addWidget((QWidget*)0, LineEdit::RightSide); + edit.removeWidget((QWidget*)0); + QCOMPARE(edit.widgetSpacing(), 3); + edit.setWidgetSpacing(-1); + QCOMPARE(edit.textMargin(LineEdit::LeftSide), 0); + QCOMPARE(edit.textMargin(LineEdit::RightSide), 0); +} + +Q_DECLARE_METATYPE(LineEdit::WidgetPosition) +void tst_LineEdit::addWidget_data() +{ + QTest::addColumn("position"); + QTest::addColumn("spacing"); + for (int i = 0; i < 4; ++i) { + QTest::newRow("left") << LineEdit::LeftSide << i; + QTest::newRow("right") << LineEdit::RightSide << i; + } +} + +// public void addWidget(QWidget *widget, LineEdit::WidgetPosition position) +void tst_LineEdit::addWidget() +{ + QFETCH(LineEdit::WidgetPosition, position); + QFETCH(int, spacing); + LineEdit::WidgetPosition other = position == LineEdit::LeftSide ? LineEdit::RightSide : LineEdit::LeftSide; + + SubLineEdit edit; + edit.setWidgetSpacing(spacing); + + QToolButton *button = new QToolButton; + button->setMinimumSize(10, 10); + button->setMaximumSize(10, 10); + edit.addWidget(button, position); + edit.show(); + + spacing = edit.widgetSpacing(); + QCOMPARE(edit.textMargin(position), 10 + spacing * 2); + QCOMPARE(edit.textMargin(other), 0); + + edit.removeWidget(button); + qApp->processEvents(); + QCOMPARE(edit.textMargin(position), 0); +} + +// public void removeWidget(QWidget *widget) +void tst_LineEdit::removeWidget() +{ + SubLineEdit edit; + QToolButton *button = new QToolButton; + edit.addWidget(button, LineEdit::LeftSide); + edit.show(); + QVERIFY(edit.textMargin(LineEdit::LeftSide) != 0); + edit.removeWidget(button); + qApp->processEvents(); + QVERIFY(edit.textMargin(LineEdit::LeftSide) == 0); +} + +void tst_LineEdit::setWidgetSpacing_data() +{ + QTest::addColumn("spacing"); + QTest::newRow("0") << 0; + QTest::newRow("1") << 1; + QTest::newRow("2") << 2; +} + +// public void setWidgetSpacing(int spacing) +void tst_LineEdit::setWidgetSpacing() +{ + QFETCH(int, spacing); + + SubLineEdit edit; + + edit.setWidgetSpacing(spacing); + QCOMPARE(edit.widgetSpacing(), spacing); +} + +void tst_LineEdit::textMargin_data() +{ + QTest::addColumn("position"); + QTest::addColumn("textMargin"); + QTest::newRow("null") << LineEdit::LeftSide << 0; +} + +// public int textMargin(LineEdit::WidgetPosition position) const +void tst_LineEdit::textMargin() +{ + QFETCH(LineEdit::WidgetPosition, position); + QFETCH(int, textMargin); + + SubLineEdit edit; + + QCOMPARE(edit.textMargin(position), textMargin); +} + +void tst_LineEdit::inactiveText_data() +{ + QTest::addColumn("inactiveText"); + QTest::newRow("foo") << QString("foo"); +} + +// public QString inactiveText() const +void tst_LineEdit::inactiveText() +{ + QFETCH(QString, inactiveText); + + SubLineEdit edit; + edit.setInactiveText(inactiveText); + QCOMPARE(edit.inactiveText(), inactiveText); +} + +QTEST_MAIN(tst_LineEdit) +#include "tst_lineedit.moc" + diff --git a/autotests/utils/networkaccessmanagerproxy/.gitignore b/autotests/utils/networkaccessmanagerproxy/.gitignore new file mode 100644 index 00000000..1b40b446 --- /dev/null +++ b/autotests/utils/networkaccessmanagerproxy/.gitignore @@ -0,0 +1 @@ +networkaccessmanagerproxy diff --git a/autotests/utils/networkaccessmanagerproxy/networkaccessmanagerproxy.pro b/autotests/utils/networkaccessmanagerproxy/networkaccessmanagerproxy.pro new file mode 100644 index 00000000..125fc571 --- /dev/null +++ b/autotests/utils/networkaccessmanagerproxy/networkaccessmanagerproxy.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES = tst_networkaccessmanagerproxy.cpp networkaccessmanagerproxy.cpp webpageproxy.cpp +HEADERS = networkaccessmanagerproxy.h networkaccessmanagerproxy_p.h webpageproxy.h +FORMS = +RESOURCES = diff --git a/autotests/utils/networkaccessmanagerproxy/tst_networkaccessmanagerproxy.cpp b/autotests/utils/networkaccessmanagerproxy/tst_networkaccessmanagerproxy.cpp new file mode 100644 index 00000000..40ed7203 --- /dev/null +++ b/autotests/utils/networkaccessmanagerproxy/tst_networkaccessmanagerproxy.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +#include +#include +#include + +class tst_NetworkAccessManagerProxy : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void networkaccessmanagerproxy_data(); + void networkaccessmanagerproxy(); + + void primaryNetworkAccessManager(); + void webPage(); + + void createRequest_data(); + void createRequest(); +}; + +// Subclass that exposes the protected functions. +class SubNetworkAccessManagerProxy : public NetworkAccessManagerProxy +{ +public: + QNetworkReply *call_createRequest(QNetworkAccessManager::Operation op, QNetworkRequest const &request, QIODevice *outgoingData = 0) + { return SubNetworkAccessManagerProxy::createRequest(op, request, outgoingData); } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_NetworkAccessManagerProxy::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_NetworkAccessManagerProxy::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_NetworkAccessManagerProxy::init() +{ +} + +// This will be called after every test function. +void tst_NetworkAccessManagerProxy::cleanup() +{ +} + +void tst_NetworkAccessManagerProxy::networkaccessmanagerproxy_data() +{ +} + +void tst_NetworkAccessManagerProxy::networkaccessmanagerproxy() +{ + SubNetworkAccessManagerProxy proxy; + QVERIFY(proxy.call_createRequest(QNetworkAccessManager::GetOperation, + QNetworkRequest(), + (QIODevice*)0)); +} + +// public void setPrimaryNetworkAccessManager(NetworkAccessManagerProxy *primaryManager) +void tst_NetworkAccessManagerProxy::primaryNetworkAccessManager() +{ + SubNetworkAccessManagerProxy proxy; + + NetworkAccessManagerProxy primaryManager; + + proxy.setPrimaryNetworkAccessManager(&primaryManager); + QCOMPARE(&primaryManager, proxy.primaryNetworkAccessManager()); + QVERIFY(primaryManager.cookieJar()->parent() == &primaryManager); +} + +// public void setWebPage(WebPageProxy *page) +void tst_NetworkAccessManagerProxy::webPage() +{ + SubNetworkAccessManagerProxy proxy; + + WebPageProxy webPage; + proxy.setWebPage(&webPage); + QCOMPARE(&webPage, proxy.webPage()); +} + +void tst_NetworkAccessManagerProxy::createRequest_data() +{ + QTest::addColumn("primary"); + QTest::newRow("true") << true; + QTest::newRow("false") << false; +} + +// protected QNetworkReply *createRequest(QNetworkAccessManager::Operation op, QNetworkRequest const &request, QIODevice *outgoingData = 0) +void tst_NetworkAccessManagerProxy::createRequest() +{ + QFETCH(bool, primary); + + SubNetworkAccessManagerProxy proxy; + SubNetworkAccessManagerProxy primaryManager; + WebPageProxy webPage; + if (!primary) { + proxy.setPrimaryNetworkAccessManager(&primaryManager); + proxy.setWebPage(&webPage); + } + + QIODevice *outgoingData = 0; + QNetworkRequest request; + QNetworkReply *reply = proxy.call_createRequest(QNetworkAccessManager::GetOperation, request, outgoingData); + QVERIFY(reply); + if (primary) + QCOMPARE(reply->request(), request); + else + QVERIFY(reply->request() != request); +} + +QTEST_MAIN(tst_NetworkAccessManagerProxy) +#include "tst_networkaccessmanagerproxy.moc" + diff --git a/autotests/utils/utils.pro b/autotests/utils/utils.pro new file mode 100644 index 00000000..08666cd6 --- /dev/null +++ b/autotests/utils/utils.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs +SUBDIRS = \ + editlistview \ + edittreeview \ + languagemanager \ + lineedit + +CONFIG += ordered diff --git a/autotests/utils/webpageproxy/.gitignore b/autotests/utils/webpageproxy/.gitignore new file mode 100644 index 00000000..76350346 --- /dev/null +++ b/autotests/utils/webpageproxy/.gitignore @@ -0,0 +1 @@ +webpageproxy diff --git a/autotests/utils/webpageproxy/tst_webpageproxy.cpp b/autotests/utils/webpageproxy/tst_webpageproxy.cpp new file mode 100644 index 00000000..dd9db5f8 --- /dev/null +++ b/autotests/utils/webpageproxy/tst_webpageproxy.cpp @@ -0,0 +1,103 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include + +#include +#include + +class tst_WebPageProxy : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void webpageproxy_data(); + void webpageproxy(); + + void populateNetworkRequest(); +}; + +// Subclass that exposes the protected functions. +class SubWebPageProxy : public WebPageProxy +{ +public: + void call_populateNetworkRequest(QNetworkRequest &request) + { return SubWebPageProxy::populateNetworkRequest(request); } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_WebPageProxy::initTestCase() +{ +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_WebPageProxy::cleanupTestCase() +{ +} + +// This will be called before each test function is executed. +void tst_WebPageProxy::init() +{ +} + +// This will be called after every test function. +void tst_WebPageProxy::cleanup() +{ +} + +void tst_WebPageProxy::webpageproxy_data() +{ +} + +void tst_WebPageProxy::webpageproxy() +{ + SubWebPageProxy proxy; + QCOMPARE(proxy.pageAttributeId(), 1100); + QNetworkRequest request; + proxy.call_populateNetworkRequest(request); +} + +// protected void populateNetworkRequest(QNetworkRequest &request) +void tst_WebPageProxy::populateNetworkRequest() +{ + SubWebPageProxy proxy; + + QNetworkRequest emptyRequest; + QNetworkRequest request = emptyRequest; + proxy.call_populateNetworkRequest(request); + + QVERIFY(request != emptyRequest); + QVariant v = request.attribute((QNetworkRequest::Attribute)(proxy.pageAttributeId())); + QVERIFY(v.isValid()); + QWebPage *webPage = (QWebPage*)(v.value()); + QVERIFY(webPage); + QCOMPARE(webPage, &proxy); +} + +QTEST_MAIN(tst_WebPageProxy) +#include "tst_webpageproxy.moc" + diff --git a/autotests/utils/webpageproxy/webpageproxy.pro b/autotests/utils/webpageproxy/webpageproxy.pro new file mode 100644 index 00000000..2c3b1913 --- /dev/null +++ b/autotests/utils/webpageproxy/webpageproxy.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../autotests.pri) + +# Input +SOURCES = tst_webpageproxy.cpp webpageproxy.cpp +HEADERS = webpageproxy.h +FORMS = +RESOURCES = diff --git a/autotests/webactionmapper/.gitignore b/autotests/webactionmapper/.gitignore new file mode 100644 index 00000000..a1908626 --- /dev/null +++ b/autotests/webactionmapper/.gitignore @@ -0,0 +1 @@ +webactionmapper diff --git a/autotests/webactionmapper/tst_webactionmapper.cpp b/autotests/webactionmapper/tst_webactionmapper.cpp index cae62bd1..ad78b8dd 100644 --- a/autotests/webactionmapper/tst_webactionmapper.cpp +++ b/autotests/webactionmapper/tst_webactionmapper.cpp @@ -25,6 +25,8 @@ #include #include +#include "qtest_arora.h" + class tst_WebActionMapper : public QObject { Q_OBJECT @@ -54,7 +56,7 @@ class SubWebActionMapper : public WebActionMapper { public: SubWebActionMapper(QAction *root, QWebPage::WebAction webAction, QObject *parent) - : WebActionMapper(root, webAction, parent){} + : WebActionMapper(root, webAction, parent) {} }; @@ -92,7 +94,7 @@ void tst_WebActionMapper::webactionmapper() QCOMPARE(mapper.webAction(), QWebPage::Stop); } -// public void addChild(QAction* action) +// public void addChild(QAction *action) void tst_WebActionMapper::addChild() { QAction *root = new QAction(this); @@ -112,7 +114,7 @@ void tst_WebActionMapper::updateCurrent_data() QTest::newRow("null") << 0; } -// public void updateCurrent(WebView* currentParent) +// public void updateCurrent(WebView *currentParent) void tst_WebActionMapper::updateCurrent() { QAction *root = new QAction(this); diff --git a/autotests/webpage/.gitignore b/autotests/webpage/.gitignore new file mode 100644 index 00000000..be7aca59 --- /dev/null +++ b/autotests/webpage/.gitignore @@ -0,0 +1 @@ +webpage diff --git a/autotests/webpage/tst_webpage.cpp b/autotests/webpage/tst_webpage.cpp new file mode 100644 index 00000000..7c70ff3f --- /dev/null +++ b/autotests/webpage/tst_webpage.cpp @@ -0,0 +1,396 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include +#include "qtest_arora.h" + +class tst_WebPage : public QObject +{ + Q_OBJECT + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void webpage_data(); + void webpage(); + + void loadSettings_data(); + void loadSettings(); + void webPluginFactory_data(); + void webPluginFactory(); + void acceptNavigationRequest_data(); + void acceptNavigationRequest(); + void createPlugin_data(); + void createPlugin(); + void createWindow_data(); + void createWindow(); + void handleUnsupportedContent(); + void linkedResources(); + void javaScriptObjects_data(); + void javaScriptObjects(); + void userAgent(); +}; + +// Subclass that exposes the protected functions. +class SubWebPage : public WebPage +{ +public: + QString call_userAgentForUrl(const QUrl &url) const + { return SubWebPage::userAgentForUrl(url); } + + void call_aboutToLoadUrl(QUrl const &url) + { return SubWebPage::aboutToLoadUrl(url); } + + bool call_acceptNavigationRequest(QWebFrame *frame, QNetworkRequest const &request, NavigationType type) + { return SubWebPage::acceptNavigationRequest(frame, request, type); } + + QObject *call_createPlugin(QString const &classId, QUrl const &url, QStringList const ¶mNames, QStringList const ¶mValues) + { return SubWebPage::createPlugin(classId, url, paramNames, paramValues); } + + QWebPage *call_createWindow(QWebPage::WebWindowType type) + { return SubWebPage::createWindow(type); } +}; + +// This will be called before the first test function is executed. +// It is only called once. +void tst_WebPage::initTestCase() +{ + QCoreApplication::setApplicationName("tst_webpage"); + + QDesktopServices::setUrlHandler(QLatin1String("mailto"), this, "openUrl"); + QDesktopServices::setUrlHandler(QLatin1String("ftp"), this, "openUrl"); +} + +// This will be called after the last test function is executed. +// It is only called once. +void tst_WebPage::cleanupTestCase() +{ + QSettings settings; + settings.setValue("userAgent", QString()); +} + +// This will be called before each test function is executed. +void tst_WebPage::init() +{ +} + +// This will be called after every test function. +void tst_WebPage::cleanup() +{ +} + +void tst_WebPage::webpage_data() +{ +} + +void tst_WebPage::webpage() +{ + SubWebPage page; + page.loadSettings(); + QVERIFY(page.webPluginFactory()); + page.call_aboutToLoadUrl(QUrl()); + QCOMPARE(page.call_acceptNavigationRequest((QWebFrame*)0, QNetworkRequest(), QWebPage::NavigationTypeLinkClicked), true); + QCOMPARE(page.call_createPlugin(QString(), QUrl(), QStringList(), QStringList()), (QObject*)0); + QCOMPARE(page.call_createWindow(QWebPage::WebBrowserWindow), (QWebPage*)0); +} + +void tst_WebPage::loadSettings_data() +{ + QTest::addColumn("foo"); + QTest::newRow("0") << 0; + QTest::newRow("-1") << -1; +} + +// public void loadSettings() +void tst_WebPage::loadSettings() +{ +#if 0 + QFETCH(int, foo); + + SubWebPage page; + + QSignalSpy spy0(&page, SIGNAL(aboutToLoadUrl(QUrl const&))); + + page.loadSettings(); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +Q_DECLARE_METATYPE(WebPluginFactory*) +void tst_WebPage::webPluginFactory_data() +{ +#if 0 + QTest::addColumn("webPluginFactory"); + QTest::newRow("null") << WebPluginFactory*(); +#endif +} + +// public WebPluginFactory *webPluginFactory() +void tst_WebPage::webPluginFactory() +{ +#if 0 + QFETCH(WebPluginFactory*, webPluginFactory); + + SubWebPage page; + + QSignalSpy spy0(&page, SIGNAL(aboutToLoadUrl(QUrl const&))); + + QCOMPARE(page.webPluginFactory(), webPluginFactory); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +Q_DECLARE_METATYPE(QWebPage::WebWindowType) +Q_DECLARE_METATYPE(QWebPage::NavigationType) +Q_DECLARE_METATYPE(Qt::MouseButton) +Q_DECLARE_METATYPE(Qt::KeyboardModifier) +void tst_WebPage::acceptNavigationRequest_data() +{ + QTest::addColumn("pressedButton"); + QTest::addColumn("pressedKeys"); + QTest::addColumn("validFrame"); + QTest::addColumn("request"); + QTest::addColumn("type"); + QTest::addColumn("acceptNavigationRequest"); + QTest::addColumn("spyCount"); + + QTest::newRow("null-noframe") << Qt::NoButton << Qt::NoModifier << false << QNetworkRequest() << QWebPage::NavigationTypeLinkClicked << true << 0; + QTest::newRow("null-frame") << Qt::NoButton << Qt::NoModifier << true << QNetworkRequest() << QWebPage::NavigationTypeLinkClicked << true << 1; + + QTest::newRow("mailto-0") << Qt::NoButton << Qt::NoModifier << true << QNetworkRequest(QUrl("mailto:foo@bar.com")) << QWebPage::NavigationTypeLinkClicked << false << 0; + QTest::newRow("mailto-1") << Qt::NoButton << Qt::NoModifier << false << QNetworkRequest(QUrl("mailto:foo@bar.com")) << QWebPage::NavigationTypeLinkClicked << false << 0; + QTest::newRow("ftp-0") << Qt::NoButton << Qt::NoModifier << true << QNetworkRequest(QUrl("ftp:foo@bar.com")) << QWebPage::NavigationTypeLinkClicked << false << 0; + QTest::newRow("ftp-1") << Qt::NoButton << Qt::NoModifier << false << QNetworkRequest(QUrl("ftp:foo@bar.com")) << QWebPage::NavigationTypeLinkClicked << false << 0; + + + QTest::newRow("normal-0") << Qt::NoButton << Qt::NoModifier << false << QNetworkRequest(QUrl("http://www.foo.com")) << QWebPage::NavigationTypeLinkClicked << true << 0; + QTest::newRow("normal-1") << Qt::NoButton << Qt::NoModifier << true << QNetworkRequest(QUrl("http://www.foo.com")) << QWebPage::NavigationTypeLinkClicked << true << 1; + + QTest::newRow("midclick-0") << Qt::MidButton << Qt::NoModifier << true << QNetworkRequest(QUrl("http://www.foo.com")) << QWebPage::NavigationTypeLinkClicked << false << 0; + QTest::newRow("midclick-1") << Qt::MidButton << Qt::ShiftModifier << true << QNetworkRequest(QUrl("http://www.foo.com")) << QWebPage::NavigationTypeLinkClicked << false << 0; + QTest::newRow("midclick-2") << Qt::MidButton << Qt::AltModifier << true << QNetworkRequest(QUrl("http://www.foo.com")) << QWebPage::NavigationTypeLinkClicked << false << 0; +} + +// protected bool acceptNavigationRequest(QWebFrame *frame, QNetworkRequest const &request, NavigationType type) +void tst_WebPage::acceptNavigationRequest() +{ + QFETCH(Qt::MouseButton, pressedButton); + QFETCH(Qt::KeyboardModifier, pressedKeys); + QFETCH(bool, validFrame); + QFETCH(QNetworkRequest, request); + QFETCH(QWebPage::NavigationType, type); + QFETCH(bool, acceptNavigationRequest); + QFETCH(int, spyCount); + + BrowserApplication::instance()->setEventMouseButtons(pressedButton); + BrowserApplication::instance()->setEventKeyboardModifiers(pressedKeys); + SubWebPage page; + QSignalSpy spy0(&page, SIGNAL(aboutToLoadUrl(QUrl const&))); + + QWebFrame *frame = validFrame ? page.mainFrame() : (QWebFrame*)0; + QCOMPARE(page.call_acceptNavigationRequest(frame, request, type), acceptNavigationRequest); + + QCOMPARE(spy0.count(), spyCount); + BrowserApplication::instance()->setEventMouseButtons(Qt::NoButton); + BrowserApplication::instance()->setEventKeyboardModifiers(Qt::NoModifier); +} + +Q_DECLARE_METATYPE(QStringList) +Q_DECLARE_METATYPE(QObject*) +void tst_WebPage::createPlugin_data() +{ +#if 0 + QTest::addColumn("classId"); + QTest::addColumn("url"); + QTest::addColumn("paramNames"); + QTest::addColumn("paramValues"); + QTest::addColumn("createPlugin"); + QTest::newRow("null") << QString() << QUrl() << QStringList() << QStringList() << QObject*(); +#endif +} + +// protected QObject *createPlugin(QString const &classId, QUrl const &url, QStringList const ¶mNames, QStringList const ¶mValues) +void tst_WebPage::createPlugin() +{ +#if 0 + QFETCH(QString, classId); + QFETCH(QUrl, url); + QFETCH(QStringList, paramNames); + QFETCH(QStringList, paramValues); + QFETCH(QObject*, createPlugin); + + SubWebPage page; + + QSignalSpy spy0(&page, SIGNAL(aboutToLoadUrl(QUrl const&))); + + QCOMPARE(page.call_createPlugin(classId, url, paramNames, paramValues), createPlugin); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +Q_DECLARE_METATYPE(QWebPage*) +void tst_WebPage::createWindow_data() +{ +#if 0 + QTest::addColumn("type"); + QTest::addColumn("createWindow"); + QTest::newRow("null") << QWebPage::WebWindowType() << QWebPage*(); +#endif +} + +// protected QWebPage *createWindow(QWebPage::WebWindowType type) +void tst_WebPage::createWindow() +{ +#if 0 + QFETCH(QWebPage::WebWindowType, type); + QFETCH(QWebPage*, createWindow); + + SubWebPage page; + + QSignalSpy spy0(&page, SIGNAL(aboutToLoadUrl(QUrl const&))); + + QCOMPARE(page.call_createWindow(type), createWindow); + + QCOMPARE(spy0.count(), 0); +#endif + QSKIP("Test is not implemented.", SkipAll); +} + +void tst_WebPage::handleUnsupportedContent() +{ + SubWebPage page; + QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); + page.mainFrame()->load(QUrl("http://exampletesttesttesttesttesttes.com/test.html")); + QTRY_COMPARE(spy.count(), 1); +} + +void tst_WebPage::linkedResources() +{ + SubWebPage page; + + QString html = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + ""; + + page.mainFrame()->setHtml(html, QUrl("http://foobar.baz/foo/")); + + QList resources = page.linkedResources(); + QCOMPARE(resources.count(), 4); + + QCOMPARE(resources.at(0).rel, QString("stylesheet")); + QCOMPARE(resources.at(0).type, QString("text/css")); + QCOMPARE(resources.at(0).href, QUrl("http://foobar.baz/foo/styles/common.css")); + QCOMPARE(resources.at(0).title, QString()); + + QCOMPARE(resources.at(1).rel, QString("alternate")); + QCOMPARE(resources.at(1).type, QString("application/rss+xml")); + QCOMPARE(resources.at(1).href, QUrl("http://foobar.baz/foo/rss.xml")); + + QCOMPARE(resources.at(2).href, QUrl("http://foobar.baz/atom.xml")); + QCOMPARE(resources.at(2).title, QString("Feed")); + + QCOMPARE(resources.at(3).rel, QString("search")); + QCOMPARE(resources.at(3).type, QString("application/opensearchdescription+xml")); + QCOMPARE(resources.at(3).href, QUrl("http://external.foo/search.xml")); + + QString js = "var base = document.createElement('base');" + "base.setAttribute('href', 'http://barbaz.foo/bar/');" + "document.getElementsByTagName('head')[0].appendChild(base);"; + + page.mainFrame()->evaluateJavaScript(js); + + resources = page.linkedResources(); + QCOMPARE(resources.count(), 4); + + QCOMPARE(resources.at(0).href, QUrl("http://barbaz.foo/bar/styles/common.css")); + QCOMPARE(resources.at(1).href, QUrl("http://barbaz.foo/bar/rss.xml")); + QCOMPARE(resources.at(2).href, QUrl("http://barbaz.foo/atom.xml")); + QCOMPARE(resources.at(3).href, QUrl("http://external.foo/search.xml")); +} + +void tst_WebPage::javaScriptObjects_data() +{ + QTest::addColumn("url"); + QTest::addColumn("windowExternal"); + QTest::addColumn("windowArora"); + + QTest::newRow("qrc:/notfound.html") << QUrl("qrc:/notfound.html") << true << false; + QTest::newRow("qrc:/startpage.html") << QUrl("qrc:/startpage.html") << true << true; +} + +void tst_WebPage::javaScriptObjects() +{ + QFETCH(QUrl, url); + QFETCH(bool, windowExternal); + QFETCH(bool, windowArora); + + SubWebPage page; + QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); + page.mainFrame()->load(url); + QTRY_COMPARE(spy.count(), 1); + + QVariant windowExternalVariant = page.mainFrame()->evaluateJavaScript(QLatin1String("window.external")); + QVariant windowAroraVariant = page.mainFrame()->evaluateJavaScript(QLatin1String("window.arora")); + + QCOMPARE(windowExternal, !windowExternalVariant.isNull()); + QCOMPARE(windowArora, !windowAroraVariant.isNull()); +} + +void tst_WebPage::userAgent() +{ + QSettings settings; + settings.setValue("userAgent", QString()); + SubWebPage page; + QString defaultUserAgent = page.call_userAgentForUrl(QUrl()); + QVERIFY(!defaultUserAgent.isEmpty()); + QVERIFY(defaultUserAgent.contains("tst_webpage")); + settings.setValue("userAgent", "ben"); + page.loadSettings(); + QString customUserAgent = page.call_userAgentForUrl(QUrl()); + QVERIFY(!customUserAgent.isEmpty()); + QCOMPARE(customUserAgent, QString("ben")); +} + + +QTEST_MAIN(tst_WebPage) +#include "tst_webpage.moc" + diff --git a/autotests/edittreeview/edittreeview.pro b/autotests/webpage/webpage.pro similarity index 77% rename from autotests/edittreeview/edittreeview.pro rename to autotests/webpage/webpage.pro index 521acda8..cd99685e 100644 --- a/autotests/edittreeview/edittreeview.pro +++ b/autotests/webpage/webpage.pro @@ -6,5 +6,5 @@ INCLUDEPATH += . ../ include(../autotests.pri) # Input -SOURCES += tst_edittreeview.cpp +SOURCES += tst_webpage.cpp HEADERS += diff --git a/autotests/xbel/.gitignore b/autotests/xbel/.gitignore new file mode 100644 index 00000000..aab0929b --- /dev/null +++ b/autotests/xbel/.gitignore @@ -0,0 +1 @@ +xbel diff --git a/autotests/xbel/all.xbel b/autotests/xbel/all.xbel index ca6227f0..2cfce66e 100644 --- a/autotests/xbel/all.xbel +++ b/autotests/xbel/all.xbel @@ -15,11 +15,14 @@ Title 2 + + Title 3 + Has SubFolder - + SubFolder @@ -30,6 +33,6 @@ Title3 - + diff --git a/autotests/xbel/bad.xbel b/autotests/xbel/bad.xbel index d81ace82..0fa652d2 100644 --- a/autotests/xbel/bad.xbel +++ b/autotests/xbel/bad.xbel @@ -19,7 +19,7 @@ Has SubFolder - + SubFolder @@ -30,6 +30,6 @@ Title3 - + diff --git a/autotests/xbel/tst_xbel.cpp b/autotests/xbel/tst_xbel.cpp index 2a69373a..6700f756 100644 --- a/autotests/xbel/tst_xbel.cpp +++ b/autotests/xbel/tst_xbel.cpp @@ -18,7 +18,10 @@ */ #include -#include + +#include "bookmarknode.h" +#include "xbelreader.h" +#include "xbelwriter.h" class tst_Xbel : public QObject { @@ -90,8 +93,10 @@ void tst_Xbel::xbelreader_data() void tst_Xbel::xbelreader() { SubXbelReader reader; - QVERIFY(reader.read(QString())); + BookmarkNode *root = reader.read(QString()); + QVERIFY(root); QVERIFY(reader.error() == QXmlStreamReader::NoError); + delete root; } Q_DECLARE_METATYPE(QXmlStreamReader::Error) @@ -105,7 +110,7 @@ void tst_Xbel::read_data() QTest::newRow("bad") << QString("bad.xbel") << QXmlStreamReader::CustomError; } -// public BookmarkNode* read(QString const& fileName) +// public BookmarkNode *read(QString const &fileName) void tst_Xbel::read() { QFETCH(QString, fileName); @@ -113,7 +118,9 @@ void tst_Xbel::read() SubXbelReader reader; - QVERIFY(reader.read(fileName)); + BookmarkNode *root = reader.read(fileName); + QVERIFY(root); + delete root; QCOMPARE(reader.error(), error); } @@ -122,7 +129,7 @@ void tst_Xbel::readProperly() SubXbelReader reader; BookmarkNode *root = reader.read("all.xbel"); QCOMPARE(reader.error(), QXmlStreamReader::NoError); - QListchildren = root->children(); + QListchildren = root->children(); QCOMPARE(children.count(), 4); // null folder QCOMPARE(children[0]->children().count(), 0); @@ -137,8 +144,7 @@ void tst_Xbel::readProperly() QCOMPARE(children[1]->expanded, true); QCOMPARE(children[1]->type(), BookmarkNode::Folder); - // folder with two bookmarks - QCOMPARE(children[2]->children().count(), 2); + QCOMPARE(children[2]->children().count(), 3); QCOMPARE(children[2]->title, QString("Folder Title")); QCOMPARE(children[2]->url, QString()); QCOMPARE(children[2]->expanded, false); @@ -156,6 +162,8 @@ void tst_Xbel::readProperly() QCOMPARE(children[1]->url, QString("http://www.bar.com/")); QCOMPARE(children[1]->expanded, false); QCOMPARE(children[1]->type(), BookmarkNode::Bookmark); + + QCOMPARE(children[2]->title, QString("Title 3")); } children = root->children(); @@ -185,6 +193,7 @@ void tst_Xbel::readProperly() QCOMPARE(children[2]->expanded, false); QCOMPARE(children[2]->type(), BookmarkNode::Separator); } + delete root; } @@ -207,7 +216,7 @@ void tst_Xbel::write_data() QTest::newRow("all") << QString("all.xbel"); } -// public BookmarkNode* read(QString const& fileName) +// public BookmarkNode *read(QString const &fileName) void tst_Xbel::write() { QFETCH(QString, readFileName); @@ -223,6 +232,8 @@ void tst_Xbel::write() QVERIFY(writer.write(file.fileName(), root)); BookmarkNode *writtenRoot = reader.read(file.fileName()); QVERIFY(*writtenRoot == *root); + delete root; + delete writtenRoot; } QTEST_MAIN(tst_Xbel) diff --git a/autotests/xbel/xbel.pro b/autotests/xbel/xbel.pro index c40ebf6c..d9e417c7 100644 --- a/autotests/xbel/xbel.pro +++ b/autotests/xbel/xbel.pro @@ -6,5 +6,13 @@ INCLUDEPATH += . include(../autotests.pri) # Input -SOURCES = tst_xbel.cpp xbel.cpp -HEADERS = xbel.h +SOURCES = \ + tst_xbel.cpp \ + bookmarks/bookmarknode.cpp \ + bookmarks/xbel/xbelreader.cpp \ + bookmarks/xbel/xbelwriter.cpp + +HEADERS = \ + bookmarks/bookmarknode.h \ + bookmarks/xbel/xbelreader.h \ + bookmarks/xbel/xbelwriter.h diff --git a/buildosx.sh b/buildosx.sh new file mode 100755 index 00000000..360aa7e8 --- /dev/null +++ b/buildosx.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# +# This script requires the use of the macdeployqt tool that is found in Qt 4.5 +# + +APP="Arora" +VERSION="0.11.0" +#BACKGROUND="src/data/512x512/arora.png" + +DIR="bundle" +if [ -d $DIR.app ] ; then + echo "$DIR.app already exists" + exit 1; +fi + +# build app with Qt libraries +make distclean --quiet +qmake -r -config release +make --quiet +$QTDIR/bin/macdeployqt $APP.app/ + +# Create Bundle +mkdir $DIR +#cp $BACKGROUND $DIR/.Background.png +cp -rf $APP.app $DIR/ +hdiutil create -ov -srcfolder $DIR -format UDBZ -volname "$APP $VERSION" "$APP.dmg" +hdiutil internet-enable -yes "$APP.dmg" +rm -rf $DIR + +DATE=`date +"%m-%d-%Y"` +QTVERSION=`qmake --version | grep Qt | sed -e s/.*4/4/g -e 's/\/.*//g'` +mv $APP.dmg "$APP Snapshot ($DATE) Intel-Qt$QTVERSION.dmg" diff --git a/debian-upstream/arora.1 b/debian-upstream/arora.1 deleted file mode 100644 index ff420ac5..00000000 --- a/debian-upstream/arora.1 +++ /dev/null @@ -1,34 +0,0 @@ -.TH ARORA "1" "May 2008" - -.SH NAME -Arora - Lightweight web browser based on Qt and WebKit - -.SH SYNOPSIS -.B arora - -.SH DESCRIPTION -.B Arora -is a lightweight, cross-platform web browser using the Qt 4.4 port of the WebKit -layout engine. It is based on the demo browser application shipped with Qt -demos. -.PP -.B Arora -cannot be used from the command line, as it is Qt-based software. -Please run it under X. - -.SH OPTIONS -.B Arora -has no options. - -.SH BUGS -Please report bugs to \fIhttp://code.google.com/p/arora/issues/list\fR. - -.SH AUTHOR -Arora is developed by Benjamin C. Meyer , based on code release by Trolltech ASA. -.PP -This manual page was written by Matvey Kozhev for the Ubuntu system (but may be used by others). -.PP -Permission is granted to copy, distribute and/or modify this document under the terms of the -GNU General Public License, Version 2 or any later version published by the Free Software Foundation. -.PP -On Debian systems, the complete text of the GNU General Public License can be found in /usr/share/common-licenses/GPL. diff --git a/debian-upstream/arora.menu b/debian-upstream/arora.menu new file mode 100644 index 00000000..f410cd82 --- /dev/null +++ b/debian-upstream/arora.menu @@ -0,0 +1,3 @@ +?package(arora):needs="x11" section="Applications/Network/Web Browsing" \ + title="Arora" longtitle="Arora Web Browser" \ + command="arora" icon="/usr/share/pixmaps/arora.xpm" diff --git a/debian-upstream/arora.postinst b/debian-upstream/arora.postinst new file mode 100644 index 00000000..b8268742 --- /dev/null +++ b/debian-upstream/arora.postinst @@ -0,0 +1,8 @@ +#!/bin/sh +set -e + +update-alternatives --install \ + /usr/bin/x-www-browser x-www-browser /usr/bin/arora 90 \ + --slave /usr/share/man/man1/x-www-browser.1.gz x-www-browser.1.gz /usr/share/man/man1/arora.1.gz + +#DEBHELPER# diff --git a/debian-upstream/arora.prerm b/debian-upstream/arora.prerm new file mode 100644 index 00000000..e139f5cf --- /dev/null +++ b/debian-upstream/arora.prerm @@ -0,0 +1,10 @@ +#!/bin/sh +set -e + +if [ "$1" = "remove" ] || [ "$1" = "deconfigure" ] ; then + update-alternatives --remove x-www-browser /usr/bin/arora +fi + +#DEBHELPER# + +exit 0 diff --git a/debian-upstream/changelog.in b/debian-upstream/changelog.in index d938507a..37daf6f4 100644 --- a/debian-upstream/changelog.in +++ b/debian-upstream/changelog.in @@ -1,4 +1,4 @@ -arora (0.2~git##DATE##-1~##DIST##1~upstream1) ##DIST##; urgency=low +arora (0.11.0~git##DATE##-1~##DIST##1~upstream1) ##DIST##; urgency=low * Initial release (LP: #231731) diff --git a/debian-upstream/compat b/debian-upstream/compat index 1e8b3149..7ed6ff82 100644 --- a/debian-upstream/compat +++ b/debian-upstream/compat @@ -1 +1 @@ -6 +5 diff --git a/debian-upstream/control b/debian-upstream/control index 491ad9bc..010aaff7 100644 --- a/debian-upstream/control +++ b/debian-upstream/control @@ -1,23 +1,13 @@ Source: arora Section: web -Priority: optional -Maintainer: Ubuntu MOTU Developers -XSBC-Original-Maintainer: Matvey Kozhev -Build-Depends: cdbs, debhelper (>= 6), git-core, libqt4-dev (>= 4.4.0) +Priority: extra +Maintainer: Sune Vuorela +Build-Depends: debhelper (>= 5), libqt4-dev (>= 4.5) Standards-Version: 3.7.3 -Homepage: http://arora-browser.org Package: arora Architecture: any -Depends: ${shlibs:Depends} -Description: Lightweight web browser based on Qt and WebKit - Arora is a lightweight, cross-platform web browser using the Qt 4.4 port of - the WebKit layout engine. It is based on the demo browser application shipped - with Qt demos. - . - Its features include: - * WebKit layout engine - * History - * Bookmarks - * User styles - * Tabbed browsing +Depends: ${shlibs:Depends}, ${misc:Depends} +Provides: www-browser +Description: Arora is an open-source browser project that aims to build a cross-platform + WebKit browser that integrates with every desktop. diff --git a/debian-upstream/copyright b/debian-upstream/copyright index 429bb894..0750b3a1 100644 --- a/debian-upstream/copyright +++ b/debian-upstream/copyright @@ -1,54 +1,49 @@ -This package was debianized by Matvey Kozhev on -Sun, 18 May 2008 22:29:04 +0700. +This package was debianized by Sune Vuorela on +Sun, 25 May 2008 15:45:28 +0200. + +It was downloaded from http://arora-browser.org + +Upstream Author: + + Benjamin Meyer + +Copyright: + Copyright 1998-1999 Netscape Communications Corporation. All + Copyright 2005-2008 Trolltech ASA. All rights reserved. + Copyright 2006 Junio C Hamano + Copyright 2007-2009 Benjamin C. Meyer + Copyright 2008 Ariya Hidayat + Copyright 2008-2009 Christian Franke + Copyright 2008 Diego Iastrubni, elcuco, at, kde.org + Copyright 2008 Jason A. Donenfeld + Copyright 2008 Matvey Kozhev + Copyright 2008-2009 Arora Developers + Copyright 2008-2009 Benjamin K. Stuhl + Copyright 2008-2009 Jason A. Donenfeld + Copyright 2009 Jakub Wieczorek + Copyright 2009 Torch Mobile Inc. http://www.torchmobile.com/ -It was downloaded from . +License: -Upstream Authors: +The contents is a mix of files under GPLv2, GPLv2 or later, GPLv2 with Trolltech exceptions. +Effectively, this makes the package GPLv2: - Copyright 2008 Benjamin C. Meyer - Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. + This package 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; either version 2 of the License, or + (at your option) any later version. -License: + This package 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 package; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - This file may be used under the terms of the GNU General Public - License versions 2.0 or 3.0 as published by the Free Software - Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 - included in the packaging of this file. Alternatively you may (at - your option) use any later version of the GNU General Public - License if such license has been publicly approved by Trolltech ASA - (or its successors, if any) and the KDE Free Qt Foundation. In - addition, as a special exception, Trolltech gives you certain - additional rights. These rights are described in the Trolltech GPL - Exception version 1.2, which can be found at - http://www.trolltech.com/products/qt/gplexception/ and in the file - GPL_EXCEPTION.txt in this package. - - Please review the following information to ensure GNU General - Public Licensing requirements will be met: - http://trolltech.com/products/qt/licenses/licensing/opensource/. If - you are unsure which license is appropriate for your use, please - review the following information: - http://trolltech.com/products/qt/licenses/licensing/licensingoverview - or contact the sales department at sales@trolltech.com. - - In addition, as a special exception, Trolltech, as the sole - copyright holder for Qt Designer, grants users of the Qt/Eclipse - Integration plug-in the right for the Qt/Eclipse Integration to - link to functionality provided by Qt Designer and its related - libraries. - - This file is provided "AS IS" with NO WARRANTY OF ANY KIND, - INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly - granted herein. - - This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE - WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -The Debian packaging is (C) 2008, Matvey Kozhev and -is licensed under the same conditions as above. - -On Debian systems, the complete text of the GNU General Public License is -available at `/usr/share/common-licenses/GPL-2' for version 2 and -`/usr/share/common-licenses/GPL-3' for version 3. +On Debian systems, the complete text of the GNU General +Public License can be found in `/usr/share/common-licenses/GPL-2'. +The Debian packaging is (C) 2008, Sune Vuorela and +is licensed under the GPL, see above. diff --git a/debian-upstream/dirs b/debian-upstream/dirs deleted file mode 100644 index 9622f20f..00000000 --- a/debian-upstream/dirs +++ /dev/null @@ -1,3 +0,0 @@ -usr/share/icons/hicolor/16x16/apps -usr/share/icons/hicolor/32x32/apps -usr/share/icons/hicolor/128x128/apps diff --git a/debian-upstream/manpages b/debian-upstream/manpages deleted file mode 100644 index dce3afda..00000000 --- a/debian-upstream/manpages +++ /dev/null @@ -1 +0,0 @@ -debian/arora.1 diff --git a/debian-upstream/rules b/debian-upstream/rules index 99293e4d..33f04a33 100755 --- a/debian-upstream/rules +++ b/debian-upstream/rules @@ -1,26 +1,56 @@ #!/usr/bin/make -f - -include /usr/share/cdbs/1/rules/debhelper.mk -include /usr/share/cdbs/1/class/qmake.mk - -QMAKE = qmake-qt4 -DEB_QMAKE_ARGS += PREFIX=/usr QMAKE_LFLAGS+=-Wl,--as-needed -DEB_PHONY_RULES += get-orig-source -VERSION = $(shell dpkg-parsechangelog | egrep '^Version' | sed s/"Version: "//) -UPSTREAM_VERSION = $(shell echo $(VERSION) | sed s/-.*//) -DEB_INSTALL_CHANGELOGS_ALL = ChangeLog - -makebuilddir/arora:: - ./generateAuthors - -install/arora:: - cp src/data/arora-16.png debian/arora/usr/share/icons/hicolor/16x16/apps/arora.png - cp src/data/arora-32.png debian/arora/usr/share/icons/hicolor/32x32/apps/arora.png - cp src/data/arora-128.png debian/arora/usr/share/icons/hicolor/128x128/apps/arora.png - -get-orig-source: - cd debian && git clone git://github.com/icefox/arora.git arora-$(UPSTREAM_VERSION) - cd debian/arora-$(UPSTREAM_VERSION) && \ - git archive --format=tar --prefix=arora-$(UPSTREAM_VERSION)/ HEAD | \ - gzip -9c > ../../../arora_$(UPSTREAM_VERSION).orig.tar.gz - rm -rf debian/arora-$(UPSTREAM_VERSION) +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + + +builddir: + mkdir -p builddir + +builddir/Makefile: builddir + cd builddir && qmake-qt4 PREFIX=/usr ../arora.pro + +build: build-stamp + +build-stamp: builddir/Makefile + dh_testdir + cd builddir && $(MAKE) + touch $@ + +clean: + dh_testdir + dh_testroot + rm -rf builddir + dh_clean build-stamp + +install: build + dh_testdir + dh_testroot + dh_clean -k + cd builddir && $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/arora install + +binary-indep: build install + +binary-arch: build install + dh_testdir + dh_testroot + dh_installchangelogs ChangeLog + dh_installdocs + dh_link + dh_strip + dh_compress + dh_fixperms + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/debian-upstream/watch b/debian-upstream/watch new file mode 100644 index 00000000..78e6b00c --- /dev/null +++ b/debian-upstream/watch @@ -0,0 +1,3 @@ +version=3 +http://code.google.com/p/arora/downloads/list \ + http://arora.googlecode.com/files/arora-([\d\.]+)\.tar\.gz diff --git a/generateAuthors b/generateAuthors index 738b8205..7f939d93 100755 --- a/generateAuthors +++ b/generateAuthors @@ -1 +1,28 @@ -git log --pretty="format:%an %ae" | sort | uniq -c | sort -n -r | sed -e 's/^ *[0-9]* //g' +#!/bin/sh +# +# Generate a list of everyone who has contributed to the project merging those who commited under two names or email addresses. +# +# To can pass an arg (which goes to git log) +# Example: to see everyone who contributed between tag 0.6 and now +# ./generateAuthors 0.6..HEAD +# +# Currently this is sorted based on # of commits, sorting contributions is not a simple topic +# as pointed out in this article http://lwn.net/Articles/222773/ +# +git log --pretty="format:%an %ae" $1 \ + | sed -e 's/smart2128 /Vincenzo Reale /g' \ + | sed -e 's/buster\.xtense\.dyndns\.org/ts2server\.com/g' \ + | sed -e 's/^cfchris6 /Christian Franke /g' \ + | sed -e 's/^faw /Jakub Wieczorek /g' \ + | sed -e 's/^LEW21 /Janusz Lewandowski /g' \ + | sed -e 's/lew21@pecet.(none)$/lew21st@gmail.com/g' \ + | sed -e 's/adam\.treat@torchmobile\.com/treat@kde\.org/g' \ + | sed -e 's/torarnv@gmail\.com/tavestbo@trolltech\.com/g' \ + | sed -e 's/bks@coldkeck2\.colorado\.edu/bks24@cornell\.edu/g' \ + | sed -e 's/porphyr /Mark Reiche /g' \ + | sed -e 's/vinx@zulu\.(none)/smart2128@baslug\.org/g' \ + | sed -e 's/Matvey Kozhev/Maia Kozheva/g' \ + | sed -e 's/kristof@localhost.(none)/kristof.bal@gmail.com/g' \ + | sed -e 's/tavestbo@trolltech.com/tor.arne.vestbo@nokia.com/g' \ + | sed -e 's/ariya.hidayat@trolltech.com/ariya.hidayat@gmail.com/g' \ + | sort | uniq -c | sort -n -r | sed -e 's/^ *[0-9]* //g' diff --git a/generateReleaseContributors b/generateReleaseContributors new file mode 100755 index 00000000..0670b95a --- /dev/null +++ b/generateReleaseContributors @@ -0,0 +1,15 @@ +#!/bin/bash +./generateAuthors 0.10.2..HEAD | while read line +do + name=`echo $line | sed -e 's/ [^ ]*@[^ ]*//g'` + email=`echo $line | sed -e 's/.* //g' | tr [A-Z] [a-z]` + echo -n "\"$name\"src=\"https://secure.gravatar.com/avatar/""; + echo " $name $email
" +done + diff --git a/git_hooks/README b/git_hooks/README index ba49e99a..add9c11f 100644 --- a/git_hooks/README +++ b/git_hooks/README @@ -1,9 +1,9 @@ -These are various git hooks that are used to help improve the quality of Arora. Use them if you want. To install them replace the arora/.git/hooks directory with a symlink to this directory. +These are various git hooks that are used to help improve the quality of Arora. -cd .git/ -rm -rf .hooks -ln -s ../git_hooks hooks +They are managed using the git-hooks tool (Available here http://github.com/icefox/git-hooks) -TODO: +To enable them run "git hooks --install" + +Some hooks to add: check for a license in the file commited -check that the author has a copyright statement in the file they are modifing \ No newline at end of file +check that the author has a copyright statement in the file they are modifing diff --git a/git_hooks/applypatch-msg b/git_hooks/applypatch-msg deleted file mode 100644 index 02de1ef8..00000000 --- a/git_hooks/applypatch-msg +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, make this file executable. - -. git-sh-setup -test -x "$GIT_DIR/hooks/commit-msg" && - exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} -: diff --git a/git_hooks/commit-msg b/git_hooks/commit-msg deleted file mode 100644 index c5cdb9d7..00000000 --- a/git_hooks/commit-msg +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by git-commit with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, make this file executable. - -# Uncomment the below to add a Signed-off-by line to the message. -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/git_hooks/helper/findstyleerrors.sh b/git_hooks/helper/findstyleerrors.sh new file mode 100755 index 00000000..ea0bcb3c --- /dev/null +++ b/git_hooks/helper/findstyleerrors.sh @@ -0,0 +1,42 @@ +#!/bin/sh +# +# Coding style: http://code.google.com/p/arora/wiki/CodingStyle +# + +case "${1}" in + --about ) + echo "Hack of a script to find some common style errors." + exit 0 + ;; +esac + + +args=$1 +if [ -z "${args}" ] ; then + args="*" +fi + +options="-n --exclude=moc_* --exclude=qrc_* --include=*.cpp --include=*.h -r" + +grep $options '( ' $args +grep $options ' )' $args +grep $options 'if(' $args +grep $options 'for(' $args +grep $options 'while(' $args +grep $options 'switch(' $args +grep $options 'foreach(' $args +grep $options ' $' $args +grep $options '^{ }*{' $args +grep $options '){' $args +grep $options ' ' $args +grep $options ' \*>' $args +grep $options '#include "q' $args +egrep $options '\(.*\* .*\)' $args | grep '::' +grep $options '[a-z]++' $args | grep 'for' +grep $options '[a-z]--' $args | grep 'for' + +# var *name; +grep $options '[^\* \/]\* ' $args +grep $options '[^& ]& ' $args + +exit 0 diff --git a/git_hooks/post-commit b/git_hooks/post-commit deleted file mode 100644 index 8be6f34a..00000000 --- a/git_hooks/post-commit +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script that is called after a successful -# commit is made. -# -# To enable this hook, make this file executable. - -: Nothing diff --git a/git_hooks/post-receive b/git_hooks/post-receive deleted file mode 100644 index b70c8fd3..00000000 --- a/git_hooks/post-receive +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# -# An example hook script for the post-receive event -# -# This script is run after receive-pack has accepted a pack and the -# repository has been updated. It is passed arguments in through stdin -# in the form -# -# For example: -# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master -# -# see contrib/hooks/ for an sample, or uncomment the next line (on debian) -# - - -#. /usr/share/doc/git-core/contrib/hooks/post-receive-email diff --git a/git_hooks/post-update b/git_hooks/post-update deleted file mode 100644 index bcba8937..00000000 --- a/git_hooks/post-update +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, make this file executable by "chmod +x post-update". - -exec git-update-server-info diff --git a/git_hooks/pre-applypatch b/git_hooks/pre-applypatch deleted file mode 100644 index eeccc934..00000000 --- a/git_hooks/pre-applypatch +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, make this file executable. - -. git-sh-setup -test -x "$GIT_DIR/hooks/pre-commit" && - exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} -: diff --git a/git_hooks/pre-commit b/git_hooks/pre-commit deleted file mode 100755 index 0597b2c9..00000000 --- a/git_hooks/pre-commit +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -e -# -# An example hook script to verify what is about to be committed. -# Called by git-commit with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, make this file executable. - -# This is slightly modified from Andrew Morton's Perfect Patch. -# Lines you introduce should not have trailing whitespace. -# Also check for an indentation that has SP before a TAB. - -if git-rev-parse --verify HEAD 2>/dev/null -then - git-diff-index -p -M --cached HEAD -else - # NEEDSWORK: we should produce a diff with an empty tree here - # if we want to do the same verification for the initial import. - : -fi | -perl -e ' - my $found_bad = 0; - my $filename; - my $reported_filename = ""; - my $lineno; - sub bad_line { - my ($why, $line) = @_; - if (!$found_bad) { - print STDERR "*\n"; - print STDERR "* You have some suspicious patch lines:\n"; - print STDERR "*\n"; - $found_bad = 1; - } - if ($reported_filename ne $filename) { - print STDERR "* In $filename\n"; - $reported_filename = $filename; - } - print STDERR "* $why (line $lineno)\n"; - print STDERR "$filename:$lineno:$line\n"; - } - while (<>) { - if (m|^diff --git a/(.*) b/\1$|) { - $filename = $1; - next; - } - if (/^@@ -\S+ \+(\d+)/) { - $lineno = $1 - 1; - next; - } - if (/^ /) { - $lineno++; - next; - } - if (s/^\+//) { - $lineno++; - chomp; - if (/\s$/) { - bad_line("trailing whitespace", $_); - } - if (/^\s* /) { - bad_line("indent SP followed by a TAB", $_); - } - if (/^(?:[<>=]){7}/) { - bad_line("unresolved merge conflict", $_); - } - } - } - exit($found_bad); -' - -dir=`dirname $0` -for check in `ls -1 $dir/pre-commit_*` ; do - $check -done diff --git a/git_hooks/pre-commit/compile b/git_hooks/pre-commit/compile new file mode 100755 index 00000000..f805c463 --- /dev/null +++ b/git_hooks/pre-commit/compile @@ -0,0 +1,49 @@ +#!/bin/bash +# +# Copyright (c) 2010, Benjamin C. Meyer +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +function compile { + unset GIT_DIR + echo "--Attempting to build in $PWD--" + if [ -f Makefile ] ; then + make --quiet + if [ $? != 0 ] ; then + echo "--Build failed, fix failure before commiting--"; + exit 1 + fi + fi + echo "--Attempting to build pass--" +} + +case "${1}" in + --about ) + echo "Wherever you are make sure something compiles". + ;; + * ) + compile + ;; +esac diff --git a/git_hooks/pre-commit/compile_manualtest b/git_hooks/pre-commit/compile_manualtest new file mode 100755 index 00000000..29ed2f2c --- /dev/null +++ b/git_hooks/pre-commit/compile_manualtest @@ -0,0 +1,64 @@ +#!/bin/bash +# +# Copyright (c) 2010, Benjamin C. Meyer +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +dir=`dirname $0` + +function test_file { + file="${1}" + QMAKE=qmake + $QMAKE --version 2>&1 | grep 3.3 > /dev/null + if [ $? -eq 0 ] ; then + QMAKE=qmake-qt4 + fi + file=`echo $file | sed -e 's/src\///g' -e 's/.cpp//g'` + if [ ! -d $dir/../autotests/$file ] ; then + file=`echo $file | sed -e 's/.*\///g'`; + fi + if [ -d $dir/../manualtests/$file ] ; then + echo "--checking manualtest (should still build): $file--" + cd "$dir/../../manualtests/$file/"; + $QMAKE; + make --quiet + if [ $? != 0 ] ; then + echo "--Manualtest build failed, fix failure before commiting--"; + exit 1 + fi + echo "--checking manualtest: $file done--" + fi +} + +case "${1}" in + --about ) + echo "Check that existing manualtest for files that are being commited still build They can break when the API changes." + ;; + * ) + for file in `git diff-index --cached --name-only HEAD | grep .cpp` ; do + test_file "${file}" + done + ;; +esac diff --git a/git_hooks/pre-commit/copyrightyear b/git_hooks/pre-commit/copyrightyear new file mode 100755 index 00000000..ce5fe21a --- /dev/null +++ b/git_hooks/pre-commit/copyrightyear @@ -0,0 +1,50 @@ +#!/bin/bash +# +# Copyright (c) 2010-2014, Benjamin C. Meyer +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +function test_file { + if [ ! -f $file ] ; then + return + fi + year=`date +%Y` + echo "--checking copyright year: $file" + grep $year $file >> /dev/null + if [ $? -ne 0 ] ; then + echo "Warning: $file seems to be missing a copyright string with the year $year in it."; + fi +} + +case "${1}" in + --about ) + echo "Check the files that are being committed for a copyright with a proper year." + ;; + * ) + for file in `git diff-index --cached --name-only HEAD` ; do + test_file "${file}" + done + ;; +esac diff --git a/git_hooks/pre-commit/run_autotest b/git_hooks/pre-commit/run_autotest new file mode 100755 index 00000000..d1682f24 --- /dev/null +++ b/git_hooks/pre-commit/run_autotest @@ -0,0 +1,73 @@ +#!/bin/bash +# +# Copyright (c) 2010, Benjamin C. Meyer +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +dir=`dirname $0` + +function test_file { + file="${1}" + QMAKE=qmake + $QMAKE --version 2>&1 | grep 3.3 > /dev/null + if [ $? -eq 0 ] ; then + QMAKE=qmake-qt4 + fi + unset GIT_DIR + file=`echo $file | sed -e 's/src\///g' -e 's/.cpp//g'` + autotest=`echo $file | sed -e 's/.*\///g'` + if [ ! -d $dir/../autotests/$file ] ; then + file=$autotest; + fi + if [ -d $dir/../autotests/$file ] ; then + echo "--checking autotest: $file--" + + tempfoo=`basename $0` + TMPFILE=`mktemp -t ${tempfoo}.XXXXXXXXXX` || exit 1 + (cd "$dir/../../autotests/$file/"; $QMAKE; make --quiet $MAKE_FLAGS; ./$autotest >> $TMPFILE) + output=`cat $TMPFILE | grep ' failed,' | sed -e 's/.*passed, //g' -e 's/ failed.*//g'` + if [ "${output}" != "0" ] ; then + echo "Autotests failed for $file, please fix before committing." + cat $TMPFILE + rm $TMPFILE + exit 1 + fi + rm $TMPFILE + echo "--checking autotest: $file done--" + else + echo "--missing autotest: $file--" + fi +} + +case "${1}" in + --about ) + echo "Check that existing autotests for files that are being commited are not currently failing." + ;; + * ) + for file in `git diff-index --cached --name-only HEAD | grep .cpp` ; do + test_file "${file}" + done + ;; +esac diff --git a/git_hooks/pre-commit/stylecheck_astyle b/git_hooks/pre-commit/stylecheck_astyle new file mode 100755 index 00000000..2ba26109 --- /dev/null +++ b/git_hooks/pre-commit/stylecheck_astyle @@ -0,0 +1,64 @@ +#!/bin/bash +# +# Copyright (c) 2010, Benjamin C. Meyer +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +function test_file { + file="${1}" + + # Something close to our style which is the same as the Qt4 code style + #astyle --indent=spaces=4 --brackets=linux --indent-labels --pad=oper --unpad=paren --one-line=keep-statements --convert-tabs --indent-preprocessor `find -type f -name '*.cpp'` `find -type f -name '*.h'` + + echo "--Checking style--" + tempfoo=`basename $0` + newfile=`mktemp /tmp/${tempfoo}.XXXXXX` || exit 1 + astyle --indent=spaces=4 --brackets=linux --indent-labels --pad=oper --one-line=keep-statements --convert-tabs --indent-preprocessor < $file > $newfile 2>> /dev/null + diff "${file}" "${newfile}" + r=$? + rm "${newfile}" + if [ $r != 0 ] ; then + echo "Code style error in $file, please fix before commiting." + exit 1 + fi + echo "--Checking style pass--" +} + +case "${1}" in + --about ) + echo "Check that the code follows a consistent code style." + ;; + * ) + astyle --version 2>> /dev/null + if [ $? -eq 127 ] ; then + echo "--AStyle not found installed on the system, skiping style check" + exit 0; + fi + + for file in `git diff-index --cached --name-only HEAD | grep *.cpp` ; do + test_file "${file}" + done + ;; +esac diff --git a/git_hooks/pre-commit/stylecheck_bash b/git_hooks/pre-commit/stylecheck_bash new file mode 100755 index 00000000..fe582f20 --- /dev/null +++ b/git_hooks/pre-commit/stylecheck_bash @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright (c) 2010-2014, Benjamin C. Meyer +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. Neither the name of the project nor the +# names of its contributors may be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +dir=`dirname $0` + +function test_file { + file="${1}" + if [ ! -f "${file}" ] ; then + return + fi + echo "--checking style via bash hack: $file" + GITDIR=`git rev-parse --git-dir` + cd $GITDIR/../ + $dir/../helper/findstyleerrors.sh $file +} + +case "${1}" in + --about ) + echo "Check the files that are being commited with the bash grep style checker." + ;; + * ) + for file in `git diff-index --cached --name-only HEAD | grep .cpp` ; do + test_file "${file}" + done + ;; +esac diff --git a/git_hooks/pre-commit_autotest b/git_hooks/pre-commit_autotest deleted file mode 100755 index b51ebbe8..00000000 --- a/git_hooks/pre-commit_autotest +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# -# Check that existing autotests for files that are being commited are not currently failing -# - -dir=`dirname $0` -echo $dir -for file in `git-diff-index --name-only HEAD | grep .cpp` ; do - file=`echo $file | sed -e s/.cpp//g -e 's/.*\///g'` - if [ -d $dir/../autotests/$file ] ; then - echo "--checking autotest: $file--" - - tempfoo=`basename $0` - TMPFILE=`mktemp -t ${tempfoo}` || exit 1 - (cd "$dir/../../autotests/$file/"; qmake; make; ./$file >> $TMPFILE) - output=`cat $TMPFILE | grep ' failed,' | sed -e 's/.*passed, //g' -e 's/ failed.*//g'` - if [ "${output}" != "0" ] ; then - echo "Autotests failed for $file, please fix before commiting." - cat $TMPFILE - rm $TMPFILE - exit 1 - fi - rm $TMPFILE - echo "--checking autotest: $file done--" - fi -done diff --git a/git_hooks/pre-commit_build b/git_hooks/pre-commit_build deleted file mode 100755 index 7f95cfd8..00000000 --- a/git_hooks/pre-commit_build +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# -# Wherever you are make sure something builds. -# -# Feel free to bypass this if the current commit doesn't match the current state. - -echo "--Attempting to build--" -if [ -f Makefile ] ; then - make --quiet - if [ $? != 0 ] ; then - echo "--Build failed, fix failure before commiting--"; - exit 1 - fi -fi -echo "--Attempting to build pass--" - diff --git a/git_hooks/pre-commit_checkhour b/git_hooks/pre-commit_checkhour deleted file mode 100755 index 6f4a74bd..00000000 --- a/git_hooks/pre-commit_checkhour +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# A simple test to prevent work on Arora during the work day. - -# If it is the weekend, bail out -day=`date +%w` -# Saturday -if [ $day -eq 6 ] ; then - exit 0 -fi -# Sunday -if [ $day -eq 0 ] ; then - exit 0 -fi - -# if it is a weekday check the time -hour=`date +%H` -if [ $hour -ge 8 ] ; then - if [ $hour -le 17 ] ; then - echo "Go back to work." - exit 1 - fi -fi -exit 0 diff --git a/git_hooks/pre-commit_checkstyle b/git_hooks/pre-commit_checkstyle deleted file mode 100755 index d52ab8a3..00000000 --- a/git_hooks/pre-commit_checkstyle +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh -# -# Check that the code follows a consistant code style -# - -astyle --version 2>> /dev/null -if [ $? -eq 127 ] ; then - echo "--AStyle not found installed on the system, skiping style check" - exit 0; -fi - -// Something close to our style which is the same as the Qt4 code style -#astyle --indent=spaces=4 --brackets=linux --indent-labels --pad=oper --unpad=paren --one-line=keep-statements --convert-tabs --indent-preprocessor `find -type f -name '*.cpp'` `find -type f -name '*.h'` - -echo "--Checking style--" -for file in `git-diff-index --name-only HEAD | grep *.cpp` ; do - tempfoo=`basename $0` - newfile=`mktemp /tmp/${tempfoo}.XXXXXX` || exit 1 - astyle --indent=spaces=4 --brackets=linux --indent-labels --pad=oper --one-line=keep-statements --convert-tabs --indent-preprocessor < $file > $newfile 2>> /dev/null - diff "${file}" "${newfile}" - r=$? - rm "${newfile}" - if [ $r != 0 ] ; then - echo "Code style error in $file, please fix before commiting." - exit 1 - fi -done -echo "--Checking style pass--" diff --git a/git_hooks/pre-rebase b/git_hooks/pre-rebase deleted file mode 100644 index 981c454c..00000000 --- a/git_hooks/pre-rebase +++ /dev/null @@ -1,150 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006 Junio C Hamano -# - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` -fi - -case "$basebranch,$topic" in -master,refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Is topic fully merged to master? -not_in_master=`git-rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git-rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git-rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git-rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up-to-date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git-rev-list --pretty=oneline ^${publish} "$topic"` - perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -exit 0 - -################################################################ - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git-rev-list ^master ^topic next - git-rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git-rev-list master..topic - - if this is empty, it is fully merged to "master". diff --git a/git_hooks/update b/git_hooks/update deleted file mode 100644 index 9d3795c6..00000000 --- a/git_hooks/update +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/sh -# -# An example hook script to blocks unannotated tags from entering. -# Called by git-receive-pack with arguments: refname sha1-old sha1-new -# -# To enable this hook, make this file executable by "chmod +x update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git-repo-config --bool hooks.allowunannotated) - -# check for no description -projectdesc=$(sed -e '1p' "$GIT_DIR/description") -if [ -z "$projectdesc" -o "$projectdesc" = "Unnamed repository; edit this file to name it for gitweb" ]; then - echo "*** Project description file hasn't been set" >&2 - exit 1 -fi - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a branch -if [ -z "${newrev##0*}" ]; then - newrev_type=commit -else - newrev_type=$(git-cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - ;; - refs/heads/*,commit) - # branch - ;; - refs/remotes/*,commit) - # tracking branch - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/install.pri b/install.pri new file mode 100644 index 00000000..761010ee --- /dev/null +++ b/install.pri @@ -0,0 +1,13 @@ + +unix { + isEmpty(PREFIX) { + PREFIX = /usr/local + } + BINDIR = $$PREFIX/bin + + INSTALLS += target + target.path = $$BINDIR + + DATADIR = $$PREFIX/share +} + diff --git a/manualtests/adblock/adblock.pro b/manualtests/adblock/adblock.pro new file mode 100644 index 00000000..d0811c75 --- /dev/null +++ b/manualtests/adblock/adblock.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = \ + adblockdialog \ + adblockmodel + +CONFIG += ordered diff --git a/manualtests/adblock/adblockdialog/.gitignore b/manualtests/adblock/adblockdialog/.gitignore new file mode 100644 index 00000000..ad6f3475 --- /dev/null +++ b/manualtests/adblock/adblockdialog/.gitignore @@ -0,0 +1 @@ +adblockdialog diff --git a/manualtests/adblock/adblockdialog/adblockdialog.pro b/manualtests/adblock/adblockdialog/adblockdialog.pro new file mode 100644 index 00000000..415d82fc --- /dev/null +++ b/manualtests/adblock/adblockdialog/adblockdialog.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../manualtests.pri) +include(../../../autotests/modeltest/modeltest.pri) + +# Input +SOURCES += main_adblockdialog.cpp +HEADERS += diff --git a/manualtests/adblock/adblockdialog/main_adblockdialog.cpp b/manualtests/adblock/adblockdialog/main_adblockdialog.cpp new file mode 100644 index 00000000..ab233169 --- /dev/null +++ b/manualtests/adblock/adblockdialog/main_adblockdialog.cpp @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "adblockdialog.h" +#include "modeltest.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + AdBlockDialog dialog; + new ModelTest(dialog.treeView->model()); + dialog.show(); + return app.exec(); +} + diff --git a/manualtests/adblock/adblockmodel/.gitignore b/manualtests/adblock/adblockmodel/.gitignore new file mode 100644 index 00000000..c2bb9418 --- /dev/null +++ b/manualtests/adblock/adblockmodel/.gitignore @@ -0,0 +1 @@ +adblockmodel diff --git a/manualtests/adblock/adblockmodel/adblockmodel.pro b/manualtests/adblock/adblockmodel/adblockmodel.pro new file mode 100644 index 00000000..453974d1 --- /dev/null +++ b/manualtests/adblock/adblockmodel/adblockmodel.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../manualtests.pri) +include(../../../autotests/modeltest/modeltest.pri) + +# Input +SOURCES += main_adblockmodel.cpp +HEADERS += diff --git a/manualtests/adblock/adblockmodel/main_adblockmodel.cpp b/manualtests/adblock/adblockmodel/main_adblockmodel.cpp new file mode 100644 index 00000000..f3a50418 --- /dev/null +++ b/manualtests/adblock/adblockmodel/main_adblockmodel.cpp @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +#include "adblockmodel.h" +#include "modeltest.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + QTreeView view; + AdBlockModel *model = new AdBlockModel; + new ModelTest(model); + view.setModel(model); + view.show(); + return app.exec(); +} + diff --git a/manualtests/bookmarks/.gitignore b/manualtests/bookmarks/.gitignore new file mode 100644 index 00000000..7e1f6a71 --- /dev/null +++ b/manualtests/bookmarks/.gitignore @@ -0,0 +1 @@ +bookmarks diff --git a/manualtests/bookmarks/bookmarks.pro b/manualtests/bookmarks/bookmarks.pro index c0ec510a..dcb2e219 100644 --- a/manualtests/bookmarks/bookmarks.pro +++ b/manualtests/bookmarks/bookmarks.pro @@ -7,5 +7,5 @@ include(../manualtests.pri) include(../../autotests/modeltest/modeltest.pri) # Input -SOURCES += main.cpp +SOURCES += main_bookmarks.cpp HEADERS += diff --git a/manualtests/bookmarks/main.cpp b/manualtests/bookmarks/main_bookmarks.cpp similarity index 82% rename from manualtests/bookmarks/main.cpp rename to manualtests/bookmarks/main_bookmarks.cpp index c3347907..7628863e 100644 --- a/manualtests/bookmarks/main.cpp +++ b/manualtests/bookmarks/main_bookmarks.cpp @@ -17,11 +17,14 @@ * Boston, MA 02110-1301 USA */ -#include +#include -#include -#include -#include +#include "addbookmarkdialog.h" +#include "bookmarksdialog.h" +#include "bookmarksmanager.h" +#include "bookmarksmodel.h" +#include "browserapplication.h" +#include "modeltest.h" int main(int argc, char *argv[]) { @@ -35,7 +38,9 @@ int main(int argc, char *argv[]) dialog->show(); QString url("http://www.reddit.com"); - AddBookmarkDialog adddialog(QString("Reddit.com: a time drain"), url); + AddBookmarkDialog adddialog; + adddialog.setTitle(QString("Reddit.com: a time drain")); + adddialog.setUrl(url); //adddialog.show(); QMenuBar bar; diff --git a/manualtests/downloadmanager/.gitignore b/manualtests/downloadmanager/.gitignore new file mode 100644 index 00000000..45b3fddc --- /dev/null +++ b/manualtests/downloadmanager/.gitignore @@ -0,0 +1 @@ +downloadmanager diff --git a/manualtests/downloadmanager/downloadmanager.pro b/manualtests/downloadmanager/downloadmanager.pro index a60ce3fb..79f26c3f 100644 --- a/manualtests/downloadmanager/downloadmanager.pro +++ b/manualtests/downloadmanager/downloadmanager.pro @@ -6,5 +6,6 @@ INCLUDEPATH += . include(../manualtests.pri) # Input -SOURCES += main.cpp +RESOURCES = +SOURCES += main_downloadmanager.cpp HEADERS += diff --git a/manualtests/downloadmanager/main.cpp b/manualtests/downloadmanager/main_downloadmanager.cpp similarity index 95% rename from manualtests/downloadmanager/main.cpp rename to manualtests/downloadmanager/main_downloadmanager.cpp index 873e18e5..14579edc 100644 --- a/manualtests/downloadmanager/main.cpp +++ b/manualtests/downloadmanager/main_downloadmanager.cpp @@ -17,8 +17,6 @@ * Boston, MA 02110-1301 USA */ -#include -#include #include "downloadmanager.h" int main(int argc, char **argv) diff --git a/manualtests/history/.gitignore b/manualtests/history/.gitignore new file mode 100644 index 00000000..c375d5ba --- /dev/null +++ b/manualtests/history/.gitignore @@ -0,0 +1 @@ +history diff --git a/manualtests/history/history.pro b/manualtests/history/history.pro index c0ec510a..2fa000d9 100644 --- a/manualtests/history/history.pro +++ b/manualtests/history/history.pro @@ -7,5 +7,5 @@ include(../manualtests.pri) include(../../autotests/modeltest/modeltest.pri) # Input -SOURCES += main.cpp +SOURCES += main_history.cpp HEADERS += diff --git a/manualtests/history/main.cpp b/manualtests/history/main_history.cpp similarity index 93% rename from manualtests/history/main.cpp rename to manualtests/history/main_history.cpp index d01a67e8..6b8669cc 100644 --- a/manualtests/history/main.cpp +++ b/manualtests/history/main_history.cpp @@ -17,9 +17,14 @@ * Boston, MA 02110-1301 USA */ -#include +#include +#include + +#include +#include +#include #include -#include "history.h" +#include int main(int argc, char **argv) { @@ -62,7 +67,7 @@ int main(int argc, char **argv) historyCompletionModelView->setModel(completionModel); tabWidget.addTab(historyCompletionModelView, "HistoryCompletionModel"); - HistoryDialog dialog; + HistoryDialog dialog(0, &history); tabWidget.addTab(dialog.tree, "DialogModel"); tabWidget.setCurrentIndex(3); diff --git a/manualtests/locationbar/.gitignore b/manualtests/locationbar/.gitignore new file mode 100644 index 00000000..3c98d718 --- /dev/null +++ b/manualtests/locationbar/.gitignore @@ -0,0 +1 @@ +locationbar diff --git a/manualtests/locationbar/locationbar.pro b/manualtests/locationbar/locationbar.pro new file mode 100644 index 00000000..41b93df9 --- /dev/null +++ b/manualtests/locationbar/locationbar.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../manualtests.pri) + +# Input +SOURCES += main_locationbar.cpp +HEADERS += + diff --git a/manualtests/urllineedit/main.cpp b/manualtests/locationbar/main_locationbar.cpp similarity index 86% rename from manualtests/urllineedit/main.cpp rename to manualtests/locationbar/main_locationbar.cpp index 443edce3..94d2140f 100644 --- a/manualtests/urllineedit/main.cpp +++ b/manualtests/locationbar/main_locationbar.cpp @@ -17,9 +17,14 @@ * Boston, MA 02110-1301 USA */ -#include +#include +#include +#include +#include +#include + #include "browserapplication.h" -#include "urllineedit.h" +#include "locationbar.h" #include "webview.h" int main(int argc, char **argv) @@ -32,8 +37,8 @@ int main(int argc, char **argv) QComboBox *comboBox = new QComboBox(window); comboBox->setEditable(true); QLineEdit *lineEdit = new QLineEdit(window); - UrlLineEdit *s1 = new UrlLineEdit(window); - UrlLineEdit *s2 = new UrlLineEdit(window); + LocationBar *s1 = new LocationBar(window); + LocationBar *s2 = new LocationBar(window); WebView *view = new WebView(window); view->setUrl(QUrl("http://www.google.com")); s2->setWebView(view); @@ -50,7 +55,7 @@ int main(int argc, char **argv) QToolBar *bar = w.addToolBar("foo"); QSplitter *splitter = new QSplitter(window); - splitter->addWidget(new UrlLineEdit); + splitter->addWidget(new LocationBar); splitter->addWidget(new QLineEdit); bar->addWidget(splitter); return application.exec(); diff --git a/manualtests/manualtests.pri b/manualtests/manualtests.pri index 07350652..eab9f33c 100644 --- a/manualtests/manualtests.pri +++ b/manualtests/manualtests.pri @@ -2,10 +2,3 @@ win32: CONFIG += console mac:CONFIG -= app_bundle include($$PWD/../src/src.pri) - -RCC_DIR = $$PWD/.rcc -UI_DIR = $$PWD/.ui -MOC_DIR = $$PWD/.moc -# can't share main.cpp objects of course -OBJECTS_DIR = .obj - diff --git a/manualtests/manualtests.pro b/manualtests/manualtests.pro index b61810c3..52817cad 100644 --- a/manualtests/manualtests.pro +++ b/manualtests/manualtests.pro @@ -1,7 +1,13 @@ TEMPLATE = subdirs -SUBDIRS = bookmarks \ - downloadmanager \ - history \ - searchlineedit \ - urllineedit +SUBDIRS = \ + adblock \ + bookmarks \ + downloadmanager \ + history \ + locationbar \ + modelmenu \ + searchlineedit \ + utils \ + webviewsearch +CONFIG += ordered diff --git a/manualtests/modelmenu/.gitignore b/manualtests/modelmenu/.gitignore new file mode 100644 index 00000000..2f8ac853 --- /dev/null +++ b/manualtests/modelmenu/.gitignore @@ -0,0 +1 @@ +modelmenu diff --git a/manualtests/modelmenu/main_modelmenu.cpp b/manualtests/modelmenu/main_modelmenu.cpp new file mode 100644 index 00000000..4ba3c627 --- /dev/null +++ b/manualtests/modelmenu/main_modelmenu.cpp @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include + +#include + +class Menu : public ModelMenu +{ + Q_OBJECT + +public: + Menu(QWidget *parent); + +protected: + bool prePopulated(); + void postPopulated(); + ModelMenu *createBaseMenu(); + +private slots: + void activated2(const QModelIndex &index); + +}; + +Menu::Menu(QWidget *parent) + : ModelMenu(parent) +{ + connect(this, SIGNAL(activated(const QModelIndex &)), + this, SLOT(activated2(const QModelIndex &))); +} + +bool Menu::prePopulated() +{ + qDebug() << __FUNCTION__; + return ModelMenu::prePopulated(); +} + +void Menu::postPopulated() +{ + qDebug() << __FUNCTION__; + return ModelMenu::postPopulated(); +} + +ModelMenu *Menu::createBaseMenu() +{ + qDebug() << __FUNCTION__; + return new Menu(this); + return ModelMenu::createBaseMenu(); +} + +void Menu::activated2(const QModelIndex &index) +{ + qDebug() << __FUNCTION__ << index.data() << this; +} + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + + QMainWindow mainWindow; + Menu *menu = new Menu(&mainWindow); + menu->setTitle("Test"); + QDirModel *model = new QDirModel(menu); + menu->setModel(model); + menu->setRootIndex(model->index(QDir::homePath())); + mainWindow.menuBar()->addMenu(menu); + mainWindow.show(); + return app.exec(); +} + +#include "main_modelmenu.moc" + diff --git a/manualtests/urllineedit/urllineedit.pro b/manualtests/modelmenu/modelmenu.pro similarity index 77% rename from manualtests/urllineedit/urllineedit.pro rename to manualtests/modelmenu/modelmenu.pro index a60ce3fb..78a06670 100644 --- a/manualtests/urllineedit/urllineedit.pro +++ b/manualtests/modelmenu/modelmenu.pro @@ -6,5 +6,5 @@ INCLUDEPATH += . include(../manualtests.pri) # Input -SOURCES += main.cpp +SOURCES += main_modelmenu.cpp HEADERS += diff --git a/manualtests/searchlineedit/.gitignore b/manualtests/searchlineedit/.gitignore new file mode 100644 index 00000000..1713e66b --- /dev/null +++ b/manualtests/searchlineedit/.gitignore @@ -0,0 +1 @@ +searchlineedit diff --git a/manualtests/searchlineedit/main_searchlineedit.cpp b/manualtests/searchlineedit/main_searchlineedit.cpp new file mode 100644 index 00000000..6d1a693a --- /dev/null +++ b/manualtests/searchlineedit/main_searchlineedit.cpp @@ -0,0 +1,56 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +#include "searchlineedit.h" +#include "searchbutton.h" + +int main(int argc, char **argv) +{ + QApplication application(argc, argv); + + QDialog window; + QPushButton *button1 = new QPushButton("One"); + SearchLineEdit *s1 = new SearchLineEdit(&window); + SearchLineEdit *s2 = new SearchLineEdit(&window); + QCompleter *completer = new QCompleter(&window); + s2->setCompleter(completer); + s2->searchButton()->setShowMenuTriangle(true); + QObject::connect(s2->searchButton(), SIGNAL(clicked()), + completer, SLOT(complete())); + QStringList list; + list << "a" << "b" << "c"; + s2->completer()->setModel(new QStringListModel(list)); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(s1); + layout->addWidget(s2); + layout->addWidget(button1); + + window.setLayout(layout); + window.show(); + return application.exec(); +} + diff --git a/manualtests/searchlineedit/searchlineedit.pro b/manualtests/searchlineedit/searchlineedit.pro index a60ce3fb..3cc1340b 100644 --- a/manualtests/searchlineedit/searchlineedit.pro +++ b/manualtests/searchlineedit/searchlineedit.pro @@ -6,5 +6,9 @@ INCLUDEPATH += . include(../manualtests.pri) # Input -SOURCES += main.cpp -HEADERS += +RESOURCES = +FORMS = +SOURCES = searchbutton.cpp clearbutton.cpp lineedit.cpp searchlineedit.cpp +HEADERS = searchbutton.h clearbutton.h lineedit.h lineedit_p.h searchlineedit.h + +SOURCES += main_searchlineedit.cpp diff --git a/manualtests/utils/editview/.gitignore b/manualtests/utils/editview/.gitignore new file mode 100644 index 00000000..53dfa8a4 --- /dev/null +++ b/manualtests/utils/editview/.gitignore @@ -0,0 +1 @@ +editview diff --git a/manualtests/utils/editview/editview.pro b/manualtests/utils/editview/editview.pro new file mode 100644 index 00000000..18c3fe24 --- /dev/null +++ b/manualtests/utils/editview/editview.pro @@ -0,0 +1,11 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../manualtests.pri) + +# Input +FORMS += editview.ui +SOURCES += main_editview.cpp +HEADERS += diff --git a/manualtests/utils/editview/editview.ui b/manualtests/utils/editview/editview.ui new file mode 100644 index 00000000..beee2a32 --- /dev/null +++ b/manualtests/utils/editview/editview.ui @@ -0,0 +1,87 @@ + + + Dialog + + + + 0 + 0 + 790 + 398 + + + + Dialog + + + + + + Qt::Horizontal + + + + + + + + + + RemoveAll + + + + + + + + + + + + + + RemoveAll + + + + + + + + + + + + + + RemoveAll + + + + + + + + + + + + EditListView + QListView +
editlistview.h
+
+ + EditTreeView + QTreeView +
edittreeview.h
+
+ + EditTableView + QTableView +
edittableview.h
+
+
+ + +
diff --git a/manualtests/utils/editview/main_editview.cpp b/manualtests/utils/editview/main_editview.cpp new file mode 100644 index 00000000..7eb4daf5 --- /dev/null +++ b/manualtests/utils/editview/main_editview.cpp @@ -0,0 +1,77 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +#include "ui_editview.h" + +class Window : public QDialog, public Ui_Dialog +{ + Q_OBJECT + +public: + Window(); +}; + +Window::Window() + : QDialog() +{ + setupUi(this); + QStringList list; + list << "a" << "b" << "c"; + listView->setModel(new QStringListModel(list)); + tableView->setModel(new QStringListModel(list)); + connect(listViewRemoveAllButton, SIGNAL(clicked()), listView, SLOT(removeAll())); + connect(tableViewRemoveAllButton, SIGNAL(clicked()), tableView, SLOT(removeAll())); + connect(treeViewRemoveAllButton, SIGNAL(clicked()), treeView, SLOT(removeAll())); + + QStandardItemModel *model = new QStandardItemModel(this); + QStandardItem *parentItem = model->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + item = new QStandardItem(QString("item %0").arg(i * 2)); + parentItem->appendRow(item); + parentItem = item; + } + treeView->setModel(model); + treeView->expandAll(); +} + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window window; + window.show(); + return app.exec(); +} + +#include "main_editview.moc" + diff --git a/manualtests/utils/lineedit/.gitignore b/manualtests/utils/lineedit/.gitignore new file mode 100644 index 00000000..19f5a9a7 --- /dev/null +++ b/manualtests/utils/lineedit/.gitignore @@ -0,0 +1 @@ +lineedit diff --git a/manualtests/utils/lineedit/bookmark.png b/manualtests/utils/lineedit/bookmark.png new file mode 100644 index 00000000..be21134b Binary files /dev/null and b/manualtests/utils/lineedit/bookmark.png differ diff --git a/manualtests/utils/lineedit/dialog.ui b/manualtests/utils/lineedit/dialog.ui new file mode 100644 index 00000000..4f5f0a72 --- /dev/null +++ b/manualtests/utils/lineedit/dialog.ui @@ -0,0 +1,289 @@ + + Dialog + + + + 0 + 0 + 474 + 348 + + + + Dialog + + + + + + + + Left: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Foo Bar Baz Arora LineEdit Manual Test This is the end + + + + + + + Right: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Foo Bar Baz Arora LineEdit Manual Test This is the end + + + + + + + Foo Bar Baz Arora LineEdit Manual Test This is the end + + + + + + + Empty: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Horizontal + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Foo Bar Baz Arora LineEdit Manual Test + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Widget + + + + + + Site Icon + + + true + + + + + + + RSS + + + false + + + + + + + Bookmark + + + + + + + + + + Position + + + + + + Left + + + true + + + + + + + Right + + + + + + + + + + + 0 + 0 + + + + 3 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical + + + + 20 + 28 + + + + + + + + + + Add + + + + + + + Remove + + + + + + + Swap Visibility + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Add ToolButton + + + + + + + + + + LineEdit + QLineEdit +
lineedit.h
+
+
+ + +
diff --git a/manualtests/utils/lineedit/lineedit.pro b/manualtests/utils/lineedit/lineedit.pro new file mode 100644 index 00000000..55d0d804 --- /dev/null +++ b/manualtests/utils/lineedit/lineedit.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../manualtests.pri) + +# Input +RESOURCES = +FORMS = dialog.ui +SOURCES = main_lineedit.cpp lineedit.cpp +HEADERS = lineedit.h lineedit_p.h diff --git a/manualtests/utils/lineedit/main_lineedit.cpp b/manualtests/utils/lineedit/main_lineedit.cpp new file mode 100644 index 00000000..b55e64e8 --- /dev/null +++ b/manualtests/utils/lineedit/main_lineedit.cpp @@ -0,0 +1,142 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include + +#include +#include "ui_dialog.h" + +class Dialog : public QDialog, public Ui_Dialog +{ + Q_OBJECT +public: + Dialog(QWidget *parent = 0); + + QLabel *rssButton; + QLabel *bookmarkButton; + QLabel *siteIconButton; + +private slots: + void setWidgetSpacing(int s); + void add(); + void remove(); + void showW(); + void addToolButton(); + + QWidget *getWidget(); +}; + +Dialog::Dialog(QWidget *parent) + : QDialog(parent) +{ + setupUi(this); + rssButton = new QLabel(this); + rssButton->setPixmap(QPixmap("rss.png")); + rssButton->hide(); + bookmarkButton = new QLabel(this); + bookmarkButton->setPixmap(QPixmap("bookmark.png")); + bookmarkButton->hide(); + siteIconButton = new QLabel(this); + siteIconButton->setPixmap(QPixmap("siteicon.png")); + siteIconButton->hide(); + + { + QToolButton *b = new QToolButton(this); + b->resize(16, 16); + leftLineEdit->addWidget(b, LineEdit::LeftSide); + } + { + QToolButton *b = new QToolButton(this); + b->resize(16, 16); + rightLineEdit->addWidget(b, LineEdit::RightSide); + } + connect(addButton, SIGNAL(clicked()), this, SLOT(add())); + connect(removeButton, SIGNAL(clicked()), this, SLOT(remove())); + connect(showButton, SIGNAL(clicked()), this, SLOT(showW())); + connect(addToolButtonButton, SIGNAL(clicked()), this, SLOT(addToolButton())); + connect(spacing, SIGNAL(valueChanged(int)), this, SLOT(setWidgetSpacing(int))); +} + +QWidget *Dialog::getWidget() +{ + if (rssWidget->isChecked()) { + bookmarkWidget->setChecked(true); + return rssButton; + } + if (bookmarkWidget->isChecked()) { + siteIconWidget->setChecked(true); + return bookmarkButton; + } + if (siteIconWidget->isChecked()) { + rssWidget->setChecked(true); + return siteIconButton; + } + return 0; +} + +void Dialog::setWidgetSpacing(int s) +{ + lineEdit->setWidgetSpacing(s); +} + +void Dialog::add() +{ + LineEdit::WidgetPosition position = leftSide->isChecked() ? LineEdit::LeftSide : LineEdit::RightSide; + lineEdit->addWidget(getWidget(), position); +} + +void Dialog::remove() +{ + lineEdit->removeWidget(getWidget()); +} + +void Dialog::showW() +{ + QWidget *w = getWidget(); + w->setVisible(!w->isVisible()); +} + +void Dialog::addToolButton() +{ + LineEdit::WidgetPosition position = leftSide->isChecked() ? LineEdit::LeftSide : LineEdit::RightSide; + QToolButton *button = new QToolButton; + lineEdit->addWidget(button, position); +} + +int main(int argc,char ** argv) +{ + QApplication app(argc,argv); + + if (app.arguments().count() == 1) { + Dialog dialog; + dialog.show(); + return app.exec(); + } else { + LineEdit lineEdit; + QPushButton *rightButton = new QPushButton("Dialog bar"); + qDebug() << rightButton->sizeHint(); + lineEdit.addWidget(rightButton, LineEdit::RightSide); + lineEdit.show(); + return app.exec(); + } +} + +#include "main_lineedit.moc" + diff --git a/manualtests/utils/lineedit/rss.png b/manualtests/utils/lineedit/rss.png new file mode 100755 index 00000000..b3c949d2 Binary files /dev/null and b/manualtests/utils/lineedit/rss.png differ diff --git a/manualtests/utils/lineedit/siteicon.png b/manualtests/utils/lineedit/siteicon.png new file mode 100644 index 00000000..e0caa872 Binary files /dev/null and b/manualtests/utils/lineedit/siteicon.png differ diff --git a/manualtests/utils/singleapplication/.gitignore b/manualtests/utils/singleapplication/.gitignore new file mode 100644 index 00000000..a24818bd --- /dev/null +++ b/manualtests/utils/singleapplication/.gitignore @@ -0,0 +1 @@ +singleapplication diff --git a/manualtests/utils/singleapplication/main_singleapplication.cpp b/manualtests/utils/singleapplication/main_singleapplication.cpp new file mode 100644 index 00000000..c73ab930 --- /dev/null +++ b/manualtests/utils/singleapplication/main_singleapplication.cpp @@ -0,0 +1,71 @@ +/** + * Copyright (c) 2008, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include + +class PlainTextEdit : public QPlainTextEdit { + Q_OBJECT + +public: + PlainTextEdit(QWidget *parent = 0) + : QPlainTextEdit(parent) { } + +public slots: + void messageReceived(QLocalSocket *socket) { + QString message; + QTextStream stream(socket); + stream >> message; + appendPlainText(message); + } + +}; + +int main(int argc, char **argv) +{ + SingleApplication app(argc, argv); + app.setApplicationName("testapp"); + if (app.arguments().count() > 1 + && app.sendMessage(app.arguments().last().toUtf8())) + return 0; + + PlainTextEdit plainTextEdit; + plainTextEdit.show(); + if (!app.startSingleServer()) + qWarning() << "Error starting server"; + app.connect(&app, SIGNAL(messageReceived(QLocalSocket *)), + &plainTextEdit, SLOT(messageReceived(QLocalSocket *))); + return app.exec(); +} + +#include "main_singleapplication.moc" + diff --git a/manualtests/utils/singleapplication/singleapplication.pro b/manualtests/utils/singleapplication/singleapplication.pro new file mode 100644 index 00000000..a511dcd1 --- /dev/null +++ b/manualtests/utils/singleapplication/singleapplication.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../manualtests.pri) + +# Input +RESOURCES = +FORMS = +SOURCES = main_singleapplication.cpp singleapplication.cpp +HEADERS = singleapplication.h diff --git a/manualtests/utils/squeezelabel/.gitignore b/manualtests/utils/squeezelabel/.gitignore new file mode 100644 index 00000000..f6332511 --- /dev/null +++ b/manualtests/utils/squeezelabel/.gitignore @@ -0,0 +1 @@ +squeezelabel diff --git a/manualtests/searchlineedit/main.cpp b/manualtests/utils/squeezelabel/main_squeezelabel.cpp similarity index 60% rename from manualtests/searchlineedit/main.cpp rename to manualtests/utils/squeezelabel/main_squeezelabel.cpp index 9381d6e9..97bcc0f6 100644 --- a/manualtests/searchlineedit/main.cpp +++ b/manualtests/utils/squeezelabel/main_squeezelabel.cpp @@ -17,30 +17,22 @@ * Boston, MA 02110-1301 USA */ -#include -#include "searchlineedit.h" +#include + +#include "squeezelabel.h" int main(int argc, char **argv) { QApplication application(argc, argv); - QMainWindow w; - - QWidget *window = new QWidget; - QPushButton *button1 = new QPushButton("One"); - QPushButton *button2 = new QPushButton("Two"); - SearchLineEdit *s1 = new SearchLineEdit(window); - SearchLineEdit *s2 = new SearchLineEdit(window); - s2->menu()->addAction("f"); - QVBoxLayout *layout = new QVBoxLayout; - layout->addWidget(s1); - layout->addWidget(s2); - layout->addWidget(button1); - layout->addWidget(button2); + SqueezeLabel label; + if (application.arguments().count() > 1) + label.setText(application.arguments().value(1)); + else + label.setText("This is one long sentence that I will have to ponder the meaning of"); + label.show(); + label.resize(100, label.height()); - window->setLayout(layout); - w.show(); - w.setCentralWidget(window); return application.exec(); } diff --git a/manualtests/utils/squeezelabel/squeezelabel.pro b/manualtests/utils/squeezelabel/squeezelabel.pro new file mode 100644 index 00000000..502ba275 --- /dev/null +++ b/manualtests/utils/squeezelabel/squeezelabel.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../manualtests.pri) + +# Input +RESOURCES = +FORMS = +SOURCES = main_squeezelabel.cpp squeezelabel.cpp +HEADERS = squeezelabel.h diff --git a/manualtests/utils/treesortfilterproxymodel/.gitignore b/manualtests/utils/treesortfilterproxymodel/.gitignore new file mode 100644 index 00000000..c3df39de --- /dev/null +++ b/manualtests/utils/treesortfilterproxymodel/.gitignore @@ -0,0 +1 @@ +treesortfilterproxymodel diff --git a/manualtests/utils/treesortfilterproxymodel/main_treesortfilterproxymodel.cpp b/manualtests/utils/treesortfilterproxymodel/main_treesortfilterproxymodel.cpp new file mode 100644 index 00000000..50ff66d0 --- /dev/null +++ b/manualtests/utils/treesortfilterproxymodel/main_treesortfilterproxymodel.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "treesortfilterproxymodel.h" +#include "ui_treesortfilterproxymodeldialog.h" + +#include +#include +#include + +int main(int argc, char **argv) +{ + QApplication application(argc, argv); + + QDialog dialog; + Ui_TreeSortFilterProxyModelDialog ui; + ui.setupUi(&dialog); + + TreeSortFilterProxyModel *proxy = new TreeSortFilterProxyModel(&dialog); + dialog.connect(ui.search, SIGNAL(textChanged(const QString &)), + proxy, SLOT(setFilterRegExp(const QString &))); + QDirModel *dirModel = new QDirModel(&dialog); + proxy->setSourceModel(dirModel); + ui.treeView->setModel(proxy); + ui.treeView->setRootIndex(proxy->mapFromSource(dirModel->index(QDir::homePath()))); + dialog.show(); + + return application.exec(); +} + diff --git a/manualtests/utils/treesortfilterproxymodel/treesortfilterproxymodel.pro b/manualtests/utils/treesortfilterproxymodel/treesortfilterproxymodel.pro new file mode 100644 index 00000000..8cba043b --- /dev/null +++ b/manualtests/utils/treesortfilterproxymodel/treesortfilterproxymodel.pro @@ -0,0 +1,12 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +include(../../manualtests.pri) + +# Input +SOURCES = main_treesortfilterproxymodel.cpp treesortfilterproxymodel.cpp +HEADERS = treesortfilterproxymodel.h + +FORMS += treesortfilterproxymodeldialog.ui diff --git a/manualtests/utils/treesortfilterproxymodel/treesortfilterproxymodeldialog.ui b/manualtests/utils/treesortfilterproxymodel/treesortfilterproxymodeldialog.ui new file mode 100644 index 00000000..842cc4be --- /dev/null +++ b/manualtests/utils/treesortfilterproxymodel/treesortfilterproxymodeldialog.ui @@ -0,0 +1,27 @@ + + + TreeSortFilterProxyModelDialog + + + + 0 + 0 + 400 + 300 + + + + Dialog + + + + + + + + + + + + + diff --git a/manualtests/utils/utils.pro b/manualtests/utils/utils.pro new file mode 100644 index 00000000..1f38ed5d --- /dev/null +++ b/manualtests/utils/utils.pro @@ -0,0 +1,9 @@ +TEMPLATE = subdirs +SUBDIRS = \ + editview \ + lineedit \ + singleapplication \ + squeezelabel \ + treesortfilterproxymodel + +CONFIG += ordered diff --git a/manualtests/webviewsearch/.gitignore b/manualtests/webviewsearch/.gitignore new file mode 100644 index 00000000..00a73b0f --- /dev/null +++ b/manualtests/webviewsearch/.gitignore @@ -0,0 +1 @@ +webviewsearch diff --git a/manualtests/webviewsearch/main.cpp b/manualtests/webviewsearch/main_webviewsearch.cpp similarity index 91% rename from manualtests/webviewsearch/main.cpp rename to manualtests/webviewsearch/main_webviewsearch.cpp index bf3d5bf3..2e7daf0d 100644 --- a/manualtests/webviewsearch/main.cpp +++ b/manualtests/webviewsearch/main_webviewsearch.cpp @@ -17,8 +17,11 @@ * Boston, MA 02110-1301 USA */ -#include -#include +#include +#include +#include +#include +#include #include "webviewsearch.h" @@ -54,16 +57,15 @@ int main(int argc, char **argv) QApplication application(argc, argv); QMainWindow mainWindow; - WebViewSearch *webViewSearch = new WebViewSearch; QWidget *window = new QWidget; QVBoxLayout *layout = new QVBoxLayout; layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); - layout->addWidget(webViewSearch); WebViewWSearch *webView = new WebViewWSearch(&mainWindow); + WebViewSearch *webViewSearch = new WebViewSearch(webView); + layout->addWidget(webViewSearch); webView->load(QUrl("http://reddit.com")); - webViewSearch->setWebView(webView); layout->addWidget(webView); window->setLayout(layout); mainWindow.setCentralWidget(window); @@ -79,4 +81,4 @@ int main(int argc, char **argv) return application.exec(); } -#include "main.moc" +#include "main_webviewsearch.moc" diff --git a/manualtests/webviewsearch/webviewsearch.pro b/manualtests/webviewsearch/webviewsearch.pro index d717eb3d..c687d100 100644 --- a/manualtests/webviewsearch/webviewsearch.pro +++ b/manualtests/webviewsearch/webviewsearch.pro @@ -5,5 +5,5 @@ INCLUDEPATH += . include(../manualtests.pri) -SOURCES += main.cpp +SOURCES += main_webviewsearch.cpp HEADERS += diff --git a/src/Info_mac.plist b/src/Info_mac.plist index 16b350cd..5af1addb 100644 --- a/src/Info_mac.plist +++ b/src/Info_mac.plist @@ -2,19 +2,19 @@ - CFBundleIconFile - @ICON@ - CFBundlePackageType - APPL + CFBundleIconFile + @ICON@ + CFBundlePackageType + APPL CFBundleGetInfoString - Created by Qt/QMake - CFBundleIdentifier - com.trolltech.DemoBrowser - CFBundleSignature - ttxt - CFBundleExecutable - @EXECUTABLE@ - CFBundleDocumentTypes + Created by Qt/QMake + CFBundleIdentifier + com.Arora.Arora + CFBundleSignature + ttxt + CFBundleExecutable + @EXECUTABLE@ + CFBundleDocumentTypes CFBundleTypeExtensions @@ -25,8 +25,8 @@ xht xhtml - CFBundleTypeIconFile - @ICON@ + CFBundleTypeIconFile + @ICON@ CFBundleTypeName HTML Document CFBundleTypeOSTypes @@ -37,7 +37,7 @@ Viewer - NOTE - DemoBrowser by Trolltech ASA + NOTE + Arora Browser by the Arora team diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index 7513e20d..42e1c814 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -27,14 +27,23 @@ #include #include +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +#include +#endif + AboutDialog::AboutDialog(QWidget *parent) : QDialog(parent) { setupUi(this); - setWindowTitle(tr("About") + QString(" %1").arg(qApp->applicationName())); + setWindowTitle(tr("About %1").arg(qApp->applicationName())); logo->setPixmap(qApp->windowIcon().pixmap(128, 128)); name->setText(qApp->applicationName()); - version->setText(QApplication::applicationVersion()); + version->setText(qApp->applicationVersion()); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + webkitVersion->setText(tr("WebKit version: %1").arg(qWebKitVersion())); +#else + webkitVersion->hide(); +#endif connect(authorsButton, SIGNAL(clicked()), this, SLOT(authorsButtonClicked())); connect(licenseButton, SIGNAL(clicked()), @@ -43,31 +52,35 @@ AboutDialog::AboutDialog(QWidget *parent) void AboutDialog::displayFile(const QString &fileName, const QString &title) { - QDialog *dialog = new QDialog(this); - QLayout *layout = new QVBoxLayout(dialog); - QTextEdit *textEdit = new QTextEdit(dialog); - QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, Qt::Horizontal, dialog); + QDialog dialog(this); + QVBoxLayout layout(&dialog); + QTextEdit textEdit(&dialog); + QDialogButtonBox buttonBox(QDialogButtonBox::Close, Qt::Horizontal, &dialog); - textEdit->setStyleSheet(QLatin1String("font-family: monospace")); + textEdit.setLayoutDirection(Qt::LeftToRight); QFile file(fileName); - if (file.open(QIODevice::ReadOnly)) { - QString text = QTextStream(&file).readAll(); - textEdit->setPlainText(text); - } + if (!file.open(QIODevice::ReadOnly)) + return; + + QTextStream stream(&file); + stream.setCodec("UTF-8"); + QString text = stream.readAll(); + // this is done to force the content of the text editor to be LTR, and monospaced. + textEdit.setHtml(QString(QLatin1String("
%1
")).arg(text)); - textEdit->setReadOnly(true); - connect(buttonBox, SIGNAL(rejected()), dialog, SLOT(close())); - buttonBox->setCenterButtons(true); - layout->addWidget(textEdit); - layout->addWidget(buttonBox); - layout->setMargin(6); + textEdit.setReadOnly(true); + connect(&buttonBox, SIGNAL(rejected()), &dialog, SLOT(close())); + buttonBox.setCenterButtons(true); + layout.addWidget(&textEdit); + layout.addWidget(&buttonBox); + layout.setMargin(6); - dialog->setLayout(layout); - dialog->setWindowTitle(title); - dialog->setWindowFlags(Qt::Sheet); - dialog->resize(600, 350); - dialog->exec(); + dialog.setLayout(&layout); + dialog.setWindowTitle(title); + dialog.setWindowFlags(Qt::Sheet); + dialog.resize(600, 350); + dialog.exec(); } void AboutDialog::authorsButtonClicked() diff --git a/src/aboutdialog.h b/src/aboutdialog.h index 374536c9..4f4b7b01 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -23,12 +23,8 @@ #include #include "ui_aboutdialog.h" -class QVBoxLayout; -class QLabel; - class AboutDialog : public QDialog, private Ui_AboutDialog { - Q_OBJECT public: @@ -40,7 +36,6 @@ private slots: private: void displayFile(const QString &fileName, const QString &title); - }; #endif // ABOUTDIALOG_H diff --git a/src/aboutdialog.ui b/src/aboutdialog.ui index bfb6280a..414400ab 100644 --- a/src/aboutdialog.ui +++ b/src/aboutdialog.ui @@ -1,143 +1,185 @@ - + + AboutDialog - - + + 0 0 - 454 - 236 + 450 + 240 - + true - + - - - + + + 0 0 - + - + false - + Qt::AlignCenter - - - + + + 0 0 - + 16 75 true - + - + Qt::AlignCenter + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + - - - + + + 0 0 - + 12 50 false - + + + + + Qt::AlignCenter + + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + + + + + + + + 0 + 0 + + + + + 11 + 50 + false + + + - + Qt::AlignCenter + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + - - + + Lightweight WebKit-based web browser - + Qt::AlignCenter + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + - - - + + + 0 0 - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2010 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> - + Qt::AlignCenter - + true + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + - - - + + + 0 0 - - <a href="http://arora-browser.org">http://arora-browser.org</a> + + <a href="http://arora-browser.org">http://arora-browser.org</a> - + Qt::AlignCenter - + true + + Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse + - + - - + + Qt::Horizontal - + 40 20 @@ -146,35 +188,35 @@ p, li { white-space: pre-wrap; } - - + + Authors - - + + License - - + + Close - + true - - + + Qt::Horizontal - + 40 20 @@ -187,7 +229,7 @@ p, li { white-space: pre-wrap; } - + @@ -196,11 +238,11 @@ p, li { white-space: pre-wrap; } AboutDialog accept() - + 322 204 - + 372 206 diff --git a/src/acceptlanguagedialog.cpp b/src/acceptlanguagedialog.cpp new file mode 100644 index 00000000..f43be951 --- /dev/null +++ b/src/acceptlanguagedialog.cpp @@ -0,0 +1,170 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "acceptlanguagedialog.h" + +#include "browserapplication.h" +#include "languagemanager.h" + +#include +#include + +AcceptLanguageDialog::AcceptLanguageDialog(QWidget *parent, Qt::WindowFlags flags) + : QDialog(parent, flags) +{ + setupUi(this); + connect(addButton, SIGNAL(clicked()), this, SLOT(addLanguage())); + connect(removeButton, SIGNAL(clicked()), this, SLOT(removeLanguage())); + connect(moveUpButton, SIGNAL(clicked()), this, SLOT(moveLanguageUp())); + connect(moveDownButton, SIGNAL(clicked()), this, SLOT(moveLanguageDown())); + listView->setModel(&m_model); + connect(listView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(currentChanged(const QModelIndex &, const QModelIndex &))); + load(); + + QStringList allLanguages; + for (int i = 1 + (int)QLocale::C; i <= (int)QLocale::LastLanguage; ++i) + allLanguages += expand(QLocale::Language(i)); + m_allLanguagesModel.setStringList(allLanguages); + addComboBox->setModel(&m_allLanguagesModel); +} + +QStringList AcceptLanguageDialog::expand(const QLocale::Language language) +{ + QStringList allLanguages; + QList countries = QLocale::countriesForLanguage(language); + for (int j = 0; j < countries.size(); ++j) { + QString languageString; + if (countries.count() == 1) { + languageString = QString(QLatin1String("%1 [%2]")) + .arg(QLocale::languageToString(language)) + .arg(QLocale(language).name().split(QLatin1Char('_')).at(0)); + } else { + languageString = QString(QLatin1String("%1/%2 [%3]")) + .arg(QLocale::languageToString(language)) + .arg(QLocale::countryToString(countries.at(j))) + .arg(QLocale(language, countries.at(j)).name().split(QLatin1Char('_')).join(QLatin1String("-")).toLower()); + + } + if (!allLanguages.contains(languageString)) + allLanguages.append(languageString); + } + return allLanguages; +} + +void AcceptLanguageDialog::currentChanged(const QModelIndex ¤t, const QModelIndex &previous) +{ + Q_UNUSED(previous); + removeButton->setEnabled(current.isValid()); + int row = current.row(); + moveUpButton->setEnabled(row > 0); + moveDownButton->setEnabled(row != -1 && row < m_model.rowCount() - 1); +} + +QStringList AcceptLanguageDialog::defaultAcceptList() +{ + QString currentLanguage = BrowserApplication::instance()->languageManager()->currentLanguage(); + if (currentLanguage.isEmpty()) + return QStringList(); + return expand(QLocale(currentLanguage).language()); +} + +void AcceptLanguageDialog::accept() +{ + save(); + QDialog::accept(); +} + +void AcceptLanguageDialog::load() +{ + QSettings settings; + settings.beginGroup(QLatin1String("network")); + m_model.setStringList(settings.value(QLatin1String("acceptLanguages"), defaultAcceptList()).toStringList()); +} + +void AcceptLanguageDialog::save() +{ + QSettings settings; + settings.beginGroup(QLatin1String("network")); + QStringList result = m_model.stringList(); + if (result == defaultAcceptList() || result.isEmpty()) + settings.remove(QLatin1String("acceptLanguages")); + else + settings.setValue(QLatin1String("acceptLanguages"), result); +} + +/* + Return a ByteArray that can be sent along with the Accept-Language http header + + See RFC 2616 section 14.4 + */ +QByteArray AcceptLanguageDialog::httpString(const QStringList &list) +{ + QStringList processed; + qreal qvalue = 1.0; + foreach (const QString &string, list) { + int leftBracket = string.indexOf(QLatin1Char('[')); + int rightBracket = string.indexOf(QLatin1Char(']')); + QString tag = string.mid(leftBracket + 1, rightBracket - leftBracket - 1); + if (processed.isEmpty()) { + processed << tag; + } else { + processed << QString(QLatin1String("%1; %2")).arg(tag).arg(QString::number(qvalue, 'f', 1)); + } + if (qvalue > .1) + qvalue -= .1; + } + return processed.join(QLatin1String(", ")).toLatin1(); +} + +void AcceptLanguageDialog::moveLanguageUp() +{ + int currentRow = listView->currentIndex().row(); + QString item = listView->currentIndex().data().toString(); + m_model.removeRow(currentRow); + m_model.insertRows(currentRow - 1, 1); + m_model.setData(m_model.index(currentRow - 1), item); + listView->setCurrentIndex(m_model.index(currentRow + 1)); +} + +void AcceptLanguageDialog::moveLanguageDown() +{ + int currentRow = listView->currentIndex().row(); + QString item = listView->currentIndex().data().toString(); + m_model.removeRow(currentRow); + m_model.insertRows(currentRow + 1, 1); + m_model.setData(m_model.index(currentRow + 1), item); + listView->setCurrentIndex(m_model.index(currentRow + 1)); +} + +void AcceptLanguageDialog::removeLanguage() +{ + int currentRow = listView->currentIndex().row(); + m_model.removeRow(currentRow); +} + +void AcceptLanguageDialog::addLanguage() +{ + QString text = addComboBox->currentText(); + if (m_model.stringList().contains(text)) + return; + m_model.insertRow(m_model.rowCount()); + m_model.setData(m_model.index(m_model.rowCount() - 1), text); +} + diff --git a/src/acceptlanguagedialog.h b/src/acceptlanguagedialog.h new file mode 100644 index 00000000..cf6a1817 --- /dev/null +++ b/src/acceptlanguagedialog.h @@ -0,0 +1,56 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef ACCEPTLANGUAGEDIALOG_H +#define ACCEPTLANGUAGEDIALOG_H + +#include +#include "ui_acceptlanguagedialog.h" + +#include + +class AcceptLanguageDialog : public QDialog, public Ui_AcceptLanguage +{ + Q_OBJECT + +public: + AcceptLanguageDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + void accept(); + static QByteArray httpString(const QStringList &list); + static QStringList defaultAcceptList(); + +private slots: + void load(); + void save(); + + void currentChanged(const QModelIndex ¤t, const QModelIndex &previous); + void moveLanguageUp(); + void moveLanguageDown(); + void removeLanguage(); + void addLanguage(); + +private: + static QStringList expand(const QLocale::Language language); + QStringListModel m_allLanguagesModel; + QStringListModel m_model; + +}; + +#endif // ACCEPTLANGUAGEDIALOG_H + diff --git a/src/acceptlanguagedialog.ui b/src/acceptlanguagedialog.ui new file mode 100644 index 00000000..aae65afe --- /dev/null +++ b/src/acceptlanguagedialog.ui @@ -0,0 +1,139 @@ + + + AcceptLanguage + + + + 0 + 0 + 397 + 251 + + + + Languages + + + + + + Languages: in order of preference: + + + true + + + + + + + false + + + Move &Up + + + + + + + false + + + Move &Down + + + + + + + false + + + &Remove + + + + + + + Qt::Vertical + + + + 20 + 38 + + + + + + + + + + + Add... + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + listView + moveUpButton + moveDownButton + removeButton + addComboBox + addButton + buttonBox + + + + + buttonBox + accepted() + AcceptLanguage + accept() + + + 227 + 228 + + + 157 + 250 + + + + + buttonBox + rejected() + AcceptLanguage + reject() + + + 295 + 234 + + + 286 + 250 + + + + + diff --git a/src/adblock/adblock.pri b/src/adblock/adblock.pri new file mode 100644 index 00000000..c373a684 --- /dev/null +++ b/src/adblock/adblock.pri @@ -0,0 +1,28 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + adblockblockednetworkreply.h \ + adblockdialog.h \ + adblockmanager.h \ + adblockmodel.h \ + adblocknetwork.h \ + adblockpage.h \ + adblockrule.h \ + adblockschemeaccesshandler.h \ + adblocksubscription.h + +SOURCES += \ + adblockblockednetworkreply.cpp \ + adblockdialog.cpp \ + adblockmanager.cpp \ + adblockmodel.cpp \ + adblocknetwork.cpp \ + adblockpage.cpp \ + adblockrule.cpp \ + adblockschemeaccesshandler.cpp \ + adblocksubscription.cpp + +FORMS += \ + adblockdialog.ui + diff --git a/src/adblock/adblockblockednetworkreply.cpp b/src/adblock/adblockblockednetworkreply.cpp new file mode 100644 index 00000000..22bc323c --- /dev/null +++ b/src/adblock/adblockblockednetworkreply.cpp @@ -0,0 +1,58 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblockblockednetworkreply.h" + +#include "adblockrule.h" + +#include +#include + +AdBlockBlockedNetworkReply::AdBlockBlockedNetworkReply(const QNetworkRequest &request, const AdBlockRule *rule, QObject *parent) + : QNetworkReply(parent) +{ + setOperation(QNetworkAccessManager::GetOperation); + setRequest(request); + setUrl(request.url()); + setError(QNetworkReply::ContentAccessDenied, tr("Blocked by AdBlockRule: %1").arg(rule->filter())); + QTimer::singleShot(0, this, SLOT(delayedFinished())); +} + +qint64 AdBlockBlockedNetworkReply::readData(char *data, qint64 maxSize) +{ + Q_UNUSED(data); + Q_UNUSED(maxSize); + return -1; +} + +void AdBlockBlockedNetworkReply::delayedFinished() +{ + emit error(QNetworkReply::ContentAccessDenied); + emit finished(); +} + diff --git a/src/adblock/adblockblockednetworkreply.h b/src/adblock/adblockblockednetworkreply.h new file mode 100644 index 00000000..67695846 --- /dev/null +++ b/src/adblock/adblockblockednetworkreply.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKBLOCKEDNETWORKREPLY_H +#define ADBLOCKBLOCKEDNETWORKREPLY_H + +#include + +class AdBlockRule; +class AdBlockBlockedNetworkReply : public QNetworkReply +{ + Q_OBJECT + +public: + AdBlockBlockedNetworkReply(const QNetworkRequest &request, const AdBlockRule *rule, QObject *parent = 0); + void abort() {}; + +protected: + qint64 readData(char *data, qint64 maxSize); + +private slots: + void delayedFinished(); + +}; + +#endif // ADBLOCKBLOCKEDNETWORKREPLY_H + diff --git a/src/adblock/adblockdialog.cpp b/src/adblock/adblockdialog.cpp new file mode 100644 index 00000000..d5c466a9 --- /dev/null +++ b/src/adblock/adblockdialog.cpp @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblockdialog.h" + +#include "adblockmodel.h" +#include "adblockmanager.h" +#include "adblocksubscription.h" +#include "treesortfilterproxymodel.h" + +#include +#include +#include + +#include + +AdBlockDialog::AdBlockDialog(QWidget *parent) + : QDialog(parent) +{ + setupUi(this); + m_adBlockModel = new AdBlockModel(this); + m_proxyModel = new TreeSortFilterProxyModel(this); + m_proxyModel->setSourceModel(m_adBlockModel); + treeView->setModel(m_proxyModel); + connect(search, SIGNAL(textChanged(QString)), + m_proxyModel, SLOT(setFilterFixedString(QString))); + + AdBlockManager *manager = AdBlockManager::instance(); + adblockCheckBox->setChecked(manager->isEnabled()); + connect(adblockCheckBox, SIGNAL(toggled(bool)), + AdBlockManager::instance(), SLOT(setEnabled(bool))); + + QMenu *menu = new QMenu(this); + connect(menu, SIGNAL(aboutToShow()), + this, SLOT(aboutToShowActionMenu())); + actionToolButton->setMenu(menu); + actionToolButton->setIcon(QIcon(QLatin1String(":128x128/run.png"))); + actionToolButton->setPopupMode(QToolButton::InstantPopup); + + AdBlockSubscription *subscription = manager->customRules(); + QModelIndex subscriptionIndex = m_adBlockModel->index(subscription); + treeView->expand(m_proxyModel->mapFromSource(subscriptionIndex)); +} + +void AdBlockDialog::aboutToShowActionMenu() +{ + QMenu *menu = actionToolButton->menu(); + menu->clear(); + + QAction *addRule = menu->addAction(tr("Add Custom Rule")); + connect(addRule, SIGNAL(triggered()), this, SLOT(addCustomRule())); + + QAction *learnRule = menu->addAction(tr("Learn more about writing rules...")); + connect(learnRule, SIGNAL(triggered()), this, SLOT(learnAboutWritingFilters())); + + menu->addSeparator(); + + QModelIndex idx = m_proxyModel->mapToSource(treeView->currentIndex()); + + QAction *updateSubscription = menu->addAction(tr("Update Subscription")); + connect(updateSubscription, SIGNAL(triggered()), this, SLOT(updateSubscription())); + if (!idx.isValid()) + updateSubscription->setEnabled(false); + + QAction *addSubscription = menu->addAction(tr("Browse Subscriptions...")); + connect(addSubscription, SIGNAL(triggered()), this, SLOT(browseSubscriptions())); + + menu->addSeparator(); + + QAction *removeSubscription = menu->addAction(tr("Remove Subscription")); + connect(removeSubscription, SIGNAL(triggered()), this, SLOT(removeSubscription())); + if (!idx.isValid()) + removeSubscription->setEnabled(false); +} + +void AdBlockDialog::addCustomRule(const QString &rule) +{ + AdBlockManager *manager = AdBlockManager::instance(); + AdBlockSubscription *subscription = manager->customRules(); + Q_ASSERT(subscription); + subscription->addRule(AdBlockRule(rule)); + // reset the model + qApp->processEvents(); + + QModelIndex parent = m_adBlockModel->index(subscription); + int x = m_adBlockModel->rowCount(parent); + QModelIndex ruleIndex = m_adBlockModel->index(x - 1, 0, parent); + treeView->expand(m_proxyModel->mapFromSource(parent)); + treeView->edit(m_proxyModel->mapFromSource(ruleIndex)); +} + +void AdBlockDialog::updateSubscription() +{ + QModelIndex idx = m_proxyModel->mapToSource(treeView->currentIndex()); + if (!idx.isValid()) + return; + if (idx.parent().isValid()) + idx = idx.parent(); + AdBlockSubscription *subscription = (AdBlockSubscription*)m_adBlockModel->subscription(idx); + subscription->updateNow(); +} + +void AdBlockDialog::browseSubscriptions() +{ + QUrl url(QLatin1String("http://adblockplus.org/en/subscriptions")); + QDesktopServices::openUrl(url); +} + +void AdBlockDialog::learnAboutWritingFilters() +{ + QUrl url(QLatin1String("http://adblockplus.org/en/filters")); + QDesktopServices::openUrl(url); +} + +void AdBlockDialog::removeSubscription() +{ + QModelIndex idx = m_proxyModel->mapToSource(treeView->currentIndex()); + if (!idx.isValid()) + return; + if (idx.parent().isValid()) + idx = idx.parent(); + AdBlockSubscription *subscription = (AdBlockSubscription*)m_adBlockModel->subscription(idx); + AdBlockManager::instance()->removeSubscription(subscription); +} + diff --git a/src/adblock/adblockdialog.h b/src/adblock/adblockdialog.h new file mode 100644 index 00000000..b428d2a0 --- /dev/null +++ b/src/adblock/adblockdialog.h @@ -0,0 +1,61 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKDIALOG_H +#define ADBLOCKDIALOG_H + +#include +#include "ui_adblockdialog.h" + +class AdBlockModel; +class TreeSortFilterProxyModel; +class AdBlockDialog : public QDialog, public Ui_AdBlockDialog +{ + Q_OBJECT + +public: + AdBlockDialog(QWidget *parent = 0); + +public slots: + void addCustomRule(const QString &rule = QString()); + +private slots: + void learnAboutWritingFilters(); + void aboutToShowActionMenu(); + void updateSubscription(); + void browseSubscriptions(); + void removeSubscription(); + +private: + AdBlockModel *m_adBlockModel; + TreeSortFilterProxyModel *m_proxyModel; + +}; + +#endif // ADBLOCKDIALOG_H + diff --git a/src/adblock/adblockdialog.ui b/src/adblock/adblockdialog.ui new file mode 100644 index 00000000..b4fd9641 --- /dev/null +++ b/src/adblock/adblockdialog.ui @@ -0,0 +1,153 @@ + + + AdBlockDialog + + + + 0 + 0 + 483 + 487 + + + + AdBlock Configuration + + + + + + Enable AdBlock + + + true + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + true + + + + 0 + + + + + Qt::Horizontal + + + + 398 + 23 + + + + + + + + + + + + + + Action + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + SearchLineEdit + QLineEdit +
searchlineedit.h
+
+ + EditTreeView + QTreeView +
edittreeview.h
+
+
+ + + + buttonBox + accepted() + AdBlockDialog + accept() + + + 75 + 495 + + + 157 + 274 + + + + + buttonBox + rejected() + AdBlockDialog + reject() + + + 75 + 495 + + + 286 + 274 + + + + + adblockCheckBox + toggled(bool) + adblockWidget + setEnabled(bool) + + + 106 + 39 + + + 349 + 74 + + + + +
diff --git a/src/adblock/adblockmanager.cpp b/src/adblock/adblockmanager.cpp new file mode 100644 index 00000000..959f880d --- /dev/null +++ b/src/adblock/adblockmanager.cpp @@ -0,0 +1,229 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblockmanager.h" + +#include "autosaver.h" +#include "adblockdialog.h" +#include "adblocknetwork.h" +#include "adblockpage.h" +#include "adblocksubscription.h" +#include "browserapplication.h" +#include "networkaccessmanager.h" + +#include +#include + +#include + +// #define ADBLOCKMANAGER_DEBUG + +AdBlockManager *AdBlockManager::s_adBlockManager = 0; + +AdBlockManager::AdBlockManager(QObject *parent) + : QObject(parent) + , m_loaded(false) + , m_enabled(true) + , m_saveTimer(new AutoSaver(this)) + , m_adBlockDialog(0) + , m_adBlockNetwork(0) + , m_adBlockPage(0) +{ + connect(this, SIGNAL(rulesChanged()), + m_saveTimer, SLOT(changeOccurred())); +} + +AdBlockManager::~AdBlockManager() +{ + m_saveTimer->saveIfNeccessary(); +} + +AdBlockManager *AdBlockManager::instance() +{ + if (!s_adBlockManager) { + // Set a parent that will delete us before the application exits + s_adBlockManager = new AdBlockManager(BrowserApplication::networkAccessManager()); + } + return s_adBlockManager; +} + +bool AdBlockManager::isEnabled() const +{ + if (!m_loaded) { + AdBlockManager *that = const_cast(this); + that->load(); + } + return m_enabled; +} + +void AdBlockManager::setEnabled(bool enabled) +{ + if (isEnabled() == enabled) + return; + m_enabled = enabled; + emit rulesChanged(); +} + +AdBlockNetwork *AdBlockManager::network() +{ + if (!m_adBlockNetwork) + m_adBlockNetwork = new AdBlockNetwork(this); + return m_adBlockNetwork; +} + +AdBlockPage *AdBlockManager::page() +{ + if (!m_adBlockPage) + m_adBlockPage = new AdBlockPage(this); + return m_adBlockPage; +} + +static QUrl customSubscriptionLocation() +{ + QString fileName = BrowserApplication::dataFilePath(QLatin1String("adblock_subscription_custom")); + return QUrl::fromLocalFile(fileName); +} + +QUrl AdBlockManager::customSubscriptionUrl() +{ + QUrl location = customSubscriptionLocation(); + QString encodedUrl = QString::fromUtf8(location.toEncoded()); + QUrl url(QString(QLatin1String("abp:subscribe?location=%1&title=%2")) + .arg(encodedUrl) + .arg(tr("Custom Rules"))); + return url; +} + +AdBlockSubscription *AdBlockManager::customRules() +{ + QUrl location = customSubscriptionLocation(); + foreach (AdBlockSubscription *subscription, m_subscriptions) { + if (subscription->location() == location) + return subscription; + } + QUrl url = customSubscriptionUrl(); + AdBlockSubscription *customAdBlockSubscription = new AdBlockSubscription(url, this); + addSubscription(customAdBlockSubscription); + return customAdBlockSubscription; +} + +QList AdBlockManager::subscriptions() const +{ + if (!m_loaded) { + AdBlockManager *that = const_cast(this); + that->load(); + } + return m_subscriptions; +} + +void AdBlockManager::removeSubscription(AdBlockSubscription *subscription) +{ + if (!subscription) + return; +#if defined(ADBLOCKMANAGER_DEBUG) + qDebug() << "AdBlockManager::" << __FUNCTION__ << subscription->location(); +#endif + m_saveTimer->saveIfNeccessary(); + m_subscriptions.removeOne(subscription); + if (subscription->parent() == this) + subscription->deleteLater(); + emit rulesChanged(); +} + +void AdBlockManager::addSubscription(AdBlockSubscription *subscription) +{ + if (!subscription) + return; +#if defined(ADBLOCKMANAGER_DEBUG) + qDebug() << "AdBlockManager::" << __FUNCTION__ << subscription->location(); +#endif + m_subscriptions.append(subscription); + connect(subscription, SIGNAL(rulesChanged()), this, SIGNAL(rulesChanged())); + connect(subscription, SIGNAL(changed()), this, SIGNAL(rulesChanged())); + emit rulesChanged(); +} + +void AdBlockManager::save() +{ +#if defined(ADBLOCKMANAGER_DEBUG) + qDebug() << "AdBlockManager::" << __FUNCTION__ << m_loaded; +#endif + if (!m_loaded) + return; + + QSettings settings; + settings.beginGroup(QLatin1String("AdBlock")); + settings.setValue(QLatin1String("enabled"), m_enabled); + QStringList subscriptions; + foreach (AdBlockSubscription *subscription, m_subscriptions) { + if (!subscription) + continue; + subscriptions.append(QString::fromUtf8(subscription->url().toEncoded())); + subscription->saveRules(); + } + settings.setValue(QLatin1String("subscriptions"), subscriptions); +} + +void AdBlockManager::load() +{ +#if defined(ADBLOCKMANAGER_DEBUG) + qDebug() << "AdBlockManager::" << __FUNCTION__ << m_loaded; +#endif + + if (m_loaded) + return; + m_loaded = true; + + QSettings settings; + settings.beginGroup(QLatin1String("AdBlock")); + m_enabled = settings.value(QLatin1String("enabled"), m_enabled).toBool(); + + QStringList defaultSubscriptions; + defaultSubscriptions.append(QString::fromUtf8(customSubscriptionUrl().toEncoded())); + defaultSubscriptions.append(QLatin1String("abp:subscribe?location=http://adblockplus.mozdev.org/easylist/easylist.txt&title=EasyList")); + + QStringList subscriptions = settings.value(QLatin1String("subscriptions"), defaultSubscriptions).toStringList(); + foreach (const QString &subscription, subscriptions) { + QUrl url = QUrl::fromEncoded(subscription.toUtf8()); + AdBlockSubscription *adBlockSubscription = new AdBlockSubscription(url, this); + connect(adBlockSubscription, SIGNAL(rulesChanged()), this, SIGNAL(rulesChanged())); + connect(adBlockSubscription, SIGNAL(changed()), this, SIGNAL(rulesChanged())); + m_subscriptions.append(adBlockSubscription); + } +} + +AdBlockDialog *AdBlockManager::showDialog() +{ + if (!m_adBlockDialog) { + m_adBlockDialog = new AdBlockDialog(0); + m_adBlockDialog->setAttribute(Qt::WA_DeleteOnClose, true); + } + m_adBlockDialog->show(); + return m_adBlockDialog; +} + diff --git a/src/adblock/adblockmanager.h b/src/adblock/adblockmanager.h new file mode 100644 index 00000000..d16e3bf3 --- /dev/null +++ b/src/adblock/adblockmanager.h @@ -0,0 +1,88 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKMANAGER_H +#define ADBLOCKMANAGER_H + +#include + +#include + +class QUrl; +class AutoSaver; +class AdBlockDialog; +class AdBlockNetwork; +class AdBlockPage; +class AdBlockSubscription; +class AdBlockManager : public QObject +{ + Q_OBJECT + +signals: + void rulesChanged(); + +public: + AdBlockManager(QObject *parent = 0); + ~AdBlockManager(); + + void load(); + + static AdBlockManager *instance(); + bool isEnabled() const; + + QList subscriptions() const; + void removeSubscription(AdBlockSubscription *subscription); + void addSubscription(AdBlockSubscription *subscription); + + AdBlockNetwork *network(); + AdBlockPage *page(); + AdBlockSubscription *customRules(); + +public slots: + void setEnabled(bool enabled); + AdBlockDialog *showDialog(); + +private slots: + void save(); + +private: + static QUrl customSubscriptionUrl(); + static AdBlockManager *s_adBlockManager; + + bool m_loaded; + bool m_enabled; + AutoSaver *m_saveTimer; + QPointer m_adBlockDialog; + AdBlockNetwork *m_adBlockNetwork; + AdBlockPage *m_adBlockPage; + QList m_subscriptions; + +}; + +#endif // ADBLOCKMANAGER_H + diff --git a/src/adblock/adblockmodel.cpp b/src/adblock/adblockmodel.cpp new file mode 100644 index 00000000..1b5ba2d3 --- /dev/null +++ b/src/adblock/adblockmodel.cpp @@ -0,0 +1,281 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblockmodel.h" + +#include "adblockrule.h" +#include "adblocksubscription.h" +#include "adblockmanager.h" + +AdBlockModel::AdBlockModel(QObject *parent) + : QAbstractItemModel(parent) + , m_manager(AdBlockManager::instance()) +{ + connect(m_manager, SIGNAL(rulesChanged()), this, SLOT(rulesChanged())); +} + +void AdBlockModel::rulesChanged() +{ + reset(); +} + +const AdBlockRule AdBlockModel::rule(const QModelIndex &index) const +{ + const AdBlockSubscription *parent = static_cast(index.internalPointer()); + Q_ASSERT(parent); + return parent->allRules().at(index.row()); +} + +AdBlockSubscription *AdBlockModel::subscription(const QModelIndex &index) const +{ + const AdBlockSubscription *parent = static_cast(index.internalPointer()); + if (parent) + return 0; + int row = index.row(); + if (row < 0 || row >= m_manager->subscriptions().count()) + return 0; + return m_manager->subscriptions().at(row); +} + +QModelIndex AdBlockModel::index(AdBlockSubscription *subscription) +{ + int row = m_manager->subscriptions().indexOf(subscription); + if (row < 0 || row >= m_manager->subscriptions().count()) + return QModelIndex(); + return createIndex(row, 0, 0); +} + +QVariant AdBlockModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + switch (section) { + case 0: return tr("Rule"); + } + } + return QAbstractItemModel::headerData(section, orientation, role); +} + +QVariant AdBlockModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() + || index.model() != this + || index.column() != 0) + return QVariant(); + + switch (role) { + case Qt::EditRole: + case Qt::DisplayRole: + if (index.parent().isValid()) { + const AdBlockRule r = rule(index); + return r.filter(); + } else { + AdBlockSubscription *sub = subscription(index); + if (sub) + return sub->title(); + } + break; + case Qt::CheckStateRole: + if (index.parent().isValid()) { + const AdBlockRule r = rule(index); + return r.isEnabled() ? Qt::Checked : Qt::Unchecked; + } else { + AdBlockSubscription *sub = subscription(index); + if (sub) + return sub->isEnabled() ? Qt::Checked : Qt::Unchecked; + } + break; + default: + break; + } + + return QVariant(); +} + +int AdBlockModel::columnCount(const QModelIndex &parent) const +{ + return (parent.column() > 0) ? 0 : 1; +} + +int AdBlockModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + return m_manager->subscriptions().count(); + + if (parent.internalPointer() != 0) + return 0; + + const AdBlockSubscription *parentNode = subscription(parent); + return parentNode ? parentNode->allRules().count() : 0; +} + +QModelIndex AdBlockModel::index(int row, int column, const QModelIndex &parent) const +{ + if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) + return QModelIndex(); + + if (!parent.isValid()) + return createIndex(row, column, (void*)0); + + // get the parent node + const AdBlockSubscription *parentNode = subscription(parent); + return createIndex(row, column, (void*)parentNode); +} + +QModelIndex AdBlockModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + AdBlockSubscription *parent = static_cast(index.internalPointer()); + if (!parent) + return QModelIndex(); + + int parentRow = m_manager->subscriptions().indexOf(parent); + return createIndex(parentRow, 0, 0); +} + +Qt::ItemFlags AdBlockModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + Qt::ItemFlags flags = Qt::ItemIsSelectable; + + if (index.parent().isValid()) { + flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable; + const AdBlockSubscription *parentNode = subscription(index.parent()); + if (parentNode && parentNode->isEnabled()) + flags |= Qt::ItemIsEnabled; + } else { + flags |= Qt::ItemIsUserCheckable | Qt::ItemIsEditable | Qt::ItemIsEnabled; + } + + return flags; +} + +bool AdBlockModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (row < 0 || count <= 0 || row + count > rowCount(parent)) + return false; + + if (!parent.isValid()) { + disconnect(m_manager, SIGNAL(rulesChanged()), this, SLOT(rulesChanged())); + beginRemoveRows(QModelIndex(), row, row + count - 1); + for (int i = row + count - 1; i >= row; --i) { + AdBlockManager *manager = AdBlockManager::instance(); + manager->removeSubscription(manager->subscriptions().at(i)); + } + endRemoveRows(); + connect(m_manager, SIGNAL(rulesChanged()), this, SLOT(rulesChanged())); + return true; + } else { + AdBlockSubscription *sub = subscription(parent); + if (sub) { + disconnect(m_manager, SIGNAL(rulesChanged()), this, SLOT(rulesChanged())); + beginRemoveRows(parent, row, row + count - 1); + QList rules = sub->allRules(); + for (int i = row + count - 1; i >= row; --i) + sub->removeRule(i); + endRemoveRows(); + connect(m_manager, SIGNAL(rulesChanged()), this, SLOT(rulesChanged())); + return true; + } + } + + return false; +} + +bool AdBlockModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() + || index.model() != this + || index.column() != 0 + || (flags(index) & Qt::ItemIsEditable) == 0) + return false; + + disconnect(m_manager, SIGNAL(rulesChanged()), this, SLOT(rulesChanged())); + bool changed = false; + switch (role) { + case Qt::EditRole: + case Qt::DisplayRole: + if (index.parent().isValid()) { + AdBlockSubscription *sub = subscription(index.parent()); + if (sub) { + AdBlockRule r = rule(index); + r.setFilter(value.toString()); + sub->replaceRule(r, index.row()); + dataChanged(index, index); + changed = true; + } + } else { + AdBlockSubscription *sub = subscription(index); + if (sub) { + sub->setTitle(value.toString()); + dataChanged(index, index); + changed = true; + } + } + break; + case Qt::CheckStateRole: + if (index.parent().isValid()) { + AdBlockSubscription *sub = subscription(index.parent()); + if (sub) { + AdBlockRule r = rule(index); + r.setEnabled(value == Qt::Checked); + sub->replaceRule(r, index.row()); + dataChanged(index, index); + changed = true; + } + } else { + AdBlockSubscription *sub = subscription(index); + if (sub) { + sub->setEnabled(value == Qt::Checked); + dataChanged(index, index); + changed = true; + } + } + break; + default: + break; + } + connect(m_manager, SIGNAL(rulesChanged()), this, SLOT(rulesChanged())); + return changed; +} + +bool AdBlockModel::hasChildren(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return true; + if (parent.internalPointer() == 0) + return true; + return false; +} + diff --git a/src/adblock/adblockmodel.h b/src/adblock/adblockmodel.h new file mode 100644 index 00000000..36066211 --- /dev/null +++ b/src/adblock/adblockmodel.h @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKMODEL_H +#define ADBLOCKMODEL_H + +#include + +class AdBlockRule; +class AdBlockSubscription; +class AdBlockManager; +class AdBlockModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + AdBlockModel(QObject *parent = 0); + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + + const AdBlockRule rule(const QModelIndex &index) const; + AdBlockSubscription *subscription(const QModelIndex &index) const; + QModelIndex index(AdBlockSubscription *subscription); + +private slots: + void rulesChanged(); + +private: + AdBlockManager *m_manager; +}; + +#endif // ADBLOCKMODEL_H + diff --git a/src/adblock/adblocknetwork.cpp b/src/adblock/adblocknetwork.cpp new file mode 100644 index 00000000..e811a406 --- /dev/null +++ b/src/adblock/adblocknetwork.cpp @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblocknetwork.h" + +#include "adblockblockednetworkreply.h" +#include "adblockmanager.h" +#include "adblocksubscription.h" + +#include + +// #define ADBLOCKNETWORK_DEBUG + +AdBlockNetwork::AdBlockNetwork(QObject *parent) + : QObject(parent) +{ +} + +QNetworkReply *AdBlockNetwork::block(const QNetworkRequest &request) +{ + QUrl url = request.url(); + + if (url.scheme() == QLatin1String("data")) + return 0; + + AdBlockManager *manager = AdBlockManager::instance(); + if (!manager->isEnabled()) + return 0; + + QString urlString = QString::fromUtf8(url.toEncoded()); + const AdBlockRule *blockedRule = 0; + const AdBlockSubscription *blockingSubscription = 0; + + QList subscriptions = manager->subscriptions(); + foreach (AdBlockSubscription *subscription, subscriptions) { + if (subscription->allow(urlString)) + return 0; + + if (const AdBlockRule *rule = subscription->block(urlString)) { + blockedRule = rule; + blockingSubscription = subscription; + break; + } + } + + if (blockedRule) { +#if defined(ADBLOCKNETWORK_DEBUG) + qDebug() << "AdBlockNetwork::" << __FUNCTION__ << "rule:" << blockedRule->filter() << "subscription:" << blockingSubscription->title() << url; +#endif + AdBlockBlockedNetworkReply *reply = new AdBlockBlockedNetworkReply(request, blockedRule, this); + return reply; + } + return 0; +} + diff --git a/src/adblock/adblocknetwork.h b/src/adblock/adblocknetwork.h new file mode 100644 index 00000000..7616a5ae --- /dev/null +++ b/src/adblock/adblocknetwork.h @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKNETWORK_H +#define ADBLOCKNETWORK_H + +#include + +class QNetworkRequest; +class QNetworkReply; +class AdBlockNetwork : public QObject +{ + Q_OBJECT + +public: + AdBlockNetwork(QObject *parent = 0); + + QNetworkReply *block(const QNetworkRequest &request); + +}; + +#endif // ADBLOCKNETWORK_H + diff --git a/src/adblock/adblockpage.cpp b/src/adblock/adblockpage.cpp new file mode 100644 index 00000000..e00e25ca --- /dev/null +++ b/src/adblock/adblockpage.cpp @@ -0,0 +1,119 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblockpage.h" + +#include "adblockmanager.h" +#include "adblocksubscription.h" +#include "adblockrule.h" + +#if QT_VERSION >= 0x040600 +#include +#endif +#include +#include + +#include + +// #define ADBLOCKPAGE_DEBUG + +AdBlockPage::AdBlockPage(QObject *parent) + : QObject(parent) +{ +} + +void AdBlockPage::checkRule(const AdBlockRule *rule, QWebPage *page, const QString &host) +{ + if (!rule->isEnabled()) + return; + + QString filter = rule->filter(); + int offset = filter.indexOf(QLatin1String("##")); + if (offset == -1) + return; + + QString selectorQuery; + if (offset > 0) { + QString domainRules = filter.mid(0, offset); + selectorQuery = filter.mid(offset + 2); + QStringList domains = domainRules.split(QLatin1Char(',')); + + bool match = false; + foreach (const QString &domain, domains) { + bool reverse = (domain[0] == QLatin1Char('~')); + if (reverse) { + QString xdomain = domain.mid(1); + if (host.endsWith(xdomain)) + return; + match = true; + } + if (host.endsWith(domain)) + match = true; + } + if (!match) + return; + } + + if (offset == 0) + selectorQuery = filter.mid(2); + + Q_UNUSED(page); +#if QT_VERSION >= 0x040600 + QWebElement document = page->mainFrame()->documentElement(); + QWebElementCollection elements = document.findAll(selectorQuery); +#if defined(ADBLOCKPAGE_DEBUG) + if (elements.count() != 0) + qDebug() << "AdBlockPage::" << __FUNCTION__ << "blocking" << elements.count() << "items" << selectorQuery << elements.count() << "rule:" << rule->filter(); +#endif + foreach (QWebElement element, elements) { + element.setStyleProperty(QLatin1String("visibility"), QLatin1String("hidden")); + element.removeFromDocument(); + } + +#endif +} + +void AdBlockPage::applyRulesToPage(QWebPage *page) +{ + if (!page || !page->mainFrame()) + return; + AdBlockManager *manager = AdBlockManager::instance(); + if (!manager->isEnabled()) + return; +#if QT_VERSION >= 0x040600 + QString host = page->mainFrame()->url().host(); + QList subscriptions = manager->subscriptions(); + foreach (AdBlockSubscription *subscription, subscriptions) { + QList rules = subscription->pageRules(); + foreach (const AdBlockRule *rule, rules) { + checkRule(rule, page, host); + } + } +#endif +} + diff --git a/src/adblock/adblockpage.h b/src/adblock/adblockpage.h new file mode 100644 index 00000000..a1f3b0d2 --- /dev/null +++ b/src/adblock/adblockpage.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKPAGE_H +#define ADBLOCKPAGE_H + +#include + +class AdBlockRule; +class QWebPage; +class AdBlockPage : public QObject +{ + Q_OBJECT + +public: + AdBlockPage(QObject *parent = 0); + + void applyRulesToPage(QWebPage *page); + +private: + void checkRule(const AdBlockRule *rule, QWebPage *page, const QString &host); +}; + +#endif // ADBLOCKPAGE_H + diff --git a/src/adblock/adblockrule.cpp b/src/adblock/adblockrule.cpp new file mode 100644 index 00000000..26ab3c86 --- /dev/null +++ b/src/adblock/adblockrule.cpp @@ -0,0 +1,198 @@ +/** + * Copyright (c) 2009, Zsombor Gegesy + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblockrule.h" + +#include "adblocksubscription.h" + +#include +#include +#include + +// #define ADBLOCKRULE_DEBUG + +AdBlockRule::AdBlockRule(const QString &filter) +{ + setFilter(filter); +} + +QString AdBlockRule::filter() const +{ + return m_filter; +} + +void AdBlockRule::setFilter(const QString &filter) +{ + m_filter = filter; + + m_cssRule = false; + m_enabled = true; + m_exception = false; + bool regExpRule = false; + + if (filter.startsWith(QLatin1String("!")) + || filter.trimmed().isEmpty()) + m_enabled = false; + + if (filter.contains(QLatin1String("##"))) + m_cssRule = true; + + QString parsedLine = filter; + if (parsedLine.startsWith(QLatin1String("@@"))) { + m_exception = true; + parsedLine = parsedLine.mid(2); + } + if (parsedLine.startsWith(QLatin1Char('/'))) { + if (parsedLine.endsWith(QLatin1Char('/'))) { + parsedLine = parsedLine.mid(1); + parsedLine = parsedLine.left(parsedLine.size() - 1); + regExpRule = true; + } + } + int options = parsedLine.indexOf(QLatin1String("$"), 0); + if (options >= 0) { + m_options = parsedLine.mid(options + 1).split(QLatin1Char(',')); + parsedLine = parsedLine.left(options); + } + + setPattern(parsedLine, regExpRule); + + if (m_options.contains(QLatin1String("match-case"))) { + m_regExp.setCaseSensitivity(Qt::CaseSensitive); + m_options.removeOne(QLatin1String("match-case")); + } +} + +bool AdBlockRule::networkMatch(const QString &encodedUrl) const +{ + if (m_cssRule) { +#if defined(ADBLOCKRULE_DEBUG) + qDebug() << "AdBlockRule::" << __FUNCTION__ << "m_cssRule" << m_cssRule; +#endif + return false; + } + + if (!m_enabled) { +#if defined(ADBLOCKRULE_DEBUG) + qDebug() << "AdBlockRule::" << __FUNCTION__ << "is not enabled"; +#endif + return false; + } + + bool matched = m_regExp.indexIn(encodedUrl) != -1; + + if (matched + && !m_options.isEmpty()) { + + // we only support domain right now + if (m_options.count() == 1) { + foreach (const QString &option, m_options) { + if (option.startsWith(QLatin1String("domain="))) { + QUrl url = QUrl::fromEncoded(encodedUrl.toUtf8()); + QString host = url.host(); + QStringList domainOptions = option.mid(7).split(QLatin1Char('|')); + foreach (QString domainOption, domainOptions) { + bool negate = domainOption.at(0) == QLatin1Char('~'); + if (negate) + domainOption = domainOption.mid(1); + bool hostMatched = domainOption == host; + if (hostMatched && !negate) + return true; + if (!hostMatched && negate) + return true; + } + } + } + } + +#if defined(ADBLOCKRULE_DEBUG) + qDebug() << "AdBlockRule::" << __FUNCTION__ << "options are currently not supported" << m_options; +#endif + return false; + } +#if defined(ADBLOCKRULE_DEBUG) + //qDebug() << "AdBlockRule::" << __FUNCTION__ << encodedUrl << "MATCHED" << matched << filter(); +#endif + + return matched; +} + +bool AdBlockRule::isException() const +{ + return m_exception; +} + +void AdBlockRule::setException(bool exception) +{ + m_exception = exception; +} + +bool AdBlockRule::isEnabled() const +{ + return m_enabled; +} + +void AdBlockRule::setEnabled(bool enabled) +{ + m_enabled = enabled; + if (!enabled) { + m_filter = QLatin1String("!") + m_filter; + } else { + m_filter = m_filter.mid(1); + } +} + +QString AdBlockRule::regExpPattern() const +{ + return m_regExp.pattern(); +} + +static QString convertPatternToRegExp(const QString &wildcardPattern) { + QString pattern = wildcardPattern; + return pattern.replace(QRegExp(QLatin1String("\\*+")), QLatin1String("*")) // remove multiple wildcards + .replace(QRegExp(QLatin1String("\\^\\|$")), QLatin1String("^")) // remove anchors following separator placeholder + .replace(QRegExp(QLatin1String("^(\\*)")), QLatin1String("")) // remove leading wildcards + .replace(QRegExp(QLatin1String("(\\*)$")), QLatin1String("")) // remove trailing wildcards + .replace(QRegExp(QLatin1String("(\\W)")), QLatin1String("\\\\1")) // escape special symbols + .replace(QRegExp(QLatin1String("^\\\\\\|\\\\\\|")), + QLatin1String("^[\\w\\-]+:\\/+(?!\\/)(?:[^\\/]+\\.)?")) // process extended anchor at expression start + .replace(QRegExp(QLatin1String("\\\\\\^")), + QLatin1String("(?:[^\\w\\d\\-.%]|$)")) // process separator placeholders + .replace(QRegExp(QLatin1String("^\\\\\\|")), QLatin1String("^")) // process anchor at expression start + .replace(QRegExp(QLatin1String("\\\\\\|$")), QLatin1String("$")) // process anchor at expression end + .replace(QRegExp(QLatin1String("\\\\\\*")), QLatin1String(".*")) // replace wildcards by .* + ; +} + +void AdBlockRule::setPattern(const QString &pattern, bool isRegExp) +{ + m_regExp = QRegExp(isRegExp ? pattern : convertPatternToRegExp(pattern), + Qt::CaseInsensitive, QRegExp::RegExp2); +} + diff --git a/src/adblock/adblockrule.h b/src/adblock/adblockrule.h new file mode 100644 index 00000000..98ff4ad9 --- /dev/null +++ b/src/adblock/adblockrule.h @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKRULE_H +#define ADBLOCKRULE_H + +#include + +class QUrl; +class QRegExp; +class AdBlockRule +{ + +public: + AdBlockRule(const QString &filter = QString()); + + QString filter() const; + void setFilter(const QString &filter); + + bool isCSSRule() const { return m_cssRule; } + bool networkMatch(const QString &encodedUrl) const; + + bool isException() const; + void setException(bool exception); + + bool isEnabled() const; + void setEnabled(bool enabled); + + QString regExpPattern() const; + void setPattern(const QString &pattern, bool isRegExp); + +private: + QString m_filter; + + bool m_cssRule; + bool m_exception; + bool m_enabled; + QRegExp m_regExp; + QStringList m_options; +}; + +#endif // ADBLOCKRULE_H + diff --git a/src/adblock/adblockschemeaccesshandler.cpp b/src/adblock/adblockschemeaccesshandler.cpp new file mode 100644 index 00000000..6acecaf5 --- /dev/null +++ b/src/adblock/adblockschemeaccesshandler.cpp @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblockschemeaccesshandler.h" + +#include "adblockmanager.h" +#include "adblocksubscription.h" +#include "adblockdialog.h" + +#include +#include + +AdBlockSchemeAccessHandler::AdBlockSchemeAccessHandler(QObject *parent) + : SchemeAccessHandler(parent) +{ +} + +QNetworkReply *AdBlockSchemeAccessHandler::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) +{ + Q_UNUSED(outgoingData); + if (op != QNetworkAccessManager::GetOperation) + return 0; + + if (request.url().path() != QLatin1String("subscribe")) + return 0; + + AdBlockSubscription *subscription = new AdBlockSubscription(request.url(), AdBlockManager::instance()); + + QMessageBox::StandardButton result = QMessageBox::question(0 + , tr("Subscribe?") + , tr("Subscribe to this AdBlock subscription?\n%1").arg(subscription->title()) + , QMessageBox::Yes | QMessageBox::No); + if (result == QMessageBox::No) { + delete subscription; + } else { + AdBlockManager::instance()->addSubscription(subscription); + AdBlockDialog *dialog = AdBlockManager::instance()->showDialog(); + QAbstractItemModel *model = dialog->treeView->model(); + dialog->treeView->setCurrentIndex(model->index(model->rowCount() -1, 0)); + dialog->setFocus(); + } + return 0; +} + diff --git a/src/adblock/adblockschemeaccesshandler.h b/src/adblock/adblockschemeaccesshandler.h new file mode 100644 index 00000000..bcec735c --- /dev/null +++ b/src/adblock/adblockschemeaccesshandler.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKSCHEMEACCESSHANDLER_H +#define ADBLOCKSCHEMEACCESSHANDLER_H + +#include "schemeaccesshandler.h" + +class AdBlockSchemeAccessHandler : public SchemeAccessHandler +{ +public: + AdBlockSchemeAccessHandler(QObject *parent = 0); + + virtual QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0); +}; + +#endif // ADBLOCKSCHEMEACCESSHANDLER_H diff --git a/src/adblock/adblocksubscription.cpp b/src/adblock/adblocksubscription.cpp new file mode 100644 index 00000000..d28c590d --- /dev/null +++ b/src/adblock/adblocksubscription.cpp @@ -0,0 +1,375 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "adblocksubscription.h" + +#include "browserapplication.h" +#include "networkaccessmanager.h" + +#include +#include +#include +#include +#include + +// #define ADBLOCKSUBSCRIPTION_DEBUG + +AdBlockSubscription::AdBlockSubscription(const QUrl &url, QObject *parent) + : QObject(parent) + , m_url(url.toEncoded()) + , m_enabled(false) + , m_downloading(0) +{ + parseUrl(url); +} + +void AdBlockSubscription::parseUrl(const QUrl &url) +{ +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << url; +#endif + if (url.scheme() != QLatin1String("abp")) + return; + if (url.path() != QLatin1String("subscribe")) + return; + + m_title = QUrl::fromPercentEncoding(url.encodedQueryItemValue("title")); + m_enabled = QUrl::fromPercentEncoding(url.encodedQueryItemValue("enabled")) != QLatin1String("false"); + m_location = QUrl::fromPercentEncoding(url.encodedQueryItemValue("location")).toUtf8(); + QByteArray lastUpdateByteArray = url.encodedQueryItemValue("lastUpdate"); + QString lastUpdateString = QUrl::fromPercentEncoding(lastUpdateByteArray); + m_lastUpdate = QDateTime::fromString(lastUpdateString, Qt::ISODate); + loadRules(); +} + +QUrl AdBlockSubscription::url() const +{ + QUrl url; + url.setScheme(QLatin1String("abp")); + url.setPath(QLatin1String("subscribe")); + + typedef QPair Query; + QList queryItems; + + queryItems.append(Query(QLatin1String("location"), QString::fromUtf8(m_location))); + queryItems.append(Query(QLatin1String("title"), m_title)); + if (!m_enabled) + queryItems.append(Query(QLatin1String("enabled"), QLatin1String("false"))); + if (m_lastUpdate.isValid()) + queryItems.append(Query(QLatin1String("lastUpdate"), m_lastUpdate.toString(Qt::ISODate))); + url.setQueryItems(queryItems); + return url; +} + +bool AdBlockSubscription::isEnabled() const +{ + return m_enabled; +} + +void AdBlockSubscription::setEnabled(bool enabled) +{ + if (m_enabled == enabled) + return; + m_enabled = enabled; + populateCache(); + emit changed(); +} + +QString AdBlockSubscription::title() const +{ + return m_title; +} + +void AdBlockSubscription::setTitle(const QString &title) +{ + if (m_title == title) + return; + m_title = title; + emit changed(); +} + +QUrl AdBlockSubscription::location() const +{ + return QUrl::fromEncoded(m_location); +} + +void AdBlockSubscription::setLocation(const QUrl &url) +{ + if (url == location()) + return; + m_location = url.toEncoded(); + m_lastUpdate = QDateTime(); + emit changed(); +} + +QDateTime AdBlockSubscription::lastUpdate() const +{ + return m_lastUpdate; +} + +QString AdBlockSubscription::rulesFileName() const +{ + if (location().scheme() == QLatin1String("file")) + return location().toLocalFile(); + + if (m_location.isEmpty()) + return QString(); + + QByteArray sha1 = QCryptographicHash::hash(m_location, QCryptographicHash::Sha1).toHex(); + QString fileName = BrowserApplication::dataFilePath(QString(QLatin1String("adblock_subscription_%1")).arg(QLatin1String(sha1))); + return fileName; +} + +void AdBlockSubscription::loadRules() +{ + QString fileName = rulesFileName(); +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << fileName; +#endif + QFile file(fileName); + if (file.exists()) { + if (!file.open(QFile::ReadOnly)) { + qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for reading" << fileName; + } else { + QTextStream textStream(&file); + QString header = textStream.readLine(1024); + if (!header.startsWith(QLatin1String("[Adblock"))) { + qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "adblock file does not start with [Adblock" << fileName << "Header:" << header; + file.close(); + file.remove(); + m_lastUpdate = QDateTime(); + } else { + m_rules.clear(); + while (!textStream.atEnd()) { + QString line = textStream.readLine(); + m_rules.append(AdBlockRule(line)); + } + populateCache(); + emit rulesChanged(); + } + } + } + + if (!m_lastUpdate.isValid() + || m_lastUpdate.addDays(7) < QDateTime::currentDateTime()) { + updateNow(); + } +} + +void AdBlockSubscription::updateNow() +{ +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << location(); +#endif + if (m_downloading) { +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << "already downloading, stopping"; +#endif + return; + } + + if (!location().isValid()) { +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << location() << "isn't valid"; +#endif + return; + } + + if (location().scheme() == QLatin1String("file")) { +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << "local file, not downloading"; +#endif + m_lastUpdate = QDateTime::currentDateTime(); + loadRules(); + emit changed(); + return; + } + + QNetworkRequest request(location()); + QNetworkReply *reply = BrowserApplication::networkAccessManager()->get(request); + m_downloading = reply; + connect(reply, SIGNAL(finished()), this, SLOT(rulesDownloaded())); +} + +void AdBlockSubscription::rulesDownloaded() +{ +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << rulesFileName(); +#endif + QNetworkReply *reply = qobject_cast(sender()); + if (!reply) { +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << "no reply?"; +#endif + return; + } + + QByteArray response = reply->readAll(); + QUrl redirect = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl(); + reply->close(); + reply->deleteLater(); + + if (reply->error() != QNetworkReply::NoError) { + qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "error" << reply->errorString(); + return; + } + + if (redirect.isValid()) { +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << "redirect to:" << redirect; +#endif + QNetworkRequest request(redirect); + m_downloading = BrowserApplication::networkAccessManager()->get(request); + connect(m_downloading, SIGNAL(finished()), this, SLOT(rulesDownloaded())); + return; + } + + if (response.isEmpty()) { + qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "empty response"; + return; + } + + QString fileName = rulesFileName(); + QFile file(fileName); + if (!file.open(QFile::ReadWrite)) { + qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << fileName; + return; + } + file.write(response); + m_lastUpdate = QDateTime::currentDateTime(); + loadRules(); + emit changed(); + m_downloading = 0; +} + +void AdBlockSubscription::saveRules() +{ +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << rulesFileName() << m_rules.count(); +#endif + QString fileName = rulesFileName(); + if (fileName.isEmpty()) + return; + + QFile file(fileName); + if (!file.open(QFile::ReadWrite | QIODevice::Truncate)) { + qWarning() << "AdBlockSubscription::" << __FUNCTION__ << "Unable to open adblock file for writing:" << fileName; + return; + } + + QTextStream textStream(&file); + textStream << "[Adblock Plus 0.7.1]" << endl; + foreach (const AdBlockRule &rule, m_rules) + textStream << rule.filter() << endl; +} + +QList AdBlockSubscription::pageRules() const +{ + return m_pageRules; +} + +const AdBlockRule *AdBlockSubscription::allow(const QString &urlString) const +{ + foreach (const AdBlockRule *rule, m_networkExceptionRules) { + if (rule->networkMatch(urlString)) + return rule; + } + return 0; +} + +const AdBlockRule *AdBlockSubscription::block(const QString &urlString) const +{ + foreach (const AdBlockRule *rule, m_networkBlockRules) { + if (rule->networkMatch(urlString)) + return rule; + } + return 0; +} + +QList AdBlockSubscription::allRules() const +{ + return m_rules; +} + +void AdBlockSubscription::addRule(const AdBlockRule &rule) +{ +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << rule.filter(); +#endif + m_rules.append(rule); + populateCache(); + emit rulesChanged(); +} + +void AdBlockSubscription::removeRule(int offset) +{ +#if defined(ADBLOCKSUBSCRIPTION_DEBUG) + qDebug() << "AdBlockSubscription::" << __FUNCTION__ << offset << m_rules.count(); +#endif + if (offset < 0 || offset >= m_rules.count()) + return; + m_rules.removeAt(offset); + populateCache(); + emit rulesChanged(); +} + +void AdBlockSubscription::replaceRule(const AdBlockRule &rule, int offset) +{ + if (offset < 0 || offset >= m_rules.count()) + return; + m_rules[offset] = rule; + populateCache(); + emit rulesChanged(); +} + +void AdBlockSubscription::populateCache() +{ + m_networkExceptionRules.clear(); + m_networkBlockRules.clear(); + m_pageRules.clear(); + if (!isEnabled()) + return; + + for (int i = 0; i < m_rules.count(); ++i) { + const AdBlockRule *rule = &m_rules.at(i); + if (!rule->isEnabled()) + continue; + + if (rule->isCSSRule()) { + m_pageRules.append(rule); + continue; + } + + if (rule->isException()) { + m_networkExceptionRules.append(rule); + } else { + m_networkBlockRules.append(rule); + } + } +} + diff --git a/src/adblock/adblocksubscription.h b/src/adblock/adblocksubscription.h new file mode 100644 index 00000000..43639a47 --- /dev/null +++ b/src/adblock/adblocksubscription.h @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ADBLOCKSUBSCRIPTION_H +#define ADBLOCKSUBSCRIPTION_H + +#include + +#include "adblockrule.h" + +#include +#include + +class QNetworkReply; +class QUrl; +class AdBlockSubscription : public QObject +{ + Q_OBJECT + +signals: + void changed(); + void rulesChanged(); + +public: + AdBlockSubscription(const QUrl &url, QObject *parent = 0); + QUrl url() const; + + bool isEnabled() const; + void setEnabled(bool enabled); + + QString title() const; + void setTitle(const QString &title); + + QUrl location() const; + void setLocation(const QUrl &url); + + void updateNow(); + QDateTime lastUpdate() const; + + void saveRules(); + + const AdBlockRule *allow(const QString &urlString) const; + const AdBlockRule *block(const QString &urlString) const; + QList pageRules() const; + + QList allRules() const; + void addRule(const AdBlockRule &rule); + void removeRule(int offset); + void replaceRule(const AdBlockRule &rule, int offset); + +private slots: + void rulesDownloaded(); + +private: + void populateCache(); + QString rulesFileName() const; + void parseUrl(const QUrl &url); + void loadRules(); + + QByteArray m_url; + + QString m_title; + QByteArray m_location; + QDateTime m_lastUpdate; + bool m_enabled; + + QNetworkReply *m_downloading; + QList m_rules; + + // sorted list + QList m_networkExceptionRules; + QList m_networkBlockRules; + QList m_pageRules; +}; + +#endif // ADBLOCKSUBSCRIPTION_H + diff --git a/src/arora.desktop b/src/arora.desktop old mode 100644 new mode 100755 index 34219276..fc668e4b --- a/src/arora.desktop +++ b/src/arora.desktop @@ -1,19 +1,38 @@ [Desktop Entry] -Comment=Arora Web Browser -Comment[en_US]=Arora Web Browser -Exec=arora %U -GenericName= -GenericName[en_US]= -Icon=arora -MimeType= Name=Arora Name[en_US]=Arora -NoDisplay=true -StartupNotify=true +Name[es]=Arora +Name[gl]=Arora +Name[sr]=Арора +Name[sr@latin]=Arora +Comment=Browse the World Wide Web +Comment[ast]=Restola pola World Wide Web +Comment[es]=Navegar por internet +Comment[fr_FR]=Surfer sur le web +Comment[gl]=Navegar pola internet +Comment[nl]=Surfen op het wereldwijde web +Comment[nl_NL]=Surfen op het wereldwijde web +Comment[sr]=Крстарите интернетом +Comment[sr@latin]=Krstarite Internetom +Comment[ja_JP]=Webを閲覧します +GenericName=Web Browser +GenericName[ast]=Restolador web +GenericName[cs_CZ]=Webový prohlížeč +GenericName[en_US]=Web Browser +GenericName[es]=Navegador web +GenericName[fr_FR]=Navigateur web +GenericName[gl]=Navegador web +GenericName[nl]=Webbrowser +GenericName[nl_NL]=Webbrowser +GenericName[pl]=Przeglądarka WWW +GenericName[sr]=Веб прегледач +GenericName[sr@latin]=Web pregledač +GenericName[nb_NO]=Nettleser +GenericName[ja_JP]=Webブラウザ +Exec=arora %u Terminal=false Type=Application -Categories=Qt;Network;WebBrowser; -X-DCOP-ServiceType= -X-KDE-HasTempFileOption=true -X-KDE-StartupNotify=true -X-KDE-SubstituteUID=false \ No newline at end of file +Icon=arora +Categories=Application;Qt;Network;WebBrowser; +MimeType=text/html;text/xml;application/xhtml+xml;application/xml;image/gif;image/jpeg;image/png; +StartupNotify=true diff --git a/src/autofilldialog.cpp b/src/autofilldialog.cpp new file mode 100644 index 00000000..7e1acd14 --- /dev/null +++ b/src/autofilldialog.cpp @@ -0,0 +1,174 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "autofilldialog.h" + +#include "autofillmanager.h" +#include "browserapplication.h" + +#include + +AutoFillModel::AutoFillModel(QObject *parent) + : QAbstractTableModel(parent) +{ + AutoFillManager *manager = BrowserApplication::instance()->autoFillManager(); + Q_ASSERT(manager); + connect(manager, SIGNAL(autoFillChanged()), this, SLOT(autoFillChanged())); + autoFillChanged(); +} + +void AutoFillModel::autoFillChanged() +{ + AutoFillManager *manager = BrowserApplication::instance()->autoFillManager(); + m_forms = manager->forms(); + reset(); +} + +QVariant AutoFillModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal + && role == Qt::DisplayRole) { + switch (section) { + case 0: return tr("WebSite"); + case 1: return tr("User Name"); + } + } + return QAbstractTableModel::headerData(section, orientation, role); +} + +QVariant AutoFillModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < 0 || index.row() >= m_forms.size()) + return QVariant(); + + switch (role) { + case Qt::UserRole: + return m_forms[index.row()].hasAPassword; + case Qt::DisplayRole: + case Qt::EditRole: { + switch (index.column()) { + case 0: + return m_forms[index.row()].url.host(); + case 1: { + QStringList help; + QStringList choices; + foreach (const AutoFillManager::Element &element, m_forms[index.row()].elements) { + QString key = element.first.toLower(); + if (key.contains(QLatin1String("pass"))) + continue; + if (key.contains(QLatin1String("user")) + || key.contains(QLatin1String("email")) + || key.contains(QLatin1String("login")) + || key == QLatin1String("u")) + return element.second; + choices.append(element.second); + help.append(element.first); + } + if (choices.count() == 1) + return choices.first(); + qWarning() << "AutoFillModel: Unknown user id, choices:" << help << "url" << m_forms[index.row()].url.toString(); + return help.join(QLatin1String(",")); + } + } + } + default: + break; + } + return QVariant(); +} + +int AutoFillModel::columnCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : 2; +} + +int AutoFillModel::rowCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : m_forms.count(); +} + +bool AutoFillModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid()) + return false; + int lastRow = row + count - 1; + beginRemoveRows(parent, row, lastRow); + for (int i = lastRow; i >= row; --i) + m_forms.removeAt(i); + AutoFillManager *manager = BrowserApplication::instance()->autoFillManager(); + disconnect(manager, SIGNAL(autoFillChanged()), this, SLOT(autoFillChanged())); + manager->setForms(m_forms); + connect(manager, SIGNAL(autoFillChanged()), this, SLOT(autoFillChanged())); + endRemoveRows(); + return true; +} + +AutoFillDialog::AutoFillDialog(QWidget *parent, Qt::WindowFlags flags) + : QDialog(parent, flags) +{ + setupUi(this); + setWindowFlags(Qt::Sheet); + connect(removeButton, SIGNAL(clicked()), tableView, SLOT(removeSelected())); + connect(removeAllButton, SIGNAL(clicked()), tableView, SLOT(removeAll())); + tableView->verticalHeader()->hide(); + tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + tableView->setAlternatingRowColors(true); + tableView->setTextElideMode(Qt::ElideMiddle); + tableView->setShowGrid(false); + tableView->setSortingEnabled(true); + + AutoFillModel *model = new AutoFillModel(); + QSortFilterProxyModel *m_proxyModel = new QSortFilterProxyModel(this); + connect(search, SIGNAL(textChanged(QString)), + m_proxyModel, SLOT(setFilterFixedString(QString))); + m_proxyModel->setSourceModel(model); + tableView->setModel(m_proxyModel); + + QFont f = font(); + f.setPointSize(10); + QFontMetrics fm(f); + int height = fm.height() + fm.height() / 3; + tableView->verticalHeader()->setDefaultSectionSize(height); + tableView->verticalHeader()->setMinimumSectionSize(-1); + for (int i = 0; i < model->columnCount(); ++i) { + int header = tableView->horizontalHeader()->sectionSizeHint(i); + switch (i) { + case 0: + header = fm.width(QLatin1String("averagehost.domain.com")); + break; + case 1: + header = fm.width(QLatin1String("_session_id")); + break; + } + int buffer = fm.width(QLatin1String("xx")); + header += buffer; + tableView->horizontalHeader()->resizeSection(i, header); + } + tableView->horizontalHeader()->setStretchLastSection(true); +} + diff --git a/src/autofilldialog.h b/src/autofilldialog.h new file mode 100644 index 00000000..79a4626f --- /dev/null +++ b/src/autofilldialog.h @@ -0,0 +1,69 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef AUTOFILLDIALOG_H +#define AUTOFILLDIALOG_H + +#include +#include "ui_autofilldialog.h" + +#include "autofillmanager.h" + +#include + +class AutoFillModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + AutoFillModel(QObject *parent = 0); + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + +private slots: + void autoFillChanged(); + +private: + QList m_forms; +}; + + +class AutoFillDialog : public QDialog, public Ui_AutoFillDialog +{ + Q_OBJECT + +public: + AutoFillDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0); + +}; + +#endif // AUTOFILLDIALOG_H + diff --git a/src/autofilldialog.ui b/src/autofilldialog.ui new file mode 100644 index 00000000..93fbcbaa --- /dev/null +++ b/src/autofilldialog.ui @@ -0,0 +1,126 @@ + + + AutoFillDialog + + + + 0 + 0 + 529 + 421 + + + + Form Passwords + + + + + + Qt::Horizontal + + + + 252 + 20 + + + + + + + + + + + false + + + + + + + Remove + + + + + + + Remove All + + + + + + + Qt::Horizontal + + + + 36 + 20 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + EditTableView + QTableView +
edittableview.h
+
+ + SearchLineEdit + QLineEdit +
searchlineedit.h
+
+
+ + + + buttonBox + accepted() + AutoFillDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AutoFillDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/src/autofillmanager.cpp b/src/autofillmanager.cpp new file mode 100644 index 00000000..b4c713ed --- /dev/null +++ b/src/autofillmanager.cpp @@ -0,0 +1,418 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "autofillmanager.h" + +#include "autosaver.h" +#include "browserapplication.h" +#include "browsermainwindow.h" +#include "networkaccessmanagerproxy.h" +#include "webpageproxy.h" +#include "webview.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// #define AUTOFILL_DEBUG + +AutoFillManager::AutoFillManager(QObject *parent) + : QObject(parent) + , m_savePasswordForms(true) + , m_allowAutoCompleteOff(true) + , m_saveTimer(new AutoSaver(this)) +{ + connect(this, SIGNAL(autoFillChanged()), + m_saveTimer, SLOT(changeOccurred())); + loadSettings(); + loadFormData(); +} + +AutoFillManager::~AutoFillManager() +{ + m_saveTimer->saveIfNeccessary(); +} + +void AutoFillManager::save() const +{ + saveFormData(); +} + +void AutoFillManager::setForms(const QList
&forms) +{ + m_forms = forms; + emit autoFillChanged(); +} + +QList AutoFillManager::forms() const +{ + return m_forms; +} + +void AutoFillManager::loadSettings() +{ + QSettings settings; + settings.beginGroup(QLatin1String("autofill")); + m_savePasswordForms = settings.value(QLatin1String("passwordForms"), m_savePasswordForms).toBool(); + m_allowAutoCompleteOff = settings.value(QLatin1String("ignoreAutoCompleteOff"), m_allowAutoCompleteOff).toBool(); +} + +QString AutoFillManager::autoFillDataFile() +{ + QString fileName = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + fileName += QLatin1String("/autofill.dat"); + return fileName; +} + +void AutoFillManager::saveFormData() const +{ + QString fileName = autoFillDataFile(); + QFile file(fileName); + if (!file.open(QFile::WriteOnly)) { + qWarning() << "Unable to open" << fileName << "to store autofill data"; + return; + } + + QDataStream stream(&file); + stream << m_forms; +} + +void AutoFillManager::loadFormData() +{ + QString fileName = autoFillDataFile(); + QFile file(fileName); + if (!file.open(QFile::ReadOnly)) + return; + + QDataStream stream(&file); + stream >> m_forms; +} + +void AutoFillManager::post(const QNetworkRequest &request, const QByteArray &outgoingData) +{ +#ifdef AUTOFILL_DEBUG + qDebug() << "AutoFillManager::" << __FUNCTION__ << outgoingData << request.url(); +#endif + + // Don't even give the options to save this site user name & password. + if (QWebSettings::globalSettings()->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { + return; + } + + // Determine the url + QByteArray refererHeader = request.rawHeader("Referer"); + if (refererHeader.isEmpty()) { + // XXX We could store the frame url in the request if this is a common problem + qWarning() << "AutoFillManager:" << "Unable to determine the request Referer"; + return; + } + QUrl url = QUrl::fromEncoded(refererHeader); + url = stripUrl(url); + + // Check that the url isn't in m_never + if (m_never.contains(url)) + return; + + // Check the request type + QVariant typeVariant = request.attribute((QNetworkRequest::Attribute)(WebPageProxy::pageAttributeId() + 1)); + QWebPage::NavigationType type = (QWebPage::NavigationType)typeVariant.toInt(); + if (typeVariant.isValid() && type != QWebPage::NavigationTypeFormSubmitted) { + // XXX Does this occur normally? + qWarning() << "AutoFillManager:" << "Type is not FormSubmitted" << type + << "expected:" << QWebPage::NavigationTypeFormSubmitted; + return; + } + + // Determine the QWebView + QVariant v = request.attribute((QNetworkRequest::Attribute)(WebPageProxy::pageAttributeId())); + QWebPage *webPage = (QWebPage*)(v.value()); + if (!webPage) { + qWarning() << "AutoFillManager:" << "QWebPage is not set in QNetworkRequest."; + return; + } +#if 0 + // TODO CHECK reply ownership + if (!NetworkAccessManagerProxy::exists(webPage)) { + qWarning() << "AutoFillManager:" << "QWebPage no longer exists."; + return; + } +#endif + + // Find the matching form on the webpage + Form form = findForm(webPage, outgoingData); + if (!form.isValid()) { +#if 0 + qWarning() << "AutoFillManager:" << "Unable to find matching form on the webpage."; +#endif + return; + } + form.url = url; + + // Check if we allow storing this form if it has a password + if (!allowedToAutoFill(form.hasAPassword)) + return; + + // Prompt if we have never seen this password + int alreadyAccepted = -1; + for (int i = 0; i < m_forms.count(); ++i) { + const Form &form = m_forms.at(i); + if (form.url == url) { + alreadyAccepted = i; + break; + } + } + if (form.hasAPassword && alreadyAccepted == -1) { + QMessageBox messageBox; + messageBox.setText(tr("Would you like to save this password?
\ + To review passwords you have saved and remove them, open the AutoFill panel of preferences.")); + messageBox.addButton(tr("Never for this site"), QMessageBox::DestructiveRole); + messageBox.addButton(tr("Not now"), QMessageBox::RejectRole); + messageBox.addButton(QMessageBox::Yes); + messageBox.setDefaultButton(QMessageBox::Yes); + messageBox.exec(); + switch (messageBox.buttonRole(messageBox.clickedButton())) { + case QMessageBox::DestructiveRole: + m_never.append(url); + return; + case QMessageBox::RejectRole: + return; + default: + break; + } + } + +#ifdef AUTOFILL_DEBUG + qDebug() << "AutoFillManager:" << "Saving" << form.url; +#endif + // TODO When we can hook into element events we can save multiple passwords for different users + if (alreadyAccepted != -1) + m_forms.removeAt(alreadyAccepted); + m_forms.append(form); + emit autoFillChanged(); +} + +AutoFillManager::Form AutoFillManager::findForm(QWebPage *webPage, const QByteArray &outgoingData) const +{ + Form form; + QUrl argsUrl = QUrl::fromEncoded(QByteArray("foo://bar.com/?" + outgoingData)); + QList > encodedArgs = argsUrl.queryItems(); + QSet > args; + // XXX Is there a Qt function to do this? (unencode '+' to ' ') + for (int i = 0; i < encodedArgs.count(); ++i) { + QString key = encodedArgs[i].first; + QString value = encodedArgs[i].second.replace(QLatin1String("+"), QLatin1String(" ")); + QPair p(key, value); + args.insert(p); + } + + QFile file(QLatin1String(":parseForms.js")); + if (!file.open(QFile::ReadOnly)) { + qWarning() << "AutoFillManager:" << "Unable to open js form parsing file"; + return form; + } + QString script = QLatin1String(file.readAll()); + + // XXX Do I need to do this on subframes? + QVariant r = webPage->mainFrame()->evaluateJavaScript(script); + QVariantList list = r.toList(); + foreach (const QVariant &formVariant, list) { + QVariantMap map = formVariant.toMap(); + bool formHasPasswords = false; + QString formName = map[QLatin1String("name")].toString(); + QVariantList elements = map[QLatin1String("elements")].toList(); + QSet > formElements; + QSet > deadElements; + foreach (const QVariant &element, elements) { + QVariantMap elementMap = element.toMap(); + QString name = elementMap[QLatin1String("name")].toString(); + QString value = elementMap[QLatin1String("value")].toString(); + QString type = elementMap[QLatin1String("type")].toString(); + if (type == QLatin1String("password")) + formHasPasswords = true; + QPair p(name, value); + if ((elementMap[QLatin1String("autocomplete")].toString()) == QLatin1String("off")) + deadElements.insert(p); + if (!name.isEmpty()) + formElements.insert(p); + } +#if 0 + QT_VERSION >= 0x040600 + if (formElements.contains(args)) { +#else + if (formElements.intersect(args) == args) { +#endif + form.hasAPassword = formHasPasswords; + form.name = formName; + if (m_allowAutoCompleteOff) + args = args.subtract(deadElements); + form.elements = args.toList(); + break; + } +#ifdef AUTOFILL_DEBUG + qDebug() << formName; + qDebug() << formElements; + qDebug() << args; + qDebug() << formElements.count() << args.count() << formElements.subtract(args); +#endif + } + return form; +} + +QUrl AutoFillManager::stripUrl(const QUrl &url) +{ + QUrl cleanUrl = url; + cleanUrl.setQueryItems(QList >()); + cleanUrl.setFragment(QString()); + cleanUrl.setUserInfo(QString()); + return cleanUrl; +} + +bool AutoFillManager::allowedToAutoFill(bool password) const +{ + if (password && m_savePasswordForms) + return true; + return false; +} + +QList AutoFillManager::fetchForms(const QUrl &url) const +{ + QList forms; + foreach (const Form &form, m_forms) + if (form.url == url) + forms.append(form); +#ifdef AUTOFILL_DEBUG + qDebug() << "AutoFillManager::" << __FUNCTION__ << url << m_forms.count() << "found:" << forms.count(); +#endif + return forms; +} + +void AutoFillManager::fill(QWebPage *page) const +{ +#ifdef AUTOFILL_DEBUG + qDebug() << "AutoFillManager::" << __FUNCTION__ << page; +#endif + if (!page || !page->mainFrame()) + return; + + QUrl url = page->mainFrame()->url(); + url = stripUrl(url); + + const QList forms = fetchForms(url); + if (forms.isEmpty()) + return; + + foreach (const Form &form, forms) { + QString formName = QString(QLatin1String("\"%1\"")).arg(form.name); + if (form.name.isEmpty()) + formName = QLatin1String("0"); + foreach (const AutoFillManager::Element &element, form.elements) { + const QString key = element.first; + const QString value = element.second; + + // When we drop 4.5 migrate this to the 4.6 dom API + bool disabled = page->mainFrame()->evaluateJavaScript(QString(QLatin1String("document.forms[%1].elements[\"%2\"].disabled")).arg(formName).arg(key)).toBool(); + if (disabled) { +#ifdef AUTOFILL_DEBUG + qDebug() << formName << "is disabled"; +#endif + continue; + } + bool readOnly = page->mainFrame()->evaluateJavaScript(QString(QLatin1String("document.forms[%1].elements[\"%2\"].readonly")).arg(formName).arg(key)).toBool(); + if (readOnly) { +#ifdef AUTOFILL_DEBUG + qDebug() << formName << "is readOnly"; +#endif + continue; + } + + QString type = page->mainFrame()->evaluateJavaScript(QString(QLatin1String("document.forms[%1].elements[\"%2\"].type")).arg(formName).arg(key)).toString(); + if (type.isEmpty() + || type == QLatin1String("hidden") + || type == QLatin1String("reset") + || type == QLatin1String("submit")) { +#ifdef AUTOFILL_DEBUG + qDebug() << formName << key << "is hidden, reset or submit"; +#endif + continue; + } +#ifdef AUTOFILL_DEBUG + qDebug() << "type:" << type << "readonly" << readOnly << "disabled" << disabled << key << value; +#endif + QString setType = (type == QLatin1String("checkbox")) + ? QLatin1String("checked") + : QLatin1String("value"); + + // XXX is there a cleaner way to do this? + QString jsValue = value; + jsValue.replace(QLatin1Char('\\'), QLatin1String("\\\\")); + jsValue.replace(QLatin1Char('\"'), QLatin1String("\\\"")); + QString javascript = QString(QLatin1String("document.forms[%1].elements[\"%2\"].%3=\"%4\";")) + .arg(formName) + .arg(key) + .arg(setType) + .arg(jsValue); + page->mainFrame()->evaluateJavaScript(javascript); + } + } +} + +QDataStream &operator>>(QDataStream &in, AutoFillManager::Form &form) +{ + AutoFillManager::Form::load(in, form); + return in; +} + +QDataStream &operator<<(QDataStream &out, const AutoFillManager::Form &form) +{ + AutoFillManager::Form::save(out, form); + return out; +} + +void AutoFillManager::Form::load(QDataStream &in, AutoFillManager::Form &form) +{ + in >> form.elements; + in >> form.url; + in >> form.name; + in >> form.hasAPassword; +} + +void AutoFillManager::Form::save(QDataStream &out, const AutoFillManager::Form &form) +{ + out << form.elements; + out << form.url; + out << form.name; + out << form.hasAPassword; +} + diff --git a/src/autofillmanager.h b/src/autofillmanager.h new file mode 100644 index 00000000..c6a0c00e --- /dev/null +++ b/src/autofillmanager.h @@ -0,0 +1,95 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef AUTOFILLMANAGER_H +#define AUTOFILLMANAGER_H + +#include + +#include + +class QWebPage; +class AutoSaver; +class AutoFillManager : public QObject +{ + Q_OBJECT + +signals: + void autoFillChanged(); + +public: + typedef QPair Element; + class Form { + public: + bool isValid() { return !elements.isEmpty(); } + static void load(QDataStream &in, Form &subscription); + static void save(QDataStream &out, const Form &subscription); + + QList elements; + QUrl url; + QString name; + bool hasAPassword; + }; + + AutoFillManager(QObject *parent = 0); + ~AutoFillManager(); + + void loadSettings(); + + void post(const QNetworkRequest &request, const QByteArray &outgoingData); + void fill(QWebPage *page) const; + + void setForms(const QList &forms); + QList forms() const; + +private slots: + void save() const; + +private: + Form findForm(QWebPage *page, const QByteArray &outgoingData) const; + static QUrl stripUrl(const QUrl &url); + static QString autoFillDataFile(); + bool allowedToAutoFill(bool password) const; + QList fetchForms(const QUrl &url) const; + + void saveFormData() const; + void loadFormData(); + + bool m_savePasswordForms; + bool m_allowAutoCompleteOff; + + QList m_forms; + QList m_never; + AutoSaver *m_saveTimer; +}; + +QDataStream &operator<<(QDataStream &, const AutoFillManager::Form &form); +QDataStream &operator>>(QDataStream &, AutoFillManager::Form &form); + +#endif // AUTOFILLMANAGER_H + diff --git a/src/autosaver.cpp b/src/autosaver.cpp index 58912f1e..01714351 100644 --- a/src/autosaver.cpp +++ b/src/autosaver.cpp @@ -79,9 +79,9 @@ AutoSaver::AutoSaver(QObject *parent) : QObject(parent) AutoSaver::~AutoSaver() { if (m_timer.isActive()) { - qWarning() << "AutoSaver: still active when destroyed, changes not saved."; - if (parent()) - qWarning() << parent() << "should call saveIfNeccessary"; + qWarning() << "AutoSaver: still active when destroyed, changes not saved."; + if (parent() && parent()->metaObject()) + qWarning() << parent() << parent()->metaObject()->className() << "should call saveIfNeccessary"; } } diff --git a/src/bookmarks.cpp b/src/bookmarks.cpp deleted file mode 100644 index 7f195195..00000000 --- a/src/bookmarks.cpp +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * Copyright 2008 Benjamin C. Meyer - * - * This program 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/**************************************************************************** -** -** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "bookmarks.h" - -#include "autosaver.h" -#include "browserapplication.h" -#include "history.h" -#include "xbel.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#define BOOKMARKBAR "Bookmarks Bar" -#define BOOKMARKMENU "Bookmarks Menu" - -BookmarksManager::BookmarksManager(QObject *parent) - : QObject(parent) - , m_loaded(false) - , m_saveTimer(new AutoSaver(this)) - , m_bookmarkRootNode(0) - , m_bookmarkModel(0) -{ - connect(this, SIGNAL(entryAdded(BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryChanged(BookmarkNode *)), - m_saveTimer, SLOT(changeOccurred())); -} - -BookmarksManager::~BookmarksManager() -{ - m_saveTimer->saveIfNeccessary(); -} - -void BookmarksManager::changeExpanded() -{ - m_saveTimer->changeOccurred(); -} - -void BookmarksManager::load() -{ - if (m_loaded) - return; - m_loaded = true; - - QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); - if (!QFile::exists(bookmarkFile)) - bookmarkFile = QLatin1String(":defaultbookmarks.xbel"); - - XbelReader reader; - m_bookmarkRootNode = reader.read(bookmarkFile); - if (reader.error() != QXmlStreamReader::NoError) { - QMessageBox::warning(0, QLatin1String("Loading Bookmark"), - tr("Error when loading bookmarks on line %1, column %2:\n" - "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); - } - - BookmarkNode *toolbar = 0; - BookmarkNode *menu = 0; - QList others; - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->type() == BookmarkNode::Folder) { - // Automatically convert - if (node->title == tr("Toolbar Bookmarks") && !toolbar) { - node->title = tr(BOOKMARKBAR); - } - if (node->title == tr(BOOKMARKBAR) && !toolbar) { - toolbar = node; - } - - // Automatically convert - if (node->title == tr("Menu") && !menu) { - node->title = tr(BOOKMARKMENU); - } - if (node->title == tr(BOOKMARKMENU) && !menu) { - menu = node; - } - } else { - others.append(node); - } - m_bookmarkRootNode->remove(node); - } - Q_ASSERT(m_bookmarkRootNode->children().count() == 0); - if (!toolbar) { - toolbar = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); - toolbar->title = tr(BOOKMARKBAR); - } else { - m_bookmarkRootNode->add(toolbar); - } - - if (!menu) { - menu = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); - menu->title = tr(BOOKMARKMENU); - } else { - m_bookmarkRootNode->add(menu); - } - - for (int i = 0; i < others.count(); ++i) - menu->add(others.at(i)); -} - -void BookmarksManager::save() const -{ - if (!m_loaded) - return; - - XbelWriter writer; - QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); - if (!writer.write(bookmarkFile, m_bookmarkRootNode)) - qWarning() << "BookmarkManager: error saving to" << bookmarkFile; -} - -void BookmarksManager::addBookmark(BookmarkNode *parent, BookmarkNode *node, int row) -{ - if (!m_loaded) - return; - Q_ASSERT(parent); - InsertBookmarksCommand *command = new InsertBookmarksCommand(this, parent, node, row); - m_commands.push(command); -} - -void BookmarksManager::removeBookmark(BookmarkNode *node) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - BookmarkNode *parent = node->parent(); - int row = parent->children().indexOf(node); - RemoveBookmarksCommand *command = new RemoveBookmarksCommand(this, parent, row); - m_commands.push(command); -} - -void BookmarksManager::setTitle(BookmarkNode *node, const QString &newTitle) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newTitle, true); - m_commands.push(command); -} - -void BookmarksManager::setUrl(BookmarkNode *node, const QString &newUrl) -{ - if (!m_loaded) - return; - - Q_ASSERT(node); - ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newUrl, false); - m_commands.push(command); -} - -BookmarkNode *BookmarksManager::bookmarks() -{ - if (!m_loaded) - load(); - return m_bookmarkRootNode; -} - -BookmarkNode *BookmarksManager::menu() -{ - if (!m_loaded) - load(); - - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->title == tr(BOOKMARKMENU)) - return node; - } - Q_ASSERT(false); - return 0; -} - -BookmarkNode *BookmarksManager::toolbar() -{ - if (!m_loaded) - load(); - - for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { - BookmarkNode *node = m_bookmarkRootNode->children().at(i); - if (node->title == tr(BOOKMARKBAR)) - return node; - } - Q_ASSERT(false); - return 0; -} - -BookmarksModel *BookmarksManager::bookmarksModel() -{ - if (!m_bookmarkModel) - m_bookmarkModel = new BookmarksModel(this, this); - return m_bookmarkModel; -} - -void BookmarksManager::importBookmarks() -{ - QString fileName = QFileDialog::getOpenFileName(0, tr("Open File"), - QString(), - tr("XBEL (*.xbel *.xml)")); - if (fileName.isEmpty()) - return; - - XbelReader reader; - BookmarkNode *importRootNode = reader.read(fileName); - if (reader.error() != QXmlStreamReader::NoError) { - QMessageBox::warning(0, QLatin1String("Loading Bookmark"), - tr("Error when loading bookmarks on line %1, column %2:\n" - "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); - } - - importRootNode->setType(BookmarkNode::Folder); - importRootNode->title = (tr("Imported %1").arg(QDate::currentDate().toString(Qt::SystemLocaleShortDate))); - addBookmark(menu(), importRootNode); -} - -void BookmarksManager::exportBookmarks() -{ - QString fileName = QFileDialog::getSaveFileName(0, tr("Save File"), - tr("%1 Bookmarks.xbel").arg(QCoreApplication::applicationName()), - tr("XBEL (*.xbel *.xml)")); - if (fileName.isEmpty()) - return; - - XbelWriter writer; - if (!writer.write(fileName, m_bookmarkRootNode)) - QMessageBox::critical(0, tr("Export error"), tr("error saving bookmarks")); -} - -RemoveBookmarksCommand::RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row) - : QUndoCommand(BookmarksManager::tr("Remove Bookmark")) - , m_row(row) - , m_bookmarkManagaer(m_bookmarkManagaer) - , m_node(parent->children().value(row)) - , m_parent(parent) - , m_done(false) -{ -} - -RemoveBookmarksCommand::~RemoveBookmarksCommand() -{ - if (m_done && !m_node->parent()) { - delete m_node; - } -} - -void RemoveBookmarksCommand::undo() -{ - m_parent->add(m_node, m_row); - emit m_bookmarkManagaer->entryAdded(m_node); - m_done = false; -} - -void RemoveBookmarksCommand::redo() -{ - m_parent->remove(m_node); - emit m_bookmarkManagaer->entryRemoved(m_parent, m_row, m_node); - m_done = true; -} - -InsertBookmarksCommand::InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *parent, BookmarkNode *node, int row) - : RemoveBookmarksCommand(m_bookmarkManagaer, parent, row) -{ - setText(BookmarksManager::tr("Insert Bookmark")); - m_node = node; -} - -ChangeBookmarkCommand::ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *node, - const QString &newValue, bool title) - : QUndoCommand() - , m_bookmarkManagaer(m_bookmarkManagaer) - , m_title(title) - , m_newValue(newValue) - , m_node(node) -{ - if (m_title) { - m_oldValue = m_node->title; - setText(BookmarksManager::tr("Name Change")); - } else { - m_oldValue = m_node->url; - setText(BookmarksManager::tr("Address Change")); - } -} - -void ChangeBookmarkCommand::undo() -{ - if (m_title) - m_node->title = m_oldValue; - else - m_node->url = m_oldValue; - emit m_bookmarkManagaer->entryChanged(m_node); -} - -void ChangeBookmarkCommand::redo() -{ - if (m_title) - m_node->title = m_newValue; - else - m_node->url = m_newValue; - emit m_bookmarkManagaer->entryChanged(m_node); -} - -BookmarksModel::BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent) - : QAbstractItemModel(parent) - , m_endMacro(false) - , m_bookmarksManager(bookmarkManager) -{ - connect(bookmarkManager, SIGNAL(entryAdded(BookmarkNode *)), - this, SLOT(entryAdded(BookmarkNode *))); - connect(bookmarkManager, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), - this, SLOT(entryRemoved(BookmarkNode *, int, BookmarkNode *))); - connect(bookmarkManager, SIGNAL(entryChanged(BookmarkNode *)), - this, SLOT(entryChanged(BookmarkNode *))); -} - -QModelIndex BookmarksModel::index(BookmarkNode *node) const -{ - BookmarkNode *parent = node->parent(); - if (!parent) - return QModelIndex(); - return createIndex(parent->children().indexOf(node), 0, node); -} - -void BookmarksModel::entryAdded(BookmarkNode *item) -{ - Q_ASSERT(item && item->parent()); - int row = item->parent()->children().indexOf(item); - BookmarkNode *parent = item->parent(); - // item was already added so remove beore beginInsertRows is called - parent->remove(item); - beginInsertRows(index(parent), row, row); - parent->add(item, row); - endInsertRows(); -} - -void BookmarksModel::entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item) -{ - // item was already removed, re-add so beginRemoveRows works - parent->add(item, row); - beginRemoveRows(index(parent), row, row); - parent->remove(item); - endRemoveRows(); -} - -void BookmarksModel::entryChanged(BookmarkNode *item) -{ - QModelIndex idx = index(item); - emit dataChanged(idx, idx); -} - -bool BookmarksModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent)) - return false; - - BookmarkNode *bookmarkNode = node(parent); - for (int i = row + count - 1; i >= row; --i) { - BookmarkNode *node = bookmarkNode->children().at(i); - if (node == m_bookmarksManager->menu() - || node == m_bookmarksManager->toolbar()) - continue; - - m_bookmarksManager->removeBookmark(node); - } - if (m_endMacro) { - m_bookmarksManager->undoRedoStack()->endMacro(); - m_endMacro = false; - } - return true; -} - -QVariant BookmarksModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { - switch (section) { - case 0: return tr("Title"); - case 1: return tr("Address"); - } - } - return QAbstractItemModel::headerData(section, orientation, role); -} - -QVariant BookmarksModel::data(const QModelIndex &index, int role) const -{ - if (!index.isValid() || index.model() != this) - return QVariant(); - - const BookmarkNode *bookmarkNode = node(index); - switch (role) { - case Qt::EditRole: - case Qt::DisplayRole: - if (bookmarkNode->type() == BookmarkNode::Separator) { - switch (index.column()) { - case 0: return QString(50, 0xB7); - case 1: return QString(); - } - } - - switch (index.column()) { - case 0: return bookmarkNode->title; - case 1: return bookmarkNode->url; - } - break; - case BookmarksModel::UrlRole: - return QUrl(bookmarkNode->url); - break; - case BookmarksModel::UrlStringRole: - return bookmarkNode->url; - break; - case BookmarksModel::TypeRole: - return bookmarkNode->type(); - break; - case BookmarksModel::SeparatorRole: - return (bookmarkNode->type() == BookmarkNode::Separator); - break; - case Qt::DecorationRole: - if (index.column() == 0) { - if (bookmarkNode->type() == BookmarkNode::Folder) - return QApplication::style()->standardIcon(QStyle::SP_DirIcon); - return BrowserApplication::instance()->icon(bookmarkNode->url); - } - } - - return QVariant(); -} - -int BookmarksModel::columnCount(const QModelIndex &parent) const -{ - return (parent.column() > 0) ? 0 : 2; -} - -int BookmarksModel::rowCount(const QModelIndex &parent) const -{ - if (parent.column() > 0) - return 0; - - if (!parent.isValid()) - return m_bookmarksManager->bookmarks()->children().count(); - - const BookmarkNode *item = static_cast(parent.internalPointer()); - return item->children().count(); -} - -QModelIndex BookmarksModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) - return QModelIndex(); - - // get the parent node - BookmarkNode *parentNode = node(parent); - return createIndex(row, column, parentNode->children().at(row)); -} - -QModelIndex BookmarksModel::parent(const QModelIndex &index) const -{ - if (!index.isValid()) - return QModelIndex(); - - BookmarkNode *itemNode = node(index); - BookmarkNode *parentNode = (itemNode ? itemNode->parent() : 0); - if (!parentNode || parentNode == m_bookmarksManager->bookmarks()) - return QModelIndex(); - - // get the parent's row - BookmarkNode *grandParentNode = parentNode->parent(); - int parentRow = grandParentNode->children().indexOf(parentNode); - Q_ASSERT(parentRow >= 0); - return createIndex(parentRow, 0, parentNode); -} - -bool BookmarksModel::hasChildren(const QModelIndex &parent) const -{ - if (!parent.isValid()) - return true; - const BookmarkNode *parentNode = node(parent); - return (parentNode->type() == BookmarkNode::Folder); -} - -Qt::ItemFlags BookmarksModel::flags(const QModelIndex &index) const -{ - if (!index.isValid()) - return Qt::NoItemFlags; - - Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - - BookmarkNode *bookmarkNode = node(index); - - if (bookmarkNode != m_bookmarksManager->menu() - && bookmarkNode != m_bookmarksManager->toolbar()) { - flags |= Qt::ItemIsDragEnabled; - if (bookmarkNode->type() != BookmarkNode::Separator) - flags |= Qt::ItemIsEditable; - } - if (hasChildren(index)) - flags |= Qt::ItemIsDropEnabled; - return flags; -} - -Qt::DropActions BookmarksModel::supportedDropActions() const -{ - return Qt::CopyAction | Qt::MoveAction; -} - -#define MIMETYPE QLatin1String("application/bookmarks.xbel") - -QStringList BookmarksModel::mimeTypes() const -{ - QStringList types; - types << MIMETYPE; - return types; -} - -QMimeData *BookmarksModel::mimeData(const QModelIndexList &indexes) const -{ - QMimeData *mimeData = new QMimeData(); - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - foreach (QModelIndex index, indexes) { - if (index.column() != 0 || !index.isValid()) - continue; - QByteArray encodedData; - QBuffer buffer(&encodedData); - buffer.open(QBuffer::ReadWrite); - XbelWriter writer; - const BookmarkNode *parentNode = node(index); - writer.write(&buffer, parentNode); - stream << encodedData; - } - mimeData->setData(MIMETYPE, data); - return mimeData; -} - -bool BookmarksModel::dropMimeData(const QMimeData *data, - Qt::DropAction action, int row, int column, const QModelIndex &parent) -{ - if (action == Qt::IgnoreAction) - return true; - - if (!data->hasFormat(MIMETYPE) - || column > 0) - return false; - - QByteArray ba = data->data(MIMETYPE); - QDataStream stream(&ba, QIODevice::ReadOnly); - if (stream.atEnd()) - return false; - - QUndoStack *undoStack = m_bookmarksManager->undoRedoStack(); - undoStack->beginMacro(QLatin1String("Move Bookmarks")); - - while (!stream.atEnd()) { - QByteArray encodedData; - stream >> encodedData; - QBuffer buffer(&encodedData); - buffer.open(QBuffer::ReadOnly); - - XbelReader reader; - BookmarkNode *rootNode = reader.read(&buffer); - QList children = rootNode->children(); - for (int i = 0; i < children.count(); ++i) { - BookmarkNode *bookmarkNode = children.at(i); - rootNode->remove(bookmarkNode); - row = qMax(0, row); - BookmarkNode *parentNode = node(parent); - m_bookmarksManager->addBookmark(parentNode, bookmarkNode, row); - m_endMacro = true; - } - delete rootNode; - } - return true; -} - -bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value, int role) -{ - if (!index.isValid() || (flags(index) & Qt::ItemIsEditable) == 0) - return false; - - BookmarkNode *item = node(index); - - switch (role) { - case Qt::EditRole: - case Qt::DisplayRole: - if (index.column() == 0) { - m_bookmarksManager->setTitle(item, value.toString()); - break; - } - if (index.column() == 1) { - m_bookmarksManager->setUrl(item, value.toString()); - break; - } - return false; - case BookmarksModel::UrlRole: - m_bookmarksManager->setUrl(item, value.toUrl().toString()); - break; - case BookmarksModel::UrlStringRole: - m_bookmarksManager->setUrl(item, value.toString()); - break; - default: - break; - return false; - } - - return true; -} - -BookmarkNode *BookmarksModel::node(const QModelIndex &index) const -{ - BookmarkNode *itemNode = static_cast(index.internalPointer()); - if (!itemNode) - return m_bookmarksManager->bookmarks(); - return itemNode; -} - - -AddBookmarkProxyModel::AddBookmarkProxyModel(QObject *parent) - : QSortFilterProxyModel(parent) -{ -} - -int AddBookmarkProxyModel::columnCount(const QModelIndex &parent) const -{ - return qMin(1, QSortFilterProxyModel::columnCount(parent)); -} - -bool AddBookmarkProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); - return sourceModel()->hasChildren(idx); -} - -AddBookmarkDialog::AddBookmarkDialog(const QString &url, const QString &title, QWidget *parent, BookmarksManager *bookmarkManager) - : QDialog(parent) - , m_url(url) - , m_bookmarksManager(bookmarkManager) -{ - setWindowFlags(Qt::Sheet); - if (!m_bookmarksManager) - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setupUi(this); - QTreeView *view = new QTreeView(this); - m_proxyModel = new AddBookmarkProxyModel(this); - BookmarksModel *model = m_bookmarksManager->bookmarksModel(); - m_proxyModel->setSourceModel(model); - view->setModel(m_proxyModel); - view->expandAll(); - view->header()->setStretchLastSection(true); - view->header()->hide(); - view->setItemsExpandable(false); - view->setRootIsDecorated(false); - view->setIndentation(10); - location->setModel(m_proxyModel); - view->show(); - location->setView(view); - BookmarkNode *menu = m_bookmarksManager->menu(); - QModelIndex idx = m_proxyModel->mapFromSource(model->index(menu)); - view->setCurrentIndex(idx); - location->setCurrentIndex(idx.row()); - name->setText(title); -} - -void AddBookmarkDialog::accept() -{ - QModelIndex index = location->view()->currentIndex(); - index = m_proxyModel->mapToSource(index); - if (!index.isValid()) - index = m_bookmarksManager->bookmarksModel()->index(0, 0); - BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(index); - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark); - bookmark->url = m_url; - bookmark->title = name->text(); - m_bookmarksManager->addBookmark(parent, bookmark); - QDialog::accept(); -} - -BookmarksMenu::BookmarksMenu(QWidget *parent) - : ModelMenu(parent) - , m_bookmarksManager(0) -{ - connect(this, SIGNAL(activated(const QModelIndex &)), - this, SLOT(activated(const QModelIndex &))); - setMaxRows(-1); - setStatusBarTextRole(BookmarksModel::UrlStringRole); - setSeparatorRole(BookmarksModel::SeparatorRole); -} - -void BookmarksMenu::activated(const QModelIndex &index) -{ - emit openUrl( - index.data(BookmarksModel::UrlRole).toUrl(), - TabWidget::CurrentTab, - index.data(Qt::DisplayRole).toString()); -} - -bool BookmarksMenu::prePopulated() -{ - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setModel(m_bookmarksManager->bookmarksModel()); - setRootIndex(m_bookmarksManager->bookmarksModel()->index(1, 0)); - // initial actions - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); - if (!m_initialActions.isEmpty()) - addSeparator(); - createMenu(model()->index(0, 0), 1, this); - return true; -} - -void BookmarksMenu::setInitialActions(QList actions) -{ - m_initialActions = actions; - for (int i = 0; i < m_initialActions.count(); ++i) - addAction(m_initialActions.at(i)); -} - -BookmarksDialog::BookmarksDialog(QWidget *parent, BookmarksManager *manager) - : QDialog(parent) -{ - m_bookmarksManager = manager; - if (!m_bookmarksManager) - m_bookmarksManager = BrowserApplication::bookmarksManager(); - setupUi(this); - - tree->setUniformRowHeights(true); - tree->setSelectionBehavior(QAbstractItemView::SelectRows); - tree->setSelectionMode(QAbstractItemView::ContiguousSelection); - tree->setTextElideMode(Qt::ElideMiddle); - m_bookmarksModel = m_bookmarksManager->bookmarksModel(); - m_proxyModel = new TreeProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeSelected())); - m_proxyModel->setSourceModel(m_bookmarksModel); - tree->setModel(m_proxyModel); - tree->setDragDropMode(QAbstractItemView::InternalMove); - tree->setExpanded(m_proxyModel->index(0, 0), true); - tree->setAlternatingRowColors(true); - QFontMetrics fm(font()); - int header = fm.width(QLatin1Char('m')) * 40; - tree->header()->resizeSection(0, header); - tree->header()->setStretchLastSection(true); - connect(tree, SIGNAL(activated(const QModelIndex&)), - this, SLOT(openInCurrentTab())); - tree->setContextMenuPolicy(Qt::CustomContextMenu); - connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), - this, SLOT(customContextMenuRequested(const QPoint &))); - connect(addFolderButton, SIGNAL(clicked()), - this, SLOT(newFolder())); - expandNodes(m_bookmarksManager->bookmarks()); - setAttribute(Qt::WA_DeleteOnClose); -} - -BookmarksDialog::~BookmarksDialog() -{ - if (saveExpandedNodes(tree->rootIndex())) - m_bookmarksManager->changeExpanded(); -} - -bool BookmarksDialog::saveExpandedNodes(const QModelIndex &parent) -{ - bool changed = false; - for (int i = 0; i < m_proxyModel->rowCount(parent); ++i) { - QModelIndex child = m_proxyModel->index(i, 0, parent); - QModelIndex sourceIndex = m_proxyModel->mapToSource(child); - BookmarkNode *childNode = m_bookmarksModel->node(sourceIndex); - bool wasExpanded = childNode->expanded; - if (tree->isExpanded(child)) { - childNode->expanded = true; - changed |= saveExpandedNodes(child); - } else { - childNode->expanded = false; - } - changed |= (wasExpanded != childNode->expanded); - } - return changed; -} - -void BookmarksDialog::expandNodes(BookmarkNode *node) -{ - for (int i = 0; i < node->children().count(); ++i) { - BookmarkNode *childNode = node->children()[i]; - if (childNode->expanded) { - QModelIndex idx = m_bookmarksModel->index(childNode); - idx = m_proxyModel->mapFromSource(idx); - tree->setExpanded(idx, true); - expandNodes(childNode); - } - } -} - -void BookmarksDialog::customContextMenuRequested(const QPoint &pos) -{ - QMenu menu; - QModelIndex index = tree->indexAt(pos); - index = index.sibling(index.row(), 0); - if (index.isValid() && !tree->model()->hasChildren(index)) { - menu.addAction(tr("Open"), this, SLOT(openInCurrentTab())); - menu.addAction(tr("Open in New Tab"), this, SLOT(openInNewTab())); - menu.addSeparator(); - } - menu.addAction(tr("Delete"), tree, SLOT(removeSelected())); - menu.exec(QCursor::pos()); -} - -void BookmarksDialog::open(TabWidget::Tab tab) -{ - QModelIndex index = tree->currentIndex(); - if (!index.parent().isValid()) - return; - emit openUrl( - index.sibling(index.row(), 1).data(BookmarksModel::UrlRole).toUrl(), - tab, - index.sibling(index.row(), 0).data(Qt::DisplayRole).toString()); -} - -void BookmarksDialog::openInCurrentTab() -{ - open(TabWidget::CurrentTab); -} - -void BookmarksDialog::openInNewTab() -{ - open(TabWidget::NewTab); -} - -void BookmarksDialog::newFolder() -{ - QModelIndex currentIndex = tree->currentIndex(); - QModelIndex idx = currentIndex; - if (idx.isValid() && !idx.model()->hasChildren(idx)) - idx = idx.parent(); - if (!idx.isValid()) - idx = tree->rootIndex(); - idx = m_proxyModel->mapToSource(idx); - BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(idx); - BookmarkNode *node = new BookmarkNode(BookmarkNode::Folder); - node->title = tr("New Folder"); - m_bookmarksManager->addBookmark(parent, node, currentIndex.row() + 1); -} - -BookmarkToolButton::BookmarkToolButton(QUrl url, QWidget *parent) - : QToolButton(parent) - , m_url(url) -{ - connect(this, SIGNAL(clicked()), this, SLOT(openBookmark())); -} - -void BookmarkToolButton::mouseReleaseEvent(QMouseEvent *event) -{ - QToolButton::mouseReleaseEvent(event); - if (event->button() == Qt::MidButton) - emit openBookmark(url(), TabWidget::NewTab, text()); -} - -QUrl BookmarkToolButton::url() const -{ - return m_url; -} - -void BookmarkToolButton::openBookmark() -{ - emit openBookmark(url(), TabWidget::CurrentTab, text()); -} - -BookmarksToolBar::BookmarksToolBar(BookmarksModel *model, QWidget *parent) - : QToolBar(tr("Bookmark"), parent) - , m_bookmarksModel(model) -{ - setRootIndex(model->index(0, 0)); - connect(m_bookmarksModel, SIGNAL(modelReset()), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(build())); - connect(m_bookmarksModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(build())); - setAcceptDrops(true); -} - -void BookmarksToolBar::dragEnterEvent(QDragEnterEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasUrls()) - event->acceptProposedAction(); - QToolBar::dragEnterEvent(event); -} - -void BookmarksToolBar::dropEvent(QDropEvent *event) -{ - const QMimeData *mimeData = event->mimeData(); - if (mimeData->hasUrls() && mimeData->hasText()) { - QList urls = mimeData->urls(); - QAction *action = actionAt(event->pos()); - QString dropText; - if (action) - dropText = action->text(); - int row = -1; - QModelIndex parentIndex = m_root; - for (int i = 0; i < m_bookmarksModel->rowCount(m_root); ++i) { - QModelIndex idx = m_bookmarksModel->index(i, 0, m_root); - QString title = idx.data().toString(); - if (title == dropText) { - row = i; - if (m_bookmarksModel->hasChildren(idx)) { - parentIndex = idx; - row = -1; - } - break; - } - } - BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark); - bookmark->url = urls.at(0).toString(); - bookmark->title = mimeData->text(); - - BookmarkNode *parent = m_bookmarksModel->node(parentIndex); - BookmarksManager *bookmarksManager = m_bookmarksModel->bookmarksManager(); - bookmarksManager->addBookmark(parent, bookmark, row); - event->acceptProposedAction(); - } - QToolBar::dropEvent(event); -} - - -void BookmarksToolBar::setRootIndex(const QModelIndex &index) -{ - m_root = index; - build(); -} - -QModelIndex BookmarksToolBar::rootIndex() const -{ - return m_root; -} - -void BookmarksToolBar::build() -{ - clear(); - for (int i = 0; i < m_bookmarksModel->rowCount(m_root); ++i) { - QModelIndex idx = m_bookmarksModel->index(i, 0, m_root); - if (m_bookmarksModel->hasChildren(idx)) { - QToolButton *button = new QToolButton(this); - button->setPopupMode(QToolButton::InstantPopup); - button->setArrowType(Qt::DownArrow); - button->setText(idx.data().toString()); - ModelMenu *menu = new ModelMenu(this); - menu->setModel(m_bookmarksModel); - menu->setRootIndex(idx); - menu->addAction(new QAction(menu)); - button->setMenu(menu); - button->setToolButtonStyle(Qt::ToolButtonTextOnly); - QAction *a = addWidget(button); - a->setText(idx.data().toString()); - } else { - QUrl url = idx.data(BookmarksModel::UrlRole).toUrl(); - BookmarkToolButton *button = new BookmarkToolButton(url, this); - button->setText(idx.data().toString()); - connect(button, SIGNAL(openBookmark(const QUrl &, TabWidget::Tab, const QString &)), - this, SIGNAL(openUrl(const QUrl &, TabWidget::Tab, const QString &))); - addWidget(button); - } - } -} - diff --git a/src/bookmarks.h b/src/bookmarks.h deleted file mode 100644 index 77e43a35..00000000 --- a/src/bookmarks.h +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright 2008 Benjamin C. Meyer - * - * This program 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/**************************************************************************** -** -** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef BOOKMARKS_H -#define BOOKMARKS_H - -#include - -#include -#include -#include -#include - -#include "tabwidget.h" - -/*! - Bookmark manager, owner of the bookmarks, loads, saves and basic tasks - */ -class AutoSaver; -class BookmarkNode; -class BookmarksModel; -class BookmarksManager : public QObject -{ - Q_OBJECT - -signals: - void entryAdded(BookmarkNode *item); - void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); - void entryChanged(BookmarkNode *item); - -public: - BookmarksManager(QObject *parent = 0); - ~BookmarksManager(); - - void addBookmark(BookmarkNode *parent, BookmarkNode *node, int row = -1); - void removeBookmark(BookmarkNode *node); - void setTitle(BookmarkNode *node, const QString &newTitle); - void setUrl(BookmarkNode *node, const QString &newUrl); - void changeExpanded(); - - BookmarkNode *bookmarks(); - BookmarkNode *menu(); - BookmarkNode *toolbar(); - - BookmarksModel *bookmarksModel(); - QUndoStack *undoRedoStack() { - return &m_commands; - } - -public slots: - void importBookmarks(); - void exportBookmarks(); - -private slots: - void save() const; - -private: - void load(); - - bool m_loaded; - AutoSaver *m_saveTimer; - BookmarkNode *m_bookmarkRootNode; - BookmarksModel *m_bookmarkModel; - QUndoStack m_commands; - - friend class RemoveBookmarksCommand; - friend class ChangeBookmarkCommand; -}; - -class RemoveBookmarksCommand : public QUndoCommand -{ - -public: - RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row); - ~RemoveBookmarksCommand(); - void undo(); - void redo(); - -protected: - int m_row; - BookmarksManager *m_bookmarkManagaer; - BookmarkNode *m_node; - BookmarkNode *m_parent; - bool m_done; -}; - -class InsertBookmarksCommand : public RemoveBookmarksCommand -{ - -public: - InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *parent, BookmarkNode *node, int row); - void undo() { - RemoveBookmarksCommand::redo(); - } - void redo() { - RemoveBookmarksCommand::undo(); - } - -}; - -class ChangeBookmarkCommand : public QUndoCommand -{ - -public: - ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, - BookmarkNode *node, const QString &newValue, bool title); - void undo(); - void redo(); - -private: - BookmarksManager *m_bookmarkManagaer; - bool m_title; - QString m_oldValue; - QString m_newValue; - BookmarkNode *m_node; -}; - -/*! - BookmarksModel is a QAbstractItemModel wrapper around the BookmarkManager - */ -#include -class BookmarksModel : public QAbstractItemModel -{ - Q_OBJECT - -public slots: - void entryAdded(BookmarkNode *item); - void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); - void entryChanged(BookmarkNode *item); - -public: - enum Roles { - TypeRole = Qt::UserRole + 1, - UrlRole = Qt::UserRole + 2, - UrlStringRole = Qt::UserRole + 3, - SeparatorRole = Qt::UserRole + 4 - }; - - BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent = 0); - inline BookmarksManager *bookmarksManager() const { - return m_bookmarksManager; - } - - QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index = QModelIndex()) const; - Qt::ItemFlags flags(const QModelIndex &index) const; - Qt::DropActions supportedDropActions() const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - QMimeData *mimeData(const QModelIndexList &indexes) const; - QStringList mimeTypes() const; - bool dropMimeData(const QMimeData *data, - Qt::DropAction action, int row, int column, const QModelIndex &parent); - bool hasChildren(const QModelIndex &parent = QModelIndex()) const; - - BookmarkNode *node(const QModelIndex &index) const; - QModelIndex index(BookmarkNode *node) const; - -private: - - bool m_endMacro; - BookmarksManager *m_bookmarksManager; -}; - -// Menu that is dynamically populated from the bookmarks -#include "modelmenu.h" -class BookmarksMenu : public ModelMenu -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url, TabWidget::Tab type, const QString &title); - -public: - BookmarksMenu(QWidget *parent = 0); - void setInitialActions(QList actions); - -protected: - bool prePopulated(); - -private slots: - void activated(const QModelIndex &index); - -private: - BookmarksManager *m_bookmarksManager; - QList m_initialActions; -}; - -/* - Proxy model that filters out the bookmarks so only the folders - are left behind. Used in the add bookmark dialog combobox. - */ -#include -class AddBookmarkProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT -public: - AddBookmarkProxyModel(QObject * parent = 0); - int columnCount(const QModelIndex & parent = QModelIndex()) const; - -protected: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; -}; - -/*! - Add bookmark dialog - */ -#include "ui_addbookmarkdialog.h" -class AddBookmarkDialog : public QDialog, public Ui_AddBookmarkDialog -{ - Q_OBJECT - -public: - AddBookmarkDialog(const QString &url, const QString &title, QWidget *parent = 0, BookmarksManager *bookmarkManager = 0); - -private slots: - void accept(); - -private: - QString m_url; - BookmarksManager *m_bookmarksManager; - AddBookmarkProxyModel *m_proxyModel; -}; - -#include "ui_bookmarks.h" -class TreeProxyModel; -class BookmarksDialog : public QDialog, public Ui_BookmarksDialog -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url, TabWidget::Tab, const QString &title); - -public: - BookmarksDialog(QWidget *parent = 0, BookmarksManager *manager = 0); - ~BookmarksDialog(); - -private slots: - void customContextMenuRequested(const QPoint &pos); - void open(TabWidget::Tab tab); - void openInNewTab(); - void openInCurrentTab(); - void newFolder(); - -private: - void expandNodes(BookmarkNode *node); - bool saveExpandedNodes(const QModelIndex &parent); - - BookmarksManager *m_bookmarksManager; - BookmarksModel *m_bookmarksModel; - TreeProxyModel *m_proxyModel; -}; - -class BookmarkToolButton : public QToolButton -{ - Q_OBJECT - -signals: - void openBookmark(const QUrl &url, TabWidget::Tab tab, const QString &title); - -public: - BookmarkToolButton(QUrl url, QWidget *parent = 0); - QUrl url() const; - -protected: - void mouseReleaseEvent(QMouseEvent *event); - -private slots: - void openBookmark(); - -private: - QUrl m_url; - -}; - - -class BookmarksToolBar : public QToolBar -{ - Q_OBJECT - -signals: - void openUrl(const QUrl &url, TabWidget::Tab tab, const QString &title); - -public: - BookmarksToolBar(BookmarksModel *model, QWidget *parent = 0); - void setRootIndex(const QModelIndex &index); - QModelIndex rootIndex() const; - -protected: - void dragEnterEvent(QDragEnterEvent *event); - void dropEvent(QDropEvent *event); - -private slots: - void build(); - -private: - BookmarksModel *m_bookmarksModel; - QPersistentModelIndex m_root; -}; - -#endif // BOOKMARKS_H diff --git a/src/bookmarks/addbookmarkdialog.cpp b/src/bookmarks/addbookmarkdialog.cpp new file mode 100644 index 00000000..98f34107 --- /dev/null +++ b/src/bookmarks/addbookmarkdialog.cpp @@ -0,0 +1,213 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "addbookmarkdialog.h" + +#include "bookmarknode.h" +#include "bookmarksmanager.h" +#include "bookmarksmodel.h" +#include "browserapplication.h" + +#include +#include + +AddBookmarkProxyModel::AddBookmarkProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ +} + +int AddBookmarkProxyModel::columnCount(const QModelIndex &parent) const +{ + return qMin(1, QSortFilterProxyModel::columnCount(parent)); +} + +bool AddBookmarkProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const +{ + QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent); + return sourceModel()->hasChildren(idx); +} + +AddBookmarkDialog::AddBookmarkDialog(QWidget *parent, BookmarksManager *bookmarksManager) + : QDialog(parent) + , m_bookmarksManager(bookmarksManager) + , m_addedNode(0) + , m_proxyModel(0) + , m_addFolder(false) +{ + setWindowFlags(Qt::Sheet); + setupUi(this); + + if (!m_bookmarksManager) + m_bookmarksManager = BrowserApplication::bookmarksManager(); + + m_proxyModel = new AddBookmarkProxyModel(this); + BookmarksModel *model = m_bookmarksManager->bookmarksModel(); + m_proxyModel->setSourceModel(model); + + m_treeView = new QTreeView(this); + m_treeView->setModel(m_proxyModel); + m_treeView->expandAll(); + m_treeView->header()->setStretchLastSection(true); + m_treeView->header()->hide(); + m_treeView->setItemsExpandable(false); + m_treeView->setRootIsDecorated(false); + m_treeView->setIndentation(10); + m_treeView->show(); + + location->setModel(m_proxyModel); + location->setView(m_treeView); + + address->setInactiveText(tr("Url")); + name->setInactiveText(tr("Title")); + + resize(sizeHint()); +} + +void AddBookmarkDialog::setUrl(const QString &url) +{ + address->setText(url); + address->setVisible(url.isEmpty()); + resize(sizeHint()); +} + +QString AddBookmarkDialog::url() const +{ + return address->text(); +} + +void AddBookmarkDialog::setTitle(const QString &title) +{ + name->setText(title); +} + +QString AddBookmarkDialog::title() const +{ + return name->text(); +} + +void AddBookmarkDialog::setCurrentIndex(const QModelIndex &index) +{ + if (!index.isValid()) + return; + + QModelIndex proxyIndex = m_proxyModel->mapFromSource(index); + m_treeView->setCurrentIndex(proxyIndex); + location->setCurrentIndex(proxyIndex.row()); +} + +QModelIndex AddBookmarkDialog::currentIndex() const +{ + QModelIndex index = location->view()->currentIndex(); + index = m_proxyModel->mapToSource(index); + return index; +} + +void AddBookmarkDialog::setFolder(bool addFolder) +{ + m_addFolder = addFolder; + + if (addFolder) { + setWindowTitle(tr("Add Folder")); + address->setVisible(false); + } else { + setWindowTitle(tr("Add Bookmark")); + address->setVisible(true); + } + + resize(sizeHint()); +} + +bool AddBookmarkDialog::isFolder() const +{ + return m_addFolder; +} + +BookmarkNode *AddBookmarkDialog::addedNode() const +{ + return m_addedNode; +} + +void AddBookmarkDialog::accept() +{ + if ((!m_addFolder && address->text().isEmpty()) || name->text().isEmpty()) { + QDialog::accept(); + return; + } + + QModelIndex index = currentIndex(); + if (!index.isValid()) + index = m_bookmarksManager->bookmarksModel()->index(0, 0); + BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(index); + + BookmarkNode::Type type = (m_addFolder) ? BookmarkNode::Folder : BookmarkNode::Bookmark; + BookmarkNode *bookmark = new BookmarkNode(type); + bookmark->title = name->text(); + if (!m_addFolder) + bookmark->url = address->text(); + + m_bookmarksManager->addBookmark(parent, bookmark); + m_addedNode = bookmark; + + QDialog::accept(); +} + diff --git a/src/urllineedit.h b/src/bookmarks/addbookmarkdialog.h similarity index 67% rename from src/urllineedit.h rename to src/bookmarks/addbookmarkdialog.h index 4f31c24e..d57873f8 100644 --- a/src/urllineedit.h +++ b/src/bookmarks/addbookmarkdialog.h @@ -1,5 +1,6 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,76 +61,58 @@ ** ****************************************************************************/ -#ifndef URLLINEEDIT_H -#define URLLINEEDIT_H +#ifndef ADDBOOKMARKDIALOG_H +#define ADDBOOKMARKDIALOG_H -#include -#include -#include +#include "ui_addbookmarkdialog.h" -QT_BEGIN_NAMESPACE -class QLineEdit; -QT_END_NAMESPACE +#include -class ClearButton; -class ExLineEdit : public QWidget +class AddBookmarkProxyModel : public QSortFilterProxyModel { Q_OBJECT public: - ExLineEdit(QWidget *parent = 0); - - inline QLineEdit *lineEdit() const { return m_lineEdit; } - - void setLeftWidget(QWidget *widget); - QWidget *leftWidget() const; - - QSize sizeHint() const; + AddBookmarkProxyModel(QObject *parent = 0); + int columnCount(const QModelIndex &parent = QModelIndex()) const; protected: - void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); - void keyPressEvent(QKeyEvent *event); - void paintEvent(QPaintEvent *event); - void resizeEvent(QResizeEvent *event); - bool event(QEvent *event); - void clear(); - -protected: - void updateGeometries(); - void initStyleOption(QStyleOptionFrameV2 *option) const; - - QWidget *m_leftWidget; - QLineEdit *m_lineEdit; - ClearButton *m_clearButton; + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; }; -class UrlIconLabel; -class WebView; -class UrlLineEdit : public ExLineEdit +class BookmarkNode; +class BookmarksManager; +class QTreeView; +class AddBookmarkDialog : public QDialog, public Ui_AddBookmarkDialog { Q_OBJECT public: - UrlLineEdit(QWidget *parent = 0); - void setWebView(WebView *webView); + AddBookmarkDialog(QWidget *parent = 0, BookmarksManager *bookmarksManager = 0); -protected: - void paintEvent(QPaintEvent *event); - void focusOutEvent(QFocusEvent *event); + void setUrl(const QString &url); + QString url() const; -private slots: - void webViewUrlChanged(const QUrl &url); - void webViewIconChanged(); + void setTitle(const QString &title); + QString title() const; -private: - QLinearGradient generateGradient(const QColor &color) const; - WebView *m_webView; - UrlIconLabel *m_iconLabel; - QColor m_defaultBaseColor; + void setCurrentIndex(const QModelIndex &index); + QModelIndex currentIndex() const; -}; + void setFolder(bool addFolder); + bool isFolder() const; + BookmarkNode *addedNode() const; -#endif // URLLINEEDIT_H +private slots: + void accept(); + +private: + QTreeView *m_treeView; + BookmarksManager *m_bookmarksManager; + BookmarkNode *m_addedNode; + AddBookmarkProxyModel *m_proxyModel; + bool m_addFolder; +}; +#endif // ADDBOOKMARKDIALOG_H diff --git a/src/addbookmarkdialog.ui b/src/bookmarks/addbookmarkdialog.ui similarity index 56% rename from src/addbookmarkdialog.ui rename to src/bookmarks/addbookmarkdialog.ui index 3460d7bb..c454fd93 100644 --- a/src/addbookmarkdialog.ui +++ b/src/bookmarks/addbookmarkdialog.ui @@ -1,43 +1,47 @@ - + + AddBookmarkDialog - - + + 0 0 240 - 168 + 179 - + Add Bookmark - + - - + + Type a name for the bookmark, and choose where to keep it. - + Qt::PlainText - + true - + - + - - + + + + + Qt::Vertical - + 20 2 @@ -46,20 +50,27 @@ - - + + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok - + false + + + LineEdit + QLineEdit +
lineedit.h
+
+
@@ -68,11 +79,11 @@ AddBookmarkDialog accept() - + 248 254 - + 157 274 @@ -84,11 +95,11 @@ AddBookmarkDialog reject() - + 316 260 - + 286 274 diff --git a/src/edittreeview.cpp b/src/bookmarks/bookmarknode.cpp similarity index 61% rename from src/edittreeview.cpp rename to src/bookmarks/bookmarknode.cpp index 69cc1173..a05e2394 100644 --- a/src/edittreeview.cpp +++ b/src/bookmarks/bookmarknode.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2014 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ /**************************************************************************** ** -** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. ** ** This file is part of the demonstration applications of the Qt Toolkit. ** @@ -60,62 +60,83 @@ ** ****************************************************************************/ -#include "edittreeview.h" +#include "bookmarknode.h" -#include +BookmarkNode::BookmarkNode(BookmarkNode::Type type, BookmarkNode *parent) : + expanded(false) + , m_parent(parent) + , m_type(type) +{ + if (parent) + parent->add(this); +} -EditTreeView::EditTreeView(QWidget *parent) - : QTreeView(parent) +BookmarkNode::~BookmarkNode() { + if (m_parent) + m_parent->remove(this); + for (int i = m_children.count() -1; i >= 0; --i) + delete m_children[i]; + m_parent = 0; + m_type = BookmarkNode::Root; } -void EditTreeView::keyPressEvent(QKeyEvent *event) +bool BookmarkNode::operator==(const BookmarkNode &other) const { - if ((event->key() == Qt::Key_Delete - || event->key() == Qt::Key_Backspace) - && model()) { - removeSelected(); - } else { - QAbstractItemView::keyPressEvent(event); - } + if (url != other.url + || title != other.title + || desc != other.desc + || expanded != other.expanded + || m_type != other.m_type + || m_children.count() != other.m_children.count()) + return false; + + for (int i = 0; i < m_children.count(); ++i) + if (!((*(m_children[i])) == (*(other.m_children[i])))) + return false; + return true; } -void EditTreeView::removeSelected() +BookmarkNode::Type BookmarkNode::type() const { - if (!model() || !selectionModel()) - return; + return m_type; +} - QModelIndexList selectedRows = selectionModel()->selectedRows(); - QModelIndex first = selectedRows.value(0); - // get parent before removing first - QModelIndex firstParent = first.parent(); - for (int i = selectedRows.count() - 1; i >= 0; --i) { - QModelIndex idx = selectedRows.at(i); - model()->removeRow(idx.row(), idx.parent()); - } - // select the item at the same position - QModelIndex idx = model()->index(first.row(), 0, firstParent); - // if that was the last item - if (!idx.isValid()) { - int parentRows = model()->rowCount(firstParent); - if (parentRows == 0) { - // removed the only item, goto parent - idx = firstParent; - } else { - // removed the last item, goto new last item - idx = model()->index(parentRows - 1, 0, firstParent); - } - } - if (!idx.isValid()) - idx = model()->index(0, 0, rootIndex()); - selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); - setCurrentIndex(idx); +void BookmarkNode::setType(Type type) +{ + m_type = type; +} + +QList BookmarkNode::children() const +{ + return m_children; +} + +BookmarkNode *BookmarkNode::parent() const +{ + return m_parent; +} + +void BookmarkNode::add(BookmarkNode *child, int offset) +{ + if (!child) + return; + if (m_type == BookmarkNode::Bookmark) + return; + Q_ASSERT(child->m_type != Root); + if (child->m_parent) + child->m_parent->remove(child); + child->m_parent = this; + if (-1 == offset) + offset = m_children.size(); + m_children.insert(offset, child); } -void EditTreeView::removeAll() +void BookmarkNode::remove(BookmarkNode *child) { - if (!model()) + if (!child) return; - model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); + child->m_parent = 0; + m_children.removeAll(child); } diff --git a/src/bookmarks/bookmarknode.h b/src/bookmarks/bookmarknode.h new file mode 100644 index 00000000..69c05d20 --- /dev/null +++ b/src/bookmarks/bookmarknode.h @@ -0,0 +1,103 @@ +/* + * Copyright 2008-2014 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef BOOKMARKNODE_H +#define BOOKMARKNODE_H + +#include +#include + +class BookmarkNode +{ +public: + enum Type { + Root, + Folder, + Bookmark, + Separator + }; + + BookmarkNode(Type type = Root, BookmarkNode *parent = 0); + ~BookmarkNode(); + bool operator==(const BookmarkNode &other) const; + + Type type() const; + void setType(Type type); + QList children() const; + BookmarkNode *parent() const; + + void add(BookmarkNode *child, int offset = -1); + void remove(BookmarkNode *child); + + QString url; + QString title; + QString desc; + bool expanded; + +private: + BookmarkNode *m_parent; + Type m_type; + QList m_children; + +}; + +#endif // BOOKMARKNODE_H diff --git a/src/bookmarks/bookmarks.pri b/src/bookmarks/bookmarks.pri new file mode 100644 index 00000000..ee03defd --- /dev/null +++ b/src/bookmarks/bookmarks.pri @@ -0,0 +1,26 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + addbookmarkdialog.h \ + bookmarksdialog.h \ + bookmarksmanager.h \ + bookmarksmenu.h \ + bookmarksmodel.h \ + bookmarkstoolbar.h \ + bookmarknode.h + +SOURCES += \ + addbookmarkdialog.cpp \ + bookmarksdialog.cpp \ + bookmarksmanager.cpp \ + bookmarksmenu.cpp \ + bookmarksmodel.cpp \ + bookmarkstoolbar.cpp \ + bookmarknode.cpp + +FORMS += \ + addbookmarkdialog.ui \ + bookmarksdialog.ui + +include(xbel/xbel.pri) diff --git a/src/bookmarks/bookmarksdialog.cpp b/src/bookmarks/bookmarksdialog.cpp new file mode 100644 index 00000000..8ec09ca7 --- /dev/null +++ b/src/bookmarks/bookmarksdialog.cpp @@ -0,0 +1,241 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "bookmarksdialog.h" + +#include "bookmarknode.h" +#include "bookmarksmanager.h" +#include "bookmarksmodel.h" +#include "browserapplication.h" +#include "treesortfilterproxymodel.h" + +#include +#include + +BookmarksDialog::BookmarksDialog(QWidget *parent, BookmarksManager *manager) + : QDialog(parent) + , m_bookmarksManager(0) + , m_bookmarksModel(0) + , m_proxyModel(0) +{ + m_bookmarksManager = manager; + if (!m_bookmarksManager) + m_bookmarksManager = BrowserApplication::bookmarksManager(); + setupUi(this); + + tree->setUniformRowHeights(true); + tree->setSelectionBehavior(QAbstractItemView::SelectRows); + tree->setSelectionMode(QAbstractItemView::ExtendedSelection); + tree->setTextElideMode(Qt::ElideMiddle); + m_bookmarksModel = m_bookmarksManager->bookmarksModel(); + m_proxyModel = new TreeSortFilterProxyModel(this); + m_proxyModel->setFilterKeyColumn(-1); + connect(search, SIGNAL(textChanged(QString)), + m_proxyModel, SLOT(setFilterFixedString(QString))); + connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeSelected())); + m_proxyModel->setSourceModel(m_bookmarksModel); + tree->setModel(m_proxyModel); + tree->setDragDropMode(QAbstractItemView::InternalMove); + tree->setExpanded(m_proxyModel->index(0, 0), true); + tree->setAlternatingRowColors(true); + QFontMetrics fm(font()); + int header = fm.width(QLatin1Char('m')) * 40; + tree->header()->resizeSection(0, header); + tree->header()->setStretchLastSection(true); + connect(tree, SIGNAL(activated(const QModelIndex&)), + this, SLOT(openBookmark())); + tree->setContextMenuPolicy(Qt::CustomContextMenu); + connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(customContextMenuRequested(const QPoint &))); + connect(addFolderButton, SIGNAL(clicked()), + this, SLOT(newFolder())); + expandNodes(m_bookmarksManager->bookmarks()); +} + +BookmarksDialog::~BookmarksDialog() +{ + if (saveExpandedNodes(tree->rootIndex())) + m_bookmarksManager->changeExpanded(); +} + +bool BookmarksDialog::saveExpandedNodes(const QModelIndex &parent) +{ + bool changed = false; + for (int i = 0; i < m_proxyModel->rowCount(parent); ++i) { + QModelIndex child = m_proxyModel->index(i, 0, parent); + QModelIndex sourceIndex = m_proxyModel->mapToSource(child); + BookmarkNode *childNode = m_bookmarksModel->node(sourceIndex); + bool wasExpanded = childNode->expanded; + if (tree->isExpanded(child)) { + childNode->expanded = true; + changed |= saveExpandedNodes(child); + } else { + childNode->expanded = false; + } + changed |= (wasExpanded != childNode->expanded); + } + return changed; +} + +void BookmarksDialog::expandNodes(BookmarkNode *node) +{ + for (int i = 0; i < node->children().count(); ++i) { + BookmarkNode *childNode = node->children()[i]; + if (childNode->expanded) { + QModelIndex idx = m_bookmarksModel->index(childNode); + idx = m_proxyModel->mapFromSource(idx); + tree->setExpanded(idx, true); + expandNodes(childNode); + } + } +} + +void BookmarksDialog::customContextMenuRequested(const QPoint &pos) +{ + QMenu menu; + QModelIndex index = tree->indexAt(pos); + index = index.sibling(index.row(), 0); + QModelIndex sourceIndex = m_proxyModel->mapToSource(index); + const BookmarkNode *node = m_bookmarksModel->node(sourceIndex); + if (index.isValid() && node->type() != BookmarkNode::Folder) { + menu.addAction(tr("Open"), this, SLOT(openInCurrentTab())); + menu.addAction(tr("Open in New Tab"), this, SLOT(openInNewTab())); + menu.addSeparator(); + } + menu.addSeparator(); + QAction *renameAction = menu.addAction(tr("Edit Name"), this, SLOT(editName())); + renameAction->setEnabled(index.flags() & Qt::ItemIsEditable); + if (index.isValid() && node->type() != BookmarkNode::Folder) { + menu.addAction(tr("Edit Address"), this, SLOT(editAddress())); + } + menu.addSeparator(); + QAction *deleteAction = menu.addAction(tr("Delete"), tree, SLOT(removeSelected())); + deleteAction->setEnabled(index.flags() & Qt::ItemIsDragEnabled); + menu.exec(QCursor::pos()); +} + +void BookmarksDialog::openBookmark(TabWidget::OpenUrlIn tab) +{ + QModelIndex index = tree->currentIndex(); + QModelIndex sourceIndex = m_proxyModel->mapToSource(index); + const BookmarkNode *node = m_bookmarksModel->node(sourceIndex); + if (!index.parent().isValid() || !node || node->type() == BookmarkNode::Folder) + return; + emit openUrl( + index.sibling(index.row(), 1).data(BookmarksModel::UrlRole).toUrl(), + tab, + index.sibling(index.row(), 0).data(Qt::DisplayRole).toString()); +} + +void BookmarksDialog::openBookmark() +{ + BrowserApplication::instance()->setEventMouseButtons(qApp->mouseButtons()); + BrowserApplication::instance()->setEventKeyboardModifiers(qApp->keyboardModifiers()); + openBookmark(TabWidget::UserOrCurrent); +} + +void BookmarksDialog::openInCurrentTab() +{ + openBookmark(TabWidget::CurrentTab); +} + +void BookmarksDialog::openInNewTab() +{ + openBookmark(TabWidget::NewTab); +} + +void BookmarksDialog::editName() +{ + QModelIndex idx = tree->currentIndex(); + idx = idx.sibling(idx.row(), 0); + tree->edit(idx); +} + +void BookmarksDialog::editAddress() +{ + QModelIndex idx = tree->currentIndex(); + idx = idx.sibling(idx.row(), 1); + tree->edit(idx); +} + +void BookmarksDialog::newFolder() +{ + QModelIndex currentIndex = tree->currentIndex(); + QModelIndex idx = currentIndex; + QModelIndex sourceIndex = m_proxyModel->mapToSource(idx); + const BookmarkNode *sourceNode = m_bookmarksModel->node(sourceIndex); + int row = -1; // default: append new folder as last item in selected folder + if (sourceNode && sourceNode->type() != BookmarkNode::Folder) { + // if selected item is not a folder, add new folder to parent folder, + // but direcly below the selected item + idx = idx.parent(); + row = currentIndex.row() + 1; + } + if (!idx.isValid()) + idx = m_proxyModel->index(1, 0); // Select Bookmarks menu as default + idx = m_proxyModel->mapToSource(idx); + BookmarkNode *parent = m_bookmarksManager->bookmarksModel()->node(idx); + BookmarkNode *node = new BookmarkNode(BookmarkNode::Folder); + node->title = tr("New Folder"); + m_bookmarksManager->addBookmark(parent, node, row); +} + diff --git a/src/bookmarks/bookmarksdialog.h b/src/bookmarks/bookmarksdialog.h new file mode 100644 index 00000000..78fe83ae --- /dev/null +++ b/src/bookmarks/bookmarksdialog.h @@ -0,0 +1,108 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef BOOKMARKSDIALOG_H +#define BOOKMARKSDIALOG_H + +#include +#include "ui_bookmarksdialog.h" + +#include "tabwidget.h" + +#include +#include + +class TreeSortFilterProxyModel; +class BookmarksManager; +class BookmarksModel; +class BookmarkNode; +class BookmarksDialog : public QDialog, public Ui_BookmarksDialog +{ + Q_OBJECT + +signals: + void openUrl(const QUrl &url, TabWidget::OpenUrlIn tab, const QString &title); + +public: + BookmarksDialog(QWidget *parent = 0, BookmarksManager *manager = 0); + ~BookmarksDialog(); + +private slots: + void customContextMenuRequested(const QPoint &pos); + void openBookmark(TabWidget::OpenUrlIn tab); + void openBookmark(); + void openInNewTab(); + void openInCurrentTab(); + void editName(); + void editAddress(); + void newFolder(); + +private: + void expandNodes(BookmarkNode *node); + bool saveExpandedNodes(const QModelIndex &parent); + + BookmarksManager *m_bookmarksManager; + BookmarksModel *m_bookmarksModel; + TreeSortFilterProxyModel *m_proxyModel; +}; + +#endif // BOOKMARKSDIALOG_H diff --git a/src/bookmarks.ui b/src/bookmarks/bookmarksdialog.ui similarity index 96% rename from src/bookmarks.ui rename to src/bookmarks/bookmarksdialog.ui index c893e941..080a979e 100644 --- a/src/bookmarks.ui +++ b/src/bookmarks/bookmarksdialog.ui @@ -64,7 +64,7 @@ - QDialogButtonBox::Ok + QDialogButtonBox::Close @@ -88,9 +88,9 @@ buttonBox - accepted() + rejected() BookmarksDialog - accept() + close() 472 diff --git a/src/bookmarks/bookmarksmanager.cpp b/src/bookmarks/bookmarksmanager.cpp new file mode 100644 index 00000000..8db5abfc --- /dev/null +++ b/src/bookmarks/bookmarksmanager.cpp @@ -0,0 +1,413 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "bookmarksmanager.h" + +#include "autosaver.h" +#include "bookmarknode.h" +#include "bookmarksmodel.h" +#include "browserapplication.h" +#include "history.h" +#include "xbelreader.h" +#include "xbelwriter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define BOOKMARKBAR QT_TRANSLATE_NOOP("BookmarksManager", "Bookmarks Bar") +#define BOOKMARKMENU QT_TRANSLATE_NOOP("BookmarksManager", "Bookmarks Menu") + +BookmarksManager::BookmarksManager(QObject *parent) + : QObject(parent) + , m_loaded(false) + , m_saveTimer(new AutoSaver(this)) + , m_bookmarkRootNode(0) + , m_toolbar(0) + , m_menu(0) + , m_bookmarkModel(0) +{ + connect(this, SIGNAL(entryAdded(BookmarkNode *)), + m_saveTimer, SLOT(changeOccurred())); + connect(this, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), + m_saveTimer, SLOT(changeOccurred())); + connect(this, SIGNAL(entryChanged(BookmarkNode *)), + m_saveTimer, SLOT(changeOccurred())); +} + +BookmarksManager::~BookmarksManager() +{ + m_saveTimer->saveIfNeccessary(); + delete m_bookmarkRootNode; +} + +void BookmarksManager::changeExpanded() +{ + m_saveTimer->changeOccurred(); +} + +void BookmarksManager::load() +{ + if (m_loaded) + return; + m_loaded = true; + + QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); + if (!QFile::exists(bookmarkFile)) + bookmarkFile = QLatin1String(":defaultbookmarks.xbel"); + + XbelReader reader; + m_bookmarkRootNode = reader.read(bookmarkFile); + if (reader.error() != QXmlStreamReader::NoError) { + QMessageBox::warning(0, QLatin1String("Loading Bookmark"), + tr("Error when loading bookmarks on line %1, column %2:\n" + "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); + } + + QList others; + for (int i = m_bookmarkRootNode->children().count() - 1; i >= 0; --i) { + BookmarkNode *node = m_bookmarkRootNode->children().at(i); + if (node->type() == BookmarkNode::Folder) { + // Automatically convert + if ((node->title == tr("Toolbar Bookmarks") + || node->title == QLatin1String(BOOKMARKBAR)) && !m_toolbar) { + node->title = tr(BOOKMARKBAR); + + m_toolbar = node; + } + + // Automatically convert + if ((node->title == tr("Menu") + || node->title == QLatin1String(BOOKMARKMENU)) && !m_menu) { + node->title = tr(BOOKMARKMENU); + m_menu = node; + } + } else { + others.append(node); + } + m_bookmarkRootNode->remove(node); + } + Q_ASSERT(m_bookmarkRootNode->children().count() == 0); + if (!m_toolbar) { + m_toolbar = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); + m_toolbar->title = tr(BOOKMARKBAR); + } else { + m_bookmarkRootNode->add(m_toolbar); + } + + if (!m_menu) { + m_menu = new BookmarkNode(BookmarkNode::Folder, m_bookmarkRootNode); + m_menu->title = tr(BOOKMARKMENU); + } else { + m_bookmarkRootNode->add(m_menu); + } + + for (int i = 0; i < others.count(); ++i) + m_menu->add(others.at(i)); +} + +void BookmarksManager::save() const +{ + if (!m_loaded) + return; + + XbelWriter writer; + QString dir = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + QString bookmarkFile = dir + QLatin1String("/bookmarks.xbel"); + // Save root folder titles in English (i.e. not localized) + m_menu->title = QLatin1String(BOOKMARKMENU); + m_toolbar->title = QLatin1String(BOOKMARKBAR); + if (!writer.write(bookmarkFile, m_bookmarkRootNode)) + qWarning() << "BookmarkManager: error saving to" << bookmarkFile; + // Restore localized titles + retranslate(); +} + +void BookmarksManager::retranslate() const +{ + if (m_menu) + m_menu->title = tr(BOOKMARKMENU); + if (m_toolbar) + m_toolbar->title = tr(BOOKMARKBAR); +} + +void BookmarksManager::addBookmark(BookmarkNode *parent, BookmarkNode *node, int row) +{ + if (!m_loaded) + return; + Q_ASSERT(parent); + InsertBookmarksCommand *command = new InsertBookmarksCommand(this, parent, node, row); + m_commands.push(command); +} + +void BookmarksManager::removeBookmark(BookmarkNode *node) +{ + if (!m_loaded) + return; + + Q_ASSERT(node); + BookmarkNode *parent = node->parent(); + int row = parent->children().indexOf(node); + RemoveBookmarksCommand *command = new RemoveBookmarksCommand(this, parent, row); + m_commands.push(command); +} + +void BookmarksManager::setTitle(BookmarkNode *node, const QString &newTitle) +{ + if (!m_loaded) + return; + + Q_ASSERT(node); + ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newTitle, true); + m_commands.push(command); +} + +void BookmarksManager::setUrl(BookmarkNode *node, const QString &newUrl) +{ + if (!m_loaded) + return; + + Q_ASSERT(node); + ChangeBookmarkCommand *command = new ChangeBookmarkCommand(this, node, newUrl, false); + m_commands.push(command); +} + +BookmarkNode *BookmarksManager::bookmarks() +{ + if (!m_loaded) + load(); + return m_bookmarkRootNode; +} + +BookmarkNode *BookmarksManager::menu() +{ + if (!m_loaded) + load(); + + Q_ASSERT(m_menu); + return m_menu; +} + +BookmarkNode *BookmarksManager::toolbar() +{ + if (!m_loaded) + load(); + + Q_ASSERT(m_toolbar); + return m_toolbar; +} + +BookmarksModel *BookmarksManager::bookmarksModel() +{ + if (!m_bookmarkModel) + m_bookmarkModel = new BookmarksModel(this, this); + return m_bookmarkModel; +} + +void BookmarksManager::importBookmarks() +{ + QStringList supportedFormats; + supportedFormats << tr("XBEL bookmarks").append(QLatin1String("(*.xbel *.xml)")); + supportedFormats << tr("HTML Netscape bookmarks").append(QLatin1String("(*.html)")); + + QString fileName = QFileDialog::getOpenFileName(0, tr("Open File"), + QString(), supportedFormats.join(QLatin1String(";;"))); + if (fileName.isEmpty()) + return; + + XbelReader reader; + BookmarkNode *importRootNode = 0; + if (fileName.endsWith(QLatin1String(".html"))) { + QString program = QLatin1String("htmlToXBel"); + QStringList arguments; + arguments << fileName; + QProcess process; + process.start(program, arguments); + process.waitForFinished(-1); + if (process.error() != QProcess::UnknownError) { + if (process.error() == QProcess::FailedToStart) { + QMessageBox::warning(0, tr("htmlToXBel tool required"), + tr("htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, " + "is not installed or not available in the search paths.")); + } else { + QMessageBox::warning(0, tr("Loading Bookmark"), + tr("Error when loading HTML bookmarks: %1\n").arg(process.errorString())); + } + return; + } + importRootNode = reader.read(&process); + } else { + importRootNode = reader.read(fileName); + } + if (reader.error() != QXmlStreamReader::NoError) { + QMessageBox::warning(0, QLatin1String("Loading Bookmark"), + tr("Error when loading bookmarks on line %1, column %2:\n" + "%3").arg(reader.lineNumber()).arg(reader.columnNumber()).arg(reader.errorString())); + delete importRootNode; + return; + } + + importRootNode->setType(BookmarkNode::Folder); + importRootNode->title = (tr("Imported %1").arg(QDate::currentDate().toString(Qt::SystemLocaleShortDate))); + addBookmark(menu(), importRootNode); +} + +void BookmarksManager::exportBookmarks() +{ + QString fileName = QFileDialog::getSaveFileName(0, tr("Save File"), + tr("%1 Bookmarks.xbel").arg(QCoreApplication::applicationName()), + tr("XBEL bookmarks").append(QLatin1String("(*.xbel *.xml)"))); + if (fileName.isEmpty()) + return; + + XbelWriter writer; + if (!writer.write(fileName, m_bookmarkRootNode)) + QMessageBox::critical(0, tr("Export error"), tr("error saving bookmarks")); +} + +RemoveBookmarksCommand::RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row) + : QUndoCommand(BookmarksManager::tr("Remove Bookmark")) + , m_row(row) + , m_bookmarkManagaer(m_bookmarkManagaer) + , m_node(parent->children().value(row)) + , m_parent(parent) + , m_done(false) +{ +} + +RemoveBookmarksCommand::~RemoveBookmarksCommand() +{ + if (m_done && !m_node->parent()) { + delete m_node; + } +} + +void RemoveBookmarksCommand::undo() +{ + m_parent->add(m_node, m_row); + emit m_bookmarkManagaer->entryAdded(m_node); + m_done = false; +} + +void RemoveBookmarksCommand::redo() +{ + m_parent->remove(m_node); + emit m_bookmarkManagaer->entryRemoved(m_parent, m_row, m_node); + m_done = true; +} + +InsertBookmarksCommand::InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, + BookmarkNode *parent, BookmarkNode *node, int row) + : RemoveBookmarksCommand(m_bookmarkManagaer, parent, row) +{ + setText(BookmarksManager::tr("Insert Bookmark")); + m_node = node; +} + +ChangeBookmarkCommand::ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *node, + const QString &newValue, bool title) + : QUndoCommand() + , m_bookmarkManagaer(m_bookmarkManagaer) + , m_title(title) + , m_newValue(newValue) + , m_node(node) +{ + if (m_title) { + m_oldValue = m_node->title; + setText(BookmarksManager::tr("Name Change", "Undo bookmark title change")); + } else { + m_oldValue = m_node->url; + setText(BookmarksManager::tr("Address Change", "Undo bookmark url change")); + } +} + +void ChangeBookmarkCommand::undo() +{ + if (m_title) + m_node->title = m_oldValue; + else + m_node->url = m_oldValue; + emit m_bookmarkManagaer->entryChanged(m_node); +} + +void ChangeBookmarkCommand::redo() +{ + if (m_title) + m_node->title = m_newValue; + else + m_node->url = m_newValue; + emit m_bookmarkManagaer->entryChanged(m_node); +} + diff --git a/src/bookmarks/bookmarksmanager.h b/src/bookmarks/bookmarksmanager.h new file mode 100644 index 00000000..b89a75e4 --- /dev/null +++ b/src/bookmarks/bookmarksmanager.h @@ -0,0 +1,132 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef BOOKMARKSMANAGER_H +#define BOOKMARKSMANAGER_H + +#include + +#include + +#include "tabwidget.h" + +class AutoSaver; +class BookmarkNode; +class BookmarksModel; +class BookmarksManager : public QObject +{ + Q_OBJECT + +signals: + void entryAdded(BookmarkNode *item); + void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); + void entryChanged(BookmarkNode *item); + +public: + BookmarksManager(QObject *parent = 0); + ~BookmarksManager(); + + void addBookmark(BookmarkNode *parent, BookmarkNode *node, int row = -1); + void removeBookmark(BookmarkNode *node); + void setTitle(BookmarkNode *node, const QString &newTitle); + void setUrl(BookmarkNode *node, const QString &newUrl); + void changeExpanded(); + void retranslate() const; + + BookmarkNode *bookmarks(); + BookmarkNode *menu(); + BookmarkNode *toolbar(); + + BookmarksModel *bookmarksModel(); + QUndoStack *undoRedoStack() { + return &m_commands; + } + +public slots: + void importBookmarks(); + void exportBookmarks(); + +private slots: + void save() const; + +private: + void load(); + + bool m_loaded; + AutoSaver *m_saveTimer; + BookmarkNode *m_bookmarkRootNode; + BookmarkNode *m_toolbar; + BookmarkNode *m_menu; + BookmarksModel *m_bookmarkModel; + QUndoStack m_commands; + + friend class RemoveBookmarksCommand; + friend class ChangeBookmarkCommand; +}; + +class RemoveBookmarksCommand : public QUndoCommand +{ + +public: + RemoveBookmarksCommand(BookmarksManager *m_bookmarkManagaer, BookmarkNode *parent, int row); + ~RemoveBookmarksCommand(); + void undo(); + void redo(); + +protected: + int m_row; + BookmarksManager *m_bookmarkManagaer; + BookmarkNode *m_node; + BookmarkNode *m_parent; + bool m_done; +}; + +class InsertBookmarksCommand : public RemoveBookmarksCommand +{ + +public: + InsertBookmarksCommand(BookmarksManager *m_bookmarkManagaer, + BookmarkNode *parent, BookmarkNode *node, int row); + void undo() { + RemoveBookmarksCommand::redo(); + } + void redo() { + RemoveBookmarksCommand::undo(); + } + +}; + +class ChangeBookmarkCommand : public QUndoCommand +{ + +public: + ChangeBookmarkCommand(BookmarksManager *m_bookmarkManagaer, + BookmarkNode *node, const QString &newValue, bool title); + void undo(); + void redo(); + +private: + BookmarksManager *m_bookmarkManagaer; + bool m_title; + QString m_oldValue; + QString m_newValue; + BookmarkNode *m_node; +}; + +#endif // BOOKMARKSMANAGER_H diff --git a/src/bookmarks/bookmarksmenu.cpp b/src/bookmarks/bookmarksmenu.cpp new file mode 100644 index 00000000..56b8877a --- /dev/null +++ b/src/bookmarks/bookmarksmenu.cpp @@ -0,0 +1,167 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "bookmarksmenu.h" + +#include "bookmarknode.h" +#include "bookmarksmanager.h" +#include "bookmarksmodel.h" +#include "browserapplication.h" + +BookmarksMenu::BookmarksMenu(QWidget *parent) + : ModelMenu(parent) +{ + connect(this, SIGNAL(activated(const QModelIndex &)), + this, SLOT(activated(const QModelIndex &))); + setStatusBarTextRole(BookmarksModel::UrlStringRole); + setSeparatorRole(BookmarksModel::SeparatorRole); +} + +ModelMenu *BookmarksMenu::createBaseMenu() +{ + BookmarksMenu *menu = new BookmarksMenu(this); + connect(menu, SIGNAL(openUrl(const QUrl&, TabWidget::OpenUrlIn, const QString&)), + this, SIGNAL(openUrl(const QUrl&, TabWidget::OpenUrlIn, const QString&))); + return menu; +} + +void BookmarksMenu::activated(const QModelIndex &index) +{ + emit openUrl(index.data(BookmarksModel::UrlRole).toUrl(), + index.data(Qt::DisplayRole).toString()); +} + +void BookmarksMenu::postPopulated() +{ + if (isEmpty()) + return; + + QModelIndex parent = rootIndex(); + + bool hasBookmarks = false; + + for (int i = 0; i < parent.model()->rowCount(parent); ++i) { + QModelIndex child = parent.model()->index(i, 0, parent); + + if (child.data(BookmarksModel::TypeRole) == BookmarkNode::Bookmark) { + hasBookmarks = true; + break; + } + } + + if (!hasBookmarks) + return; + + addSeparator(); + QAction *action = addAction(tr("Open in Tabs")); + connect(action, SIGNAL(triggered()), + this, SLOT(openAll())); +} + +void BookmarksMenu::openAll() +{ + ModelMenu *menu = qobject_cast(sender()->parent()); + if (!menu) + return; + QModelIndex parent = menu->rootIndex(); + if (!parent.isValid()) + return; + for (int i = 0; i < parent.model()->rowCount(parent); ++i) { + QModelIndex child = parent.model()->index(i, 0, parent); + + if (child.data(BookmarksModel::TypeRole) != BookmarkNode::Bookmark) + continue; + + TabWidget::OpenUrlIn tab; + tab = (i == 0) ? TabWidget::CurrentTab : TabWidget::NewTab; + emit openUrl(child.data(BookmarksModel::UrlRole).toUrl(), + tab, + child.data(Qt::DisplayRole).toString()); + } +} + +BookmarksMenuBarMenu::BookmarksMenuBarMenu(QWidget *parent) + : BookmarksMenu(parent) + , m_bookmarksManager(0) +{ +} + +bool BookmarksMenuBarMenu::prePopulated() +{ + m_bookmarksManager = BrowserApplication::bookmarksManager(); + setModel(m_bookmarksManager->bookmarksModel()); + setRootIndex(m_bookmarksManager->bookmarksModel()->index(m_bookmarksManager->menu())); + // initial actions + for (int i = 0; i < m_initialActions.count(); ++i) + addAction(m_initialActions.at(i)); + if (!m_initialActions.isEmpty()) + addSeparator(); + createMenu(m_bookmarksManager->bookmarksModel()->index(m_bookmarksManager->toolbar()), 1, this); + return true; +} + +void BookmarksMenuBarMenu::setInitialActions(QList actions) +{ + m_initialActions = actions; + for (int i = 0; i < m_initialActions.count(); ++i) + addAction(m_initialActions.at(i)); +} diff --git a/src/bookmarks/bookmarksmenu.h b/src/bookmarks/bookmarksmenu.h new file mode 100644 index 00000000..cdff8721 --- /dev/null +++ b/src/bookmarks/bookmarksmenu.h @@ -0,0 +1,114 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef BOOKMARKSMENU_H +#define BOOKMARKSMENU_H + +#include "modelmenu.h" + +#include "tabwidget.h" + +#include +#include + +class BookmarksManager; + +// Base class for BookmarksMenuBarMenu and BookmarksToolBarMenu +class BookmarksMenu : public ModelMenu +{ + Q_OBJECT + +signals: + void openUrl(const QUrl &url, const QString &title); + void openUrl(const QUrl &url, TabWidget::OpenUrlIn tab, const QString &title); + +public: + BookmarksMenu(QWidget *parent = 0); + +protected: + void postPopulated(); + ModelMenu *createBaseMenu(); + +private slots: + void openAll(); + void activated(const QModelIndex &index); + +}; + +// Menu that is dynamically populated from the bookmarks +class BookmarksMenuBarMenu : public BookmarksMenu +{ + Q_OBJECT + +public: + BookmarksMenuBarMenu(QWidget *parent = 0); + void setInitialActions(QList actions); + +protected: + bool prePopulated(); + +private: + BookmarksManager *m_bookmarksManager; + QList m_initialActions; +}; + +#endif // BOOKMARKSMENU_H diff --git a/src/bookmarks/bookmarksmodel.cpp b/src/bookmarks/bookmarksmodel.cpp new file mode 100644 index 00000000..b6f28693 --- /dev/null +++ b/src/bookmarks/bookmarksmodel.cpp @@ -0,0 +1,410 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "bookmarksmodel.h" + +#include "addbookmarkdialog.h" +#include "bookmarknode.h" +#include "bookmarksmanager.h" +#include "browserapplication.h" +#include "xbelreader.h" +#include "xbelwriter.h" + +#include +#include + +BookmarksModel::BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent) + : QAbstractItemModel(parent) + , m_endMacro(false) + , m_bookmarksManager(bookmarkManager) +{ + connect(bookmarkManager, SIGNAL(entryAdded(BookmarkNode *)), + this, SLOT(entryAdded(BookmarkNode *))); + connect(bookmarkManager, SIGNAL(entryRemoved(BookmarkNode *, int, BookmarkNode *)), + this, SLOT(entryRemoved(BookmarkNode *, int, BookmarkNode *))); + connect(bookmarkManager, SIGNAL(entryChanged(BookmarkNode *)), + this, SLOT(entryChanged(BookmarkNode *))); +} + +QModelIndex BookmarksModel::index(BookmarkNode *node) const +{ + BookmarkNode *parent = node->parent(); + if (!parent) + return QModelIndex(); + return createIndex(parent->children().indexOf(node), 0, node); +} + +void BookmarksModel::entryAdded(BookmarkNode *item) +{ + Q_ASSERT(item && item->parent()); + int row = item->parent()->children().indexOf(item); + BookmarkNode *parent = item->parent(); + // item was already added so remove beore beginInsertRows is called + parent->remove(item); + beginInsertRows(index(parent), row, row); + parent->add(item, row); + endInsertRows(); +} + +void BookmarksModel::entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item) +{ + // item was already removed, re-add so beginRemoveRows works + parent->add(item, row); + beginRemoveRows(index(parent), row, row); + parent->remove(item); + endRemoveRows(); +} + +void BookmarksModel::entryChanged(BookmarkNode *item) +{ + QModelIndex idx = index(item); + emit dataChanged(idx, idx); +} + +bool BookmarksModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (row < 0 || count <= 0 || row + count > rowCount(parent)) + return false; + + BookmarkNode *bookmarkNode = node(parent); + for (int i = row + count - 1; i >= row; --i) { + BookmarkNode *node = bookmarkNode->children().at(i); + if (node == m_bookmarksManager->menu() + || node == m_bookmarksManager->toolbar()) + continue; + + m_bookmarksManager->removeBookmark(node); + } + if (m_endMacro) { + m_bookmarksManager->undoRedoStack()->endMacro(); + m_endMacro = false; + } + return true; +} + +QVariant BookmarksModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + switch (section) { + case 0: return tr("Title"); + case 1: return tr("Address"); + } + } + return QAbstractItemModel::headerData(section, orientation, role); +} + +QVariant BookmarksModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.model() != this) + return QVariant(); + + const BookmarkNode *bookmarkNode = node(index); + switch (role) { + case Qt::EditRole: + case Qt::DisplayRole: + if (bookmarkNode->type() == BookmarkNode::Separator) { + switch (index.column()) { + case 0: return QString(50, 0xB7); + case 1: return QString(); + } + } + + switch (index.column()) { + case 0: return bookmarkNode->title; + case 1: return bookmarkNode->url; + } + break; + case BookmarksModel::UrlRole: + return QUrl(bookmarkNode->url); + break; + case BookmarksModel::UrlStringRole: + return bookmarkNode->url; + break; + case BookmarksModel::TypeRole: + return bookmarkNode->type(); + break; + case BookmarksModel::SeparatorRole: + return (bookmarkNode->type() == BookmarkNode::Separator); + break; + case Qt::DecorationRole: + if (index.column() == 0) { + if (bookmarkNode->type() == BookmarkNode::Folder) + return QApplication::style()->standardIcon(QStyle::SP_DirIcon); + return BrowserApplication::instance()->icon(bookmarkNode->url); + } + } + + return QVariant(); +} + +int BookmarksModel::columnCount(const QModelIndex &parent) const +{ + return (parent.column() > 0) ? 0 : 2; +} + +int BookmarksModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + return m_bookmarksManager->bookmarks()->children().count(); + + const BookmarkNode *item = static_cast(parent.internalPointer()); + return item->children().count(); +} + +QModelIndex BookmarksModel::index(int row, int column, const QModelIndex &parent) const +{ + if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) + return QModelIndex(); + + // get the parent node + BookmarkNode *parentNode = node(parent); + return createIndex(row, column, parentNode->children().at(row)); +} + +QModelIndex BookmarksModel::parent(const QModelIndex &index) const +{ + if (!index.isValid()) + return QModelIndex(); + + BookmarkNode *itemNode = node(index); + BookmarkNode *parentNode = (itemNode ? itemNode->parent() : 0); + if (!parentNode || parentNode == m_bookmarksManager->bookmarks()) + return QModelIndex(); + + // get the parent's row + BookmarkNode *grandParentNode = parentNode->parent(); + int parentRow = grandParentNode->children().indexOf(parentNode); + Q_ASSERT(parentRow >= 0); + return createIndex(parentRow, 0, parentNode); +} + +bool BookmarksModel::hasChildren(const QModelIndex &parent) const +{ + if (!parent.isValid()) + return true; + const BookmarkNode *parentNode = node(parent); + return (parentNode->type() == BookmarkNode::Folder); +} + +Qt::ItemFlags BookmarksModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + + BookmarkNode *node = this->node(index); + BookmarkNode::Type type = node->type(); + Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; + + if (hasChildren(index)) + flags |= Qt::ItemIsDropEnabled; + + if (node == m_bookmarksManager->menu() + || node == m_bookmarksManager->toolbar()) + return flags; + + flags |= Qt::ItemIsDragEnabled; + + if ((index.column() == 0 && type != BookmarkNode::Separator) + || (index.column() == 1 && type == BookmarkNode::Bookmark)) + flags |= Qt::ItemIsEditable; + + return flags; +} + +Qt::DropActions BookmarksModel::supportedDropActions() const +{ + return Qt::CopyAction | Qt::MoveAction; +} + +#define MIMETYPE QLatin1String("application/bookmarks.xbel") + +QStringList BookmarksModel::mimeTypes() const +{ + QStringList types; + types << MIMETYPE; + types << QLatin1String("text/uri-list"); + return types; +} + +QMimeData *BookmarksModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData(); + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + QList urls; + foreach (const QModelIndex &index, indexes) { + if (index.column() != 0 || !index.isValid()) + continue; + QByteArray encodedData; + QBuffer buffer(&encodedData); + buffer.open(QBuffer::ReadWrite); + XbelWriter writer; + const BookmarkNode *parentNode = node(index); + writer.write(&buffer, parentNode); + stream << encodedData; + urls.append(index.data(BookmarksModel::UrlRole).toUrl()); + } + mimeData->setData(MIMETYPE, data); + mimeData->setUrls(urls); + return mimeData; +} + +bool BookmarksModel::dropMimeData(const QMimeData *data, + Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + if (action == Qt::IgnoreAction) + return true; + + if (column > 0) + return false; + + BookmarkNode *parentNode = node(parent); + + if (!data->hasFormat(MIMETYPE)) { + if (!data->hasUrls()) + return false; + + BookmarkNode *node = new BookmarkNode(BookmarkNode::Bookmark, parentNode); + node->url = QString::fromUtf8(data->urls().at(0).toEncoded()); + + if (data->hasText()) + node->title = data->text(); + else + node->title = node->url; + + m_bookmarksManager->addBookmark(parentNode, node, row); + return true; + } + + QByteArray ba = data->data(MIMETYPE); + QDataStream stream(&ba, QIODevice::ReadOnly); + if (stream.atEnd()) + return false; + + QUndoStack *undoStack = m_bookmarksManager->undoRedoStack(); + undoStack->beginMacro(QLatin1String("Move Bookmarks")); + + while (!stream.atEnd()) { + QByteArray encodedData; + stream >> encodedData; + QBuffer buffer(&encodedData); + buffer.open(QBuffer::ReadOnly); + + XbelReader reader; + BookmarkNode *rootNode = reader.read(&buffer); + QList children = rootNode->children(); + for (int i = 0; i < children.count(); ++i) { + BookmarkNode *bookmarkNode = children.at(i); + rootNode->remove(bookmarkNode); + row = qMax(0, row); + m_bookmarksManager->addBookmark(parentNode, bookmarkNode, row); + m_endMacro = true; + } + delete rootNode; + } + return true; +} + +bool BookmarksModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() || (flags(index) & Qt::ItemIsEditable) == 0) + return false; + + BookmarkNode *item = node(index); + + switch (role) { + case Qt::EditRole: + case Qt::DisplayRole: + if (index.column() == 0) { + m_bookmarksManager->setTitle(item, value.toString()); + break; + } + if (index.column() == 1) { + m_bookmarksManager->setUrl(item, value.toString()); + break; + } + return false; + case BookmarksModel::UrlRole: + m_bookmarksManager->setUrl(item, value.toUrl().toString()); + break; + case BookmarksModel::UrlStringRole: + m_bookmarksManager->setUrl(item, value.toString()); + break; + default: + break; + return false; + } + + return true; +} + +BookmarkNode *BookmarksModel::node(const QModelIndex &index) const +{ + BookmarkNode *itemNode = static_cast(index.internalPointer()); + if (!itemNode) + return m_bookmarksManager->bookmarks(); + return itemNode; +} + diff --git a/src/bookmarks/bookmarksmodel.h b/src/bookmarks/bookmarksmodel.h new file mode 100644 index 00000000..a374a488 --- /dev/null +++ b/src/bookmarks/bookmarksmodel.h @@ -0,0 +1,119 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef BOOKMARKSMODEL_H +#define BOOKMARKSMODEL_H + +#include + +#include + +class BookmarkNode; +class BookmarksManager; +class BookmarksModel : public QAbstractItemModel +{ + Q_OBJECT + +public slots: + void entryAdded(BookmarkNode *item); + void entryRemoved(BookmarkNode *parent, int row, BookmarkNode *item); + void entryChanged(BookmarkNode *item); + +public: + enum Roles { + TypeRole = Qt::UserRole + 1, + UrlRole = Qt::UserRole + 2, + UrlStringRole = Qt::UserRole + 3, + SeparatorRole = Qt::UserRole + 4 + }; + + BookmarksModel(BookmarksManager *bookmarkManager, QObject *parent = 0); + inline BookmarksManager *bookmarksManager() const { + return m_bookmarksManager; + } + + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + Qt::DropActions supportedDropActions() const; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + QMimeData *mimeData(const QModelIndexList &indexes) const; + QStringList mimeTypes() const; + bool dropMimeData(const QMimeData *data, + Qt::DropAction action, int row, int column, const QModelIndex &parent); + bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + + BookmarkNode *node(const QModelIndex &index) const; + QModelIndex index(BookmarkNode *node) const; + +private: + + bool m_endMacro; + BookmarksManager *m_bookmarksManager; +}; + +#endif // BOOKMARKSMODEL_H diff --git a/src/bookmarks/bookmarkstoolbar.cpp b/src/bookmarks/bookmarkstoolbar.cpp new file mode 100644 index 00000000..42c12cfc --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.cpp @@ -0,0 +1,153 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "bookmarkstoolbar.h" + +#include "addbookmarkdialog.h" +#include "bookmarknode.h" +#include "bookmarksmanager.h" +#include "bookmarksmenu.h" +#include "bookmarksmodel.h" +#include "browserapplication.h" +#include "modelmenu.h" + +#include + +BookmarksToolBar::BookmarksToolBar(BookmarksModel *model, QWidget *parent) + : ModelToolBar(parent) + , m_bookmarksModel(model) +{ + setModel(model); + setRootIndex(model->index(BrowserApplication::bookmarksManager()->toolbar())); + + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(contextMenuRequested(const QPoint &))); + connect(this, SIGNAL(activated(const QModelIndex &)), + this, SLOT(bookmarkActivated(const QModelIndex &))); + + setHidden(true); + setToolButtonStyle(Qt::ToolButtonTextOnly); +} + +void BookmarksToolBar::contextMenuRequested(const QPoint &position) +{ + QAction *action = actionAt(position); + + QMenu menu; + + if (action) { + QVariant variant = action->data(); + Q_ASSERT(variant.canConvert()); + + QAction *menuAction = 0; + + if (!action->menu()) { + menuAction = menu.addAction(tr("Open"), this, SLOT(openBookmarkInCurrentTab())); + menuAction->setData(variant); + + menuAction = menu.addAction(tr("Open in New &Tab"), this, SLOT(openBookmarkInNewTab())); + menuAction->setData(variant); + + menu.addSeparator(); + } + + menuAction = menu.addAction(tr("Remove"), this, SLOT(removeBookmark())); + menuAction->setData(variant); + + menu.addSeparator(); + } + + menu.addAction(tr("Add Bookmark..."), this, SLOT(newBookmark())); + menu.addAction(tr("Add Folder..."), this, SLOT(newFolder())); + + menu.exec(QCursor::pos()); +} + +void BookmarksToolBar::bookmarkActivated(const QModelIndex &index) +{ + Q_ASSERT(index.isValid()); + + emit openUrl( + index.data(BookmarksModel::UrlRole).toUrl(), + index.data(Qt::DisplayRole).toString()); +} + +void BookmarksToolBar::openBookmark() +{ + QModelIndex index = ModelToolBar::index(qobject_cast(sender())); + + emit openUrl( + index.data(BookmarksModel::UrlRole).toUrl(), + index.data(Qt::DisplayRole).toString()); +} + +void BookmarksToolBar::openBookmarkInCurrentTab() +{ + QModelIndex index = ModelToolBar::index(qobject_cast(sender())); + + emit openUrl( + index.data(BookmarksModel::UrlRole).toUrl(), + TabWidget::CurrentTab, + index.data(Qt::DisplayRole).toString()); +} + +void BookmarksToolBar::openBookmarkInNewTab() +{ + QModelIndex index = ModelToolBar::index(qobject_cast(sender())); + + emit openUrl( + index.data(BookmarksModel::UrlRole).toUrl(), + TabWidget::NewTab, + index.data(Qt::DisplayRole).toString()); +} + +void BookmarksToolBar::removeBookmark() +{ + QModelIndex index = ModelToolBar::index(qobject_cast(sender())); + + m_bookmarksModel->removeRow(index.row(), rootIndex()); +} + +void BookmarksToolBar::newBookmark() +{ + AddBookmarkDialog dialog; + dialog.setCurrentIndex(rootIndex()); + dialog.exec(); +} + +void BookmarksToolBar::newFolder() +{ + AddBookmarkDialog dialog; + dialog.setCurrentIndex(rootIndex()); + dialog.setFolder(true); + dialog.exec(); +} + +ModelMenu *BookmarksToolBar::createMenu() +{ + BookmarksMenu *menu = new BookmarksMenu(this); + connect(menu, SIGNAL(openUrl(const QUrl&, const QString&)), + this, SIGNAL(openUrl(const QUrl&, const QString&))); + connect(menu, SIGNAL(openUrl(const QUrl&, TabWidget::OpenUrlIn, const QString &)), + this, SIGNAL(openUrl(const QUrl&, TabWidget::OpenUrlIn, const QString &))); + return menu; +} + diff --git a/src/bookmarks/bookmarkstoolbar.h b/src/bookmarks/bookmarkstoolbar.h new file mode 100644 index 00000000..6ace7c0a --- /dev/null +++ b/src/bookmarks/bookmarkstoolbar.h @@ -0,0 +1,65 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef BOOKMARKSTOOLBAR_H +#define BOOKMARKSTOOLBAR_H + +#include "modeltoolbar.h" + +#include "tabwidget.h" + +#include +#include +#include + +class BookmarksModel; +class BookmarksToolBar : public ModelToolBar +{ + Q_OBJECT + +signals: + void openUrl(const QUrl &url, const QString &title); + void openUrl(const QUrl &url, TabWidget::OpenUrlIn tab, const QString &title); + +public: + BookmarksToolBar(BookmarksModel *model, QWidget *parent = 0); + +protected: + virtual ModelMenu *createMenu(); + +private slots: + void contextMenuRequested(const QPoint &position); + +protected slots: + void openBookmark(); + void openBookmarkInCurrentTab(); + void openBookmarkInNewTab(); + void removeBookmark(); + void newBookmark(); + void newFolder(); + void bookmarkActivated(const QModelIndex &); + +private: + BookmarksModel *m_bookmarksModel; + + QPoint m_dragStartPosition; +}; + +#endif // BOOKMARKSTOOLBAR_H diff --git a/src/bookmarks/xbel/xbel.pri b/src/bookmarks/xbel/xbel.pri new file mode 100644 index 00000000..02b0258f --- /dev/null +++ b/src/bookmarks/xbel/xbel.pri @@ -0,0 +1,10 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + xbelreader.h \ + xbelwriter.h + +SOURCES += \ + xbelreader.cpp \ + xbelwriter.cpp diff --git a/src/xbel.cpp b/src/bookmarks/xbel/xbelreader.cpp similarity index 66% rename from src/xbel.cpp rename to src/bookmarks/xbel/xbelreader.cpp index 02dad7c5..5639bbf7 100644 --- a/src/xbel.cpp +++ b/src/bookmarks/xbel/xbelreader.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,7 @@ /**************************************************************************** ** -** Copyright (C) 2005-2008 Trolltech ASA. All rights reserved. +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. ** ** This file is part of the demonstration applications of the Qt Toolkit. ** @@ -60,84 +60,30 @@ ** ****************************************************************************/ -#include "xbel.h" +#include "xbelreader.h" #include -BookmarkNode::BookmarkNode(BookmarkNode::Type type, BookmarkNode *parent) : - expanded(false) - , m_parent(parent) - , m_type(type) -{ - if (parent) - parent->add(this); -} - -BookmarkNode::~BookmarkNode() -{ - if (m_parent) - m_parent->remove(this); - qDeleteAll(m_children); - m_parent = 0; - m_type = BookmarkNode::Root; -} +#include "bookmarknode.h" -bool BookmarkNode::operator==(const BookmarkNode &other) +QString XmlEntityResolver::resolveUndeclaredEntity(const QString &entity) { - if (url != other.url - || title != other.title - || desc != other.desc - || expanded != other.expanded - || m_type != other.m_type - || m_children.count() != other.m_children.count()) - return false; + if (entity == QLatin1String("nbsp")) + return QLatin1String(" "); - for (int i = 0; i < m_children.count(); ++i) - if (!((*(m_children[i])) == (*(other.m_children[i])))) - return false; - return true; -} - -BookmarkNode::Type BookmarkNode::type() const -{ - return m_type; -} - -void BookmarkNode::setType(Type type) -{ - m_type = type; + return QString(); } -QList BookmarkNode::children() const -{ - return m_children; -} - -BookmarkNode *BookmarkNode::parent() const -{ - return m_parent; -} - -void BookmarkNode::add(BookmarkNode *child, int offset) -{ - Q_ASSERT(child->m_type != Root); - if (child->m_parent) - child->m_parent->remove(child); - child->m_parent = this; - if (-1 == offset) - offset = m_children.size(); - m_children.insert(offset, child); -} - -void BookmarkNode::remove(BookmarkNode *child) +XbelReader::XbelReader() + : m_entityResolver(0) { - child->m_parent = 0; - m_children.removeAll(child); + m_entityResolver = new XmlEntityResolver(); + setEntityResolver(m_entityResolver); } - -XbelReader::XbelReader() +XbelReader::~XbelReader() { + delete m_entityResolver; } BookmarkNode *XbelReader::read(const QString &fileName) @@ -278,64 +224,3 @@ void XbelReader::skipUnknownElement() } } - -XbelWriter::XbelWriter() -{ - setAutoFormatting(true); -} - -bool XbelWriter::write(const QString &fileName, const BookmarkNode *root) -{ - QFile file(fileName); - if (!root || !file.open(QFile::WriteOnly)) - return false; - return write(&file, root); -} - -bool XbelWriter::write(QIODevice *device, const BookmarkNode *root) -{ - setDevice(device); - - writeStartDocument(); - writeDTD(QLatin1String("")); - writeStartElement(QLatin1String("xbel")); - writeAttribute(QLatin1String("version"), QLatin1String("1.0")); - if (root->type() == BookmarkNode::Root) { - for (int i = 0; i < root->children().count(); ++i) - writeItem(root->children().at(i)); - } else { - writeItem(root); - } - - writeEndDocument(); - return true; -} - -void XbelWriter::writeItem(const BookmarkNode *parent) -{ - switch (parent->type()) { - case BookmarkNode::Folder: - writeStartElement(QLatin1String("folder")); - writeAttribute(QLatin1String("folded"), parent->expanded ? QLatin1String("no") : QLatin1String("yes")); - writeTextElement(QLatin1String("title"), parent->title); - for (int i = 0; i < parent->children().count(); ++i) - writeItem(parent->children().at(i)); - writeEndElement(); - break; - case BookmarkNode::Bookmark: - writeStartElement(QLatin1String("bookmark")); - if (!parent->url.isEmpty()) - writeAttribute(QLatin1String("href"), parent->url); - writeTextElement(QLatin1String("title"), parent->title); - if (!parent->desc.isEmpty()) - writeAttribute(QLatin1String("desc"), parent->desc); - writeEndElement(); - break; - case BookmarkNode::Separator: - writeEmptyElement(QLatin1String("separator")); - break; - default: - break; - } -} - diff --git a/src/xbel.h b/src/bookmarks/xbel/xbelreader.h similarity index 77% rename from src/xbel.h rename to src/bookmarks/xbel/xbelreader.h index a40a5e97..667912aa 100644 --- a/src/xbel.h +++ b/src/bookmarks/xbel/xbelreader.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,50 +60,25 @@ ** ****************************************************************************/ -#ifndef XBEL_H -#define XBEL_H +#ifndef XBELREADER_H +#define XBELREADER_H #include #include -class BookmarkNode +class BookmarkNode; +class XmlEntityResolver : public QXmlStreamEntityResolver { public: - enum Type { - Root, - Folder, - Bookmark, - Separator - }; - - BookmarkNode(Type type = Root, BookmarkNode *parent = 0); - ~BookmarkNode(); - bool operator==(const BookmarkNode &other); - - Type type() const; - void setType(Type type); - QList children() const; - BookmarkNode *parent() const; - - void add(BookmarkNode *child, int offset = -1); - void remove(BookmarkNode *child); - - QString url; - QString title; - QString desc; - bool expanded; - -private: - BookmarkNode *m_parent; - Type m_type; - QList m_children; - + QString resolveUndeclaredEntity(const QString &entity); }; class XbelReader : public QXmlStreamReader { public: XbelReader(); + ~XbelReader(); + BookmarkNode *read(const QString &fileName); BookmarkNode *read(QIODevice *device); @@ -115,18 +90,10 @@ class XbelReader : public QXmlStreamReader void readSeparator(BookmarkNode *parent); void readFolder(BookmarkNode *parent); void readBookmarkNode(BookmarkNode *parent); -}; - -class XbelWriter : public QXmlStreamWriter -{ -public: - XbelWriter(); - bool write(const QString &fileName, const BookmarkNode *root); - bool write(QIODevice *device, const BookmarkNode *root); private: - void writeItem(const BookmarkNode *parent); + XmlEntityResolver *m_entityResolver; }; -#endif // XBEL_H +#endif // XBELREADER_H diff --git a/src/bookmarks/xbel/xbelwriter.cpp b/src/bookmarks/xbel/xbelwriter.cpp new file mode 100644 index 00000000..2c186aa5 --- /dev/null +++ b/src/bookmarks/xbel/xbelwriter.cpp @@ -0,0 +1,128 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "xbelwriter.h" + +#include + +#include "bookmarknode.h" + +XbelWriter::XbelWriter() +{ + setAutoFormatting(true); +} + +bool XbelWriter::write(const QString &fileName, const BookmarkNode *root) +{ + QFile file(fileName); + if (!root || !file.open(QFile::WriteOnly)) + return false; + return write(&file, root); +} + +bool XbelWriter::write(QIODevice *device, const BookmarkNode *root) +{ + setDevice(device); + + writeStartDocument(); + writeDTD(QLatin1String("")); + writeStartElement(QLatin1String("xbel")); + writeAttribute(QLatin1String("version"), QLatin1String("1.0")); + if (root->type() == BookmarkNode::Root) { + for (int i = 0; i < root->children().count(); ++i) + writeItem(root->children().at(i)); + } else { + writeItem(root); + } + + writeEndDocument(); + return true; +} + +void XbelWriter::writeItem(const BookmarkNode *parent) +{ + switch (parent->type()) { + case BookmarkNode::Folder: + writeStartElement(QLatin1String("folder")); + writeAttribute(QLatin1String("folded"), parent->expanded ? QLatin1String("no") : QLatin1String("yes")); + writeTextElement(QLatin1String("title"), parent->title); + for (int i = 0; i < parent->children().count(); ++i) + writeItem(parent->children().at(i)); + writeEndElement(); + break; + case BookmarkNode::Bookmark: + writeStartElement(QLatin1String("bookmark")); + if (!parent->url.isEmpty()) + writeAttribute(QLatin1String("href"), parent->url); + writeTextElement(QLatin1String("title"), parent->title); + if (!parent->desc.isEmpty()) + writeAttribute(QLatin1String("desc"), parent->desc); + writeEndElement(); + break; + case BookmarkNode::Separator: + writeEmptyElement(QLatin1String("separator")); + break; + default: + break; + } +} + diff --git a/src/squeezelabel.h b/src/bookmarks/xbel/xbelwriter.h similarity index 86% rename from src/squeezelabel.h rename to src/bookmarks/xbel/xbelwriter.h index bb7bcb2f..f53bc94f 100644 --- a/src/squeezelabel.h +++ b/src/bookmarks/xbel/xbelwriter.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,22 +60,23 @@ ** ****************************************************************************/ -#ifndef SQUEEZELABEL_H -#define SQUEEZELABEL_H +#ifndef XBELWRITER_H +#define XBELWRITER_H -#include +#include +#include -class SqueezeLabel : public QLabel +class BookmarkNode; +class XbelWriter : public QXmlStreamWriter { - Q_OBJECT - public: - SqueezeLabel(QWidget *parent = 0); - -protected: - void paintEvent(QPaintEvent *event); + XbelWriter(); + bool write(const QString &fileName, const BookmarkNode *root); + bool write(QIODevice *device, const BookmarkNode *root); +private: + void writeItem(const BookmarkNode *parent); }; -#endif // SQUEEZELABEL_H +#endif // XBELWRITER_H diff --git a/src/browser_os2.ico b/src/browser_os2.ico new file mode 100644 index 00000000..a893038d Binary files /dev/null and b/src/browser_os2.ico differ diff --git a/src/browser_os2.rc b/src/browser_os2.rc new file mode 100644 index 00000000..cf0071fa --- /dev/null +++ b/src/browser_os2.rc @@ -0,0 +1 @@ +ICON 1 "browser_os2.ico" diff --git a/src/browserapplication.cpp b/src/browserapplication.cpp index 8a39dfba..4514a803 100644 --- a/src/browserapplication.cpp +++ b/src/browserapplication.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,11 +62,14 @@ #include "browserapplication.h" -#include "bookmarks.h" +#include "autosaver.h" +#include "autofillmanager.h" +#include "bookmarksmanager.h" #include "browsermainwindow.h" #include "cookiejar.h" #include "downloadmanager.h" -#include "history.h" +#include "historymanager.h" +#include "languagemanager.h" #include "networkaccessmanager.h" #include "tabwidget.h" #include "webview.h" @@ -76,52 +79,60 @@ #include #include #include -#include -#include -#include - -#include #include -#include - +#include +#include #include #include +#ifdef Q_OS_WIN +#include +#endif + +// #define BROWSERAPPLICATION_DEBUG + DownloadManager *BrowserApplication::s_downloadManager = 0; HistoryManager *BrowserApplication::s_historyManager = 0; NetworkAccessManager *BrowserApplication::s_networkAccessManager = 0; BookmarksManager *BrowserApplication::s_bookmarksManager = 0; +LanguageManager *BrowserApplication::s_languageManager = 0; +AutoFillManager *BrowserApplication::s_autoFillManager = 0; BrowserApplication::BrowserApplication(int &argc, char **argv) - : QApplication(argc, argv) - , m_localServer(0) + : SingleApplication(argc, argv) + , quitting(false) { QCoreApplication::setOrganizationDomain(QLatin1String("arora-browser.org")); QCoreApplication::setApplicationName(QLatin1String("Arora")); - QString version = QString("0.2 (Change: %1 %2)").arg(GITCHANGENUMBER).arg(GITVERSION); - QCoreApplication::setApplicationVersion(version); -#ifdef Q_WS_QWS - // Use a different server name for QWS so we can run an X11 - // browser and a QWS browser in parallel on the same machine for - // debugging - QString serverName = QCoreApplication::applicationName() + QLatin1String("_qws"); -#else - QString serverName = QCoreApplication::applicationName(); + QCoreApplication::setApplicationVersion(QLatin1String("0.11.0" +#ifdef GITVERSION + " (Git: " GITCHANGENUMBER " " GITVERSION ")" #endif - QLocalSocket socket; - socket.connectToServer(serverName); - if (socket.waitForConnected(500)) { - QTextStream stream(&socket); - QStringList args = QCoreApplication::arguments(); - if (args.count() > 1) - stream << args.last(); - else - stream << QString(); - stream.flush(); - socket.waitForBytesWritten(); - return; + )); + +#ifndef AUTOTESTS + connect(this, SIGNAL(messageReceived(QLocalSocket *)), + this, SLOT(messageReceived(QLocalSocket *))); + + QStringList args = QCoreApplication::arguments(); + if (args.count() > 1) { + QString message = parseArgumentUrl(args.last()); + sendMessage(message.toUtf8()); } + // If we could connect to another Arora then exit + QString message = QString(QLatin1String("aroramessage://getwinid")); + if (sendMessage(message.toUtf8(), 500)) + return; + +#ifdef BROWSERAPPLICATION_DEBUG + qDebug() << "BrowserApplication::" << __FUNCTION__ << "I am the only arora"; +#endif + + // not sure what else to do... + if (!startSingleServer()) + return; +#endif #if defined(Q_WS_MAC) QApplication::setQuitOnLastWindowClosed(false); @@ -129,22 +140,11 @@ BrowserApplication::BrowserApplication(int &argc, char **argv) QApplication::setQuitOnLastWindowClosed(true); #endif - m_localServer = new QLocalServer(this); - connect(m_localServer, SIGNAL(newConnection()), - this, SLOT(newLocalSocketConnection())); - if (!m_localServer->listen(serverName)) { - if (m_localServer->serverError() == QAbstractSocket::AddressInUseError - && QFile::exists(m_localServer->serverName())) { - QFile::remove(m_localServer->serverName()); - m_localServer->listen(serverName); - } - } - QDesktopServices::setUrlHandler(QLatin1String("http"), this, "openUrl"); - QString localSysName = QLocale::system().name(); - installTranslator(QLatin1String("qt_") + localSysName); - installTranslator(dataDirectory() + QDir::separator() + "locale" + QDir::separator() + localSysName); + // Until QtWebkit defaults to 16 + QWebSettings::globalSettings()->setFontSize(QWebSettings::DefaultFontSize, 16); + QWebSettings::globalSettings()->setFontSize(QWebSettings::DefaultFixedFontSize, 16); QSettings settings; settings.beginGroup(QLatin1String("sessions")); @@ -156,15 +156,26 @@ BrowserApplication::BrowserApplication(int &argc, char **argv) this, SLOT(lastWindowClosed())); #endif + // setting this in the postLaunch actually takes a lot more time + // because the event has to be propagated to everyone. + setWindowIcon(QIcon(QLatin1String(":128x128/arora.png"))); + +#ifndef AUTOTESTS QTimer::singleShot(0, this, SLOT(postLaunch())); +#endif + languageManager(); } BrowserApplication::~BrowserApplication() { + quitting = true; delete s_downloadManager; qDeleteAll(m_mainWindows); delete s_networkAccessManager; delete s_bookmarksManager; + delete s_languageManager; + delete s_historyManager; + delete s_autoFillManager; } #if defined(Q_WS_MAC) @@ -172,61 +183,166 @@ void BrowserApplication::lastWindowClosed() { clean(); BrowserMainWindow *mw = new BrowserMainWindow; - mw->slotHome(); + mw->goHome(); m_mainWindows.prepend(mw); } #endif BrowserApplication *BrowserApplication::instance() { - return (static_cast(QCoreApplication::instance())); + return (static_cast(QCoreApplication::instance())); } -#if defined(Q_WS_MAC) -#include -void BrowserApplication::quitBrowser() +void BrowserApplication::retranslate() { - clean(); - int tabCount = 0; - for (int i = 0; i < m_mainWindows.count(); ++i) { - tabCount += m_mainWindows.at(i)->tabWidget()->count(); + bookmarksManager()->retranslate(); + networkAccessManager()->loadSettings(); +} + +// The only special property of an argument url is that the file's +// can be local, they don't have to be absolute. +QString BrowserApplication::parseArgumentUrl(const QString &string) const +{ + if (QFile::exists(string)) { + QFileInfo info(string); + return info.canonicalFilePath(); } + return string; +} - if (tabCount > 1) { - int ret = QMessageBox::warning(mainWindow(), QString(), - tr("There are %1 windows and %2 tabs open\n" - "Do you want to quit anyway?").arg(m_mainWindows.count()).arg(tabCount), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - if (ret == QMessageBox::No) +void BrowserApplication::messageReceived(QLocalSocket *socket) +{ + QString message; + QTextStream stream(socket); + stream >> message; +#ifdef BROWSERAPPLICATION_DEBUG + qDebug() << "BrowserApplication::" << __FUNCTION__ << message; +#endif + if (message.isEmpty()) + return; + + // Got a normal url + if (!message.startsWith(QLatin1String("aroramessage://"))) { + QSettings settings; + settings.beginGroup(QLatin1String("tabs")); + TabWidget::OpenUrlIn tab = TabWidget::OpenUrlIn(settings.value(QLatin1String("openLinksFromAppsIn"), TabWidget::NewSelectedTab).toInt()); + settings.endGroup(); + if (QUrl(message) == m_lastAskedUrl + && m_lastAskedUrlDateTime.addSecs(10) > QDateTime::currentDateTime()) { + qWarning() << "Possible recursive openUrl called, ignoring url:" << m_lastAskedUrl; return; + } + mainWindow()->tabWidget()->loadString(message, tab); + return; + } + + if (message.startsWith(QLatin1String("aroramessage://getwinid"))) { +#ifdef Q_OS_WIN + QString winid = QString(QLatin1String("%1")).arg((qlonglong)mainWindow()->winId()); +#else + mainWindow()->show(); + mainWindow()->setFocus(); + mainWindow()->raise(); + mainWindow()->activateWindow(); + alert(mainWindow()); + QString winid; +#endif +#ifdef BROWSERAPPLICATION_DEBUG + qDebug() << "BrowserApplication::" << __FUNCTION__ << "sending win id" << winid << mainWindow()->winId(); +#endif + QString message = QLatin1String("aroramessage://winid/") + winid; + socket->write(message.toUtf8()); + socket->waitForBytesWritten(); + return; + } + + if (message.startsWith(QLatin1String("aroramessage://winid"))) { + QString winid = message.mid(21); +#ifdef BROWSERAPPLICATION_DEBUG + qDebug() << "BrowserApplication::" << __FUNCTION__ << "got win id:" << winid; +#endif +#ifdef Q_OS_WIN + WId wid = (WId)winid.toLongLong(); + SetForegroundWindow(wid); +#endif + return; + } +} + +void BrowserApplication::quitBrowser() +{ + if (s_downloadManager && !downloadManager()->allowQuit()) + return; + + if (QSettings().value(QLatin1String("tabs/confirmClosingMultipleTabs"), true).toBool()) { + clean(); + int tabCount = 0; + for (int i = 0; i < m_mainWindows.count(); ++i) { + tabCount += m_mainWindows.at(i)->tabWidget()->count(); + } + + if (tabCount > 1) { + QWidget *widget = mainWindow(); + QApplication::alert(widget); + int ret = QMessageBox::warning(widget, QString(), + tr("There are %1 windows and %2 tabs open\n" + "Do you want to quit anyway?").arg(m_mainWindows.count()).arg(tabCount), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No); + if (ret == QMessageBox::No) + return; + } } + saveSession(); exit(0); } -#endif /*! Any actions that can be delayed until the window is visible */ void BrowserApplication::postLaunch() { - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + QDesktopServices::StandardLocation location; + location = QDesktopServices::CacheLocation; + QString directory = QDesktopServices::storageLocation(location); if (directory.isEmpty()) directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); QWebSettings::setIconDatabasePath(directory); - setWindowIcon(QIcon(QLatin1String(":arora-128.png"))); - loadSettings(); // newMainWindow() needs to be called in main() for this to happen if (m_mainWindows.count() > 0) { + QSettings settings; + settings.beginGroup(QLatin1String("MainWindow")); + int startup = settings.value(QLatin1String("startupBehavior")).toInt(); QStringList args = QCoreApplication::arguments(); - if (args.count() > 1) - mainWindow()->loadPage(args.last()); - else - mainWindow()->slotHome(); + + if (args.count() > 1) { + QString argumentUrl = parseArgumentUrl(args.last()); + switch (startup) { + case 2: { + restoreLastSession(); + mainWindow()->tabWidget()->loadString(argumentUrl, TabWidget::NewSelectedTab); + break; + } + default: + mainWindow()->tabWidget()->loadString(argumentUrl); + break; + } + } else { + switch (startup) { + case 0: + mainWindow()->goHome(); + break; + case 1: + break; + case 2: + restoreLastSession(); + break; + } + } } BrowserApplication::historyManager(); } @@ -243,6 +359,9 @@ void BrowserApplication::loadSettings() standardFont = qVariantValue(settings.value(QLatin1String("standardFont"), standardFont)); defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family()); defaultSettings->setFontSize(QWebSettings::DefaultFontSize, standardFont.pointSize()); + int minimumFontSize = settings.value(QLatin1String("minimumFontSize"), + defaultSettings->fontSize(QWebSettings::MinimumFontSize)).toInt(); + defaultSettings->setFontSize(QWebSettings::MinimumFontSize, minimumFontSize); QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont); int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize); @@ -251,13 +370,22 @@ void BrowserApplication::loadSettings() defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family()); defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fixedFont.pointSize()); + defaultSettings->setAttribute(QWebSettings::JavascriptCanOpenWindows, !(settings.value(QLatin1String("blockPopupWindows"), true).toBool())); defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, settings.value(QLatin1String("enableJavascript"), true).toBool()); defaultSettings->setAttribute(QWebSettings::PluginsEnabled, settings.value(QLatin1String("enablePlugins"), true).toBool()); defaultSettings->setAttribute(QWebSettings::AutoLoadImages, settings.value(QLatin1String("enableImages"), true).toBool()); + defaultSettings->setAttribute(QWebSettings::LocalStorageEnabled, settings.value(QLatin1String("enableLocalStorage"), true).toBool()); + defaultSettings->setAttribute(QWebSettings::DeveloperExtrasEnabled, settings.value(QLatin1String("enableInspector"), false).toBool()); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + defaultSettings->setAttribute(QWebSettings::DnsPrefetchEnabled, true); +#endif QUrl url = settings.value(QLatin1String("userStyleSheet")).toUrl(); defaultSettings->setUserStyleSheetUrl(url); + int maximumPagesInCache = settings.value(QLatin1String("maximumPagesInCache"), 3).toInt(); + QWebSettings::globalSettings()->setMaximumPagesInCache(maximumPagesInCache); + settings.endGroup(); } @@ -270,6 +398,18 @@ QList BrowserApplication::mainWindows() return list; } +bool BrowserApplication::allowToCloseWindow(BrowserMainWindow *window) +{ + Q_UNUSED(window) + if (mainWindows().count() > 1) + return true; + + if (s_downloadManager) + return downloadManager()->allowQuit(); + + return true; +} + void BrowserApplication::clean() { // cleanup any deleted main windows first @@ -282,13 +422,19 @@ static const qint32 BrowserApplicationMagic = 0xec; void BrowserApplication::saveSession() { + if (quitting) + return; + QSettings settings; + settings.beginGroup(QLatin1String("MainWindow")); + settings.setValue(QLatin1String("restoring"), false); + settings.endGroup(); + QWebSettings *globalSettings = QWebSettings::globalSettings(); if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) return; clean(); - QSettings settings; settings.beginGroup(QLatin1String("sessions")); int version = 2; @@ -315,6 +461,19 @@ bool BrowserApplication::canRestoreSession() const bool BrowserApplication::restoreLastSession() { + { + QSettings settings; + settings.beginGroup(QLatin1String("MainWindow")); + if (settings.value(QLatin1String("restoring"), false).toBool()) { + QMessageBox::StandardButton result = QMessageBox::question(0, tr("Restore failed"), + tr("Arora crashed while trying to restore this session. Should I try again?"), QMessageBox::Yes | QMessageBox::No); + if (result == QMessageBox::No) + return false; + } + // saveSession will be called by an AutoSaver timer from the set tabs + // and in saveSession we will reset this flag back to false + settings.setValue(QLatin1String("restoring"), true); + } int version = 2; QList windows; QBuffer buffer(&m_lastSession); @@ -337,9 +496,7 @@ bool BrowserApplication::restoreLastSession() } for (int i = 0; i < windows.count(); ++i) { BrowserMainWindow *newWindow = 0; - if (m_mainWindows.count() == 1 - && mainWindow()->tabWidget()->count() == 1 - && mainWindow()->currentTab()->url() == QUrl()) { + if (i == 0 && m_mainWindows.count() >= 1) { newWindow = mainWindow(); } else { newWindow = newMainWindow(); @@ -349,20 +506,8 @@ bool BrowserApplication::restoreLastSession() return true; } -bool BrowserApplication::isTheOnlyBrowser() const -{ - return (m_localServer != 0); -} - -void BrowserApplication::installTranslator(const QString &name) -{ - QTranslator *translator = new QTranslator(this); - translator->load(name, QLibraryInfo::location(QLibraryInfo::TranslationsPath)); - QApplication::installTranslator(translator); -} - #if defined(Q_WS_MAC) -bool BrowserApplication::event(QEvent* event) +bool BrowserApplication::event(QEvent *event) { switch (event->type()) { case QEvent::ApplicationActivate: { @@ -377,7 +522,8 @@ bool BrowserApplication::event(QEvent* event) } case QEvent::FileOpen: if (!m_mainWindows.isEmpty()) { - mainWindow()->loadPage(static_cast(event)->file()); + QString file = static_cast(event)->file(); + mainWindow()->tabWidget()->loadUrl(QUrl::fromLocalFile(file)); return true; } default: @@ -387,15 +533,28 @@ bool BrowserApplication::event(QEvent* event) } #endif +void BrowserApplication::askDesktopToOpenUrl(const QUrl &url) +{ + m_lastAskedUrl = url; + m_lastAskedUrlDateTime = QDateTime::currentDateTime(); + QDesktopServices::openUrl(url); +} + void BrowserApplication::openUrl(const QUrl &url) { - mainWindow()->loadPage(url.toString()); + setEventMouseButtons(mouseButtons()); + setEventKeyboardModifiers(keyboardModifiers()); + mainWindow()->tabWidget()->loadUrl(url); } BrowserMainWindow *BrowserApplication::newMainWindow() { + if (!m_mainWindows.isEmpty()) + mainWindow()->m_autoSaver->saveIfNeccessary(); BrowserMainWindow *browser = new BrowserMainWindow(); m_mainWindows.prepend(browser); + connect(this, SIGNAL(privacyChanged(bool)), + browser, SLOT(privacyChanged(bool))); browser->show(); return browser; } @@ -403,34 +562,18 @@ BrowserMainWindow *BrowserApplication::newMainWindow() BrowserMainWindow *BrowserApplication::mainWindow() { clean(); - if (m_mainWindows.isEmpty()) - newMainWindow(); - return m_mainWindows[0]; -} -void BrowserApplication::newLocalSocketConnection() -{ - QLocalSocket *socket = m_localServer->nextPendingConnection(); - if (!socket) - return; - socket->waitForReadyRead(1000); - QTextStream stream(socket); - QString url; - stream >> url; - if (!url.isEmpty()) { - QSettings settings; - settings.beginGroup(QLatin1String("general")); - int openLinksIn = settings.value(QLatin1String("openLinksIn"), 0).toInt(); - settings.endGroup(); - if (openLinksIn == 1) - newMainWindow(); - else - mainWindow()->tabWidget()->newTab(); - openUrl(url); + BrowserMainWindow *activeWindow = 0; + + if (m_mainWindows.isEmpty()) { + activeWindow = newMainWindow(); + } else { + activeWindow = qobject_cast(QApplication::activeWindow()); + if (!activeWindow) + activeWindow = m_mainWindows[0]; } - delete socket; - mainWindow()->raise(); - mainWindow()->activateWindow(); + + return activeWindow; } CookieJar *BrowserApplication::cookieJar() @@ -440,18 +583,15 @@ CookieJar *BrowserApplication::cookieJar() DownloadManager *BrowserApplication::downloadManager() { - if (!s_downloadManager) { + if (!s_downloadManager) s_downloadManager = new DownloadManager(); - } return s_downloadManager; } NetworkAccessManager *BrowserApplication::networkAccessManager() { - if (!s_networkAccessManager) { + if (!s_networkAccessManager) s_networkAccessManager = new NetworkAccessManager(); - s_networkAccessManager->setCookieJar(new CookieJar); - } return s_networkAccessManager; } @@ -464,27 +604,109 @@ HistoryManager *BrowserApplication::historyManager() BookmarksManager *BrowserApplication::bookmarksManager() { - if (!s_bookmarksManager) { + if (!s_bookmarksManager) s_bookmarksManager = new BookmarksManager; - } return s_bookmarksManager; } -QIcon BrowserApplication::icon(const QUrl &url) const +LanguageManager *BrowserApplication::languageManager() +{ + if (!s_languageManager) { + s_languageManager = new LanguageManager(); + s_languageManager->addLocaleDirectory(dataFilePath(QLatin1String("locale"))); + s_languageManager->addLocaleDirectory(qApp->applicationDirPath() + QLatin1String("/src/.qm/locale")); + s_languageManager->addLocaleDirectory(installedDataDirectory() + QLatin1String("/locale")); + s_languageManager->loadLanguageFromSettings(); + connect(s_languageManager, SIGNAL(languageChanged(const QString &)), + qApp, SLOT(retranslate())); + } + return s_languageManager; +} + +AutoFillManager *BrowserApplication::autoFillManager() +{ + if (!s_autoFillManager) { + s_autoFillManager = new AutoFillManager; + } + return s_autoFillManager; +} + +QIcon BrowserApplication::icon(const QUrl &url) { QIcon icon = QWebSettings::iconForUrl(url); if (!icon.isNull()) return icon.pixmap(16, 16); - if (m_defaultIcon.isNull()) - m_defaultIcon = QIcon(QLatin1String(":defaulticon.png")); - return m_defaultIcon.pixmap(16, 16); + if (icon.isNull()) { + QPixmap pixmap = QWebSettings::webGraphic(QWebSettings::DefaultFrameIconGraphic); + if (pixmap.isNull()) { + pixmap = QPixmap(QLatin1String(":graphics/defaulticon.png")); + QWebSettings::setWebGraphic(QWebSettings::DefaultFrameIconGraphic, pixmap); + } + return pixmap; + } + return icon; } -QString BrowserApplication::dataDirectory() const +QString BrowserApplication::installedDataDirectory() { #if defined(Q_WS_X11) - return PKGDATADIR; + return QLatin1String(PKGDATADIR); #else - return applicationDirPath(); + return qApp->applicationDirPath(); #endif } + +QString BrowserApplication::dataFilePath(const QString &fileName) +{ + QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); + if (directory.isEmpty()) + directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); + if (!QFile::exists(directory)) { + QDir dir; + dir.mkpath(directory); + } + return directory + QLatin1String("/") + fileName; +} + +bool BrowserApplication::zoomTextOnly() +{ + return QWebSettings::globalSettings()->testAttribute(QWebSettings::ZoomTextOnly); +} + +void BrowserApplication::setZoomTextOnly(bool textOnly) +{ + QWebSettings::globalSettings()->setAttribute(QWebSettings::ZoomTextOnly, textOnly); + emit instance()->zoomTextOnlyChanged(textOnly); +} + +bool BrowserApplication::isPrivate() +{ + return QWebSettings::globalSettings()->testAttribute(QWebSettings::PrivateBrowsingEnabled); +} + +void BrowserApplication::setPrivate(bool isPrivate) +{ + QWebSettings::globalSettings()->setAttribute(QWebSettings::PrivateBrowsingEnabled, isPrivate); + emit instance()->privacyChanged(isPrivate); +} + +Qt::MouseButtons BrowserApplication::eventMouseButtons() const +{ + return m_eventMouseButtons; +} + +Qt::KeyboardModifiers BrowserApplication::eventKeyboardModifiers() const +{ + return m_eventKeyboardModifiers; +} + +void BrowserApplication::setEventMouseButtons(Qt::MouseButtons buttons) +{ + m_eventMouseButtons = buttons; +} + +void BrowserApplication::setEventKeyboardModifiers(Qt::KeyboardModifiers modifiers) +{ + m_eventKeyboardModifiers = modifiers; +} + diff --git a/src/browserapplication.h b/src/browserapplication.h index 64436a82..e345836a 100644 --- a/src/browserapplication.h +++ b/src/browserapplication.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,23 +63,22 @@ #ifndef BROWSERAPPLICATION_H #define BROWSERAPPLICATION_H -#include +#include "singleapplication.h" -#include #include #include +#include -QT_BEGIN_NAMESPACE -class QLocalServer; -QT_END_NAMESPACE - +class AutoFillManager; class BookmarksManager; class BrowserMainWindow; class CookieJar; class DownloadManager; class HistoryManager; class NetworkAccessManager; -class BrowserApplication : public QApplication +class LanguageManager; +class QLocalSocket; +class BrowserApplication : public SingleApplication { Q_OBJECT @@ -89,10 +88,11 @@ class BrowserApplication : public QApplication static BrowserApplication *instance(); void loadSettings(); - bool isTheOnlyBrowser() const; BrowserMainWindow *mainWindow(); QList mainWindows(); - QIcon icon(const QUrl &url) const; + bool allowToCloseWindow(BrowserMainWindow *window); + + static QIcon icon(const QUrl &url); void saveSession(); bool canRestoreSession() const; @@ -102,8 +102,21 @@ class BrowserApplication : public QApplication static DownloadManager *downloadManager(); static NetworkAccessManager *networkAccessManager(); static BookmarksManager *bookmarksManager(); + static LanguageManager *languageManager(); + static AutoFillManager *autoFillManager(); + + static QString installedDataDirectory(); + static QString dataFilePath(const QString &fileName); - QString dataDirectory() const; + Qt::MouseButtons eventMouseButtons() const; + Qt::KeyboardModifiers eventKeyboardModifiers() const; + void setEventMouseButtons(Qt::MouseButtons buttons); + void setEventKeyboardModifiers(Qt::KeyboardModifiers modifiers); + + static bool zoomTextOnly(); + + static bool isPrivate(); + static void setPrivate(bool isPrivate); #if defined(Q_WS_MAC) bool event(QEvent *event); @@ -114,27 +127,43 @@ public slots: bool restoreLastSession(); #if defined(Q_WS_MAC) void lastWindowClosed(); - void quitBrowser(); #endif + void quitBrowser(); + + static void setZoomTextOnly(bool textOnly); + + void askDesktopToOpenUrl(const QUrl &url); private slots: + void retranslate(); + void messageReceived(QLocalSocket *socket); void postLaunch(); void openUrl(const QUrl &url); - void newLocalSocketConnection(); + +signals: + void zoomTextOnlyChanged(bool textOnly); + void privacyChanged(bool isPrivate); private: + QString parseArgumentUrl(const QString &string) const; void clean(); - void installTranslator(const QString &name); static HistoryManager *s_historyManager; static DownloadManager *s_downloadManager; static NetworkAccessManager *s_networkAccessManager; static BookmarksManager *s_bookmarksManager; + static LanguageManager *s_languageManager; + static AutoFillManager *s_autoFillManager; QList > m_mainWindows; - QLocalServer *m_localServer; QByteArray m_lastSession; - mutable QIcon m_defaultIcon; + bool quitting; + + Qt::MouseButtons m_eventMouseButtons; + Qt::KeyboardModifiers m_eventKeyboardModifiers; + + QUrl m_lastAskedUrl; + QDateTime m_lastAskedUrlDateTime; }; #endif // BROWSERAPPLICATION_H diff --git a/src/browsermainwindow.cpp b/src/browsermainwindow.cpp index cb10e333..05f23b18 100644 --- a/src/browsermainwindow.cpp +++ b/src/browsermainwindow.cpp @@ -1,6 +1,7 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * Copyright 2008 Jason A. Donenfeld + * Copyright 2008 Ariya Hidayat * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,27 +65,38 @@ #include "browsermainwindow.h" #include "aboutdialog.h" +#include "adblockmanager.h" +#include "addbookmarkdialog.h" #include "autosaver.h" -#include "bookmarks.h" +#include "bookmarksdialog.h" +#include "bookmarksmanager.h" +#include "bookmarksmenu.h" +#include "bookmarksmodel.h" +#include "bookmarkstoolbar.h" #include "browserapplication.h" #include "clearprivatedata.h" #include "downloadmanager.h" #include "history.h" +#include "languagemanager.h" +#include "networkaccessmanager.h" +#include "opensearchdialog.h" #include "settings.h" +#include "sourceviewer.h" #include "tabbar.h" #include "tabwidget.h" #include "toolbarsearch.h" -#include "ui_passworddialog.h" +#include "useragentmenu.h" #include "webview.h" #include "webviewsearch.h" #include +#include #include -#include #include #include #include #include +#include #include #include #include @@ -92,6 +104,7 @@ #include #include +#include #include #include @@ -99,32 +112,66 @@ BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) + , m_navigationBar(0) + , m_navigationSplitter(0) + , m_toolbarSearch(0) +#if defined(Q_WS_MAC) + , m_bookmarksToolbarFrame(0) +#endif + , m_bookmarksToolbar(0) , m_tabWidget(new TabWidget(this)) , m_autoSaver(new AutoSaver(this)) - , m_historyBack(0) - , m_historyForward(0) - , m_stop(0) - , m_reload(0) { setAttribute(Qt::WA_DeleteOnClose, true); statusBar()->setSizeGripEnabled(true); + // fixes https://bugzilla.mozilla.org/show_bug.cgi?id=219070 + // yes, that's a Firefox bug! + statusBar()->setLayoutDirection(Qt::LeftToRight); setupMenu(); setupToolBar(); + m_filePrivateBrowsingAction->setChecked(BrowserApplication::isPrivate()); + QWidget *centralWidget = new QWidget(this); BookmarksModel *boomarksModel = BrowserApplication::bookmarksManager()->bookmarksModel(); m_bookmarksToolbar = new BookmarksToolBar(boomarksModel, this); - connect(m_bookmarksToolbar, SIGNAL(openUrl(const QUrl&, TabWidget::Tab, const QString&)), - m_tabWidget, SLOT(loadUrl(const QUrl&, TabWidget::Tab, const QString&))); - connect(m_bookmarksToolbar->toggleViewAction(), SIGNAL(toggled(bool)), - this, SLOT(updateBookmarksToolbarActionText(bool))); + m_bookmarksToolbar->setObjectName(QLatin1String("BookmarksToolbar")); + connect(m_bookmarksToolbar, SIGNAL(openUrl(const QUrl&, const QString&)), + m_tabWidget, SLOT(loadUrlFromUser(const QUrl&, const QString&))); + connect(m_bookmarksToolbar, SIGNAL(openUrl(const QUrl&, TabWidget::OpenUrlIn, const QString&)), + m_tabWidget, SLOT(loadUrl(const QUrl&, TabWidget::OpenUrlIn, const QString&))); QVBoxLayout *layout = new QVBoxLayout; layout->setSpacing(0); layout->setMargin(0); #if defined(Q_WS_MAC) + m_bookmarksToolbarFrame = new QFrame(this); + m_bookmarksToolbarFrame->setLineWidth(1); + m_bookmarksToolbarFrame->setMidLineWidth(0); + m_bookmarksToolbarFrame->setFrameShape(QFrame::HLine); + m_bookmarksToolbarFrame->setFrameShadow(QFrame::Raised); + QPalette fp = m_bookmarksToolbarFrame->palette(); + fp.setColor(QPalette::Active, QPalette::Light, QColor(64, 64, 64)); + fp.setColor(QPalette::Active, QPalette::Dark, QColor(192, 192, 192)); + fp.setColor(QPalette::Inactive, QPalette::Light, QColor(135, 135, 135)); + fp.setColor(QPalette::Inactive, QPalette::Dark, QColor(226, 226, 226)); + m_bookmarksToolbarFrame->setAttribute(Qt::WA_MacNoClickThrough, true); + m_bookmarksToolbarFrame->setPalette(fp); + layout->addWidget(m_bookmarksToolbarFrame); + layout->addWidget(m_bookmarksToolbar); - layout->addWidget(new QWidget); // <- OS X tab widget style bug + QPalette p = m_bookmarksToolbar->palette(); + p.setColor(QPalette::Active, QPalette::Window, QColor(150, 150, 150)); + p.setColor(QPalette::Inactive, QPalette::Window, QColor(207, 207, 207)); + m_bookmarksToolbar->setAttribute(Qt::WA_MacNoClickThrough, true); + m_bookmarksToolbar->setAutoFillBackground(true); + m_bookmarksToolbar->setPalette(p); + m_bookmarksToolbar->setBackgroundRole(QPalette::Window); + m_bookmarksToolbar->setMaximumHeight(19); + + QWidget *w = new QWidget(this); + w->setMaximumHeight(0); + layout->addWidget(w); // <- OS X tab widget style bug #else addToolBarBreak(); addToolBar(m_bookmarksToolbar); @@ -133,16 +180,14 @@ BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags) centralWidget->setLayout(layout); setCentralWidget(centralWidget); - connect(m_tabWidget, SIGNAL(loadPage(const QString &)), - this, SLOT(loadPage(const QString &))); connect(m_tabWidget, SIGNAL(setCurrentTitle(const QString &)), - this, SLOT(slotUpdateWindowTitle(const QString &))); + this, SLOT(updateWindowTitle(const QString &))); connect(m_tabWidget, SIGNAL(showStatusBarMessage(const QString&)), statusBar(), SLOT(showMessage(const QString&))); connect(m_tabWidget, SIGNAL(linkHovered(const QString&)), statusBar(), SLOT(showMessage(const QString&))); connect(m_tabWidget, SIGNAL(loadProgress(int)), - this, SLOT(slotLoadProgress(int))); + this, SLOT(loadProgress(int))); connect(m_tabWidget, SIGNAL(tabsChanged()), m_autoSaver, SLOT(changeOccurred())); connect(m_tabWidget, SIGNAL(geometryChangeRequested(const QRect &)), @@ -157,20 +202,32 @@ BrowserMainWindow::BrowserMainWindow(QWidget *parent, Qt::WindowFlags flags) m_navigationBar, SLOT(setVisible(bool))); connect(m_tabWidget, SIGNAL(toolBarVisibilityChangeRequested(bool)), m_bookmarksToolbar, SLOT(setVisible(bool))); -#if defined(Q_WS_MAC) connect(m_tabWidget, SIGNAL(lastTabClosed()), - this, SLOT(close())); -#else - connect(m_tabWidget, SIGNAL(lastTabClosed()), - m_tabWidget, SLOT(newTab())); -#endif + this, SLOT(lastTabClosed())); - slotUpdateWindowTitle(); + updateWindowTitle(); loadDefaultState(); m_tabWidget->newTab(); + m_tabWidget->currentLocationBar()->setFocus(); +#if defined(Q_WS_MAC) + m_navigationBar->setIconSize(QSize(18, 18)); +#endif - int size = m_tabWidget->lineEditStack()->sizeHint().height(); - m_navigationBar->setIconSize(QSize(size, size)); + // Add each item in the menu bar to the main window so + // if the menu bar is hidden the shortcuts still work. + QList actions = menuBar()->actions(); + foreach (QAction *action, actions) { + if (action->menu()) + actions += action->menu()->actions(); + addAction(action); + } +#if defined(Q_WS_MAC) + setWindowIcon(QIcon()); +#endif +#if defined(Q_WS_X11) + setWindowRole(QLatin1String("browser")); +#endif + retranslate(); } BrowserMainWindow::~BrowserMainWindow() @@ -179,6 +236,44 @@ BrowserMainWindow::~BrowserMainWindow() m_autoSaver->saveIfNeccessary(); } +void BrowserMainWindow::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_HomePage: + m_historyHomeAction->trigger(); + event->accept(); + break; + case Qt::Key_Favorites: + m_bookmarksShowAllAction->trigger(); + event->accept(); + break; + case Qt::Key_Search: + m_toolsWebSearchAction->trigger(); + event->accept(); + break; + case Qt::Key_OpenUrl: + m_fileOpenLocationAction->trigger(); + event->accept(); + break; + default: + QMainWindow::keyPressEvent(event); + break; + } +} + +BrowserMainWindow *BrowserMainWindow::parentWindow(QWidget *widget) +{ + while (widget) { + if (BrowserMainWindow *parent = qobject_cast(widget)) + return parent; + + widget = widget->parentWidget(); + } + + qWarning() << "BrowserMainWindow::" << __FUNCTION__ << " used with a widget none of whose parents is a main window."; + return BrowserApplication::instance()->mainWindow(); +} + void BrowserMainWindow::loadDefaultState() { QSettings settings; @@ -210,16 +305,17 @@ static const qint32 BrowserMainWindowMagic = 0xba; QByteArray BrowserMainWindow::saveState(bool withTabs) const { - int version = 2; + int version = 3; QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream << qint32(BrowserMainWindowMagic); stream << qint32(version); - stream << size(); - stream << !m_navigationBar->isHidden(); - stream << !m_bookmarksToolbar->isHidden(); + // save the normal size so exiting fullscreen/maximize will work reasonably + stream << normalGeometry().size(); + stream << !m_navigationBar->isHidden(); // DEAD + stream << !m_bookmarksToolbar->isHidden(); // DEAD stream << !statusBar()->isHidden(); if (withTabs) stream << tabWidget()->saveState(); @@ -227,294 +323,736 @@ QByteArray BrowserMainWindow::saveState(bool withTabs) const stream << QByteArray(); stream << m_navigationSplitter->saveState(); stream << m_tabWidget->tabBar()->showTabBarWhenOneTab(); + + stream << qint32(toolBarArea(m_navigationBar)); + stream << qint32(toolBarArea(m_bookmarksToolbar)); + + // version 3 + stream << isMaximized(); + stream << isFullScreen(); + stream << menuBar()->isVisible(); + stream << m_menuBarVisible; // DEAD + stream << m_statusBarVisible; + + stream << QMainWindow::saveState(); + return data; } bool BrowserMainWindow::restoreState(const QByteArray &state) { - int version = 2; QByteArray sd = state; QDataStream stream(&sd, QIODevice::ReadOnly); if (stream.atEnd()) return false; qint32 marker; - qint32 v; + qint32 version; stream >> marker; - stream >> v; - if (marker != BrowserMainWindowMagic || v != version) + stream >> version; + if (marker != BrowserMainWindowMagic || !(version == 2 || version == 3)) return false; QSize size; - bool showToolbar; - bool showBookmarksBar; + bool showToolbarDEAD; + bool showBookmarksBarDEAD; bool showStatusbar; QByteArray tabState; QByteArray splitterState; bool showTabBarWhenOneTab; + qint32 navigationBarLocation; + qint32 bookmarkBarLocation; + bool maximized; + bool fullScreen; + bool showMenuBar; + QByteArray qMainWindowState; stream >> size; - stream >> showToolbar; - stream >> showBookmarksBar; + stream >> showToolbarDEAD; + stream >> showBookmarksBarDEAD; stream >> showStatusbar; stream >> tabState; stream >> splitterState; stream >> showTabBarWhenOneTab; + stream >> navigationBarLocation; + stream >> bookmarkBarLocation; + + if (version >= 3) { + stream >> maximized; + stream >> fullScreen; + stream >> showMenuBar; + stream >> showMenuBar; // m_menuBarVisible DEAD + stream >> m_statusBarVisible; + stream >> qMainWindowState; + } else { + maximized = false; + fullScreen = false; + showMenuBar = true; + m_statusBarVisible = showStatusbar; + } - resize(size); + if (size.isValid()) + resize(size); - m_navigationBar->setVisible(showToolbar); - updateToolbarActionText(showToolbar); + if (maximized) + setWindowState(windowState() | Qt::WindowMaximized); + if (fullScreen) { + setWindowState(windowState() | Qt::WindowFullScreen); + m_viewFullScreenAction->setChecked(true); + } - m_bookmarksToolbar->setVisible(showBookmarksBar); - updateBookmarksToolbarActionText(showBookmarksBar); + menuBar()->setVisible(showMenuBar); + m_menuBarVisible = showMenuBar; statusBar()->setVisible(showStatusbar); - updateStatusbarActionText(showStatusbar); m_navigationSplitter->restoreState(splitterState); - if (!tabState.isEmpty() && !tabWidget()->restoreState(tabState)) - return false; + tabWidget()->restoreState(tabState); m_tabWidget->tabBar()->setShowTabBarWhenOneTab(showTabBarWhenOneTab); + if (qMainWindowState.isEmpty()) { + m_navigationBar->setVisible(showToolbarDEAD); + m_bookmarksToolbar->setVisible(showBookmarksBarDEAD); + Qt::ToolBarArea navigationArea = Qt::ToolBarArea(navigationBarLocation); + if (navigationArea != Qt::TopToolBarArea && navigationArea != Qt::NoToolBarArea) + addToolBar(navigationArea, m_navigationBar); + Qt::ToolBarArea bookmarkArea = Qt::ToolBarArea(bookmarkBarLocation); + if (bookmarkArea != Qt::TopToolBarArea && bookmarkArea != Qt::NoToolBarArea) + addToolBar(bookmarkArea, m_bookmarksToolbar); + } else { + QMainWindow::restoreState(qMainWindowState); + } + +#if defined(Q_WS_MAC) + m_bookmarksToolbarFrame->setVisible(m_bookmarksToolbar->isVisible()); +#endif + return true; } +void BrowserMainWindow::lastTabClosed() +{ + QSettings settings; + settings.beginGroup(QLatin1String("tabs")); + bool quit = settings.value(QLatin1String("quitAsLastTabClosed"), true).toBool(); + + if (quit) + close(); + else + m_tabWidget->makeNewTab(true); +} + +QAction *BrowserMainWindow::showMenuBarAction() const +{ + return m_viewShowMenuBarAction; +} + void BrowserMainWindow::setupMenu() { - new QShortcut(QKeySequence(Qt::Key_F6), this, SLOT(slotSwapFocus())); + m_menuBarVisible = true; + + new QShortcut(QKeySequence(Qt::Key_F6), this, SLOT(swapFocus())); // File - QMenu *fileMenu = menuBar()->addMenu(tr("&File")); - - fileMenu->addAction(tr("&New Window"), this, SLOT(slotFileNew()), QKeySequence::New); - fileMenu->addAction(m_tabWidget->newTabAction()); - fileMenu->addAction(tr("&Open File..."), this, SLOT(slotFileOpen()), QKeySequence::Open); - fileMenu->addAction(tr("Open &Location..."), this, - SLOT(slotSelectLineEdit()), QKeySequence(Qt::ControlModifier + Qt::Key_L)); - fileMenu->addSeparator(); - fileMenu->addAction(m_tabWidget->closeTabAction()); - fileMenu->addSeparator(); - fileMenu->addAction(tr("&Save As..."), this, - SLOT(slotFileSaveAs()), QKeySequence(QKeySequence::Save)); - fileMenu->addSeparator(); - BookmarksManager *bookmarksManager = BrowserApplication::bookmarksManager(); - fileMenu->addAction(tr("&Import Bookmarks..."), bookmarksManager, SLOT(importBookmarks())); - fileMenu->addAction(tr("&Export Bookmarks..."), bookmarksManager, SLOT(exportBookmarks())); - fileMenu->addSeparator(); - fileMenu->addAction(tr("P&rint Preview..."), this, SLOT(slotFilePrintPreview())); - fileMenu->addAction(tr("&Print..."), this, SLOT(slotFilePrint()), QKeySequence::Print); - fileMenu->addSeparator(); - m_privateBrowsing = fileMenu->addAction(tr("Private &Browsing..."), this, SLOT(slotPrivateBrowsing())); - m_privateBrowsing->setCheckable(true); - fileMenu->addSeparator(); + m_fileMenu = new QMenu(menuBar()); + menuBar()->addMenu(m_fileMenu); + + m_fileNewWindowAction = new QAction(m_fileMenu); + m_fileNewWindowAction->setShortcut(QKeySequence::New); + connect(m_fileNewWindowAction, SIGNAL(triggered()), + this, SLOT(fileNew())); + m_fileMenu->addAction(m_fileNewWindowAction); + m_fileMenu->addAction(m_tabWidget->newTabAction()); + + m_fileOpenFileAction = new QAction(m_fileMenu); + m_fileOpenFileAction->setShortcut(QKeySequence::Open); + connect(m_fileOpenFileAction, SIGNAL(triggered()), + this, SLOT(fileOpen())); + m_fileMenu->addAction(m_fileOpenFileAction); + + m_fileOpenLocationAction = new QAction(m_fileMenu); + // Add the location bar shortcuts familiar to users from other browsers + QList openLocationShortcuts; + openLocationShortcuts.append(QKeySequence(Qt::ControlModifier + Qt::Key_L)); + openLocationShortcuts.append(QKeySequence(Qt::AltModifier + Qt::Key_O)); + openLocationShortcuts.append(QKeySequence(Qt::AltModifier + Qt::Key_D)); + m_fileOpenLocationAction->setShortcuts(openLocationShortcuts); + connect(m_fileOpenLocationAction, SIGNAL(triggered()), + this, SLOT(selectLineEdit())); + m_fileMenu->addAction(m_fileOpenLocationAction); + + m_fileMenu->addSeparator(); + m_fileMenu->addAction(m_tabWidget->closeTabAction()); + m_fileMenu->addSeparator(); + + m_fileSaveAsAction = new QAction(m_fileMenu); + m_fileSaveAsAction->setShortcut(QKeySequence::Save); + connect(m_fileSaveAsAction, SIGNAL(triggered()), + this, SLOT(fileSaveAs())); + m_fileMenu->addAction(m_fileSaveAsAction); + m_fileMenu->addSeparator(); -#if defined(Q_WS_MAC) - fileMenu->addAction(tr("&Quit"), BrowserApplication::instance(), SLOT(quitBrowser()), QKeySequence(Qt::CTRL | Qt::Key_Q)); -#else - fileMenu->addAction(tr("&Quit"), this, SLOT(close()), QKeySequence(Qt::CTRL | Qt::Key_Q)); + BookmarksManager *bookmarksManager = BrowserApplication::bookmarksManager(); + m_fileImportBookmarksAction = new QAction(m_fileMenu); + connect(m_fileImportBookmarksAction, SIGNAL(triggered()), + bookmarksManager, SLOT(importBookmarks())); + m_fileMenu->addAction(m_fileImportBookmarksAction); + m_fileExportBookmarksAction = new QAction(m_fileMenu); + connect(m_fileExportBookmarksAction, SIGNAL(triggered()), + bookmarksManager, SLOT(exportBookmarks())); + m_fileMenu->addAction(m_fileExportBookmarksAction); + m_fileMenu->addSeparator(); + + m_filePrintPreviewAction= new QAction(m_fileMenu); + connect(m_filePrintPreviewAction, SIGNAL(triggered()), + this, SLOT(filePrintPreview())); + m_fileMenu->addAction(m_filePrintPreviewAction); + + m_filePrintAction = new QAction(m_fileMenu); + m_filePrintAction->setShortcut(QKeySequence::Print); + connect(m_filePrintAction, SIGNAL(triggered()), + this, SLOT(filePrint())); + m_fileMenu->addAction(m_filePrintAction); + m_fileMenu->addSeparator(); + + m_filePrivateBrowsingAction = new QAction(m_fileMenu); + connect(m_filePrivateBrowsingAction, SIGNAL(triggered()), + this, SLOT(privateBrowsing())); + m_filePrivateBrowsingAction->setCheckable(true); + m_fileMenu->addAction(m_filePrivateBrowsingAction); + m_fileMenu->addSeparator(); + + m_fileCloseWindow = new QAction(m_fileMenu); + connect(m_fileCloseWindow, SIGNAL(triggered()), this, SLOT(close())); + m_fileCloseWindow->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_W)); + m_fileMenu->addAction(m_fileCloseWindow); + + m_fileQuit = new QAction(m_fileMenu); + int kdeSessionVersion = QString::fromLocal8Bit(qgetenv("KDE_SESSION_VERSION")).toInt(); + if (kdeSessionVersion != 0) + connect(m_fileQuit, SIGNAL(triggered()), this, SLOT(close())); + else + connect(m_fileQuit, SIGNAL(triggered()), BrowserApplication::instance(), SLOT(quitBrowser())); + m_fileQuit->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_Q)); + m_fileMenu->addAction(m_fileQuit); + +#if QT_VERSION >= 0x040600 && defined(Q_WS_X11) + m_fileNewWindowAction->setIcon(QIcon::fromTheme(QLatin1String("window-new"))); + m_fileOpenFileAction->setIcon(QIcon::fromTheme(QLatin1String("document-open"))); + m_filePrintPreviewAction->setIcon(QIcon::fromTheme(QLatin1String("document-print-preview"))); + m_filePrintAction->setIcon(QIcon::fromTheme(QLatin1String("document-print"))); + m_fileSaveAsAction->setIcon(QIcon::fromTheme(QLatin1String("document-save-as"))); + m_fileCloseWindow->setIcon(QIcon::fromTheme(QLatin1String("window-close"))); + m_fileQuit->setIcon(QIcon::fromTheme(QLatin1String("application-exit"))); #endif // Edit - QMenu *editMenu = menuBar()->addMenu(tr("&Edit")); - QAction *m_undo = editMenu->addAction(tr("&Undo")); - m_undo->setShortcuts(QKeySequence::Undo); - m_tabWidget->addWebAction(m_undo, QWebPage::Undo); - QAction *m_redo = editMenu->addAction(tr("&Redo")); - m_redo->setShortcuts(QKeySequence::Redo); - m_tabWidget->addWebAction(m_redo, QWebPage::Redo); - editMenu->addSeparator(); - QAction *m_cut = editMenu->addAction(tr("Cu&t")); - m_cut->setShortcuts(QKeySequence::Cut); - m_tabWidget->addWebAction(m_cut, QWebPage::Cut); - QAction *m_copy = editMenu->addAction(tr("&Copy")); - m_copy->setShortcuts(QKeySequence::Copy); - m_tabWidget->addWebAction(m_copy, QWebPage::Copy); - QAction *m_paste = editMenu->addAction(tr("&Paste")); - m_paste->setShortcuts(QKeySequence::Paste); - m_tabWidget->addWebAction(m_paste, QWebPage::Paste); - editMenu->addSeparator(); - - QAction *m_find = editMenu->addAction(tr("&Find")); - m_find->setShortcuts(QKeySequence::Find); - connect(m_find, SIGNAL(triggered()), this, SLOT(slotEditFind())); - new QShortcut(QKeySequence(Qt::Key_Slash), this, SLOT(slotEditFind())); - - QAction *m_findNext = editMenu->addAction(tr("&Find Next")); - m_findNext->setShortcuts(QKeySequence::FindNext); - connect(m_findNext, SIGNAL(triggered()), this, SLOT(slotEditFindNext())); - - QAction *m_findPrevious = editMenu->addAction(tr("&Find Previous")); - m_findPrevious->setShortcuts(QKeySequence::FindPrevious); - connect(m_findPrevious, SIGNAL(triggered()), this, SLOT(slotEditFindPrevious())); - - editMenu->addSeparator(); - editMenu->addAction(tr("&Preferences"), this, SLOT(slotPreferences()), tr("Ctrl+,")); + m_editMenu = new QMenu(menuBar()); + menuBar()->addMenu(m_editMenu); + m_editUndoAction = new QAction(m_editMenu); + m_editUndoAction->setShortcuts(QKeySequence::Undo); + m_tabWidget->addWebAction(m_editUndoAction, QWebPage::Undo); + m_editMenu->addAction(m_editUndoAction); + m_editRedoAction = new QAction(m_editMenu); + m_editRedoAction->setShortcuts(QKeySequence::Redo); + m_tabWidget->addWebAction(m_editRedoAction, QWebPage::Redo); + m_editMenu->addAction(m_editRedoAction); + m_editMenu->addSeparator(); + m_editCutAction = new QAction(m_editMenu); + m_editCutAction->setShortcuts(QKeySequence::Cut); + m_tabWidget->addWebAction(m_editCutAction, QWebPage::Cut); + m_editMenu->addAction(m_editCutAction); + m_editCopyAction = new QAction(m_editMenu); + m_editCopyAction->setShortcuts(QKeySequence::Copy); + m_tabWidget->addWebAction(m_editCopyAction, QWebPage::Copy); + m_editMenu->addAction(m_editCopyAction); + m_editPasteAction = new QAction(m_editMenu); + m_editPasteAction->setShortcuts(QKeySequence::Paste); + m_tabWidget->addWebAction(m_editPasteAction, QWebPage::Paste); + m_editMenu->addAction(m_editPasteAction); + m_editSelectAllAction = new QAction(m_editMenu); + m_editSelectAllAction->setShortcuts(QKeySequence::SelectAll); + m_tabWidget->addWebAction(m_editSelectAllAction, QWebPage::SelectAll); + m_editMenu->addAction(m_editSelectAllAction); + m_editMenu->addSeparator(); + + m_editFindAction = new QAction(m_editMenu); + m_editFindAction->setShortcuts(QKeySequence::Find); + connect(m_editFindAction, SIGNAL(triggered()), this, SLOT(editFind())); + m_editMenu->addAction(m_editFindAction); + new QShortcut(QKeySequence(Qt::Key_Slash), this, SLOT(editFind())); + + m_editFindNextAction = new QAction(m_editMenu); + m_editFindNextAction->setShortcuts(QKeySequence::FindNext); + connect(m_editFindNextAction, SIGNAL(triggered()), this, SLOT(editFindNext())); + m_editMenu->addAction(m_editFindNextAction); + + m_editFindPreviousAction = new QAction(m_editMenu); + m_editFindPreviousAction->setShortcuts(QKeySequence::FindPrevious); + connect(m_editFindPreviousAction, SIGNAL(triggered()), this, SLOT(editFindPrevious())); + m_editMenu->addAction(m_editFindPreviousAction); + +#if QT_VERSION >= 0x040600 && defined(Q_WS_X11) + m_editUndoAction->setIcon(QIcon::fromTheme(QLatin1String("edit-undo"))); + m_editRedoAction->setIcon(QIcon::fromTheme(QLatin1String("edit-redo"))); + m_editCutAction->setIcon(QIcon::fromTheme(QLatin1String("edit-cut"))); + m_editCopyAction->setIcon(QIcon::fromTheme(QLatin1String("edit-copy"))); + m_editPasteAction->setIcon(QIcon::fromTheme(QLatin1String("edit-paste"))); + m_editSelectAllAction->setIcon(QIcon::fromTheme(QLatin1String("edit-select-all"))); + m_editFindAction->setIcon(QIcon::fromTheme(QLatin1String("edit-find"))); +#endif // View - QMenu *viewMenu = menuBar()->addMenu(tr("&View")); - new QShortcut(QKeySequence("Ctrl+m"), this, SLOT(slotViewMenuBar())); + m_viewMenu = new QMenu(menuBar()); + connect(m_viewMenu, SIGNAL(aboutToShow()), + this, SLOT(aboutToShowViewMenu())); + menuBar()->addMenu(m_viewMenu); - m_viewToolbar = new QAction(this); - updateToolbarActionText(true); - m_viewToolbar->setShortcut(tr("Ctrl+|")); - connect(m_viewToolbar, SIGNAL(triggered()), this, SLOT(slotViewToolbar())); - viewMenu->addAction(m_viewToolbar); + m_viewShowMenuBarAction = new QAction(m_viewMenu); + m_viewShowMenuBarAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_M)); + connect(m_viewShowMenuBarAction, SIGNAL(triggered()), this, SLOT(viewMenuBar())); + addAction(m_viewShowMenuBarAction); - m_viewBookmarkBar = new QAction(this); - updateBookmarksToolbarActionText(true); - m_viewBookmarkBar->setShortcut(tr("Shift+Ctrl+B")); - connect(m_viewBookmarkBar, SIGNAL(triggered()), this, SLOT(slotViewBookmarksBar())); - viewMenu->addAction(m_viewBookmarkBar); + m_viewToolbarAction = new QAction(this); + connect(m_viewToolbarAction, SIGNAL(triggered()), this, SLOT(viewToolbar())); + m_viewMenu->addAction(m_viewToolbarAction); + + m_viewBookmarkBarAction = new QAction(m_viewMenu); + connect(m_viewBookmarkBarAction, SIGNAL(triggered()), this, SLOT(viewBookmarksBar())); + m_viewMenu->addAction(m_viewBookmarkBarAction); QAction *viewTabBarAction = m_tabWidget->tabBar()->viewTabBarAction(); - viewMenu->addAction(viewTabBarAction); - connect(viewTabBarAction, SIGNAL(changed()), + m_viewMenu->addAction(viewTabBarAction); + connect(viewTabBarAction, SIGNAL(toggled(bool)), m_autoSaver, SLOT(changeOccurred())); - m_viewStatusbar = new QAction(this); - updateStatusbarActionText(true); - m_viewStatusbar->setShortcut(tr("Ctrl+/")); - connect(m_viewStatusbar, SIGNAL(triggered()), this, SLOT(slotViewStatusbar())); - viewMenu->addAction(m_viewStatusbar); + m_viewStatusbarAction = new QAction(m_viewMenu); + connect(m_viewStatusbarAction, SIGNAL(triggered()), this, SLOT(viewStatusbar())); + m_viewMenu->addAction(m_viewStatusbarAction); - viewMenu->addSeparator(); + m_viewMenu->addSeparator(); - m_stop = viewMenu->addAction(tr("&Stop")); + m_viewStopAction = new QAction(m_viewMenu); QList shortcuts; shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Period)); shortcuts.append(Qt::Key_Escape); - m_stop->setShortcuts(shortcuts); - m_tabWidget->addWebAction(m_stop, QWebPage::Stop); - - m_reload = viewMenu->addAction(tr("Reload Page")); - m_reload->setShortcuts(QKeySequence::Refresh); - m_tabWidget->addWebAction(m_reload, QWebPage::Reload); - - viewMenu->addAction(tr("&Make Text Bigger"), this, SLOT(slotViewTextBigger()), QKeySequence(Qt::CTRL | Qt::Key_Plus)); - viewMenu->addAction(tr("&Make Text Normal"), this, SLOT(slotViewTextNormal()), QKeySequence(Qt::CTRL | Qt::Key_0)); - viewMenu->addAction(tr("&Make Text Smaller"), this, SLOT(slotViewTextSmaller()), QKeySequence(Qt::CTRL | Qt::Key_Minus)); + m_viewStopAction->setShortcuts(shortcuts); + m_tabWidget->addWebAction(m_viewStopAction, QWebPage::Stop); + m_viewMenu->addAction(m_viewStopAction); + + m_viewReloadAction = new QAction(m_viewMenu); + shortcuts.clear(); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_R)); + shortcuts.append(QKeySequence(Qt::Key_F5)); + m_viewReloadAction->setShortcuts(shortcuts); + m_tabWidget->addWebAction(m_viewReloadAction, QWebPage::Reload); + m_viewMenu->addAction(m_viewReloadAction); + + m_viewZoomInAction = new QAction(m_viewMenu); + shortcuts.clear(); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Plus)); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Equal)); + m_viewZoomInAction->setShortcuts(shortcuts); + connect(m_viewZoomInAction, SIGNAL(triggered()), + this, SLOT(zoomIn())); + m_viewMenu->addAction(m_viewZoomInAction); + + m_viewZoomNormalAction = new QAction(m_viewMenu); + m_viewZoomNormalAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_0)); + connect(m_viewZoomNormalAction, SIGNAL(triggered()), + this, SLOT(zoomNormal())); + m_viewMenu->addAction(m_viewZoomNormalAction); + + m_viewZoomOutAction = new QAction(m_viewMenu); + shortcuts.clear(); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Minus)); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Underscore)); + m_viewZoomOutAction->setShortcuts(shortcuts); + connect(m_viewZoomOutAction, SIGNAL(triggered()), + this, SLOT(zoomOut())); + m_viewMenu->addAction(m_viewZoomOutAction); + + m_viewZoomTextOnlyAction = new QAction(m_viewMenu); + m_viewZoomTextOnlyAction->setCheckable(true); + connect(m_viewZoomTextOnlyAction, SIGNAL(toggled(bool)), + BrowserApplication::instance(), SLOT(setZoomTextOnly(bool))); + connect(BrowserApplication::instance(), SIGNAL(zoomTextOnlyChanged(bool)), + this, SLOT(zoomTextOnlyChanged(bool))); + m_viewMenu->addAction(m_viewZoomTextOnlyAction); + + m_viewFullScreenAction = new QAction(m_viewMenu); + m_viewFullScreenAction->setShortcut(Qt::Key_F11); + connect(m_viewFullScreenAction, SIGNAL(triggered(bool)), + this, SLOT(viewFullScreen(bool))); + m_viewFullScreenAction->setCheckable(true); + m_viewMenu->addAction(m_viewFullScreenAction); + + + m_viewMenu->addSeparator(); + + m_viewSourceAction = new QAction(m_viewMenu); + connect(m_viewSourceAction, SIGNAL(triggered()), + this, SLOT(viewPageSource())); + m_viewMenu->addAction(m_viewSourceAction); + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + m_viewMenu->addSeparator(); + + m_viewTextEncodingAction = new QAction(m_viewMenu); + m_viewMenu->addAction(m_viewTextEncodingAction); + m_viewTextEncodingMenu = new QMenu(m_viewMenu); + m_viewTextEncodingAction->setMenu(m_viewTextEncodingMenu); + connect(m_viewTextEncodingMenu, SIGNAL(aboutToShow()), + this, SLOT(aboutToShowTextEncodingMenu())); + connect(m_viewTextEncodingMenu, SIGNAL(triggered(QAction *)), + this, SLOT(viewTextEncoding(QAction *))); +#endif - viewMenu->addSeparator(); - viewMenu->addAction(tr("Page S&ource"), this, SLOT(slotViewPageSource()), tr("Ctrl+Alt+U")); - QAction *a = viewMenu->addAction(tr("&Full Screen"), this, SLOT(slotViewFullScreen(bool)), Qt::Key_F11); - a->setCheckable(true); + m_stopIcon = style()->standardIcon(QStyle::SP_BrowserStop); + m_reloadIcon = style()->standardIcon(QStyle::SP_BrowserReload); +#if QT_VERSION >= 0x040600 && defined(Q_WS_X11) + m_viewStopAction->setIcon(m_stopIcon); + m_viewReloadAction->setIcon(m_reloadIcon); + m_viewZoomInAction->setIcon(QIcon::fromTheme(QLatin1String("zoom-in"))); + m_viewZoomNormalAction->setIcon(QIcon::fromTheme(QLatin1String("zoom-original"))); + m_viewZoomOutAction->setIcon(QIcon::fromTheme(QLatin1String("zoom-out"))); + m_viewFullScreenAction->setIcon(QIcon::fromTheme(QLatin1String("view-fullscreen"))); +#endif // History - HistoryMenu *historyMenu = new HistoryMenu(this); - connect(historyMenu, SIGNAL(openUrl(const QUrl&)), - m_tabWidget, SLOT(loadUrl(const QUrl&))); - historyMenu->setTitle(tr("Hi&story")); - menuBar()->addMenu(historyMenu); + m_historyMenu = new HistoryMenu(this); + connect(m_historyMenu, SIGNAL(openUrl(const QUrl&, const QString&)), + m_tabWidget, SLOT(loadUrlFromUser(const QUrl&, const QString&))); + menuBar()->addMenu(m_historyMenu); QList historyActions; - m_historyBack = new QAction(tr("Back"), this); - m_tabWidget->addWebAction(m_historyBack, QWebPage::Back); - m_historyBack->setShortcuts(QKeySequence::Back); - m_historyBack->setIconVisibleInMenu(false); + m_historyBackAction = new QAction(this); + m_tabWidget->addWebAction(m_historyBackAction, QWebPage::Back); + m_historyBackAction->setShortcuts(QKeySequence::Back); +#if QT_VERSION < 0x040600 || (QT_VERSION >= 0x040600 && !defined(Q_WS_X11)) + m_historyBackAction->setIconVisibleInMenu(false); +#endif - m_historyForward = new QAction(tr("Forward"), this); - m_tabWidget->addWebAction(m_historyForward, QWebPage::Forward); - m_historyForward->setShortcuts(QKeySequence::Forward); - m_historyForward->setIconVisibleInMenu(false); + m_historyForwardAction = new QAction(this); + m_tabWidget->addWebAction(m_historyForwardAction, QWebPage::Forward); + m_historyForwardAction->setShortcuts(QKeySequence::Forward); +#if QT_VERSION < 0x040600 || (QT_VERSION >= 0x040600 && !defined(Q_WS_X11)) + m_historyForwardAction->setIconVisibleInMenu(false); +#endif - QAction *m_historyHome = new QAction(tr("Home"), this); - connect(m_historyHome, SIGNAL(triggered()), this, SLOT(slotHome())); - m_historyHome->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H)); + m_historyHomeAction = new QAction(this); + connect(m_historyHomeAction, SIGNAL(triggered()), this, SLOT(goHome())); + m_historyHomeAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_H)); - m_restoreLastSession = new QAction(tr("Restore Last Session"), this); - connect(m_restoreLastSession, SIGNAL(triggered()), BrowserApplication::instance(), SLOT(restoreLastSession())); - m_restoreLastSession->setEnabled(BrowserApplication::instance()->canRestoreSession()); + m_historyRestoreLastSessionAction = new QAction(this); + connect(m_historyRestoreLastSessionAction, SIGNAL(triggered()), + BrowserApplication::instance(), SLOT(restoreLastSession())); + m_historyRestoreLastSessionAction->setEnabled(BrowserApplication::instance()->canRestoreSession()); - historyActions.append(m_historyBack); - historyActions.append(m_historyForward); - historyActions.append(m_historyHome); + historyActions.append(m_historyBackAction); + historyActions.append(m_historyForwardAction); + historyActions.append(m_historyHomeAction); historyActions.append(m_tabWidget->recentlyClosedTabsAction()); - historyActions.append(m_restoreLastSession); - historyMenu->setInitialActions(historyActions); + historyActions.append(m_historyRestoreLastSessionAction); + m_historyMenu->setInitialActions(historyActions); +#if QT_VERSION >= 0x040600 && defined(Q_WS_X11) + m_historyRestoreLastSessionAction->setIcon(QIcon::fromTheme(QLatin1String("document-revert"))); + m_historyHomeAction->setIcon(QIcon::fromTheme(QLatin1String("go-home"))); +#endif // Bookmarks - BookmarksMenu *bookmarksMenu = new BookmarksMenu(this); - connect(bookmarksMenu, SIGNAL(openUrl(const QUrl&, TabWidget::Tab, const QString &)), - m_tabWidget, SLOT(loadUrl(const QUrl&, TabWidget::Tab, const QString&))); - bookmarksMenu->setTitle(tr("&Bookmarks")); - menuBar()->addMenu(bookmarksMenu); + m_bookmarksMenu = new BookmarksMenuBarMenu(this); + connect(m_bookmarksMenu, SIGNAL(openUrl(const QUrl&, const QString &)), + m_tabWidget, SLOT(loadUrlFromUser(const QUrl&, const QString&))); + connect(m_bookmarksMenu, SIGNAL(openUrl(const QUrl&, TabWidget::OpenUrlIn, const QString&)), + m_tabWidget, SLOT(loadUrl(const QUrl&, TabWidget::OpenUrlIn, const QString&))); + menuBar()->addMenu(m_bookmarksMenu); + + m_bookmarksShowAllAction = new QAction(this); + m_bookmarksShowAllAction->setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_B)); + connect(m_bookmarksShowAllAction, SIGNAL(triggered()), + this, SLOT(showBookmarksDialog())); + + m_bookmarksAddAction = new QAction(this); + m_bookmarksAddAction->setIcon(QIcon(QLatin1String(":addbookmark.png"))); +#if QT_VERSION < 0x040600 || (QT_VERSION >= 0x040600 && !defined(Q_WS_X11)) + m_bookmarksAddAction->setIconVisibleInMenu(false); +#endif + connect(m_bookmarksAddAction, SIGNAL(triggered()), + this, SLOT(addBookmark())); + m_bookmarksAddAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D)); + + m_bookmarksAddFolderAction = new QAction(this); + connect(m_bookmarksAddFolderAction, SIGNAL(triggered()), + this, SLOT(addBookmarkFolder())); QList bookmarksActions; + bookmarksActions.append(m_bookmarksShowAllAction); + bookmarksActions.append(m_bookmarksAddAction); + bookmarksActions.append(tabWidget()->bookmarkTabsAction()); + bookmarksActions.append(m_bookmarksAddFolderAction); + m_bookmarksMenu->setInitialActions(bookmarksActions); + +#if QT_VERSION >= 0x040600 + m_bookmarksAddFolderAction->setIcon(QIcon::fromTheme(QLatin1String("folder-new"))); + m_bookmarksShowAllAction->setIcon(QIcon::fromTheme(QLatin1String("user-bookmarks"))); +#endif - QAction *showAllBookmarksAction = new QAction(tr("Manage Bookmarks..."), this); - connect(showAllBookmarksAction, SIGNAL(triggered()), this, SLOT(slotShowBookmarksDialog())); - m_addBookmark = new QAction(QIcon(QLatin1String(":addbookmark.png")), tr("Add Bookmark..."), this); - m_addBookmark->setIconVisibleInMenu(false); + // Window + m_windowMenu = new QMenu(menuBar()); + menuBar()->addMenu(m_windowMenu); + connect(m_windowMenu, SIGNAL(aboutToShow()), + this, SLOT(aboutToShowWindowMenu())); + aboutToShowWindowMenu(); + + // Tools + m_toolsMenu = new QMenu(menuBar()); + menuBar()->addMenu(m_toolsMenu); + + m_toolsWebSearchAction = new QAction(m_toolsMenu); + connect(m_toolsWebSearchAction, SIGNAL(triggered()), + this, SLOT(webSearch())); + m_toolsMenu->addAction(m_toolsWebSearchAction); + + m_toolsClearPrivateDataAction = new QAction(m_toolsMenu); + connect(m_toolsClearPrivateDataAction, SIGNAL(triggered()), + this, SLOT(clearPrivateData())); + m_toolsMenu->addAction(m_toolsClearPrivateDataAction); + + m_toolsEnableInspectorAction = new QAction(m_toolsMenu); + connect(m_toolsEnableInspectorAction, SIGNAL(triggered(bool)), + this, SLOT(toggleInspector(bool))); + m_toolsEnableInspectorAction->setCheckable(true); + QSettings settings; + settings.beginGroup(QLatin1String("websettings")); + m_toolsEnableInspectorAction->setChecked(settings.value(QLatin1String("enableInspector"), false).toBool()); + m_toolsMenu->addAction(m_toolsEnableInspectorAction); + + m_toolsSearchManagerAction = new QAction(m_toolsMenu); + m_toolsSearchManagerAction->setMenuRole(QAction::NoRole); + connect(m_toolsSearchManagerAction, SIGNAL(triggered()), + this, SLOT(showSearchDialog())); + m_toolsMenu->addAction(m_toolsSearchManagerAction); + + m_toolsUserAgentMenu = new UserAgentMenu(m_toolsMenu); + m_toolsMenu->addMenu(m_toolsUserAgentMenu); + + m_adBlockDialogAction = new QAction(m_toolsMenu); + connect(m_adBlockDialogAction, SIGNAL(triggered()), + AdBlockManager::instance(), SLOT(showDialog())); + m_toolsMenu->addAction(m_adBlockDialogAction); + + m_toolsMenu->addSeparator(); + m_toolsPreferencesAction = new QAction(m_toolsMenu); + m_toolsPreferencesAction->setMenuRole(QAction::PreferencesRole); + connect(m_toolsPreferencesAction, SIGNAL(triggered()), + this, SLOT(preferences())); + m_toolsMenu->addAction(m_toolsPreferencesAction); + + // Help + m_helpMenu = new QMenu(menuBar()); + menuBar()->addMenu(m_helpMenu); + + m_helpChangeLanguageAction = new QAction(m_helpMenu); + connect(m_helpChangeLanguageAction, SIGNAL(triggered()), + BrowserApplication::languageManager(), SLOT(chooseNewLanguage())); + m_helpMenu->addAction(m_helpChangeLanguageAction); + m_helpMenu->addSeparator(); + + m_helpAboutQtAction = new QAction(m_helpMenu); + connect(m_helpAboutQtAction, SIGNAL(triggered()), + qApp, SLOT(aboutQt())); + m_helpMenu->addAction(m_helpAboutQtAction); + + m_helpAboutApplicationAction = new QAction(m_helpMenu); + connect(m_helpAboutApplicationAction, SIGNAL(triggered()), + this, SLOT(aboutApplication())); + m_helpMenu->addAction(m_helpAboutApplicationAction); + +#if QT_VERSION >= 0x040600 && defined(Q_WS_X11) + m_helpChangeLanguageAction->setIcon(QIcon::fromTheme(QLatin1String("preferences-desktop-locale"))); + m_helpAboutQtAction->setIcon(QPixmap(QLatin1String(":/trolltech/qmessagebox/images/qtlogo-64.png"))); + m_helpAboutApplicationAction->setIcon(windowIcon()); +#endif +} - connect(m_addBookmark, SIGNAL(triggered()), this, SLOT(slotAddBookmark())); - m_addBookmark->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_D)); +void BrowserMainWindow::aboutToShowViewMenu() +{ + m_viewToolbarAction->setText(m_navigationBar->isVisible() ? tr("Hide Toolbar") : tr("Show Toolbar")); + m_viewBookmarkBarAction->setText(m_bookmarksToolbar->isVisible() ? tr("Hide Bookmarks Bar") : tr("Show Bookmarks Bar")); + m_viewStatusbarAction->setText(statusBar()->isVisible() ? tr("Hide Status Bar") : tr("Show Status Bar")); +} - bookmarksActions.append(showAllBookmarksAction); - bookmarksActions.append(m_addBookmark); - bookmarksMenu->setInitialActions(bookmarksActions); +void BrowserMainWindow::aboutToShowTextEncodingMenu() +{ +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + m_viewTextEncodingMenu->clear(); + + int currentCodec = -1; + QStringList codecs; + QList mibs = QTextCodec::availableMibs(); + foreach (const int &mib, mibs) { + QString codec = QLatin1String(QTextCodec::codecForMib(mib)->name()); + codecs.append(codec); + } + codecs.sort(); + + QString defaultTextEncoding = QWebSettings::globalSettings()->defaultTextEncoding(); + currentCodec = codecs.indexOf(defaultTextEncoding); + + QAction *defaultEncoding = m_viewTextEncodingMenu->addAction(tr("Default")); + defaultEncoding->setData(QString()); + defaultEncoding->setCheckable(true); + if (currentCodec == -1) + defaultEncoding->setChecked(true); + m_viewTextEncodingMenu->addSeparator(); + + for (int i = 0; i < codecs.count(); ++i) { + const QString &codec = codecs.at(i); + QAction *action = m_viewTextEncodingMenu->addAction(codec); + action->setData(codec); + action->setCheckable(true); + if (currentCodec == i) + action->setChecked(true); + } +#endif +} - // Window - m_windowMenu = menuBar()->addMenu(tr("&Window")); - connect(m_windowMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowWindowMenu())); - slotAboutToShowWindowMenu(); - - QMenu *toolsMenu = menuBar()->addMenu(tr("&Tools")); - toolsMenu->addAction(tr("Web &Search"), this, SLOT(slotWebSearch()), - QKeySequence(tr("Ctrl+K", "Web Search"))); - toolsMenu->addAction(tr("&Clear Private Data"), this, SLOT(slotClearPrivateData()), - QKeySequence(tr("Ctrl+Shift+Delete", "Clear Private Data"))); -#ifndef Q_CC_MINGW - a = toolsMenu->addAction(tr("Enable Web &Inspector"), this, SLOT(slotToggleInspector(bool))); - a->setCheckable(true); +void BrowserMainWindow::viewTextEncoding(QAction *action) +{ + Q_UNUSED(action); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + Q_ASSERT(action); + QString codec = action->data().toString(); + if (codec.isEmpty()) + QWebSettings::globalSettings()->setDefaultTextEncoding(QString()); + else + QWebSettings::globalSettings()->setDefaultTextEncoding(codec); #endif +} - QMenu *helpMenu = menuBar()->addMenu(tr("&Help")); - helpMenu->addAction(tr("About &Qt"), qApp, SLOT(aboutQt())); - helpMenu->addAction(tr("About &Arora"), this, SLOT(slotAboutApplication())); +void BrowserMainWindow::retranslate() +{ + m_fileMenu->setTitle(tr("&File")); + m_fileNewWindowAction->setText(tr("&New Window")); + m_fileOpenFileAction->setText(tr("&Open File...")); + m_fileOpenLocationAction->setText(tr("Open &Location...")); + m_fileSaveAsAction->setText(tr("&Save As...")); + m_fileImportBookmarksAction->setText(tr("&Import Bookmarks...")); + m_fileExportBookmarksAction->setText(tr("&Export Bookmarks...")); + m_filePrintPreviewAction->setText(tr("P&rint Preview...")); + m_filePrintAction->setText(tr("&Print...")); + m_filePrivateBrowsingAction->setText(tr("Private &Browsing...")); + m_fileCloseWindow->setText(tr("Close Window")); + m_fileQuit->setText(tr("&Quit")); + + m_editMenu->setTitle(tr("&Edit")); + m_editUndoAction->setText(tr("&Undo")); + m_editRedoAction->setText(tr("&Redo")); + m_editCutAction->setText(tr("Cu&t")); + m_editCopyAction->setText(tr("&Copy")); + m_editPasteAction->setText(tr("&Paste")); + m_editSelectAllAction->setText(tr("Select &All")); + m_editFindAction->setText(tr("&Find")); + m_editFindNextAction->setText(tr("Find Nex&t")); + m_editFindPreviousAction->setText(tr("Find P&revious")); + + m_viewMenu->setTitle(tr("&View")); + m_viewToolbarAction->setShortcut(tr("Ctrl+|")); + m_viewBookmarkBarAction->setShortcut(tr("Alt+Ctrl+B")); + m_viewStatusbarAction->setShortcut(tr("Ctrl+/")); + m_viewShowMenuBarAction->setText(tr("Show Menu Bar")); + m_viewReloadAction->setText(tr("&Reload Page")); + m_viewStopAction->setText(tr("&Stop")); + m_viewZoomInAction->setText(tr("Zoom &In")); + m_viewZoomNormalAction->setText(tr("Zoom &Normal")); + m_viewZoomOutAction->setText(tr("Zoom &Out")); + m_viewZoomTextOnlyAction->setText(tr("Zoom &Text Only")); + m_viewSourceAction->setText(tr("Page S&ource")); + m_viewSourceAction->setShortcut(tr("Ctrl+Alt+U")); + m_viewFullScreenAction->setText(tr("&Full Screen")); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + m_viewTextEncodingAction->setText(tr("Text Encoding")); +#endif + + m_historyMenu->setTitle(tr("Hi&story")); + m_historyBackAction->setText(tr("Back")); + m_historyForwardAction->setText(tr("Forward")); + m_historyHomeAction->setText(tr("Home")); + m_historyRestoreLastSessionAction->setText(tr("Restore Last Session")); + + m_bookmarksMenu->setTitle(tr("&Bookmarks")); + m_bookmarksShowAllAction->setText(tr("Show All Bookmarks...")); + m_bookmarksAddAction->setText(tr("Add Bookmark...")); + m_bookmarksAddFolderAction->setText(tr("Add Folder...")); + + m_windowMenu->setTitle(tr("&Window")); + + m_toolsMenu->setTitle(tr("&Tools")); + m_toolsWebSearchAction->setText(tr("Web &Search")); + m_toolsWebSearchAction->setShortcut(QKeySequence(tr("Ctrl+K", "Web Search"))); + m_toolsClearPrivateDataAction->setText(tr("&Clear Private Data")); + m_toolsClearPrivateDataAction->setShortcut(QKeySequence(tr("Ctrl+Shift+Delete", "Clear Private Data"))); + m_toolsEnableInspectorAction->setText(tr("Enable Web &Inspector")); + m_toolsPreferencesAction->setText(tr("Options...")); + m_toolsPreferencesAction->setShortcut(tr("Ctrl+,")); + m_toolsSearchManagerAction->setText(tr("Configure Search Engines...")); + m_toolsUserAgentMenu->setTitle(tr("User Agent")); + m_adBlockDialogAction->setText(tr("&Ad Block...")); + + m_helpMenu->setTitle(tr("&Help")); + m_helpChangeLanguageAction->setText(tr("Switch application language ")); + m_helpAboutQtAction->setText(tr("About &Qt")); + m_helpAboutApplicationAction->setText(tr("About &%1", "About Browser").arg(QApplication::applicationName())); + + // Toolbar + m_navigationBar->setWindowTitle(tr("Navigation")); + m_bookmarksToolbar->setWindowTitle(tr("&Bookmarks")); + + m_stopReloadAction->setText(tr("Reload / Stop")); + updateStopReloadActionText(false); } void BrowserMainWindow::setupToolBar() { setUnifiedTitleAndToolBarOnMac(true); - m_navigationBar = addToolBar(tr("Navigation")); - connect(m_navigationBar->toggleViewAction(), SIGNAL(toggled(bool)), - this, SLOT(updateToolbarActionText(bool))); + m_navigationBar = new QToolBar(this); + m_navigationBar->setObjectName(QLatin1String("NavigationToolBar")); + addToolBar(m_navigationBar); - m_historyBack->setIcon(style()->standardIcon(QStyle::SP_ArrowBack, 0, this)); + m_historyBackAction->setIcon(style()->standardIcon(QStyle::SP_ArrowBack, 0, this)); m_historyBackMenu = new QMenu(this); - m_historyBack->setMenu(m_historyBackMenu); + m_historyBackAction->setMenu(m_historyBackMenu); connect(m_historyBackMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowBackMenu())); + this, SLOT(aboutToShowBackMenu())); connect(m_historyBackMenu, SIGNAL(triggered(QAction *)), - this, SLOT(slotOpenActionUrl(QAction *))); - m_navigationBar->addAction(m_historyBack); + this, SLOT(openActionUrl(QAction *))); + m_navigationBar->addAction(m_historyBackAction); - m_historyForward->setIcon(style()->standardIcon(QStyle::SP_ArrowForward, 0, this)); + m_historyForwardAction->setIcon(style()->standardIcon(QStyle::SP_ArrowForward, 0, this)); m_historyForwardMenu = new QMenu(this); connect(m_historyForwardMenu, SIGNAL(aboutToShow()), - this, SLOT(slotAboutToShowForwardMenu())); + this, SLOT(aboutToShowForwardMenu())); connect(m_historyForwardMenu, SIGNAL(triggered(QAction *)), - this, SLOT(slotOpenActionUrl(QAction *))); - m_historyForward->setMenu(m_historyForwardMenu); - m_navigationBar->addAction(m_historyForward); - - m_stopReload = new QAction(this); - m_reloadIcon = style()->standardIcon(QStyle::SP_BrowserReload); - m_stopReload->setIcon(m_reloadIcon); + this, SLOT(openActionUrl(QAction *))); + m_historyForwardAction->setMenu(m_historyForwardMenu); + m_navigationBar->addAction(m_historyForwardAction); - m_navigationBar->addAction(m_stopReload); + m_stopReloadAction = new QAction(this); + m_stopReloadAction->setIcon(m_reloadIcon); + m_navigationBar->addAction(m_stopReloadAction); m_navigationSplitter = new QSplitter(m_navigationBar); - m_navigationSplitter->addWidget(m_tabWidget->lineEditStack()); + m_navigationSplitter->addWidget(m_tabWidget->locationBarStack()); + m_toolbarSearch = new ToolbarSearch(m_navigationBar); m_navigationSplitter->addWidget(m_toolbarSearch); - connect(m_toolbarSearch, SIGNAL(search(const QUrl&)), SLOT(loadUrl(const QUrl&))); + connect(m_toolbarSearch, SIGNAL(search(const QUrl&, TabWidget::OpenUrlIn)), + m_tabWidget, SLOT(loadUrl(const QUrl&, TabWidget::OpenUrlIn))); m_navigationSplitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum); - m_tabWidget->lineEditStack()->setMinimumWidth(120); + m_tabWidget->locationBarStack()->setMinimumWidth(120); m_navigationSplitter->setCollapsible(0, false); m_navigationBar->addWidget(m_navigationSplitter); int splitterWidth = m_navigationSplitter->width(); @@ -523,155 +1061,122 @@ void BrowserMainWindow::setupToolBar() m_navigationSplitter->setSizes(sizes); } -void BrowserMainWindow::slotShowBookmarksDialog() +void BrowserMainWindow::showBookmarksDialog() { BookmarksDialog *dialog = new BookmarksDialog(this); - connect(dialog, SIGNAL(openUrl(const QUrl&, TabWidget::Tab, const QString &)), - m_tabWidget, SLOT(loadUrl(const QUrl&, TabWidget::Tab, const QString &))); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(dialog, SIGNAL(openUrl(const QUrl&, TabWidget::OpenUrlIn, const QString &)), + m_tabWidget, SLOT(loadUrl(const QUrl&, TabWidget::OpenUrlIn, const QString &))); dialog->show(); } -void BrowserMainWindow::slotAddBookmark() +void BrowserMainWindow::addBookmark() { WebView *webView = currentTab(); - QString url = webView->url().toString(); + QString url = QLatin1String(webView->url().toEncoded()); QString title = webView->title(); - AddBookmarkDialog dialog(url, title); + + AddBookmarkDialog dialog; + dialog.setUrl(url); + dialog.setTitle(title); + BookmarkNode *menu = BrowserApplication::bookmarksManager()->menu(); + QModelIndex index = BrowserApplication::bookmarksManager()->bookmarksModel()->index(menu); + dialog.setCurrentIndex(index); dialog.exec(); } -void BrowserMainWindow::slotViewMenuBar() +void BrowserMainWindow::addBookmarkFolder() +{ + AddBookmarkDialog dialog; + BookmarksManager *bookmarksManager = BrowserApplication::bookmarksManager(); + BookmarkNode *menu = bookmarksManager->menu(); + QModelIndex index = bookmarksManager->bookmarksModel()->index(menu); + dialog.setCurrentIndex(index); + dialog.setFolder(true); + dialog.exec(); +} + +void BrowserMainWindow::viewMenuBar() { menuBar()->setVisible(!menuBar()->isVisible()); + + m_menuBarVisible = menuBar()->isVisible(); + m_autoSaver->changeOccurred(); } -void BrowserMainWindow::slotViewToolbar() +void BrowserMainWindow::viewToolbar() { if (m_navigationBar->isVisible()) { - updateToolbarActionText(false); m_navigationBar->close(); } else { - updateToolbarActionText(true); m_navigationBar->show(); } m_autoSaver->changeOccurred(); } -void BrowserMainWindow::slotViewBookmarksBar() +void BrowserMainWindow::viewBookmarksBar() { if (m_bookmarksToolbar->isVisible()) { - updateBookmarksToolbarActionText(false); - m_bookmarksToolbar->close(); + m_bookmarksToolbar->hide(); +#if defined(Q_WS_MAC) + m_bookmarksToolbarFrame->hide(); +#endif } else { - updateBookmarksToolbarActionText(true); m_bookmarksToolbar->show(); +#if defined(Q_WS_MAC) + m_bookmarksToolbarFrame->show(); +#endif } m_autoSaver->changeOccurred(); } -void BrowserMainWindow::updateStatusbarActionText(bool visible) -{ - m_viewStatusbar->setText(!visible ? tr("Show Status Bar") : tr("Hide Status Bar")); -} - -void BrowserMainWindow::updateToolbarActionText(bool visible) -{ - m_viewToolbar->setText(!visible ? tr("Show Toolbar") : tr("Hide Toolbar")); -} - -void BrowserMainWindow::updateBookmarksToolbarActionText(bool visible) -{ - m_viewBookmarkBar->setText(!visible ? tr("Show Bookmarks bar") : tr("Hide Bookmarks bar")); -} - -void BrowserMainWindow::slotViewStatusbar() +void BrowserMainWindow::viewStatusbar() { if (statusBar()->isVisible()) { - updateStatusbarActionText(false); statusBar()->close(); } else { - updateStatusbarActionText(true); statusBar()->show(); } - m_autoSaver->changeOccurred(); -} - -QUrl BrowserMainWindow::guessUrlFromString(const QString &string) -{ - QString urlStr = string.trimmed(); - QRegExp test(QLatin1String("^[a-zA-Z]+\\:.*")); - - // Check if it looks like a qualified URL. Try parsing it and see. - bool hasSchema = test.exactMatch(urlStr); - if (hasSchema) { - QUrl url(urlStr, QUrl::TolerantMode); - if (url.isValid()) - return url; - } - - // Might be a file. - if (QFile::exists(urlStr)) { - QFileInfo info(urlStr); - return QUrl::fromLocalFile(info.absoluteFilePath()); - } - // Might be a shorturl - try to detect the schema. - if (!hasSchema) { - int dotIndex = urlStr.indexOf(QLatin1Char('.')); - if (dotIndex != -1) { - QString prefix = urlStr.left(dotIndex).toLower(); - QString schema = (prefix == QLatin1String("ftp")) ? prefix : QLatin1String("http"); - QUrl url(schema + QLatin1String("://") + urlStr, QUrl::TolerantMode); - if (url.isValid()) - return url; - } - } - - // Fall back to QUrl's own tolerant parser. - QUrl url = QUrl(string, QUrl::TolerantMode); + m_statusBarVisible = statusBar()->isVisible(); - // finally for cases where the user just types in a hostname add http - if (url.scheme().isEmpty()) - url = QUrl(QLatin1String("http://") + string, QUrl::TolerantMode); - return url; -} - -void BrowserMainWindow::loadUrl(const QUrl &url) -{ - loadPage(url.toString()); + m_autoSaver->changeOccurred(); } -void BrowserMainWindow::slotDownloadManager() +void BrowserMainWindow::downloadManager() { BrowserApplication::downloadManager()->show(); } -void BrowserMainWindow::slotSelectLineEdit() +void BrowserMainWindow::selectLineEdit() { - m_tabWidget->currentLineEdit()->selectAll(); - m_tabWidget->currentLineEdit()->setFocus(); + if (m_navigationBar->isHidden()) + m_navigationBar->show(); + + m_tabWidget->currentLocationBar()->selectAll(); + m_tabWidget->currentLocationBar()->setFocus(); } -void BrowserMainWindow::slotFileSaveAs() +void BrowserMainWindow::fileSaveAs() { BrowserApplication::downloadManager()->download(currentTab()->url(), true); } -void BrowserMainWindow::slotPreferences() +void BrowserMainWindow::preferences() { - SettingsDialog s(this); - s.exec(); + SettingsDialog settingsDialog(this); + settingsDialog.exec(); } -void BrowserMainWindow::slotUpdateStatusbar(const QString &string) +void BrowserMainWindow::updateStatusbar(const QString &string) { statusBar()->showMessage(string, 2000); } -void BrowserMainWindow::slotUpdateWindowTitle(const QString &title) +void BrowserMainWindow::updateWindowTitle(const QString &title) { if (title.isEmpty()) { - setWindowTitle(tr("Arora")); + setWindowTitle(QApplication::applicationName()); } else { #if defined(Q_WS_MAC) setWindowTitle(title); @@ -681,20 +1186,26 @@ void BrowserMainWindow::slotUpdateWindowTitle(const QString &title) } } -void BrowserMainWindow::slotAboutApplication() +void BrowserMainWindow::aboutApplication() { AboutDialog *aboutDialog = new AboutDialog(this); + aboutDialog->setAttribute(Qt::WA_DeleteOnClose); aboutDialog->show(); } -void BrowserMainWindow::slotFileNew() +void BrowserMainWindow::fileNew() { - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *mw = BrowserApplication::instance()->mainWindow(); - mw->slotHome(); + BrowserMainWindow *window = BrowserApplication::instance()->newMainWindow(); + + QSettings settings; + settings.beginGroup(QLatin1String("MainWindow")); + int startup = settings.value(QLatin1String("startupBehavior")).toInt(); + + if (startup == 0) + window->goHome(); } -void BrowserMainWindow::slotFileOpen() +void BrowserMainWindow::fileOpen() { QString file = QFileDialog::getOpenFileName(this, tr("Open Web Resource"), QString(), tr("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)")); @@ -702,20 +1213,20 @@ void BrowserMainWindow::slotFileOpen() if (file.isEmpty()) return; - loadPage(file); + tabWidget()->loadUrl(QUrl::fromLocalFile(file)); } -void BrowserMainWindow::slotFilePrintPreview() +void BrowserMainWindow::filePrintPreview() { if (!currentTab()) return; - QPrintPreviewDialog *dialog = new QPrintPreviewDialog(this); - connect(dialog, SIGNAL(paintRequested(QPrinter *)), + QPrintPreviewDialog dialog(this); + connect(&dialog, SIGNAL(paintRequested(QPrinter *)), currentTab(), SLOT(print(QPrinter *))); - dialog->exec(); + dialog.exec(); } -void BrowserMainWindow::slotFilePrint() +void BrowserMainWindow::filePrint() { if (!currentTab()) return; @@ -725,57 +1236,76 @@ void BrowserMainWindow::slotFilePrint() void BrowserMainWindow::printRequested(QWebFrame *frame) { QPrinter printer; - QPrintDialog *dialog = new QPrintDialog(&printer, this); - dialog->setWindowTitle(tr("Print Document")); - if (dialog->exec() != QDialog::Accepted) + QPrintDialog dialog(&printer, this); + dialog.setWindowTitle(tr("Print Document")); + if (dialog.exec() != QDialog::Accepted) return; frame->print(&printer); } -void BrowserMainWindow::slotPrivateBrowsing() +void BrowserMainWindow::privateBrowsing() { - QWebSettings *settings = QWebSettings::globalSettings(); - bool pb = settings->testAttribute(QWebSettings::PrivateBrowsingEnabled); - if (!pb) { + if (!BrowserApplication::isPrivate()) { QString title = tr("Are you sure you want to turn on private browsing?"); - QString text = tr("%1

When private browsing is turned on," - " some actions concerning your privacy will be disabled:" - "
  • Webpages are not added to the history.
  • " - "
  • Items are automatically removed from the Downloads window.
  • " - "
  • New cookies are not stored, current cookies can't be accessed.
  • " - "
  • Site icons won't be stored, session won't be saved.
  • " - "
  • Searches are not addded to the pop-up menu in the search box.
" - "Until you close the window, you can still click the Back and Forward buttons" - " to return to the webpages you have opened.").arg(title); - - QMessageBox::StandardButton button = QMessageBox::question(this, QString(), text, - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok); - if (button == QMessageBox::Ok) { - settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); - } + QString text1 = tr("When private browsing is turned on, some actions concerning your privacy will be disabled:"); + + QStringList actions; + actions.append(tr("Webpages are not added to the history.")); + actions.append(tr("Items are automatically removed from the Downloads window.")); + actions.append(tr("New cookies are not stored, current cookies can't be accessed.")); + actions.append(tr("Site icons won't be stored.")); + actions.append(tr("Session won't be saved.")); + actions.append(tr("Searches are not added to the pop-up menu in the search box.")); + actions.append(tr("No new network cache is written to disk.")); + + QString text2 = tr("Until you close the window, you can still click the Back and Forward " + "buttons to return to the webpages you have opened."); + + QString message = QString(QLatin1String("%1

%2

  • %3

%4

")) + .arg(title, text1, actions.join(QLatin1String("
  • ")), text2); + + QMessageBox::StandardButton button = QMessageBox::question(this, tr("Private Browsing"), message, + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Ok); + if (button == QMessageBox::Ok) + BrowserApplication::setPrivate(true); + else + m_filePrivateBrowsingAction->setChecked(false); } else { - settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); - - QList windows = BrowserApplication::instance()->mainWindows(); - for (int i = 0; i < windows.count(); ++i) { - BrowserMainWindow *window = windows.at(i); - window->tabWidget()->clear(); - } + BrowserApplication::setPrivate(false); } - m_privateBrowsing->setChecked(settings->testAttribute(QWebSettings::PrivateBrowsingEnabled)); +} + +void BrowserMainWindow::zoomTextOnlyChanged(bool textOnly) +{ + m_viewZoomTextOnlyAction->setChecked(textOnly); +} + +void BrowserMainWindow::privacyChanged(bool isPrivate) +{ + m_filePrivateBrowsingAction->setChecked(isPrivate); + if (!isPrivate) + tabWidget()->clear(); } void BrowserMainWindow::closeEvent(QCloseEvent *event) { + if (!BrowserApplication::instance()->allowToCloseWindow(this)) { + event->ignore(); + if (m_tabWidget->count() == 0) + m_tabWidget->newTab(); + return; + } + if (m_tabWidget->count() > 1) { QSettings settings; settings.beginGroup(QLatin1String("tabs")); bool confirm = settings.value(QLatin1String("confirmClosingMultipleTabs"), true).toBool(); if (confirm) { + QApplication::alert(this); int ret = QMessageBox::warning(this, QString(), tr("Are you sure you want to close the window?" - " There are %1 tab open").arg(m_tabWidget->count()), + " There are %1 tabs open").arg(m_tabWidget->count()), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (ret == QMessageBox::No) { @@ -784,89 +1314,119 @@ void BrowserMainWindow::closeEvent(QCloseEvent *event) } } } + event->accept(); - deleteLater(); } -void BrowserMainWindow::slotEditFind() +void BrowserMainWindow::mousePressEvent(QMouseEvent *event) +{ + switch (event->button()) { + case Qt::XButton1: + m_historyBackAction->activate(QAction::Trigger); + break; + case Qt::XButton2: + m_historyForwardAction->activate(QAction::Trigger); + break; + default: + QMainWindow::mousePressEvent(event); + break; + } +} + +void BrowserMainWindow::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslate(); + QMainWindow::changeEvent(event); +} + +void BrowserMainWindow::editFind() { tabWidget()->webViewSearch(m_tabWidget->currentIndex())->showFind(); } -void BrowserMainWindow::slotEditFindNext() +void BrowserMainWindow::editFindNext() { tabWidget()->webViewSearch(m_tabWidget->currentIndex())->findNext(); } -void BrowserMainWindow::slotEditFindPrevious() +void BrowserMainWindow::editFindPrevious() { tabWidget()->webViewSearch(m_tabWidget->currentIndex())->findPrevious(); } -void BrowserMainWindow::slotViewTextBigger() +void BrowserMainWindow::zoomIn() { if (!currentTab()) return; - currentTab()->setTextSizeMultiplier(currentTab()->textSizeMultiplier() + 0.1); + currentTab()->zoomIn(); } -void BrowserMainWindow::slotViewTextNormal() +void BrowserMainWindow::zoomNormal() { if (!currentTab()) return; - currentTab()->setTextSizeMultiplier(1.0); + currentTab()->resetZoom(); } -void BrowserMainWindow::slotViewTextSmaller() +void BrowserMainWindow::zoomOut() { if (!currentTab()) return; - currentTab()->setTextSizeMultiplier(currentTab()->textSizeMultiplier() - 0.1); + currentTab()->zoomOut(); } -void BrowserMainWindow::slotViewFullScreen(bool makeFullScreen) +void BrowserMainWindow::viewFullScreen(bool makeFullScreen) { if (makeFullScreen) { + setUnifiedTitleAndToolBarOnMac(false); setWindowState(windowState() | Qt::WindowFullScreen); + + menuBar()->hide(); + statusBar()->hide(); } else { setWindowState(windowState() & ~Qt::WindowFullScreen); + + setUnifiedTitleAndToolBarOnMac(true); + menuBar()->setVisible(m_menuBarVisible); + statusBar()->setVisible(m_statusBarVisible); } } -void BrowserMainWindow::slotViewPageSource() +void BrowserMainWindow::viewPageSource() { if (!currentTab()) return; + QString title = currentTab()->title(); QString markup = currentTab()->page()->mainFrame()->toHtml(); - QPlainTextEdit *view = new QPlainTextEdit(markup); - view->setWindowTitle(tr("Page Source of %1").arg(currentTab()->title())); - view->setMinimumWidth(640); - view->setAttribute(Qt::WA_DeleteOnClose); - view->show(); + QUrl url = currentTab()->url(); + SourceViewer *viewer = new SourceViewer(markup, title, url); + viewer->setAttribute(Qt::WA_DeleteOnClose); + viewer->show(); } -void BrowserMainWindow::slotHome() +void BrowserMainWindow::goHome() { QSettings settings; settings.beginGroup(QLatin1String("MainWindow")); - QString home = settings.value(QLatin1String("home"), QLatin1String("http://www.arora-browser.org")).toString(); - loadPage(home); + QString home = settings.value(QLatin1String("home"), QLatin1String("about:home")).toString(); + tabWidget()->loadString(home); } -void BrowserMainWindow::slotWebSearch() +void BrowserMainWindow::webSearch() { - m_toolbarSearch->lineEdit()->selectAll(); - m_toolbarSearch->lineEdit()->setFocus(); + m_toolbarSearch->selectAll(); + m_toolbarSearch->setFocus(); } -void BrowserMainWindow::slotClearPrivateData() +void BrowserMainWindow::clearPrivateData() { ClearPrivateData dialog; dialog.exec(); } -void BrowserMainWindow::slotToggleInspector(bool enable) +void BrowserMainWindow::toggleInspector(bool enable) { QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable); if (enable) { @@ -878,28 +1438,21 @@ void BrowserMainWindow::slotToggleInspector(bool enable) m_tabWidget->reloadAllTabs(); } } + QSettings settings; + settings.beginGroup(QLatin1String("websettings")); + settings.setValue(QLatin1String("enableInspector"), enable); } -void BrowserMainWindow::slotSwapFocus() +void BrowserMainWindow::swapFocus() { if (currentTab()->hasFocus()) { - m_tabWidget->currentLineEdit()->setFocus(); - m_tabWidget->currentLineEdit()->selectAll(); + m_tabWidget->currentLocationBar()->setFocus(); + m_tabWidget->currentLocationBar()->selectAll(); } else { currentTab()->setFocus(); } } -void BrowserMainWindow::loadPage(const QString &page) -{ - if (!currentTab() || page.isEmpty()) - return; - - QUrl url = guessUrlFromString(page); - m_tabWidget->currentLineEdit()->setText(url.toString()); - m_tabWidget->loadUrl(url, TabWidget::CurrentTab); -} - TabWidget *BrowserMainWindow::tabWidget() const { return m_tabWidget; @@ -915,24 +1468,39 @@ ToolbarSearch *BrowserMainWindow::toolbarSearch() const return m_toolbarSearch; } -void BrowserMainWindow::slotLoadProgress(int progress) +void BrowserMainWindow::updateStopReloadActionText(bool loading) +{ + if (loading) { + m_stopReloadAction->setToolTip(tr("Stop loading the current page")); + m_stopReloadAction->setIconText(tr("Stop")); + } else { + m_stopReloadAction->setToolTip(tr("Reload the current page")); + m_stopReloadAction->setIconText(tr("Reload")); + } +} + +void BrowserMainWindow::loadProgress(int progress) { if (progress < 100 && progress > 0) { - disconnect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger())); - if (m_stopIcon.isNull()) - m_stopIcon = style()->standardIcon(QStyle::SP_BrowserStop); - m_stopReload->setIcon(m_stopIcon); - connect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger())); - m_stopReload->setToolTip(tr("Stop loading the current page")); + disconnect(m_stopReloadAction, SIGNAL(triggered()), m_viewReloadAction, SLOT(trigger())); + m_stopReloadAction->setIcon(m_stopIcon); + connect(m_stopReloadAction, SIGNAL(triggered()), m_viewStopAction, SLOT(trigger())); + updateStopReloadActionText(true); } else { - disconnect(m_stopReload, SIGNAL(triggered()), m_stop, SLOT(trigger())); - m_stopReload->setIcon(m_reloadIcon); - connect(m_stopReload, SIGNAL(triggered()), m_reload, SLOT(trigger())); - m_stopReload->setToolTip(tr("Reload the current page")); + disconnect(m_stopReloadAction, SIGNAL(triggered()), m_viewStopAction, SLOT(trigger())); + m_stopReloadAction->setIcon(m_reloadIcon); + connect(m_stopReloadAction, SIGNAL(triggered()), m_viewReloadAction, SLOT(trigger())); + updateStopReloadActionText(false); } } -void BrowserMainWindow::slotAboutToShowBackMenu() +void BrowserMainWindow::showSearchDialog() +{ + OpenSearchDialog dialog(this); + dialog.exec(); +} + +void BrowserMainWindow::aboutToShowBackMenu() { m_historyBackMenu->clear(); if (!currentTab()) @@ -950,7 +1518,7 @@ void BrowserMainWindow::slotAboutToShowBackMenu() } } -void BrowserMainWindow::slotAboutToShowForwardMenu() +void BrowserMainWindow::aboutToShowForwardMenu() { m_historyForwardMenu->clear(); if (!currentTab()) @@ -968,19 +1536,25 @@ void BrowserMainWindow::slotAboutToShowForwardMenu() } } -void BrowserMainWindow::slotAboutToShowWindowMenu() +void BrowserMainWindow::aboutToShowWindowMenu() { m_windowMenu->clear(); m_windowMenu->addAction(m_tabWidget->nextTabAction()); m_windowMenu->addAction(m_tabWidget->previousTabAction()); m_windowMenu->addSeparator(); - m_windowMenu->addAction(tr("Downloads"), this, SLOT(slotDownloadManager()), QKeySequence(tr("Alt+Ctrl+L", "Download Manager"))); + QAction *downloadManagerAction = m_windowMenu->addAction(tr("Downloads"), this, SLOT(downloadManager()), QKeySequence(tr("Ctrl+Y", "Download Manager"))); + +#if QT_VERSION >= 0x040600 + downloadManagerAction->setIcon(QIcon::fromTheme(QLatin1String("emblem-downloads"))); +#else + Q_UNUSED(downloadManagerAction); +#endif m_windowMenu->addSeparator(); QList windows = BrowserApplication::instance()->mainWindows(); for (int i = 0; i < windows.count(); ++i) { BrowserMainWindow *window = windows.at(i); - QAction *action = m_windowMenu->addAction(window->windowTitle(), this, SLOT(slotShowWindow())); + QAction *action = m_windowMenu->addAction(window->windowTitle(), this, SLOT(showWindow())); action->setData(i); action->setCheckable(true); if (window == this) @@ -988,7 +1562,7 @@ void BrowserMainWindow::slotAboutToShowWindowMenu() } } -void BrowserMainWindow::slotShowWindow() +void BrowserMainWindow::showWindow() { if (QAction *action = qobject_cast(sender())) { QVariant v = action->data(); @@ -996,12 +1570,13 @@ void BrowserMainWindow::slotShowWindow() int offset = qvariant_cast(v); QList windows = BrowserApplication::instance()->mainWindows(); windows.at(offset)->activateWindow(); + windows.at(offset)->raise(); windows.at(offset)->currentTab()->setFocus(); } } } -void BrowserMainWindow::slotOpenActionUrl(QAction *action) +void BrowserMainWindow::openActionUrl(QAction *action) { int offset = action->data().toInt(); QWebHistory *history = currentTab()->history(); diff --git a/src/browsermainwindow.h b/src/browsermainwindow.h index ea98df12..a00870f8 100644 --- a/src/browsermainwindow.h +++ b/src/browsermainwindow.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,17 +64,18 @@ #define BROWSERMAINWINDOW_H #include -#include -#include class AutoSaver; class BookmarksToolBar; -class ChaseWidget; class QWebFrame; class TabWidget; class ToolbarSearch; class WebView; class QSplitter; +class QFrame; +class HistoryMenu; +class BookmarksMenuBarMenu; +class UserAgentMenu; /*! The MainWindow of the Browser Application. @@ -91,102 +92,180 @@ class BrowserMainWindow : public QMainWindow QSize sizeHint() const; public: - static QUrl guessUrlFromString(const QString &url); + static BrowserMainWindow *parentWindow(QWidget *widget); + TabWidget *tabWidget() const; WebView *currentTab() const; ToolbarSearch *toolbarSearch() const; QByteArray saveState(bool withTabs = true) const; bool restoreState(const QByteArray &state); + QAction *showMenuBarAction() const; + QAction *searchManagerAction() const { return m_toolsSearchManagerAction; } public slots: - void loadPage(const QString &url); - void slotHome(); + void goHome(); + void privacyChanged(bool isPrivate); + void zoomTextOnlyChanged(bool textOnly); protected: void closeEvent(QCloseEvent *event); + void keyPressEvent(QKeyEvent *event); + void mousePressEvent(QMouseEvent *event); + void changeEvent(QEvent *event); private slots: void save(); - void slotLoadProgress(int); - void slotUpdateStatusbar(const QString &string); - void slotUpdateWindowTitle(const QString &title = QString()); - - void loadUrl(const QUrl &url); - void slotPreferences(); - - void slotFileNew(); - void slotFileOpen(); - void slotFilePrintPreview(); - void slotFilePrint(); - void slotPrivateBrowsing(); - void slotFileSaveAs(); - void slotEditFind(); - void slotEditFindNext(); - void slotEditFindPrevious(); - void slotShowBookmarksDialog(); - void slotAddBookmark(); - void slotViewTextBigger(); - void slotViewTextNormal(); - void slotViewTextSmaller(); - void slotViewMenuBar(); - void slotViewToolbar(); - void slotViewBookmarksBar(); - void slotViewStatusbar(); - void slotViewPageSource(); - void slotViewFullScreen(bool enable); - - void slotWebSearch(); - void slotClearPrivateData(); - void slotToggleInspector(bool enable); - void slotAboutApplication(); - void slotDownloadManager(); - void slotSelectLineEdit(); - - void slotAboutToShowBackMenu(); - void slotAboutToShowForwardMenu(); - void slotAboutToShowWindowMenu(); - void slotOpenActionUrl(QAction *action); - void slotShowWindow(); - void slotSwapFocus(); + void lastTabClosed(); + + void loadProgress(int); + void updateStatusbar(const QString &string); + void updateWindowTitle(const QString &title = QString()); + + void preferences(); + + void fileNew(); + void fileOpen(); + void filePrintPreview(); + void filePrint(); + void privateBrowsing(); + void fileSaveAs(); + void editFind(); + void editFindNext(); + void editFindPrevious(); + void showBookmarksDialog(); + void addBookmark(); + void addBookmarkFolder(); + void zoomIn(); + void zoomNormal(); + void zoomOut(); + void viewMenuBar(); + void viewToolbar(); + void viewBookmarksBar(); + void viewStatusbar(); + void viewPageSource(); + void viewFullScreen(bool enable); + void viewTextEncoding(QAction *action); + + void webSearch(); + void clearPrivateData(); + void toggleInspector(bool enable); + void aboutApplication(); + void downloadManager(); + void selectLineEdit(); + + void aboutToShowBackMenu(); + void aboutToShowForwardMenu(); + void aboutToShowViewMenu(); + void aboutToShowWindowMenu(); + void aboutToShowTextEncodingMenu(); + void openActionUrl(QAction *action); + void showSearchDialog(); + void showWindow(); + void swapFocus(); void printRequested(QWebFrame *frame); void geometryChangeRequested(const QRect &geometry); - void updateToolbarActionText(bool visible); - void updateBookmarksToolbarActionText(bool visible); private: + void retranslate(); void loadDefaultState(); void setupMenu(); void setupToolBar(); - void updateStatusbarActionText(bool visible); + void updateStopReloadActionText(bool loading); private: + QMenu *m_fileMenu; + QAction *m_fileNewWindowAction; + QAction *m_fileOpenFileAction; + QAction *m_fileOpenLocationAction; + QAction *m_fileSaveAsAction; + QAction *m_fileImportBookmarksAction; + QAction *m_fileExportBookmarksAction; + QAction *m_filePrintPreviewAction; + QAction *m_filePrintAction; + QAction *m_filePrivateBrowsingAction; + QAction *m_fileCloseWindow; + QAction *m_fileQuit; + + QMenu *m_editMenu; + QAction *m_editUndoAction; + QAction *m_editRedoAction; + QAction *m_editCutAction; + QAction *m_editCopyAction; + QAction *m_editPasteAction; + QAction *m_editSelectAllAction; + QAction *m_editFindAction; + QAction *m_editFindNextAction; + QAction *m_editFindPreviousAction; + + QMenu *m_viewMenu; + QAction *m_viewShowMenuBarAction; + QAction *m_viewToolbarAction; + QAction *m_viewBookmarkBarAction; + QAction *m_viewStatusbarAction; + QAction *m_viewStopAction; + QAction *m_viewReloadAction; + QAction *m_viewZoomInAction; + QAction *m_viewZoomNormalAction; + QAction *m_viewZoomOutAction; + QAction *m_viewZoomTextOnlyAction; + QAction *m_viewSourceAction; + QAction *m_viewFullScreenAction; + QAction *m_viewTextEncodingAction; + QMenu *m_viewTextEncodingMenu; + + HistoryMenu *m_historyMenu; + QAction *m_historyBackAction; + QAction *m_historyForwardAction; + QAction *m_historyHomeAction; + QAction *m_historyRestoreLastSessionAction; + + BookmarksMenuBarMenu *m_bookmarksMenu; + QAction *m_bookmarksShowAllAction; + QAction *m_bookmarksAddAction; + QAction *m_bookmarksAddFolderAction; + + QMenu *m_windowMenu; + + QMenu *m_toolsMenu; + QAction *m_toolsWebSearchAction; + QAction *m_toolsClearPrivateDataAction; + QAction *m_toolsEnableInspectorAction; + QAction *m_toolsPreferencesAction; + QAction *m_toolsSearchManagerAction; + UserAgentMenu *m_toolsUserAgentMenu; + QAction *m_adBlockDialogAction; + + QMenu *m_helpMenu; + QAction *m_helpChangeLanguageAction; + QAction *m_helpAboutQtAction; + QAction *m_helpAboutApplicationAction; + + // Toolbar QToolBar *m_navigationBar; + QMenu *m_historyBackMenu; + QMenu *m_historyForwardMenu; + QAction *m_stopReloadAction; + QIcon m_reloadIcon; + QIcon m_stopIcon; QSplitter *m_navigationSplitter; ToolbarSearch *m_toolbarSearch; +#if defined(Q_WS_MAC) + QFrame *m_bookmarksToolbarFrame; +#endif BookmarksToolBar *m_bookmarksToolbar; + TabWidget *m_tabWidget; - AutoSaver *m_autoSaver; - QAction *m_historyBack; - QMenu *m_historyBackMenu; - QAction *m_historyForward; - QMenu *m_historyForwardMenu; - QMenu *m_windowMenu; - QAction *m_privateBrowsing; + AutoSaver *m_autoSaver; - QAction *m_stop; - QAction *m_reload; - QAction *m_stopReload; - QAction *m_viewToolbar; - QAction *m_viewBookmarkBar; - QAction *m_viewStatusbar; - QAction *m_restoreLastSession; - QAction *m_addBookmark; + // These store if the user requested the menu/status bars visible. They are + // used to determine if these bars should be reshown when leaving fullscreen. + bool m_menuBarVisible; + bool m_statusBarVisible; - QIcon m_reloadIcon; - QIcon m_stopIcon; + friend class BrowserApplication; }; #endif // BROWSERMAINWINDOW_H diff --git a/src/clearbutton.cpp b/src/clearbutton.cpp new file mode 100644 index 00000000..a0a5e99d --- /dev/null +++ b/src/clearbutton.cpp @@ -0,0 +1,92 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "clearbutton.h" + +#include + +ClearButton::ClearButton(QWidget *parent) + : QAbstractButton(parent) +{ + setCursor(Qt::ArrowCursor); + setFocusPolicy(Qt::NoFocus); + setToolTip(tr("Clear")); + setMinimumSize(22, 22); + setVisible(false); + +#if QT_VERSION >= 0x040600 + // First check for a style icon, current KDE provides one + if (m_styleImage.isNull()) { + QLatin1String iconName = (layoutDirection() == Qt::RightToLeft) + ? QLatin1String("edit-clear-locationbar-ltr") + : QLatin1String("edit-clear-locationbar-rtl"); + QIcon icon = QIcon::fromTheme(iconName); + if (!icon.isNull()) + m_styleImage = icon.pixmap(16, 16).toImage(); + } +#endif +} + +void ClearButton::textChanged(const QString &text) +{ + setVisible(!text.isEmpty()); +} + +void ClearButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + QPainter painter(this); + + if (!m_styleImage.isNull()) { + int x = (width() - m_styleImage.width()) / 2 - 1; + int y = (height() - m_styleImage.height()) / 2 - 1; + painter.drawImage(x, y, m_styleImage); + return; + } + + // Fall back to boring circle X + painter.setRenderHint(QPainter::Antialiasing, true); + + QPalette p = palette(); + QColor circleColor = isDown() ? p.color(QPalette::Dark) : p.color(QPalette::Mid); + QColor xColor = p.color(QPalette::Window); + + // draw circle + painter.setBrush(circleColor); + painter.setPen(circleColor); + int padding = width() / 5; + int circleRadius = width() - (padding * 2); + painter.drawEllipse(padding, padding, circleRadius, circleRadius); + + // draw X + painter.setPen(xColor); + padding = padding * 2; + painter.drawLine(padding, padding, width() - padding, width() - padding); + painter.drawLine(padding, height() - padding, width() - padding, padding); +} + diff --git a/src/clearbutton.h b/src/clearbutton.h new file mode 100644 index 00000000..f018ba45 --- /dev/null +++ b/src/clearbutton.h @@ -0,0 +1,52 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef CLEARBUTTON_H +#define CLEARBUTTON_H + +#include + +class ClearButton : public QAbstractButton +{ + Q_OBJECT + +public: + ClearButton(QWidget *parent = 0); + +public slots: + void textChanged(const QString &text); + +protected: + void paintEvent(QPaintEvent *event); + +private: + QImage m_styleImage; +}; + +#endif // CLEARBUTTON_H + diff --git a/src/clearprivatedata.cpp b/src/clearprivatedata.cpp index f92074a9..5afeef02 100644 --- a/src/clearprivatedata.cpp +++ b/src/clearprivatedata.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Jason A. Donenfeld + * Copyright 2008-2009 Jason A. Donenfeld * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,19 +17,24 @@ * Boston, MA 02110-1301 USA */ +#include "clearprivatedata.h" + #include "browserapplication.h" #include "browsermainwindow.h" -#include "clearprivatedata.h" #include "cookiejar.h" #include "downloadmanager.h" -#include "history.h" +#include "historymanager.h" +#include "networkaccessmanager.h" #include "toolbarsearch.h" +#include #include +#include #include #include #include #include +#include #include ClearPrivateData::ClearPrivateData(QWidget *parent) @@ -40,30 +45,39 @@ ClearPrivateData::ClearPrivateData(QWidget *parent) QVBoxLayout *layout = new QVBoxLayout(); layout->addWidget(new QLabel(tr("Clear the following items:"))); + QSettings settings; + settings.beginGroup(QLatin1String("clearprivatedata")); + m_browsingHistory = new QCheckBox(tr("&Browsing History")); - m_browsingHistory->setChecked(true); + m_browsingHistory->setChecked(settings.value(QLatin1String("browsingHistory"), true).toBool()); layout->addWidget(m_browsingHistory); m_downloadHistory = new QCheckBox(tr("&Download History")); - m_downloadHistory->setChecked(true); + m_downloadHistory->setChecked(settings.value(QLatin1String("downloadHistory"), true).toBool()); layout->addWidget(m_downloadHistory); m_searchHistory = new QCheckBox(tr("&Search History")); - m_searchHistory->setChecked(true); + m_searchHistory->setChecked(settings.value(QLatin1String("searchHistory"), true).toBool()); layout->addWidget(m_searchHistory); m_cookies = new QCheckBox(tr("&Cookies")); - m_cookies->setChecked(true); + m_cookies->setChecked(settings.value(QLatin1String("cookies"), true).toBool()); layout->addWidget(m_cookies); - m_cache = new QCheckBox(tr("C&ache")); - m_cache->setEnabled(false); + m_cache = new QCheckBox(tr("C&ached Web Pages")); + if (BrowserApplication::networkAccessManager()->cache()) { + m_cache->setChecked(settings.value(QLatin1String("cache"), true).toBool()); + } else { + m_cache->setEnabled(false); + } layout->addWidget(m_cache); m_favIcons = new QCheckBox(tr("Website &Icons")); - m_favIcons->setChecked(true); + m_favIcons->setChecked(settings.value(QLatin1String("favIcons"), true).toBool()); layout->addWidget(m_favIcons); + settings.endGroup(); + QPushButton *acceptButton = new QPushButton(tr("Clear &Private Data")); acceptButton->setDefault(true); QPushButton *rejectButton = new QPushButton(tr("&Cancel")); @@ -80,25 +94,42 @@ ClearPrivateData::ClearPrivateData(QWidget *parent) void ClearPrivateData::accept() { + QSettings settings; + settings.beginGroup(QLatin1String("clearprivatedata")); + + settings.setValue(QLatin1String("browsingHistory"), m_browsingHistory->isChecked()); + settings.setValue(QLatin1String("downloadHistory"), m_downloadHistory->isChecked()); + settings.setValue(QLatin1String("searchHistory"), m_searchHistory->isChecked()); + settings.setValue(QLatin1String("cookies"), m_cookies->isChecked()); + settings.setValue(QLatin1String("cache"), m_cache->isChecked()); + settings.setValue(QLatin1String("favIcons"), m_favIcons->isChecked()); + + settings.endGroup(); + if (m_browsingHistory->isChecked()) { BrowserApplication::historyManager()->clear(); } + if (m_downloadHistory->isChecked()) { BrowserApplication::downloadManager()->cleanup(); BrowserApplication::downloadManager()->hide(); } + if (m_searchHistory->isChecked()) { QList mainWindows = BrowserApplication::instance()->mainWindows(); for (int i = 0; i < mainWindows.count(); ++i) { - mainWindows.at(i)->toolbarSearch()->clear(); + mainWindows.at(i)->toolbarSearch()->setText(QString()); } } + if (m_cookies->isChecked()) { BrowserApplication::cookieJar()->clear(); } - if (m_cache->isChecked()) { - //not implemented + + if (m_cache->isChecked() && BrowserApplication::networkAccessManager()->cache()) { + BrowserApplication::networkAccessManager()->cache()->clear(); } + if (m_favIcons->isChecked()) { QWebSettings::clearIconDatabase(); } diff --git a/src/cookiejar.cpp b/src/cookiejar.cpp deleted file mode 100644 index 40c04d8b..00000000 --- a/src/cookiejar.cpp +++ /dev/null @@ -1,775 +0,0 @@ -/* - * Copyright 2008 Benjamin C. Meyer - * - * This program 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/**************************************************************************** -** -** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "cookiejar.h" - -#include "autosaver.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -static const unsigned int JAR_VERSION = 23; - -QT_BEGIN_NAMESPACE -QDataStream &operator<<(QDataStream &stream, const QList &list) -{ - stream << JAR_VERSION; - stream << quint32(list.size()); - for (int i = 0; i < list.size(); ++i) - stream << list.at(i).toRawForm(); - return stream; -} - -QDataStream &operator>>(QDataStream &stream, QList &list) -{ - list.clear(); - - quint32 version; - stream >> version; - - if (version != JAR_VERSION) - return stream; - - quint32 count; - stream >> count; - for (quint32 i = 0; i < count; ++i) { - QByteArray value; - stream >> value; - QList newCookies = QNetworkCookie::parseCookies(value); - if (newCookies.count() == 0 && value.length() != 0) { - qWarning() << "CookieJar: Unable to parse saved cookie:" << value; - } - for (int j = 0; j < newCookies.count(); ++j) - list.append(newCookies.at(j)); - if (stream.atEnd()) - break; - } - return stream; -} -QT_END_NAMESPACE - -CookieJar::CookieJar(QObject *parent) - : QNetworkCookieJar(parent) - , m_loaded(false) - , m_saveTimer(new AutoSaver(this)) - , m_acceptCookies(AcceptOnlyFromSitesNavigatedTo) -{ -} - -CookieJar::~CookieJar() -{ - if (m_keepCookies == KeepUntilExit) - clear(); - m_saveTimer->saveIfNeccessary(); -} - -void CookieJar::clear() -{ - setAllCookies(QList()); - m_saveTimer->changeOccurred(); - emit cookiesChanged(); -} - -void CookieJar::load() -{ - if (m_loaded) - return; - // load cookies and exceptions - qRegisterMetaTypeStreamOperators >("QList"); - QSettings cookieSettings(QDesktopServices::storageLocation(QDesktopServices::DataLocation) + QLatin1String("/cookies.ini"), QSettings::IniFormat); - setAllCookies(qvariant_cast >(cookieSettings.value(QLatin1String("cookies")))); - cookieSettings.beginGroup(QLatin1String("Exceptions")); - m_exceptions_block = cookieSettings.value(QLatin1String("block")).toStringList(); - m_exceptions_allow = cookieSettings.value(QLatin1String("allow")).toStringList(); - m_exceptions_allowForSession = cookieSettings.value(QLatin1String("allowForSession")).toStringList(); - qSort(m_exceptions_block.begin(), m_exceptions_block.end()); - qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); - qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); - - loadSettings(); -} - -void CookieJar::loadSettings() -{ - QSettings settings; - settings.beginGroup(QLatin1String("cookies")); - QByteArray value = settings.value(QLatin1String("acceptCookies"), - QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray(); - QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); - m_acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? - AcceptOnlyFromSitesNavigatedTo : - static_cast(acceptPolicyEnum.keyToValue(value)); - - value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("KeepUntilExpire")).toByteArray(); - QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); - m_keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? - KeepUntilExpire : - static_cast(keepPolicyEnum.keyToValue(value)); - - if (m_keepCookies == KeepUntilExit) - setAllCookies(QList()); - - m_loaded = true; - emit cookiesChanged(); -} - -void CookieJar::save() -{ - if (!m_loaded) - return; - purgeOldCookies(); - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - if (!QFile::exists(directory)) { - QDir dir; - dir.mkpath(directory); - } - QSettings cookieSettings(directory + QLatin1String("/cookies.ini"), QSettings::IniFormat); - QList cookies = allCookies(); - for (int i = cookies.count() - 1; i >= 0; --i) { - if (cookies.at(i).isSessionCookie()) - cookies.removeAt(i); - } - cookieSettings.setValue(QLatin1String("cookies"), qVariantFromValue >(cookies)); - cookieSettings.beginGroup(QLatin1String("Exceptions")); - cookieSettings.setValue(QLatin1String("block"), m_exceptions_block); - cookieSettings.setValue(QLatin1String("allow"), m_exceptions_allow); - cookieSettings.setValue(QLatin1String("allowForSession"), m_exceptions_allowForSession); - - // save cookie settings - QSettings settings; - settings.beginGroup(QLatin1String("cookies")); - QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); - settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(m_acceptCookies))); - - QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); - settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(m_keepCookies))); -} - -void CookieJar::purgeOldCookies() -{ - QList cookies = allCookies(); - if (cookies.isEmpty()) - return; - int oldCount = cookies.count(); - QDateTime now = QDateTime::currentDateTime(); - for (int i = cookies.count() - 1; i >= 0; --i) { - if (!cookies.at(i).isSessionCookie() && cookies.at(i).expirationDate() < now) - cookies.removeAt(i); - } - if (oldCount == cookies.count()) - return; - setAllCookies(cookies); - emit cookiesChanged(); -} - -QList CookieJar::cookiesForUrl(const QUrl &url) const -{ - CookieJar *that = const_cast(this); - if (!m_loaded) - that->load(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { - QList noCookies; - return noCookies; - } - - // Not sure if this conforms to the cookie specification, in fact I am - // pretty sure it incomplete and in the worst case a security hole. - QList cookies; - QString host = url.host(); - while (host.count(QLatin1Char('.')) > 0) { - QUrl subUrl = url; - subUrl.setHost(host); - cookies += QNetworkCookieJar::cookiesForUrl(subUrl); - host = host.mid(host.indexOf(QLatin1Char('.')) + 1); - } - return cookies; -} - -bool CookieJar::setCookiesFromUrl(const QList &cookieList, const QUrl &url) -{ - if (!m_loaded) - load(); - - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return false; - - QString host = url.host(); - bool eBlock = qBinaryFind(m_exceptions_block.begin(), m_exceptions_block.end(), host) != m_exceptions_block.end(); - bool eAllow = qBinaryFind(m_exceptions_allow.begin(), m_exceptions_allow.end(), host) != m_exceptions_allow.end(); - bool eAllowSession = qBinaryFind(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end(), host) != m_exceptions_allowForSession.end(); - - bool addedCookies = false; - // pass exceptions - bool acceptInitially = (m_acceptCookies != AcceptNever); - if ((acceptInitially && !eBlock) - || (!acceptInitially && (eAllow || eAllowSession))) { - // pass url domain == cookie domain - QDateTime soon = QDateTime::currentDateTime(); - soon = soon.addDays(90); - foreach(QNetworkCookie cookie, cookieList) { - QList lst; - if (m_keepCookies == KeepUntilTimeLimit - && !cookie.isSessionCookie() - && cookie.expirationDate() > soon) { - cookie.setExpirationDate(soon); - } - lst += cookie; - if (QNetworkCookieJar::setCookiesFromUrl(lst, url)) { - addedCookies = true; - } else { - // finally force it in if wanted - if (m_acceptCookies == AcceptAlways) { - QList cookies = allCookies(); - QList::Iterator it = cookies.begin(), - end = cookies.end(); - for ( ; it != end; ++it) { - // does this cookie already exist? - if (cookie.name() == it->name() && - cookie.domain() == it->domain() && - cookie.path() == it->path()) { - // found a match - cookies.erase(it); - break; - } - } - - cookies += cookie; - setAllCookies(cookies); - addedCookies = true; - } -#if 0 - else - qWarning() << "setCookiesFromUrl failed" << url << cookieList.value(0).toRawForm(); -#endif - } - } - } - - if (addedCookies) { - m_saveTimer->changeOccurred(); - emit cookiesChanged(); - } - return addedCookies; -} - -CookieJar::AcceptPolicy CookieJar::acceptPolicy() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_acceptCookies; -} - -void CookieJar::setAcceptPolicy(AcceptPolicy policy) -{ - if (!m_loaded) - load(); - if (policy == m_acceptCookies) - return; - m_acceptCookies = policy; - m_saveTimer->changeOccurred(); -} - -CookieJar::KeepPolicy CookieJar::keepPolicy() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_keepCookies; -} - -void CookieJar::setKeepPolicy(KeepPolicy policy) -{ - if (!m_loaded) - load(); - if (policy == m_keepCookies) - return; - m_keepCookies = policy; - m_saveTimer->changeOccurred(); -} - -QStringList CookieJar::blockedCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_block; -} - -QStringList CookieJar::allowedCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_allow; -} - -QStringList CookieJar::allowForSessionCookies() const -{ - if (!m_loaded) - (const_cast(this))->load(); - return m_exceptions_allowForSession; -} - -void CookieJar::setBlockedCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_block = list; - qSort(m_exceptions_block.begin(), m_exceptions_block.end()); - m_saveTimer->changeOccurred(); -} - -void CookieJar::setAllowedCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_allow = list; - qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); - m_saveTimer->changeOccurred(); -} - -void CookieJar::setAllowForSessionCookies(const QStringList &list) -{ - if (!m_loaded) - load(); - m_exceptions_allowForSession = list; - qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); - m_saveTimer->changeOccurred(); -} - -CookieModel::CookieModel(CookieJar *cookieJar, QObject *parent) - : QAbstractTableModel(parent) - , m_cookieJar(cookieJar) -{ - connect(m_cookieJar, SIGNAL(cookiesChanged()), this, SLOT(cookiesChanged())); - m_cookieJar->load(); -} - -QVariant CookieModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::SizeHintRole) { - QFont font; - font.setPointSize(10); - QFontMetrics fm(font); - int height = fm.height() + fm.height() / 3; - int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); - return QSize(width, height); - } - - if (orientation == Qt::Horizontal) { - if (role != Qt::DisplayRole) - return QVariant(); - - switch (section) { - case 0: - return tr("Website"); - case 1: - return tr("Name"); - case 2: - return tr("Path"); - case 3: - return tr("Secure"); - case 4: - return tr("Expires"); - case 5: - return tr("Contents"); - default: - return QVariant(); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant CookieModel::data(const QModelIndex &index, int role) const -{ - QList lst; - if (m_cookieJar) - lst = m_cookieJar->allCookies(); - if (index.row() < 0 || index.row() >= lst.size()) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - QNetworkCookie cookie = lst.at(index.row()); - switch (index.column()) { - case 0: - return cookie.domain(); - case 1: - return cookie.name(); - case 2: - return cookie.path(); - case 3: - return cookie.isSecure(); - case 4: - return cookie.expirationDate(); - case 5: - return cookie.value(); - } - } - case Qt::FontRole: { - QFont font; - font.setPointSize(10); - return font; - } - } - - return QVariant(); -} - -int CookieModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 6; -} - -int CookieModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !m_cookieJar) ? 0 : m_cookieJar->allCookies().count(); -} - -bool CookieModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid() || !m_cookieJar) - return false; - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - QList lst = m_cookieJar->allCookies(); - for (int i = lastRow; i >= row; --i) { - lst.removeAt(i); - } - m_cookieJar->setAllCookies(lst); - endRemoveRows(); - return true; -} - -void CookieModel::cookiesChanged() -{ - reset(); -} - -CookiesDialog::CookiesDialog(CookieJar *cookieJar, QWidget *parent) : QDialog(parent) -{ - setupUi(this); - setWindowFlags(Qt::Sheet); - CookieModel *model = new CookieModel(cookieJar, this); - m_proxyModel = new QSortFilterProxyModel(this); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - connect(removeButton, SIGNAL(clicked()), cookiesTable, SLOT(removeSelected())); - connect(removeAllButton, SIGNAL(clicked()), cookiesTable, SLOT(removeAll())); - m_proxyModel->setSourceModel(model); - cookiesTable->verticalHeader()->hide(); - cookiesTable->setSelectionBehavior(QAbstractItemView::SelectRows); - cookiesTable->setModel(m_proxyModel); - cookiesTable->setAlternatingRowColors(true); - cookiesTable->setTextElideMode(Qt::ElideMiddle); - cookiesTable->setShowGrid(false); - cookiesTable->setSortingEnabled(true); - QFont f = font(); - f.setPointSize(10); - QFontMetrics fm(f); - int height = fm.height() + fm.height() / 3; - cookiesTable->verticalHeader()->setDefaultSectionSize(height); - cookiesTable->verticalHeader()->setMinimumSectionSize(-1); - for (int i = 0; i < model->columnCount(); ++i) { - int header = cookiesTable->horizontalHeader()->sectionSizeHint(i); - switch (i) { - case 0: - header = fm.width(QLatin1String("averagehost.domain.com")); - break; - case 1: - header = fm.width(QLatin1String("_session_id")); - break; - case 4: - header = fm.width(QDateTime::currentDateTime().toString(Qt::LocalDate)); - break; - } - int buffer = fm.width(QLatin1String("xx")); - header += buffer; - cookiesTable->horizontalHeader()->resizeSection(i, header); - } - cookiesTable->horizontalHeader()->setStretchLastSection(true); -} - - - -CookieExceptionsModel::CookieExceptionsModel(CookieJar *cookiejar, QObject *parent) - : QAbstractTableModel(parent) - , m_cookieJar(cookiejar) -{ - m_allowedCookies = m_cookieJar->allowedCookies(); - m_blockedCookies = m_cookieJar->blockedCookies(); - m_sessionCookies = m_cookieJar->allowForSessionCookies(); -} - -QVariant CookieExceptionsModel::headerData(int section, Qt::Orientation orientation, int role) const -{ - if (role == Qt::SizeHintRole) { - QFont font; - font.setPointSize(10); - QFontMetrics fm(font); - int height = fm.height() + fm.height() / 3; - int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); - return QSize(width, height); - } - - if (orientation == Qt::Horizontal - && role == Qt::DisplayRole) { - switch (section) { - case 0: - return tr("Website"); - case 1: - return tr("Status"); - } - } - return QAbstractTableModel::headerData(section, orientation, role); -} - -QVariant CookieExceptionsModel::data(const QModelIndex &index, int role) const -{ - if (index.row() < 0 || index.row() >= rowCount()) - return QVariant(); - - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: { - int row = index.row(); - if (row < m_allowedCookies.count()) { - switch (index.column()) { - case 0: - return m_allowedCookies.at(row); - case 1: - return tr("Allow"); - } - } - row = row - m_allowedCookies.count(); - if (row < m_blockedCookies.count()) { - switch (index.column()) { - case 0: - return m_blockedCookies.at(row); - case 1: - return tr("Block"); - } - } - row = row - m_blockedCookies.count(); - if (row < m_sessionCookies.count()) { - switch (index.column()) { - case 0: - return m_sessionCookies.at(row); - case 1: - return tr("Allow For Session"); - } - } - } - case Qt::FontRole: { - QFont font; - font.setPointSize(10); - return font; - } - } - return QVariant(); -} - -int CookieExceptionsModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 2; -} - -int CookieExceptionsModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !m_cookieJar) ? 0 : m_allowedCookies.count() + m_blockedCookies.count() + m_sessionCookies.count(); -} - -bool CookieExceptionsModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (parent.isValid() || !m_cookieJar) - return false; - - int lastRow = row + count - 1; - beginRemoveRows(parent, row, lastRow); - for (int i = lastRow; i >= row; --i) { - if (i < m_allowedCookies.count()) { - m_allowedCookies.removeAt(row); - continue; - } - i = i - m_allowedCookies.count(); - if (i < m_blockedCookies.count()) { - m_blockedCookies.removeAt(row); - continue; - } - i = i - m_blockedCookies.count(); - if (i < m_sessionCookies.count()) { - m_sessionCookies.removeAt(row); - continue; - } - } - m_cookieJar->setAllowedCookies(m_allowedCookies); - m_cookieJar->setBlockedCookies(m_blockedCookies); - m_cookieJar->setAllowForSessionCookies(m_sessionCookies); - endRemoveRows(); - return true; -} - -CookiesExceptionsDialog::CookiesExceptionsDialog(CookieJar *cookieJar, QWidget *parent) - : QDialog(parent) - , m_cookieJar(cookieJar) -{ - setupUi(this); - setWindowFlags(Qt::Sheet); - connect(removeButton, SIGNAL(clicked()), exceptionTable, SLOT(removeSelected())); - connect(removeAllButton, SIGNAL(clicked()), exceptionTable, SLOT(removeAll())); - exceptionTable->verticalHeader()->hide(); - exceptionTable->setSelectionBehavior(QAbstractItemView::SelectRows); - exceptionTable->setAlternatingRowColors(true); - exceptionTable->setTextElideMode(Qt::ElideMiddle); - exceptionTable->setShowGrid(false); - exceptionTable->setSortingEnabled(true); - m_exceptionsModel = new CookieExceptionsModel(cookieJar, this); - m_proxyModel = new QSortFilterProxyModel(this); - m_proxyModel->setSourceModel(m_exceptionsModel); - connect(search, SIGNAL(textChanged(QString)), - m_proxyModel, SLOT(setFilterFixedString(QString))); - exceptionTable->setModel(m_proxyModel); - - CookieModel *cookieModel = new CookieModel(cookieJar, this); - domainLineEdit->setCompleter(new QCompleter(cookieModel, domainLineEdit)); - - connect(domainLineEdit, SIGNAL(textChanged(const QString &)), - this, SLOT(textChanged(const QString &))); - connect(blockButton, SIGNAL(clicked()), this, SLOT(block())); - connect(allowButton, SIGNAL(clicked()), this, SLOT(allow())); - connect(allowForSessionButton, SIGNAL(clicked()), this, SLOT(allowForSession())); - - QFont f = font(); - f.setPointSize(10); - QFontMetrics fm(f); - int height = fm.height() + fm.height() / 3; - exceptionTable->verticalHeader()->setDefaultSectionSize(height); - exceptionTable->verticalHeader()->setMinimumSectionSize(-1); - for (int i = 0; i < m_exceptionsModel->columnCount(); ++i) { - int header = exceptionTable->horizontalHeader()->sectionSizeHint(i); - switch (i) { - case 0: - header = fm.width(QLatin1String("averagebiglonghost.domain.com")); - break; - case 1: - header = fm.width(QLatin1String("Allow For Session")); - break; - } - int buffer = fm.width(QLatin1String("xx")); - header += buffer; - exceptionTable->horizontalHeader()->resizeSection(i, header); - } -} - -void CookiesExceptionsDialog::textChanged(const QString &text) -{ - bool enabled = !text.isEmpty(); - blockButton->setEnabled(enabled); - allowButton->setEnabled(enabled); - allowForSessionButton->setEnabled(enabled); -} - -void CookiesExceptionsDialog::block() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_blockedCookies.append(domainLineEdit->text()); - m_cookieJar->setBlockedCookies(m_exceptionsModel->m_blockedCookies); - m_exceptionsModel->reset(); -} - -void CookiesExceptionsDialog::allow() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_allowedCookies.append(domainLineEdit->text()); - m_cookieJar->setAllowedCookies(m_exceptionsModel->m_allowedCookies); - m_exceptionsModel->reset(); -} - -void CookiesExceptionsDialog::allowForSession() -{ - if (domainLineEdit->text().isEmpty()) - return; - m_exceptionsModel->m_sessionCookies.append(domainLineEdit->text()); - m_cookieJar->setAllowForSessionCookies(m_exceptionsModel->m_sessionCookies); - m_exceptionsModel->reset(); -} - diff --git a/src/data/arora-128.png b/src/data/128x128/arora.png similarity index 100% rename from src/data/arora-128.png rename to src/data/128x128/arora.png diff --git a/src/data/128x128/run.license b/src/data/128x128/run.license new file mode 100644 index 00000000..7925f44d --- /dev/null +++ b/src/data/128x128/run.license @@ -0,0 +1,2 @@ +run.png was created by Everaldo Coelho and YellowIcon from the crystal icon set +Crystal icons were posted by the author as LGPL on kde-look under the name (Crystal_Clear_action_run.png) diff --git a/src/data/128x128/run.png b/src/data/128x128/run.png new file mode 100644 index 00000000..e32edb74 Binary files /dev/null and b/src/data/128x128/run.png differ diff --git a/src/data/arora-16.png b/src/data/16x16/arora.png similarity index 100% rename from src/data/arora-16.png rename to src/data/16x16/arora.png diff --git a/src/data/arora-32.png b/src/data/32x32/arora.png similarity index 100% rename from src/data/arora-32.png rename to src/data/32x32/arora.png diff --git a/src/data/arora-512.png b/src/data/512x512/arora.png similarity index 100% rename from src/data/arora-512.png rename to src/data/512x512/arora.png diff --git a/src/data/arora.1 b/src/data/arora.1 new file mode 100644 index 00000000..445131c5 --- /dev/null +++ b/src/data/arora.1 @@ -0,0 +1,53 @@ +.TH ARORA "1" "May 2008" + +.SH NAME +Arora - Lightweight web browser based on Qt and WebKit + +.SH SYNOPSIS +.B arora [Qt options] [url] + +.SH DESCRIPTION +.B Arora +is a lightweight, cross-platform web browser using the Qt 4.4 port of the WebKit +layout engine. It is based on the demo browser application shipped with Qt +demos. + +.SH OPTIONS +.SS Common Qt Options +.TP +.B -style style, -style=style +Specify the Qt widget style to use (examples: plastique, cleanlooks). +.TP +.B -stylesheet stylesheet, -stylesheet=stylesheet +Specify the user stylesheet to use when rendering widgets. +.TP +.B -session session, -session=session +Restore the application from an earlier \fBsession\fR. +.TP +.B -widgetcount +Print a debug message at the end about the number of widgets left undestroyed +and the maximum number of widgets that existed at the same time. +.TP +.B -reverse +Sets the application's layout direction to right-to-left. + +.SS Options Specific to Arora +.TP +.B url +The URL address to open in the browser. + +.SH BUGS +Please report bugs to \fIhttp://code.google.com/p/arora/issues/list\fR. + +.SH AUTHOR +The author of Arora is Benjamin C. Meyer . +.PP +This manual page was written by Matvey Kozhev . +.PP +Permission is granted to copy, distribute and/or modify this document under the +terms of the +GNU General Public License, Version 2 or any later version published by the Free +Software Foundation. +.PP +On Debian systems, the complete text of the GNU General Public License can be +found in /usr/share/common-licenses/GPL. diff --git a/src/data/browser.svg b/src/data/arora.svg similarity index 100% rename from src/data/browser.svg rename to src/data/arora.svg diff --git a/src/data/arora.xml b/src/data/arora.xml new file mode 100644 index 00000000..41d1a425 --- /dev/null +++ b/src/data/arora.xml @@ -0,0 +1,14 @@ + + + + + + Arora + arora + arora %s + arora + false + false + + + \ No newline at end of file diff --git a/src/data/arora.xpm b/src/data/arora.xpm new file mode 100644 index 00000000..d446b8d0 --- /dev/null +++ b/src/data/arora.xpm @@ -0,0 +1,598 @@ +/* XPM */ +static char * arora_xpm[] = { +"32 32 563 2", +" c None", +". c #6B7691", +"+ c #6E7B93", +"@ c #6F7B95", +"# c #6F7A94", +"$ c #717C95", +"% c #727E97", +"& c #BBC3D0", +"* c #CED5DF", +"= c #CCD4DD", +"- c #C5CDD8", +"; c #BCC6D2", +"> c #ADB7C5", +", c #97A3B5", +"' c #7C88A0", +") c #69758F", +"! c #79869E", +"~ c #CED5DE", +"{ c #DFE4E8", +"] c #E2E8E9", +"^ c #E1E7E7", +"/ c #D9E0E0", +"( c #CED7D9", +"_ c #C5CED4", +": c #C0C9D2", +"< c #BEC7D2", +"[ c #B6C2CB", +"} c #6E7B94", +"| c #6E7B95", +"1 c #E4E6EB", +"2 c #F5F7F6", +"3 c #F0F1F1", +"4 c #E8EBEA", +"5 c #DDE3E3", +"6 c #D3DBDB", +"7 c #CAD2D2", +"8 c #C9D2D3", +"9 c #CBD4D3", +"0 c #C2CCD1", +"a c #BDC6D1", +"b c #B6C0CD", +"c c #76829D", +"d c #65738D", +"e c #E8ECEB", +"f c #FAFBFA", +"g c #F3F6F6", +"h c #EBEDED", +"i c #E0E6E6", +"j c #D7DDDF", +"k c #CCD4D4", +"l c #C6CFD0", +"m c #C8D1D1", +"n c #C8D1D2", +"o c #BAC4D1", +"p c #71809A", +"q c #62708B", +"r c #DEE0E4", +"s c #FEFFFD", +"t c #FBFAFA", +"u c #EFF1F2", +"v c #E5E9E9", +"w c #DBDEE1", +"x c #CED7D7", +"y c #C4CECF", +"z c #C7D0D2", +"A c #CAD3D3", +"B c #BEC8D1", +"C c #C1CAD6", +"D c #98A3B8", +"E c #62718C", +"F c #D6DAE0", +"G c #FFFFFF", +"H c #F4F5F6", +"I c #E8ECEC", +"J c #DDE1E4", +"K c #D1D8DA", +"L c #C7D0D1", +"M c #C5D0D0", +"N c #C4CDD1", +"O c #CBD4D5", +"P c #CCD5D5", +"Q c #C4CDD2", +"R c #C1CAD5", +"S c #B4C0CF", +"T c #57647A", +"U c #677490", +"V c #E0E4E6", +"W c #F9F9F8", +"X c #EBEFF0", +"Y c #E1E6E6", +"Z c #D4DCDC", +"` c #CBD3D3", +" . c #C0CACF", +".. c #BEC9D2", +"+. c #B0B9C4", +"@. c #D3D9DA", +"#. c #D7DDDD", +"$. c #CAD1D6", +"%. c #C0C9D4", +"&. c #C6D1DD", +"*. c #6F7C95", +"=. c #6F7B94", +"-. c #E7EBEC", +";. c #FEFFFE", +">. c #F9FBFA", +",. c #EEF1F1", +"'. c #E4E6E9", +"). c #CDD4D6", +"!. c #CED6D6", +"~. c #C3CED0", +"{. c #B8C5D2", +"]. c #818DA2", +"^. c #B5C0CB", +"/. c #9BAAB9", +"(. c #B7BDC8", +"_. c #DCE0E0", +":. c #CDD6D8", +"<. c #C5CFDB", +"[. c #6F7B93", +"}. c #7A869E", +"|. c #79869C", +"1. c #EBEEEE", +"2. c #F8F7F7", +"3. c #FDFFFD", +"4. c #F0F3F2", +"5. c #E6E9EA", +"6. c #DCE2E2", +"7. c #D5DCDC", +"8. c #D0D8D8", +"9. c #C1CBD3", +"0. c #AAB7C8", +"a. c #6D7F9B", +"b. c #A3B0C1", +"c. c #AAB1C0", +"d. c #E4E8E8", +"e. c #D3DADA", +"f. c #BECAD4", +"g. c #C6D1DB", +"h. c #6E7A94", +"i. c #76839B", +"j. c #808B9F", +"k. c #ECEFEE", +"l. c #D0D5DC", +"m. c #A0A8BB", +"n. c #EFF1F3", +"o. c #F1F4F3", +"p. c #E9EBEA", +"q. c #E1E4E5", +"r. c #D9DFDD", +"s. c #CED6D5", +"t. c #CDD5D4", +"u. c #D8DFDE", +"v. c #E8ECEA", +"w. c #BAC5D3", +"x. c #97A7B9", +"y. c #6A7E9A", +"z. c #B0B8C1", +"A. c #F2F3F0", +"B. c #D7DFDE", +"C. c #C4CED5", +"D. c #CAD4DD", +"E. c #74819B", +"F. c #687590", +"G. c #E1E6E5", +"H. c #A8B8C8", +"I. c #C3CDDA", +"J. c #EAEEEC", +"K. c #E2E6E6", +"L. c #D3D7D8", +"M. c #8F9AAA", +"N. c #6D7A94", +"O. c #6B7793", +"P. c #B6BEC4", +"Q. c #EFF2EF", +"R. c #DFE4E3", +"S. c #CCD4D5", +"T. c #B9C5D6", +"U. c #6D7E9C", +"V. c #6C839A", +"W. c #F6F7F3", +"X. c #E2E7E5", +"Y. c #D6DDDF", +"Z. c #C6D2DC", +"`. c #7D89A4", +" + c #98A2B2", +".+ c #EAEDEB", +"++ c #EDF2EF", +"@+ c #EBF0F1", +"#+ c #EDF0EF", +"$+ c #E9ECEA", +"%+ c #DADEDF", +"&+ c #8B96A8", +"*+ c #6B7A93", +"=+ c #6186A1", +"-+ c #4878A2", +";+ c #305392", +">+ c #5C6B8E", +",+ c #B1B9C3", +"'+ c #F1F3F0", +")+ c #D2D9D7", +"!+ c #C2CDD6", +"~+ c #8394AB", +"{+ c #114E7D", +"]+ c #818CA2", +"^+ c #EEF1ED", +"/+ c #E1E7E5", +"(+ c #D0D9E0", +"_+ c #A8B4C4", +":+ c #5E6D89", +"<+ c #BBC2CA", +"[+ c #E9EDEC", +"}+ c #E9EDED", +"|+ c #E5EAE9", +"1+ c #C2C9CE", +"2+ c #6D7A93", +"3+ c #7692AC", +"4+ c #79A0B7", +"5+ c #83B2C5", +"6+ c #85BCCD", +"7+ c #4163A3", +"8+ c #315393", +"9+ c #6E7994", +"0+ c #EEF1EC", +"a+ c #D9E0DC", +"b+ c #C4CED9", +"c+ c #7888A1", +"d+ c #0D3675", +"e+ c #13306C", +"f+ c #8798A8", +"g+ c #E4E8E7", +"h+ c #DEE4E5", +"i+ c #CFD8E2", +"j+ c #7885A0", +"k+ c #65738E", +"l+ c #B5BDCE", +"m+ c #C6CBD8", +"n+ c #C4C9D4", +"o+ c #E4E9E6", +"p+ c #E1E5E4", +"q+ c #768399", +"r+ c #91ABBF", +"s+ c #9ABACB", +"t+ c #B5DBE4", +"u+ c #ABD6E2", +"v+ c #9BCDD9", +"w+ c #5782AE", +"x+ c #315292", +"y+ c #5C6B8D", +"z+ c #DBDEDD", +"A+ c #E2E5E2", +"B+ c #C6D0DA", +"C+ c #747F98", +"D+ c #0E2C6E", +"E+ c #0B2B6D", +"F+ c #0E4475", +"G+ c #8C9CAD", +"H+ c #EBEEEC", +"I+ c #D8E0E7", +"J+ c #9BA6BC", +"K+ c #727F97", +"L+ c #E3E9E8", +"M+ c #E5EAE7", +"N+ c #DFE3E2", +"O+ c #DBE1DE", +"P+ c #8A95A6", +"Q+ c #8A99AD", +"R+ c #A8BECE", +"S+ c #D3F0F1", +"T+ c #C5E7EC", +"U+ c #B0D9E1", +"V+ c #9DCDDA", +"W+ c #5F8BB1", +"X+ c #294889", +"Y+ c #334A80", +"Z+ c #B3B8C1", +"`+ c #E7EAE5", +" @ c #C8D4DC", +".@ c #6C7993", +"+@ c #0D2E6B", +"@@ c #0E2E6F", +"#@ c #496A8D", +"$@ c #C2C7CF", +"%@ c #DFE6E3", +"&@ c #D2DAE3", +"*@ c #97A3B9", +"=@ c #A2ABBA", +"-@ c #E4E9E8", +";@ c #DFE5E2", +">@ c #C9CFD2", +",@ c #79869B", +"'@ c #7089A8", +")@ c #99B1C5", +"!@ c #CDE2E8", +"~@ c #DEF8F9", +"{@ c #C6E6EB", +"]@ c #AFD7E0", +"^@ c #9CCBD8", +"/@ c #85BBCD", +"(@ c #5B92B1", +"_@ c #4E8AAB", +":@ c #8D98A9", +"<@ c #EAEDE7", +"[@ c #C8D2D9", +"}@ c #6A7894", +"|@ c #0F2E6F", +"1@ c #143371", +"2@ c #7C889D", +"3@ c #EDF1E8", +"4@ c #D4DBDF", +"5@ c #99A3B8", +"6@ c #6C768B", +"7@ c #697891", +"8@ c #797C86", +"9@ c #CAD1CF", +"0@ c #878B96", +"a@ c #7B8AA0", +"b@ c #4D6E9C", +"c@ c #294986", +"d@ c #2F4F8E", +"e@ c #5273A6", +"f@ c #D6F4F4", +"g@ c #C0E4E9", +"h@ c #AAD3DE", +"i@ c #98C7D5", +"j@ c #71AFC4", +"k@ c #57A2BA", +"l@ c #777F97", +"m@ c #EEF1E8", +"n@ c #D3DBDF", +"o@ c #7C869D", +"p@ c #133170", +"q@ c #173673", +"r@ c #487394", +"s@ c #8591A3", +"t@ c #7C8EA4", +"u@ c #355B8A", +"v@ c #707682", +"w@ c #7A7F8C", +"x@ c #6F83A0", +"y@ c #76A2BB", +"z@ c #2F4F89", +"A@ c #395993", +"B@ c #365591", +"C@ c #2C4A89", +"D@ c #B5D9E2", +"E@ c #B5DDE5", +"F@ c #A1CED9", +"G@ c #90C2D1", +"H@ c #7EB7C9", +"I@ c #6AABC2", +"J@ c #539FB9", +"K@ c #6A7A95", +"L@ c #E9E6E2", +"M@ c #A9AFBC", +"N@ c #657191", +"O@ c #183774", +"P@ c #1D3976", +"Q@ c #1D3A75", +"R@ c #094C83", +"S@ c #006393", +"T@ c #26679D", +"U@ c #374461", +"V@ c #456894", +"W@ c #5E87AB", +"X@ c #375793", +"Y@ c #33548D", +"Z@ c #2C4984", +"`@ c #466596", +" # c #A6D4DC", +".# c #96C8D6", +"+# c #87BCCD", +"@# c #76B0C6", +"## c #65A5BD", +"$# c #509BB5", +"%# c #4083A2", +"&# c #6E7893", +"*# c #4F5D86", +"=# c #193572", +"-# c #1E3A76", +";# c #223E78", +"># c #1D3774", +",# c #08246A", +"'# c #082B72", +")# c #2A5B90", +"!# c #3B5D8C", +"~# c #72A0C4", +"{# c #385692", +"]# c #35538C", +"^# c #2F4E88", +"/# c #2A4480", +"(# c #1E3776", +"_# c #5A82A5", +":# c #8AC0D0", +"<# c #7AB4C7", +"[# c #6CA9C0", +"}# c #5B9FB9", +"|# c #4B95B2", +"1# c #388DAC", +"2# c #2680A3", +"3# c #193E78", +"4# c #203975", +"5# c #233E78", +"6# c #1B3674", +"7# c #0C296C", +"8# c #0C276C", +"9# c #136398", +"0# c #20437C", +"a# c #1C3E73", +"b# c #6E98C0", +"c# c #324F8B", +"d# c #2F4D86", +"e# c #2A4781", +"f# c #243F7A", +"g# c #345286", +"h# c #7CAFC5", +"i# c #7AB7CA", +"j# c #6EABC1", +"k# c #60A2BB", +"l# c #5298B4", +"m# c #4490AD", +"n# c #3288A7", +"o# c #2380A3", +"p# c #18618E", +"q# c #233975", +"r# c #132E6E", +"s# c #0C286B", +"t# c #0D276B", +"u# c #024D85", +"v# c #2987B5", +"w# c #12376B", +"x# c #092D68", +"y# c #608BB6", +"z# c #2B4882", +"A# c #284680", +"B# c #26407B", +"C# c #1F3874", +"D# c #49759C", +"E# c #77BACA", +"F# c #6BACC2", +"G# c #5FA2BB", +"H# c #5499B5", +"I# c #4792AE", +"J# c #3A89A8", +"K# c #2B81A3", +"L# c #1B7A9D", +"M# c #0F6D96", +"N# c #0F256A", +"O# c #0D2769", +"P# c #0F266A", +"Q# c #05457E", +"R# c #00739D", +"S# c #307EB0", +"T# c #0E2B5C", +"U# c #315A8E", +"V# c #254180", +"W# c #213E78", +"X# c #213C77", +"Y# c #203974", +"Z# c #1F3673", +"`# c #5E9EB9", +" $ c #5BA2BA", +".$ c #5098B4", +"+$ c #4690AE", +"@$ c #3B89A8", +"#$ c #2C7EA2", +"$$ c #11739A", +"%$ c #006893", +"&$ c #005283", +"*$ c #0F2367", +"=$ c #102569", +"-$ c #06437D", +";$ c #007198", +">$ c #167FAC", +",$ c #2C5187", +"'$ c #05295E", +")$ c #315392", +"!$ c #0E2A6E", +"~$ c #122E6E", +"{$ c #193070", +"]$ c #1D316E", +"^$ c #4382A6", +"/$ c #4594B1", +"($ c #3A8BAA", +"_$ c #2C81A4", +":$ c #19759B", +"<$ c #036A93", +"[$ c #006490", +"}$ c #006992", +"|$ c #0B3373", +"1$ c #102568", +"2$ c #054880", +"3$ c #006F97", +"4$ c #02769F", +"5$ c #3773A4", +"6$ c #0E2654", +"7$ c #11326D", +"8$ c #37649F", +"9$ c #1A598E", +"0$ c #0C2B6E", +"a$ c #123C78", +"b$ c #2887A8", +"c$ c #207EA2", +"d$ c #16769D", +"e$ c #0B6E96", +"f$ c #006791", +"g$ c #00648F", +"h$ c #006690", +"i$ c #005D8B", +"j$ c #0A3674", +"k$ c #00638F", +"l$ c #006D98", +"m$ c #00709B", +"n$ c #3184B2", +"o$ c #1A3972", +"p$ c #254E80", +"q$ c #3C90B9", +"r$ c #1985A9", +"s$ c #157BA1", +"t$ c #11799E", +"u$ c #097098", +"v$ c #016A94", +"w$ c #006691", +"x$ c #006892", +"y$ c #006994", +"z$ c #006A95", +"A$ c #006D97", +"B$ c #00729E", +"C$ c #2E82B2", +"D$ c #294B83", +"E$ c #1C3972", +"F$ c #3874A6", +"G$ c #117BA6", +"H$ c #006A96", +"I$ c #006894", +"J$ c #006793", +"K$ c #006995", +"L$ c #006B97", +"M$ c #006D99", +"N$ c #157CAA", +"O$ c #3870A5", +"P$ c #1E3B74", +"Q$ c #0D2A5F", +"R$ c #2F588D", +"S$ c #2F7EAF", +"T$ c #2180AF", +"U$ c #0F77A5", +"V$ c #006E9B", +"W$ c #00709D", +"X$ c #137AA7", +"Y$ c #2581B2", +"Z$ c #347DAE", +"`$ c #2F5289", +" % c #142C5A", +".% c #143266", +"+% c #203D74", +"@% c #324E86", +"#% c #3B659B", +"$% c #3970A3", +"%% c #3B6498", +"&% c #334C84", +"*% c #213C75", +"=% c #163465", +"-% c #141D3E", +" . + @ # $ ", +" % & * = - ; > , ' ) ", +" ! ~ { ] ^ / ( _ : < [ } ", +" | 1 2 3 4 5 6 7 8 9 0 a b c ", +" d e f g h i j k l m n 8 0 < o p ", +" q r s t u v w x y l z n n A B C D ", +" E F G G H I J K L M z N n O P Q R S T ", +" U V G G W X Y Z ` .z 7 ..+.@.#.$.%.&.*. ", +" =.-.;.G >.,.'.j ).!.~.{.].^./.(._.:.%.<.[. ", +" }.|.1.2.3.f 4.5.6.@.l 7.8.9.0.a.b.c.d.e.f.g.h. ", +" i.j.k.l.m.n.o.p.q.r.s.t.u.v.P w.x.y.z.A.B.C.D.E. ", +" F.G.5.H.I.I J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.`. ", +" +.+++@+#+$+%+&+*+=+-+;+>+,+'+)+!+~+{+]+^+/+(+_+ ", +" :+<+[+}+[+|+1+2+3+4+5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+j+ ", +" k+l+m+n+o+p+q+r+s+t+u+v+w+x+y+z+A+B+C+D+E+F+G+H+I+J+ ", +" K+L+M+N+O+P+Q+R+S+T+U+V+W+X+Y+Z+`+ @.@+@@@#@$@%@&@*@ ", +" =@-@;@>@,@'@)@!@~@{@]@^@/@(@_@:@<@[@}@|@1@2@3@4@5@6@ ", +" 7@8@9@0@a@b@c@d@e@f@g@h@i@6+j@k@l@m@n@o@p@q@r@s@t@u@ ", +" 7@v@w@x@y@z@A@B@C@D@E@F@G@H@I@J@K@L@M@N@O@P@Q@R@S@T@ ", +" U@V@W@X@A@Y@Z@`@ #.#+#@###$#%#&#*#=#-#;#>#,#'#)# ", +" !#~#{#]#^#/#(#_#:#<#[#}#|#1#2#3#4#5#6#7#8#9#0# ", +" a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w# ", +" x#y#z#A#B#C#D#E#F#G#H#I#J#K#L#M#N#O#P#Q#R#S#T# ", +" U#V#W#X#Y#Z#`# $.$+$@$#$$$%$&$*$=$-$;$>$,$ ", +" '$)$!$~${$]$^$/$($_$:$<$[$}$|$1$2$3$4$5$6$ ", +" 7$8$9$0$a$b$c$d$e$f$g$h$i$j$k$l$m$n$o$ ", +" p$q$r$s$t$u$v$[$[$w$x$y$z$A$B$C$D$ ", +" E$F$G$H$I$J$J$J$K$z$L$M$N$O$P$ ", +" Q$R$S$T$U$V$M$W$X$Y$Z$`$ % ", +" .%+%@%#%$%%%&%*%=% ", +" -% ", +" "}; diff --git a/src/data/data.qrc b/src/data/data.qrc index 780b9e78..8769d1b3 100644 --- a/src/data/data.qrc +++ b/src/data/data.qrc @@ -1,12 +1,11 @@ - addtab.png - closetab.png - history.png - arora-128.png + 128x128/arora.png + 128x128/run.png + arora.svg defaultbookmarks.xbel - loading.gif - defaulticon.png + fetchLinks.js + parseForms.js ../../AUTHORS ../../LICENSE.GPL2 diff --git a/src/data/defaultbookmarks.xbel b/src/data/defaultbookmarks.xbel index b749aca1..58699291 100644 --- a/src/data/defaultbookmarks.xbel +++ b/src/data/defaultbookmarks.xbel @@ -6,32 +6,8 @@ Arora - - WebKit.org - - - Qt Documentation - - - Qt Quarterly - - - Trolltech Labs - - - Qt Centre - - - Qt-Apps.org - - - xkcd - Bookmarks Menu - - reddit.com: what's new online! - diff --git a/src/data/fetchLinks.js b/src/data/fetchLinks.js new file mode 100644 index 00000000..f3436549 --- /dev/null +++ b/src/data/fetchLinks.js @@ -0,0 +1,15 @@ +(function (){ + var links = new Array; + var it = document.evaluate('/html/head/link', document, null, XPathResult.ANY_TYPE, null); + var link = it.iterateNext(); + while (link) { + var obj = new Object; + obj.rel = link.rel; + obj.type = link.type; + obj.href = link.href; + obj.title = link.title; + links.push(obj); + link = it.iterateNext(); + } + return links; +})(); \ No newline at end of file diff --git a/src/data/addtab.png b/src/data/graphics/addtab.png similarity index 100% rename from src/data/addtab.png rename to src/data/graphics/addtab.png diff --git a/src/data/closetab.png b/src/data/graphics/closetab.png similarity index 100% rename from src/data/closetab.png rename to src/data/graphics/closetab.png diff --git a/src/data/defaulticon.png b/src/data/graphics/defaulticon.png similarity index 100% rename from src/data/defaulticon.png rename to src/data/graphics/defaulticon.png diff --git a/src/data/graphics/graphics.qrc b/src/data/graphics/graphics.qrc new file mode 100644 index 00000000..e1770c1c --- /dev/null +++ b/src/data/graphics/graphics.qrc @@ -0,0 +1,10 @@ + + + addtab.png + closetab.png + defaulticon.png + history.png + loading.gif + private.png + + diff --git a/src/data/history.png b/src/data/graphics/history.png similarity index 100% rename from src/data/history.png rename to src/data/graphics/history.png diff --git a/src/data/loading.gif b/src/data/graphics/loading.gif similarity index 100% rename from src/data/loading.gif rename to src/data/graphics/loading.gif diff --git a/src/data/graphics/private.png b/src/data/graphics/private.png new file mode 100644 index 00000000..8f5e43f6 Binary files /dev/null and b/src/data/graphics/private.png differ diff --git a/src/data/parseForms.js b/src/data/parseForms.js new file mode 100644 index 00000000..2eadb0b8 --- /dev/null +++ b/src/data/parseForms.js @@ -0,0 +1,23 @@ +(function (){ + var forms = new Array; + for (var i = 0; i < document.forms.length; ++i) { + var form = document.forms[i]; + var formObject = new Object; + formObject.name = form.name; + var elements = new Array; + for (var j = 0; j < form.elements.length; ++j) { + var e = form.elements[j]; + var element = new Object; + element.name = e.name; + element.value = e.value; + element.type = e.type; + element.autocomplete = e.attributes.getNamedItem("autocomplete"); + if (element.autocomplete != null) + element.autocomplete = element.autocomplete.value; + elements.push(element); + } + formObject.elements = elements; + forms.push(formObject); + } + return forms; +}()) diff --git a/src/data/searchengines/Google.xml b/src/data/searchengines/Google.xml new file mode 100644 index 00000000..18122858 --- /dev/null +++ b/src/data/searchengines/Google.xml @@ -0,0 +1,8 @@ + + + Google + Google Web Search + + + http://www.google.com/favicon.ico + \ No newline at end of file diff --git a/src/data/searchengines/Google_Im_Feeling_Lucky.xml b/src/data/searchengines/Google_Im_Feeling_Lucky.xml new file mode 100644 index 00000000..b216be47 --- /dev/null +++ b/src/data/searchengines/Google_Im_Feeling_Lucky.xml @@ -0,0 +1,8 @@ + + + Google (I'm Feeling Lucky) + Google Web Search + + + http://www.google.com/favicon.ico + \ No newline at end of file diff --git a/src/data/searchengines/Reddit.xml b/src/data/searchengines/Reddit.xml new file mode 100644 index 00000000..ec250fb3 --- /dev/null +++ b/src/data/searchengines/Reddit.xml @@ -0,0 +1,7 @@ + + + Reddit + Reddit Site Search + + http://www.reddit.com/favicon.ico + \ No newline at end of file diff --git a/src/data/searchengines/Wikipedia_en.xml b/src/data/searchengines/Wikipedia_en.xml new file mode 100644 index 00000000..a6ed7351 --- /dev/null +++ b/src/data/searchengines/Wikipedia_en.xml @@ -0,0 +1,8 @@ + + + Wikipedia (en) + Full text search in the English Wikipedia + + + http://en.wikipedia.org/favicon.ico + \ No newline at end of file diff --git a/src/data/searchengines/Yahoo.xml b/src/data/searchengines/Yahoo.xml new file mode 100644 index 00000000..007d79f1 --- /dev/null +++ b/src/data/searchengines/Yahoo.xml @@ -0,0 +1,7 @@ + + + Yahoo! + Yahoo Web Search + + http://www.yahoo.com/favicon.ico + \ No newline at end of file diff --git a/src/data/searchengines/YouTube.xml b/src/data/searchengines/YouTube.xml new file mode 100644 index 00000000..03fe5f94 --- /dev/null +++ b/src/data/searchengines/YouTube.xml @@ -0,0 +1,8 @@ + + + YouTube + YouTube + + + http://www.youtube.com/favicon.ico + \ No newline at end of file diff --git a/src/data/searchengines/searchengines.qrc b/src/data/searchengines/searchengines.qrc new file mode 100644 index 00000000..de90aef0 --- /dev/null +++ b/src/data/searchengines/searchengines.qrc @@ -0,0 +1,10 @@ + + + Google.xml + Google_Im_Feeling_Lucky.xml + Yahoo.xml + Wikipedia_en.xml + YouTube.xml + Reddit.xml + + diff --git a/src/downloaditem.ui b/src/downloaditem.ui index 4a0a0fd9..e927a59e 100644 --- a/src/downloaditem.ui +++ b/src/downloaditem.ui @@ -9,9 +9,6 @@ 110 - - Form - 0 diff --git a/src/downloadmanager.cpp b/src/downloadmanager.cpp index 3afea011..81963535 100644 --- a/src/downloadmanager.cpp +++ b/src/downloadmanager.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * Copyright 2008 Jason A. Donenfeld * * This program is free software; you can redistribute it and/or modify @@ -73,13 +73,18 @@ #include #include #include +#include #include +#include +#include #include #include #include +//#define DOWNLOADMANAGER_DEBUG + /*! DownloadItem is a widget that is displayed in the download manager list. It moves the data from the QNetworkReply into the QFile as well @@ -90,6 +95,10 @@ DownloadItem::DownloadItem(QNetworkReply *reply, bool requestFileName, QWidget * , m_reply(reply) , m_requestFileName(requestFileName) , m_bytesReceived(0) + , m_startedSaving(false) + , m_finishedDownloading(false) + , m_gettingFileName(false) + , m_canceledFileSelect(false) { setupUi(this); QPalette p = downloadInfoLabel->palette(); @@ -118,6 +127,8 @@ void DownloadItem::init() m_startedSaving = false; m_finishedDownloading = false; + openButton->setEnabled(false); + // attach to the m_reply m_url = m_reply->url(); m_reply->setParent(this); @@ -147,24 +158,41 @@ void DownloadItem::init() void DownloadItem::getFileName() { - QSettings settings; - settings.beginGroup(QLatin1String("downloadmanager")); - QString defaultLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); - QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString(); - if (!downloadDirectory.isEmpty()) - downloadDirectory += QLatin1Char('/'); + if (m_gettingFileName) + return; + + QString downloadDirectory = BrowserApplication::downloadManager()->downloadDirectory(); QString defaultFileName = saveFileName(downloadDirectory); QString fileName = defaultFileName; if (m_requestFileName) { + m_gettingFileName = true; fileName = QFileDialog::getSaveFileName(this, tr("Save File"), defaultFileName); + m_gettingFileName = false; if (fileName.isEmpty()) { - m_reply->close(); + progressBar->setVisible(false); + stop(); fileNameLabel->setText(tr("Download canceled: %1").arg(QFileInfo(defaultFileName).fileName())); + m_canceledFileSelect = true; return; } + QFileInfo fileInfo = QFileInfo(fileName); + BrowserApplication::downloadManager()->setDownloadDirectory(fileInfo.absoluteDir().absolutePath()); + fileNameLabel->setText(fileInfo.fileName()); } m_output.setFileName(fileName); + + // Check file path for saving. + QDir saveDirPath = QFileInfo(m_output.fileName()).dir(); + if (!saveDirPath.exists()) { + if (!saveDirPath.mkpath(saveDirPath.absolutePath())) { + progressBar->setVisible(false); + stop(); + downloadInfoLabel->setText(tr("Download directory (%1) couldn't be created.").arg(saveDirPath.absolutePath())); + return; + } + } + fileNameLabel->setText(QFileInfo(m_output.fileName()).fileName()); if (m_requestFileName) downloadReadyRead(); @@ -175,7 +203,7 @@ QString DownloadItem::saveFileName(const QString &directory) const // Move this function into QNetworkReply to also get file name sent from the server QString path; if (m_reply->hasRawHeader("Content-Disposition")) { - QString value = m_reply->rawHeader("Content-Disposition"); + QString value = QLatin1String(m_reply->rawHeader("Content-Disposition")); int pos = value.indexOf(QLatin1String("filename=")); if (pos != -1) { QString name = value.mid(pos + 9); @@ -193,14 +221,21 @@ QString DownloadItem::saveFileName(const QString &directory) const if (baseName.isEmpty()) { baseName = QLatin1String("unnamed_download"); - qDebug() << "DownloadManager:: downloading unknown file:" << m_url; + +#ifdef DOWNLOADMANAGER_DEBUG + qDebug() << "DownloadItem::" << __FUNCTION__ << "downloading unknown file:" << m_url; +#endif } - QString name = directory + baseName + QLatin1Char('.') + endName; + + if (!endName.isEmpty()) + endName = QLatin1Char('.') + endName; + + QString name = directory + baseName + endName; if (!m_requestFileName && QFile::exists(name)) { // already exists, don't overwrite int i = 1; do { - name = directory + baseName + QLatin1Char('-') + QString::number(i++) + QLatin1Char('.') + endName; + name = directory + baseName + QLatin1Char('-') + QString::number(i++) + endName; } while (QFile::exists(name)); } return name; @@ -215,12 +250,13 @@ void DownloadItem::stop() tryAgainButton->show(); setUpdatesEnabled(true); m_reply->abort(); + emit downloadFinished(); } void DownloadItem::open() { QFileInfo info(m_output); - QUrl url = QUrl::fromLocalFile(info.absolutePath()); + QUrl url = QUrl::fromLocalFile(info.absoluteFilePath()); QDesktopServices::openUrl(url); } @@ -254,7 +290,7 @@ void DownloadItem::downloadReadyRead() if (!m_requestFileName) getFileName(); if (!m_output.open(QIODevice::WriteOnly)) { - downloadInfoLabel->setText(tr("Error opening save file: %1") + downloadInfoLabel->setText(tr("Error opening output file: %1") .arg(m_output.errorString())); stop(); emit statusChanged(); @@ -275,90 +311,122 @@ void DownloadItem::downloadReadyRead() void DownloadItem::error(QNetworkReply::NetworkError) { - qDebug() << "DownloadItem::error" << m_reply->errorString() << m_url; +#ifdef DOWNLOADMANAGER_DEBUG + qDebug() << "DownloadItem::" << __FUNCTION__ << m_reply->errorString() << m_url; +#endif + downloadInfoLabel->setText(tr("Network Error: %1").arg(m_reply->errorString())); tryAgainButton->setEnabled(true); tryAgainButton->setVisible(true); + emit downloadFinished(); } void DownloadItem::metaDataChanged() { - qDebug() << "DownloadItem::metaDataChanged: not handled."; + QVariant locationHeader = m_reply->header(QNetworkRequest::LocationHeader); + if (locationHeader.isValid()) { + m_url = locationHeader.toUrl(); + m_reply->deleteLater(); + m_reply = BrowserApplication::networkAccessManager()->get(QNetworkRequest(m_url)); + init(); + return; + } + +#ifdef DOWNLOADMANAGER_DEBUG + qDebug() << "DownloadItem::" << __FUNCTION__ << "not handled."; +#endif } void DownloadItem::downloadProgress(qint64 bytesReceived, qint64 bytesTotal) { + QTime now = QTime::currentTime(); + if (m_lastProgressTime.msecsTo(now) < 200) + return; + + m_lastProgressTime = now; + m_bytesReceived = bytesReceived; - if (bytesTotal == -1) { - progressBar->setValue(0); - progressBar->setMaximum(0); - } else { - progressBar->setValue(bytesReceived); - progressBar->setMaximum(bytesTotal); + qint64 currentValue = 0; + qint64 totalValue = 0; + if (bytesTotal > 0) { + currentValue = bytesReceived * 100 / bytesTotal; + totalValue = 100; } + progressBar->setValue(currentValue); + progressBar->setMaximum(totalValue); + + emit progress(currentValue, totalValue); updateInfoLabel(); } +qint64 DownloadItem::bytesTotal() const +{ + return m_reply->header(QNetworkRequest::ContentLengthHeader).toULongLong(); +} + +qint64 DownloadItem::bytesReceived() const +{ + return m_bytesReceived; +} + +double DownloadItem::remainingTime() const +{ + if (!downloading()) + return -1.0; + + double timeRemaining = ((double)(bytesTotal() - bytesReceived())) / currentSpeed(); + + // When downloading the eta should never be 0 + if (timeRemaining == 0) + timeRemaining = 1; + + return timeRemaining; +} + +double DownloadItem::currentSpeed() const +{ + if (!downloading()) + return -1.0; + + return m_bytesReceived * 1000.0 / m_downloadTime.elapsed(); +} + void DownloadItem::updateInfoLabel() { if (m_reply->error() != QNetworkReply::NoError) return; - qint64 bytesTotal = progressBar->maximum(); + qint64 bytesTotal = m_reply->header(QNetworkRequest::ContentLengthHeader).toULongLong(); bool running = !downloadedSuccessfully(); // update info label - double speed = m_bytesReceived * 1000.0 / m_downloadTime.elapsed(); - double timeRemaining = ((double)(bytesTotal - m_bytesReceived)) / speed; - QString timeRemainingString = tr("seconds"); - if (timeRemaining > 60) { - timeRemaining = timeRemaining / 60; - timeRemainingString = tr("minutes"); - } - timeRemaining = floor(timeRemaining); - - // When downloading the eta should never be 0 - if (timeRemaining == 0) - timeRemaining = 1; + double speed = currentSpeed(); + double timeRemaining = remainingTime(); QString info; if (running) { QString remaining; - if (bytesTotal != 0) - remaining = tr("- %4 %5 remaining") - .arg(timeRemaining) - .arg(timeRemainingString); - info = QString(tr("%1 of %2 (%3/sec) %4")) - .arg(dataString(m_bytesReceived)) - .arg(bytesTotal == 0 ? tr("?") : dataString(bytesTotal)) - .arg(dataString((int)speed)) + + if (bytesTotal != 0) { + remaining = DownloadManager::timeString(timeRemaining); + } + + info = QString(tr("%1 of %2 (%3/sec) - %4")) + .arg(DownloadManager::dataString(m_bytesReceived)) + .arg(bytesTotal == 0 ? tr("?") : DownloadManager::dataString(bytesTotal)) + .arg(DownloadManager::dataString((int)speed)) .arg(remaining); } else { if (m_bytesReceived == bytesTotal) - info = dataString(m_output.size()); + info = DownloadManager::dataString(m_output.size()); else - info = tr("%1 of %2 - Stopped") - .arg(dataString(m_bytesReceived)) - .arg(dataString(bytesTotal)); + info = tr("%1 of %2 - Download Complete") + .arg(DownloadManager::dataString(m_bytesReceived)) + .arg(DownloadManager::dataString(bytesTotal)); } downloadInfoLabel->setText(info); } -QString DownloadItem::dataString(int size) const -{ - QString unit; - if (size < 1024) { - unit = tr("bytes"); - } else if (size < 1024 * 1024) { - size /= 1024; - unit = tr("kB"); - } else { - size /= 1024 * 1024; - unit = tr("MB"); - } - return QString(QLatin1String("%1 %2")).arg(size).arg(unit); -} - bool DownloadItem::downloading() const { return (progressBar->isVisible()); @@ -378,9 +446,11 @@ void DownloadItem::finished() progressBar->hide(); stopButton->setEnabled(false); stopButton->hide(); + openButton->setEnabled(true); m_output.close(); updateInfoLabel(); emit statusChanged(); + emit downloadFinished(); } /*! @@ -392,19 +462,26 @@ void DownloadItem::finished() DownloadManager::DownloadManager(QWidget *parent) : QDialog(parent) , m_autoSaver(new AutoSaver(this)) + , m_model(new DownloadModel(this)) , m_manager(BrowserApplication::networkAccessManager()) , m_iconProvider(0) , m_removePolicy(Never) { setupUi(this); + + QSettings settings; + settings.beginGroup(QLatin1String("downloadmanager")); + QString defaultLocation = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation); + setDownloadDirectory(settings.value(QLatin1String("downloadDirectory"), defaultLocation).toString()); + downloadsView->setShowGrid(false); downloadsView->verticalHeader()->hide(); downloadsView->horizontalHeader()->hide(); downloadsView->setAlternatingRowColors(true); downloadsView->horizontalHeader()->setStretchLastSection(true); - m_model = new DownloadModel(this); downloadsView->setModel(m_model); connect(cleanupButton, SIGNAL(clicked()), this, SLOT(cleanup())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(close())); load(); } @@ -426,10 +503,50 @@ int DownloadManager::activeDownloads() const return count; } +bool DownloadManager::allowQuit() +{ + if (activeDownloads() >= 1) { + int choice = QMessageBox::warning(this, QString(), + tr("There are %1 downloads in progress\n" + "Do you want to quit anyway?").arg(activeDownloads()), + QMessageBox::Yes | QMessageBox::No, + QMessageBox::No); + if (choice == QMessageBox::No) { + show(); + return false; + } + } + return true; +} + +bool DownloadManager::externalDownload(const QUrl &url) +{ + QSettings settings; + settings.beginGroup(QLatin1String("downloadmanager")); + if (!settings.value(QLatin1String("external"), false).toBool()) + return false; + + QString program = settings.value(QLatin1String("externalPath")).toString(); + if (program.isEmpty()) + return false; + + // Split program at every space not inside double quotes + QRegExp regex(QLatin1String("\"([^\"]+)\"|([^ ]+)")); + QStringList args; + for (int pos = 0; (pos = regex.indexIn(program, pos)) != -1; pos += regex.matchedLength()) + args << regex.cap(1) + regex.cap(2); + if (args.isEmpty()) + return false; + + return QProcess::startDetached(args.takeFirst(), args << QString::fromUtf8(url.toEncoded())); +} + void DownloadManager::download(const QNetworkRequest &request, bool requestFileName) { if (request.url().isEmpty()) return; + if (externalDownload(request.url())) + return; handleUnsupportedContent(m_manager->get(request), requestFileName); } @@ -437,40 +554,72 @@ void DownloadManager::handleUnsupportedContent(QNetworkReply *reply, bool reques { if (!reply || reply->url().isEmpty()) return; + if (externalDownload(reply->url())) + return; + QVariant header = reply->header(QNetworkRequest::ContentLengthHeader); bool ok; int size = header.toInt(&ok); if (ok && size == 0) return; - qDebug() << "DownloadManager::handleUnsupportedContent" << reply->url() << "requestFileName" << requestFileName; +#ifdef DOWNLOADMANAGER_DEBUG + qDebug() << "DownloadManager::" << __FUNCTION__ << reply->url() << "requestFileName" << requestFileName; +#endif + DownloadItem *item = new DownloadItem(reply, requestFileName, this); addItem(item); + + if (item->m_canceledFileSelect) + return; + + if (!isVisible()) + show(); + + activateWindow(); + raise(); } void DownloadManager::addItem(DownloadItem *item) { connect(item, SIGNAL(statusChanged()), this, SLOT(updateRow())); + connect(item, SIGNAL(downloadFinished()), this, SLOT(finished())); int row = m_downloads.count(); m_model->beginInsertRows(QModelIndex(), row, row); m_downloads.append(item); m_model->endInsertRows(); updateItemCount(); - if (row == 0) - show(); downloadsView->setIndexWidget(m_model->index(row, 0), item); QIcon icon = style()->standardIcon(QStyle::SP_FileIcon); item->fileIcon->setPixmap(icon.pixmap(48, 48)); downloadsView->setRowHeight(row, item->sizeHint().height()); updateRow(item); //incase download finishes before the constructor returns + updateActiveItemCount(); +} + +void DownloadManager::updateActiveItemCount() +{ + int acCount = activeDownloads(); + if (acCount > 0) { + setWindowTitle(QApplication::translate("DownloadDialog", "Downloading %1", 0, QApplication::UnicodeUTF8).arg(acCount)); + } else { + setWindowTitle(QApplication::translate("DownloadDialog", "Downloads", 0, QApplication::UnicodeUTF8)); + } } +void DownloadManager::finished() +{ + updateActiveItemCount(); + if (isVisible()) { + QApplication::alert(this); + } +} + + void DownloadManager::updateRow() { - DownloadItem *item = qobject_cast(sender()); - if (item) { + if (DownloadItem *item = qobject_cast(sender())) updateRow(item); - } } void DownloadManager::updateRow(DownloadItem *item) @@ -484,7 +633,9 @@ void DownloadManager::updateRow(DownloadItem *item) if (icon.isNull()) icon = style()->standardIcon(QStyle::SP_FileIcon); item->fileIcon->setPixmap(icon.pixmap(48, 48)); - downloadsView->setRowHeight(row, item->minimumSizeHint().height()); + + int oldHeight = downloadsView->rowHeight(row); + downloadsView->setRowHeight(row, qMax(oldHeight, item->minimumSizeHint().height())); bool remove = false; QWebSettings *globalSettings = QWebSettings::globalSettings(); @@ -575,6 +726,7 @@ void DownloadManager::load() key = QString(QLatin1String("download_%1_")).arg(++i); } cleanupButton->setEnabled(m_downloads.count() - activeDownloads() > 0); + updateActiveItemCount(); } void DownloadManager::cleanup() @@ -583,6 +735,7 @@ void DownloadManager::cleanup() return; m_model->removeRows(0, m_downloads.count()); updateItemCount(); + updateActiveItemCount(); if (m_downloads.isEmpty() && m_iconProvider) { delete m_iconProvider; m_iconProvider = 0; @@ -593,7 +746,58 @@ void DownloadManager::cleanup() void DownloadManager::updateItemCount() { int count = m_downloads.count(); - itemCount->setText(count == 1 ? tr("1 Download") : tr("%1 Downloads").arg(count)); + itemCount->setText(tr("%n Download(s)", "", count)); +} + +void DownloadManager::setDownloadDirectory(const QString &directory) +{ + m_downloadDirectory = directory; + if (!m_downloadDirectory.isEmpty()) + m_downloadDirectory += QLatin1Char('/'); +} + +QString DownloadManager::downloadDirectory() +{ + return m_downloadDirectory; +} + +QString DownloadManager::timeString(double timeRemaining) +{ + QString remaining; + + if (timeRemaining > 60) { + timeRemaining = timeRemaining / 60; + timeRemaining = floor(timeRemaining); + remaining = tr("%n minutes remaining", "", int(timeRemaining)); + } + else { + timeRemaining = floor(timeRemaining); + remaining = tr("%n seconds remaining", "", int(timeRemaining)); + } + + return remaining; +} + +QString DownloadManager::dataString(qint64 size) +{ + QString unit; + double newSize; + + if (size < 1024) { + newSize = size; + unit = tr("bytes"); + } else if (size < 1024 * 1024) { + newSize = (double)size / (double)1024; + unit = tr("kB"); + } else if (size < 1024 * 1024 * 1024) { + newSize = (double)size / (double)(1024 * 1024); + unit = tr("MB"); + } else { + newSize = (double)size / (double)(1024 * 1024 * 1024); + unit = tr("GB"); + } + + return QString(QLatin1String("%1 %2")).arg(newSize, 0, 'f', 1).arg(unit); } DownloadModel::DownloadModel(DownloadManager *downloadManager, QObject *parent) @@ -632,6 +836,35 @@ bool DownloadModel::removeRows(int row, int count, const QModelIndex &parent) } } m_downloadManager->m_autoSaver->changeOccurred(); + m_downloadManager->updateItemCount(); return true; } +Qt::ItemFlags DownloadModel::flags(const QModelIndex &index) const +{ + if (index.row() < 0 || index.row() >= rowCount(index.parent())) + return 0; + + Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); + + DownloadItem *item = m_downloadManager->m_downloads.at(index.row()); + if (item->downloadedSuccessfully()) + return defaultFlags | Qt::ItemIsDragEnabled; + + return defaultFlags; +} + +QMimeData *DownloadModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData(); + QList urls; + foreach (const QModelIndex &index, indexes) { + if (!index.isValid()) + continue; + DownloadItem *item = m_downloadManager->m_downloads.at(index.row()); + urls.append(QUrl::fromLocalFile(QFileInfo(item->m_output).absoluteFilePath())); + } + mimeData->setUrls(urls); + return mimeData; +} + diff --git a/src/downloadmanager.h b/src/downloadmanager.h index 89f54821..f37f8e1d 100644 --- a/src/downloadmanager.h +++ b/src/downloadmanager.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * Copyright 2008 Jason A. Donenfeld * * This program is free software; you can redistribute it and/or modify @@ -78,12 +78,19 @@ class DownloadItem : public QWidget, public Ui_DownloadItem signals: void statusChanged(); + void progress(qint64 bytesReceived = 0, qint64 bytesTotal = 0); + void downloadFinished(); public: DownloadItem(QNetworkReply *reply = 0, bool requestFileName = false, QWidget *parent = 0); bool downloading() const; bool downloadedSuccessfully() const; + qint64 bytesTotal() const; + qint64 bytesReceived() const; + double remainingTime() const; + double currentSpeed() const; + QUrl m_url; QFile m_output; @@ -104,7 +111,6 @@ private slots: void getFileName(); void init(); void updateInfoLabel(); - QString dataString(int size) const; QString saveFileName(const QString &directory) const; @@ -113,12 +119,18 @@ private slots: QTime m_downloadTime; bool m_startedSaving; bool m_finishedDownloading; + bool m_gettingFileName; + bool m_canceledFileSelect; + QTime m_lastProgressTime; + + friend class DownloadManager; }; class AutoSaver; class DownloadModel; QT_BEGIN_NAMESPACE class QFileIconProvider; +class QMimeData; QT_END_NAMESPACE class DownloadManager : public QDialog, public Ui_DownloadDialog @@ -137,10 +149,17 @@ class DownloadManager : public QDialog, public Ui_DownloadDialog DownloadManager(QWidget *parent = 0); ~DownloadManager(); int activeDownloads() const; + bool allowQuit(); RemovePolicy removePolicy() const; void setRemovePolicy(RemovePolicy policy); + static QString timeString(double timeRemaining); + static QString dataString(qint64 size); + + void setDownloadDirectory(const QString &directory); + QString downloadDirectory(); + public slots: void download(const QNetworkRequest &request, bool requestFileName = false); inline void download(const QUrl &url, bool requestFileName = false) @@ -152,11 +171,14 @@ private slots: void save() const; void updateRow(DownloadItem *item); void updateRow(); + void finished(); private: void addItem(DownloadItem *item); void updateItemCount(); void load(); + bool externalDownload(const QUrl &url); + void updateActiveItemCount(); AutoSaver *m_autoSaver; DownloadModel *m_model; @@ -164,6 +186,8 @@ private slots: QFileIconProvider *m_iconProvider; QList m_downloads; RemovePolicy m_removePolicy; + QString m_downloadDirectory; + friend class DownloadModel; }; @@ -177,6 +201,8 @@ class DownloadModel : public QAbstractListModel QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + Qt::ItemFlags flags(const QModelIndex &index) const; + QMimeData *mimeData(const QModelIndexList &indexes) const; private: DownloadManager *m_downloadManager; diff --git a/src/downloads.ui b/src/downloads.ui index e856b017..134148b2 100644 --- a/src/downloads.ui +++ b/src/downloads.ui @@ -1,49 +1,56 @@ - + + DownloadDialog - - + + 0 0 - 332 - 252 + 340 + 233 - + Downloads - - + + 0 - + 0 - - - + + + QFrame::NoFrame + + true + + + QAbstractItemView::DragOnly + - - + + - - + + false - + Clean up - + Qt::Horizontal - + 58 24 @@ -53,25 +60,36 @@ - - - + + + 0 Items - - - - Qt::Horizontal - - - - 148 - 20 - - - + + + + + + Qt::Horizontal + + + + 50 + 20 + + + + + + + + QDialogButtonBox::Close + + + + diff --git a/src/history.cpp b/src/history/history.cpp similarity index 64% rename from src/history.cpp rename to src/history/history.cpp index 6086155c..7419cf00 100644 --- a/src/history.cpp +++ b/src/history/history.cpp @@ -64,6 +64,8 @@ #include "autosaver.h" #include "browserapplication.h" +#include "historymanager.h" +#include "treesortfilterproxymodel.h" #include #include @@ -76,313 +78,14 @@ #include #include #include +#include +#include #include #include #include -static const unsigned int HISTORY_VERSION = 23; - -HistoryManager::HistoryManager(QObject *parent) - : QWebHistoryInterface(parent) - , m_saveTimer(new AutoSaver(this)) - , m_historyLimit(30) - , m_historyModel(0) - , m_historyFilterModel(0) - , m_historyTreeModel(0) -{ - m_expiredTimer.setSingleShot(true); - connect(&m_expiredTimer, SIGNAL(timeout()), - this, SLOT(checkForExpired())); - connect(this, SIGNAL(entryAdded(const HistoryItem &)), - m_saveTimer, SLOT(changeOccurred())); - connect(this, SIGNAL(entryRemoved(const HistoryItem &)), - m_saveTimer, SLOT(changeOccurred())); - load(); - - m_historyModel = new HistoryModel(this, this); - m_historyFilterModel = new HistoryFilterModel(m_historyModel, this); - m_historyTreeModel = new HistoryTreeModel(m_historyFilterModel, this); - - // QWebHistoryInterface will delete the history manager - QWebHistoryInterface::setDefaultInterface(this); -} - -HistoryManager::~HistoryManager() -{ - // remove history items on application exit - if (m_historyLimit == -2) - clear(); - m_saveTimer->saveIfNeccessary(); -} - -QList HistoryManager::history() const -{ - return m_history; -} - -bool HistoryManager::historyContains(const QString &url) const -{ - return m_historyFilterModel->historyContains(url); -} - -void HistoryManager::addHistoryEntry(const QString &url) -{ - QUrl cleanUrl(url); - cleanUrl.setPassword(QString()); - cleanUrl.setHost(cleanUrl.host().toLower()); - HistoryItem item(cleanUrl.toString(), QDateTime::currentDateTime()); - addHistoryItem(item); -} - -void HistoryManager::setHistory(const QList &history, bool loadedAndSorted) -{ - m_history = history; - - // verify that it is sorted by date - if (!loadedAndSorted) - qSort(m_history.begin(), m_history.end()); - - checkForExpired(); - - if (loadedAndSorted) { - m_lastSavedUrl = m_history.value(0).url; - } else { - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - } - emit historyReset(); -} - -HistoryModel *HistoryManager::historyModel() const -{ - return m_historyModel; -} - -HistoryFilterModel *HistoryManager::historyFilterModel() const -{ - return m_historyFilterModel; -} - -HistoryTreeModel *HistoryManager::historyTreeModel() const -{ - return m_historyTreeModel; -} - -void HistoryManager::checkForExpired() -{ - if (m_historyLimit < 0 || m_history.isEmpty()) - return; - - QDateTime now = QDateTime::currentDateTime(); - int nextTimeout = 0; - - while (!m_history.isEmpty()) { - QDateTime checkForExpired = m_history.last().dateTime; - checkForExpired.setDate(checkForExpired.date().addDays(m_historyLimit)); - if (now.daysTo(checkForExpired) > 7) { - // check at most in a week to prevent int overflows on the timer - nextTimeout = 7 * 86400; - } else { - nextTimeout = now.secsTo(checkForExpired); - } - if (nextTimeout > 0) - break; - HistoryItem item = m_history.takeLast(); - // remove from saved file also - m_lastSavedUrl = QString(); - emit entryRemoved(item); - } - - if (nextTimeout > 0) - m_expiredTimer.start(nextTimeout * 1000); -} - -void HistoryManager::addHistoryItem(const HistoryItem &item) -{ - QWebSettings *globalSettings = QWebSettings::globalSettings(); - if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) - return; - - m_history.prepend(item); - emit entryAdded(item); - if (m_history.count() == 1) - checkForExpired(); -} - -void HistoryManager::updateHistoryItem(const QUrl &url, const QString &title) -{ - for (int i = 0; i < m_history.count(); ++i) { - if (url == m_history.at(i).url) { - m_history[i].title = title; - m_saveTimer->changeOccurred(); - if (m_lastSavedUrl.isEmpty()) - m_lastSavedUrl = m_history.at(i).url; - emit entryUpdated(i); - break; - } - } -} - -int HistoryManager::historyLimit() const -{ - return m_historyLimit; -} - -void HistoryManager::setHistoryLimit(int limit) -{ - if (m_historyLimit == limit) - return; - m_historyLimit = limit; - checkForExpired(); - m_saveTimer->changeOccurred(); -} - -void HistoryManager::clear() -{ - m_history.clear(); - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - m_saveTimer->saveIfNeccessary(); - historyReset(); -} - -void HistoryManager::loadSettings() -{ - // load settings - QSettings settings; - settings.beginGroup(QLatin1String("history")); - m_historyLimit = settings.value(QLatin1String("historyLimit"), 30).toInt(); -} - -void HistoryManager::load() -{ - loadSettings(); - - QFile historyFile(QDesktopServices::storageLocation(QDesktopServices::DataLocation) - + QLatin1String("/history")); - if (!historyFile.exists()) - return; - if (!historyFile.open(QFile::ReadOnly)) { - qWarning() << "Unable to open history file" << historyFile.fileName(); - return; - } - - QList list; - QDataStream in(&historyFile); - // Double check that the history file is sorted as it is read in - bool needToSort = false; - HistoryItem lastInsertedItem; - QByteArray data; - QDataStream stream; - QBuffer buffer; - stream.setDevice(&buffer); - while (!historyFile.atEnd()) { - in >> data; - buffer.close(); - buffer.setBuffer(&data); - buffer.open(QIODevice::ReadOnly); - quint32 ver; - stream >> ver; - if (ver != HISTORY_VERSION) - continue; - HistoryItem item; - stream >> item.url; - stream >> item.dateTime; - stream >> item.title; - - if (!item.dateTime.isValid()) - continue; - - if (item == lastInsertedItem) { - if (lastInsertedItem.title.isEmpty() && !list.isEmpty()) - list[0].title = item.title; - continue; - } - - if (!needToSort && !list.isEmpty() && lastInsertedItem < item) - needToSort = true; - - list.prepend(item); - lastInsertedItem = item; - } - if (needToSort) - qSort(list.begin(), list.end()); - - setHistory(list, true); - - // If we had to sort re-write the whole history sorted - if (needToSort) { - m_lastSavedUrl = QString(); - m_saveTimer->changeOccurred(); - } -} - -void HistoryManager::save() -{ - QSettings settings; - settings.beginGroup(QLatin1String("history")); - settings.setValue(QLatin1String("historyLimit"), m_historyLimit); - - bool saveAll = m_lastSavedUrl.isEmpty(); - int first = m_history.count() - 1; - if (!saveAll) { - // find the first one to save - for (int i = 0; i < m_history.count(); ++i) { - if (m_history.at(i).url == m_lastSavedUrl) { - first = i - 1; - break; - } - } - } - if (first == m_history.count() - 1) - saveAll = true; - - QString directory = QDesktopServices::storageLocation(QDesktopServices::DataLocation); - if (directory.isEmpty()) - directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); - if (!QFile::exists(directory)) { - QDir dir; - dir.mkpath(directory); - } - - QFile historyFile(directory + QLatin1String("/history")); - // When saving everything use a temporary file to prevent possible data loss. - QTemporaryFile tempFile; - tempFile.setAutoRemove(false); - bool open = false; - if (saveAll) { - open = tempFile.open(); - } else { - open = historyFile.open(QFile::Append); - } - - if (!open) { - qWarning() << "Unable to open history file for saving" - << (saveAll ? tempFile.fileName() : historyFile.fileName()); - return; - } - - QDataStream out(saveAll ? &tempFile : &historyFile); - for (int i = first; i >= 0; --i) { - QByteArray data; - QDataStream stream(&data, QIODevice::WriteOnly); - HistoryItem item = m_history.at(i); - stream << HISTORY_VERSION << item.url << item.dateTime << item.title; - out << data; - } - tempFile.close(); - - if (saveAll) { - if (historyFile.exists() && !historyFile.remove()) - qWarning() << "History: error removing old history." << historyFile.errorString(); - if (!tempFile.rename(historyFile.fileName())) - qWarning() << "History: error moving new history over old." << tempFile.errorString() << historyFile.fileName(); - } - m_lastSavedUrl = m_history.value(0).url; -} - HistoryModel::HistoryModel(HistoryManager *history, QObject *parent) : QAbstractTableModel(parent) , m_history(history) @@ -390,10 +93,10 @@ HistoryModel::HistoryModel(HistoryManager *history, QObject *parent) Q_ASSERT(m_history); connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); - connect(m_history, SIGNAL(entryRemoved(const HistoryItem &)), + connect(m_history, SIGNAL(entryRemoved(const HistoryEntry &)), this, SLOT(historyReset())); - connect(m_history, SIGNAL(entryAdded(const HistoryItem &)), + connect(m_history, SIGNAL(entryAdded(const HistoryEntry &)), this, SLOT(entryAdded())); connect(m_history, SIGNAL(entryUpdated(int)), this, SLOT(entryUpdated(int))); @@ -430,11 +133,11 @@ QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int QVariant HistoryModel::data(const QModelIndex &index, int role) const { - QList lst = m_history->history(); + QList lst = m_history->history(); if (index.row() < 0 || index.row() >= lst.size()) return QVariant(); - const HistoryItem &item = lst.at(index.row()); + const HistoryEntry &item = lst.at(index.row()); switch (role) { case DateTimeRole: return item.dateTime; @@ -444,18 +147,13 @@ QVariant HistoryModel::data(const QModelIndex &index, int role) const return QUrl(item.url); case UrlStringRole: return item.url; + case TitleRole: + return item.userTitle(); case Qt::DisplayRole: case Qt::EditRole: { switch (index.column()) { case 0: - // when there is no title try to generate one from the url - if (item.title.isEmpty()) { - QString page = QFileInfo(QUrl(item.url).path()).fileName(); - if (!page.isEmpty()) - return page; - return item.url; - } - return item.title; + return item.userTitle(); case 1: return item.url; } @@ -484,7 +182,7 @@ bool HistoryModel::removeRows(int row, int count, const QModelIndex &parent) return false; int lastRow = row + count - 1; beginRemoveRows(parent, row, lastRow); - QList lst = m_history->history(); + QList lst = m_history->history(); for (int i = lastRow; i >= row; --i) lst.removeAt(i); disconnect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); @@ -545,6 +243,11 @@ int HistoryMenuModel::rowCount(const QModelIndex &parent) const return defaultCount; } +QModelIndex HistoryMenuModel::buddy(const QModelIndex &index) const +{ + return index; +} + QModelIndex HistoryMenuModel::mapFromSource(const QModelIndex &sourceIndex) const { // currently not used or autotested @@ -611,11 +314,25 @@ QModelIndex HistoryMenuModel::parent(const QModelIndex &index) const return createIndex(bumpedItems + treeIndexParent.row(), treeIndexParent.column(), sr); } +QMimeData *HistoryMenuModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData; + QList urls; + foreach (const QModelIndex &idx, indexes) { + QUrl url = idx.data(HistoryModel::UrlRole).toUrl(); + urls.append(url); + } + mimeData->setUrls(urls); + return mimeData; +} + HistoryMenu::HistoryMenu(QWidget *parent) : ModelMenu(parent) , m_history(0) + , m_historyMenuModel(0) { + setMaxRows(7); connect(this, SIGNAL(activated(const QModelIndex &)), this, SLOT(activated(const QModelIndex &))); setStatusBarTextRole(HistoryModel::UrlStringRole); @@ -623,7 +340,8 @@ HistoryMenu::HistoryMenu(QWidget *parent) void HistoryMenu::activated(const QModelIndex &index) { - emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); + emit openUrl(index.data(HistoryModel::UrlRole).toUrl(), + index.data(HistoryModel::TitleRole).toString()); } bool HistoryMenu::prePopulated() @@ -649,22 +367,34 @@ void HistoryMenu::postPopulated() addSeparator(); QAction *showAllAction = new QAction(tr("Show All History"), this); +#if !defined(Q_WS_MAC) + showAllAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_H)); +#endif connect(showAllAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog())); addAction(showAllAction); - QAction *clearAction = new QAction(tr("Clear History"), this); - connect(clearAction, SIGNAL(triggered()), m_history, SLOT(clear())); + QAction *clearAction = new QAction(tr("Clear History..."), this); + connect(clearAction, SIGNAL(triggered()), this, SLOT(clearHistoryDialog())); addAction(clearAction); } void HistoryMenu::showHistoryDialog() { HistoryDialog *dialog = new HistoryDialog(this); - connect(dialog, SIGNAL(openUrl(const QUrl&)), - this, SIGNAL(openUrl(const QUrl&))); + dialog->setAttribute(Qt::WA_DeleteOnClose); + connect(dialog, SIGNAL(openUrl(const QUrl&, const QString &)), + this, SIGNAL(openUrl(const QUrl&, const QString &))); dialog->show(); } +void HistoryMenu::clearHistoryDialog() +{ + if (m_history && QMessageBox::question(0, tr("Clear History"), tr("Do you want to clear the history?"), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) { + m_history->clear(); + } +} + void HistoryMenu::setInitialActions(QList actions) { m_initialActions = actions; @@ -672,20 +402,6 @@ void HistoryMenu::setInitialActions(QList actions) addAction(m_initialActions.at(i)); } -TreeProxyModel::TreeProxyModel(QObject *parent) : QSortFilterProxyModel(parent) -{ - setSortRole(HistoryModel::DateTimeRole); - setFilterCaseSensitivity(Qt::CaseInsensitive); -} - -bool TreeProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const -{ - QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); - if (sourceModel()->hasChildren(idx)) - return true; - return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); -} - HistoryDialog::HistoryDialog(QWidget *parent, HistoryManager *setHistory) : QDialog(parent) { HistoryManager *history = setHistory; @@ -694,9 +410,12 @@ HistoryDialog::HistoryDialog(QWidget *parent, HistoryManager *setHistory) : QDia setupUi(this); tree->setUniformRowHeights(true); tree->setSelectionBehavior(QAbstractItemView::SelectRows); + tree->setSelectionMode(QAbstractItemView::ExtendedSelection); tree->setTextElideMode(Qt::ElideMiddle); QAbstractItemModel *model = history->historyTreeModel(); - TreeProxyModel *proxyModel = new TreeProxyModel(this); + TreeSortFilterProxyModel *proxyModel = new TreeSortFilterProxyModel(this); + proxyModel->setSortRole(HistoryModel::DateTimeRole); + proxyModel->setFilterKeyColumn(-1); connect(search, SIGNAL(textChanged(QString)), proxyModel, SLOT(setFilterFixedString(QString))); connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeSelected())); @@ -735,7 +454,10 @@ void HistoryDialog::open() QModelIndex index = tree->currentIndex(); if (!index.parent().isValid()) return; - emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); + BrowserApplication::instance()->setEventMouseButtons(qApp->mouseButtons()); + BrowserApplication::instance()->setEventKeyboardModifiers(qApp->keyboardModifiers()); + emit openUrl(index.data(HistoryModel::UrlRole).toUrl(), + index.data(HistoryModel::TitleRole).toString()); } void HistoryDialog::copy() @@ -753,7 +475,25 @@ HistoryFilterModel::HistoryFilterModel(QAbstractItemModel *sourceModel, QObject : QAbstractProxyModel(parent) , m_loaded(false) { + m_frecencyTimer.setSingleShot(true); + connect(&m_frecencyTimer, SIGNAL(timeout()), + this, SLOT(refreshFrecencies())); + setSourceModel(sourceModel); + startFrecencyTimer(); +} + +void HistoryFilterModel::refreshFrecencies() +{ + recalculateFrecencies(); + startFrecencyTimer(); +} + +void HistoryFilterModel::startFrecencyTimer() +{ + // schedule us to recalculate the frecencies once per day, at 3:00 am (aka 03h00) + QDateTime tomorrow(QDate::currentDate().addDays(1), QTime(3, 00)); + m_frecencyTimer.start(QDateTime::currentDateTime().secsTo(tomorrow)*1000); } int HistoryFilterModel::historyLocation(const QString &url) const @@ -761,11 +501,16 @@ int HistoryFilterModel::historyLocation(const QString &url) const load(); if (!m_historyHash.contains(url)) return 0; + return sourceModel()->rowCount() - m_historyHash.value(url); } QVariant HistoryFilterModel::data(const QModelIndex &index, int role) const { + if (role == FrecencyRole && index.isValid()) { + return m_filteredRows[index.row()].frecency; + } + return QAbstractProxyModel::data(index, role); } @@ -805,6 +550,11 @@ QVariant HistoryFilterModel::headerData(int section, Qt::Orientation orientation return sourceModel()->headerData(section, orientation, role); } +void HistoryFilterModel::recalculateFrecencies() +{ + sourceReset(); +} + void HistoryFilterModel::sourceReset() { m_loaded = false; @@ -838,23 +588,15 @@ QModelIndex HistoryFilterModel::mapFromSource(const QModelIndex &sourceIndex) co if (!m_historyHash.contains(url)) return QModelIndex(); - // This can be done in a binary search, but we can't use qBinary find - // because it can't take: qBinaryFind(m_sourceRow.end(), m_sourceRow.begin(), v); - // so if this is a performance bottlneck then convert to binary search, until then - // the cleaner/easier to read code wins the day. - int realRow = -1; - int sourceModelRow = sourceModel()->rowCount() - sourceIndex.row(); - - for (int i = 0; i < m_sourceRow.count(); ++i) { - if (m_sourceRow.at(i) == sourceModelRow) { - realRow = i; - break; - } - } - if (realRow == -1) + int sourceOffset = sourceModel()->rowCount() - sourceIndex.row(); + + QList::iterator pos = qBinaryFind(m_filteredRows.begin(), + m_filteredRows.end(), HistoryData(sourceOffset, -1)); + + if (pos == m_filteredRows.end()) return QModelIndex(); - return createIndex(realRow, sourceIndex.column(), sourceModel()->rowCount() - sourceIndex.row()); + return createIndex(pos - m_filteredRows.begin(), sourceIndex.column(), sourceOffset); } QModelIndex HistoryFilterModel::index(int row, int column, const QModelIndex &parent) const @@ -864,7 +606,7 @@ QModelIndex HistoryFilterModel::index(int row, int column, const QModelIndex &pa || column < 0 || column >= columnCount(parent)) return QModelIndex(); - return createIndex(row, column, m_sourceRow[row]); + return createIndex(row, column, m_filteredRows[row].tailOffset); } QModelIndex HistoryFilterModel::parent(const QModelIndex &) const @@ -876,15 +618,23 @@ void HistoryFilterModel::load() const { if (m_loaded) return; - m_sourceRow.clear(); + m_filteredRows.clear(); m_historyHash.clear(); m_historyHash.reserve(sourceModel()->rowCount()); + m_scaleTime = QDateTime::currentDateTime(); for (int i = 0; i < sourceModel()->rowCount(); ++i) { QModelIndex idx = sourceModel()->index(i, 0); QString url = idx.data(HistoryModel::UrlStringRole).toString(); if (!m_historyHash.contains(url)) { - m_sourceRow.append(sourceModel()->rowCount() - i); - m_historyHash[url] = sourceModel()->rowCount() - i; + int sourceOffset = sourceModel()->rowCount() - i; + m_filteredRows.append(HistoryData(sourceOffset, frecencyScore(idx))); + m_historyHash.insert(url, sourceOffset); + } else { + // we already know about this url: just increment its frecency score + QList::iterator pos = qBinaryFind(m_filteredRows.begin(), + m_filteredRows.end(), HistoryData(m_historyHash[url], -1)); + Q_ASSERT(pos != m_filteredRows.end()); + pos->frecency += frecencyScore(idx); } } m_loaded = true; @@ -898,17 +648,21 @@ void HistoryFilterModel::sourceRowsInserted(const QModelIndex &parent, int start return; QModelIndex idx = sourceModel()->index(start, 0, parent); QString url = idx.data(HistoryModel::UrlStringRole).toString(); + int currentFrecency = 0; if (m_historyHash.contains(url)) { - int sourceRow = sourceModel()->rowCount() - m_historyHash[url]; - int realRow = mapFromSource(sourceModel()->index(sourceRow, 0)).row(); + QList::iterator pos = qBinaryFind(m_filteredRows.begin(), + m_filteredRows.end(), HistoryData(m_historyHash[url], -1)); + Q_ASSERT(pos != m_filteredRows.end()); + int realRow = pos - m_filteredRows.begin(); + currentFrecency = pos->frecency; beginRemoveRows(QModelIndex(), realRow, realRow); - m_sourceRow.removeAt(realRow); + m_filteredRows.erase(pos); m_historyHash.remove(url); endRemoveRows(); } beginInsertRows(QModelIndex(), 0, 0); - m_historyHash.insert(url, sourceModel()->rowCount() - start); - m_sourceRow.insert(0, sourceModel()->rowCount()); + m_filteredRows.insert(0, HistoryData(sourceModel()->rowCount(), frecencyScore(idx) + currentFrecency)); + m_historyHash.insert(url, sourceModel()->rowCount()); endInsertRows(); } @@ -932,8 +686,8 @@ bool HistoryFilterModel::removeRows(int row, int count, const QModelIndex &paren this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); beginRemoveRows(parent, row, lastRow); int oldCount = rowCount(); - int start = sourceModel()->rowCount() - m_sourceRow.value(row); - int end = sourceModel()->rowCount() - m_sourceRow.value(lastRow); + int start = sourceModel()->rowCount() - m_filteredRows[row].tailOffset; + int end = sourceModel()->rowCount() - m_filteredRows[lastRow].tailOffset; sourceModel()->removeRows(start, end - start + 1); endRemoveRows(); connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), @@ -944,98 +698,29 @@ bool HistoryFilterModel::removeRows(int row, int count, const QModelIndex &paren return true; } -HistoryCompletionModel::HistoryCompletionModel(QObject *parent) - : QAbstractProxyModel(parent) +int HistoryFilterModel::frecencyScore(const QModelIndex &sourceIndex) const { -} + QDateTime loadTime = sourceModel()->data(sourceIndex, HistoryModel::DateTimeRole).toDateTime(); + int days = loadTime.daysTo(m_scaleTime); -QVariant HistoryCompletionModel::data(const QModelIndex &index, int role) const -{ - if (sourceModel() - && (role == Qt::EditRole || role == Qt::DisplayRole) - && index.isValid()) { - QModelIndex idx = mapToSource(index); - idx = idx.sibling(idx.row(), 1); - QString urlString = idx.data(HistoryModel::UrlStringRole).toString(); - if (index.row() % 2) { - QUrl url = urlString; - QString s = url.toString(QUrl::RemoveScheme - | QUrl::RemoveUserInfo - | QUrl::StripTrailingSlash); - return s.mid(2); // strip // from the front - } - return urlString; + if (days <= 1) { + return 100; + } else if (days < 5) { // within the last 4 days + return 90; + } else if (days < 15) { // within the last two weeks + return 70; + } else if (days < 31) { // within the last month + return 50; + } else if (days < 91) { // within the last 3 months + return 30; } - return QAbstractProxyModel::data(index, role); -} - -int HistoryCompletionModel::rowCount(const QModelIndex &parent) const -{ - return (parent.isValid() || !sourceModel()) ? 0 : sourceModel()->rowCount(parent) * 2; -} - -int HistoryCompletionModel::columnCount(const QModelIndex &parent) const -{ - return (parent.isValid()) ? 0 : 1; -} - -QModelIndex HistoryCompletionModel::mapFromSource(const QModelIndex &sourceIndex) const -{ - int row = sourceIndex.row() * 2; - return index(row, sourceIndex.column()); -} - -QModelIndex HistoryCompletionModel::mapToSource(const QModelIndex &proxyIndex) const -{ - if (!sourceModel()) - return QModelIndex(); - int row = proxyIndex.row() / 2; - return sourceModel()->index(row, proxyIndex.column()); -} - -QModelIndex HistoryCompletionModel::index(int row, int column, const QModelIndex &parent) const -{ - if (row < 0 || row >= rowCount(parent) - || column < 0 || column >= columnCount(parent)) - return QModelIndex(); - return createIndex(row, column, 0); -} - -QModelIndex HistoryCompletionModel::parent(const QModelIndex &) const -{ - return QModelIndex(); -} - -void HistoryCompletionModel::setSourceModel(QAbstractItemModel *newSourceModel) -{ - if (sourceModel()) { - disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - QAbstractProxyModel::setSourceModel(newSourceModel); - - if (newSourceModel) { - connect(newSourceModel, SIGNAL(modelReset()), this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), - this, SLOT(sourceReset())); - } - - reset(); -} -void HistoryCompletionModel::sourceReset() -{ - reset(); + return 10; } HistoryTreeModel::HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent) : QAbstractProxyModel(parent) + , removingDown(false) { setSourceModel(sourceModel); } @@ -1047,7 +732,9 @@ QVariant HistoryTreeModel::headerData(int section, Qt::Orientation orientation, QVariant HistoryTreeModel::data(const QModelIndex &index, int role) const { - if ((role == Qt::EditRole || role == Qt::DisplayRole)) { + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: { int start = index.internalId(); if (start == 0) { int offset = sourceDateRow(index.row()); @@ -1059,16 +746,21 @@ QVariant HistoryTreeModel::data(const QModelIndex &index, int role) const return date.toString(QLatin1String("dddd, MMMM d, yyyy")); } if (index.column() == 1) { - return tr("%1 items").arg(rowCount(index.sibling(index.row(), 0))); + return tr("%n item(s)", "", rowCount(index.sibling(index.row(), 0))); } } } - if (role == Qt::DecorationRole && index.column() == 0 && !index.parent().isValid()) - return QIcon(QLatin1String(":history.png")); - if (role == HistoryModel::DateRole && index.column() == 0 && index.internalId() == 0) { - int offset = sourceDateRow(index.row()); - QModelIndex idx = sourceModel()->index(offset, 0); - return idx.data(HistoryModel::DateRole); + case Qt::DecorationRole: { + if (index.column() == 0 && !index.parent().isValid()) + return QIcon(QLatin1String(":graphics/history.png")); + } + case HistoryModel::DateRole: { + if (index.column() == 0 && index.internalId() == 0) { + int offset = sourceDateRow(index.row()); + QModelIndex idx = sourceModel()->index(offset, 0); + return idx.data(HistoryModel::DateRole); + } + } } return QAbstractProxyModel::data(index, role); @@ -1173,27 +865,6 @@ Qt::ItemFlags HistoryTreeModel::flags(const QModelIndex &index) const return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled; } -bool HistoryTreeModel::removeRows(int row, int count, const QModelIndex &parent) -{ - if (row < 0 || count <= 0 || row + count > rowCount(parent)) - return false; - - if (parent.isValid()) { - // removing pages - int offset = sourceDateRow(parent.row()); - return sourceModel()->removeRows(offset + row, count); - } else { - // removing whole dates - for (int i = row + count - 1; i >= row; --i) { - QModelIndex dateParent = index(i, 0); - int offset = sourceDateRow(dateParent.row()); - if (!sourceModel()->removeRows(offset, rowCount(dateParent))) - return false; - } - } - return true; -} - void HistoryTreeModel::setSourceModel(QAbstractItemModel *newSourceModel) { if (sourceModel()) { @@ -1264,22 +935,45 @@ QModelIndex HistoryTreeModel::mapFromSource(const QModelIndex &sourceIndex) cons return createIndex(row, sourceIndex.column(), dateRow + 1); } +bool HistoryTreeModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (row < 0 || count <= 0 || row + count > rowCount(parent)) + return false; + + removingDown = true; + if (parent.isValid() && rowCount(parent) == count - row) + beginRemoveRows(QModelIndex(), parent.row(), parent.row()); + else + beginRemoveRows(parent, row, row + count - 1); + if (parent.isValid()) { + // removing pages + int offset = sourceDateRow(parent.row()); + return sourceModel()->removeRows(offset + row, count); + } else { + // removing whole dates + for (int i = row + count - 1; i >= row; --i) { + QModelIndex dateParent = index(i, 0); + int offset = sourceDateRow(dateParent.row()); + if (!sourceModel()->removeRows(offset, rowCount(dateParent))) + return false; + } + } + return true; +} + void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, int end) { + if (!removingDown) { + reset(); + m_sourceRowCache.clear(); + return; + } Q_UNUSED(parent); // Avoid warnings when compiling release Q_ASSERT(!parent.isValid()); - if (m_sourceRowCache.isEmpty()) - return; + if (!m_sourceRowCache.isEmpty()) for (int i = end; i >= start;) { QList::iterator it; it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), i); - // playing it safe - if (it == m_sourceRowCache.end()) { - m_sourceRowCache.clear(); - reset(); - return; - } - if (*it != i) --it; int row = qMax(0, it - m_sourceRowCache.begin()); @@ -1288,17 +982,18 @@ void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, i // If we can remove all the rows in the date do that and skip over them int rc = rowCount(dateParent); if (i - rc + 1 == offset && start <= i - rc + 1) { - beginRemoveRows(QModelIndex(), row, row); m_sourceRowCache.removeAt(row); i -= rc + 1; } else { - beginRemoveRows(dateParent, i - offset, i - offset); ++row; --i; } for (int j = row; j < m_sourceRowCache.count(); ++j) --m_sourceRowCache[j]; + } + if (removingDown) { endRemoveRows(); + removingDown = false; } } diff --git a/src/history.h b/src/history/history.h similarity index 71% rename from src/history.h rename to src/history/history.h index 24f647fe..84e596f7 100644 --- a/src/history.h +++ b/src/history/history.h @@ -74,88 +74,7 @@ #include -class HistoryItem -{ -public: - HistoryItem() {} - HistoryItem(const QString &u, - const QDateTime &d = QDateTime(), const QString &t = QString()) - : title(t), url(u), dateTime(d) {} - - inline bool operator==(const HistoryItem &other) const { - return other.title == title - && other.url == url && other.dateTime == dateTime; - } - - // history is sorted in reverse - inline bool operator <(const HistoryItem &other) const - { return dateTime > other.dateTime; } - - QString title; - QString url; - QDateTime dateTime; -}; - -class AutoSaver; -class HistoryModel; -class HistoryFilterModel; -class HistoryTreeModel; -class HistoryManager : public QWebHistoryInterface -{ - Q_OBJECT - Q_PROPERTY(int historyLimit READ historyLimit WRITE setHistoryLimit) - -signals: - void historyReset(); - void entryAdded(const HistoryItem &item); - void entryRemoved(const HistoryItem &item); - void entryUpdated(int offset); - -public: - HistoryManager(QObject *parent = 0); - ~HistoryManager(); - - bool historyContains(const QString &url) const; - void addHistoryEntry(const QString &url); - - void updateHistoryItem(const QUrl &url, const QString &title); - - int historyLimit() const; - void setHistoryLimit(int limit); - - QList history() const; - void setHistory(const QList &history, bool loadedAndSorted = false); - - // History manager keeps around these models for use by the completer and other classes - HistoryModel *historyModel() const; - HistoryFilterModel *historyFilterModel() const; - HistoryTreeModel *historyTreeModel() const; - -public slots: - void clear(); - void loadSettings(); - -private slots: - void save(); - void checkForExpired(); - -protected: - void addHistoryItem(const HistoryItem &item); - -private: - void load(); - - AutoSaver *m_saveTimer; - int m_historyLimit; - QTimer m_expiredTimer; - QList m_history; - QString m_lastSavedUrl; - - HistoryModel *m_historyModel; - HistoryFilterModel *m_historyFilterModel; - HistoryTreeModel *m_historyTreeModel; -}; - +class HistoryManager; class HistoryModel : public QAbstractTableModel { Q_OBJECT @@ -170,7 +89,9 @@ public slots: DateRole = Qt::UserRole + 1, DateTimeRole = Qt::UserRole + 2, UrlRole = Qt::UserRole + 3, - UrlStringRole = Qt::UserRole + 4 + UrlStringRole = Qt::UserRole + 4, + TitleRole = Qt::UserRole + 5, + MaxRole = TitleRole }; HistoryModel(HistoryManager *history, QObject *parent = 0); @@ -200,29 +121,62 @@ class HistoryFilterModel : public QAbstractProxyModel { load(); return m_historyHash.contains(url); } int historyLocation(const QString &url) const; + enum Roles { + FrecencyRole = HistoryModel::MaxRole + 1, + MaxRole = FrecencyRole + }; + QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; QModelIndex mapToSource(const QModelIndex &proxyIndex) const; void setSourceModel(QAbstractItemModel *sourceModel); QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index = QModelIndex()) const; + QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index = QModelIndex()) const; bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + void recalculateFrecencies(); + private slots: void sourceReset(); void sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); void sourceRowsInserted(const QModelIndex &parent, int start, int end); void sourceRowsRemoved(const QModelIndex &, int, int); + void refreshFrecencies(); private: void load() const; + void startFrecencyTimer(); - mutable QList m_sourceRow; + QTimer m_frecencyTimer; + QString m_lastSavedUrl; + + struct HistoryData { + int tailOffset; + int frecency; + + HistoryData(int off, int f = 0) : tailOffset(off), frecency(f) { } + + bool operator==(const HistoryData &other) const { + return (tailOffset == other.tailOffset) + && (frecency == -1 || other.frecency == -1 || frecency == other.frecency); + } + bool operator!=(const HistoryData &other) const { + return !(*this == other); + } + // like the actual history entries, our index mapping data is sorted in reverse + bool operator<(const HistoryData &other) const { + return (tailOffset > other.tailOffset); + } + }; + int frecencyScore(const QModelIndex &sourceIndex) const; + + mutable QList m_filteredRows; mutable QHash m_historyHash; mutable bool m_loaded; + mutable QDateTime m_scaleTime; }; /* @@ -233,6 +187,7 @@ private slots: The mapping is done by knowing that HistoryTreeModel is over a table We store that row offset in our index's private data. */ +class HistoryTreeModel; class HistoryMenuModel : public QAbstractProxyModel { Q_OBJECT @@ -245,6 +200,8 @@ class HistoryMenuModel : public QAbstractProxyModel QModelIndex mapToSource(const QModelIndex & proxyIndex) const; QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index = QModelIndex()) const; + QMimeData *mimeData(const QModelIndexList &indexes) const; + QModelIndex buddy(const QModelIndex &index) const; int bumpedRows() const; @@ -258,7 +215,7 @@ class HistoryMenu : public ModelMenu Q_OBJECT signals: - void openUrl(const QUrl &url); + void openUrl(const QUrl &url, const QString &title); public: HistoryMenu(QWidget *parent = 0); @@ -271,6 +228,7 @@ class HistoryMenu : public ModelMenu private slots: void activated(const QModelIndex &index); void showHistoryDialog(); + void clearHistoryDialog(); private: HistoryManager *m_history; @@ -278,28 +236,6 @@ private slots: QList m_initialActions; }; -// proxy model for the history model that -// exposes each url http://www.foo.com and it url starting at the host www.foo.com -class HistoryCompletionModel : public QAbstractProxyModel -{ - Q_OBJECT - -public: - HistoryCompletionModel(QObject *parent = 0); - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; - QModelIndex mapToSource(const QModelIndex &proxyIndex) const; - QModelIndex index(int, int, const QModelIndex& = QModelIndex()) const; - QModelIndex parent(const QModelIndex& index = QModelIndex()) const; - void setSourceModel(QAbstractItemModel *sourceModel); - -private slots: - void sourceReset(); - -}; - // proxy model for the history model that converts the list // into a tree, one top level node per day. // Used in the HistoryDialog. @@ -331,23 +267,10 @@ private slots: private: int sourceDateRow(int row) const; mutable QList m_sourceRowCache; + bool removingDown; }; -// A modified QSortFilterProxyModel that always accepts the root nodes in the tree -// so filtering is only done on the children. -// Used in the HistoryDialog -class TreeProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT - -public: - TreeProxyModel(QObject *parent = 0); - -protected: - bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; -}; - #include "ui_history.h" class HistoryDialog : public QDialog, public Ui_HistoryDialog @@ -355,7 +278,7 @@ class HistoryDialog : public QDialog, public Ui_HistoryDialog Q_OBJECT signals: - void openUrl(const QUrl &url); + void openUrl(const QUrl &url, const QString &title); public: HistoryDialog(QWidget *parent = 0, HistoryManager *history = 0); diff --git a/src/history/history.pri b/src/history/history.pri new file mode 100644 index 00000000..6ee163dd --- /dev/null +++ b/src/history/history.pri @@ -0,0 +1,16 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + history.h \ + historycompleter.h \ + historymanager.h + +SOURCES += \ + history.cpp \ + historycompleter.cpp \ + historymanager.cpp + +FORMS += \ + history.ui + diff --git a/src/history.ui b/src/history/history.ui similarity index 96% rename from src/history.ui rename to src/history/history.ui index 0944940e..3ea3eac1 100644 --- a/src/history.ui +++ b/src/history/history.ui @@ -64,7 +64,7 @@ - QDialogButtonBox::Ok + QDialogButtonBox::Close @@ -88,9 +88,9 @@ buttonBox - accepted() + rejected() HistoryDialog - accept() + close() 472 diff --git a/src/history/historycompleter.cpp b/src/history/historycompleter.cpp new file mode 100644 index 00000000..06bb3f51 --- /dev/null +++ b/src/history/historycompleter.cpp @@ -0,0 +1,278 @@ +/* + * Copyright 2009 Benjamin K. Stuhl + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "historycompleter.h" + +#include +#include +#include + +HistoryCompletionView::HistoryCompletionView(QWidget *parent) + : QTableView(parent) +{ + horizontalHeader()->hide(); + verticalHeader()->hide(); + + setShowGrid(false); + + setSelectionBehavior(QAbstractItemView::SelectRows); + setSelectionMode(QAbstractItemView::SingleSelection); + setTextElideMode(Qt::ElideRight); + + QFontMetrics metrics = fontMetrics(); + verticalHeader()->setDefaultSectionSize(metrics.height()); + + // As URLs are always LRT, this should be LRT as well + setLayoutDirection(Qt::LeftToRight); +} + +void HistoryCompletionView::resizeEvent(QResizeEvent *event) +{ + horizontalHeader()->resizeSection(0, 0.65 * width()); + horizontalHeader()->setStretchLastSection(true); + + QTableView::resizeEvent(event); +} + +int HistoryCompletionView::sizeHintForRow(int row) const +{ + Q_UNUSED(row) + QFontMetrics metrics = fontMetrics(); + return metrics.height(); +} + +HistoryCompletionModel::HistoryCompletionModel(QObject *parent) + : QSortFilterProxyModel(parent) + , m_searchMatcher(QString(), Qt::CaseInsensitive, QRegExp::FixedString) + , m_wordMatcher(QString(), Qt::CaseInsensitive) + , m_isValid(false) +{ + setDynamicSortFilter(true); +} + +QVariant HistoryCompletionModel::data(const QModelIndex &index, int role) const +{ + // if we are valid, tell QCompleter that everything we have filtered matches + // what the user typed; if not, nothing matches + if (role == HistoryCompletionRole && index.isValid()) { + if (isValid()) + return QLatin1String("a"); + else + return QLatin1String("b"); + } + + if (role == Qt::FontRole && index.column() == 1) { + QFont font = qvariant_cast(QSortFilterProxyModel::data(index, role)); + font.setWeight(QFont::Light); + return font; + } + + if (role == Qt::DisplayRole) + role = (index.column() == 0) ? HistoryModel::UrlStringRole : HistoryModel::TitleRole; + + return QSortFilterProxyModel::data(index, role); +} + +QString HistoryCompletionModel::searchString() const +{ + return m_searchString; +} + +void HistoryCompletionModel::setSearchString(const QString &str) +{ + if (str == m_searchString) + return; + + m_searchString = str; + m_searchMatcher.setPattern(str); + m_wordMatcher.setPattern(QLatin1String("\\b") + QRegExp::escape(str)); + invalidateFilter(); +} + +bool HistoryCompletionModel::isValid() const +{ + return m_isValid; +} + +void HistoryCompletionModel::setValid(bool b) +{ + if (b == m_isValid) + return; + + m_isValid = b; + + // tell the HistoryCompleter that we've changed + emit dataChanged(index(0, 0), index(0, rowCount() - 1)); +} + +bool HistoryCompletionModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + // do a case-insensitive substring match against both the url and title; + // we have also made sure that the user doesn't accidentally use regexp + // metacharacters + QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); + QString url = sourceModel()->data(idx, HistoryModel::UrlStringRole).toString(); + + if (m_searchMatcher.indexIn(url) != -1) + return true; + + QString title = sourceModel()->data(idx, HistoryModel::TitleRole).toString(); + + if (m_searchMatcher.indexIn(title) != -1) + return true; + + return false; +} + +bool HistoryCompletionModel::lessThan(const QModelIndex &left, const QModelIndex &right) const +{ + // We give a bonus to hits that match on a word boundary so that e.g. "dot.kde.org" + // is a better result for typing "dot" than "slashdot.org". However, we only look + // for the string in the host name, not the entire url, since while it makes sense + // to e.g. give "www.phoronix.com" a bonus for "ph", it does _not_ make sense to + // give "www.yadda.com/foo.php" the bonus. + int frecency_l = sourceModel()->data(left, HistoryFilterModel::FrecencyRole).toInt(); + QString url_l = sourceModel()->data(left, HistoryModel::UrlRole).toUrl().host(); + QString title_l = sourceModel()->data(left, HistoryModel::TitleRole).toString(); + + if (m_wordMatcher.indexIn(url_l) != -1 || m_wordMatcher.indexIn(title_l) != -1) + frecency_l *= 2; + + int frecency_r = sourceModel()->data(right, HistoryFilterModel::FrecencyRole).toInt(); + QString url_r = sourceModel()->data(right, HistoryModel::UrlRole).toUrl().host(); + QString title_r = sourceModel()->data(right, HistoryModel::TitleRole).toString(); + if (m_wordMatcher.indexIn(url_r) != -1 || m_wordMatcher.indexIn(title_r) != -1) + frecency_r *= 2; + + // sort results in descending frecency-derived score + return (frecency_r < frecency_l); +} + +HistoryCompleter::HistoryCompleter(QObject *parent) + : QCompleter(parent) +{ + init(); +} + +HistoryCompleter::HistoryCompleter(QAbstractItemModel *m, QObject *parent) + : QCompleter(m, parent) +{ + init(); +} + +void HistoryCompleter::init() +{ + setPopup(new HistoryCompletionView()); + + // we want to complete against our own faked role + setCompletionRole(HistoryCompletionModel::HistoryCompletionRole); + + // and since we fake our completion role, we can take + // advantage of the sorted-model optimizations in QCompleter + setCaseSensitivity(Qt::CaseSensitive); + setModelSorting(QCompleter::CaseSensitivelySortedModel); + + m_filterTimer.setSingleShot(true); + connect(&m_filterTimer, SIGNAL(timeout()), this, SLOT(updateFilter())); +} + +QString HistoryCompleter::pathFromIndex(const QModelIndex &index) const +{ + // we want to return the actual url from the history for the + // data the QCompleter finally returns + return model()->data(index, HistoryModel::UrlStringRole).toString(); +} + +QStringList HistoryCompleter::splitPath(const QString &path) const +{ + if (path == m_searchString) + return QStringList() << QLatin1String("a"); + + // queue an update to our search string + // We will wait a bit so that if the user is quickly typing, + // we don't try to complete until they pause. + if (m_filterTimer.isActive()) + m_filterTimer.stop(); + m_filterTimer.start(150); + + // if the previous search results are not a superset of + // the current search results, tell the model that it is not valid yet + if (!path.startsWith(m_searchString)) { + HistoryCompletionModel *completionModel = qobject_cast(model()); + Q_ASSERT(completionModel); + completionModel->setValid(false); + } + + m_searchString = path; + + // the actual filtering is done by the HistoryCompletionModel; we just + // return a short dummy here so that QCompleter thinks we match everything + return QStringList() << QLatin1String("a"); +} + +bool HistoryCompleter::eventFilter(QObject *obj, QEvent *event) +{ + if (event->type() == QEvent::KeyPress && popup()->isVisible()) { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Tab) { + QKeyEvent *newEvent = new QKeyEvent(QEvent::KeyPress, + Qt::Key_Down, + keyEvent->modifiers(), + QString()); + + if (!QCompleter::eventFilter(obj, newEvent)) + obj->event(newEvent); + return true; + } else if (keyEvent->key() == Qt::Key_Backtab) { + QKeyEvent *newEvent = new QKeyEvent(QEvent::KeyPress, + Qt::Key_Up, + keyEvent->modifiers(), + keyEvent->text(), + keyEvent->isAutoRepeat(), + keyEvent->count()); + + if (!QCompleter::eventFilter(obj, newEvent)) + obj->event(newEvent); + return true; + } else if (keyEvent->key() == Qt::Key_Escape) { + popup()->hide(); + } + } + return QCompleter::eventFilter(obj, event); +} + +void HistoryCompleter::updateFilter() +{ + HistoryCompletionModel *completionModel = qobject_cast(model()); + Q_ASSERT(completionModel); + + // tell the HistoryCompletionModel about the new search string + completionModel->setSearchString(m_searchString); + + // sort the model + completionModel->sort(0); + + // mark it valid + completionModel->setValid(true); + + // and now update the QCompleter widget, but only if the user is still + // typing a url + if (widget() && widget()->hasFocus()) + complete(); +} diff --git a/src/history/historycompleter.h b/src/history/historycompleter.h new file mode 100644 index 00000000..fd4af994 --- /dev/null +++ b/src/history/historycompleter.h @@ -0,0 +1,107 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * Copyright 2009 Benjamin K. Stuhl + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef HISTORYCOMPLETER_H +#define HISTORYCOMPLETER_H + +#include "history.h" + +#include +#include +#include +#include +#include + +class QResizeEvent; +class HistoryCompletionView : public QTableView +{ +public: + HistoryCompletionView(QWidget *parent = 0); + int sizeHintForRow(int row) const; + +protected: + void resizeEvent(QResizeEvent *event); +}; + +// These two classes constitute a dirty hack around QCompleter's inflexibility: +// QCompleter does not allow changing the matching algorithm; it is fixed +// at a simple QString::startsWith() comparison against the model's completionRole() +// data. (QCompleter also does not allow post-facto sorting of the completion results, +// the source model must already be completed.) To work around these limitations, +// we create a custom subclass of QCompleter which abuses the QCompleter::pathFromIndex() +// virtual override to tell the HistoryCompletionModel which string to look for, +// _before_ the QCompleter tries to do matching. Since the HistoryCompletionModel does +// its own filtering, we just lie to the QCompleter and tell it everything matches. We then +// abuse QCompleter::pathFromIndex() to return a url that does not start with what +// the user typed -- but is what they were looking for. + +class HistoryCompletionModel : public QSortFilterProxyModel +{ + Q_OBJECT + Q_PROPERTY(QString searchString READ searchString WRITE setSearchString) + +public: + HistoryCompletionModel(QObject *parent = 0); + + enum Roles { HistoryCompletionRole = HistoryFilterModel::MaxRole + 1 }; + + QString searchString() const; + void setSearchString(const QString &str); + + bool isValid() const; + void setValid(bool b); + + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +protected: + virtual bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const; + +private: + QString m_searchString; + QRegExp m_searchMatcher; + QRegExp m_wordMatcher; + bool m_isValid; +}; + +class HistoryCompleter : public QCompleter +{ + Q_OBJECT + +public: + HistoryCompleter(QObject *parent = 0); + HistoryCompleter(QAbstractItemModel *model, QObject *parent = 0); + + virtual QString pathFromIndex(const QModelIndex &index) const; + virtual QStringList splitPath(const QString &path) const; + +protected: + bool eventFilter(QObject *obj, QEvent *event); + +private slots: + void updateFilter(); + +private: + void init(); + mutable QString m_searchString; + mutable QTimer m_filterTimer; +}; + +#endif diff --git a/src/history/historymanager.cpp b/src/history/historymanager.cpp new file mode 100644 index 00000000..87c0cf53 --- /dev/null +++ b/src/history/historymanager.cpp @@ -0,0 +1,416 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "historymanager.h" + +#include "autosaver.h" +#include "browserapplication.h" +#include "history.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +QString HistoryEntry::userTitle() const +{ + // when there is no title try to generate one from the url + if (title.isEmpty()) { + QString page = QFileInfo(QUrl(url).path()).fileName(); + if (!page.isEmpty()) + return page; + return url; + } + return title; +} + +static const unsigned int HISTORY_VERSION = 23; + +HistoryManager::HistoryManager(QObject *parent) + : QWebHistoryInterface(parent) + , m_saveTimer(new AutoSaver(this)) + , m_daysToExpire(30) + , m_historyModel(0) + , m_historyFilterModel(0) + , m_historyTreeModel(0) +{ + m_expiredTimer.setSingleShot(true); + connect(&m_expiredTimer, SIGNAL(timeout()), + this, SLOT(checkForExpired())); + connect(this, SIGNAL(entryAdded(const HistoryEntry &)), + m_saveTimer, SLOT(changeOccurred())); + connect(this, SIGNAL(entryRemoved(const HistoryEntry &)), + m_saveTimer, SLOT(changeOccurred())); + load(); + + m_historyModel = new HistoryModel(this, this); + m_historyFilterModel = new HistoryFilterModel(m_historyModel, this); + m_historyTreeModel = new HistoryTreeModel(m_historyFilterModel, this); + + // QWebHistoryInterface will delete the history manager + QWebHistoryInterface::setDefaultInterface(this); +} + +HistoryManager::~HistoryManager() +{ + // remove history items on application exit + if (m_daysToExpire == -2) + clear(); + m_saveTimer->saveIfNeccessary(); +} + +QList HistoryManager::history() const +{ + return m_history; +} + +bool HistoryManager::historyContains(const QString &url) const +{ + return m_historyFilterModel->historyContains(url); +} + +void HistoryManager::addHistoryEntry(const QString &url) +{ + QUrl cleanUrl(url); + cleanUrl.setPassword(QString()); + cleanUrl.setHost(cleanUrl.host().toLower()); + HistoryEntry item(atomicString(cleanUrl.toString()), QDateTime::currentDateTime()); + prependHistoryEntry(item); +} + +void HistoryManager::setHistory(const QList &history, bool loadedAndSorted) +{ + m_history = history; + + // verify that it is sorted by date + if (!loadedAndSorted) + qSort(m_history.begin(), m_history.end()); + + checkForExpired(); + + if (loadedAndSorted) { + m_lastSavedUrl = m_history.value(0).url; + } else { + m_lastSavedUrl.clear(); + m_saveTimer->changeOccurred(); + } + emit historyReset(); +} + +HistoryModel *HistoryManager::historyModel() const +{ + return m_historyModel; +} + +HistoryFilterModel *HistoryManager::historyFilterModel() const +{ + return m_historyFilterModel; +} + +HistoryTreeModel *HistoryManager::historyTreeModel() const +{ + return m_historyTreeModel; +} + +void HistoryManager::checkForExpired() +{ + if (m_daysToExpire < 0 || m_history.isEmpty()) + return; + + QDateTime now = QDateTime::currentDateTime(); + int nextTimeout = 0; + + while (!m_history.isEmpty()) { + QDateTime checkForExpired = m_history.last().dateTime; + checkForExpired.setDate(checkForExpired.date().addDays(m_daysToExpire)); + if (now.daysTo(checkForExpired) > 7) { + // check at most in a week to prevent int overflows on the timer + nextTimeout = 7 * 86400; + } else { + nextTimeout = now.secsTo(checkForExpired); + } + if (nextTimeout > 0) + break; + HistoryEntry item = m_history.takeLast(); + // remove from saved file also + m_lastSavedUrl.clear(); + emit entryRemoved(item); + } + + if (nextTimeout > 0) + m_expiredTimer.start(nextTimeout * 1000); +} + +void HistoryManager::prependHistoryEntry(const HistoryEntry &item) +{ + QWebSettings *globalSettings = QWebSettings::globalSettings(); + if (globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) + return; + + m_history.prepend(item); + emit entryAdded(item); + if (m_history.count() == 1) + checkForExpired(); +} + +void HistoryManager::updateHistoryEntry(const QUrl &url, const QString &title) +{ + for (int i = 0; i < m_history.count(); ++i) { + if (url == m_history.at(i).url) { + m_history[i].title = atomicString(title); + m_saveTimer->changeOccurred(); + if (m_lastSavedUrl.isEmpty()) + m_lastSavedUrl = m_history.at(i).url; + emit entryUpdated(i); + break; + } + } +} + +void HistoryManager::removeHistoryEntry(const HistoryEntry &item) +{ + m_lastSavedUrl.clear(); + m_history.removeOne(item); + emit entryRemoved(item); +} + +void HistoryManager::removeHistoryEntry(const QUrl &url, const QString &title) +{ + for (int i = 0; i < m_history.count(); ++i) { + if (url == m_history.at(i).url + && (title.isEmpty() || title == m_history.at(i).title)) { + removeHistoryEntry(m_history.at(i)); + break; + } + } +} + +int HistoryManager::daysToExpire() const +{ + return m_daysToExpire; +} + +void HistoryManager::setDaysToExpire(int limit) +{ + if (m_daysToExpire == limit) + return; + m_daysToExpire = limit; + checkForExpired(); + m_saveTimer->changeOccurred(); +} + +void HistoryManager::clear() +{ + m_history.clear(); + m_atomicStringHash.clear(); + m_lastSavedUrl.clear(); + m_saveTimer->changeOccurred(); + m_saveTimer->saveIfNeccessary(); + emit historyReset(); + emit historyCleared(); +} + +void HistoryManager::loadSettings() +{ + // load settings + QSettings settings; + settings.beginGroup(QLatin1String("history")); + m_daysToExpire = settings.value(QLatin1String("historyLimit"), 30).toInt(); +} + +void HistoryManager::load() +{ + loadSettings(); + + QFile historyFile(BrowserApplication::dataFilePath(QLatin1String("history"))); + + if (!historyFile.exists()) + return; + if (!historyFile.open(QFile::ReadOnly)) { + qWarning() << "Unable to open history file" << historyFile.fileName(); + return; + } + + QList list; + QDataStream in(&historyFile); + // Double check that the history file is sorted as it is read in + bool needToSort = false; + HistoryEntry lastInsertedItem; + QByteArray data; + QDataStream stream; + QBuffer buffer; + QString string; + stream.setDevice(&buffer); + while (!historyFile.atEnd()) { + in >> data; + buffer.close(); + buffer.setBuffer(&data); + buffer.open(QIODevice::ReadOnly); + quint32 ver; + stream >> ver; + if (ver != HISTORY_VERSION) + continue; + HistoryEntry item; + stream >> string; + item.url = atomicString(string); + stream >> item.dateTime; + stream >> string; + item.title = atomicString(string); + + if (!item.dateTime.isValid()) + continue; + + if (item == lastInsertedItem) { + if (lastInsertedItem.title.isEmpty() && !list.isEmpty()) + list[0].title = item.title; + continue; + } + + if (!needToSort && !list.isEmpty() && lastInsertedItem < item) + needToSort = true; + + list.prepend(item); + lastInsertedItem = item; + } + if (needToSort) + qSort(list.begin(), list.end()); + + setHistory(list, true); + + // If we had to sort re-write the whole history sorted + if (needToSort) { + m_lastSavedUrl.clear(); + m_saveTimer->changeOccurred(); + } +} + +QString HistoryManager::atomicString(const QString &string) { + QHash::const_iterator it = m_atomicStringHash.constFind(string); + if (it == m_atomicStringHash.constEnd()) { + QHash::iterator insertedIterator = m_atomicStringHash.insert(string, 0); + return insertedIterator.key(); + } + return it.key(); +} + +void HistoryManager::save() +{ + QSettings settings; + settings.beginGroup(QLatin1String("history")); + settings.setValue(QLatin1String("historyLimit"), m_daysToExpire); + + bool saveAll = m_lastSavedUrl.isEmpty(); + int first = m_history.count() - 1; + if (!saveAll) { + // find the first one to save + for (int i = 0; i < m_history.count(); ++i) { + if (m_history.at(i).url == m_lastSavedUrl) { + first = i - 1; + break; + } + } + } + if (first == m_history.count() - 1) + saveAll = true; + + QFile historyFile(BrowserApplication::dataFilePath(QLatin1String("history"))); + + // When saving everything use a temporary file to prevent possible data loss. + QTemporaryFile tempFile; + tempFile.setAutoRemove(false); + bool open = false; + if (saveAll) { + open = tempFile.open(); + } else { + open = historyFile.open(QFile::Append); + } + + if (!open) { + qWarning() << "Unable to open history file for saving" + << (saveAll ? tempFile.fileName() : historyFile.fileName()); + return; + } + + QDataStream out(saveAll ? &tempFile : &historyFile); + for (int i = first; i >= 0; --i) { + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + HistoryEntry item = m_history.at(i); + stream << HISTORY_VERSION << item.url << item.dateTime << item.title; + out << data; + } + tempFile.close(); + + if (saveAll) { + if (historyFile.exists() && !historyFile.remove()) + qWarning() << "History: error removing old history." << historyFile.errorString(); + if (!tempFile.rename(historyFile.fileName())) + qWarning() << "History: error moving new history over old." << tempFile.errorString() << historyFile.fileName(); + } + m_lastSavedUrl = m_history.value(0).url; +} \ No newline at end of file diff --git a/src/history/historymanager.h b/src/history/historymanager.h new file mode 100644 index 00000000..13c0854f --- /dev/null +++ b/src/history/historymanager.h @@ -0,0 +1,162 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef HISTORYMANAGER_H +#define HISTORYMANAGER_H + +#include +#include +#include +#include +#include + +class HistoryEntry +{ +public: + HistoryEntry() {} + HistoryEntry(const QString &u, + const QDateTime &d = QDateTime(), const QString &t = QString()) + : url(u), title(t), dateTime(d) {} + + inline bool operator==(const HistoryEntry &other) const { + return other.title == title + && other.url == url && other.dateTime == dateTime; + } + + // history is sorted in reverse + inline bool operator <(const HistoryEntry &other) const + { return dateTime > other.dateTime; } + + QString userTitle() const; + + QString url; + QString title; + QDateTime dateTime; +}; + +class AutoSaver; +class HistoryModel; +class HistoryFilterModel; +class HistoryTreeModel; +class HistoryManager : public QWebHistoryInterface +{ + Q_OBJECT + Q_PROPERTY(int daysToExpire READ daysToExpire WRITE setDaysToExpire) + +signals: + void historyCleared(); + void historyReset(); + void entryAdded(const HistoryEntry &item); + void entryRemoved(const HistoryEntry &item); + void entryUpdated(int offset); + +public: + HistoryManager(QObject *parent = 0); + ~HistoryManager(); + + bool historyContains(const QString &url) const; + void addHistoryEntry(const QString &url); + void updateHistoryEntry(const QUrl &url, const QString &title); + void removeHistoryEntry(const QUrl &url, const QString &title = QString()); + + int daysToExpire() const; + void setDaysToExpire(int limit); + + QList history() const; + void setHistory(const QList &history, bool loadedAndSorted = false); + + // History manager keeps around these models for use by the completer and other classes + HistoryModel *historyModel() const; + HistoryFilterModel *historyFilterModel() const; + HistoryTreeModel *historyTreeModel() const; + +public slots: + void clear(); + void loadSettings(); + +private slots: + void save(); + void checkForExpired(); + +protected: + void prependHistoryEntry(const HistoryEntry &item); + void removeHistoryEntry(const HistoryEntry &item); + +private: + void load(); + QString atomicString(const QString &string); + void startFrecencyTimer(); + + AutoSaver *m_saveTimer; + int m_daysToExpire; + QTimer m_expiredTimer; + QHash m_atomicStringHash; + QList m_history; + QString m_lastSavedUrl; + + HistoryModel *m_historyModel; + HistoryFilterModel *m_historyFilterModel; + HistoryTreeModel *m_historyTreeModel; +}; + +#endif // HISTORYMANAGER_H + diff --git a/src/htmls/dirlist.html b/src/htmls/dirlist.html new file mode 100644 index 00000000..d865c274 --- /dev/null +++ b/src/htmls/dirlist.html @@ -0,0 +1,95 @@ + + + +%1 + + + + +
    +

    %2

    +
    + %5 +
    + +%4 +
    +
    + + diff --git a/src/htmls/htmls.qrc b/src/htmls/htmls.qrc index 03b256cc..da555367 100644 --- a/src/htmls/htmls.qrc +++ b/src/htmls/htmls.qrc @@ -1,5 +1,8 @@ + dirlist.html notfound.html + startpage.html + startpage.css diff --git a/src/htmls/notfound.html b/src/htmls/notfound.html old mode 100755 new mode 100644 index c3f89713..edce82ef --- a/src/htmls/notfound.html +++ b/src/htmls/notfound.html @@ -36,7 +36,7 @@ ul { font-size: 80%; padding-left: 48px; - margin: 0; + margin: 5px 0; } #reloadButton { padding-left: 48px; @@ -47,17 +47,12 @@

    %2

    -

    When connecting to: %3.

    +

    %3

      -
    • Check the address for errors such as ww.trolltech.com - instead of www.trolltech.com
    • -
    • If the address is correct, try to check the network - connection.
    • -
    • If your computer or network is protected by a firewall or - proxy, make sure that the browser is permitted to access - the network.
    • +
    • %4
    • +
    • %5
    • +
    • %6
    -

    diff --git a/src/htmls/startpage.css b/src/htmls/startpage.css new file mode 100644 index 00000000..432b4c2a --- /dev/null +++ b/src/htmls/startpage.css @@ -0,0 +1,74 @@ +* { + margin: 0; + padding: 0; + font-family: "DejaVu Sans"; +} + +body { + background: -webkit-gradient(linear, left top, left bottom, from(#ccc), to(#fff), color-stop(0.5, #fff)); + background-repeat: repeat-x; + margin-top: 100px; +} + +#header, #search, #footer { + width: 500px; + margin: 10px auto; +} + +#header, #search { + -webkit-border-radius: 0.8em; + padding: 25px; +} + +#header { + background: -webkit-gradient(linear, left top, left bottom, from(#228), to(#668), color-stop(0.9, #66a)); + height: 20px; +} + +#header h1 { + display: inline; + font-size: 1.7em; + color: #fff; + font-weight: bold; +} + +#header img { + display: inline; + float: right; + height: 150px; + margin-top: -80px; +} + +#search { + background: -webkit-gradient(linear, left top, right top, from(#cdf), to(#cdf), color-stop(0.5, #eff)); + height: 50px; + color: #000; + text-align: center; + padding-top: 40px !important; +} + +#search fieldset { + border: 0; +} + +#search input[type=text] { + width: 65%; +} + +#search input[type=submit] { + width: 25%; +} + +#footer { + text-align: center; + color: #999; +} + +#footer a { + color: #555; + text-decoration: none; +} + +#footer a:hover { + text-decoration: underline; +} diff --git a/src/htmls/startpage.html b/src/htmls/startpage.html new file mode 100644 index 00000000..c6cdd853 --- /dev/null +++ b/src/htmls/startpage.html @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + diff --git a/src/locale/.gitattributes b/src/locale/.gitattributes new file mode 100644 index 00000000..47e45937 --- /dev/null +++ b/src/locale/.gitattributes @@ -0,0 +1 @@ +*.ts -crlf -diff -merge diff --git a/src/locale/ast.ts b/src/locale/ast.ts new file mode 100644 index 00000000..d327bc75 --- /dev/null +++ b/src/locale/ast.ts @@ -0,0 +1,2229 @@ + + + + + AboutDialog + + Lightweight WebKit-based web browser + Restolador llixeru basáu en WebKit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Authors + Autores + + + License + Llicencia + + + Close + Zarrar + + + About %1 + Tocante a %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + Llingües + + + Languages: in order of preference: + Llingües: n'orde de preferencia: + + + Move &Up + Mover p'&arriba + + + Move &Down + Mover p'a&baxo + + + &Remove + &Desaniciar + + + Add... + Amestar... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Regla + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Amestar marcador + + + Type a name for the bookmark, and choose where to keep it. + Escribi un nome pal marcador y escueye au quiés guardalu. + + + Url + Url + + + Title + Títulu + + + Add Folder + Amestar carpeta + + + + AutoFillDialog + + Form Passwords + + + + Remove + Desaniciar + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Bookmarks + Marcadores + + + &Remove + &Desaniciar + + + Add Folder + Criar carpeta + + + Open + Abrir + + + Open in New Tab + Abrir nuna nueva llingüeta + + + Delete + Desaniciar + + + New Folder + Nueva carpeta + + + Edit Name + Editar nome + + + Edit Address + Editar direición + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Error al cargar los marcadores na llinia %1, columna %2: %3 + + + + Toolbar Bookmarks + Barra de ferramientes de marcadores + + + Menu + Menú + + + Open File + Abrir Ficheru + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importáu %1 + + + Save File + Guardar Ficheru + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Error al esportar + + + error saving bookmarks + Error guardando los marcadores + + + Remove Bookmark + Desaniciar marcador + + + Insert Bookmark + Enxertar marcador + + + Bookmarks Bar + Barra de marcadores + + + Bookmarks Menu + Menú de marcadores + + + Error when loading html bookmarks: %1 + + Error al cargar marcadores html: %1 + + + + XBEL + XBEL + + + Name Change + Undo bookmark title change + Cambear el nome + + + Address Change + Undo bookmark url change + Cambear la direición + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + Abrir en llingüetes + + + + BookmarksModel + + Title + Títulu + + + Address + Direición + + + + BookmarksToolBar + + Bookmark + Marcador + + + Open + Abrir + + + Open in New &Tab + Abrir nuna Nueva &Llingüeta + + + Remove + Desaniciar + + + Add Bookmark... + Amestar marcador... + + + Add Folder... + Amestar carpeta... + + + Bookmarks + Marcadores + + + + BrowserApplication + + (Change: %1 %2) + (Cambéu: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Hai %1 ventanes y %2 llingüetes abiertes +¿Tas seguru de que quiés colar? + + + Restore failed + Falló la recuperación + + + The saved session will not be restored because Arora crashed while trying to restore this session. + La sesión guardada nun puede recuperase darréu que Arora falló durante la cabera recuperación. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Ficheru + + + &New Window + &Ventana Nueva + + + &Open File... + &Abrir Ficheru... + + + Open &Location... + Abrir &sitiu... + + + &Save As... + &Guardar como... + + + &Import Bookmarks... + &Importar marcadores... + + + &Export Bookmarks... + &Esportar marcadores... + + + P&rint Preview... + V&ista previa... + + + &Print... + Im&prentar... + + + Private &Browsing... + &Restolación privao... + + + &Quit + &Colar + + + &Edit + &Editar + + + &Undo + &Desfacer + + + &Redo + &Refacer + + + Cu&t + Cor&tar + + + &Copy + &Copiar + + + &Paste + &Apegar + + + &Find + &Guetar + + + Find Nex&t + Guetar siguiente + + + Find P&revious + Guetar &anterior + + + Prefere&nces... + &Preferencies... + + + Ctrl+, + Ctrl+, + + + &View + &Ver + + + Show Menu Bar + Amosar barra de menú + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Parar + + + &Reload Page + &Recargar páxina + + + Page S&ource + Códigu &fonte + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Pantalla &completa + + + Hi&story + &Hestorial + + + Back + Atrás + + + Forward + Alantre + + + Home + Aniciu + + + Restore Last Session + Recuperar la cabera sesión + + + &Bookmarks + &Marcadores + + + Add Bookmark... + Amestar marcador... + + + &Window + &Ventana + + + &Tools + &Ferramientes + + + Web &Search + &Guetar na web + + + Ctrl+K + +Web Search + + Ctrl+K + + + &Clear Private Data + &Llimpiar datos privaos + + + Ctrl+Shift+Delete + +Clear Private Data + + Ctrl+Shift+Delete + + + Enable Web &Inspector + Activar l'&inspector web + + + &Help + A&ida + + + About &Qt + Tocante a &Qt + + + Navigation + Restolación + + + Show Status Bar + Amosar la barra d'estáu + + + Hide Status Bar + Anubrir la barra d'estáu + + + Show Toolbar + Amosar la barra de ferramientes + + + Hide Toolbar + Anubrir la barra de ferramientes + + + Show Bookmarks Bar + Amosar la barra de marcadores + + + Hide Bookmarks Bar + Anubrir la barra de marcadores + + + %1 - Arora + +Page title and Browser name + + %1 - Arora + + + Open Web Resource + Abrir un recursu web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Recursos web (*.html *.htm *.svg *.png *.gif *.svgz);;Tolos ficheros (*.*) + + + Print Document + Imprentar documentu + + + Are you sure you want to turn on private browsing? + ¿Tas seguru de que quiés activar la restolación privao? + + + Are you sure you want to close the window? There are %1 tabs open + ¿Tas seguru de que quiés zarrar la ventana? Hai %1 llingüetes abiertes + + + Web Inspector + Inspector web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + L'inspector web namás furrulará correcho coles páxines cargaes dempués d'activalu. +¿Quiés recargar toles páxines? + + + Stop loading the current page + Detener la carga de la páxina actual + + + Reload the current page + Recargar la páxina actual + + + Downloads + Descargues + + + Show &Network Monitor + Amosar mo&nitor de rede + + + Switch application language + Cambear la llingua de l'aplicación + + + Close Window + Zarrar ventana + + + Zoom &In + Zoom &aumentar + + + Zoom &Normal + Zoom &normal + + + Zoom &Out + Zoom &amenorgar + + + Zoom &Text Only + Zoom solo &testu + + + About &%1 + About Browser + + Tocante a &%1 + + + Ctrl+Y + +Download Manager + + Ctrl+Y + + + Show All Bookmarks... + Amosar tolos marcadores... + + + Add Folder... + Amestar carpeta... + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Al activar la restolación privao, desactiváranse delles midíes relatives a la to privacidá:<ul><li> Les páxines web nun van amestase al hestorial.</li><li> Desaniciaránse automáticamente los elementos de la ventana de descargues.</li><li> Nun s'amestarán nueves galletes y les actuales nun sedrán accesibles.</li><li> Los iconos de los sitios nun s'atroxarán, nin se guardarán les sesiones.</li><li> Les guetes nun s'amestarán al menú emerxente nel cuadru de gueta.</li></ul>Podrás facer clic nos botones Atrás y Alantre pa volver a les páxines web qu'abristi namás fasta que se zarre la ventana. + + + Default + + + + Select &All + + + + Alt+Ctrl+B + + + + Text Encoding + + + + Ctrl+K + Web Search + Ctrl+K + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + About &%1 + About Browser + Tocante a &%1 + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Options... + + + + Configure Search Engines... + Configurar motores de gueta... + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Llimpiar + + + + ClearPrivateData + + Clear Private Data + Llimpiar datos privaos + + + Clear the following items: + Llimpiar los siguientes elementos: + + + &Browsing History + Hestorial de &restolación + + + &Download History + Hestorial de &descargues + + + &Search History + Hestorial de &guetes + + + &Cookies + &Galletes + + + C&ached Web Pages + Páxines &web na memoria caché + + + Website &Icons + &Iconos de los sitios web + + + Clear &Private Data + Llimpiar datos &privaos + + + &Cancel + &Encaboxar + + + + ClickToFlash + + Load + Cargar + + + Load All + Cargar too + + + Add %1 to Whitelist + Amestar %1 a la llista blanca + + + Remove from Whitelist + Quitar de la llista blanca + + + Settings + Axustes + + + Load Flash + Cargar «Flash» + + + + ClickToFlashSettings + + Whitelist sites + Llista blanca de sitios + + + + CookieExceptionsModel + + Website + Sitiu web + + + Rule + Regla + + + Allow + Permitir + + + Block + Bloquiar + + + Allow For Session + Permitir namái pa esta sesión + + + + CookieModel + + Website + Sitiu web + + + Name + Nome + + + Path + Ubicación + + + Secure + Seguru + + + Expires + Caduca + + + Contents + Conteníos + + + true + verdaderu + + + false + falsu + + + Session cookie + Galleta de la sesión + + + + CookiesDialog + + Cookies + Galletes + + + &Remove + &Desaniciar + + + Remove &All Cookies + Desaniciar &toles galletes + + + Add &Rule + Amestar &regla + + + + CookiesExceptionsDialog + + Cookie Exceptions + Galletes escluyíes + + + New Exception + Nueva esceición + + + Domain: + Dominiu: + + + Block + Bloquiar + + + Allow For Session + Permitir namás pa esta sesión + + + Allow + Permitir + + + Exceptions + Esceiciones + + + &Remove + &Desaniciar + + + Remove &All + Desaniciar &toes + + + + DownloadDialog + + Downloads + Descargues + + + Clean up + Vaciar + + + 0 Items + 0 elementos + + + + DownloadItem + + Form + Formulariu + + + Ico + Iconu + + + Filename + Nome d'archivu + + + Try Again + Volver a intentalo + + + Stop + Parar + + + Open + Abrir + + + Save File + Guardar ficheru + + + Download canceled: %1 + Descarga encaboxada: %1 + + + Error opening output file: %1 + Error al abrir l'archivu de salida: %1 + + + Error saving: %1 + Error al guardar: %1 + + + Network Error: %1 + Error de rede: %1 + + + ? + ? + + + %1 of %2 - Stopped + %1 de %2 - Parao + + + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/seg) - %4 + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + %n Download(s) + + %n Descarga(ues) + + + + + + + There are %1 downloads in progress +Do you want to quit anyway? + Hai %1 descargues en procesu +¿Quiés colar de toes formes? + + + %n minutes remaining + + Falten %n minutos + + + + + + %n seconds remaining + + Falten %n segundos + + + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + History + Hestorial + + + &Remove + &Desaniciar + + + Remove &All + Desaniciar &too + + + Open + Abrir + + + Copy + Copiar + + + Delete + Desaniciar + + + + HistoryMenu + + Show All History + Amosar tol hestorial + + + Clear History... + Llimpiar hestorial... + + + Clear History + Llimpiar hestorial + + + Do you want to clear the history? + ¿Quiés llimpiar l'hestorial? + + + + HistoryModel + + Title + Títulu + + + Address + Direición + + + + HistoryTreeModel + + Earlier Today + Vai un ratu + + + %n item(s) + + %n elementu(os) + + + + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + Choose language + Escoyer llingua + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Pué executase con una llingua distinta<br>a la predeterminá del sistema operativu.</p><p>Per favor, escueye la llingua que quiés utilizar</p> + + + No translation files are installed. + Los archivos de torna nun tan instalaos. + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Introduz el nome d'usuariu y la contraseña pa "%1" en %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Coneutar al proxy "%1" usando:</qt> + + + - SSL Errors + Errores -SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Errores SSL:<br/><br/>pa: <tt>%1</tt><ul><li>%2</li></ul> + +¿Inorar estos errores?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificaos:<br/>%1<br/>¿Quiés aceutar toos estos certificaos?</qt> + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Nome + + + Value + Valor + + + + NetworkMonitorDialog + + Network Monitor + Monitor de rede + + + Network Requests + Solicitudes de rede + + + Request Headers + Cabeceres de les solicitudes + + + Response Headers + Cabeceres de retruca + + + &Remove + &Desaniciar + + + Remove &All Requests + Desaniciar &toles solicitudes + + + + OpenSearchDialog + + Open File + Abrir Ficheru + + + OpenSearch + OpenSearch + + + Error + Error + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 nun ye una descripción correcho pa OpenSearch 1.1 o yá ta na to llista. + + + You must have at least one search engine in here. + Tienes de tener equí polo menos un motor de gueta. + + + OpenSearch Manager + Xestor OpenSearch + + + &Restore Defaults + &Restaurar predeterminaos + + + &Delete + &Desaniciar + + + &Add + &Amestar + + + &Close + &Zarrar + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descripción:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Proporciona suxerencies contestuales</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Nome + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + ¿Quiés amestar el siguiente motor a la to llista de motores de gueta?<br /><br />Nome: %1<br />Guetes en: %2 + + + + PasswordDialog + + Authentication Required + Precísase autenticación + + + DUMMY ICON + ICONU SIMULAU + + + INTRO TEXT DUMMY + ENXERTAR TESTU SIMULAU + + + Username: + Nome d'usuariu: + + + Password: + Contraseña: + + + + PlainTextEditSearch + + Not Found + Non alcontráu + + + + ProxyDialog + + Proxy Authentication + Autenticación nel proxy + + + Connect to proxy + Coneutar al proxy + + + Username: + Nome d'usuariu: + + + Password: + Contraseña: + + + + QObject + + The file is not an XBEL version 1.0 file. + L'archivu nun ye un archivu XBEL versión 1.0. + + + Unknown title + Títulu desconociu + + + The file is not an OpenSearch 1.1 file. + Esti archivu nun ye un archivu OpenSearch 1.1. + + + + RequestModel + + Redirect: %1 + Redirixe a: %1 + + + Method + Métodu + + + Address + Direición + + + Response + Retruca + + + Length + Llonxitú + + + Content Type + Triba de conteníu + + + Info + Información + + + + SearchBanner + + Form + Formulariu + + + Done + Fecho + + + Highlight All + + + + + SearchLineEdit + + Search + Guetar + + + + Settings + + Preferences + Preferencies + + + General + Xeneral + + + On startup: + Nel aniciu: + + + Show my home page + Amosar la mio páxina d'aniciu + + + Show a blank page + Amosar páxina en blancu + + + Restore windows and tabs from last time + Restaurar ventanes y llingüetes de la cabera sesión + + + Home Page: + Páxina d'aniciu: + + + Set to current page + Páxina actual + + + Remove history items: + Desaniciar páxines del hestorial: + + + After one day + Al cabu d'un día + + + After one week + Al cabu d'una selmana + + + After two weeks + Al cabu de dos selmanes + + + After one month + Al cabu d'un mes + + + After one year + Al cabu d'un añu + + + Manually + Manualmente + + + On application exit + Al zarrar l'aplicación + + + Open links from applications: + Abrir enllaces dende aplicaciones: + + + In a new window + Nuna ventana nueva + + + Downloads + Descargues + + + Ask for a destination each time + Entrugar en cada casu ónde se quier guardar + + + Use this destination: + Usar esti destinu: + + + Appearance + Apariencia + + + Standard font: + Tipografía estándar: + + + Select... + Seleicionar... + + + Fixed-width font: + Tipografía d'anchu fixu: + + + Privacy + Privacidá + + + Web Content + Conteniu web + + + Enable Plugins + Activar añadíos + + + Enable Javascript + Activar javascript + + + View Images + Ver imáxenes + + + Cookies + Galletes + + + Accept Cookies: + Aceutar galletes: + + + Always + Siempres + + + Never + Nunca + + + Only from sites you navigate to + Namás dende los sitios que visite + + + Exceptions... + Esceiciones... + + + Keep Cookies Until: + Caltener les galletes: + + + They expire + Fasta que caduquen + + + I exit the application + Fasta que zarre l'aplicación + + + At most 90 days + 90 díes como máximu + + + Cookies... + Galletes... + + + Tabs + Llingüetes + + + Select tabs and windows as they are created + Seleicionar llingüetes y ventanes al ser criaes + + + Proxy + Proxy + + + Use proxy server + Usar un sirvidor proxy + + + Type: + Tipu: + + + Socks5 + Socks5 + + + Host name: + Nome de la máquina: + + + Port: + Puertu: + + + User Name: + Nome d'usuariu: + + + Password: + Contraseña: + + + Advanced + Avanzao + + + Style Sheet: + Fueya d'estilos: + + + Show only one close button instead of one for each tab + Amosar namás qu'un botón de cierre en llugar d'unu pa cada llingüeta + + + Block Popup Windows + Bloquiar ventanes emerxentes + + + Opening links + Abriendo enllaces + + + Links that want to open in a new window: + Enllaces que quiés abrir nuna nueva ventana: + + + In a new selected tab in the current window + Na llingüeta seleicioná na ventana actual + + + In a new tab in the current window + Nuna nueva llingüeta na ventana actual + + + In the current tab + Na llingüeta actual + + + Http (Secure) + Http (Seguru) + + + Http (Transparent) + Http (Tresparente) + + + Preferred languages for viewing webpages in: + Llingües preferíes pa visualizar páxines web en: + + + Use ClickToFlash on flash plugins + Usar ClickToFlash nes estensiones flash + + + Filter Tracking Cookies + Peñerar les galletes de seguimientu + + + Confirm when closing multiple tabs or windows + Pedir confirmación cuando se zarren multiples llingüetes o ventanes + + + Quit the application when last tab is closed + Colar de l'aplicación cuando se zarre la cabera llingüeta + + + Enable network cache + Activar caché de rede + + + Maximum Size: + Tamañu máximu: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + Precísase reaniciar + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + La configuración de la caché de rede camudó. Col fin de que seya tenida en cunta, el restolador tién de reaniciase. + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Cargando... + + + &Edit + &Editar + + + &Find + &Guetar + + + &View + &Ver + + + &Wrap lines + A&xustar les llinies + + + Source of Page + Códigu fonte de la páxina + + + Source of Page %1 + + + + + TabBar + + Show Tab Bar + Amosar barra de llingüetes + + + Hide Tab Bar + Anubrir barra de llingüetes + + + Duplicate Tab + Duplicar llingüeta + + + &Close Tab + &Zarrar llingüeta + + + Close &Other Tabs + Zarrar les &otres llingüetes + + + Reload Tab + Recargar llingüeta + + + Reload All Tabs + Recargar toles llingüetes + + + + TabWidget + + New &Tab + Nueva &llingüeta + + + &Close Tab + &Zarrar llingüeta + + + Show Next Tab + Amosar llingüeta siguiente + + + Show Previous Tab + Amosar llingüeta anterior + + + Recently Closed Tabs + Llingüetes zarraes caberamente + + + Untitled + Ensin títulu + + + Do you really want to close this page? + ¿Tas seguru de querer zarrar esta páxina? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Modificasti esta páxina y si la zarres perderás tolos cambeos. +¿Daveres quies zarrar esta páxina? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Llingüetes guardaes + + + Loading... + Cargando... + + + Loading %1% (%2 %3)... + Cargando %1% (%2 %3)... + + + Finished loading + Carga finada + + + Failed to load + Hebo un fallu durante la carga + + + Bookmark All Tabs + Toles llingüetes a marcadores + + + + ToolbarSearch + + No Recent Searches + Nun hai guetes recientes + + + Recent Searches + Guetes recientes + + + Clear Recent Searches + Llimpiar guetes recientes + + + Suggestions + Suxerencies + + + Add '%1' + Amestar «%1» + + + Configure Search Engines... + Configurar motores de gueta... + + + + WebPage + + Error loading page: %1 + Error al cargar la páxina: %1 + + + When connecting to: %1. + Cuando se coneuta a: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Comproba que nun hai errores na direición como<b>ww</b>.arora-browser.org en llugar de <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Si el to ordenador o rede tan protexios per un cortafueos o un proxy, comproba que al restolador se-y permite l'accesu a la rede. + + + If the address is correct, try checking the network connection. + Si la direición ye correcha, comproba la conesión de rede. + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Abrir nuna &ventana nueva + + + Open in New &Tab + Abrir nuna &llingüeta nueva + + + Save Lin&k + &Guardar enllaz + + + &Bookmark This Link + &Amestar esta páxina a marcadores + + + &Copy Link Location + &Copiar direición del enllaz + + + Open Image in New &Window + Abrir &imaxe nuna ventana nueva + + + Open Image in New &Tab + Abrir i&maxe nuna llingüeta nueva + + + &Save Image + G&uardar imaxe + + + &Copy Image + Co&piar imaxe + + + C&opy Image Location + Copiar &direición de la imaxe + + + Loading... + Cargando... + + + Search with... + Guetar con... + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Non alcontráu + + + diff --git a/src/locale/ca.ts b/src/locale/ca.ts new file mode 100644 index 00000000..d417744b --- /dev/null +++ b/src/locale/ca.ts @@ -0,0 +1,2175 @@ + + + + + AboutDialog + + About %1 + Quant a %1 + + + Authors + Autors + + + License + Llicència + + + Lightweight WebKit-based web browser + Navegador web lleuger basat en WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Tanca + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + Idiomes + + + Languages: in order of preference: + Idiomes en odre de preferència: + + + Move &Up + Mou am&unt + + + Move &Down + Mou a&vall + + + &Remove + Esbo&rra + + + Add... + Afegeix... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Regla + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Url + Url + + + Title + Títol + + + Add Folder + Afegeix carpeta + + + Add Bookmark + Afegeix punt + + + Type a name for the bookmark, and choose where to keep it. + Introduïu un nom pel punt i escolliu on desar-lo. + + + + AutoFillDialog + + Form Passwords + + + + Remove + Elimina + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Obre + + + Open in New Tab + Obre en una pestanya nova + + + Edit Name + Edita nom + + + Edit Address + Edita adreça + + + Delete + Esborra + + + New Folder + Carpeta nova + + + Bookmarks + Punts + + + &Remove + &Elimina + + + Add Folder + Afegeix carpeta + + + + BookmarksManager + + Bookmarks Bar + Barra de punts + + + Bookmarks Menu + Menú de punts + + + Error when loading bookmarks on line %1, column %2: +%3 + Error en carregar punts a la línia %1, columna %2: %3 + + + Toolbar Bookmarks + Barra d'eines de punts + + + Menu + Menú + + + Open File + Obre fitxer + + + XBEL + XBEL + + + Error when loading html bookmarks: %1 + + Error en carregar punts html: %1 + + + Imported %1 + Importat: %1 + + + Save File + Desa el fitxer + + + %1 Bookmarks.xbel + %1 Punts.xbel + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Export error + Error d'exportació + + + error saving bookmarks + Erro en desar els punts + + + Remove Bookmark + Elimina punt + + + Insert Bookmark + Insereix punt + + + Name Change + Undo bookmark title change + Canvia el nom + + + Address Change + Undo bookmark url change + Canvia l'adreça + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + Obre en pestanyes + + + + BookmarksModel + + Title + Títol + + + Address + Adreça + + + + BookmarksToolBar + + Bookmark + Punt + + + Open + Obre + + + Open in New &Tab + Obre en una nova pes&tanya + + + Remove + Elimina + + + Add Bookmark... + Afegeix punt... + + + Add Folder... + Afegeix carpeta... + + + Bookmarks + Punts + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Hi ha obertes %1 finestres i %2 pestanyes +Voleu sortir igualment? + + + Restore failed + Ha fallat la restauració + + + The saved session will not be restored because Arora crashed while trying to restore this session. + La sessió desada no es restablirà perquè l'Arora va petar mentre tractava de restaurar aquesta sessió. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + Default + Predeterminat + + + &File + &Fitxer + + + &New Window + &Nova finestra + + + &Open File... + &Obre fitxer... + + + Open &Location... + Obre &localització... + + + &Save As... + &Desa com a... + + + &Import Bookmarks... + &Importa punts... + + + &Export Bookmarks... + &Exporta punts... + + + P&rint Preview... + Vista p&rèvia d'impressió... + + + &Print... + Im&primeix... + + + Private &Browsing... + Nave&gació.privada... + + + Close Window + Tanca la finestra + + + &Quit + &Abandona + + + &Edit + &Edita + + + &Undo + &Desfés + + + &Redo + &Refés + + + Cu&t + &Talla + + + &Copy + &Copia + + + &Paste + &Enganxa + + + &Find + &Cerca + + + Find Nex&t + Cerca Següen&t + + + Find P&revious + Ce&rca Anterior + + + Prefere&nces... + Preferè&ncies... + + + Ctrl+, + Ctrl+, + + + &View + &Visualitza + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Maj+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + Show Menu Bar + Mostra la barra de menú + + + &Reload Page + &Recarrega la pàgina + + + &Stop + A&tura + + + Zoom &In + &Apropa + + + Zoom &Normal + Zoom &Normal + + + Zoom &Out + A&llunya + + + Zoom &Text Only + Zoom només el &text + + + Page S&ource + C&odi font de la pàgina + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Pantalla completa + + + Text Encoding + Codificació del text + + + Hi&story + Hi&storial + + + Back + Enrere + + + Forward + Endavant + + + Home + Inici + + + Restore Last Session + Restaura l'última sessió + + + &Bookmarks + &Punts + + + Show All Bookmarks... + Mostra tots els punts... + + + Add Bookmark... + Afegeix punt... + + + Add Folder... + Afegeix carpeta... + + + &Window + &Finestra + + + &Tools + &Eines + + + Web &Search + &Cerca a la web + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Neteja les dades privades + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Maj+Supr + + + Show &Network Monitor + Mostra el mo&nitor de xarxa + + + Enable Web &Inspector + Hab&ilita l'inspector web + + + &Help + A&juda + + + Switch application language + Canvia l'idioma de l'aplicació + + + About &Qt + Quant a &Qt + + + About &%1 + About Browser + Quant a &%1 + + + Navigation + Navegació + + + Show Status Bar + Mostra la barra d'estat + + + Hide Status Bar + Oculta la barra d'estat + + + Show Toolbar + Mostra barra d'eines + + + Hide Toolbar + Oculta Barra d'eines + + + Show Bookmarks Bar + Mostra la barra de punts + + + Hide Bookmarks Bar + Oculta la barra de punts + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Obre recurs web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Recursos web (*.html *.htm *.svg *.png *.gif *.svgz);;Tots els fitxers (*.*) + + + Print Document + Imprimeix document + + + Are you sure you want to turn on private browsing? + Esteu segur que voleu activar la navegació privada? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Quan la navegació privada està activada, algunes accions corresponents a la privadesa es deshabilitaran:<ul><li>Les pàgines web no s'afegeixen a l'historial.</li><li>Els ítems son eliminats automàticament de la finestra de baixades.</li><li>No es desen les noves galetes, no es pot accedir a les galetes actuals.</li><li>Les icones dels llocs no es poden desar, les sessions no es poden desar.</li><li>Les cerques no s'afegeixen al menú desplegable a la caixa de cerca.</li></ul>Fins que no tanqueu la finestra, podeu clicar als botons Enrere i Endavant per tornar a les pàgines web que heu obert. + + + Are you sure you want to close the window? There are %1 tabs open + Esteu segur que voleu tancar la finestra? Hi ha %1 pestanyes obertes + + + Web Inspector + Inspector web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + L'inspector web només funciona correctament per pagines carregades després d'habilitar-lo. +Voleu recarregar totes les pàgines? + + + Stop loading the current page + Atura la càrrega de la pàgina actual + + + Reload the current page + Recarrega la pàgina actual + + + Downloads + Baixades + + + Ctrl+Y + + + +Download Manager + + Ctrl+Y + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + Configura els motors de cerca... + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Neteja + + + + ClearPrivateData + + Clear Private Data + Neteja les dades privades + + + Clear the following items: + Neteja els següents ítems: + + + &Browsing History + Historial de &navegació + + + &Download History + Historial de baixa&des + + + &Search History + Hi&storial de cerca + + + &Cookies + &Galetes + + + C&ached Web Pages + P&àgines web en memòria cau + + + Website &Icons + &Icones dels llocs web + + + Clear &Private Data + Neteja les dades &privades + + + &Cancel + &Cancel·la + + + + ClickToFlash + + Load + Carrega + + + Load All + Carrega-ho tot + + + Add %1 to Whitelist + Afegeix %1 a la llista blanca + + + Remove from Whitelist + Elimina de la llista blanca + + + Settings + Arranjament + + + Load Flash + Carrega Flash + + + + ClickToFlashSettings + + Whitelist sites + Llista blanca de llocs + + + + CookieExceptionsModel + + Website + Lloc web + + + Rule + Regla + + + Allow + Permet + + + Block + Bloqueja + + + Allow For Session + Permet per aquesta sessió + + + + CookieModel + + Website + Lloc web + + + Name + Nom + + + Path + Ruta + + + Secure + És segura + + + Expires + Expira + + + Contents + Continguts + + + true + cert + + + false + fals + + + Session cookie + Galeta de sessió + + + + CookiesDialog + + Cookies + Galetes + + + &Remove + &Elimina + + + Remove &All Cookies + Esborra totes les g&aletes + + + Add &Rule + Afegeix &regla + + + + CookiesExceptionsDialog + + Cookie Exceptions + Excepcions de galetes + + + New Exception + Nova excepció + + + Domain: + Domini: + + + Block + Bloqueja + + + Allow For Session + Permet per aquesta sessió + + + Allow + Permet + + + Exceptions + Excepcions + + + &Remove + &Elimina + + + Remove &All + Elimin&a-ho tot + + + + DownloadDialog + + Downloads + Baixades + + + Clean up + Neteja + + + 0 Items + 0 ítems + + + + DownloadItem + + Ico + Ico + + + Filename + Nom del fitxer + + + Try Again + Torna a intentar-ho + + + Stop + Atura + + + Open + Obre + + + Save File + Desa el fitxer + + + Download canceled: %1 + S'ha cancel·lat la baixada: %1 + + + Error opening output file: %1 + Error en obrir el fitxer de sortida: %1 + + + Error saving: %1 + Error en desar: %1 + + + Network Error: %1 + Error de xarxa: %1 + + + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/seg) - %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 de %2 - aturat + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + Hi ha %1 baixades en curs +Voleu abandonar igualment? + + + %n Download(s) + + %n baixada(es) + + + + %n minutes remaining + + %n minuts restants + + + + %n seconds remaining + + %n segons restants + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + Obre + + + Copy + Copia + + + Delete + Esborra + + + History + Historial + + + &Remove + &Elimina + + + Remove &All + Elimin&a-ho tot + + + + HistoryMenu + + Show All History + Mostra tot l'historial + + + Clear History... + Neteja l'historial... + + + Clear History + Neteja l'historial + + + Do you want to clear the history? + Voleu netejar l'historial? + + + + HistoryModel + + Title + Títol + + + Address + Adreça + + + + HistoryTreeModel + + Earlier Today + Anterior a avui + + + %n item(s) + + %n ítem(s) + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + No translation files are installed. + No s'han instal·lat fitxers de traducció. + + + Choose language + Seleccioneu l'idioma + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Podeu treballar amb un idioma diferent al<br>predeterminat del sistema.</p><p>Si us plau, seleccioneu un idioma a usar</p> + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Introduïu nom d'usuari i contrasenya per \"%1\" a \"%2\"</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Connecta al proxy \"%1\" usant:</qt> + + + - SSL Errors + - errors SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Errors SSL:<br/><br/>per: <tt>%1</tt><ul><li>%2</li></ul> + +Voleu ignorar aquests errors?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificats:<br/>%1<br/>Voleu acceptar aquests certificats?</qt> + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Nom + + + Value + Valor + + + + NetworkMonitorDialog + + Network Monitor + Monitor de xarxa + + + Network Requests + Peticions de xarxa + + + Request Headers + Capçaleres de petició + + + Response Headers + Capçaleres de resposta + + + &Remove + &Elimina + + + Remove &All Requests + Elimin&a Totes les peticions + + + + OpenSearchDialog + + Open File + Obre fitxer + + + OpenSearch + OpenSearch + + + Error + Error + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 no és una descripció OpenSearch 1.1 vàlida o ja està a la llista. + + + You must have at least one search engine in here. + Heu de tenir almenys un motor de cerca aquí. + + + OpenSearch Manager + Gestor OpenSearch + + + &Add + &Afegeix + + + &Delete + Es&borra + + + &Restore Defaults + &Restaura els valors predeterminats + + + &Close + &Tanca + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descripció:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Proporciona suggeriments contextuals</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Nom + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Voleu afegir el següent motor a la llista de motors de cerca?<br/><br />Nom: %1<br />Cerca a: %2 + + + + PasswordDialog + + Authentication Required + Es requereix autenticació + + + DUMMY ICON + ICONA SIMULADA + + + INTRO TEXT DUMMY + TEXT INTRODUÏT SIMULAT + + + Username: + Nom d'usuari: + + + Password: + Contrasenya: + + + + PlainTextEditSearch + + Not Found + No s'ha trobat + + + + ProxyDialog + + Proxy Authentication + Autenticació proxy + + + Connect to proxy + Connecta a proxy + + + Username: + Nom d'usuari: + + + Password: + Contrasenya: + + + + QObject + + The file is not an XBEL version 1.0 file. + El fitxer no és un fitxer XBEL versió 1.0. + + + Unknown title + Títol desconegut + + + The file is not an OpenSearch 1.1 file. + El fitxer no és un fitxer Opensearch 1,1. + + + + RequestModel + + Redirect: %1 + Redirecciona: %1 + + + Method + Mètode + + + Address + Adreça + + + Response + Resposta + + + Length + Durada + + + Content Type + Tipus de contingut + + + Info + Informació + + + + SearchBanner + + Done + Fet + + + Highlight All + + + + + SearchLineEdit + + Search + Cerca + + + + Settings + + Preferences + Preferències + + + General + General + + + On startup: + En iniciar: + + + Show my home page + Mostra la meva pàgina d'inici + + + Show a blank page + Mostra una pàgina en blanc + + + Restore windows and tabs from last time + Restaura les finestres i les pestanyes de la darrera vegada + + + Home Page: + Pàgina d'inici: + + + Set to current page + Estableix a la pàgina actual + + + Remove history items: + Elimina ítems de l'historial: + + + After one day + Després d'un dia + + + After one week + Després d'una setmana + + + After two weeks + Després de dos setmanes + + + After one month + Després d'una mes + + + After one year + Després d'un any + + + Manually + Manualment + + + On application exit + En sortir del programa + + + Downloads + Baixades + + + Ask for a destination each time + Pregunta el destí cada vegada + + + Use this destination: + Usa aquesta destí: + + + Appearance + Aparença + + + Standard font: + Tipus de lletra estàndard: + + + Select... + Selecciona... + + + Fixed-width font: + Tipus d'amplada fixa: + + + Preferred languages for viewing webpages in: + Idiomes preferits per mostrar les pàgines web: + + + Privacy + Privadesa + + + Web Content + Contingut web + + + Block Popup Windows + Bloqueja les finestres emergents + + + Enable Plugins + Habilita connectors + + + Use ClickToFlash on flash plugins + Usa ClickToFlash en els connectors Flash + + + Enable Javascript + Habilita el Javascript + + + View Images + Mostra les imatges + + + Cookies + Galetes + + + Accept Cookies: + Accepta galetes: + + + Always + Sempre + + + Never + Mai + + + Only from sites you navigate to + Només dels llocs que visiteu + + + Exceptions... + Excepcions... + + + Keep Cookies Until: + Conserva les galetes fins que: + + + They expire + Expirin + + + I exit the application + Es tanqui el programa + + + At most 90 days + Com a molt 90 dies + + + Cookies... + Galetes... + + + Filter Tracking Cookies + Filtra les galetes de seguiment + + + Tabs + Pestanyes + + + Select tabs and windows as they are created + Selecciona les pestanyes i les finestres en crear-les + + + Confirm when closing multiple tabs or windows + Demana confirmació en tancar múltiples pestanyes o finestres + + + Show only one close button instead of one for each tab + Mostra només un botó de tancament enlloc d'un per cada pestanya + + + Quit the application when last tab is closed + Abandona el programa en tancar la darrera pestanya + + + Opening links + Opertura d'enllaços + + + Links that want to open in a new window: + Enllaços que volen obrir-se en una nova finestra: + + + In a new window + En una nova finestra + + + In a new selected tab in the current window + En una pestanya nova seleccionada de la finestra actual + + + In a new tab in the current window + En una nova pestanya de la finestra actual + + + In the current tab + En la pestanya actual + + + Open links from applications: + Obre enllaços des de programes: + + + Proxy + Proxy + + + Use proxy server + Usa servidor proxy + + + Type: + Tipus: + + + Socks5 + Socks5 + + + Http (Secure) + Http (segur) + + + Http (Transparent) + Http (transparent) + + + Host name: + Nom de la màquina: + + + Port: + Port: + + + User Name: + Nom d'usuari: + + + Password: + Contrasenya: + + + Advanced + Avançat + + + Style Sheet: + Full d'estil: + + + Enable network cache + Habilita la memòria cau de xarxa + + + Maximum Size: + Mida màxima: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + S'ha de reiniciar + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + La configuració de la memòria cau de xarxa ha canviat. S'ha de reiniciar el navegador per tenir-ho en compte. + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + S'està carregant... + + + &Edit + &Edita + + + &Find + &Cerca + + + &View + &Visualitza + + + &Wrap lines + &Ajusta les línies + + + Source of Page %1 + Codi font de la pàgina %1 + + + + TabBar + + Show Tab Bar + Mostra la barra de pestanyes + + + Hide Tab Bar + Oculta la barra de pestanyes + + + Duplicate Tab + Duplica la pestanya + + + &Close Tab + &Tanca la pestanya + + + Close &Other Tabs + Tanca les &altres pestanyes + + + Reload Tab + Recarrega la pestanya + + + Reload All Tabs + Recarrega totes les pestanyes + + + + TabWidget + + Untitled + Sense títol + + + Saved Tabs + Pestanyes desades + + + Do you really want to close this page? + Realment voleu tancar aquesta pàgina? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Heu modificat aquesta pàgina i les modificacions es perdran en tancar-la. +Realment voleu tancar aquesta pàgina? + + + Loading... + S'està carregant... + + + Loading %1% (%2 %3)... + S'està carregant %1% (%2 %3)... + + + Finished loading + Ha finalitzat la càrrega + + + Failed to load + Ha fallat en carregar + + + Show Next Tab + Mostra la pestanya següent + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + Mostra la pestanya anterior + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + Pestanyes tancades recentment + + + New &Tab + Nova pes&tanya + + + &Close Tab + &Tanca la pestanya + + + Bookmark All Tabs + Afegeix totes les pestanyes als punts + + + + ToolbarSearch + + Suggestions + Suggeriments + + + Add '%1' + Afegeix '%1' + + + Configure Search Engines... + Configura els motors de cerca... + + + Clear Recent Searches + Neteja les cerques recents + + + No Recent Searches + Cap cerca recent + + + Recent Searches + Cerques recents + + + + WebPage + + Resending POST request + S'està tornant a enviar la petició POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Per tal de mostrar el lloc, s'han d'enviar novament la sol licitud junt amb totes les dades, això pot donar lloc a comportaments inesperats del lloc web, p.ex. la mateixa acció podria ser realitzada una vegada més. Voleu continuar igualment? + + + Error loading page: %1 + Error en carregar la pàgina %1 + + + When connecting to: %1. + En connectar a: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Comproveu l'adreça per trobar errors com ara <b>ww</b>.arora-browser.org enlloc de <b>www</b>.arora-browser.org + + + If the address is correct, try checking the network connection. + Si l'adreça és correcta, intenteu-ho comprovant la connexió de la xarxa. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Si el vostre ordinador està protegit per un tallafocs o proxy, assegureu-vos que el navegador té permés accedir a la xarxa. + + + + WebView + + Open in New &Window + Obre en una &finestra nova + + + Open in New &Tab + Obre en una pes&tanya nova + + + Save Lin&k + Desa l'enlla&ç + + + &Bookmark This Link + &Apunta aquest enllaç + + + &Copy Link Location + &Copia la ubicació de l'enllaç + + + Open Image in New &Window + Obre la imatge en una &finestra nova + + + Open Image in New &Tab + Obre la imatge en una pes&tanya nova + + + &Save Image + De&sa la imatge + + + &Copy Image + &Copia la imatge + + + C&opy Image Location + C&opia la ubicació de la Imatge + + + Search with... + Cerca amb... + + + Add to the toolbar search + Afegeix a la barra de cerques + + + Method not supported + Mètode no acceptat + + + %1 method is not supported. + %1 mètode no està acceptat. + + + Search engine + Motor de cerca + + + Choose the desired search engine + Seleccioneu el motor de cerca + + + Engine name + Nom del motor + + + Type in a name for the engine + Introduïu un nom pel motor + + + Loading... + S'està carregant... + + + Block Image + + + + + WebViewSearch + + Not Found + No s'ha trobat + + + diff --git a/src/locale/calculate_completion.sh b/src/locale/calculate_completion.sh new file mode 100755 index 00000000..1f1a4e0b --- /dev/null +++ b/src/locale/calculate_completion.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# This script was written to get some data on how far the various translations are +# compared to each other +# +# This script is donated to the public domain +# +# Klaas van Gend, 2008 + +printf "\n translation file %%ready (unfinished/(total-obsolete))\n" +printf '=============================================================\n' +for I in `ls -1 *.ts`; +do + UNFINISHED=`grep 'type="unfinished"' $I | wc -l`; + OBSOLETE=`grep 'obsolete' $I | wc -l`; + MSGLINES=`grep '' $I | wc -l`; + let "REALLINES=$MSGLINES-$OBSOLETE"; + let "PERCENT=(100*$UNFINISHED)/$REALLINES"; + let "FINISHED=100-$PERCENT"; + printf "% 18s : % 4d%% %d/(%d-%d)\n" $I $FINISHED $UNFINISHED $MSGLINES $OBSOLETE ; +done +printf "\n" + diff --git a/src/locale/cs_CZ.ts b/src/locale/cs_CZ.ts index e416599d..6b81171c 100644 --- a/src/locale/cs_CZ.ts +++ b/src/locale/cs_CZ.ts @@ -1,147 +1,380 @@ - + + AboutDialog - About - O prohlížeči + O prohlížeči + + + About %1 + O %1 + + + Authors + Autoři + + + License + Licence + + + Lightweight WebKit-based web browser + Lehký webový prohlížeč založený na WebKitu + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Autorská práva vyhrazena © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + + Close + Zavřít + + + WebKit version: %1 + Verze WebKitu: %1 + + + + AcceptLanguage + + Languages + Jazyky + + + Languages: in order of preference: + Jazyky seřazené podle vašich preferencí: + + + Move &Up + Posunout &výše + + + Move &Down + Posunout &níže + + + &Remove + &Odstranit + + + Add... + Přidat... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Blokováno AdBlock pravidlem: %1 + + + + AdBlockDialog + + Add Custom Rule + Přidat vlastní pravidlo + + + Learn more about writing rules... + Více informací o psaní pravidel... + + + Update Subscription + Aktualizovat cizí filtry + + + Browse Subscriptions... + Prohlížet cizí filtry... + + + Remove Subscription + Odstranit cizí filtry + + + AdBlock Configuration + Konfigurace AdBlock + + + Enable AdBlock + Povolit AdBlock + + + Action + Akce + + + + AdBlockManager + + Custom Rules + Vlastní pravidla + + + + AdBlockModel + + Rule + Pravidlo + + + + AdBlockSchemeAccessHandler + + Subscribe? + Přidat cizí filtry? + + + Subscribe to this AdBlock subscription? +%1 + Přidat tyto cizí AdBlock filtry? +%1 AddBookmarkDialog - Add Bookmark Přidat záložku - Type a name for the bookmark, and choose where to keep it. - Napiš jméno pro záložku, a vyber, kam ji uchovat. + Napište jméno pro záložku a vyberte, kde má být uložena. + + + Url + Adresa + + + Title + Titulek + + + Add Folder + Přidat složku + + + + AutoFillDialog + + Form Passwords + Formulář hesel + + + Remove + Odstranit + + + Remove All + Odstranit vše + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Chcete uložit toto heslo?</b><br> Pro prohlížení uložených hesel a jejich odstranění otevřete kartu Automatické doplňování v dialogu nastavení. + + + Never for this site + Nikdy na této stránce + + + Not now + Nyní ne + + + + AutoFillModel + + WebSite + Webová stránka + + + User Name + Uživatelské jméno BookmarksDialog - Open Otevřít - Delete Smazat - New Folder Nová složka - Bookmarks Záložky - &Remove - &Smazat + &Odstranit - Add Folder Přidat složku - Open in New Tab - Otevřít v novém panelu + Otevřít v nové kartě + + + Edit Name + Upravit název + + + Edit Address + Upravit adresu BookmarksManager - Error when loading bookmarks on line %1, column %2: %3 - Chyba při načítání záložek na řádku %1, sloupci %2: %3 + Chyba při načítání záložek na řádku %1, v sloupci %2: %3 + + + Bookmarks Bar + Lišta záložek + + + Bookmarks Menu + Menu záložek - Toolbar Bookmarks - Nástrojová lista záložek + Nástrojová lišta záložek - Menu Menu - Open File Otevřít soubor - XBEL (*.xbel *.xml) - XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) - Imported %1 Importováno %1 - + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Chyba při načítání HTML záložek: %1 + + + Save File Uložit soubor - %1 Bookmarks.xbel %1 Bookmarks.xbel - Export error Chyba exportu - error saving bookmarks chyba při ukládání záložek - Remove Bookmark - Smazat záložku + Odstranit záložku - Insert Bookmark Vložit záložku - Name Change + Změna jména + + + Address Change + Změna adresy + + + Name Change + Undo bookmark title change Změna jména - Address Change + Undo bookmark url change Změna adresy + + XBEL bookmarks + XBEL záložky + + + HTML Netscape bookmarks + Záložky Netscape HTML + + + htmlToXBel tool required + je vyžadován nástroj htmlToXBel + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Nástroj htmlToXBel, který je dodáván s Arorou a je nutný k importu HTML záložek, není nainstalován nebo není dostupný v hledaných cestách. + + + Loading Bookmark + Načítání záložky + + + Error when loading HTML bookmarks: %1 + + Chyba při načítání HTML záložek: %1 + + + + + BookmarksMenu + + Open in Tabs + Otevřít v kartách + BookmarksModel - Title Titulek - Address Adresa @@ -149,616 +382,769 @@ BookmarksToolBar - Bookmark - Záložky + Záložky + + + Open + Otevřít + + + Open in New &Tab + Otevřít v &nové kartě + + + Remove + Odstranit + + + Add Bookmark... + Přidat záložku... + + + Add Folder... + Přidat složku... + + + Bookmarks + Záložky BrowserApplication - There are %1 windows and %2 tabs open Do you want to quit anyway? - Je otevřeno %1 oken a %2 panelů + Je otevřeno %1 oken a %2 karet Přesto ukončit? + + Restore failed + Obnovení selhalo + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Uložená relace nebude obnovena, protože Arora spadla při pokusu o její obnovení. + + + (Change: %1 %2) + (Revize: %1 %2) + + + Arora crashed while trying to restore this session. Should I try again? + Arora spadla při pokusu o obnovu této relace. Zkusit znovu? + BrowserMainWindow - &File &Soubor - &New Window &Nové okno - &Open File... Otevřít &soubor... - Open &Location... &Otevřít adresu... - &Save As... &Uložit jako... - &Import Bookmarks... &Importovat záložky... - &Export Bookmarks... &Exportovat záložky... - P&rint Preview... Ná&hled tisku... - &Print... &Tisk... - Private &Browsing... Soukro&mé prohlížení... - + Close Window + Zavřít okno + + &Quit U&končit - &Edit Úpr&avy - &Undo &Zpět - &Redo Zn&ovu - Cu&t &Vyjmout - &Copy &Kopírovat - &Paste V&ložit - &Find Na&jít - + About &%1 + About Browser + O &%1 + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Když je zapnuto soukromé prohlížení, některé akce narušující tvoje soukromí budou zakázány:<ul><li> Stránky nejsou přidávány do historie.</li><li> Položky jsou automaticky smazány z okna stahování.</li><li> Nové cookies nejsou uloženy, aktuální nebudou přístupné.</li><li> Ikony stránek nejsou ukládány, relace taky ne.</li><li> Hledání nejsou přidávány do vyjížděcího menu v políčku hledání.</li></ul>Dokud nezavřeš okno, můžeš vždy klikat Zpět a Vpřed pro vrácení na dříve otevřené stránky. + + + Ctrl+Y + Download Manager + Ctrl+Y + + &Find Next - Nají&t další + Nají&t další - &Find Previous - Najít &předchozí + Najít &předchozí - &Preferences - Před&volby + Před&volby - Ctrl+, Ctrl+, - &View &Zobrazit - Shift+Ctrl+B - Shift+Ctrl+B + Shift+Ctrl+B - Ctrl+| Ctrl+| - Ctrl+/ Ctrl+/ - &Stop Z&astavit - Reload Page - O&bnovit + O&bnovit - &Make Text Bigger - Z&většit písmo + Z&většit písmo - &Make Text Normal - &Normální velikost písma + &Normální velikost písma - &Make Text Smaller - Z&menšit písmo + Z&menšit písmo - Page S&ource &Zdrojový kód stránky - Ctrl+Alt+U Ctrl+Alt+U - &Full Screen &Celá obrazovka - Hi&story &Historie - Back Zpět - Forward Vpřed - Home Domů - Restore Last Session Obnovit poslední relaci - &Bookmarks Zál&ožky - Manage Bookmarks... - Spravovat záložky... + Spravovat záložky... - Add Bookmark... Přidat záložku... - + Add Folder... + Přidat složku... + + &Window &Okno - &Tools &Nástroje - Web &Search &Hledání na webu - Ctrl+K Web Search Ctrl+K - + Show &Network Monitor + Zobrazit &monitor sítě + + Enable Web &Inspector Povolit Web &Inspector - &Help Nápo&věda - About &Qt O &Qt - About &Arora - O &Arora + O &Arora - Navigation Navigace - Show Status Bar Zobrazit stavový řádek - Hide Status Bar Skrýt stavový řádek - Show Toolbar Zobrazit panel nástrojů - Hide Toolbar Skrýt panel nástrojů - Show Bookmarks bar - Zobrazit panel záložek + Zobrazit panel záložek - Hide Bookmarks bar - Skrýt panel záložek + Skrýt panel záložek - Arora - Arora + Arora - %1 - Arora Page title and Browser name %1 - Arora - About O prohlížeči - Version %1<p>This demo demonstrates Qt's webkit facilities in action, providing an example browser for you to experiment with.<p><p>QtWebKit is based on the Open Source WebKit Project developed at <a href="http://webkit.org/">http://webkit.org/</a>. Verze %1<p>Tato ukázka předvádí schopnosti WebKitu v Qt v akci, poskytnutím vzorového prohlížeče, abys s ním mohl(a) experimentovat.<p><p>QtWebKit je založen na open-source projektu WebKit vyvíjeného na <a href="http://webkit.org/">http://webkit.org/</a>. - Open Web Resource Otevřít webovou stránku - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) Webové stránky (*.html *.htm *.svg *.png *.gif *.svgz);;Všechny soubory (*.*) - Print Document Vytisknout dokument - Are you sure you want to turn on private browsing? - Opravdu chceš zapnout soukromé prohlížení? + Opravdu chcete zapnout soukromé prohlížení? - <b>%1</b><br><br>When private browsing in turned on, webpages are not added to the history, items are automatically removed from the Downloads window, new cookies are not stored, current cookies can't be accessed, site icons wont be stored, session wont be saved, and searches are not addded to the pop-up menu in the Google search box. Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. <b>%1</b><br><br>Když je zapnuto soukromé prohlížení, stránky nejsou přidávány do historie, soubory jsou automaticky smazány z okna stahování, nové cookies nejsou ukládány, aktuální cookies nejsou přístupné, ikony stránek nejsou ukládány, relace se neukádá a hledání nejsou přidávány do vysouvacího menu v políčku Google hledání. Dokud nezavřeš okno, můžeš vždy klikat Zpět a Vpřed pro vrácení na dříve otevřené stránky. - - Are you sure you want to close the window? There are %1 tab open - Opravdu chceš zavřít okno? Je tu otevřeno %1 panelů + Are you sure you want to close the window? There are %1 tabs open + Opravdu chcete zavřít okno? Je otevřeno %1 karet - Page Source of %1 - Zdrojový kód stránky %1 + Zdrojový kód stránky %1 - Web Inspector Web Inspector - The web inspector will only work correctly for pages that were loaded after enabling. Do you want to reload all pages? - Webový inspektor bude fungovat pouze pro stránky načtené po jeho povolení. Chceš znovu načíst všechny stránky? + Webový inspektor bude fungovat pouze pro stránky načtené po jeho povolení. +Chcete znovu načíst všechny stránky? - Stop loading the current page Zastaví načítání aktuální stránky - Reload the current page Znovu načte aktuální stránku - Downloads Stahování - Alt+Ctrl+L Download Manager - Alt+Ctrl+L + Alt+Ctrl+L - &Clear Private Data Smazat &soukromá data - Ctrl+Shift+Delete Clear Private Data - + - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. - <b>%1</b><br><br>Když je zapnuto soukromé prohlížení, některé akce narušující tvoje soukromí budou zakázány:<ul><li> Stránky nejsou přidávány do historie.</li><li> Položky jsou automaticky smazány z okna stahování.</li><li> Nové cookies nejsou uloženy, aktuální nebudou přístupné.</li><li> Ikony stránek nejsou ukládány, relace taky ne.</li><li> Hledání nejsou přidávány do vyjížděcího menu v políčku hledání.</li></ul>Dokud nezavřeš okno, můžeš vždy klikat Zpět a Vpřed pro vrácení na dříve otevřené stránky. + <b>%1</b><br><br>Když je zapnuto soukromé prohlížení, některé akce narušující tvoje soukromí budou zakázány:<ul><li> Stránky nejsou přidávány do historie.</li><li> Položky jsou automaticky smazány z okna stahování.</li><li> Nové cookies nejsou uloženy, aktuální nebudou přístupné.</li><li> Ikony stránek nejsou ukládány, relace taky ne.</li><li> Hledání nejsou přidávány do vyjížděcího menu v políčku hledání.</li></ul>Dokud nezavřeš okno, můžeš vždy klikat Zpět a Vpřed pro vrácení na dříve otevřené stránky. - - - ClearButton - - Clear - Vyčistit + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Když je zapnuto soukromé prohlížení, některé akce narušující tvoje soukromí budou zakázány:<ul><li> Stránky nejsou přidávány do historie.</li><li> Položky jsou automaticky smazány z okna stahování.</li><li> Nové cookies nejsou uloženy, aktuální nebudou přístupné.</li><li> Ikony stránek nejsou ukládány, relace taky ne.</li><li> Hledání nejsou přidávány do vyjížděcího menu v políčku hledání.</li></ul>Dokud nezavřeš okno, můžeš vždy klikat Zpět a Vpřed pro vrácení na dříve otevřené stránky. - - - ClearPrivateData - - Clear Private Data - + Show Bookmarks Bar + Zobrazit lištu záložek - - Clear the following items: - + Hide Bookmarks Bar + Skrýt lištu záložek - - &Browsing History - + Find &Next + Nají&t další - - &Download History - + Find P&revious + Najít &předchozí - - &Search History - + Prefe&rences + Před&volby - - &Cookies - + &Reload Page + O&bnovit stránku - - C&ache - + Make Text &Bigger + Z&většit text - - Website &Icons - + Make Text &Normal + &Normální velikost textu - - Clear &Private Data - + Make Text &Smaller + Z&menšit text - - &Cancel - + Find Nex&t + Nají&t další - - - CookieExceptionsModel - - Website - Adresa + Prefere&nces... + Před&volby... - - Status - Stav + Show Menu Bar + Zobrazit menu - - Allow - Povoleno + Zoom &In + Při&blížit - - Block - Blokovat + Zoom &Normal + &Normální velikost - - Allow For Session - Povolit pro relaci + Zoom &Out + Od&dálit - - - CookieModel - - Website - Adresa + Zoom &Text Only + Přibližovat pouze &text - - Name - Jméno + Show All Bookmarks... + Zobrazit všechny záložky... - - Path - Cesta + Switch application language + Přepnout jazyk aplikace - - Secure - Zabezpečené + Default + Výchozí - - Expires - Vyprší + Text Encoding + Kódování textu - - Contents - Obsah + Select &All + Vybr&at vše - - - CookiesDialog - - Cookies - Cookies + Alt+Ctrl+B + - - &Remove - &Smazat + Options... + Nastavení... - - Remove &All Cookies - Smazat &vše + Configure Search Engines... + Nastavit vyhledávače... - - - CookiesExceptionsDialog - - Cookie Exceptions - Výjimky pro cookies + &Ad Block... + &AdBlock... - - New Exception - Nová výjimka + When private browsing is turned on, some actions concerning your privacy will be disabled: + Při zapnutém soukromém prolížení budou některé akce týkající se vašeho soukromí zakázány: - - Domain: - Doména: + Webpages are not added to the history. + Stránky nejsou přidávány do historie. - - Block - Blokovat + Items are automatically removed from the Downloads window. + Soubory jsou automaticky odstraňovány z okna stahování. - - Allow For Session - Povolit pro relaci + New cookies are not stored, current cookies can't be accessed. + Nové cookies nejsou ukládány, ke stávajícím cookies nemůže být přistupováno. - - Allow - Povolit + Site icons won't be stored. + Ikony stránek nebudou ukládány. - - Exceptions - Výjimky + Session won't be saved. + Relace nebude uložena. - - &Remove + Searches are not added to the pop-up menu in the search box. + Vyhledávání nejsou přidávána do vyskakovacího menu vyhledávacího políčka. + + + No new network cache is written to disk. + Síťová mezipaměť není ukládána na disk. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Dokud nezavřete okno, můžete se pomocí tlačítek Zpět a Vpřed vrácet na vámi otevřené stránky. + + + Private Browsing + Soukromé prohlížení + + + + ClearButton + + Clear + Vyčistit + + + + ClearPrivateData + + Clear Private Data + Snazat soukromá data + + + Clear the following items: + Smazat tyto položky: + + + &Browsing History + &Historie prohlížení + + + &Download History + Historie &stahování + + + &Search History + Historie vyhledávání + + + &Cookies + &Cookies + + + C&ache + Vyrovnávací &paměť + + + Website &Icons + Ikony stránek + + + Clear &Private Data + Smazat soukromá data + + + &Cancel + Zrušit + + + C&ached Web Pages + Stránky v &mezipaměti + + + + ClickToFlash + + Load + Načíst + + + Load All + Načíst vše + + + Add %1 to Whitelist + Přidat %1 do povolených + + + Remove from Whitelist + Odebrat z povolených + + + Settings + Nastavení + + + Load Flash + Načíst flash + + + + ClickToFlashSettings + + Whitelist sites + Povolené weby + + + + CookieExceptionsModel + + Website + Webová stránka + + + Status + Stav + + + Allow + Povoleno + + + Block + Blokovat + + + Allow For Session + Povolit pro relaci + + + Rule + Pravidlo + + + + CookieModel + + Website + Webová stránka + + + Name + Jméno + + + Path + Cesta + + + Secure + Zabezpečené + + + Expires + Vyprší + + + Contents + Obsah + + + true + + + + false + + + + Session cookie + Relační cookie + + + + CookiesDialog + + Cookies + Cookies + + + &Remove &Smazat - - Remove &All + Remove &All Cookies Smazat &vše + + Add &Rule + Přidat &pravidlo + + + + CookiesExceptionsDialog + + Cookie Exceptions + Výjimky pro cookies + + + New Exception + Nová výjimka + + + Domain: + Doména: + + + Block + Blokovat + + + Allow For Session + Povolit pro relaci + + + Allow + Povolit + + + Exceptions + Výjimky + + + &Remove + &Odstranit + + + Remove &All + Odstranit &vše + DownloadDialog - Downloads Stahování - Clean up Vyčistit - 0 Items 0 položek @@ -766,278 +1152,527 @@ Do you want to reload all pages? DownloadItem - - Form - - - - Ico - + - Filename Název souboru - Try Again Zkusit znovu - Stop Zastavit - Open Otevřít - Save File Uložit soubor - Download canceled: %1 Stahování zrušeno: %1 - + %1 of %2 (%3/sec) - %4 + %1 z %2 (%3/sek) - %4 + + Error opening save file: %1 - Chyba při otevírání souboru pro uložení: %1 + Chyba při otevírání souboru pro uložení: %1 - Error saving: %1 Chyba při ukládání: %1 - Network Error: %1 Chyba sítě: %1 - seconds - sekund + sekund - minutes - minut + minut - - %4 %5 remaining - - %4 %5 zbývá + - %4 %5 zbývá - %1 of %2 (%3/sec) %4 - %1 z %2 (%3/s) %4 + %1 z %2 (%3/s) %4 - ? - + - %1 of %2 - Stopped %1 z %2 - Zastaveno - bytes - bajtů + bajtů + + + - %n minutes remaining + + - %n minuta zbývá + - %n minuty zbývají + - %n minut zbývá + + + + - %n seconds remaining + + - %n sekunda zbývá + - %n sekundy zbývají + - %n sekund zbývá + - - kB - + Error opening output file: %1 + Chyba při otevírání výstupního souboru: %1 - - MB - + Download directory (%1) couldn't be created. + Složka pro stahování (%1) nemůže být vytvořena. DownloadManager - + There are %1 downloads in progress +Do you want to quit anyway? + Právě probíhá %1 stahování +Přesto ukončit? + + + %n minutes remaining + + %n minuta zbývá + %n minuty zbývají + %n minut zbývá + + + + %n seconds remaining + + %n sekunda zbývá + %n sekundy zbývají + %n sekund zbývá + + + + bytes + bajtů + + + kB + kB + + + MB + MB + + 1 Download - 1 stahování + 1 stahování - %1 Downloads - %1 stahování + %1 stahování + + + %n Download(s) + + %n stahování + %n stahování + %n stahování + + + + GB + GB + + + + FileAccessReply + + No Error + Žádná chyba + + + Error opening: %1: No such file or directory + Chyba při otevírání %1: Soubor nebo složka neexistuje + + + Unable to read %1 + Chyba při čtení %1 + + + Contents of %1 + Obsah %1 + + + %1 KB + %1 KB HistoryDialog - Open Otevřít - Copy Kopírovat - Delete Smazat - - History - Historie + History + Historie + + + &Remove + &Odstranit + + + Remove &All + Odstranit &vše + + + + HistoryMenu + + Show All History + Zobrazit celou historii + + + Clear History + Vyčistit historii + + + Clear History... + Vyčistit historii... + + + Do you want to clear the history? + Chcete vyčistit historii? + + + + HistoryModel + + Title + Titulek + + + Address + Adresa + + + + HistoryTreeModel + + Earlier Today + Dříve dnes + + + %1 items + %1 položek + + + %n item(s) + + %n položka + %n položky + %n položek + + + + + JavaScriptAroraObject + + Welcome to Arora! + Vítejte v Aroře! + + + Arora Start + + + + Search! + Vyhledat! + + + Search results provided by + Výsledky vyhledávání poskytovány + + + About Arora + O Aroře + + + + LanguageManager + + Default + Výchozí + + + No translation files are installed. + Žádné překlady nejsou nainstalovány + + + Choose language + Vyberte jazyk + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Arora může používat jiný jazyk, než<br>je výchozí jazyk operačního systému.</p><p>Prosím vyberte, který jazyk má být použit</p> + + + No translation files are installed at %1. + Žádné překladové soubory nejsou nainstalovány v %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Zadejte uživatelské jméno a heslo pro "%1" na %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Připojit k proxy "%1" pomocí:</qt> + + + - SSL Errors + - Chyby SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Chyby SSL:<br/><br/>pro: <tt>%1</tt><ul><li>%2</li></ul> + +Chcete ignorovat tyto chyby?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certifikáty:<br/>%1<br/>Chcete přijmout všechny tyto certifikáty?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certifikáty:<br/>%1<br/>Chceš přijmout všechny tyto certifikáty?</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Chyby SSL: + +%1 + +%2 + +Chceš ignorovat tyto chyby? + + + Do you want to accept all these certificates? + Chceš přijmout všechny tyto certifikáty? + + + Issuer: %1 + Vydal: %1 + + + Not valid before: %1 + Neplatný před: %1 + + + Valid until: %1 + Platný do: %1 + + + Alternate Names: + Alternativní jména: + + + + NetworkMonitor + + Name + Název + + + Value + Hodnota + + + + NetworkMonitorDialog + + Network Monitor + Monitor sítě + + + Network Requests + Síťové požadavky + + + Request Headers + Hlavičky požadavku + + + Response Headers + Hlavičky odpovědi + + + &Remove + &Smazat + + + Remove &All Requests + Smazat &všechny požadavky + + + + OpenSearchDialog + + Open File + Otevřít soubor + + + OpenSearch + OpenSearch + + + Error + Chyba + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 není validní OpenSearch 1.1 popis, nebo už je na seznamu. - - &Remove - &Smazat + You must have at least one search engine in here. + Musíte mít alespoň jeden vyhledávač. - - Remove &All - Smazat &vše + OpenSearch Manager + Správce OpenSearch - - - HistoryMenu - - Show All History - Zobrazit všechnu historii + &Restore Defaults + &Obnovit původní - - Clear History - Vyčistit historii + &Delete + &Smazat - - - HistoryModel - - Title - Titulek + &Add + &Přidat - - Address - Adresa + &Close + &Zavřít - HistoryTreeModel + OpenSearchEngineModel - - Earlier Today - Dříve dnes + <strong>Description:</strong> %1 + <strong>Popis:</strong> %1 - - %1 items - %1 položek + <strong>Provides contextual suggestions</strong> + <strong>Poskytuje kontextové návrhy</strong> - - - NetworkAccessManager - - <qt>Enter username and password for "%1" at %2</qt> - <qt>Napiš uživatelské jméno a heslo pro "%1" na %2</qt> + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Seznam čárkou oddělených klíčových slov, která mají být vložena do vyhledávacího políčka následovány vyhledávanými slovy s tímto vyhledávačem - - <qt>Connect to proxy "%1" using:</qt> - <qt>Připojit k proxy "%1" použitím:</qt> + Name + Název - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - Chyby SSL: - -%1 - -%2 - -Chceš ignorovat tyto chyby? + Keywords + Klíčová slova + + + OpenSearchManager - - Do you want to accept all these certificates? - Chceš přijmout všechny tyto certifikáty? + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Chcete přidat následující vyhledávač do seznamu svých vyhledávačů?<br /><br />Jméno: %1<br />Vyhledává na: %2 PasswordDialog - Authentication Required - Vyžadované přihlášení + Vyžadováno přihlášení - DUMMY ICON - + - INTRO TEXT DUMMY - + - Username: Uživatelské jméno: - Password: Heslo: + + PlainTextEditSearch + + Not Found + Nenalezeno + + ProxyDialog - Proxy Authentication Přihlášení k proxy - - ICON - - - - Connect to proxy Připojit k proxy - Username: Uživatelské jméno: - Password: Heslo: @@ -1045,48 +1680,63 @@ Chceš ignorovat tyto chyby? QObject - The file is not an XBEL version 1.0 file. - Soubor není XBEL verze 1.0. + Soubor není souborem XBEL verze 1.0. - Unknown title Neznámý titulek + + The file is not an OpenSearch 1.1 file. + Toto není soubor OpenSearch 1.1. + - SearchBanner + RequestModel - - Form - + Redirect: %1 + Přesměrování: %1 - - TextLabel - + Method + Metoda - - < - + Address + Adresa + + + Response + Odpověď + + + Length + Délka + + + Content Type + Typ obsahu - - > - + Info + Info + + + SearchBanner - Done - Hotovo + Hotovo + + + Highlight All + Vyznačit vše SearchLineEdit - Search Hledat @@ -1094,431 +1744,708 @@ Chceš ignorovat tyto chyby? Settings - Settings - Nastavení + Nastavení - General - Hlavní + Obecné - Home: - Domov: + Domov: - Set to current page - Nastav na aktuální stránku + Nastavit na aktuální stránku - Remove history items: Odstranit položky historie: - After one day Po jednom dni - After one week Po jednom týdnu - After two weeks Po dvou týdnech - After one month Po měsíci - After one year Po roce - Manually Ručně - Save downloads to: Uložit stahování do: - Open links from applications: Otevřít odkazy z aplikací: - In a tab in the current window - V panelu v aktuálním okně + V panelu v aktuálním okně - In a new window V novém okně - Appearance Vzhled - Standard font: Standardní písmo: - Times 16 - Times 16 + Times 16 - Select... Vybrat... - Fixed-width font: Písmo s pevnou šířkou: - Courier 13 - Courier 13 + Courier 13 + + + Preferred languages for viewing webpages in: + Upřednostňované jazyky pro prohlížení stránek: - Privacy Soukromí - Web Content Obsah webu - + Block Popup Windows + Blokovat vyskakovací okna + + Enable Plugins - Povolit plug-iny + Povolit zásuvné moduly - Enable Javascript Povolit JavaScript - Cookies Cookies - Accept Cookies: Přijímat cookies: - Always Vždy - Never Nikdy - Only from sites you navigate to Pouze z navštívených stránek - Exceptions... Výjimky... - Keep until: - Uchovat dokud: + Uchovat dokud: - They expire Vyprší - I exit the application Ukončení aplikace - At most 90 days Maximálně 90 dní - Cookies... Cookies... - Proxy Proxy - Enable proxy - Povolit proxy + Povolit proxy - Type: Typ: - Socks5 Socks5 - Http - Http + Http - Host: - Server: + Server: - Port: Port: - User Name: Uživatelské jméno: - Password: Heslo: - Advanced Rozšířené - Style Sheet: CSS styl: - Downloads - Stahování + Stahování - Ask for a destination each time Vždy se ptát na umístění stahování - Use this destination: Použít toto umístění: + + On application exit + Při ukončení aplikace + + + Enable Images + Povolit obrázky + + + Tabs + Karty + + + Select tabs and windows as they are created + Přepínat na okna nebo karty, když jsou vytvořeny + + + Confirm when closing multiple tabs + Vyžadovat potvrzení při zavírání více panelů + + + On startup: + Po spuštění: + + + Show my home page + Zobrazit moji domovskou stránku + + + Show a blank page + Zobrazit prázdnou stránku + + + Restore windows and tabs from last time + Obnovit okna a karty z poslední relace + + + Preferences + Předvolby + + + Home Page: + Domovská stránka: + + + Use ClickToFlash on flash plugins + Používat ClickToFlash na zásuvných modulech flash + + + View Images + Zobrazovat obrázky + + + Keep Cookies Until: + Ponechat cookies dokud: + + + Filter Tracking Cookies + Filtrovat sledovací cookies + + + Confirm when closing multiple tabs or windows + Vyžadovat potvzrení při zavírání více karet nebo oken + + + Quit the application when last tab is closed + Ukončit aplikaci, když je zavřena poslední karta + + + Opening links + Otevírání odkazů + + + Links that want to open in a new window: + Odkazy, které chtějí otevřít v novém okně: + + + In a new selected tab in the current window + V nové kartě aktuálního okna, který bude označen + + + In a new tab in the current window + V nové kartě aktuálního okna + + + In the current tab + V aktuálním kartě + + + Use proxy server + Používat proxy server + + + Http (Secure) + HTTP (zabezpečené) + + + Http (Transparent) + HTTP (průhledné) + + + Host name: + Jméno hostitele: + + + Enable network cache + Povolit síťovou mezipaměť + + + Maximum Size: + Maximální velikost: + + + MB + MB + + + Show only one close button instead of one for each tab + Zobrazit pouze jedno zavírací tlačítko místo jednoho pro každou kartu + + + Use the default search engine as fallback when the URL given by the user is invalid + Použít výchozí vyhledávač jako nouzový, když je adresa zadaná uživatelem neplatná + + + Choose Directory... + Vybrat adresář... + + + A cookie session ends: + Relace cookies končí: + + + When I exit the application + Když ukončím aplikaci + + + 1 day + 1 den + + + 2 days + 2 dny + + + 3 days + 3 dny + + + 7 days + 7 dní + + + 30 days + 30 dní + + + AutoFill + Automatické doplňování + + + AutoFill web forms: + Automaticky doplňovat webové formuláře: + + + User names and passwords + Uživatelská jména a hesla + + + Edit... + Upravit... + + + Browse... + Prohlížet... + + + + SettingsDialog + + Restart required + Vyžadován restart aplikace + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Byla změněna nastavení síťové cache. Aby se změny projevily, prohlížeč musí být restartován. + + + Choose Directory + Vybrat adresář + + + Choose CSS File + Vybrat soubor CSS + + + + SourceViewer + + Loading... + Načítání... + + + &Edit + Úpr&avy + + + &Find + Na&jít + + + &View + &Zobrazit + + + &Wrap lines + Za&lamovat řádky + + + Source of Page + Zdrojový kód stránky + + + Source of Page %1 + Zdrojový kód stránky %1 + TabBar - New &Tab - &Nový panel + &Nový panel - Duplicate Tab - Duplikovat panel + Duplikovat kartu - &Close Tab - &Zavřít panel + &Zavřít kartu - Close &Other Tabs - Zavřít o&statní panely + Zavřít o&statní karty - Reload Tab - &Obnovit panel + Obnovit kartu - Reload All Tabs - O&bnovit všechny panely + Obnovit všechny karty + + + Show Tab Bar + Zobrazit lištu karet + + + Hide Tab Bar + Skrýt lištu karet TabWidget - New &Tab - &Nový panel + &Nová karta - &Close Tab - &Zavřít panel + &Zavřít kartu - Show Next Tab - Zobrazit další panel + Zobrazit další kartu + + + Saved Tabs + Uložené karty + + + Loading... + Načítání... + + + Loading %1% (%2 %3)... + Načítání %1% (%2 %3)... + + + Finished loading + Načítání dokončeno + + + Failed to load + Nepovedlo se načíst + + + Ctrl-] + Ctrl-] - Show Previous Tab - Zobrazit předchozí panel + Zobrazit předchozí kartu + + + Ctrl-[ + Ctrl-[ - Recently Closed Tabs - Posledně zavřené panely + Naposledy zavřené karty + + + Bookmark All Tabs + Přidat všechny karty do záložek - (Untitled) - (Bez titulku) + (Bez titulku) - Do you really want to close this page? - Opravdu chceš zavřít tuto stránku? + Opravdu chcete zavřít tuto stránku? - You have modified this page and when closing it you would lose the modification. Do you really want to close this page? - Stránka byla tebou měněna a když ji zavřeš, změny budou ztraceny. -Opravdu chceš zavřít tuto stránku? + Změnili jste tuto stránku, pokud ji zavřete, změny budou ztraceny. +Opravdu chcete zavřít tuto stránku? + + Untitled + Bez názvu + ToolbarSearch - - Google - + Suggestions + Návrhy + + + Add '%1' + Přidat '%1' + + + Configure Search Engines... + Nastavit vyhledávací enginy... - No Recent Searches - Žádná nedávná hledání + Žádná nedávná vyhledávání - Recent Searches - Nedávná hledání + Nedávná vyhledávání - Clear Recent Searches - Vyčístit nedávná hledání + Vyčistit nedávná vyhledávání WebPage - Error loading page: %1 Chyba při načítání stránky: %1 + + When connecting to: %1. + Při připojování k: %1. + + + Check the address for errors such as <b>ww</b>.trolltech.com instead of <b>www</b>.trolltech.com. + Zkontroluj adresu na chyby jako <b>ww</b>.trolltech.com místo <b>www</b>.trolltech.com. + + + If the address is correct, try to check the network connection. + Pokud je adresa správná, zkontroluj síťové připojení. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Pokud je váš počítač nebo vaše síť chráněna firewallem nebo proxy, ujistěte se, že je prohlížeči povolen přístup k síti. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Zkontrolujte adresu kvůli chybách jako <b>ww</b>.arora-browser.org namísto <b>www</b>.arora-browser.org + + + If the address is correct, try checking the network connection. + Pokud je adresa správná, zkontrolujte síťové připojení. + + + Resending POST request + Opětovné posílání POST požadavku + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Pro zobrazení stránky musí být požadavek spolu se všemi daty poslán znovu, což může způsobit neočekávané chování stránky, například ta samá akce může být vykonána znovu. Přesto pokračovat? + WebView - Open in New Tab Otevřít v novém panelu - Open in New &Window - Otevřít v novém okně + &Otevřít v novém okně - Open in New &Tab - Otevřít v &novém panelu + Otevřít v &nové kartě - Save Lin&k - Uložit o&dkaz + Uložit o&dkaz - &Bookmark This Link - &Vytvořit záložku pro tento odkaz + &Vytvořit záložku pro tento odkaz - &Copy Link Location - &Kopírovat adresu odkazu + &Kopírovat adresu odkazu - Open Image in New &Window - Otevřít obrázek v novém okně + Otevřít obrázek v novém okně - Open Image in New &Tab - Otevřít obrázek v novém panelu + Otevřít obrázek v nové kartě - &Save Image - Uložit obrázek + &Uložit obrázek - &Copy Image - Kopírovat o&brázek + Kopírovat o&brázek - C&opy Image Location - Kopírovat adresu ob&rázku + Kopírovat adresu ob&rázku + + + Search with... + Vyhledat pomocí... + + + Loading... + Načítání... + + + Add to the toolbar search + Přidat do políčka vyhledávání + + + Method not supported + Metoda není podporována + + + %1 method is not supported. + Metoda %1 není podporována. + + + Search engine + Vyhledávač + + + Choose the desired search engine + Vyber požadovaný vyhledávač + + + Engine name + Název vyhledávače + + + Type in a name for the engine + Napište jméno pro vyhledávač + + + Block Image + Blokovat obrázek WebViewSearch - Not Found - Neexistuje + Nenalezeno diff --git a/src/locale/da_DK.ts b/src/locale/da_DK.ts new file mode 100644 index 00000000..4082c3c8 --- /dev/null +++ b/src/locale/da_DK.ts @@ -0,0 +1,2317 @@ + + + + + AboutDialog + + Lightweight WebKit-based web browser + Letvægts WebKit-baseret internetbrowser + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Ophavsret © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + About %1 + + + + Authors + Ophavsmænd + + + License + Licens + + + Close + Luk + + + About + Om + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + + + + Languages: in order of preference: + + + + Move &Up + + + + Move &Down + + + + &Remove + &Fjern + + + Add... + + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Tilføj bogmærke + + + Type a name for the bookmark, and choose where to keep it. + Skriv et navn for bogmærket og vælg et sted at gemme det. + + + Url + + + + Title + Titel + + + Add Folder + Tilføj mappe + + + + AutoFillDialog + + Form Passwords + + + + Remove + + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Bookmarks + Bogmærker + + + &Remove + &Fjern + + + Add Folder + Tilføj mappe + + + Open + Åbn + + + Open in New Tab + Åbn i nyt faneblad + + + Delete + Slet + + + New Folder + Ny mappe + + + Edit Name + + + + Edit Address + + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Fejl under indlæsning af bogmærker på linje %1, kolonne %2: +%3 + + + Bookmarks Bar + + + + Bookmarks Menu + + + + Toolbar Bookmarks + Værktøjslinjebogmærker + + + Menu + Menu + + + Open File + Åbn fil + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + %1 er importeret + + + Save File + Gem fil + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Eksporteringsfejl + + + error saving bookmarks + fejl under lagring af bogmærker + + + Remove Bookmark + Fjern bogmærke + + + Insert Bookmark + Indsæt bogmærke + + + Name Change + Ændre navn + + + Address Change + Ændre adresse + + + Name Change + Undo bookmark title change + Ændre navn + + + Address Change + Undo bookmark url change + Ændre adresse + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + + + + + BookmarksModel + + Title + Titel + + + Address + Adresse + + + + BookmarksToolBar + + Bookmark + Bogmærke + + + Open + Åbn + + + Open in New &Tab + Åbn i nyt &faneblad + + + Remove + + + + Add Bookmark... + Tilføj bogmærke... + + + Add Folder... + + + + Bookmarks + Bogmærker + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Der er %1 vinduer og %2 faneblade åbne +Ønsker du alligevel at afslutte? + + + Restore failed + + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Fil + + + &New Window + &Nyt vindue + + + &Open File... + &Åbn fil... + + + Open &Location... + Åbn &adresse... + + + &Save As... + Ge&m Som... + + + &Import Bookmarks... + &Importér bogmærker... + + + &Export Bookmarks... + &Exportér bogmærker... + + + P&rint Preview... + &Vis udskrift... + + + &Print... + &Udskriv... + + + Private &Browsing... + Privat &browsing... + + + Close Window + + + + &Quit + &Afslut + + + &Edit + &Redigér + + + &Undo + &Fortryd + + + &Redo + &Omgør + + + Cu&t + Kli&p + + + &Copy + &Kopiér + + + &Paste + &Indsæt + + + &Find + &Find + + + Show All Bookmarks... + + + + About &%1 + About Browser + + + + Ctrl+Y + Download Manager + + + + &Find Next + &Find næste + + + &Find Previous + &Find forrige + + + &Preferences + &Indstillinger + + + Ctrl+, + Ctrl+, + + + &View + &Vis + + + Ctrl+| + Crtl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Crtl+/ + + + &Stop + &Stop + + + Reload Page + Genindlæs side + + + &Make Text Bigger + &Gør tekst større + + + &Make Text Normal + &Gør tekst normal + + + &Make Text Smaller + &Gør tekst mindre + + + Find Nex&t + + + + Show Menu Bar + + + + Zoom &In + + + + Zoom &Normal + + + + Zoom &Out + + + + Zoom &Text Only + + + + Page S&ource + Sidens &kilde + + + Ctrl+Alt+U + Crtl+Alt+U + + + &Full Screen + &Fuldskærm + + + Hi&story + Hi&storik + + + Back + Tilbage + + + Forward + Frem + + + Home + Hjem + + + Restore Last Session + Genindlæs sidste session + + + &Bookmarks + &Bogmærker + + + Manage Bookmarks... + Håndtér bogmærker... + + + Add Bookmark... + Tilføj bogmærke... + + + Add Folder... + + + + &Window + &Vindue + + + &Tools + &Værktøjer + + + Web &Search + Net&søgning + + + Ctrl+K + Web Search + Crtl+K + + + &Clear Private Data + &Ryd private informationer + + + Ctrl+Shift+Delete + Clear Private Data + Crtl+Shift+Delete + + + Enable Web &Inspector + Aktivér Web&inspektør + + + &Help + &Hjælp + + + Switch application language + + + + About &Qt + Om &Qt + + + About &Arora + Om &Arora + + + Navigation + Navigation + + + Show Status Bar + Vis statuslinje + + + Hide Status Bar + Skjul statuslinje + + + Show Toolbar + Vis værktøjslinje + + + Hide Toolbar + Skjul værktøjslinje + + + Show Bookmarks bar + Vis bogmærkelinje + + + Hide Bookmarks bar + Skjul bogmærkelinje + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Åbn netressource + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Netressourcer (*.html *.htm *.svg *.png *.gif *.svgz);; Alle filer (*.*) + + + Print Document + Udskriv dokument + + + Are you sure you want to turn on private browsing? + Er du sikker på du vil slå privat browsing til? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Når privat browsing er slået til, vil nogle handlinger vedrørende dine hemmeligheder blive slået fra:<ul><li>Sider bliver ikke tilføjet til historikken.</li><li> Filer bliver automatisk fjernet fra "Downloads"-vinduet.</li><li> Nye cookies bliver ikke gemt og eksisterende cookies kan ikke tilgås.</li><li> Sideikoner bliver ikke gemt, og sessioner vil ikke blive gemt.</li><li> Søgetermer bliver ikke tilføjet pop-op-menuen i søgefeltet.</li></ul>Indtil du lukker vinduet, kan du stadig klikke på frem- og tilbage-knapperne for at komme tilbage til åbne netsider. + + + Are you sure you want to close the window? There are %1 tab open + Er du sikker på du vil lukke vinduet? Der er %1 faneblade åbne + + + Page Source of %1 + Kilde til %1 + + + Web Inspector + Webinspektør + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Webinspektøren vil kun virke korrekt for sider der er indlæst efter webinspektøren er aktiveret +Vil du genindlæse alle sider? + + + Stop loading the current page + Stop indlæsning af den aktuelle side + + + Reload the current page + Genindlæs den aktuelle side + + + Downloads + Downloads + + + Alt+Ctrl+L + Download Manager + Alt+Crtl+L + + + Find P&revious + + + + &Reload Page + + + + Show Bookmarks Bar + + + + Hide Bookmarks Bar + + + + Are you sure you want to close the window? There are %1 tabs open + + + + Default + + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Ryd + + + + ClearPrivateData + + Clear Private Data + Ryd private data + + + Clear the following items: + Ryd følgende emner: + + + &Browsing History + &Browserhistorik + + + &Download History + &Downloadhistorik + + + &Search History + &Søgehistorik + + + &Cookies + &Cookies + + + C&ached Web Pages + + + + C&ache + C&ache + + + Website &Icons + Side&Ikoner + + + Clear &Private Data + Ryd &private data + + + &Cancel + &Annullér + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + Opsætning + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + Hjemmeside + + + Status + Status + + + Rule + + + + Allow + Tillad + + + Block + Blokér + + + Allow For Session + Tillad for session + + + + CookieModel + + Website + Hjemmeside + + + Name + Navn + + + Path + Sti + + + Secure + Sikker + + + Expires + Udløber + + + Contents + Indhold + + + true + + + + false + + + + Session cookie + + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Fjern + + + Remove &All Cookies + Fjern &alle cookies + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + cookie-undtagelser + + + New Exception + Ny undtagelse + + + Domain: + Domæne: + + + Block + Blokér + + + Allow For Session + Tillad for session + + + Allow + Tillad + + + Exceptions + Undtagelser + + + &Remove + &Fjern + + + Remove &All + Fjern &alle + + + + DownloadDialog + + Downloads + Downloads + + + Clean up + Ryd op + + + 0 Items + 0 elementer + + + + DownloadItem + + Form + Formular + + + Ico + Ikon + + + Filename + Filnavn + + + Try Again + Prøv Igen + + + Stop + Stop + + + Open + Åbn + + + Save File + Gem fil + + + Download canceled: %1 + Download annulleret: %1 + + + %1 of %2 (%3/sec) - %4 + + + + Error opening save file: %1 + Fejl under åbning af fil for skrivning: %1 + + + Error saving: %1 + Fejl ved skrivning: %1 + + + Network Error: %1 + Netværksfejl: %1 + + + seconds + Sekunder + + + minutes + Minutter + + + - %4 %5 remaining + - %4 %5 tilbage + + + %1 of %2 (%3/sec) %4 + %1 af %2 (%3/sek) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 af %2 - Stoppet + + + bytes + Bytes + + + kB + kB + + + MB + MB + + + Error opening output file: %1 + + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + + + + %n minutes remaining + + + + + + + %n seconds remaining + + + + + + + bytes + Bytes + + + kB + kB + + + MB + MB + + + 1 Download + 1 Download + + + %1 Downloads + %1 Downloads + + + %n Download(s) + + + + + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + History + Historik + + + &Remove + &Fjern + + + Remove &All + Fjern &alt + + + Open + Åbn + + + Copy + Kopiér + + + Delete + Slet + + + + HistoryMenu + + Show All History + Vis fuld historik + + + Clear History + Ryd historik + + + Clear History... + + + + Do you want to clear the history? + + + + + HistoryModel + + Title + Titel + + + Address + Adresse + + + + HistoryTreeModel + + Earlier Today + Tidligere i dag + + + %1 items + %1 elementer + + + %n item(s) + + + + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + Choose language + + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Indtast brugernavn og kodeord for "%1" på %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Forbind til proxy'en "%1" ved brug af:</qt> + + + - SSL Errors + + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + SSL-fejl: + +%1 + +%2 + +Vil du ignorere disse fejl? + + + Do you want to accept all these certificates? + Vil du acceptere alle disse certifikater? + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Navn + + + + NetworkMonitorDialog + + &Remove + &Fjern + + + + OpenSearchDialog + + Open File + Åbn fil + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Navn + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + Godkendelse påkrævet + + + DUMMY ICON + STANDARDIKON + + + INTRO TEXT DUMMY + INTRODUKTIONSSTANDARDTEKST + + + Username: + Brugernavn: + + + Password: + Kodeord: + + + + PlainTextEditSearch + + Not Found + Ikke fundet + + + + ProxyDialog + + Proxy Authentication + Proxy-godkendelse + + + ICON + IKON + + + Connect to proxy + Forbind til proxy + + + Username: + Brugernavn: + + + Password: + Kodeord: + + + + QObject + + The file is not an XBEL version 1.0 file. + Filen er ikke af typen XBEL version 1.0. + + + Unknown title + Ukendt titel + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Address + Adresse + + + + SearchBanner + + Form + Formular + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + Færdig + + + Highlight All + + + + + SearchLineEdit + + Search + Søg + + + + Settings + + Settings + Opsætning + + + General + Generelt + + + Home: + Hjem: + + + Home Page: + + + + Set to current page + Sæt til nuværende side + + + Remove history items: + Fjern elementer fra historik: + + + After one day + Efter en dag + + + After one week + Efter en uge + + + After two weeks + Efter to uger + + + After one month + Efter en måned + + + After one year + Efter et år + + + Manually + Manuelt + + + On application exit + Ved afslutning af program + + + Open links from applications: + Åbn links fra programmer: + + + In a tab in the current window + I et faneblad i nuværende vindue + + + In a new window + I et nyt vindue + + + Downloads + Downloads + + + Ask for a destination each time + Bed om destination hver gang + + + Use this destination: + Brug denne destination: + + + Appearance + Udseende + + + Standard font: + Standardskrifttype: + + + Times 16 + Times 16 + + + Select... + Vælg... + + + Fixed-width font: + Skrifttype med fast bredde: + + + Courier 13 + Courier 13 + + + Preferred languages for viewing webpages in: + + + + Privacy + Privatliv + + + Web Content + Netindhold + + + Block Popup Windows + + + + Enable Plugins + Aktivér plugins + + + Use ClickToFlash on flash plugins + + + + Enable Javascript + Aktivér JavaScript + + + View Images + + + + Keep Cookies Until: + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Opening links + + + + Links that want to open in a new window: + + + + In a new selected tab in the current window + + + + In a new tab in the current window + + + + In the current tab + + + + Use proxy server + + + + Http (Secure) + + + + Http (Transparent) + + + + Host name: + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Enable Images + Aktivér billeder + + + Cookies + Cookies + + + Accept Cookies: + Acceptér cookies: + + + Always + Altid + + + Never + Aldrig + + + Only from sites you navigate to + Kun fra sider du aktivt besøger + + + Exceptions... + Undtagelser... + + + Keep until: + Behold indtil: + + + They expire + De udløber + + + I exit the application + Jeg afslutter programmet + + + At most 90 days + Højst 90 dage + + + Cookies... + Cookies... + + + Tabs + Faneblade + + + Select tabs and windows as they are created + Vælg faneblade og vinduer når de oprettes + + + Confirm when closing multiple tabs + Bekræft ved afslutning af flere faneblade + + + Show only one close button instead of one for each tab + + + + Proxy + Proxy + + + Enable proxy + Aktivér proxy + + + Type: + Type: + + + Socks5 + Socks5 + + + Http + Http + + + Host: + Vært: + + + Port: + Port: + + + User Name: + Brugernavn: + + + Password: + Kodeord: + + + Advanced + Avanceret + + + Style Sheet: + Stilark: + + + On startup: + + + + Preferences + + + + Show my home page + + + + Show a blank page + + + + Restore windows and tabs from last time + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Indlæser... + + + &Edit + &Redigér + + + &Find + &Find + + + &View + &Vis + + + Source of Page %1 + + + + + TabBar + + Show Tab Bar + Vis fanebladslinje + + + Hide Tab Bar + Skjul fanebladslinje + + + New &Tab + Nyt &faneblad + + + Duplicate Tab + Duplikér faneblad + + + &Close Tab + &Luk faneblad + + + Close &Other Tabs + Luk &andre faneblade + + + Reload Tab + Genindlæs faneblad + + + Reload All Tabs + Genindlæs alle faneblade + + + + TabWidget + + New &Tab + Nyt &faneblad + + + &Close Tab + &Luk faneblad + + + Show Next Tab + Vis næste faneblad + + + Saved Tabs + + + + Loading... + Indlæser... + + + Loading %1% (%2 %3)... + + + + Finished loading + + + + Failed to load + + + + Ctrl-] + + + + Show Previous Tab + Vis forrige faneblad + + + Ctrl-[ + + + + Recently Closed Tabs + Nyligt lukkede faneblade + + + Bookmark All Tabs + + + + Untitled + + + + (Untitled) + (Uden titel) + + + Do you really want to close this page? + Vil du virkelig lukke denne side? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Du har ændret i denne side og ved at lukke den, vil du miste ændringerne +Er du sikker på du vil lukke siden? + + + + + ToolbarSearch + + Google + Google + + + Suggestions + + + + Add '%1' + + + + No Recent Searches + Ingen nylige søgninger + + + Recent Searches + Nylige søgninger + + + Clear Recent Searches + Ryd nylige søgninger + + + + WebPage + + Error loading page: %1 + Fejl ved indlæsning af side: %1 + + + When connecting to: %1. + + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + + + + If the address is correct, try checking the network connection. + + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Åbn i nyt &vindue + + + Open in New &Tab + Åbn i nyt &faneblad + + + Save Lin&k + Gem lin&k + + + &Bookmark This Link + Tilføj link til &bogmærker + + + &Copy Link Location + &Kopiér linkadresse + + + Open Image in New &Window + Åbn billede i nyt &vindue + + + Open Image in New &Tab + Åbn billede i nyt &faneblad + + + &Save Image + &Gem billede + + + &Copy Image + &Kopiér billede + + + C&opy Image Location + K&opiér billedadresse + + + Search with... + + + + Loading... + Indlæser... + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Ikke fundet + + + diff --git a/src/locale/de.ts b/src/locale/de.ts deleted file mode 100644 index a6dd61b4..00000000 --- a/src/locale/de.ts +++ /dev/null @@ -1,1604 +0,0 @@ - - - - - @default - - Error - Fehler - - - Arora is already running. Exiting. - Arora läuft bereits. - - - - AboutDialog - - - About - Über - - - - Authors - Autoren - - - - License - Lizenz - - - - Lightweight WebKit-based web browser - leichgewichtiger WebKit basierender Webbrowser - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> - - - - - <a href="http://arora-browser.org">http://arora-browser.org</a> - - - - - Close - Schließen - - - - AddBookmarkDialog - - - Add Bookmark - Lesezeichen hinzufügen - - - - Type a name for the bookmark, and choose where to keep it. - Geben Sie einen Namen und Speicherort für das Lesezeichen an. - - - - BookmarksDialog - - - Open - Öffnen - - - - Delete - Löschen - - - - New Folder - Neuer Ordner - - - - Bookmarks - Lesezeichen - - - - &Remove - &Entfernen - - - - Add Folder - Ordner hinzufügen - - - - Open in New Tab - In einem neuen tab öffnen - - - - BookmarksManager - - - Error when loading bookmarks on line %1, column %2: -%3 - - - - - Toolbar Bookmarks - Lesezeichenleiste - - - - Menu - Menü - - - - Open File - Datei öffnen - - - - XBEL (*.xbel *.xml) - XBEL (*.xbel *.xml) - - - - Imported %1 - Importiert %1 - - - - Save File - Datei speichern - - - - %1 Bookmarks.xbel - %1 Bookmarks.xbel - - - - Export error - Export Fehler - - - - error saving bookmarks - Fehler beim Speichern der Lesezeichen - - - - Remove Bookmark - Lesezeichen entfernen - - - - Insert Bookmark - Lesezeichen einfügen - - - - Name Change - Namensänderung - - - - Address Change - Adressänderung - - - - BookmarksModel - - - Title - Titel - - - - Address - Adresse - - - - BookmarksToolBar - - - Bookmark - Leszeichen - - - - BrowserApplication - - - There are %1 windows and %2 tabs open -Do you want to quit anyway? - %1 Fenster und %2 Tabs sind geöffnet -Arora wirklich beenden? - - - - BrowserMainWindow - - - &File - &Datei - - - - &New Window - &Neues Fenster - - - - &Open File... - &Datei öffnen... - - - - Open &Location... - &Adresse aufrufen... - - - - &Save As... - &Speichern unter... - - - - &Import Bookmarks... - &Lesezeichen importieren... - - - - &Export Bookmarks... - &Lesezeichen exportieren... - - - - P&rint Preview... - Druckvorschau - - - - &Print... - &Drucken... - - - - Private &Browsing... - Private &Browsing... - - - - &Quit - Beenden - - - - &Edit - &Bearbeiten - - - - &Undo - &Rückgängig - - - - &Redo - &Wiederholen - - - - Cu&t - &Ausschneiden - - - - &Copy - &Kopieren - - - - &Paste - &Einfügen - - - - &Find - &Suchen - - - - &Find Next - Nächstes &Ergebnis - - - - &Find Previous - Vorheriges &Ergebnis - - - - &Preferences - &Einstellungen - - - - Ctrl+, - Strg+, - - - - &View - &Ansicht - - - - Shift+Ctrl+B - Shift+Strg+B - - - - Ctrl+| - Strg+| - - - - Ctrl+/ - Strg+/ - - - - &Stop - &Stop - - - - Reload Page - Seite aktualisieren - - - - &Make Text Bigger - &Text vergrößern - - - - &Make Text Normal - Normale &Textgröße - - - - &Make Text Smaller - &Text verkleinern - - - - Page S&ource - &Quelltext - - - - Ctrl+Alt+U - Strg+Alt+U - - - - &Full Screen - &Vollbild - - - - Hi&story - &Verlauf - - - - Back - Zurück - - - - Forward - Vorwärts - - - - Home - Startseite - - - - Restore Last Session - Letzte Sitzung wiederherstellen - - - - &Bookmarks - &Lesezeichen - - - - Manage Bookmarks... - Lesezeichen verwalten... - - - - Add Bookmark... - Lesezeichen hinzufügen... - - - - &Window - &Fenster - - - - &Tools - &Werkzeuge - - - - Web &Search - Web &Suche - - - - Ctrl+K - Web Search - Strg+K - - - - Enable Web &Inspector - Web Inspector aktivieren - - - - &Help - &Hilfe - - - - About &Qt - Über &Qt - - - - About &Arora - Über &Arora - - - - Navigation - Navigation - - - - Show Status Bar - Statusleiste zeigen - - - - Hide Status Bar - Statusleiste verbergen - - - - Show Toolbar - Werkzeugleiste zeigen - - - - Hide Toolbar - Werkzeugleiste verbergen - - - - Show Bookmarks bar - Lesezeichenleiste zeigen - - - - Hide Bookmarks bar - Lesezeichenleiste verbergen - - - - Arora - Arora - - - - %1 - Arora - Page title and Browser name - %1 - Arora - - - - Open Web Resource - Webinhalte öffnen - - - - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - Webinhalte (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - - - - Print Document - Dokument drucken - - - - Are you sure you want to turn on private browsing? - Private Browsing wirklich aktivieren? - - - - Are you sure you want to close the window? There are %1 tab open - Soll das Fenster wirklich geschlossen werden? Es sind %1 Tabs geöffnet - - - - Page Source of %1 - Quelltext von %1 - - - - Web Inspector - Web Inspector - - - - The web inspector will only work correctly for pages that were loaded after enabling. -Do you want to reload all pages? - Der Web Inspector funktioniert nur auf neu geladenen Seiten. -Sollen alle Seiten neu geladen werden? - - - - Stop loading the current page - Ladevorgang abbrechen - - - - Reload the current page - Seite aktualisieren - - - - Downloads - Downloads - - - - Alt+Ctrl+L - Download Manager - Alt+Strg+L - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. - <b>%1</b><br><br>Wenn Private Browsing aktiviert ist, werden einige Funktionen deaktiviert die Ihre Privatsphäre betreffen:<ul><li> Aufgerufene Webseiten erscheinen nicht im Verlauf.</li><li> Einträge im Downloadfenster werden automatisch entfernt.</li><li> Neue Cookies werden nicht gespeichert, auf bestehende Cookies gibt es keinen Zugriff.</li><li> Seitensymbole und Sitzungen werden nicht gespeichert.</li><li> Suchen erscheinen nicht im Suchverlauf.</li></ul>Die Zurück- und Vorwärtsbuttons funktionieren noch auf offenen Webseiten bis das Fenster geschlossen wird. - - - - &Clear Private Data - Private Daten löschen... - - - - Ctrl+Shift+Delete - Clear Private Data - Ctrl+Shift+Delete - - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. - <b>%1</b><br><br>Wenn Private Browsing aktiviert ist, werden einige Funktionen deaktiviert die Ihre Privatsphäre betreffen:<ul><li> Aufgerufene Webseiten erscheinen nicht im Verlauf.</li><li> Einträge im Downloadfenster werden automatisch entfernt.</li><li> Neue Cookies werden nicht gespeichert, auf bestehende Cookies gibt es keinen Zugriff.</li><li> Seitensymbole und Sitzungen werden nicht gespeichert.</li><li> Suchen erscheinen nicht im Suchverlauf.</li></ul>Die Zurück- und Vorwärtsbuttons funktionieren noch auf offenen Webseiten bis das Fenster geschlossen wird. - - - - ClearButton - - - Clear - Leeren - - - - ClearPrivateData - - - Clear Private Data - Private Daten löschen... - - - - Clear the following items: - Folgende Einträge löschen: - - - - &Browsing History - &Seitenverlauf - - - - &Download History - &Downloadverlauf - - - - &Search History - &Suchverlauf - - - - &Cookies - &Cookies - - - - C&ache - C&ache - - - - Website &Icons - &Webseiten Symbole - - - - Clear &Private Data - &Private Daten löschen... - - - - &Cancel - &Abbrechen - - - - CookieExceptionsModel - - - Website - Website - - - - Status - Status - - - - Allow - Erlauben - - - - Block - Blocken - - - - Allow For Session - Für diese Sitzung erlauben - - - - CookieModel - - - Website - Website - - - - Name - Name - - - - Path - Pfad - - - - Secure - Sicher - - - - Expires - Läuft ab am - - - - Contents - Inhalte - - - - CookiesDialog - - - Cookies - Cookies - - - - &Remove - &Entfernen - - - - Remove &All Cookies - &Alle Cookies entfernen - - - - CookiesExceptionsDialog - - - Cookie Exceptions - Cookie Ausnahme - - - - New Exception - Neue Ausnahme - - - - Domain: - Domain: - - - - Block - Blocken - - - - Allow For Session - Für diese Sitzung erlauben - - - - Allow - Erlauben - - - - Exceptions - Ausnahmen - - - - &Remove - &Entfernen - - - - Remove &All - &Alle entfernen - - - - DownloadDialog - - - Downloads - Downloads - - - - Clean up - Leeren - - - - 0 Items - 0 Einträge - - - - DownloadItem - - - Save File - Datei speichern - - - - Download canceled: %1 - Downloads abgebrochen: %1 - - - - Error opening save file: %1 - Fehler beim öffnen der gespeicherten Datei: %1 - - - - Error saving: %1 - Fehler beim Speichern: %1 - - - - Network Error: %1 - Netzwerk Fehler: %1 - - - - seconds - Sekunden - - - - minutes - Minuten - - - - - %4 %5 remaining - - noch %4 %5 - - - - %1 of %2 (%3/sec) %4 - %1 von %2 (%3/Sek) %4 - - - - ? - ? - - - - %1 of %2 - Stopped - %1 von %2 - Angehalten - - - - bytes - bytes - - - - kB - kB - - - - MB - MB - - - - Form - Form - - - - Ico - Ico - - - - Filename - Dateiname - - - - Try Again - Erneut versuchen - - - - Stop - Stop - - - - Open - Öffnen - - - - DownloadManager - - - 1 Download - 1 Download - - - - %1 Downloads - %1 Downloads - - - - HistoryDialog - - - Open - Öffnen - - - - Copy - Kopieren - - - - Delete - Löschen - - - - History - Verlauf - - - - &Remove - &Entfernen - - - - Remove &All - &Alle entfernen - - - - HistoryMenu - - - Show All History - Kompletten Verlauf zeigen - - - - Clear History - Verlauf leeren - - - - HistoryModel - - - Title - Titel - - - - Address - Adresse - - - - HistoryTreeModel - - - Earlier Today - Heute - - - - %1 items - %1 Einträge - - - - NetworkAccessManager - - - <qt>Enter username and password for "%1" at %2</qt> - - - - - <qt>Connect to proxy "%1" using:</qt> - - - - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - SSL Errors: - -%1 - -%2 - -Möchten Sie diese Fehler ignorieren? - - - - Do you want to accept all these certificates? - Alle Zertifikate akzeptieren? - - - - PasswordDialog - - - Authentication Required - Authentifikation erforderlich - - - - DUMMY ICON - DUMMY ICON - - - - INTRO TEXT DUMMY - INTRO TEXT DUMMY - - - - Username: - Benutzername: - - - - Password: - Passwort: - - - - ProxyDialog - - - Proxy Authentication - Proxy Authentifikation - - - - ICON - ICON - - - - Connect to proxy - Zum Proxy verbinden - - - - Username: - Benutzername: - - - - Password: - Passwort: - - - - QObject - - - The file is not an XBEL version 1.0 file. - Die Datei ist keine XBEL Version 1.0 Datei. - - - - Unknown title - Unbekannter Titel - - - - SearchBanner - - - Form - Form - - - - TextLabel - TextLabel - - - - < - < - - - - > - > - - - - Done - Fertig - - - - SearchLineEdit - - - Search - Suche - - - - Settings - - - Settings - Einstellungen - - - - General - Allgemein - - - - Home: - Startseite: - - - - Set to current page - Aktuelle Seite - - - - Remove history items: - Verlauf Einträge löschen: - - - - After one day - Nach einem Tag - - - - After one week - Nach einer Woche - - - - After two weeks - Nach zwei Wochen - - - - After one month - Nach einem Monat - - - - After one year - Nach einem Jahr - - - - Manually - Manuell - - - Save downloads to: - Downloads speichern nach: - - - - Open links from applications: - Links von Programmen öffnen in: - - - - In a tab in the current window - in einem Tab im aktuellen Fenster - - - - In a new window - In einem neuen Fenster - - - - Appearance - Aussehen - - - - Fixed-width font: - Schrift fester Breite: - - - - Privacy - Privatsphäre - - - - Web Content - Webinhalt - - - - Enable Plugins - Plugins aktivieren - - - - Enable Javascript - Javascript aktivieren - - - - Cookies - Cookies - - - - Accept Cookies: - Cookies akzeptieren: - - - - Always - Immer - - - - Never - Nie - - - - Only from sites you navigate to - Nur von besuchten Seiten - - - - Exceptions... - Ausnahmen... - - - - Keep until: - Speichern bis: - - - - They expire - die Cookies ablaufen - - - - I exit the application - Ich beende das Programm - - - - At most 90 days - Maximal 90 Tage - - - - Cookies... - Cookies... - - - - Proxy - Proxy - - - - Enable proxy - Proxy aktivieren - - - - Type: - Typ: - - - - Socks5 - Socks5 - - - - Http - Http - - - - Host: - Host: - - - - Port: - Port: - - - - User Name: - Benutzername: - - - - Password: - Passwort: - - - - Advanced - Erweitert - - - - Style Sheet: - Style Sheet: - - - Size: - Größe: - - - Default font: - Standardschrift: - - - Sans serif - Sans serif - - - Serif - Serif - - - - Downloads - Downloads - - - - Ask for a destination each time - Jedes Mal nach Ziel fragen - - - - Use this destination: - Hier speichern: - - - - Standard font: - Standard Schriftart - - - - Times 16 - Times 16 - - - - Select... - Auswahl... - - - - Courier 13 - Courier 13 - - - - Tabs - Tabs - - - - Select tabs and windows as they are created - Neue Tabs und Fenster anzeigen - - - - Confirm when closing multiple tabs - Nachfragen wenn mehrere Tabs geschlossen werden - - - - Enable Images - Bilder anzeigen - - - - TabBar - - - New &Tab - Neuer Tab - - - - Duplicate Tab - Tab duplizieren - - - - &Close Tab - Tab &schließen - - - - Close &Other Tabs - &Andere Tabs schließen - - - - Reload Tab - Tab neu laden - - - - Reload All Tabs - Alle Tabs neu laden - - - - Shift+Ctrl+T - Shift+Ctrl+T - - - - Show Tab Bar - Tableiste zeigen - - - - Hide Tab Bar - Tableiste verbergen - - - - TabWidget - - - New &Tab - Neuer &Tab - - - - &Close Tab - &Tab schließen - - - - Show Next Tab - Nächster Tab - - - - Show Previous Tab - Vorheriger Tab - - - - Recently Closed Tabs - Zuletzt geschlossene Tabs - - - - (Untitled) - (Unbetitelt) - - - - Do you really want to close this page? - Diese Seite wirklich schließen? - - - - You have modified this page and when closing it you would lose the modification. -Do you really want to close this page? - - Die Seite wurde modifiziert. Wenn die Seite geschlossen wird gehen die Änderungen verloren. -Diese Seite wirklich schließen? - - - - ToolbarSearch - - - Google - Google - - - - No Recent Searches - Keine vorherigen Suchvorgänge - - - - Recent Searches - Letzte Suchvorgänge - - - - Clear Recent Searches - Letzte Suchvorgänge löschen - - - - WebPage - - - Error loading page: %1 - Fehler beim Laden von: %1 - - - - WebView - - - Open in New &Window - In einem neuen &Fenster öffnen - - - - Open in New &Tab - In einem neuen &Tab öffnen - - - - Save Lin&k - Lin&k speichern - - - - &Bookmark This Link - &Lesezeichen für diesen Link setzen - - - - &Copy Link Location - Linkadresse &kopieren - - - - Open Image in New &Window - Bild in einem neuen &Fenster öffnen - - - - Open Image in New &Tab - Bild in einem neuen &Tab öffnen - - - - &Save Image - Bild &speichern - - - - &Copy Image - Bild &kopieren - - - - C&opy Image Location - Bildadresse &kopieren - - - - WebViewSearch - - - Not Found - Nicht gefunden - - - diff --git a/src/locale/de_DE.ts b/src/locale/de_DE.ts new file mode 100644 index 00000000..7dceae0d --- /dev/null +++ b/src/locale/de_DE.ts @@ -0,0 +1,2599 @@ + + + + + + + Error + Fehler + + + Arora is already running. Exiting. + Arora läuft bereits. + + + + AboutDialog + + About + Über + + + About %1 + Über %1 + + + Authors + Autoren + + + License + Lizenz + + + Lightweight WebKit-based web browser + schlanker WebKit-basierter Webbrowser + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Schließen + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + WebKit Version: %1 + + + + AcceptLanguage + + Languages + Sprachen + + + Languages: in order of preference: + Sprachen: bevorzugte Reihenfolge: + + + Move &Up + Nach &Oben + + + Move &Down + Nach &Unten + + + &Remove + &Entfernen + + + Add... + Hinzufügen... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Blockiert durch AdBlockRegel: %1 + + + + AdBlockDialog + + Add Custom Rule + Benutzerdefinierte Regel hinzufügen + + + Learn more about writing rules... + Weitere Informationen zum Schreiben von Regeln... + + + Update Subscription + Abonnement aktualisieren + + + Browse Subscriptions... + Abonnements anzeigen... + + + Remove Subscription + Abonnement entfernen + + + AdBlock Configuration + AdBlock Konfiguration + + + Enable AdBlock + AdBlock aktivieren + + + Action + Aktion + + + + AdBlockManager + + Custom Rules + Benutzerdefinierte Regeln + + + + AdBlockModel + + Rule + Regel + + + + AdBlockSchemeAccessHandler + + Subscribe? + Abonnieren? + + + Subscribe to this AdBlock subscription? +%1 + Wollen sie dieses AdBlock Abonnement hinzufügen? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Lesezeichen hinzufügen + + + Type a name for the bookmark, and choose where to keep it. + Geben Sie einen Namen und Speicherort für das Lesezeichen an. + + + Url + Url + + + Title + Titel + + + Add Folder + Ordner hinzufügen + + + + AutoFillDialog + + Form Passwords + Formular Passwörter + + + Remove + Löschen + + + Remove All + Alle löschen + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Möchten Sie dieses Passwort speichern?</b><br> Um die gespeicherte Passwörter anzuzeigen oder zu löschen, nutzen Sie das Autovervollständigungs-Tab im Einstellungsmenü. + + + Never for this site + Nie für diese Seite + + + Not now + Nicht jetzt + + + + AutoFillModel + + WebSite + Webseite + + + User Name + Benutzername + + + + BookmarksDialog + + Open + Öffnen + + + Delete + Löschen + + + New Folder + Neuer Ordner + + + Bookmarks + Lesezeichen + + + &Remove + &Entfernen + + + Add Folder + Ordner hinzufügen + + + Open in New Tab + In einem neuen Tab öffnen + + + Edit Name + Titel editieren + + + Edit Address + Adresse editieren + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Fehler beim Laden der Lesezeichen in Zeile %1, Spalte %2: +%3 + + + Bookmarks Bar + Lesezeichenleiste + + + Bookmarks Menu + Lesezeichenmenü + + + Toolbar Bookmarks + Lesezeichenleiste + + + Menu + Menü + + + Open File + Datei öffnen + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importiert %1 + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Fehler beim Laden der html Lesezeichen: %1 + + + Save File + Datei speichern + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Exportfehler + + + error saving bookmarks + Fehler beim Speichern der Lesezeichen + + + Remove Bookmark + Lesezeichen entfernen + + + Insert Bookmark + Lesezeichen einfügen + + + Name Change + Namensänderung + + + Address Change + Adressänderung + + + Name Change + Undo bookmark title change + Namensänderung + + + Address Change + Undo bookmark url change + Adressänderung + + + XBEL bookmarks + XBEL Lesezeichen + + + HTML Netscape bookmarks + HTML Netscape Lesezeichen + + + htmlToXBel tool required + htmlToXbel wird benötigt + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + htmlToXBel - welches mit Arora vertrieben wird und nötig ist um HTML Lesezeichen zu importieren - ist nicht installiert oder nicht im Suchpfad verfügbar. + + + Loading Bookmark + Lade Lesezeichen + + + Error when loading HTML bookmarks: %1 + + Fehler beim Laden der HTML Lesezeichen: %1 + + + + + BookmarksMenu + + Open in Tabs + In Tabs öffnen + + + + BookmarksModel + + Title + Titel + + + Address + Adresse + + + + BookmarksToolBar + + Bookmark + Lesezeichen + + + Open + Öffnen + + + Open in New &Tab + In einem neuen &Tab öffnen + + + Remove + Entfernen + + + Add Bookmark... + Lesezeichen hinzufügen... + + + Add Folder... + Ordner hinzufügen... + + + Bookmarks + Lesezeichen + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + %1 Fenster und %2 Tabs sind geöffnet +Arora wirklich beenden? + + + Restore failed + Wiederherstellung fehlgeschlagen + + + The saved session will not being restored because last time it was restored Arora crashed. + Die gespeicherte Sitzung wird nicht wiederhergestellt weil bei der letzten Wiederherstellung Arora abgestürzt ist. + + + (Change: %1 %2) + (Änderung: %1 %2) + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Die gespeicherte Sitzung wird nicht wiederhergestellt, weil bei der letzten Wiederherstellung Arora abgestürzt ist. + + + Arora crashed while trying to restore this session. Should I try again? + Arora ist bei dem Versuch die Sitzung wiederherzustellen abgestürzt. Soll erneut versucht werden, die Sitzung wiederherzustellen? + + + + BrowserMainWindow + + &File + &Datei + + + &New Window + &Neues Fenster + + + &Open File... + &Datei öffnen... + + + Open &Location... + &Adresse aufrufen... + + + &Save As... + &Speichern unter... + + + &Import Bookmarks... + Lesezeichen &importieren... + + + &Export Bookmarks... + Lesezeichen &exportieren... + + + P&rint Preview... + Druck&vorschau... + + + &Print... + &Drucken... + + + Private &Browsing... + &Private Browsing... + + + Close Window + Fenster schließen + + + &Quit + &Beenden + + + &Edit + &Bearbeiten + + + &Undo + &Rückgängig + + + &Redo + &Wiederholen + + + Cu&t + &Ausschneiden + + + &Copy + &Kopieren + + + &Paste + &Einfügen + + + &Find + &Suchen + + + About &%1 + About Browser + Über&%1 + + + Ctrl+Y + Download Manager + Not sure if the Key is the same in german + Strg+Y + + + &Find Next + Nächstes &Ergebnis + + + &Find Previous + Vorheriges &Ergebnis + + + &Preferences + &Einstellungen + + + Ctrl+, + Strg+, + + + &View + &Ansicht + + + Shift+Ctrl+B + Shift+Strg+B + + + Ctrl+| + Strg+| + + + Ctrl+/ + Strg+/ + + + &Stop + &Stop + + + Reload Page + Seite aktualisieren + + + &Make Text Bigger + &Text vergrößern + + + &Make Text Normal + Normale &Textgröße + + + &Make Text Smaller + &Text verkleinern + + + Page S&ource + &Quelltext + + + Ctrl+Alt+U + Strg+Alt+U + + + &Full Screen + &Vollbild + + + Hi&story + &Verlauf + + + Back + Zurück + + + Forward + Vorwärts + + + Home + Startseite + + + Restore Last Session + Letzte Sitzung wiederherstellen + + + &Bookmarks + &Lesezeichen + + + Manage Bookmarks... + Lesezeichen verwalten... + + + Add Bookmark... + Lesezeichen hinzufügen... + + + Add Folder... + Ordner hinzufügen... + + + &Window + &Fenster + + + &Tools + &Werkzeuge + + + Web &Search + Web&suche + + + Ctrl+K + Web Search + Strg+K + + + Show &Network Monitor + &Netzwerk Monitor anzeigen + + + Enable Web &Inspector + Web-&Inspector aktivieren + + + &Help + &Hilfe + + + About &Qt + Über &Qt + + + About &Arora + Über &Arora + + + Navigation + Navigation + + + Show Status Bar + Statusleiste zeigen + + + Hide Status Bar + Statusleiste verbergen + + + Show Toolbar + Werkzeugleiste zeigen + + + Hide Toolbar + Werkzeugleiste verbergen + + + Show Bookmarks bar + Lesezeichenleiste zeigen + + + Hide Bookmarks bar + Lesezeichenleiste verbergen + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Webinhalte öffnen + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Webinhalte (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + + + Print Document + Dokument drucken + + + Are you sure you want to turn on private browsing? + Private Browsing wirklich aktivieren? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Wenn Private Browsing aktiviert ist, werden einige Funktionen deaktiviert die Ihre Privatsphäre betreffen:<ul><li> Aufgerufene Webseiten erscheinen nicht im Verlauf.</li><li> Einträge im Downloadfenster werden automatisch entfernt.</li><li> Neue Cookies werden nicht gespeichert, auf bestehende Cookies gibt es keinen Zugriff.</li><li> Seitensymbole und Sitzungen werden nicht gespeichert.</li><li> Suchen erscheinen nicht im Suchverlauf.</li></ul>Die Zurück- und Vorwärtsbuttons funktionieren noch auf offenen Webseiten bis das Fenster geschlossen wird. + + + Are you sure you want to close the window? There are %1 tabs open + Soll das Fenster wirklich geschlossen werden? Es sind %1 Tabs geöffnet + + + Page Source of %1 + Quelltext von %1 + + + Web Inspector + Web Inspector + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Der Web Inspector funktioniert nur auf neu geladenen Seiten. +Sollen alle Seiten neu geladen werden? + + + Stop loading the current page + Ladevorgang abbrechen + + + Reload the current page + Seite aktualisieren + + + Downloads + Downloads + + + Alt+Ctrl+L + Download Manager + Alt+Strg+L + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. + <b>%1</b><br><br>Wenn Private Browsing aktiviert ist, werden einige Funktionen deaktiviert die Ihre Privatsphäre betreffen:<ul><li> Aufgerufene Webseiten erscheinen nicht im Verlauf.</li><li> Einträge im Downloadfenster werden automatisch entfernt.</li><li> Neue Cookies werden nicht gespeichert, auf bestehende Cookies gibt es keinen Zugriff.</li><li> Seitensymbole und Sitzungen werden nicht gespeichert.</li><li> Suchen erscheinen nicht im Suchverlauf.</li></ul>Die Zurück- und Vorwärtsbuttons funktionieren noch auf offenen Webseiten bis das Fenster geschlossen wird. + + + &Clear Private Data + Private Daten &löschen + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Wenn Private Browsing aktiviert ist, werden einige Funktionen deaktiviert die Ihre Privatsphäre betreffen:<ul><li> Aufgerufene Webseiten erscheinen nicht im Verlauf.</li><li> Einträge im Downloadfenster werden automatisch entfernt.</li><li> Neue Cookies werden nicht gespeichert, auf bestehende Cookies gibt es keinen Zugriff.</li><li> Seitensymbole und Sitzungen werden nicht gespeichert.</li><li> Suchen erscheinen nicht im Suchverlauf.</li></ul>Die Zurück- und Vorwärtsbuttons funktionieren noch auf offenen Webseiten bis das Fenster geschlossen wird. + + + Find &Next + Nächstes &Ergebnis + + + Find P&revious + &Vorheriges Ergebnis + + + Prefe&rences + &Einstellungen + + + &Reload Page + Seite &aktualisieren + + + Make Text &Bigger + Text ver&größern + + + Make Text &Normal + &Normale Textgröße + + + Make Text &Smaller + Text ver&kleinern + + + Show Bookmarks Bar + Lesezeichenleiste zeigen + + + Hide Bookmarks Bar + Lesezeichenleiste verbergen + + + Find Nex&t + &Nächstes Ergebnis + + + Prefere&nces... + Einstellun&gen... + + + Show Menu Bar + Menüleiste zeigen + + + Zoom &In + Ver&größern + + + Zoom &Normal + &Normale Größe + + + Zoom &Out + Ver&kleinern + + + Zoom &Text Only + Nur &Textgröße ändern + + + Show All Bookmarks... + Alle Lezeichen anzeigen... + + + Switch application language + Sprache ändern + + + Default + Standard + + + Text Encoding + Text Kodierung + + + Select &All + &Alle auswählen + + + Alt+Ctrl+B + Alt+Strg+B + + + Options... + Optionen... + + + Configure Search Engines... + Suchmaschinen verwalten... + + + &Ad Block... + &AdBlock... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Sobald privates Surfen aktiviert ist, sind einige Aktionen die ihre Privatsphäre betreffen deaktiviert: + + + Webpages are not added to the history. + Webseiten werden nicht zum Verlauf hinzugefügt. + + + Items are automatically removed from the Downloads window. + Objekte werden automatisch aus dem Download Fenster entfernt. + + + New cookies are not stored, current cookies can't be accessed. + Neue Cookies werden nicht gespeichert, auf aktuelle Cookies kann nicht zugegriffen werden. + + + Site icons won't be stored. + Website Symbole werden nicht gespeichert. + + + Session won't be saved. + Die Sitzung wird nicht gespeichert. + + + Searches are not added to the pop-up menu in the search box. + Suchen werden nicht in den Suchverlauf aufgenommen. + + + No new network cache is written to disk. + Kein neuer Netzwerk-Cache wird auf der Platte erstellt. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Bis Sie das Fenster geschlossen haben, können Sie die Zurück und Vorwärts Schaltflächen wie gewohnt benutzen. + + + Private Browsing + Privates Surfen + + + + ClearButton + + Clear + Leeren + + + + ClearPrivateData + + Clear Private Data + Private Daten löschen + + + Clear the following items: + Folgende Einträge löschen: + + + &Browsing History + &Seitenverlauf + + + &Download History + &Downloadverlauf + + + &Search History + &Suchverlauf + + + &Cookies + &Cookies + + + C&ache + C&ache + + + Website &Icons + &Webseiten-Symbole + + + Clear &Private Data + &Private Daten löschen + + + &Cancel + &Abbrechen + + + C&ached Web Pages + &Zwischengespeicherte Webseiten + + + + ClickToFlash + + Load + Laden + + + Load All + Alle Laden + + + Add %1 to Whitelist + %1 zur Whitelist hinzufügen + + + Remove from Whitelist + Von der Whitelist entfernen + + + Settings + Einstellungen + + + Load Flash + Flash laden + + + + ClickToFlashSettings + + Whitelist sites + Webseiten auf der Whitelist + + + + CookieExceptionsModel + + Website + Website + + + Status + Status + + + Allow + Erlauben + + + Block + Blocken + + + Allow For Session + Für diese Sitzung erlauben + + + Rule + Regel + + + + CookieModel + + Website + Website + + + Name + Name + + + Path + Pfad + + + Secure + Sicher + + + Expires + Läuft ab am + + + Contents + Inhalte + + + true + wahr + + + false + falsch + + + Session cookie + Sitzungs-Cookie + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Entfernen + + + Remove &All Cookies + &Alle Cookies entfernen + + + Add &Rule + Regel hinzufügen + + + + CookiesExceptionsDialog + + Cookie Exceptions + Cookie Ausnahmen + + + New Exception + Neue Ausnahme + + + Domain: + Domain: + + + Block + Blocken + + + Allow For Session + Für diese Sitzung erlauben + + + Allow + Erlauben + + + Exceptions + Ausnahmen + + + &Remove + &Entfernen + + + Remove &All + &Alle entfernen + + + + Dialog + + Dialog + + + + RemoveAll + + + + Left: + + + + Foo Bar Baz Arora LineEdit Manual Test This is the end + + + + Right: + + + + Empty: + + + + Foo Bar Baz Arora LineEdit Manual Test + + + + Widget + + + + Site Icon + + + + RSS + + + + Bookmark + Lesezeichen + + + Position + + + + Left + + + + Right + + + + Add + + + + Remove + + + + Swap Visibility + + + + Add ToolButton + + + + + DownloadDialog + + Downloads + Downloads + + + Clean up + Leeren + + + 0 Items + 0 Einträge + + + &OK + &OK + + + + DownloadItem + + Save File + Datei speichern + + + Download canceled: %1 + Download abgebrochen: %1 + + + %1 of %2 (%3/sec) - %4 + %1 von %2 (%3/Sek) - %4 + + + Error opening save file: %1 + Fehler beim öffnen der gespeicherten Datei: %1 + + + Error saving: %1 + Fehler beim Speichern: %1 + + + Network Error: %1 + Netzwerk-Fehler: %1 + + + seconds + Sekunden + + + minutes + Minuten + + + - %4 %5 remaining + - noch %4 %5 + + + %1 of %2 (%3/sec) %4 + %1 von %2 (%3/Sek) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 von %2 - Angehalten + + + bytes + bytes + + + kB + kB + + + MB + MB + + + Form + Form + + + Ico + Ico + + + Filename + Dateiname + + + Try Again + Erneut versuchen + + + Stop + Stop + + + Open + Öffnen + + + - %n minutes remaining + + - noch %n Minute(n) + + + + + - %n seconds remaining + + - noch %n Sekunden + + + + + Error opening output file: %1 + Fehler beim Öffnen der Ausgabedatei: %1 + + + Download directory (%1) couldn't be created. + Download Verzeichnis (%1) konnte nicht erstellt werden. + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + Es sind noch %1 Download(s) aktiv. +Trotzdem beenden? + + + %n minutes remaining + + noch %n Minute verbleibend + noch %n Minuten verbleibend + + + + %n seconds remaining + + noch %n sekunde verbleibend + noch %n sekunden verbleibend + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + 1 Download + 1 Download + + + %1 Downloads + %1 Downloads + + + %n Download(s) + + %n Download + %n Downloads + + + + GB + GB + + + + FileAccessReply + + No Error + Kein Fehler + + + Error opening: %1: No such file or directory + Fehler beim Öffnen von %1: Datei oder Verzeichnis nicht gefunden + + + Unable to read %1 + Kann %1 nicht lesen + + + Contents of %1 + Inhalt von %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + Öffnen + + + Copy + Kopieren + + + Delete + Löschen + + + History + Verlauf + + + &Remove + &Entfernen + + + Remove &All + &Alle entfernen + + + + HistoryMenu + + Show All History + Kompletten Verlauf zeigen + + + Clear History + Verlauf leeren + + + Clear History... + Verlauf leeren... + + + Do you want to clear the history? + Soll der Verlauf geleert werden? + + + + HistoryModel + + Title + Titel + + + Address + Adresse + + + + HistoryTreeModel + + Earlier Today + Heute + + + %1 items + %1 Einträge + + + %n item(s) + + %n Einträg + %n Einträge + + + + + JavaScriptAroraObject + + Welcome to Arora! + Willkommen bei Arora! + + + Arora Start + Arora Start + + + Search! + Suche! + + + Search results provided by + Suchergebnisse werden zur Verfügung gestellt von + + + About Arora + Über Arora + + + + LanguageManager + + System locale (%1) %2 + System-Vorgabe (%1) %2 + + + Default + Standard + + + No translation files are installed. + Keine Sprachdateien installiert. + + + Choose language + Sprache wählen + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Sie können eine andere Sprache wählen,<br>als im Betriebssystem voreingestellt.</p><p>Bitte wählen Sie die Sprache,<br> die verwendet werden soll + + + No translation files are installed at %1. + In %1 befinden sich keine Übersetzungsdateien. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Benutzernamen und Password eingeben für "%1" bei "%2"</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Mit Proxy "%1" verbinden mit:</qt> + + + - SSL Errors + - SSL Fehler + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL-Fehler:<br/><br/>für:<tt>%1</tt><ul><li>%2</li></ul> + +Möchten Sie diese Fehler ignorieren?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificates:<br/>%1<br/>Möchten Sie all diese Zertifikate akzeptieren?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Zertifikate:<br/>%1<br/>Alle Zertifikate akzeptieren?</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + SSL-Fehler: + +%1 + +%2 + +Möchten Sie diese Fehler ignorieren? + + + Do you want to accept all these certificates? + Alle Zertifikate akzeptieren? + + + Issuer: %1 + Herausgeber: %1 + + + Not valid before: %1 + Nicht gültig vor: %1 + + + Valid until: %1 + Gültig bis: %1 + + + Alternate Names: + Alternative Namen: + + + + NetworkMonitor + + Name + Name + + + Value + Wert + + + + NetworkMonitorDialog + + Network Monitor + Netzwerk Monitor + + + Network Requests + Netzwerkanfragen + + + Request Headers + Anfrage Header + + + Response Headers + Antwort Header + + + &Remove + &Entfernen + + + Remove &All Requests + &Alle Entfernen + + + + OpenSearchDialog + + Open File + Datei öffnen + + + OpenSearch + OpenSearch + + + Error + Fehler + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 ist keine gültige OpenSearch 1.1 Beschreibung oder schon in Ihrer Liste. + + + You must have at least one search engine in here. + Mindestens eine Suchmaschiene muss hier eingetragen sein. + + + OpenSearch Manager + OpenSearch Verwaltung + + + &Restore Defaults + Auf Standard zu&rücksetzen + + + &Delete + &Löschen + + + &Add + &Hinzufügen + + + &Close + &Schließen + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Beschreibung:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Stellt Kontextvorschläge bereit</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Mit Kommas getrennte Liste von Schlüsselwörtern die In der Adressleiste von Suchbegriffen gefolgt eingegeben werden können um mit dieser Suchmaschine zu suchen + + + Name + Name + + + Keywords + Schlüsselwörter + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Möchten Sie die folgende Suchmaschiene zu Ihrer Liste hinzufügen?<br /><br />Name: %1<br />Sucht mit: %2 + + + + PasswordDialog + + Authentication Required + Authentifikation erforderlich + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Benutzername: + + + Password: + Passwort: + + + + PlainTextEditSearch + + Not Found + Nicht gefunden + + + + ProxyDialog + + Proxy Authentication + Proxy Authentifikation + + + ICON + ICON + + + Connect to proxy + Zum Proxy verbinden + + + Username: + Benutzername: + + + Password: + Passwort: + + + + QObject + + The file is not an XBEL version 1.0 file. + Die Datei ist keine XBEL Version 1.0 Datei. + + + Unknown title + Unbekannter Titel + + + The file is not an OpenSearch 1.1 file. + Diese Datei ist keine OpenSearch 1.1 Datei. + + + + RequestModel + + Redirect: %1 + Umleitung: %1 + + + Method + Methode + + + Address + Adresse + + + Response + Antwort + + + Length + Länge + + + Content Type + Format + + + Info + Information + + + + SearchBanner + + Form + Form + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + Fertig + + + Highlight All + Alle hervorheben + + + + SearchLineEdit + + Search + Suche + + + + Settings + + Settings + Einstellungen + + + General + Allgemein + + + Home: + Startseite: + + + Set to current page + Aktuelle Seite + + + Remove history items: + Verlauf Einträge löschen: + + + After one day + Nach einem Tag + + + After one week + Nach einer Woche + + + After two weeks + Nach zwei Wochen + + + After one month + Nach einem Monat + + + After one year + Nach einem Jahr + + + Manually + Manuell + + + Save downloads to: + Downloads speichern nach: + + + Open links from applications: + Links von Programmen öffnen in: + + + In a tab in the current window + einem Tab im aktuellen Fenster + + + In a new window + einem neuen Fenster + + + Appearance + Aussehen + + + Fixed-width font: + Schrift fester Breite: + + + Preferred languages for viewing webpages in: + Sprachen: bevorzugte Reihenfolge für Webseiten: + + + Privacy + Privatsphäre + + + Web Content + Webinhalt + + + Block Popup Windows + Popup Fenster blockieren + + + Enable Plugins + Plugins aktivieren + + + Use ClickToFlash on flash plugins + KlickToFlash benutzen + + + Enable Javascript + Javascript aktivieren + + + Cookies + Cookies + + + Accept Cookies: + Cookies akzeptieren: + + + Always + Immer + + + Never + Nie + + + Only from sites you navigate to + Nur von besuchten Seiten + + + Exceptions... + Ausnahmen... + + + Keep until: + Speichern bis: + + + They expire + die Cookies ablaufen + + + I exit the application + das Programm beende + + + At most 90 days + maximal 90 Tage + + + Cookies... + Cookies... + + + Proxy + Proxy + + + Enable proxy + Proxy aktivieren + + + Type: + Typ: + + + Socks5 + Socks5 + + + Http + Http + + + Host: + Host: + + + Port: + Port: + + + User Name: + Benutzername: + + + Password: + Passwort: + + + Advanced + Erweitert + + + Style Sheet: + Style Sheet: + + + Size: + Größe: + + + Default font: + Standardschrift: + + + Sans serif + Sans serif + + + Serif + Serif + + + Downloads + Downloads + + + Ask for a destination each time + Jedes Mal nach Ziel fragen + + + Use this destination: + Hier speichern: + + + Standard font: + Standard-Schriftart: + + + Times 16 + Times 16 + + + Select... + Auswahl... + + + Courier 13 + Courier 13 + + + Tabs + Tabs + + + Select tabs and windows as they are created + Neue erzeugte Tabs und Fenster selektieren + + + Confirm when closing multiple tabs + Nachfragen, wenn mehrere Tabs geschlossen werden + + + Enable Images + Bilder anzeigen + + + On startup: + Beim Starten: + + + Show my home page + Meine Homepage zeigen + + + Show a blank page + Eine leere Seite zeigen + + + Restore windows and tabs from last time + Letzte Sitzung wiederherstellen + + + On application exit + Beim Beenden + + + Preferences + Einstellungen + + + Home Page: + Startseite: + + + View Images + Bilder anzeigen + + + Keep Cookies Until: + Cookies speichern bis: + + + Filter Tracking Cookies + Seitenfremde Cookies verbieten + + + Confirm when closing multiple tabs or windows + Das Schließen mehrerer Tabs oder Fenster bestätigen + + + Show only one close button instead of one for each tab + Nur einen Schließen Button anzeigen, statt einen für jeden Tab + + + Quit the application when last tab is closed + Anwendung beenden wenn letztes Tab geschlossen wurde + + + Opening links + Öffnen von LInks + + + Links that want to open in a new window: + Links die in einem neuen Fenster geöffnet werden sollen: + + + In a new selected tab in the current window + In einem neuen aktiven Tab im aktuellen Fenster + + + In a new tab in the current window + In einem neuen Tab im aktiven Fenster + + + In the current tab + Im aktuellen Tab + + + Use proxy server + Proxyserver verwenden + + + Http (Secure) + Http (Sicher) + + + Http (Transparent) + Http (Unsicher) + + + Host name: + Hostname: + + + Enable network cache + Netzwerk-Cache aktivieren + + + Maximum Size: + Maximale Größe: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Standardsuchmaschine benutzen falls die vom Nutzer angegebene URL ungültig ist + + + Choose Directory... + Verzeichnis auswählen... + + + A cookie session ends: + Gültigkeit einer Cookie Sitzung: + + + When I exit the application + Bis zum schließen des Browsers + + + 1 day + 1 Tag + + + 2 days + 2 Tage + + + 3 days + 3 Tage + + + 7 days + 7 Tage + + + 30 days + 30 Tage + + + AutoFill + Autovervollständigung + + + AutoFill web forms: + Autovervollständigungs Formulare: + + + User names and passwords + Benutzernamen und Passwörter + + + Edit... + Editieren... + + + Browse... + Anzeigen... + + + + SettingsDialog + + Restart required + Neustart nötig + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Die Netzwerk-Cache Konfiguration wurde geändert. Damit diese Änderung Effekt hat, muss der Browser neu gestartet werden. + + + Choose Directory + Verzeichnis auswählen + + + Choose CSS File + CSS Datei auswählen + + + + SourceViewer + + Loading... + Laden... + + + &Edit + &Bearbeiten + + + &Find + &Suchen + + + &View + &Ansicht + + + &Wrap lines + Zeilen &Umbrechen + + + Source of Page + Quelltext der Seite + + + Source of Page %1 + Quelltext der Seite %1 + + + + SuggestionsTestNetworkReply + + No Error + Kein Fehler + + + + TabBar + + New &Tab + Neuer &Tab + + + Duplicate Tab + Tab duplizieren + + + &Close Tab + Tab &schließen + + + Close &Other Tabs + &Andere Tabs schließen + + + Reload Tab + Tab neu laden + + + Reload All Tabs + Alle Tabs neu laden + + + Shift+Ctrl+T + Shift+Ctrl+T + + + Show Tab Bar + Tableiste zeigen + + + Hide Tab Bar + Tableiste verbergen + + + + TabWidget + + New &Tab + Neuer &Tab + + + &Close Tab + &Tab schließen + + + Show Next Tab + Nächster Tab + + + Saved Tabs + Gespeicherte Tabs + + + Loading... + Laden... + + + Loading %1% (%2 %3)... + Laden %1% (%2 %3)... + + + Finished loading + Laden abgeschlossen + + + Failed to load + Laden fehlgeschlagen + + + Ctrl-] + Not sure if the Key is the same in german + Strg+] + + + Show Previous Tab + Vorheriger Tab + + + Ctrl-[ + Not sure if the Key is the same in german + Strg+[ + + + Recently Closed Tabs + Zuletzt geschlossene Tabs + + + Bookmark All Tabs + Alle Tabs als Lezeichen hinzufügen + + + (Untitled) + (Unbetitelt) + + + Do you really want to close this page? + Diese Seite wirklich schließen? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Die Seite wurde modifiziert. Wenn die Seite geschlossen wird gehen die Änderungen verloren. +Diese Seite wirklich schließen? + + + Untitled + Namenlos + + + + ToolbarSearch + + Google + Google + + + Suggestions + Vorschläge + + + Add '%1' + '%1' hinzufügen + + + No Recent Searches + Keine vorherigen Suchvorgänge + + + Recent Searches + Letzte Suchvorgänge + + + Clear Recent Searches + Letzte Suchvorgänge löschen + + + + TreeSortFilterProxyModelDialog + + Dialog + + + + + WebPage + + Error loading page: %1 + Fehler beim Laden von: %1 + + + When connecting to: %1. + Beim Verbinden zu: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Überprüfen Sie die Adresse auf Fehler wie <b>ww</b>.arora-browser.org statt <b>www</b>.arora-browser.org + + + If the address is correct, try to check the network connection. + Falls die Adresse stimmt, versuchen Sie, die Netzwerkverbindung zu überprüfen. + + + If the address is correct, try checking the network connection. + Falls die Adresse stimmt, versuchen Sie, die Netzwerkverbindung zu überprüfen. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Wenn Ihr Computer oder Ihr Netzwerk durch eine Firewall oder einen Proxy geschützt ist, stellen Sie sicher, dass der Browser auf das Netzwerk zugreifen darf. + + + Resending POST request + Erneutes Senden einer POST Anfrage + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Um diese Seite anzeigen können, muss die Anfrage mit allen Daten erneut gesendet werden, was zu unerwartetem Verhalten der Seite führen kann, so könnte z.B. die selbe Aktion erneut ausgeführt werden. Möchten Sie trotzdem fortfahren? + + + + WebView + + Open in New &Window + In einem neuen &Fenster öffnen + + + Open in New &Tab + In einem neuen &Tab öffnen + + + Save Lin&k + Lin&k speichern + + + &Bookmark This Link + &Lesezeichen für diesen Link setzen + + + &Copy Link Location + Linkadresse &kopieren + + + Open Image in New &Window + Bild in einem neuen &Fenster öffnen + + + Open Image in New &Tab + Bild in einem neuen &Tab öffnen + + + &Save Image + Bild &speichern + + + &Copy Image + Bild &kopieren + + + C&opy Image Location + Bildadresse &kopieren + + + Search with... + Suchen mit... + + + Loading... + Laden... + + + Add to the toolbar search + Zur Suchleiste hinzufügen + + + Method not supported + Methode nicht unterstützt + + + %1 method is not supported. + %1 Methode wird nicht unterstützt. + + + Search engine + Suchmaschiene + + + Choose the desired search engine + Wählen Sie die gewünschte Suchmaschiene + + + Engine name + Name + + + Type in a name for the engine + Geben Sie einen Namen für die Suchmaschiene ein + + + Block Image + Bild unterdrücken + + + + WebViewSearch + + Not Found + Nicht gefunden + + + diff --git a/src/locale/el_GR.ts b/src/locale/el_GR.ts new file mode 100644 index 00000000..f3a06e7e --- /dev/null +++ b/src/locale/el_GR.ts @@ -0,0 +1,2348 @@ + + + + + AboutDialog + + About + Σχετικά με το + + + About %1 + + + + Authors + Συγγραφείς + + + License + Άδεια + + + Lightweight WebKit-based web browser + Ένας ελαφρύς περιηγητής ιστοσελίδων βασισμένος στο WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Κλείσιμο + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + Γλώσσες + + + Languages: in order of preference: + Γλώσσες: κατά σειρά προτίμησης: + + + Move &Up + Μετακίνηση &Πάνω + + + Move &Down + Μετακίνηση &Κάτω + + + &Remove + &Αφαίρεση + + + Add... + Προσθήκη... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Κανόνας + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Προσθήκη σελιδοδείκτη + + + Type a name for the bookmark, and choose where to keep it. + Δώστε ένα όνομα και επιλέξτε θέση. + + + Url + Url + + + Title + Τίτλος + + + Add Folder + Προσθήκη Φακέλου + + + + AutoFillDialog + + Form Passwords + + + + Remove + Αφαίρεση + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Άνοιγμα + + + Open in New Tab + Άνοιγμα σε Νέα Καρτέλα + + + Edit Name + Αλλαγή Ονόματος + + + Edit Address + Αλλαγή Διεύθυνσης + + + Delete + Διαγραφή + + + New Folder + Νέος Φάκελος + + + Bookmarks + Σελιδοδείκτες + + + &Remove + &Αφαίρεση + + + Add Folder + Προσθήκη Φακέλου + + + + BookmarksManager + + Bookmarks Bar + Μπάρα Σελιδοδεικτών + + + Bookmarks Menu + Μενού Σελιδοδεικτών + + + Error when loading bookmarks on line %1, column %2: +%3 + Σφάλμα φόρτωσης σελιδοδεικτών στη γραμμή %1, στήλη %2: +%3 + + + Toolbar Bookmarks + Εργαλειοθήκη Σελιδοδεικτών + + + Menu + Μενού + + + Open File + Άνοιγμα Αρχείου + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Εισήχθησαν %1 + + + Save File + Αποθήκευση Αρχείου + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Σφάλμα εισαγωγής + + + error saving bookmarks + σφάλμα κατά την αποθήκευση σελιδοδεικτών + + + Remove Bookmark + Αφαίρεση Σελιδοδείκτη + + + Insert Bookmark + Εισαγωγή Σελιδοδείκτη + + + Name Change + Αλλαγή Ονόματος + + + Address Change + Αλλαγή Διεύθυνσης + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Σφάλμα κατά τη φόρτωση html σελιδοδεικτών: %1 + + + + Name Change + Undo bookmark title change + Αλλαγή Ονόματος + + + Address Change + Undo bookmark url change + Αλλαγή Διεύθυνσης + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + Άνοιγμα σε Καρτέλες + + + + BookmarksModel + + Title + Τίτλος + + + Address + Διεύθυνση + + + + BookmarksToolBar + + Bookmark + Σελιδοδείκτης + + + Open + Άνοιγμα + + + Open in New &Tab + Άνοιγμα σε Νέα &Καρτέλα + + + Remove + Αφαίρεση + + + Add Bookmark... + Προσθήκη Σελιδοδείκτη... + + + Add Folder... + Προσθήκη Φακέλου... + + + Bookmarks + Σελιδοδείκτες + + + + BrowserApplication + + (Change: %1 %2) + (Αλλαγή: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Είναι ανοιχτά %1 παράθυρα και %2 καρτέλες +Είστε σίγουροι ότι θέλετε να κλείσετε; + + + Restore failed + Η επαναφορά απέτυχε + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Δεν μπορεί να γίνει επαναφορά της αποθηκευμένης συνεδρίας επειδή το Arora τερμάτισε απρόσμενα κατά τη διάρκεια της επαναφοράς. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Αρχείο + + + &New Window + &Νέο Παράθυρο + + + &Open File... + Άν&οιγμα Αρχείου... + + + Open &Location... + Άνοιγμα Τ&οποθεσίας... + + + &Save As... + Απο&θήκευση Ως... + + + &Import Bookmarks... + &Εισαγωγή Σελιδοδεικτών... + + + &Export Bookmarks... + Εξαγωγή &Σελιδοδεικτών... + + + P&rint Preview... + Π&ροεπισκόπηση Εκτύπωσης... + + + &Print... + Ε&κτύπωση... + + + Private &Browsing... + Ασφαλής &Περιήγηση... + + + &Quit + &Τερματισμός + + + &Edit + &Επεξεργασία + + + &Undo + &Αναίρεση + + + &Redo + Α&κύρωση Αναίρεσης + + + Cu&t + Αποκο&πή + + + &Copy + Α&ντιγραφή + + + &Paste + Επικόλλη&ση + + + &Find + Ανα&ζήτηση + + + Find Nex&t + Αναζήτηση Επό&μενου + + + Find P&revious + Αναζήτηση Προη&γούμενου + + + Prefere&nces... + Προ&τιμήσεις... + + + Ctrl+, + Ctrl+, + + + &View + &Προβολή + + + Show Menu Bar + Εμφάνιση Γραμμής Μενού + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Διακοπή + + + &Reload Page + &Επαναφόρτωση + + + Make Text &Bigger + &Μεγέθυνση Γραμματοσειράς + + + Make Text &Normal + Ε&παναφορά Γραμματοσειράς + + + Make Text &Smaller + &Σμίκρυνση Γραμματοσειράς + + + Page S&ource + &Κώδικας Σελίδας + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Πλήρης &Οθόνη + + + Hi&story + &Ιστορικό + + + Back + Πίσω + + + Forward + Μπροστά + + + Home + Αρχική Σελίδα + + + Restore Last Session + Επαναφορά Προηγούμενης Συνεδρίας + + + &Bookmarks + &Σελιδοδείκτες + + + Manage Bookmarks... + Οργάνωση Σελιδοδεικτών... + + + Add Bookmark... + Προσθήκη Σελιδοδείκτη... + + + &Window + Παρά&θυρο + + + &Tools + Ερ&γαλεία + + + Web &Search + Αναζήτηση στο &Διαδίκτυο + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Εκκαθάριση Προσωπικών Δεδομένων + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Show &Network Monitor + Παρακο&λούθηση Δικτύου + + + Enable Web &Inspector + Ενε&ργοποίηση του Επόπτη Ιστοσελίδων + + + &Help + &Βοήθεια + + + Switch application language + Αλλάγη γλώσσας της εφαρμογής + + + About &Qt + Σχετικά με το &Qt + + + About &Arora + Σχετικά με το &Arora + + + Navigation + Πλοήγηση + + + Show Status Bar + Εμφάνιση Γραμμής Κατάστασης + + + Hide Status Bar + Απόκρυψη Γραμμής Κατάστασης + + + Show Toolbar + Εμφάνιση Εργαλειοθήκης + + + Hide Toolbar + Απόκρυψη Εργαλειοθήκης + + + Show Bookmarks Bar + Εμφάνιση Γραμμής Σελιδοδεικτών + + + Hide Bookmarks Bar + Απόκρυψη Γραμμής Σελιδοδεικτών + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Άνοιγμα Αρχείου + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Αρχεία Web (*.html *.htm *.svg *.png *.gif *.svgz);;Όλα τα αρχεία (*.*) + + + Print Document + Εκτύπωση + + + Are you sure you want to turn on private browsing? + Είσαι βέβαιος ότι θέλεις να ενεργοποιήσεις την ασφαλή περιήγηση; + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Όταν η ασφαλής περιήγηση είναι ενεργή, μερικές λειτουργίες θα απενεργοποιηθούν:<ul><li> Οι ιστοσελίδες δεν προστίθενται στο ιστορικό.</li><li> Τα αντικείμενα που κατεβάζετε, αυτομάτως απομακρύνονται από το παράθυρο λήψης αρχείων.</li><li> Δεν αποθηκεύονται νέα cookies και τα ήδη υπάρχοντα είναι αδύνατον να προσπελαστούν.</li><li> Το εικονίδια των ιστοσελίδων δεν αποθηκεύονται, η συνεδρία δεν θα αποθηκευτεί.</li><li> Το ιστορικό των αναζητήσεων δεν αποθηκεύεται στο πλαίσιο αναζητήσεων.</li></ul>Εώς ότου να κλείσετε το παράθυρο, μπορείτε να κάνετε χρήση των κουμπιών Πίσω και Μπροστά, για να πάτε σε σελίδες που έχει ήδη ανοίξει. + + + Are you sure you want to close the window? There are %1 tabs open + Είστε σίγουροι ότι θέλετε να κλείσετε το παράθυρο; Υπάρχουν %1 ανοιχτές καρτέλες + + + Web Inspector + Επόπτης Ιστοσελίδων + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Ο επόπτης ιστοσελίδων θα δουλέψει σωστά μόνο για τις σελίδες μετά την ενεργοποίηση του. +Θέλετε να επαναφορτώσετε όλες τις σελίδες; + + + Stop loading the current page + Διακοπή φόρτωσης αυτής της σελίδας + + + Reload the current page + Επαναφόρτωση της τρέχουσας σελίδας + + + Downloads + Λήψεις Αρχείων + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + Close Window + Κλείσιμο Παραθύρου + + + Zoom &In + &Μεγέθυνση + + + Zoom &Normal + Ε&παναφορά Προβολής + + + Zoom &Out + &Σμίκρυνση + + + Zoom &Text Only + Μεγένθυνση &Μόνο Κειμένου + + + About &%1 + About Browser + Σχετικά με το &%1 + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Όταν η ασφαλής περιήγηση είναι ενεργή, μερικές λειτουργίες θα απενεργοποιηθούν:<ul><li> Οι ιστοσελίδες δεν προστίθενται στο ιστορικό.</li><li> Τα αντικείμενα που κατεβάζετε, αυτομάτως απομακρύνονται από το παράθυρο λήψης αρχείων.</li><li> Δεν αποθηκεύονται νέα cookies και τα ήδη υπάρχοντα είναι αδύνατον να προσπελαστούν.</li><li> Το εικονίδια των ιστοσελίδων δεν αποθηκεύονται, η συνεδρία δεν θα αποθηκευτεί.</li><li> Το ιστορικό των αναζητήσεων δεν αποθηκεύεται στο πλαίσιο αναζητήσεων.</li></ul>Εώς ότου να κλείσετε το παράθυρο, μπορείτε να κάνετε χρήση των κουμπιών Πίσω και Μπροστά, για να πάτε σε σελίδες που έχει ήδη ανοίξει. + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Show All Bookmarks... + Εμφάνιση Όλων των Σελιδοδεικτών... + + + Add Folder... + Προσθήκη Φακέλου... + + + Default + Προεπιλογή + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Καθαρισμός + + + + ClearPrivateData + + Clear Private Data + Εκκαθάριση Προσωπικών Δεδομένων + + + Clear the following items: + Εκκαθάριση των ακόλουθων αντικειμένων: + + + &Browsing History + &Ιστορικό Περιήγησης + + + &Download History + Ιστορικό &Λήψης Αρχείων + + + &Search History + Ιστορικό &Αναζήτησης + + + &Cookies + &Cookies + + + C&ached Web Pages + &Λανθάνουσα Μνήμη + + + Website &Icons + Εικονίδια &Ιστοσελίδων + + + Clear &Private Data + Εκκαθάριση &Προσωπικών Δεδομένων + + + &Cancel + &Ακύρωση + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + Ιστοσελίδα + + + Rule + Κανόνας + + + Allow + Να επιτρέπεται + + + Block + Φραγή + + + Allow For Session + Να επιτρέπεται μόνο για τη συνεδρία + + + + CookieModel + + Website + Ιστοσελίδα + + + Name + Όνομα + + + Path + Διαδρομή + + + Secure + Ασφάλεια + + + Expires + Λήξη + + + Contents + Περιεχόμενα + + + true + αληθές + + + false + ψευδές + + + Session cookie + + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Απομάκρυνση + + + Remove &All Cookies + Απομάκρυνση &Όλων των Cookies + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + Εξαιρέσεις Cookies + + + New Exception + Νέα Εξαίρεση + + + Domain: + Διεύθυνση: + + + Block + Φραγή + + + Allow For Session + Να επιτρέπεται μόνο για τη συνεδρία + + + Allow + Να επιτρέπεται + + + Exceptions + Εξαιρέσεις + + + &Remove + &Απομάκρυνση + + + Remove &All + Απομάκρυνση &Όλων + + + + DownloadDialog + + Downloads + Λήψεις Αρχείων + + + Clean up + Εκκαθάριση λίστας + + + 0 Items + 0 Αντικείμενα + + + &OK + &OK + + + + DownloadItem + + Form + Φόρμα + + + Ico + Ico + + + Filename + Όνομα Αρχείου + + + Try Again + Ξανά Προσπαθήστε + + + Stop + Διακοπή + + + Open + Άνοιγμα + + + Save File + Αποθήκευση Αρχείου + + + Download canceled: %1 + Η μεταφόρτωση ακυρώθηκε: %1 + + + Error opening output file: %1 + Σφάλμα κατά το άνοιγμα του αρχείου εξόδου: %1 + + + Error saving: %1 + Σφάλμα αποθήκευσης: %1 + + + Network Error: %1 + Σφάλμα Δικτύου: %1 + + + seconds + δευτερόλεπτα + + + - %n minutes remaining + + - απομένει %n λεπτό + - απομένουν %n λεπτά + + + + - %n seconds remaining + + - απομένει %n δευτερόλεπτο + - απομένουν %n δευτερόλεπτα + + + + %1 of %2 (%3/sec) %4 + %1 από %2 (%3/δευτ) %4 + + + ? + ; + + + %1 of %2 - Stopped + %1 από %2 - Διακόπηκε + + + bytes + bytes + + + kB + kB + + + MB + MB + + + %1 of %2 (%3/sec) - %4 + %1 από %2 (%3/δευτ) - %4 + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + %n Download(s) + + %n Λήψη + %n Λήψεις + + + + There are %1 downloads in progress +Do you want to quit anyway? + Είναι %1 λήψεις σε εξέλιξη +Είστε σίγουροι ότι θέλετε να κλείσετε; + + + %n minutes remaining + + απομένει %n λεπτό + απομένουν %n λεπτά + + + + %n seconds remaining + + απομένει %n δευτερόλεπτο + απομένουν %n δευτερόλεπτα + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + Άνοιγμα + + + Copy + Αντιγραφή + + + Delete + Διαγραφή + + + History + Ιστορικό + + + &Remove + &Απομάκρυνση + + + Remove &All + Α&πομάκρυνση Όλων + + + + HistoryMenu + + Show All History + Προβολή Ιστορικού + + + Clear History... + Εκκαθάριση Ιστορικού... + + + Clear History + Εκκαθάριση Ιστορικού + + + Do you want to clear the history? + Θέλετε να διαγράψετε το ιστορικό; + + + + HistoryModel + + Title + Τίτλος + + + Address + Διεύθυνση + + + + HistoryTreeModel + + Earlier Today + Νωρίτερα Σήμερα + + + %n item(s) + + %n αντικείμενο + %n αντικείμενα + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + Default + Προεπιλογή + + + Choose language + Επιλογή γλώσσας + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Μπορείτε να επιλέξετε μια γλώσσα διαφορετική από<br>την προεπιλεγμένη του λειτουργικού συστήματος.</p><p>Παρακαλώ επιλέξτε τη γλώσσα που επιθυμείτε</p> + + + No translation files are installed. + Δεν έχουν εγκατασταθεί αρχεία μεταφράσεων. + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Εισάγετε το όνομα χρήστη και τον κωδικό για "%1" στο %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Σύνδεση στον διαμεσολαβητή "%1" χρησιμοποιώντας:</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Σφάλματα SSL: + +%1 + +%2 + +Θέλετε να αγνοήσετε αυτά τα σφάλματα; + + + Do you want to accept all these certificates? + Θέλετε να αποδεχτείτε όλα αυτά τα πιστοποιητικά; + + + - SSL Errors + - Σφάλματα SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Σφάλματα SSL:<br/><br/>για: <tt>%1</tt><ul><li>%2</li></ul> + +Θέλετε να αγνοήσετε αυτά τα σφάλματα;</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Πιστοποιητικά:<br/>%1<br/>Θέλετε να αποδεχτείτε όλα αυτά τα πιστοποιητικά;</qt> + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Όνομα + + + Value + Τιμή + + + + NetworkMonitorDialog + + Network Monitor + Παρακολούθηση Δικτύου + + + Network Requests + Αιτήσεις Δικτύου + + + Request Headers + Κεφαλίδες Αίτησης + + + Response Headers + Κεφαλίδες Απάντησης + + + &Remove + &Αφαίρεση + + + Remove &All Requests + Αφαίρεση &Όλων των Αιτημάτων + + + + OpenSearchDialog + + Open File + Άνοιγμα Αρχείου + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Όνομα + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + Χρειάζεται Αυθεντικοποίηση + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Όνομα Χρήστη: + + + Password: + Κωδικός: + + + + PlainTextEditSearch + + Not Found + Δεν Βρέθηκε + + + + ProxyDialog + + Proxy Authentication + Αυθεντικοποίηση Διαμεσολαβητή + + + ICON + ICON + + + Connect to proxy + Σύνδεση σε διαμεσολαβητή + + + Username: + Όνομα Χρήστη: + + + Password: + Κωδικός: + + + + QObject + + The file is not an XBEL version 1.0 file. + Το αρχείο δεν είναι XBEL έκδοσης 1.0. + + + Unknown title + Άγνωστος τίτλος + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Redirect: %1 + Επαναδρομολόγηση: %1 + + + Method + Μέθοδος + + + Address + Διεύθυνση + + + Response + Απάντηση + + + Length + Μήκος + + + Content Type + Τύπος Περιεχομένου + + + Info + Πληροφορίες + + + + SearchBanner + + Form + Φόρμα + + + TextLabel + Ετικέτα + + + < + < + + + > + > + + + Done + Ολοκλήρωση + + + Highlight All + + + + + SearchLineEdit + + Search + Αναζήτηση + + + + Settings + + Preferences + Προτιμήσεις + + + General + Γενικά + + + On startup: + Στην εκκίνηση του Arora: + + + Show my home page + Προβολή της αρχικής μου σελίδας + + + Show a blank page + Προβολή μιας κενής σελίδας + + + Restore windows and tabs from last time + Επαναφορά των παραθύρων και καρτελών που υπήρχαν την τελευταία φορά + + + Home Page: + Αρχική Σελίδα: + + + Set to current page + Χρήση της τρέχουσας + + + Remove history items: + Απαλοιφή ιστορικού: + + + After one day + Μετά από μια μέρα + + + After one week + Μετά από μια εβδομάδα + + + After two weeks + Μετά από δύο εβδομάδες + + + After one month + Μετά από ένα μήνα + + + After one year + Μετά από ένα χρόνο + + + Manually + Χειροκίνητα + + + On application exit + Κατά την έξοδο από την εφαρμογή + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Open links from applications: + Άνοιγμα συνδέσμων από εφαρμογές: + + + In a tab in the current window + Σε καρτέλα στο τρέχον παράθυρο + + + In a new window + Σε νέο παράθυρο + + + Downloads + Λήψεις Αρχείων + + + Ask for a destination each time + Πάντα ερώτηση για την τοποθεσία αποθήκευσης + + + Use this destination: + Αποθήκευση αρχείων σε: + + + Appearance + Εμφάνιση + + + Standard font: + Προεπιλεγμένη γραμματοσειρά: + + + Times 16 + Times 16 + + + Select... + Επιλογή... + + + Fixed-width font: + Σταθερού πλάτους γραμματοσειρά: + + + Courier 13 + Courier 13 + + + Privacy + Απόρρητο + + + Web Content + Περιεχόμενο Ιστοσελίδων + + + Enable Plugins + Ενεργοποίηση Πρόσθετων + + + Use ClickToFlash on flash plugins + + + + Enable Javascript + Ενεργοποίηση της Javascript + + + View Images + Προβολή Εικόνων + + + Cookies + Cookies + + + Accept Cookies: + Αποδοχή Cookies: + + + Always + Πάντα + + + Never + Ποτέ + + + Only from sites you navigate to + Μόνο από σελίδες που μπαίνει ο ίδιος ο χρήστης + + + Exceptions... + Εξαιρέσεις... + + + Keep Cookies Until: + Διατήρηση Cookies Μέχρι: + + + They expire + Να λήξουν + + + I exit the application + Να βγω από την εφαρμογή + + + At most 90 days + Το πολύ 90 ημέρες + + + Cookies... + Cookies... + + + Filter Tracking Cookies + + + + Tabs + Καρτέλες + + + Select tabs and windows as they are created + Επιλογή καρτελών και παραθύρων καθώς δημιουργούνται + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Confirm when closing multiple tabs + Προειδοποίηση στο κλείσιμο πολλαπλών καρτελών + + + Show only one close button instead of one for each tab + Εμφάνισε μόνο ένα κουμπί κλεισίματος αντί για ένα σε κάθε καρτέλα + + + Proxy + Διαμεσολαβητής + + + Use proxy server + Χρήση διαμεσολαβητή + + + Type: + Τύπος: + + + Socks5 + Socks5 + + + Http + Http + + + Host name: + Διαμεσολαβητής: + + + Port: + Θύρα: + + + User Name: + Όνομα Χρήστη: + + + Password: + Κωδικός: + + + Advanced + Για Προχωρημένους + + + Style Sheet: + Style Sheet: + + + Prefered languages for viewing webpages in: + Προτιμώμενες γλώσσες για την εμφάνιση των ιστοσελίδων: + + + Block Popup Windows + Φραγή Αναδυόμενων Παραθύρων + + + Opening links + Άνοιγμα συνδέσμων + + + Links that want to open in a new window: + Συνδέσμους που θέλετε να ανοίξετε σε νέο παράθυρο: + + + In a new selected tab in the current window + Σε μια νέα επιλεγμένη καρτέλα στο τρέχον παράθυρο + + + In a new tab in the current window + Σε μια νέα καρτέλα στο τρέχον παράθυρο + + + In the current tab + Στην τρέχουσα καρτέλα + + + Http (Secure) + Http (Ασφαλές) + + + Http (Transparent) + Http (Διαφανές) + + + Preferred languages for viewing webpages in: + Προτιμώμενες γλώσσες για την εμφάνιση των ιστοσελίδων: + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Φορτώνει... + + + &Edit + &Επεξεργασία + + + &Find + &Αναζήτηση + + + &View + &Προβολή + + + &Wrap lines + &Περιορισμός γραμμής κειμένου στο παράθυρο + + + Source of Page + Κώδικας της Σελίδας + + + Source of Page %1 + + + + + TabBar + + Show Tab Bar + Εμφάνιση Γραμμής Καρτελών + + + Hide Tab Bar + Απόκρυψη Γραμμής Καρτελών + + + New &Tab + Νέα &Καρτέλα + + + Duplicate Tab + Αντίγραφο Καρτέλας + + + &Close Tab + Κ&λείσιμο Καρτέλας + + + Close &Other Tabs + Κλ&είσιμο των άλλων Καρτελών + + + Reload Tab + Επαναφόρτωση Καρτέλας + + + Reload All Tabs + Επαναφόρτωση όλων των Καρτελών + + + + TabWidget + + New &Tab + &Νέα Καρτέλα + + + &Close Tab + &Κλείσιμο Καρτέλας + + + Show Next Tab + Προβολή Επόμενης Καρτέλας + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + Προβολή Προηγούμενης Καρτέλας + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + Πρόσφατα Κλεισμένες Καρτέλες + + + Untitled + Χωρίς τίτλο + + + Do you really want to close this page? + Θέλετε σίγουρα να κλείσετε αυτή τη σελίδα; + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Έχετε τροποποιήσει τη σελίδα και μόλις την κλείσετε θα χάσετε τις αλλαγές. +Θέλετε σίγουρα να κλείσετε αυτή τη σελίδα; + + + + Loading... + Φορτώνει... + + + Loading %1% (%2 %3)... + Φορτώνει %1% (%2 %3)... + + + Finished loading + Ολοκλήρωση φόρτωσης + + + Failed to load + Αποτυχία φόρτωσης + + + Saved Tabs + [Όνομα Φακέλου] + + + Bookmark All Tabs + Όλες οι Καρτέλες ως Σελιδοδείκτης + + + + ToolbarSearch + + Add '%1' + + + + No Recent Searches + Δεν Υπάρχουν Πρόσφατες Αναζητήσεις + + + Recent Searches + Πρόσφατες Αναζητήσεις + + + Clear Recent Searches + Απαλοιφή Πρόσφατων Αναζητήσεων + + + Suggestions + Προτάσεις + + + + WebPage + + Error loading page: %1 + Σφάλμα κατά την φόρτωση της σελίδας: %1 + + + When connecting to: %1. + Κατά τη σύνδεση στο: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Έλεγξε την διεύθυνση για λάθη όπως <b>ww</b>.arora-browser.org αντί για <b>www</b>.arora-browser.org + + + If the address is correct, try to check the network connection. + Εάν η διεύθυνση είναι σωστή, ελέγξτε την σύνδεση σας. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Εάν ο υπολογιστής σας ή το δίκτυο σας προστατεύεται από τείχος προστασίας ή διαμεσολαβητή, βεβαιωθείται ότι ο περιηγητής σας έχει τα κατάλληλα δικαιώματα για πρόσβαση στο δίκτυο. + + + If the address is correct, try checking the network connection. + Εάν η διεύθυνση είναι σωστή, ελέγξτε την σύνδεση σας. + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Άνοιγμα σε Νέο &Παράθυρο + + + Open in New &Tab + Άνοιγμα σε Νέα &Καρτέλα + + + Save Lin&k + Αποθήκευση &Δεσμού + + + &Bookmark This Link + Ο Δεσμός ως &Σελιδοδείκτης + + + &Copy Link Location + &Αντιγραφή Τοποθεσίας Δεσμού + + + Open Image in New &Window + Προβολή Εικόνας σε Νέο &Παράθυρο + + + Open Image in New &Tab + Προβολή Εικόνας σε Νέα &Καρτέλα + + + &Save Image + &Αποθήκευση Εικόνας + + + &Copy Image + Αντιγραφή &Εικόνας + + + C&opy Image Location + Αντιγραφή &Τοποθεσίας Εικόνας + + + Search with... + + + + Loading... + Φορτώνει... + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Δεν Βρέθηκε + + + diff --git a/src/locale/en.ts b/src/locale/en.ts deleted file mode 100644 index 2de6168a..00000000 --- a/src/locale/en.ts +++ /dev/null @@ -1,1215 +0,0 @@ - - - AboutDialog - - About - - - - - AddBookmarkDialog - - Add Bookmark - - - - Type a name for the bookmark, and choose where to keep it. - - - - - BookmarksDialog - - Open - - - - Delete - - - - New Folder - - - - Bookmarks - - - - &Remove - - - - Add Folder - - - - Open in New Tab - - - - - BookmarksManager - - Error when loading bookmarks on line %1, column %2: -%3 - - - - Toolbar Bookmarks - - - - Menu - - - - Open File - - - - XBEL (*.xbel *.xml) - - - - Imported %1 - - - - Save File - - - - %1 Bookmarks.xbel - - - - Export error - - - - error saving bookmarks - - - - Remove Bookmark - - - - Insert Bookmark - - - - Name Change - - - - Address Change - - - - - BookmarksModel - - Title - - - - Address - - - - - BookmarksToolBar - - Bookmark - - - - - BrowserApplication - - There are %1 windows and %2 tabs open -Do you want to quit anyway? - - - - - BrowserMainWindow - - &File - - - - &New Window - - - - &Open File... - - - - Open &Location... - - - - &Save As... - - - - &Import Bookmarks... - - - - &Export Bookmarks... - - - - P&rint Preview... - - - - &Print... - - - - Private &Browsing... - - - - &Quit - - - - &Edit - - - - &Undo - - - - &Redo - - - - Cu&t - - - - &Copy - - - - &Paste - - - - &Find - - - - &Find Next - - - - &Find Previous - - - - &Preferences - - - - Ctrl+, - - - - &View - - - - Shift+Ctrl+B - - - - Ctrl+| - - - - Ctrl+/ - - - - &Stop - - - - Reload Page - - - - &Make Text Bigger - - - - &Make Text Normal - - - - &Make Text Smaller - - - - Page S&ource - - - - Ctrl+Alt+U - - - - &Full Screen - - - - Hi&story - - - - Back - - - - Forward - - - - Home - - - - Restore Last Session - - - - &Bookmarks - - - - Manage Bookmarks... - - - - Add Bookmark... - - - - &Window - - - - &Tools - - - - Web &Search - - - - Ctrl+K - Web Search - - - - Enable Web &Inspector - - - - &Help - - - - About &Qt - - - - About &Arora - - - - Navigation - - - - Show Status Bar - - - - Hide Status Bar - - - - Show Toolbar - - - - Hide Toolbar - - - - Show Bookmarks bar - - - - Hide Bookmarks bar - - - - Arora - - - - %1 - Arora - Page title and Browser name - - - - Open Web Resource - - - - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - - - - Print Document - - - - Are you sure you want to turn on private browsing? - - - - Are you sure you want to close the window? There are %1 tab open - - - - Page Source of %1 - - - - Web Inspector - - - - The web inspector will only work correctly for pages that were loaded after enabling. -Do you want to reload all pages? - - - - Stop loading the current page - - - - Reload the current page - - - - Downloads - - - - Alt+Ctrl+L - Download Manager - - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. - - - - &Clear Private Data - - - - Ctrl+Shift+Delete - Clear Private Data - - - - - ClearButton - - Clear - - - - - ClearPrivateData - - Clear Private Data - - - - Clear the following items: - - - - &Browsing History - - - - &Download History - - - - &Search History - - - - &Cookies - - - - C&ache - - - - Website &Icons - - - - Clear &Private Data - - - - &Cancel - - - - - CookieExceptionsModel - - Website - - - - Status - - - - Allow - - - - Block - - - - Allow For Session - - - - - CookieModel - - Website - - - - Name - - - - Path - - - - Secure - - - - Expires - - - - Contents - - - - - CookiesDialog - - Cookies - - - - &Remove - - - - Remove &All Cookies - - - - - CookiesExceptionsDialog - - Cookie Exceptions - - - - New Exception - - - - Domain: - - - - Block - - - - Allow For Session - - - - Allow - - - - Exceptions - - - - &Remove - - - - Remove &All - - - - - DownloadDialog - - Downloads - - - - Clean up - - - - 0 Items - - - - - DownloadItem - - Save File - - - - Download canceled: %1 - - - - Error opening save file: %1 - - - - Error saving: %1 - - - - Network Error: %1 - - - - seconds - - - - minutes - - - - - %4 %5 remaining - - - - %1 of %2 (%3/sec) %4 - - - - ? - - - - %1 of %2 - Stopped - - - - bytes - - - - kB - - - - MB - - - - Form - - - - Ico - - - - Filename - - - - Try Again - - - - Stop - - - - Open - - - - - DownloadManager - - 1 Download - - - - %1 Downloads - - - - - HistoryDialog - - Open - - - - Copy - - - - Delete - - - - History - - - - &Remove - - - - Remove &All - - - - - HistoryMenu - - Show All History - - - - Clear History - - - - - HistoryModel - - Title - - - - Address - - - - - HistoryTreeModel - - Earlier Today - - - - %1 items - - - - - NetworkAccessManager - - <qt>Enter username and password for "%1" at %2</qt> - - - - <qt>Connect to proxy "%1" using:</qt> - - - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - - - - Do you want to accept all these certificates? - - - - - PasswordDialog - - Authentication Required - - - - DUMMY ICON - - - - INTRO TEXT DUMMY - - - - Username: - - - - Password: - - - - - ProxyDialog - - Proxy Authentication - - - - ICON - - - - Connect to proxy - - - - Username: - - - - Password: - - - - - QObject - - The file is not an XBEL version 1.0 file. - - - - Unknown title - - - - - SearchBanner - - Form - - - - TextLabel - - - - < - - - - > - - - - Done - - - - - SearchLineEdit - - Search - - - - - Settings - - Settings - - - - General - - - - Home: - - - - Set to current page - - - - Remove history items: - - - - After one day - - - - After one week - - - - After two weeks - - - - After one month - - - - After one year - - - - Manually - - - - Open links from applications: - - - - In a tab in the current window - - - - In a new window - - - - Appearance - - - - Fixed-width font: - - - - Privacy - - - - Web Content - - - - Enable Plugins - - - - Enable Javascript - - - - Cookies - - - - Accept Cookies: - - - - Always - - - - Never - - - - Only from sites you navigate to - - - - Exceptions... - - - - Keep until: - - - - They expire - - - - I exit the application - - - - At most 90 days - - - - Cookies... - - - - Proxy - - - - Enable proxy - - - - Type: - - - - Socks5 - - - - Http - - - - Host: - - - - Port: - - - - User Name: - - - - Password: - - - - Advanced - - - - Style Sheet: - - - - Downloads - - - - Ask for a destination each time - - - - Use this destination: - - - - Standard font: - - - - Times 16 - - - - Select... - - - - Courier 13 - - - - - TabBar - - New &Tab - - - - Duplicate Tab - - - - &Close Tab - - - - Close &Other Tabs - - - - Reload Tab - - - - Reload All Tabs - - - - - TabWidget - - New &Tab - - - - &Close Tab - - - - Show Next Tab - - - - Show Previous Tab - - - - Recently Closed Tabs - - - - (Untitled) - - - - Do you really want to close this page? - - - - You have modified this page and when closing it you would lose the modification. -Do you really want to close this page? - - - - - - ToolbarSearch - - Google - - - - No Recent Searches - - - - Recent Searches - - - - Clear Recent Searches - - - - - WebPage - - Error loading page: %1 - - - - - WebView - - Open in New &Window - - - - Open in New &Tab - - - - Save Lin&k - - - - &Bookmark This Link - - - - &Copy Link Location - - - - Open Image in New &Window - - - - Open Image in New &Tab - - - - &Save Image - - - - &Copy Image - - - - C&opy Image Location - - - - - WebViewSearch - - Not Found - - - - diff --git a/src/locale/es.ts b/src/locale/es.ts index 081bb684..cc1c7ab6 100644 --- a/src/locale/es.ts +++ b/src/locale/es.ts @@ -1,1500 +1,2215 @@ - - - - - AboutDialog - - - About - Acerca de... - - - - AddBookmarkDialog - - - Add Bookmark - Añadir marcador - - - - Type a name for the bookmark, and choose where to keep it. - Escriba un nombre para el marcador y elija dónde quiere guardarlo. - - - - BookmarksDialog - - - Open - Abrir - - - - Open in New Tab - Abrir en una pestaña nueva - - - - Delete - Borrar - - - - New Folder - Nueva carpeta - - - - Bookmarks - Marcadores - - - - &Remove - &Eliminar - - - - Add Folder - Crear carpeta - - - - BookmarksManager - - - Error when loading bookmarks on line %1, column %2: -%3 - Error al cargar los marcadores en la línea %1, columna %2: %3 - - - - Toolbar Bookmarks - Barra de herramientas de marcadores - - - - Menu - Menú - - - - Open File - Abrir archivo - - - - XBEL (*.xbel *.xml) - XBEL (*.xbel *.xml) - - - - Imported %1 - Importado %1 - - - - Save File - Guardar archivo - - - - %1 Bookmarks.xbel - %1 Bookmarks.xbel - - - - Export error - Error al exportar - - - - error saving bookmarks - Error guardando los marcadores - - - - Remove Bookmark - Eliminar marcador - - - - Insert Bookmark - Insertar marcador - - - - Name Change - Cambiar el nombre - - - - Address Change - Cambiar la dirección - - - - BookmarksModel - - - Title - Título - - - - Address - Dirección - - - - BookmarksToolBar - - - Bookmark - Marcador - - - - BrowserApplication - - - There are %1 windows and %2 tabs open -Do you want to quit anyway? - Hay %1 ventanas y %2 pestañas abiertas -¿Está seguro de que desea salir? - - - - BrowserMainWindow - - - &File - &Archivo - - - - &New Window - &Ventana nueva - - - - &Open File... - &Abrir archivo... - - - - Open &Location... - Abrir &ubicación... - - - - &Save As... - &Guardar como... - - - - &Import Bookmarks... - &Importar marcadores... - - - - &Export Bookmarks... - &Exportar marcadores... - - - - P&rint Preview... - V&ista previa... - - - - &Print... - Im&primir... - - - - Private &Browsing... - &Navegación privada... - - - - &Quit - &Salir - - - - &Edit - &Editar - - - - &Undo - &Deshacer - - - - &Redo - &Rehacer - - - - Cu&t - Cor&tar - - - - &Copy - &Copiar - - - - &Paste - &Pegar - - - - &Find - &Buscar - - - - &Find Next - Buscar &siguiente - - - - &Find Previous - Buscar &anterior - - - - &Preferences - &Preferencias - - - - Ctrl+, - Ctrl+, - - - - &View - &Ver - - - - Shift+Ctrl+B - Shift+Ctrl+B - - - - Ctrl+| - Ctrl+| - - - - Ctrl+/ - Ctrl+/ - - - - &Stop - &Detener - - - - Reload Page - &Recargar la página - - - - &Make Text Bigger - &Ampliar tamaño del texto - - - - &Make Text Normal - Tamaño del texto &normal - - - - &Make Text Smaller - &Reducir tamaño del texto - - - - Page S&ource - Código &fuente - - - - Ctrl+Alt+U - Ctrl+Alt+U - - - - &Full Screen - Pantalla &completa - - - - Hi&story - &Historial - - - - Back - Atrás - - - - Forward - Adelante - - - - Home - Inicio - - - - Restore Last Session - Restaurar la última sesión - - - - &Bookmarks - &Marcadores - - - - Manage Bookmarks... - Administrar marcadores... - - - - Add Bookmark... - Añadir marcador... - - - - &Window - &Ventana - - - - &Tools - &Herramientas - - - - Web &Search - &Buscar en la web - - - - Ctrl+K - Web Search - Ctrl+K - - - - &Clear Private Data - &Borrar datos privados - - - - Ctrl+Shift+Delete - Clear Private Data - Ctrl+Shift+Delete - - - - Enable Web &Inspector - Activar el &inspector web - - - - &Help - &Ayuda - - - - About &Qt - Acerca de &Qt - - - - About &Arora - Acerca de &Arora - - - - Navigation - Navegación - - - - Show Status Bar - Mostrar la barra de estado - - - - Hide Status Bar - Ocultar la barra de estado - - - - Show Toolbar - Mostrar la barra de herramientas - - - - Hide Toolbar - Ocultar la barra de herramientas - - - - Show Bookmarks bar - Mostrar la barra de marcadores - - - - Hide Bookmarks bar - Ocultar la barra de marcadores - - - - Arora - Arora - - - - %1 - Arora - Page title and Browser name - %1 - Arora - - - - Open Web Resource - Abrir un recurso web - - - - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - Recursos web (*.html *.htm *.svg *.png *.gif *.svgz);;Todos los archivos (*.*) - - - - Print Document - Imprimir documento - - - - Are you sure you want to turn on private browsing? - ¿Está seguro de que quiere activar la navegación privada? - - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. - <b>%1</b><br><br>Cuando la navegación privada está activada, se desactivan algunas opciones relacionadas con su privacidad:<ul><li> Las páginas web no se añaden al historial.</li><li> Las descargas se quitan automáticamente de la ventana de descargas.</li><li> No se guardan las cookies nuevas y no se puede acceder a las cookies actuales.</li><li> No se guardan los iconos de los sitios web ni tampoco la sesión.</li><li> Las búsquedas no se añaden al menú emergente del cuadro de búsqueda.</li></ul>Aún puede pulsar los botones Atrás y Adelante para volver a las páginas que ha abierto hasta que cierre la ventana. - - - - Are you sure you want to close the window? There are %1 tab open - ¿Está seguro de que quiere cerrar la ventana? Hay %1 pestañas abiertas - - - - Page Source of %1 - Código fuente de %1 - - - - Web Inspector - Inspector web - - - - The web inspector will only work correctly for pages that were loaded after enabling. -Do you want to reload all pages? - El inspector web sólo funcionará correctamente con las páginas que se carguen después de activarlo. -¿Desea recargar todas las páginas? - - - - Stop loading the current page - Detener la carga de la página actual - - - - Reload the current page - Recargar la página actual - - - - Downloads - Descargas - - - - Alt+Ctrl+L - Download Manager - Alt+Ctrl+L - - - - ClearButton - - - Clear - Limpiar - - - - ClearPrivateData - - - Clear Private Data - Limpiar datos privados - - - - Clear the following items: - Limpiar los siguientes elementos: - - - - &Browsing History - Historial de &navegación - - - - &Download History - Historial de &descargas - - - - &Search History - Historial de &búsquedas - - - - &Cookies - &Cookies - - - - C&ache - C&aché - - - - Website &Icons - &Iconos de los sitios web - - - - Clear &Private Data - Limpiar datos &privados - - - - &Cancel - &Cancelar - - - - CookieExceptionsModel - - - Website - Sitio web - - - - Status - Estado - - - - Allow - Permitir - - - - Block - Bloquar - - - - Allow For Session - Permitir sólo durante esta sesión - - - - CookieModel - - - Website - Sitio web - - - - Name - Nombre - - - - Path - Ruta - - - - Secure - Segura - - - - Expires - Caducidad - - - - Contents - Contenidos - - - - CookiesDialog - - - Cookies - Cookies - - - - &Remove - &Eliminar - - - - Remove &All Cookies - Eliminar &todas las cookies - - - - CookiesExceptionsDialog - - - Cookie Exceptions - Cookies exentas - - - - New Exception - Nueva excepción - - - - Domain: - Dominio: - - - - Block - Bloquear - - - - Allow For Session - Permitir sólo durante esta sesión - - - - Allow - Permitir - - - - Exceptions - Excepciones - - - - &Remove - &Eliminar - - - - Remove &All - Eliminar &todas - - - - DownloadDialog - - - Downloads - Descargas - - - - Clean up - Vaciar - - - - 0 Items - 0 elementos - - - - DownloadItem - - - Form - Formulario - - - - Ico - Ico - - - - Filename - Nombre de archivo - - - - Try Again - Volver a intentarlo - - - - Stop - Detener - - - - Open - Abrir - - - - Save File - Guardar archivo - - - - Download canceled: %1 - Descarga cancelada: %1 - - - - Error opening save file: %1 - Error al abrir el archivo guardado: %1 - - - - Error saving: %1 - Error al guardar: %1 - - - - Network Error: %1 - Error de red: %1 - - - - seconds - segundos - - - - minutes - minutos - - - - - %4 %5 remaining - - %4 %5 restantes - - - - %1 of %2 (%3/sec) %4 - %1 de %2 (%3/seg) %4 - - - - ? - ? - - - - %1 of %2 - Stopped - %1 de %2 - Detenida - - - - bytes - bytes - - - - kB - kB - - - - MB - MB - - - - DownloadManager - - - 1 Download - 1 descarga - - - - %1 Downloads - %1 descargas - - - - HistoryDialog - - - Open - Abrir - - - - Copy - Copiar - - - - Delete - Borrar - - - - History - Historial - - - - &Remove - &Eliminar - - - - Remove &All - Eliminar &todo - - - - HistoryMenu - - - Show All History - Mostrar todo el historial - - - - Clear History - Limpiar historial - - - - HistoryModel - - - Title - Título - - - - Address - Dirección - - - - HistoryTreeModel - - - Earlier Today - Hace un rato - - - - %1 items - %1 elementos - - - - NetworkAccessManager - - - <qt>Enter username and password for "%1" at %2</qt> - <qt>Introduzca el nombre de usuario y la contraseña para "%1" en %2</qt> - - - - <qt>Connect to proxy "%1" using:</qt> - <qt>Conectar al proxy "%1" usando:</qt> - - - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - Errores SSL: - -%1 - -%2 - -¿Quiere omitir estos errores? - - - - Do you want to accept all these certificates? - ¿Desea aceptar todos estos certificados? - - - - PasswordDialog - - - Authentication Required - Autenticación necesaria - - - - DUMMY ICON - - - - - INTRO TEXT DUMMY - - - - - Username: - Nombre de usuario: - - - - Password: - Contraseña: - - - - ProxyDialog - - - Proxy Authentication - Autenticación con el proxy - - - - ICON - - - - - Connect to proxy - Conectar al proxy - - - - Username: - Nombre de usuario: - - - - Password: - Contraseña: - - - - QObject - - - The file is not an XBEL version 1.0 file. - El archivo no es un archivo XBEL versión 1.0. - - - - Unknown title - Título desconocido - - - - SearchBanner - - - Form - Formulario - - - - TextLabel - - - - - < - < - - - - > - > - - - - Done - Hecho - - - - SearchLineEdit - - - Search - Buscar - - - - Settings - - - Settings - Opciones - - - - General - General - - - - Home: - Página de inicio: - - - - Set to current page - Página actual - - - - Remove history items: - Eliminar páginas del historial: - - - - After one day - Al cabo de un día - - - - After one week - Al cabo de una semana - - - - After two weeks - Al cabo de dos semanas - - - - After one month - Al cabo de un mes - - - - After one year - Al cabo de un año - - - - Manually - Manualmente - - - - Open links from applications: - Abrir enlaces desde aplicaciones: - - - - In a tab in the current window - En una pestaña en la ventana actual - - - - In a new window - En una ventana nueva - - - - Downloads - Descargas - - - - Ask for a destination each time - Preguntar dónde guardar las descargas cada vez - - - - Use this destination: - Usar este destino: - - - - Appearance - Apariencia - - - - Standard font: - Fuente estándar: - - - - Times 16 - Times 16 - - - - Select... - Seleccionar... - - - - Fixed-width font: - Fuente de anchura fija: - - - - Courier 13 - Courier 13 - - - - Privacy - Privacidad - - - - Web Content - Contenido web - - - - Enable Plugins - Activar plugins - - - - Enable Javascript - Activar javascript - - - - Cookies - Cookies - - - - Accept Cookies: - Aceptar cookies: - - - - Always - Siempre - - - - Never - Nunca - - - - Only from sites you navigate to - Sólo desde los sitios que visite - - - - Exceptions... - Excepciones... - - - - Keep until: - Mantener: - - - - They expire - Hasta que caduquen - - - - I exit the application - Hasta que cierre la aplicación - - - - At most 90 days - 90 días como máximo - - - - Cookies... - Cookies... - - - - Proxy - Proxy - - - - Enable proxy - Usar un proxy - - - - Type: - Tipo: - - - - Socks5 - Socks5 - - - - Http - Http - - - - Host: - Dirección: - - - - Port: - Puerto: - - - - User Name: - Nombre de usuario: - - - - Password: - Contraseña: - - - - Advanced - Avanzado - - - - Style Sheet: - Hoja de estilos: - - - - TabBar - - - New &Tab - &Nueva pestaña - - - - Duplicate Tab - Duplicar pestaña - - - - &Close Tab - &Cerrar pestaña - - - - Close &Other Tabs - Cerrar &otras pestañas - - - - Reload Tab - Recargar pestaña - - - - Reload All Tabs - Recargar todas las pestañas - - - - TabWidget - - - New &Tab - Nueva &pestaña - - - - &Close Tab - &Cerrar pestaña - - - - Show Next Tab - Mostrar pestaña siguiente - - - - Show Previous Tab - Mostrar pestaña anterior - - - - Recently Closed Tabs - Pestañas cerradas recientemente - - - - (Untitled) - (Sin título) - - - - Do you really want to close this page? - ¿Está seguro de que quiere cerrar esta página? - - - - You have modified this page and when closing it you would lose the modification. -Do you really want to close this page? - - Ha modificado esta página y si la cierre perderá los cambios. -¿Está seguro de que quiere cerrar esta página? - - - - ToolbarSearch - - - Google - Google - - - - No Recent Searches - No hay búsquedas recientes - - - - Recent Searches - Búsquedas recientes - - - - Clear Recent Searches - Limpiar búsquedas recientes - - - - WebPage - - - Error loading page: %1 - Error al cargar la página: %1 - - - - WebView - - - Open in New &Window - Abrir en una &ventana nueva - - - - Open in New &Tab - Abrir en una &pestaña nueva - - - - Save Lin&k - &Guardar enlace - - - - &Bookmark This Link - &Añadir esta página a marcadores - - - - &Copy Link Location - &Copiar dirección del enlace - - - - Open Image in New &Window - Abrir &imagen en una ventana nueva - - - - Open Image in New &Tab - Abrir i&magen en una pestaña nueva - - - - &Save Image - G&uardar imagen - - - - &Copy Image - Co&piar imagen - - - - C&opy Image Location - Copiar &dirección de la imagen - - - - WebViewSearch - - - Not Found - No encontrado - - - + + + AboutDialog + + Lightweight WebKit-based web browser + Navegador ligero basado en WebKit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Authors + Autores + + + License + Licencia + + + Close + Cerrar + + + About %1 + Acerca de %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">(new line) +<html><head><meta name="qrichtext" content="1" /><style type="text/css">(new line) +p, li { white-space: pre-wrap; }(new line) +</style></head><body style="font-size:9pt;">(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + WebKit versión: %1 + + + + AcceptLanguage + + Languages + Idiomas + + + Languages: in order of preference: + Idiomas: en orden de preferencia: + + + Move &Up + Mover hacia &arriba + + + Move &Down + Mover hacia a&bajo + + + &Remove + &Eliminar + + + Add... + Añadir... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Bloqueado por la regla AdBlock: %1 + + + + AdBlockDialog + + Add Custom Rule + Añadir regla personalizada + + + Learn more about writing rules... + Aprenda más sobre la escritura de reglas... + + + Update Subscription + Actualizar la subscripción + + + Browse Subscriptions... + Examinar las subscripciones... + + + Remove Subscription + Eliminar la subscripción + + + AdBlock Configuration + Configuración de AdBlock + + + Enable AdBlock + Activar AdBlock + + + Action + Acción + + + + AdBlockManager + + Custom Rules + Reglas personalizadas + + + + AdBlockModel + + Rule + Regla + + + + AdBlockSchemeAccessHandler + + Subscribe? + ¿Subscribir? + + + Subscribe to this AdBlock subscription? +%1 + ¿Aceptar esta subscripción AdBlock? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Añadir marcador + + + Type a name for the bookmark, and choose where to keep it. + Escriba un nombre para el marcador y elija dónde quiere guardarlo. + + + Url + Url + + + Title + Título + + + Add Folder + Añadir carpeta + + + + AutoFillDialog + + Form Passwords + Formulario de contraseñas + + + Remove + Eliminar + + + Remove All + Eliminar todo + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>¿Desea guardar esta contraseña?</b><br> Para revisar y eliminar las contraseñas guardadas, abra el panel Autocompletar de Preferencias. + + + Never for this site + Nunca para este sitio + + + Not now + Ahora no + + + + AutoFillModel + + WebSite + Página web + + + User Name + Nombre de usuario + + + + BookmarksDialog + + Bookmarks + Marcadores + + + &Remove + &Eliminar + + + Add Folder + Crear carpeta + + + Open + Abrir + + + Open in New Tab + Abrir en una pestaña nueva + + + Delete + Borrar + + + New Folder + Nueva carpeta + + + Edit Name + Editar nombre + + + Edit Address + Editar dirección + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Error al cargar los marcadores en la línea %1, columna %2: %3 + + + + Toolbar Bookmarks + Barra de herramientas de marcadores + + + Menu + Menú + + + Open File + Abrir archivo + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importado %1 + + + Save File + Guardar archivo + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Error al exportar + + + error saving bookmarks + Error guardando los marcadores + + + Remove Bookmark + Eliminar marcador + + + Insert Bookmark + Insertar marcador + + + Bookmarks Bar + Barra de marcadores + + + Bookmarks Menu + Menú de marcadores + + + Error when loading html bookmarks: %1 + + Error al cargar marcadores html: %1 + + + + XBEL + XBEL + + + Name Change + Undo bookmark title change + Cambiar el nombre + + + Address Change + Undo bookmark url change + Cambiar la dirección + + + XBEL bookmarks + Marcadores XBEL + + + HTML Netscape bookmarks + Marcadores HTML de Netscape + + + htmlToXBel tool required + Se necesita la herramienta htmlToXBel + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + La herramienta htmlToXBel , que se incluye con Arora y es necesaria para importar los marcadores HTML, no está instalada o no está disponible en el camino de búsqueda. + + + Loading Bookmark + Cargando marcador + + + Error when loading HTML bookmarks: %1 + + Se produjo un error mientras se cargaban los marcadores HTML: %1 + + + + + BookmarksMenu + + Open in Tabs + Abrir en pestañas + + + + BookmarksModel + + Title + Título + + + Address + Dirección + + + + BookmarksToolBar + + Bookmark + Marcador + + + Open + Abrir + + + Open in New &Tab + Abrir en una &pestaña nueva + + + Remove + Eliminar + + + Add Bookmark... + Añadir marcador... + + + Add Folder... + Añadir carpeta... + + + Bookmarks + Marcadores + + + + BrowserApplication + + (Change: %1 %2) + (Cambio: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Hay %1 ventanas y %2 pestañas abiertas +¿Está seguro de que desea salir? + + + Restore failed + Falló la recuperación + + + The saved session will not be restored because Arora crashed while trying to restore this session. + La seión guardada no puede ser recuperada ya que Arora falló durante la última recuperación. + + + Arora crashed while trying to restore this session. Should I try again? + Arora se cerró inesperadamente mientras intentaba recuperar esta sesión. ¿Intentarlo de nuevo? + + + + BrowserMainWindow + + &File + &Archivo + + + &New Window + &Ventana nueva + + + &Open File... + &Abrir archivo... + + + Open &Location... + Abrir &ubicación... + + + &Save As... + &Guardar como... + + + &Import Bookmarks... + &Importar marcadores... + + + &Export Bookmarks... + &Exportar marcadores... + + + P&rint Preview... + V&ista previa... + + + &Print... + Im&primir... + + + Private &Browsing... + &Navegación privada... + + + &Quit + &Salir + + + &Edit + &Editar + + + &Undo + &Deshacer + + + &Redo + &Rehacer + + + Cu&t + Cor&tar + + + &Copy + &Copiar + + + &Paste + &Pegar + + + &Find + &Buscar + + + Find Nex&t + Buscar &siguiente + + + Find P&revious + Buscar &anterior + + + Prefere&nces... + &Preferencias... + + + Ctrl+, + Ctrl+, + + + &View + &Ver + + + Show Menu Bar + Mostrar barra de menú + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Detener + + + &Reload Page + &Recargar página + + + Page S&ource + Código &fuente + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Pantalla &completa + + + Hi&story + &Historial + + + Back + Atrás + + + Forward + Adelante + + + Home + Inicio + + + Restore Last Session + Recuperar la última sesión + + + &Bookmarks + &Marcadores + + + Add Bookmark... + Añadir marcador... + + + &Window + &Ventana + + + &Tools + &Herramientas + + + Web &Search + &Buscar en la web + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Borrar datos privados + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Activar el &inspector web + + + &Help + A&yuda + + + About &Qt + Acerca de &Qt + + + Navigation + Navegación + + + Show Status Bar + Mostrar la barra de estado + + + Hide Status Bar + Ocultar la barra de estado + + + Show Toolbar + Mostrar la barra de herramientas + + + Hide Toolbar + Ocultar la barra de herramientas + + + Show Bookmarks Bar + Mostrar barra de marcadores + + + Hide Bookmarks Bar + Ocultar barra de marcadores + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Abrir un recurso web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Recursos web (*.html *.htm *.svg *.png *.gif *.svgz);;Todos los archivos (*.*) + + + Print Document + Imprimir documento + + + Are you sure you want to turn on private browsing? + ¿Está seguro de que quiere activar la navegación privada? + + + Are you sure you want to close the window? There are %1 tabs open + ¿Está seguro de que quiere cerrar la ventana? Hay %1 pestañas abiertas + + + Web Inspector + Inspector web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + El inspector web sólo funcionará correctamente con las páginas que se carguen después de activarlo. +¿Desea recargar todas las páginas? + + + Stop loading the current page + Detener la carga de la página actual + + + Reload the current page + Recargar la página actual + + + Downloads + Descargas + + + Show &Network Monitor + Mostrar mo&nitor de red + + + Switch application language + Cambiar el idioma de la aplicación + + + Close Window + Cerrar ventana + + + Zoom &In + Zoom &aumentar + + + Zoom &Normal + Zoom &normal + + + Zoom &Out + Zoom &reducir + + + Zoom &Text Only + Zoom &solo texto + + + About &%1 + About Browser + Acerca de &%1 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Show All Bookmarks... + Mostrar todos los marcadores... + + + Add Folder... + Añadir carpeta... + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Al activar la navegación privada, se desactivarán algunas de las medidas relativas a su privacidad:<ul><li> Las páginas web so serán añadidas al historial.</li><li> Se eliminará automáticamente los elementos de la ventana de descargas.</li><li> No se añadiran nuevas cookies y las actuales no serán accesibles.</li><li> Los iconos de los sitios no se almacenarán, tampoco se guardarán las sesiones.</li><li> Las búsquedas no serán añadidas al menú emergente en el cuadro de búsqueda.</li></ul>Podrá hacer clic en los botones Atrás y Adelante para volver a las páginas web que ha abierto solo hasta que se cierre la ventana. + + + Default + Predeterminado + + + Text Encoding + Codificación del texto + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> Network cache is disabled.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Al activar la navegación privada, se desactivarán algunas de las medidas relativas a su privacidad:<ul><li> Las páginas web so serán añadidas al historial.</li><li> Se eliminará automáticamente los elementos de la ventana de descargas.</li><li> No se añadiran nuevas cookies y las actuales no serán accesibles.</li><li> Los iconos de los sitios no se almacenarán, tampoco se guardarán las sesiones.</li><li> Las búsquedas no serán añadidas al menú emergente en el cuadro de búsqueda.</li></ul>Se desactiva la caché de red.</li></ul>Podrá hacer clic en los botones Atrás y Adelante para volver a las páginas web que ha abierto solo hasta que se cierre la ventana. + + + Select &All + Seleccionar &todo + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Al activar la navegación privada, se desactivarán algunas de las medidas relativas a su privacidad:<ul><li> Las páginas web so serán añadidas al historial..</li><li> Se eliminará automáticamente los elementos de la ventana de descargas..</li><li> No se añadiran nuevas cookies y las actuales no serán accesibles.</li><li> Los iconos de los sitios no se almacenarán, tampoco se guardarán las sesiones.</li><li> Las búsquedas no serán añadidas al menú emergente en el cuadro de búsqueda.</li><li> La nueva caché de red no se gravará en el disco.</li></ul>Podrá hacer clic en los botones Atrás y Adelante para volver a las páginas web que ha abierto solo hasta que se cierre la ventana. + + + Options... + Opciones... + + + Configure Search Engines... + Configurar los motores de búsqueda... + + + &Ad Block... + &Bloquear publicidad... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Cuando se activa la navegación privada, se desactivarán algunas acciones relacionadas con su intimidad: + + + Webpages are not added to the history. + Las páginas web no se añadirán al historial. + + + Items are automatically removed from the Downloads window. + Se eliminarán automáticamente los elementos de la ventana de descargas. + + + New cookies are not stored, current cookies can't be accessed. + No se guardarán las nuevas cookies, no se podrá acceder a las cookies actuales. + + + Site icons won't be stored. + No se guardarán los iconos de la página. + + + Session won't be saved. + No se guardará la sesión. + + + Searches are not added to the pop-up menu in the search box. + Las búsquedas no se añadirán al menú emergente en el cuadro de búsquedas. + + + No new network cache is written to disk. + No se escribirá en el disco la nueva caché de la red. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Hasta que se cierre la ventana, usted podrá hacer clic en los botones Atrás y Adelante para volver a las páginas web que ha abierto. + + + Private Browsing + Navegación privada + + + + ClearButton + + Clear + Limpiar + + + + ClearPrivateData + + Clear Private Data + Limpiar datos privados + + + Clear the following items: + Limpiar los siguientes elementos: + + + &Browsing History + Historial de &navegación + + + &Download History + Historial de &descargas + + + &Search History + Historial de &búsquedas + + + &Cookies + &Cookies + + + C&ached Web Pages + Páginas &web en memoria caché + + + Website &Icons + &Iconos de los sitios web + + + Clear &Private Data + Limpiar datos &privados + + + &Cancel + &Cancelar + + + + ClickToFlash + + Load + Cargar + + + Load All + Cargar todo + + + Add %1 to Whitelist + Añadir %1 a la lista blanca + + + Remove from Whitelist + Quitar de la lista blanca + + + Settings + Ajustes + + + Load Flash + Cargar «Flash» + + + + ClickToFlashSettings + + Whitelist sites + Lista blanca de sitios + + + + CookieExceptionsModel + + Website + Sitio web + + + Rule + Regla + + + Allow + Permitir + + + Block + Bloquear + + + Allow For Session + Permitir sólo para esta sesión + + + + CookieModel + + Website + Sitio web + + + Name + Nombre + + + Path + Ruta + + + Secure + Segura + + + Expires + Caduca + + + Contents + Contenidos + + + true + verdadero + + + false + falso + + + Session cookie + Cookie de la sesión + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Eliminar + + + Remove &All Cookies + Eliminar &todas las cookies + + + Add &Rule + Añadir &regla + + + + CookiesExceptionsDialog + + Cookie Exceptions + Cookies exentas + + + New Exception + Nueva excepción + + + Domain: + Dominio: + + + Block + Bloquear + + + Allow For Session + Permitir sólo para esta sesión + + + Allow + Permitir + + + Exceptions + Excepciones + + + &Remove + &Eliminar + + + Remove &All + Eliminar &todas + + + + DownloadDialog + + Downloads + Descargas + + + Clean up + Vaciar + + + 0 Items + 0 elementos + + + + DownloadItem + + Form + Formulario + + + Ico + Icono + + + Filename + Nombre de archivo + + + Try Again + Volver a intentarlo + + + Stop + Detener + + + Open + Abrir + + + Save File + Guardar archivo + + + Download canceled: %1 + Descarga cancelada: %1 + + + Error opening output file: %1 + Error al abrir el archivo de salida: %1 + + + Error saving: %1 + Error al guardar: %1 + + + Network Error: %1 + Error de red: %1 + + + seconds + segundos + + + %1 of %2 (%3/sec) %4 + %1 de %2 (%3/seg) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 de %2 - Detenida + + + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/sec) - %4 + + + Download directory (%1) couldn't be created. + El directorio de descarga (%1)no se puede crear. + + + + DownloadManager + + %n Download(s) + %n Descarga(s) + + + + + + + + + There are %1 downloads in progress +Do you want to quit anyway? + Hay %1 descargas en proceso +¿Quiere salir de todos modos? + + + %n minutes remaining + Faltan %n minutos + + + + + + + + %n seconds remaining + Faltan %n segundos + + + + + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Sin error + + + Error opening: %1: No such file or directory + Se produjo un error al abrir: %1: No existe el archivo o directorio + + + Unable to read %1 + No se puede leer %1 + + + Contents of %1 + Contenido de %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + History + Historial + + + &Remove + &Eliminar + + + Remove &All + Eliminar &todo + + + Open + Abrir + + + Copy + Copiar + + + Delete + Borrar + + + + HistoryMenu + + Show All History + Mostrar todo el historial + + + Clear History... + Limpiar historial... + + + Clear History + Limpiar historial + + + Do you want to clear the history? + ¿Desea limpiar el historial? + + + + HistoryModel + + Title + Título + + + Address + Dirección + + + + HistoryTreeModel + + Earlier Today + En el día de hoy + + + %n item(s) + %n elemento(s) + + + + + + + + + + JavaScriptAroraObject + + Welcome to Arora! + ¡Bienvenido a Arora! + + + Arora Start + Iniciar Arora + + + Search! + ¡Buscar! + + + Search results provided by + Resultados de la búsqueda proporcionados por + + + About Arora + Acerca de Arora + + + + LanguageManager + + Choose language + Elegir idioma + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Puede ejecutarse con un idioma distinto<br>al predeterminado del sistema operativo.</p><p>Por favor, elija el idioma que desee utilizar</p> + + + No translation files are installed. + Los archivos de traducción no están instalados. + + + No translation files are installed at %1. + Ho hay archivos de traducción instalados en %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Introduzca el nombre de usuario y la contraseña para "%1" en %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Conectar al proxy "%1" usando:</qt> + + + - SSL Errors + Errores -SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Errores SSL:<br/><br/>para: <tt>%1</tt><ul><li>%2</li></ul> + +¿Ignorar estos errores?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificados:<br/>%1<br/>¿Aceptar todos estos certificados?</qt> + + + Issuer: %1 + Emisor: %1 + + + Not valid before: %1 + No es válido antes de: %1 + + + Valid until: %1 + Válido hasta el: %1 + + + Alternate Names: + Nombres alternativos: + + + + NetworkMonitor + + Name + Nombre + + + Value + Valor + + + + NetworkMonitorDialog + + Network Monitor + Monitor de red + + + Network Requests + Solicitudes de red + + + Request Headers + Cabeceras de las solicitudes + + + Response Headers + Cabeceras de respuesta + + + &Remove + &Eliminar + + + Remove &All Requests + Eliminar &todas las solicitudes + + + + OpenSearchDialog + + Open File + Abrir archivo + + + OpenSearch + OpenSearch + + + Error + Error + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 no es una descripción correcta para OpenSearch 1.1 o ya está en su lista. + + + You must have at least one search engine in here. + Debe tener aquí al menos un motor de búsqueda. + + + OpenSearch Manager + Gestor OpenSearch + + + &Restore Defaults + &Restaurar predeterminados + + + &Delete + &Borrar + + + &Add + &Añadir + + + &Close + &Cerrar + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descripción:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Proporciona sugerencias contextuales</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Lista separada por comas de las palabras clave que se puede introducir en la barra seguidas de los términos de búsqueda para buscar con este motor + + + Name + Nombre + + + Keywords + Palabras clave + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + ¿Quiere añadir el siguiente motor a su lista de motores de búsqueda?<br /><br />Nombre: %1<br />Búsquedas en: %2 + + + + PasswordDialog + + Authentication Required + Se necesita autenticación + + + DUMMY ICON + ICONO SIMULADO + + + INTRO TEXT DUMMY + INTRODUCIR TEXTO SIMULADO + + + Username: + Nombre de usuario: + + + Password: + Contraseña: + + + + PlainTextEditSearch + + Not Found + No encontrado + + + + ProxyDialog + + Proxy Authentication + Autenticación con el proxy + + + Connect to proxy + Conectar al proxy + + + Username: + Nombre de usuario: + + + Password: + Contraseña: + + + + QObject + + The file is not an XBEL version 1.0 file. + El archivo no es un archivo XBEL versión 1.0. + + + Unknown title + Título desconocido + + + The file is not an OpenSearch 1.1 file. + Este archivo no es un archivo OpenSearch 1.1. + + + + RequestModel + + Redirect: %1 + Redirige a: %1 + + + Method + Método + + + Address + Dirección + + + Response + Respuesta + + + Length + Longitud + + + Content Type + Tipo de contenido + + + Info + Información + + + + SearchBanner + + Form + Formulario + + + Done + Hecho + + + Highlight All + Resaltar todo + + + + SearchLineEdit + + Search + Buscar + + + + Settings + + Preferences + Preferencias + + + General + General + + + On startup: + Al inicio: + + + Show my home page + Mostrar mi página de inicio + + + Show a blank page + Mostrar página en blanco + + + Restore windows and tabs from last time + Recuperar ventanas y pestañas de la última sesión + + + Home Page: + Página de inicio: + + + Set to current page + Página actual + + + Remove history items: + Eliminar páginas del historial: + + + After one day + Al cabo de un día + + + After one week + Al cabo de una semana + + + After two weeks + Al cabo de dos semanas + + + After one month + Al cabo de un mes + + + After one year + Al cabo de un año + + + Manually + Manualmente + + + On application exit + Al cerrar la aplicación + + + Open links from applications: + Abrir enlaces desde aplicaciones: + + + In a new window + En una ventana nueva + + + Downloads + Descargas + + + Ask for a destination each time + Preguntar en cada caso dónde se quieren guardar + + + Use this destination: + Usar este destino: + + + Appearance + Apariencia + + + Standard font: + Tipografía estándar: + + + Select... + Seleccionar... + + + Fixed-width font: + Tipografía de anchura fija: + + + Privacy + Privacidad + + + Web Content + Contenido web + + + Enable Plugins + Activar plugins + + + Enable Javascript + Activar javascript + + + View Images + Ver imagenes + + + Cookies + Cookies + + + Accept Cookies: + Aceptar cookies: + + + Always + Siempre + + + Never + Nunca + + + Only from sites you navigate to + Sólo desde los sitios que visite + + + Exceptions... + Excepciones... + + + Keep Cookies Until: + Mantener las cookies: + + + They expire + Hasta que caduquen + + + I exit the application + Hasta que cierre la aplicación + + + At most 90 days + 90 días como máximo + + + Cookies... + Cookies... + + + Tabs + Pestañas + + + Select tabs and windows as they are created + Seleccionar pestañas y ventanas al ser creadas + + + Proxy + Proxy + + + Use proxy server + Usar un sevidor proxy + + + Type: + Tipo: + + + Socks5 + Socks5 + + + Host name: + Nombre de la máquina: + + + Port: + Puerto: + + + User Name: + Nombre de usuario: + + + Password: + Contraseña: + + + Advanced + Avanzado + + + Style Sheet: + Hoja de estilos: + + + Show only one close button instead of one for each tab + Mostrar sólo un botón de cierre en lugar de uno para cada pestaña + + + Block Popup Windows + Bloquear ventanas emergentes + + + Opening links + Abiendo enlaces + + + Links that want to open in a new window: + Enlaces que desea abrir en una nueva ventana: + + + In a new selected tab in the current window + En la pestaña seleccionada en la ventana actual + + + In a new tab in the current window + En una nueva pestaña en la ventana actual + + + In the current tab + En la pestaña actual + + + Http (Secure) + Http (Seguro) + + + Http (Transparent) + Http (Transparente) + + + Preferred languages for viewing webpages in: + Idiomas preferidos para visualizar páginas web: + + + Use ClickToFlash on flash plugins + Use ClickToFlash en las extensiones flash + + + Filter Tracking Cookies + Filtrar las cookies de seguimiento + + + Confirm when closing multiple tabs or windows + Pedir confirmación cuando se cierren multiples pestañas o ventanas + + + Quit the application when last tab is closed + Salir de la aplicación cuando se cierre la última pestaña + + + Enable network cache + Activar caché de red + + + Maximum Size: + Tamaño máximo: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Use el motor de búsqueda predeterminado como último recurso cuando la URL dada por el usuario no es correcta + + + Choose Directory... + Elegir directorio... + + + A cookie session ends: + Una cookie de sesión caduca: + + + When I exit the application + Cuando salga de la aplicación + + + 1 day + 1 día + + + 2 days + 2 días + + + 3 days + 3 días + + + 7 days + 7 días + + + 30 days + 30 días + + + AutoFill + Autocompletar + + + AutoFill web forms: + Autocompletar formularios web: + + + User names and passwords + Nombres de usuario y contraseñas + + + Edit... + Editar... + + + Browse... + Examinar... + + + + SettingsDialog + + Restart required + Se necesita reiniciar + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + La configuración de la caché de red ha cambiado. A fin de que pueda ser tenida en cuenta, el navegador tiene que ser reiniciado. + + + Choose Directory + Elegir directorio + + + Choose CSS File + Elegir archivo CSS + + + + SourceViewer + + Loading... + Cargando... + + + &Edit + &Editar + + + &Find + &Buscar + + + &View + &Ver + + + &Wrap lines + A&justar las líneas + + + Source of Page + Código fuente de la página + + + Source of Page %1 + Código fuente de la página %1 + + + + TabBar + + Show Tab Bar + Mostrar barra de pestañas + + + Hide Tab Bar + Ocultar barra de pestañas + + + Duplicate Tab + Duplicar pestaña + + + &Close Tab + &Cerrar pestaña + + + Close &Other Tabs + Cerrar las &otras pestañas + + + Reload Tab + Recargar pestaña + + + Reload All Tabs + Recargar todas las pestañas + + + + TabWidget + + New &Tab + Nueva &pestaña + + + &Close Tab + &Cerrar pestaña + + + Show Next Tab + Mostrar pestaña siguiente + + + Show Previous Tab + Mostrar pestaña anterior + + + Recently Closed Tabs + Pestañas cerradas recientemente + + + Untitled + Sin título + + + Do you really want to close this page? + ¿Está seguro de que quiere cerrar esta página? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Ha modificado esta página y si la cierre perderá los cambios. +¿Está seguro de que quiere cerrar esta página? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Pestañas guardadas + + + Loading... + Cargando... + + + Loading %1% (%2 %3)... + Cargando %1% (%2 %3)... + + + Finished loading + Carga finalizada + + + Failed to load + Hubo un fallo durantre la carga + + + Bookmark All Tabs + Todas las pestañas a marcadores + + + + ToolbarSearch + + No Recent Searches + No hay búsquedas recientes + + + Recent Searches + Búsquedas recientes + + + Clear Recent Searches + Limpiar búsquedas recientes + + + Suggestions + Sugerencias + + + Add '%1' + Añadir «%1» + + + Configure Search Engines... + Configurar motores de búsqueda... + + + + WebPage + + Error loading page: %1 + Error al cargar la página: %1 + + + When connecting to: %1. + Cuando se conecta a: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Compruebe que no hay errores en la dirección como<b>ww</b>.arora-browser.org en lugar de <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Si su ordenador o red están protegidos por un cortafuegos o un proxy, asegúrese de que al navegador se le permite el acceso a la red. + + + If the address is correct, try checking the network connection. + Si la dirección es correcta, compruebe la conexión de red. + + + Resending POST request + Reenviar una solicitud POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Para mostrar el sitio web, la solicitud, junto con todos los datos deben ser enviados, una vez más, lo que puede llevar a algun comportamiento inesperado del sitio por ejemplo, la misma acción puede ser realizada una vez más. ¿Quiere continuar igualmente? + + + + WebView + + Open in New &Window + Abrir en una &ventana nueva + + + Open in New &Tab + Abrir en una &pestaña nueva + + + Save Lin&k + &Guardar enlace + + + &Bookmark This Link + &Añadir esta página a marcadores + + + &Copy Link Location + &Copiar dirección del enlace + + + Open Image in New &Window + Abrir &imagen en una ventana nueva + + + Open Image in New &Tab + Abrir i&magen en una pestaña nueva + + + &Save Image + G&uardar imagen + + + &Copy Image + Co&piar imagen + + + C&opy Image Location + Copiar &dirección de la imagen + + + Loading... + Cargando... + + + Search with... + Buscar con... + + + Add to the toolbar search + Añadir a la barra de herramientas de búsqueda + + + Method not supported + Método no compatible + + + %1 method is not supported. + El método %1 no es compatible. + + + Search engine + Motor de búsqueda + + + Choose the desired search engine + Elija el motor de búsqueda deseado + + + Engine name + Nombre del motor + + + Type in a name for the engine + Escriba un nombre para el motor + + + Block Image + Bloquear imagen + + + + WebViewSearch + + Not Found + No encontrado + + + diff --git a/src/locale/es_CR.ts b/src/locale/es_CR.ts new file mode 100644 index 00000000..17680b14 --- /dev/null +++ b/src/locale/es_CR.ts @@ -0,0 +1,2273 @@ + + + + + AboutDialog + + About + Acerca de + + + Authors + Autores + + + License + Licencia + + + Lightweight WebKit-based web browser + Navegador web ligero, basado en WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Cerrar + + + About %1 + Acerca %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + Idiomas + + + Languages: in order of preference: + Idiomas: En orden de preferencia: + + + Move &Up + Ir &Arriba + + + Move &Down + Ir &Abajo + + + &Remove + &Remover + + + Add... + Agregar... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Regla + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Agregar marcador + + + Type a name for the bookmark, and choose where to keep it. + Introduzca un nombre para el marcador y seleccione donde desea guardarlo. + + + Url + URL + + + Title + Título + + + Add Folder + Agregar carpeta + + + + AutoFillDialog + + Form Passwords + + + + Remove + Remover + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Abrir + + + Open in New Tab + Abrir en una nueva pestaña + + + Delete + Borrar + + + New Folder + Nueva carpeta + + + Bookmarks + Marcadores + + + &Remove + &Remover + + + Add Folder + Agregar carpeta + + + Edit Name + Editar nombre + + + Edit Address + Editar dirección + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Error durante la carga de los maradores en la línea %1, columna %2: +%3 + + + Toolbar Bookmarks + Barra de Marcadores + + + Menu + Menú + + + Open File + Abrir archivo + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importado %1 + + + Save File + Guardar archivo + + + %1 Bookmarks.xbel + %1 Marcadores.xbel + + + Export error + Error de exportación + + + error saving bookmarks + error guardando los marcadores + + + Remove Bookmark + Remover marcador + + + Insert Bookmark + Insertar marcador + + + Name Change + Cambiar nombre + + + Address Change + Cambiar dirección + + + Bookmarks Bar + Barra de marcadores + + + Bookmarks Menu + Menú de marcadores + + + Name Change + Undo bookmark title change + Cambiar nombre + + + Address Change + Undo bookmark url change + Cambiar dirección + + + XBEL bookmarks + Marcadores XBEL + + + HTML Netscape bookmarks + Marcadores Netscape HTML + + + htmlToXBel tool required + Herramienta htmlToXBel requerida + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Herramienta htmlToXBel, la cual viene incluida con Arora y es necesaria para importar marcadores HTML, no está instalado o disponible en las rutas de búsqueda. + + + Loading Bookmark + Cargando marcador + + + Error when loading HTML bookmarks: %1 + + Error durante la carga de marcadores HTML: %1 + + + + + BookmarksMenu + + Open in Tabs + Abrir en pestañas + + + + BookmarksModel + + Title + Título + + + Address + Dirección + + + + BookmarksToolBar + + Bookmark + Marcador + + + Open + Abrir + + + Open in New &Tab + Abrir en una nueva &pestaña + + + Remove + Remover + + + Add Bookmark... + Agregar marcador... + + + Add Folder... + Agregar carpeta... + + + Bookmarks + Marcadores + + + + BrowserApplication + + (Change: %1 %2) + (Cambiar: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Hay %1 ventanas y %2 pestañas abiertas +¿Desea cerrarla(s) de todos modos? + + + Restore failed + Restauración fallida + + + The saved session will not be restored because Arora crashed while trying to restore this session. + La sesión guardada no pudo ser restaurada porque Arora se bloqueó mientras intentaba restaurar esta sesión. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Archivo + + + &New Window + &Nueva ventana + + + &Open File... + &Abrir archivo... + + + Open &Location... + Abrir &Dirección... + + + &Save As... + &Guardar como... + + + &Import Bookmarks... + &Importar marcadores... + + + &Export Bookmarks... + &Exportar marcadores... + + + P&rint Preview... + Vista p&reliminar... + + + &Print... + &Imprimir... + + + Private &Browsing... + Navegación &privada... + + + &Quit + &Quitar + + + &Edit + &Editar + + + &Undo + &Deshacer + + + &Redo + &Rehacer + + + Cu&t + Cor&tar + + + &Copy + &Copiar + + + &Paste + &Pegar + + + &Find + &Buscar + + + Find Nex&t + Buscar Próxi&mo + + + Find P&revious + Encontrar A&nterior + + + Prefere&nces... + Prefere&ncias... + + + Ctrl+, + Ctrl+, + + + &View + &Ver + + + Show Menu Bar + Mostrar la barra de menú + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Detener + + + &Reload Page + &Recargar página + + + Make Text &Bigger + Hacer el texto más &grande + + + Make Text &Normal + Hacer el texto &normal + + + Make Text &Smaller + Hacer el texto más &pequeño + + + Page S&ource + F&uente de la página + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Pantalla completa + + + Hi&story + Hi&storial + + + Back + Atrás + + + Forward + Adelante + + + Home + Inicio + + + Restore Last Session + Restaurar la última sesión + + + &Bookmarks + &Marcadores + + + Manage Bookmarks... + Administrar Marcadores... + + + Add Bookmark... + Agregar Marcador... + + + &Window + &Ventana + + + &Tools + &Herramientas + + + Web &Search + Búsqueda & Web + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Limpiar información privada + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Habilitar &Inspección Web + + + &Help + &Ayuda + + + About &Qt + Acerca de &QT + + + About &Arora + Acerca de &Arora + + + Navigation + Navegación + + + Show Status Bar + Mostar barra de estado + + + Hide Status Bar + Esconder barra de estado + + + Show Toolbar + Mostrar barra de herramientas + + + Hide Toolbar + Esconder barra de herramientas + + + Show Bookmarks Bar + Mostrar barra de marcadores + + + Hide Bookmarks Bar + Esconder barra de marcadores + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Abrir recurso web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Recursos web (*.html *.htm *.svg *.png *.gif *.svgz);;Todos los archivos (*.*) + + + Print Document + Imprimir documento + + + Are you sure you want to turn on private browsing? + ¿Está seguro de activar la navegación privada? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Cuando la navegación privada se activa, algunas accciones relacionadas con su privacidad son deshabilitadas:<ul><li> Las páginas web no son agregadas en el historial.</li><li> Los objetos son automáticamente removidos de la ventana de descargas.</li><li> Las cookies nuevas no son guardadas, las cookies actuales no podrán ser accesadas.</li><li> Los íconos de los sitios no serán guardados, la sesión tampoco podrá ser guardada.</li><li> Las búsquedas no son agregadas al menú emergente de la caja de búsqueda.</li></ul> A menos que usted cierre la ventana, podrá utilizar los botones Regresar y Adelantar para regresar a páginas web que han sido abiertas. + + + Are you sure you want to close the window? There are %1 tabs open + ¿Está seguro que desea cerrar esta ventana? Hay %1 pestañana(s) abierta(s) + + + Page Source of %1 + Página fuente de %1 + + + Web Inspector + Inspector web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + El Inspector web solo funcionará correctamente para páginas que fueron cargadas después de haber sido habilitado. +¿Desea recargar las páginas? + + + Stop loading the current page + Detener la carga de la página actual + + + Reload the current page + Recargar la página actual + + + Downloads + Descargas + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + Switch application language + Cambiar el idioma del programa + + + Close Window + Cerrar ventana + + + Zoom &In + Acercamiento &Ampliar + + + Zoom &Normal + Acercamiento &Normal + + + Zoom &Out + Acercamiento &Achicar + + + Zoom &Text Only + Acercamiento &Sólo texto + + + Show All Bookmarks... + Mostrar todos los marcadores... + + + Add Folder... + Agregar carpeta... + + + About &%1 + About Browser + Acerca &%1 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Predeterminado + + + Text Encoding + Codificación de caracteres + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> Network cache is disabled.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Cuando la navegación privada se activa, algunas accciones relacionadas con su privacidad son deshabilitadas:<ul><li> Las páginas web no son agregadas en el historial.</li><li> Los objetos son automáticamente removidos de la ventana de descargas.</li><li> Las cookies nuevas no son guardadas, las cookies actuales no podrán ser accesadas.</li><li> Los íconos de los sitios no serán guardados, la sesión tampoco podrá ser guardada.</li><li> Las búsquedas no son agregadas al menú emergente de la caja de búsqueda.</li></ul> A menos que usted cierre la ventana, podrá utilizar los botones Regresar y Adelantar para regresar a páginas web que han sido abiertas. + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + Configurar motores de búsqueda... + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Borrar + + + + ClearPrivateData + + Clear Private Data + Borrar datos privados + + + Clear the following items: + Borrarr las siguientes opciones: + + + &Browsing History + &Historial de navegación + + + &Download History + &Historial de descargas + + + &Search History + &Historial de búsquedas + + + &Cookies + &Cookies + + + C&ached Web Pages + Páginas web c&acheadas + + + Website &Icons + &Íconos del sitio web + + + Clear &Private Data + Borrar los &Datos privados + + + &Cancel + &Cancelar + + + + ClickToFlash + + Load + Cargar + + + Load All + Cargar todo + + + Add %1 to Whitelist + Agregar %1 a la lista blanca + + + Remove from Whitelist + Remover de la lista blanca + + + Settings + Configuraciones + + + Load Flash + Cargar Flash + + + + ClickToFlashSettings + + Whitelist sites + Sitios de la lista blanca + + + + CookieExceptionsModel + + Website + Sitio web + + + Rule + Regla + + + Allow + Permitir + + + Block + Bloquear + + + Allow For Session + Permitir por esta sesión + + + + CookieModel + + Website + Stio web + + + Name + Nombre + + + Path + Ruta + + + Secure + Seguridad + + + Expires + Expiración + + + Contents + Contenidos + + + true + verdadero + + + false + falso + + + Session cookie + Cookie de la sesión + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Remover + + + Remove &All Cookies + Remove &todas las cookies + + + Add &Rule + Agregar &regla + + + + CookiesExceptionsDialog + + Cookie Exceptions + Excepciones de Cookies + + + New Exception + Nueva excepción + + + Domain: + Dominio: + + + Block + Bloquear + + + Allow For Session + Permitir por esta sesión + + + Allow + Permitir + + + Exceptions + Excepciones + + + &Remove + &Remover + + + Remove &All + Remover &Todo + + + + DownloadDialog + + Downloads + Descargas + + + Clean up + Borrar + + + 0 Items + 0 objetos + + + &OK + &OK + + + + DownloadItem + + Form + Foma + + + Ico + Ícono + + + Filename + Nombre del archivo + + + Try Again + Intentar de nuevo + + + Stop + Detener + + + Open + Abrir + + + Save File + Guardar archivo + + + Download canceled: %1 + Descarga cancelada: %1 + + + Error opening output file: %1 + Error abriendo el archivo de salida: %1 + + + Error saving: %1 + Error guardando: %1 + + + Network Error: %1 + Error de red: %1 + + + seconds + segundos + + + - %n minutes remaining + + - %n minuto restante + - %n minutos restantes + + + + - %n seconds remaining + + - %n segundo restante + - %n segundos restantes + + + + %1 of %2 (%3/sec) %4 + %1 de %2 (%3/seg) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 de %2 - Detenido + + + bytes + bytes + + + kB + kB + + + MB + MB + + + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/seg) - %4 + + + Download directory (%1) couldn't be created. + Descargando directorio (%1) no puede ser creado. + + + + DownloadManager + + %n Download(s) + + %n Descargado + %n Descargados + + + + There are %1 downloads in progress +Do you want to quit anyway? + Hay %1 descarga(s) en progreso +¿Desea quitarlo de todos modos? + + + %n minutes remaining + + %n minuto restante + %n minutos restantes + + + + %n seconds remaining + + %n segundo restante + %n segundos restantes + + + + bytes + bites + + + kB + kB + + + MB + MB + + + GB + + + + + FileAccessReply + + No Error + Sin Error + + + Error opening: %1: No such file or directory + Error abriendo %1: No s pudo encontrar el archivo o directorio + + + Unable to read %1 + No se puede leer %1 + + + Contents of %1 + Contenidos de %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + Abrir + + + Copy + Copiar + + + Delete + Borrar + + + History + Historial + + + &Remove + &Remover + + + Remove &All + Remover &Todo + + + + HistoryMenu + + Show All History + Mostrar todo el historial + + + Clear History... + Borrar historial... + + + Clear History + Borrar historial + + + Do you want to clear the history? + ¿Desea borrar el historial? + + + + HistoryModel + + Title + Título + + + Address + Dirección + + + + HistoryTreeModel + + Earlier Today + Lo más antiguo + + + %n item(s) + + %n objeto + %n objetos + + + + + JavaScriptAroraObject + + Welcome to Arora! + ¡Bienvenido a Arora! + + + Arora Start + Iniciar Arora + + + Search! + ¡Buscar! + + + Search results provided by + Resultados de la búsqueda proveídos por + + + About Arora + Acerca de Arora + + + + LanguageManager + + Choose language + Elija el idioma + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Usted puede ejecutar un idioma distinto al del <br>sistema operativo predeterminado.</p><p>Por favor el idioma que desea utilizar</p> + + + No translation files are installed. + No se instalarán archivos de traducción + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Digite el usuario y clave para "%1" en %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Conectarse al proxy "%1" usando:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Errores SSL: + +%1 +%2 +¿Desea ignorar esos errores? + + + Do you want to accept all these certificates? + ¿Desea aceptar todos esos certificados? + + + - SSL Errors + - Errores-SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Errores SSL:<br/><br/>para: <tt>%1</tt><ul><li>%2</li></ul> + +¿Quieres ignorar esos errores?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificados:<br/>%1<br/>¿Quieres aceptar todos esos certificados?</qt> + + + Issuer: %1 + Emitido por: %1 + + + Not valid before: %1 + No válido antes: %1 + + + Valid until: %1 + Válidao hasta: %1 + + + Alternate Names: + Nombres alternativos: + + + + NetworkMonitor + + Name + Nombre + + + + NetworkMonitorDialog + + &Remove + &Remover + + + + OpenSearchDialog + + Open File + Abrir archivo + + + OpenSearch + BuscadorLibre + + + Error + Error + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 no es una descripción de BuscadorLibre 1.1 o ya está en su lista. + + + You must have at least one search engine in here. + Debes tener al menos un motor de búsqueda acá. + + + OpenSearch Manager + Administrador de BuscadorLibre + + + &Restore Defaults + &Restaurar Predeterminado + + + &Delete + &Borrar + + + &Add + &Agregar + + + &Close + &Cerrar + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descripción:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Provee sugerencias contextuales</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Nombre + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + ¿Quieres agregar el siguiente motor a su lista de motores de búsqueda?<br /><br />Nombre: %1<br />Reliza búsquedas en: %2 + + + + PasswordDialog + + Authentication Required + Autenticación requerida + + + DUMMY ICON + ÍCONO VIRTUAL + + + INTRO TEXT DUMMY + DIGITAR TEXTO VIRTUAL + + + Username: + Nombre de usuario: + + + Password: + Contraseña: + + + + PlainTextEditSearch + + Not Found + No encontrado + + + + ProxyDialog + + Proxy Authentication + Autenticación de Proxy + + + ICON + ÍCONO + + + Connect to proxy + Conactar al proxsy + + + Username: + Usuario: + + + Password: + Clave: + + + + QObject + + The file is not an XBEL version 1.0 file. + El archivo no es una versión 1.0 XBEL. + + + Unknown title + Título desconocido + + + The file is not an OpenSearch 1.1 file. + Este no es un archivo BuscadorLibre 1.1 + + + + RequestModel + + Address + Dirección + + + + SearchBanner + + Form + Forma + + + TextLabel + Etiqueta de texto + + + < + < + + + > + > + + + Done + Finalizado + + + Highlight All + Marcar todo + + + + SearchLineEdit + + Search + Buscar + + + + Settings + + Preferences + Preferencias + + + General + General + + + On startup: + Al iniciar: + + + Show my home page + Mostrar mi página de Inicio + + + Show a blank page + Mostrar una página en blanco + + + Restore windows and tabs from last time + Restaurar ventanas y pestañas de la última sesión + + + Home Page: + Página de Inicio: + + + Set to current page + Fijar la página actual + + + Remove history items: + Remover objetos del historial: + + + After one day + Después de un día + + + After one week + Después de una semana + + + After two weeks + Después de dos semanas + + + After one month + Después de un mes + + + After one year + Después de un año + + + Manually + Manualmente + + + On application exit + Al salir de la aplicación + + + Open links from applications: + Abrir enlaces desde aplicaciones: + + + In a tab in the current window + En una pestaña en la ventana actual + + + In a new window + En una nueva ventana + + + Downloads + Descargas + + + Ask for a destination each time + Preguntar en cada caso por el destino + + + Use this destination: + Usar este destino: + + + Appearance + Apariencia + + + Standard font: + Fuente estándar: + + + Times 16 + Times 16 + + + Select... + Seleccionar... + + + Fixed-width font: + Fuente de anchura-fija: + + + Courier 13 + Courier 13 + + + Privacy + Privacidad + + + Web Content + Contenido web + + + Enable Plugins + Habilitar agregados + + + Enable Javascript + Habilitar Javascript + + + View Images + Vier Imagenes + + + Cookies + Cookies + + + Accept Cookies: + Aceptar Cookies: + + + Always + Siempre + + + Never + Nunca + + + Only from sites you navigate to + Solo de las páginas visitadas + + + Exceptions... + Excepciones... + + + Keep Cookies Until: + Mantener Cookies hasta: + + + They expire + Que expiren (caduquen) + + + I exit the application + Al salir de la aplicación + + + At most 90 days + Durante 90 días + + + Cookies... + Cookies... + + + Tabs + Pestañas + + + Select tabs and windows as they are created + Seleccionar pestañas y ventanas cuando se crean + + + Confirm when closing multiple tabs + Confirmar cuando se cierran múltiples pestañas + + + Proxy + Proxy + + + Use proxy server + Usar servidor proxsy + + + Type: + Tipo: + + + Socks5 + Socks5 + + + Http + Http + + + Host name: + Nombre del Host: + + + Port: + Puerto: + + + User Name: + Usuario: + + + Password: + Clave: + + + Advanced + Avanzado + + + Style Sheet: + Estilo de hoja: + + + Show only one close button instead of one for each tab + + + + Preferred languages for viewing webpages in: + + + + Block Popup Windows + + + + Opening links + + + + Links that want to open in a new window: + + + + In a new selected tab in the current window + + + + In a new tab in the current window + + + + In the current tab + + + + Http (Secure) + + + + Http (Transparent) + + + + Use ClickToFlash on flash plugins + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + Reinicio requerido + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + La configuración del cache de red ha cambiado. Con el fin de que sea tomado en su cuenta, el navegador debe ser reiniciado. + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Cargando... + + + &Edit + &Editar + + + &Find + &Buscar + + + &View + &Ver + + + &Wrap lines + &Ajustar líneas + + + Source of Page %1 + Fuente de la página %1 + + + + TabBar + + Show Tab Bar + Mostrar la barra de pestañas + + + Hide Tab Bar + Esconder la barra de pestañas + + + New &Tab + Nueva &pestaña + + + Duplicate Tab + Duplicar pestaña + + + &Close Tab + &Cerrar pestaña + + + Close &Other Tabs + Cerrar &otras pestañas + + + Reload Tab + Recargar pestaña + + + Reload All Tabs + Recargar todas las pestañas + + + + TabWidget + + New &Tab + Nueva &pestaña + + + &Close Tab + &Cerrar pestaña + + + Show Next Tab + Mostrar la siguiente pestaña + + + Show Previous Tab + Mostrar la pestaña anterior + + + Recently Closed Tabs + Pestañas cerradas recientemente + + + Untitled + Sin título + + + Do you really want to close this page? + ¿Desea relamente cerrar esta página? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Usted ha modificado esta página y una vez que la haya cerrado los cambios se perderán +¿Desea realmente cerrrar esta página? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Pestañas guardadas + + + Loading... + Cargando... + + + Loading %1% (%2 %3)... + Cargando %1% (%2 %3)... + + + Finished loading + Carga finalizada + + + Failed to load + Falló al cargar + + + Bookmark All Tabs + Guardar en los marcadores todas las pestañas + + + + ToolbarSearch + + No Recent Searches + No hay búsquedas recientes + + + Recent Searches + Búsquedas recientes + + + Clear Recent Searches + Limpiar búsquedas recientes + + + Suggestions + Sugerencies + + + Add '%1' + Agregar '%1' + + + Configure Search Engines... + Configurar motores de búsqueda... + + + + WebPage + + Error loading page: %1 + Error cargando página: %1 + + + When connecting to: %1. + Cuando se conecta a: %1 + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Verifica errores en la dirección como <b>ww</b>.arora-browser.org en lugar de <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + si su computadora o red está protegida por un corta fuegos o proxy, asegúrese de que el navegador web tiene acceso permitido a la red. + + + If the address is correct, try checking the network connection. + si la dirección es correcta, intente verificar la conexión de red. + + + Resending POST request + Reenviando petición POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Con el fin de mostrar el sitio, la solicitud con toda la información debe ser enviada una vez más, lo cual puede generar un comportamiento inesperado en el sitio p.e. la misma acción debe ser desempeñada una vez más. ¿Quieres continuar de todos modos? + + + + WebView + + Open in New &Window + Abrir en una nueva &ventana + + + Open in New &Tab + Abrir en una nueva &pestaña + + + Save Lin&k + Guardar en&lace + + + &Bookmark This Link + &Marcar este enlace + + + &Copy Link Location + &Copiar la dirección del enlace + + + Open Image in New &Window + Abrir imagen en una nueva &ventana + + + Open Image in New &Tab + Abrir imagen en una nueva &pestaña + + + &Save Image + &Guardar imagen + + + &Copy Image + C&opiar imagen + + + C&opy Image Location + C&opiar la ubicación de la imagen + + + Loading... + Cargando... + + + Search with... + Buscar con... + + + Add to the toolbar search + Agregar a la barra de búsqueda + + + Method not supported + Método no soportado + + + %1 method is not supported. + %1 método no es soportado. + + + Search engine + Motor de búsqueda + + + Choose the desired search engine + Elija el nombre deseado para el motor de búsqueda + + + Engine name + Nombre de motor + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + No encontrado + + + diff --git a/src/locale/et_EE.ts b/src/locale/et_EE.ts new file mode 100644 index 00000000..21545c04 --- /dev/null +++ b/src/locale/et_EE.ts @@ -0,0 +1,2294 @@ + + + + + AboutDialog + + About + Info + + + Authors + Autorid + + + License + Litsents + + + Lightweight WebKit-based web browser + Lihtne WebKit-põhine veebilehitseja + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Sulge + + + About %1 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + + + + Languages: in order of preference: + + + + Move &Up + + + + Move &Down + + + + &Remove + &Eemalda + + + Add... + + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Lisa järjehoidja + + + Type a name for the bookmark, and choose where to keep it. + Sisestage järjehoidjale nimi ja valige, kus seda hoida. + + + Url + + + + Title + Pealkiri + + + Add Folder + Lisa kaust + + + + AutoFillDialog + + Form Passwords + + + + Remove + + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + &Ava + + + Delete + &Kustuta + + + New Folder + Uus kaust + + + Bookmarks + Järjehoidjad + + + &Remove + &Eemalda + + + Add Folder + Lisa kaust + + + Open in New Tab + Ava uues &sakis + + + Edit Name + + + + Edit Address + + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Viga järjehoidjate laadimisel real %1, veerus %2: %3 + + + Toolbar Bookmarks + Tööriistariba järjehoidjad + + + Menu + Menüü + + + Open File + Ava fail + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + %1 imporditud + + + Save File + Salvesta fail + + + %1 Bookmarks.xbel + %1 järjehoidjad.xbel + + + Export error + Viga eksportimisel + + + error saving bookmarks + viga järjehoidjate salvestamisel + + + Remove Bookmark + Eemalda järjehoidja + + + Insert Bookmark + Sisesta järjehoidja + + + Name Change + Nime muutus + + + Address Change + Aadressi muutus + + + Bookmarks Bar + + + + Bookmarks Menu + + + + Name Change + Undo bookmark title change + Nime muutus + + + Address Change + Undo bookmark url change + Aadressi muutus + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + + + + + BookmarksModel + + Title + Pealkiri + + + Address + Aadress + + + + BookmarksToolBar + + Bookmark + Järjehoidja + + + Open + + + + Open in New &Tab + Ava uues &sakis + + + Remove + + + + Add Bookmark... + &Lisa järjehoidja... + + + Add Folder... + + + + Bookmarks + Järjehoidjad + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Lahti on %1 akent ja %2 sakki.Kas Te soovite siiski väljuda? + + + Restore failed + Taastamine ebaõnnestus + + + The saved session will not being restored because last time it was restored Arora crashed. + Salvestatud sessiooni ei taastata, sest viimane kord kui Arora seda üritas, jooksis ta kokku. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Fail + + + &New Window + Uus ake&n + + + &Open File... + &Ava fail... + + + Open &Location... + Ava as&ukoht... + + + &Save As... + &Salvesta failina... + + + &Import Bookmarks... + &Impordi järjehoidjaid... + + + &Export Bookmarks... + &Ekspordi järjehoidjad... + + + P&rint Preview... + P&rintimise eelvaade... + + + &Print... + &Prindi... + + + Private &Browsing... + Privaatne veebi&lehitsemine... + + + &Quit + &Välju + + + &Edit + &Redigeeri + + + &Undo + &Tühista + + + &Redo + Tee &uuesti + + + Cu&t + &Lõika + + + &Copy + &Kopeeri + + + &Paste + Klee&bi + + + &Find + &Otsi + + + &Find Next + Otsi &järgmist + + + &Find Previous + Otsi eel&mist + + + &Preferences + &Eelistused + + + Ctrl+, + + + + &View + &Vaade + + + Ctrl+| + + + + Ctrl+/ + + + + &Stop + &Katkesta lehekülje laadimine + + + Reload Page + Lae lehekülg &uuesti + + + &Make Text Bigger + Tee tekst &suuremaks + + + &Make Text Normal + T&aasta teksti suurus + + + &Make Text Smaller + Tee tekst &väiksemaks + + + Page S&ource + Veebilehe &lähtekood + + + Ctrl+Alt+U + + + + &Full Screen + &Täisekraanvaade + + + Hi&story + A&jalugu + + + Back + &Tagasi + + + Forward + &Edasi + + + Home + &Koduleht + + + Restore Last Session + Taasta eelmine &sessioon + + + &Bookmarks + &Järjehoidjad + + + Manage Bookmarks... + &Halda järjehoidjaid... + + + Add Bookmark... + &Lisa järjehoidja... + + + &Window + A&ken + + + &Tools + &Tööriistad + + + Web &Search + Veebi&otsing + + + Ctrl+K + Web Search + + + + Enable Web &Inspector + Aktiveeri &Veebiinspektor + + + &Help + &Abi + + + About &Qt + Lähemalt &Qt kohta + + + About &Arora + Lähemalt &Arora kohta + + + Navigation + Navigeerimine + + + Show Status Bar + Näita olekuriba + + + Hide Status Bar + Peida olekuriba + + + Show Toolbar + Näita tööriistariba + + + Hide Toolbar + Peida tööriistariba + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Ava veebiressurss + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Veebiressursid (*.html *.htm *.svg *.png *.gif *.svgz);;Kõik failid (*.*) + + + Print Document + Prindi dokument + + + Are you sure you want to turn on private browsing? + Kas Te olete kindel, et soovite sisse lülitada privaatse lehitsemise? + + + Are you sure you want to close the window? There are %1 tabs open + Kas Te olete kindel, et soovite akent sulgeda? Avatud on %1 sakki + + + Page Source of %1 + Lehekülje %1 lähtekood + + + Web Inspector + Veebiinspektor + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Veebiinspektor töötab korrektselt ainult lehekülgede puhul, mis laetakse pärast Veebiinspektori aktiveerimist. +Kas Te soovite kõik leheküljed uuesti laadida? + + + Stop loading the current page + Peata käesoleva lehekülje laadimine + + + Reload the current page + Lae käesolev lehekülg uuesti + + + Downloads + &Allalaadimised + + + &Clear Private Data + Kustuta &privaatseid andmeid + + + Ctrl+Shift+Delete + Clear Private Data + + + + Show Bookmarks Bar + Näita järjehoidjate riba + + + Hide Bookmarks Bar + Peida järjehoidjate riba + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Kui privaatne lehitsemine on sisse lülitatud, ei viida läbi teatud Teie privaatsust puudutavaid toiminguid:<ul><li> Veebilehti ei sisestata ajalukku.</li><li> Allalaadimisakent puhastatakse automaatselt.</li><li> Uusi küpsiseid ei salvestata, olemasolevatele küpsistele keelatakse veebilehtedel ligipääs.</li><li> Veebilehtede ikoone ei salvestata.</li><li> Sessioone ei salvestata.</li><li> Tehtud otsinguid ei lisata otsingukasti rippmenüüsse.</li></ul>Akna sulgemiseni võite siiski kasutada Edasi- ja Tagasi-nuppe avatud veebilehtedele tagasi pöördumiseks. + + + Find &Next + Otsi &järgmist + + + Find P&revious + Otsi eel&mist + + + Prefe&rences + &Eelistused + + + &Reload Page + Lae lehekülg &uuesti + + + Make Text &Bigger + Tee tekst &suuremaks + + + Make Text &Normal + T&aasta teksti suurus + + + Make Text &Smaller + Tee tekst &väiksemaks + + + Find Nex&t + + + + Show Menu Bar + + + + Switch application language + + + + Close Window + + + + Zoom &In + + + + Zoom &Normal + + + + Zoom &Out + + + + Zoom &Text Only + + + + Show All Bookmarks... + + + + Add Folder... + + + + About &%1 + About Browser + + + + Ctrl+Y + Download Manager + + + + Default + + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Tühjenda + + + + ClearPrivateData + + Clear Private Data + Privaatsete andmete kustutamine + + + Clear the following items: + Kustuta järgmised andmed: + + + &Browsing History + &Veebi lehitsemise ajalugu + + + &Download History + &Allalaadimise ajalugu + + + &Search History + &Otsingute ajalugu + + + &Cookies + &Küpsised + + + C&ache + &Puhverdatud veebileheküljed + + + Website &Icons + Veebilehekülgede &ikoonid + + + Clear &Private Data + Kustuta &privaatsed andmed + + + &Cancel + &Loobu + + + C&ached Web Pages + + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + Eelistused + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + Veebileht + + + Status + Reegel + + + Allow + Luba + + + Block + Keela + + + Allow For Session + Luba sessiooniks + + + Rule + + + + + CookieModel + + Website + Veebileht + + + Name + Nimi + + + Path + Asukoht + + + Secure + Turvaline + + + Expires + Aegub + + + Contents + Sisu + + + true + + + + false + + + + Session cookie + + + + + CookiesDialog + + Cookies + Küpsised + + + &Remove + &Eemalda + + + Remove &All Cookies + Eemalda &kõik küpsised + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + Küpsiste erandid + + + New Exception + Uus erand + + + Domain: + Domeen: + + + Block + Keela + + + Allow For Session + Luba sessiooniks + + + Allow + Luba + + + Exceptions + Erandid + + + &Remove + &Eemalda + + + Remove &All + Eemalda &kõik + + + + DownloadDialog + + Downloads + Allalaadimised + + + Clean up + Puhasta + + + 0 Items + 0 elementi + + + + DownloadItem + + Save File + Salvesta fail + + + Download canceled: %1 + Allalaadimine katkestatud: %1 + + + Error opening save file: %1 + Viga väljundfaili avamisel: %1 + + + Error saving: %1 + Viga salvestamisel: %1 + + + Network Error: %1 + Võrgu viga: %1 + + + seconds + sekundit + + + %1 of %2 (%3/sec) %4 + %1 / %2 (%3/s) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 / %2 - Katkestatud + + + bytes + baiti + + + kB + kiB + + + MB + MiB + + + Ico + + + + Filename + Faili nimi + + + Try Again + Proovi uuesti + + + Stop + Katkesta + + + Open + Ava + + + - %n minutes remaining + + - %n minut jäänud + - %n minutit jäänud + + + + - %n seconds remaining + + - %n sekund jäänud + - %n sekundit jäänud + + + + Error opening output file: %1 + + + + %1 of %2 (%3/sec) - %4 + + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + %n Download(s) + + %n Download + %n Downloads + + + + There are %1 downloads in progress +Do you want to quit anyway? + + + + %n minutes remaining + + + + + + + %n seconds remaining + + + + + + + bytes + baiti + + + kB + kiB + + + MB + MiB + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + &Ava + + + Copy + &Kopeeri + + + Delete + K&ustuta + + + History + Ajalugu + + + &Remove + &Eemalda + + + Remove &All + Eemalda &kõik + + + + HistoryMenu + + Show All History + &Näita tervet ajalugu + + + Clear History + &Unusta ajalugu + + + Clear History... + + + + Do you want to clear the history? + + + + + HistoryModel + + Title + Pealkiri + + + Address + Aadress + + + + HistoryTreeModel + + Earlier Today + Varem täna + + + %n item(s) + + %n item + %n items + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + Choose language + + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Palun sisestage kasutajanimi ja salasõna "%1" jaoks aadressilt %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Ühendu puhverserveriga "%1" kasutades:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + SSL vead: + +%1 + +%2 + +Kas Te soovite neid vigu ignoreerida? + + + Do you want to accept all these certificates? + Kas Te soovite kõik need sertifikaadid aksepteerida? + + + - SSL Errors + + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Nimi + + + + NetworkMonitorDialog + + &Remove + &Eemalda + + + + OpenSearchDialog + + Open File + Ava fail + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Nimi + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + Nõutud audentimine + + + DUMMY ICON + + + + INTRO TEXT DUMMY + + + + Username: + Kasutajanimi: + + + Password: + Salasõna: + + + + PlainTextEditSearch + + Not Found + Ei leitud + + + + ProxyDialog + + Proxy Authentication + Audentimine puhverserveriga + + + Connect to proxy + Ühendu puhverserveriga + + + Username: + Kasutajanimi: + + + Password: + Salasõna: + + + + QObject + + The file is not an XBEL version 1.0 file. + See fail ei ole XBEL versioon 1.0 vormingus. + + + Unknown title + Tundmatu pealkiri + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Address + Aadress + + + + SearchBanner + + < + < + + + > + > + + + Done + Valmis + + + Highlight All + + + + + SearchLineEdit + + Search + Otsi + + + + Settings + + Settings + Eelistused + + + General + Üldine + + + Home: + Koduleht: + + + Set to current page + Muuda hetkel avatud leheks + + + Remove history items: + Eemalda ajaloo elemendid: + + + After one day + Pärast ühte päeva + + + After one week + Pärast ühte nädalat + + + After two weeks + Pärast kahte nädalat + + + After one month + Pärast ühte kuud + + + After one year + Pärast ühte aastat + + + Manually + Käsitsi + + + Open links from applications: + Ava viitasid teistest rakendustest: + + + In a tab in the current window + Aktiivse akna uues sakis + + + In a new window + Uues aknas + + + Appearance + Välimus + + + Fixed-width font: + Fikseeritud laiusega kirjatüüp: + + + Privacy + Privaatsus + + + Web Content + Veebilehtede sisu + + + Enable Plugins + Luba pistikprogrammid + + + Enable Javascript + Luba Javascript + + + Cookies + Küpsised + + + Accept Cookies: + Luba küpsiseid: + + + Always + Alati + + + Never + Mitte kunagi + + + Only from sites you navigate to + Ainult veebilehtedelt, mida külastan + + + Exceptions... + Erandid... + + + Keep until: + Hoia küpsiseid kuni: + + + They expire + Nad aeguvad + + + I exit the application + Rakendus suletakse + + + At most 90 days + Ülimalt 90 päeva + + + Cookies... + Küpsised... + + + Proxy + Puhverserver + + + Enable proxy + Kasuta puhverserverit + + + Type: + Tüüp: + + + Socks5 + Socks5 + + + Http + HTTP + + + Host: + Hostinimi: + + + Port: + Port: + + + User Name: + Kasutajanimi: + + + Password: + Salasõna: + + + Advanced + Muud + + + Style Sheet: + Stiilileht: + + + Downloads + Allalaadimised + + + Ask for a destination each time + Küsi sihtkataloogi iga allalaadimise puhul + + + Use this destination: + Kasuta seda kataloogi: + + + Standard font: + Vaikimisi kirjatüüp: + + + Times 16 + Times 16 + + + Select... + Vali... + + + Courier 13 + Courier 13 + + + On application exit + Rakenduse sulgemisel + + + Enable Images + Näita pilte + + + Tabs + Sakid + + + Select tabs and windows as they are created + Vali sakid ja aknad kui nad luuakse + + + Confirm when closing multiple tabs + Küsi kinnitust mitme saki sulgemisel + + + On startup: + Programmi käivitamisel: + + + Show my home page + Näita kodulehte + + + Show a blank page + Näita tühja lehte + + + Restore windows and tabs from last time + Taasta aknad ja sakid eelmisest korrast + + + Preferences + + + + Home Page: + + + + View Images + + + + Keep Cookies Until: + + + + Show only one close button instead of one for each tab + + + + Use proxy server + + + + Host name: + + + + Preferred languages for viewing webpages in: + + + + Block Popup Windows + + + + Opening links + + + + Links that want to open in a new window: + + + + In a new selected tab in the current window + + + + In a new tab in the current window + + + + In the current tab + + + + Http (Secure) + + + + Http (Transparent) + + + + Use ClickToFlash on flash plugins + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Laadimine... + + + &Edit + &Redigeeri + + + &Find + &Otsi + + + &View + &Vaade + + + Source of Page %1 + + + + + TabBar + + New &Tab + Uus &sakk + + + Duplicate Tab + &Duplikeeri sakk + + + &Close Tab + S&ulge sakk + + + Close &Other Tabs + Sulge &teised sakid + + + Reload Tab + Lae sakk uuesti + + + Reload All Tabs + Lea kõik sakid uuesti + + + Show Tab Bar + Näita sakkide riba + + + Hide Tab Bar + Peida sakkide riba + + + + TabWidget + + New &Tab + Uus sa&kk + + + &Close Tab + Sul&ge sakk + + + Show Next Tab + Näita &järgmist sakki + + + Show Previous Tab + Näita &eelmist sakki + + + Recently Closed Tabs + &Viimati suletud sakid + + + (Untitled) + (nimetu) + + + Do you really want to close this page? + Kas Te tõesti soovite selle lehekülje sulgeda? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Te olete seda lehekülge muutnud. Lehekülje sulgemisel muutused kaotatakse.Kas Te tõesti soovite selle lehekülje sulgeda? + + + Ctrl-] + + + + Ctrl-[ + + + + Untitled + + + + Saved Tabs + + + + Loading... + Laadimine... + + + Loading %1% (%2 %3)... + + + + Finished loading + + + + Failed to load + + + + Bookmark All Tabs + + + + + ToolbarSearch + + No Recent Searches + Hiljutisi otsinguid pole + + + Recent Searches + Hiljuti tehtud otsingud + + + Clear Recent Searches + Unusta hiljuti tehtud otsingud + + + Suggestions + + + + Add '%1' + + + + + WebPage + + Error loading page: %1 + Viga lehekülje laadimisel: %1 + + + When connecting to: %1. + + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + + + + If the address is correct, try checking the network connection. + + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Ava uues &aknas + + + Open in New &Tab + Ava uues &sakis + + + Save Lin&k + Salvesta &viit + + + &Bookmark This Link + Lisa viit &järjehoidjaks + + + &Copy Link Location + &Kopeeri viidatav aadress + + + Open Image in New &Window + Ava pilt uues &aknas + + + Open Image in New &Tab + Ava pilt uues &sakis + + + &Save Image + Salvesta &pilt + + + &Copy Image + &Kopeeri pilt + + + C&opy Image Location + K&opeeri pildi aadress + + + Loading... + Laadimine... + + + Search with... + + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Ei leitud + + + diff --git a/src/locale/fi_FI.ts b/src/locale/fi_FI.ts new file mode 100644 index 00000000..3328f9bc --- /dev/null +++ b/src/locale/fi_FI.ts @@ -0,0 +1,2223 @@ + + + + + AboutDialog + + About + Tietoja + + + Authors + Tekijät + + + License + Lisenssi + + + Lightweight WebKit-based web browser + Kevyt WebKit-pohjainen verkkoselain + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + + Close + Sulje + + + About %1 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + Kielet + + + Languages: in order of preference: + Kielet mielekkyysjärjestyksessä: + + + Move &Up + Siirrä &ylös + + + Move &Down + Siirrä &alas + + + &Remove + &Poista + + + Add... + Lisää... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Sääntö + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Lisää kirjanmerkki + + + Type a name for the bookmark, and choose where to keep it. + Kirjoita nimi kirjanmerkille ja valitse minne se lisätään. + + + Url + Url + + + Title + Otsikko + + + Add Folder + Lisää kansio + + + + AutoFillDialog + + Form Passwords + + + + Remove + Poista + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Avaa + + + Open in New Tab + Avaa uudessa välilehdessä + + + Edit Name + Muokkaa nimeä + + + Edit Address + Muokkaa osoitetta + + + Delete + Poista + + + New Folder + Uusi kansio + + + Bookmarks + Kirjanmerkit + + + &Remove + &Poista + + + Add Folder + Lisää kansio + + + + BookmarksManager + + Bookmarks Bar + Kirjanmerkkipalkki + + + Bookmarks Menu + Kirjanmerkkivalikko + + + Error when loading bookmarks on line %1, column %2: +%3 + Virhe kirjanmerkin latauksessa rivillä %1, sarakkeella %2 +%3 + + + Toolbar Bookmarks + Työkalurivin kirjanmerkit + + + Menu + Valikko + + + Open File + Avaa tiedosto + + + Imported %1 + Tuotu %1 + + + Save File + Tallenna tiedosto + + + %1 Bookmarks.xbel + + + + Export error + Vie virhe + + + error saving bookmarks + virhe kirjanmerkkien tallennuksessa + + + Remove Bookmark + Poista kirjanmerkki + + + Insert Bookmark + Lisää kirjanmerkki + + + Name Change + Nimen muutos + + + Address Change + Osoitteen muutos + + + Error when loading html bookmarks: %1 + + Virhe ladattaessa html kirjanmerkkejä: %1 + + + + Name Change + Undo bookmark title change + Nimen muutos + + + Address Change + Undo bookmark url change + Osoitteen muutos + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + Avaa välilehtiin + + + + BookmarksModel + + Title + Otsikko + + + Address + Osoite + + + + BookmarksToolBar + + Bookmark + Kirjanmerkkipalkki + + + Open + Avaa + + + Open in New &Tab + Avaa uudessa &välilehdessä + + + Remove + Poista + + + Add Bookmark... + Lisää kirjanmerkki... + + + Add Folder... + Lisää kansio... + + + Bookmarks + Kirjanmerkit + + + + BrowserApplication + + (Change: %1 %2) + (Muuta: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + %1 ikkunaa ja %2 välilehteä ovat avoinna +Haluatko lopettaa siitä huolimatta? + + + Restore failed + Palautus epäonnistui + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Tallennettua istuntoa ei palautettu koska Arora kaatui yrittäessään palauttaa tätä istuntoa. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Tiedosto + + + &New Window + &Uusi ikkuna + + + &Open File... + &Avaa tiedosto... + + + Open &Location... + Avaa &sijainti... + + + &Save As... + &Tallenna nimellä... + + + &Import Bookmarks... + &Tuo kirjanmerkkejä... + + + &Export Bookmarks... + &Vie kirjanmerkkejä... + + + P&rint Preview... + T&ulostuksen esikatselu... + + + &Print... + &Tulosta... + + + Private &Browsing... + Yksityinen &selailu... + + + Close Window + Sulje ikkuna + + + &Quit + &Lopeta + + + &Edit + &Muokkaa + + + &Undo + &Kumoa + + + &Redo + &Tee uudelleen + + + Cu&t + Leikka&a + + + &Copy + &Kopioi + + + &Paste + &Liitä + + + &Find + &Etsi + + + Find Nex&t + Etsi seuraav&a + + + Find P&revious + Etsi e&dellinen + + + Prefere&nces... + Asetu&kset... + + + Ctrl+, + + + + &View + &Näytä + + + Ctrl+| + + + + Ctrl+/ + + + + Show Menu Bar + Näytä valikkopalkki + + + &Reload Page + &Päivitä sivu + + + &Stop + &Pysäytä + + + Zoom &In + &Suurenna + + + Zoom &Normal + &Palauta + + + Zoom &Out + &Pienennä + + + Zoom &Text Only + Suurenna vain &tekstiä + + + Page S&ource + Sivun l&ähdekoodi + + + Ctrl+Alt+U + + + + &Full Screen + &Koko näyttö + + + Hi&story + Sivuhi&storia + + + Back + Edellinen + + + Forward + Seuraava + + + Home + Aloitussivu + + + Restore Last Session + Palauta edellinen istunto + + + &Bookmarks + &Kirjanmerkit + + + Show All Bookmarks... + Näytä kaikki kirjanmerkit... + + + Add Bookmark... + Lisää kirjanmerkki... + + + Add Folder... + LIsää kansio... + + + &Window + &Ikkuna + + + &Tools + &Työkalut + + + Web &Search + Verkko&haku + + + Ctrl+K + Web Search + + + + &Clear Private Data + &Poista yksityisyystietoja + + + Ctrl+Shift+Delete + Clear Private Data + + + + Show &Network Monitor + Näytä &verkkomonitori + + + Enable Web &Inspector + Käytä Web &Inspectoria + + + &Help + &Ohje + + + Switch application language + Vaihda ohjelman kieli + + + About &Qt + Tietoja &Qt:sta + + + About &%1 + About Browser + Tietoja &%1:sta + + + Navigation + Navigointipalkki + + + Show Status Bar + Näytä tilarivi + + + Hide Status Bar + Piilota tilarivi + + + Show Toolbar + Näytä työkalupalkki + + + Hide Toolbar + Piilota työkalupalkki + + + Show Bookmarks Bar + Näytä kirjanmerkkipalkki + + + Hide Bookmarks Bar + Piilota kirjanmerkkipalkki + + + %1 - Arora + Page title and Browser name + + + + Open Web Resource + Avaa web-tiedostoja + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Web-tiedostot (*.html *.htm *.svg *.png *.gif *.svgz);;Kaikki tiedostot (*.*) + + + Print Document + Tulosta dokumentti + + + Are you sure you want to turn on private browsing? + Oletko varma että haluat sulkea yksityisen selailun? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Kun yksityinen selailu on päällä, jotkut toiminnot liittyen yksityisyyteesi ovat pois päältä:<ul><li> Verkkosivuja ei lisätä sivuhistoriaan.</li><li>Tiedostot poistetaan automaattisesti Lataukset ikkunasta</li><li>Uusia evästeitä ei lisätä, eikä nykyisiin evästeisiin pääse käsiksi.</li><li>Sivujen kuvakkeita ei tallenneta, istuntoja ei tallenneta.</li><li>Hakuja ei lisätä ponnahdusikkuna-valikkoon hakulaatikossa.</li></ul>Kunnes suljet ikkunan, vois yhä napsauttaa Edellinen ja Seuraava painikkeita palataksesi verkkosivulle minkä olet avannut. + + + Are you sure you want to close the window? There are %1 tabs open + Oletko varma että haluat sulkea ikkunan? Siinä on %1 välilehteä avoinna + + + Web Inspector + + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Web Inspector toimii oikein vain sivuilla jotka on päivitetty sen käyttöön ottamisen jälkeen. +Haluatko päivittää kaikki sivut? + + + Stop loading the current page + Lopeta nykyisen sivun lataaminen + + + Reload the current page + Päivitä nykyinen sivu + + + Downloads + Lataukset + + + Ctrl+Y + Download Manager + + + + Default + + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Tyhjennä + + + + ClearPrivateData + + Clear Private Data + Poista yksityisyystietoja + + + Clear the following items: + Poista seuraavat tiedot: + + + &Browsing History + &Sivuhistoria + + + &Download History + &Lataukset + + + &Search History + &Haut + + + &Cookies + &Evästeet + + + C&ached Web Pages + &Välimuisti + + + Website &Icons + Verkkosivujen &kuvakkeet + + + Clear &Private Data + Poista &yksityisyystiedot + + + &Cancel + &Peruuta + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + Verkkosivu + + + Rule + Sääntö + + + Allow + Salli + + + Block + Estä + + + Allow For Session + Salli istunnon ajaksi + + + + CookieModel + + Website + Verkkosivu + + + Name + Nimi + + + Path + Polku + + + Secure + Turvallinen + + + Expires + Vanhenee + + + Contents + Sisältö + + + true + tosi + + + false + epätosi + + + Session cookie + + + + + CookiesDialog + + Cookies + Evästeet + + + &Remove + &Poista + + + Remove &All Cookies + Poista &kaikki evästeet + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + Evästeiden poikkeukset + + + New Exception + Uusi poikkeus + + + Domain: + + + + Block + Estä + + + Allow For Session + Salli istunnon ajaksi + + + Allow + Salli + + + Exceptions + Poikkeukset + + + &Remove + &Poista + + + Remove &All + Poista &kaikki + + + + DownloadDialog + + Downloads + Lataukset + + + Clean up + Tyhjennä + + + 0 Items + 0 tiedostoa + + + + DownloadItem + + Form + Lomake + + + Ico + Kuvake + + + Filename + Tiedostonimi + + + Try Again + Yritä uudestaan + + + Stop + Pysäytä + + + Open + Avaa + + + Save File + Tallenna tiedosto + + + Download canceled: %1 + Lataus keskeytetty: %1 + + + Error opening output file: %1 + Virhe avattaessa tiedostoa: %1 + + + Error saving: %1 + Virhe tallennettaessa: %1 + + + Network Error: %1 + Verkon virhe: %1 + + + seconds + sekunnit + + + - %n minutes remaining + + - %n minuutti jäljellä + - %n minuuttia jäljellä + + + + - %n seconds remaining + + - %n sekunti jäljellä + - %n sekuntia jäljellä + + + + %1 of %2 (%3/sec) %4 + %1/%2 (%3/sek) %4 + + + ? + + + + %1 of %2 - Stopped + %1/%2 - Pysäytetty + + + bytes + tavua + + + kB + kt + + + MB + Mt + + + %1 of %2 (%3/sec) - %4 + %1/%2 (%3/sek) %4 + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + Käynnissä on %1 latausta +Haluatko lopettaa siitä huolimatta? + + + %n Download(s) + + %n Lataus + %n Latausta + + + + %n minutes remaining + + %n minuutti jäljellä + %n minuuttia jäljellä + + + + %n seconds remaining + + %n sekunti jäljellä + %n sekuntia jäljellä + + + + bytes + tavua + + + kB + kt + + + MB + Mt + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + Avaa + + + Copy + Kopio + + + Delete + Poista + + + History + Historia + + + &Remove + &Poista + + + Remove &All + Poista &kaikki + + + + HistoryMenu + + Show All History + Näytä koko historia + + + Clear History... + Tyhjennä historia... + + + Clear History + Poista historia + + + Do you want to clear the history? + Haluatko poistaa historian? + + + + HistoryModel + + Title + Otsikko + + + Address + Osoite + + + + HistoryTreeModel + + Earlier Today + Aiemmin tänään + + + %n item(s) + + %n kohde + %n kohdetta + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + No translation files are installed. + Yhtään käännöstä ei ole asennettu. + + + Choose language + Valitse kieli + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Voit käyttää eri kieltä<br>kuin käyttöjärjestelmän oletus.</p><p>Ole hyvä ja valitse kieli mitä käytetään</p> + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Anna käyttäjätunnus ja salasana palvelimelle %2, sivuston viesti "%1"</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Yhdistä välityspalvelimeen "%1" käyttäen:</qt> + + + - SSL Errors + - SSL Virheet + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL virheet:<br/><br/><tt>%1</tt><ul><li>%2</li></ul> + +Haluatko sivuuttaa nämä virheet?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Varmenteet:<br/>%1<br/>Hyväksytkö kaikki nämä varmenteet?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Nimi + + + Value + Arvo + + + + NetworkMonitorDialog + + Network Monitor + Verkkomonitori + + + Network Requests + Verkon pyynnöt + + + Request Headers + Pyynnön otsakkeet + + + Response Headers + Vastauksen otsakkeet + + + &Remove + &Poista + + + Remove &All Requests + Poista &kaikki pyynnöt + + + + OpenSearchDialog + + Open File + Avaa tiedosto + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Nimi + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + Tunnistautuminen vaaditaan + + + DUMMY ICON + + + + INTRO TEXT DUMMY + + + + Username: + Käyttäjätunnus: + + + Password: + Salasana: + + + + PlainTextEditSearch + + Not Found + Ei löytynyt + + + + ProxyDialog + + Proxy Authentication + Välityspalvelimen varmennus + + + Connect to proxy + Yhdistä välityspalvelimeen + + + Username: + Käyttäjätunnus: + + + Password: + Salasana: + + + + QObject + + The file is not an XBEL version 1.0 file. + Tiedosto ei ole XBEL versio 1.0 tiedosto. + + + Unknown title + Tuntematon otsikko + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Redirect: %1 + Uudelleenohjaus: %1 + + + Method + Menetelmä + + + Address + Osoite + + + Response + Vastaus + + + Length + Pituus + + + Content Type + Sisältötyyppi + + + Info + Tietoja + + + + SearchBanner + + Form + Lomake + + + Done + Valmis + + + Highlight All + + + + + SearchLineEdit + + Search + Haku + + + + Settings + + Preferences + Asetukset + + + General + Yleiset + + + On startup: + Käynnistettäessä: + + + Show my home page + Näytä kotisivuni + + + Show a blank page + Näytä tyhjä sivu + + + Restore windows and tabs from last time + Palauta ikkunat ja välilehdet viime kerralta + + + Home Page: + Kotisivu: + + + Set to current page + Käytä avointa sivua + + + Remove history items: + Poista historia: + + + After one day + Päivän jälkeen + + + After one week + Viikon jälkeen + + + After two weeks + Kahden viikon jälkeen + + + After one month + Kuukauden jälkeen + + + After one year + Vuoden jälkeen + + + Manually + Käsin + + + On application exit + Lopetettaessa + + + Downloads + Lataukset + + + Ask for a destination each time + Kysy kansiota joka kerta + + + Use this destination: + Käytä kansiota: + + + Appearance + Ulkoasu + + + Standard font: + Oletuskirjasinlaji: + + + Select... + Valitse... + + + Fixed-width font: + Tasalevyinen kirjasin: + + + Preferred languages for viewing webpages in: + Kieli, jolla sivut näytetään: + + + Privacy + Yksityisyys + + + Web Content + Sisältö + + + Block Popup Windows + Estä ponnahdusikkunat + + + Enable Plugins + Käytä liitännäisiä + + + Enable Javascript + Käytä Javascriptiä + + + View Images + Näytä kuvat + + + Cookies + Evästeet + + + Accept Cookies: + Hyväksy evästeet: + + + Always + Aina + + + Never + Ei ikinä + + + Only from sites you navigate to + Ainoastaan sivuilta joille menet + + + Exceptions... + Poikkeukset... + + + Keep Cookies Until: + Säilytä evästeet: + + + They expire + kunnes ne vanhenevat + + + I exit the application + kunnes selain suljetaan + + + At most 90 days + Korkeintaan 90 päivää + + + Cookies... + Evästeet... + + + Tabs + Välilehdet + + + Select tabs and windows as they are created + Valitse välilehdet ja ikkunat silloin kun ne luodaan + + + Confirm when closing multiple tabs + Varoita, kun yritän sulkea useita välilehtiä samanaikaisesti + + + Show only one close button instead of one for each tab + Näytä ainoastaan yksi sulkupainike sen sijaan, että jokaisella välilehdella olisi oma sulkupainike + + + Opening links + Avautuvat linkit + + + Links that want to open in a new window: + Avaa linkit jotka haluavat avautua uuteen ikkunaan: + + + In a new window + Uuteen ikkunaan + + + In a new selected tab in the current window + Uuteen valittuun välilehteen nykyisessä ikkunassa + + + In a new tab in the current window + Uuteen välilehteen nykyisessä ikkunassa + + + In the current tab + Nykyiseen välilehteen + + + Open links from applications: + Avaa linkit: + + + Proxy + Välityspalvelin + + + Use proxy server + Käytä välityspalvelinta + + + Type: + Tyyppi: + + + Socks5 + + + + Http (Secure) + Http (turvallinen) + + + Http (Transparent) + Http (läpinäkyvä) + + + Host name: + Verkko-osoite: + + + Port: + Portti: + + + User Name: + Käyttäjätunnus: + + + Password: + Salasana: + + + Advanced + Kehittyneet + + + Style Sheet: + Tyylitiedosto: + + + Use ClickToFlash on flash plugins + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Ladataan... + + + &Edit + &Muokkaa + + + &Find + &Etsi + + + &View + &Katso + + + &Wrap lines + &Rivitys + + + Source of Page + Sivun lähdekoodi + + + Source of Page %1 + + + + + TabBar + + Show Tab Bar + Näytä välilehtipalkki + + + Hide Tab Bar + Piilota välilehtipalkki + + + Duplicate Tab + Kahdenna välilehti + + + &Close Tab + &Sulje välilehti + + + Close &Other Tabs + Sulje &muut välilehdet + + + Reload Tab + Päiviä välilehti + + + Reload All Tabs + Päivitä kaikki välilehdet + + + + TabWidget + + Untitled + Nimetön + + + Saved Tabs + Tallennetut välilehdet + + + Do you really want to close this page? + Oletko varma että haluat sulkea tämän sivun? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Olet muokannut tätä sivua ja jos se suljetaan menetät muokkaukset. +Haluatko varmasti sulkea tämän sivun? + + + + Loading... + Ladataan... + + + Loading %1% (%2 %3)... + Ladataan %1 % (%2 %3)... + + + Finished loading + Ladattu + + + Failed to load + Lataus epäonnistui + + + Show Next Tab + Näytä seuraava välilehti + + + Ctrl-] + + + + Show Previous Tab + Näytä edellinen välilehti + + + Ctrl-[ + + + + Recently Closed Tabs + Äskettäin suljetut välilehdet + + + New &Tab + Uusi &välilehti + + + &Close Tab + &Sulje välilehti + + + Bookmark All Tabs + Lisää kaikki välilehdet kirjanmerkkeihin + + + + ToolbarSearch + + No Recent Searches + Ei äskeisiä hakuja + + + Recent Searches + Äskeiset haut + + + Clear Recent Searches + Tyhjennä äskeiset haut + + + Suggestions + Ehdotukset + + + Add '%1' + + + + + WebPage + + Error loading page: %1 + Virhe ladattaessa sivua: %1 + + + When connecting to: %1. + Yhdistettäessä: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Tarkista osoite virheiden varalta, esim. "<b>ww</b>.arora-browser.org" oikean muodon sijaan "<b>www</b>.arora-browser.org" + + + If the address is correct, try checking the network connection. + Jos osoite on oikea, tarkista yhteytesi. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Jos tietokoneesi tai verkkosi on suojattu palomuurilla tai välityspalvelimella, tarkista että selaimella on pääsy verkkoon. + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Avaa uudessa &ikkunassa + + + Open in New &Tab + Avaa uudessa &välilehdessä + + + Save Lin&k + Tallenna osoit&e + + + &Bookmark This Link + &Lisää tämä osoite kirjanmerkkeihin + + + &Copy Link Location + &Kopioi osoite + + + Open Image in New &Window + Avaa kuva uudessa &ikkunassa + + + Open Image in New &Tab + Avaa kuva uudessa &välilehdessä + + + &Save Image + &Tallenna kuva + + + &Copy Image + &Kopioi kuva + + + C&opy Image Location + K&opioi kuvan osoite + + + Loading... + Ladataan... + + + Search with... + + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Ei löytynyt + + + diff --git a/src/locale/fr.ts b/src/locale/fr.ts deleted file mode 100644 index c8daba3e..00000000 --- a/src/locale/fr.ts +++ /dev/null @@ -1,1513 +0,0 @@ - - - - - AboutDialog - - - About - À propos - - - - AddBookmarkDialog - - - Add Bookmark - Ajouter un marque-page - - - - Type a name for the bookmark, and choose where to keep it. - Entrer un nom pour le marque-page et choisissez où le conserver. - - - - BookmarksDialog - - - Open - Ouvrir - - - - Delete - Supprimer - - - - New Folder - Nouveau dossier - - - - Bookmarks - Marque-pages - - - - &Remove - &Retirer - - - - Add Folder - Ajouter un dossier - - - - Open in New Tab - Ouvrir dans un nouvel onglet - - - - BookmarksManager - - - Error when loading bookmarks on line %1, column %2: -%3 - Erreur pendant le chargement des marque-pages à la ligne %1, colonne %2: -%3 - - - - Toolbar Bookmarks - Barre d'outils Marque-pages - - - - Menu - Menu - - - - Open File - Ouvrir un fichier - - - - XBEL (*.xbel *.xml) - - - - - Imported %1 - %1 a été importé - - - - Save File - Enregistrer le fichier - - - - %1 Bookmarks.xbel - - - - - Export error - Erreur d'exportation - - - - error saving bookmarks - Erreur de sauvegarde des marque-pages - - - - Remove Bookmark - Retirer le marque-page - - - - Insert Bookmark - Insérer un marque-page - - - - Name Change - Changement de nom - - - - Address Change - Changement d'adresse - - - - BookmarksModel - - - Title - Titre - - - - Address - Adresse - - - - BookmarksToolBar - - - Bookmark - Marque-page - - - - BrowserApplication - - - There are %1 windows and %2 tabs open -Do you want to quit anyway? - Il y a %1 fenêtres et %2 onglets ouverts. -Voulez-vous tout de même quitter? - - - - BrowserMainWindow - - - &File - &Fichier - - - - &New Window - &Nouvelle fenêtre - - - - &Open File... - &Ouvrir un fichier... - - - - Open &Location... - Ouvrir une &adresse... - - - - &Save As... - Enregistrer &sous... - - - - &Import Bookmarks... - &Importer des marque-pages... - - - - &Export Bookmarks... - &Exporter les marque-pages... - - - - P&rint Preview... - Ape&rçu avant impression... - - - - &Print... - Im&pression - - - - Private &Browsing... - Navigation en mode privé - - - - &Quit - &Quitter - - - - &Edit - &Édition - - - - &Undo - &Annuler - - - - &Redo - &Refaire - - - - Cu&t - &Couper - - - - &Copy - Co&pier - - - - &Paste - C&oller - - - - &Find - &Rechercher - - - - &Find Next - Rechercher le &suivant - - - - &Find Previous - Rechercher le p&récédent - - - - &Preferences - &Préférences - - - - Ctrl+, - - - - - &View - &Affichage - - - - Shift+Ctrl+B - - - - - Ctrl+| - - - - - Ctrl+/ - - - - - &Stop - A&rrêter - - - - Reload Page - &Recharger la page - - - - &Make Text Bigger - Agrandir le texte - - - - &Make Text Smaller - Réduire le texte - - - - &Make Content Bigger - Agrandir la page - - - - &Make Content Smaller - Réduire la page - - - - &Make Text Normal - Réinitialiser la taile du texte - - - - &Make Content Normal - Réinitialiser la taile de la page - - - - Page S&ource - Code s&ource de la page - - - - Ctrl+Alt+U - - - - - &Full Screen - &Plein écran - - - - Hi&story - &Historique - - - - Back - Page précédente - - - - Forward - Page suivante - - - - Home - Page d'accueil - - - - Restore Last Session - Restaurer la dernière session - - - - &Bookmarks - &Marque-pages - - - - Manage Bookmarks... - Gérer les marque-pages - - - - Add Bookmark... - Ajouter un marque-page... - - - - &Window - &Fenête - - - - &Tools - &Outils - - - - Web &Search - &Recherche Web - - - - Ctrl+K - Web Search - - - - - Enable Web &Inspector - Activer l'&inspecteur Web - - - - &Help - &Aide - - - - About &Qt - À propos de &Qt - - - - About &Arora - À propos d'&Arora - - - - Navigation - - - - - Show Status Bar - Afficher la barre d'état - - - - Hide Status Bar - Masquer la barre d'état - - - - Show Toolbar - Afficher la barre d'outils - - - - Hide Toolbar - Masquer la barre d'outils - - - - Show Bookmarks bar - Afficher la barre de marque-pages - - - - Hide Bookmarks bar - Masquer la barre de marque-pages - - - - Arora - - - - - %1 - Arora - Page title and Browser name - - - - - Open Web Resource - Ouvrir un fichier Web - - - - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - Fichier Web (*.html *.htm *.svg *.png *.gif *.svgz);;Tous les fichiers (*.*) - - - - Print Document - Imprimer le document - - - - Are you sure you want to turn on private browsing? - Êtes-vous sûr de vouloir activer la navigation en mode privé? - - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. - <b>%1</b><br><br>Lorsque la navigation en mode privé est activée, certaines actions concernant votre vie privée seront désactivées:<ul><li> Les pages Web ne sont pas ajoutées à l'historique.</li><li> Les téléchargements sont automatiquement retiré de la fenêtre des téléchargements.</li><li> Les nouveaux fichiers témoins ne sont pas conservés et les fichiers témoins déjà existant ne sont pas accessibles.</li><li> Les icônes de sites Web et la session ne sont pas enregistrés.</li><li> Les recherches ne sont pas ajoutées dans la liste des recherches récentes.</li></ul>Jusqu'à la fermeture de l'écran, vous pouvez encore utiliser les boutons Page précédente et Page suivante. - - - - Are you sure you want to close the window? There are %1 tab open - Êtes-vous sûr de vouloir fermer cette fenêtre? Il y a %1 onglets ouverts. - - - - Page Source of %1 - Code source de %1 - - - - Web Inspector - Inspecteur Web - - - - The web inspector will only work correctly for pages that were loaded after enabling. -Do you want to reload all pages? - L'inspecteur Web ne fonctionne que pour les pages qui ont été chargées après son activation. Voulez-vous recharcher toutes les pages? - - - - Stop loading the current page - Arrêter le chargement de la page en cours - - - - Reload the current page - Recharger la page en cours - - - - Downloads - Téléchargements - - - - Alt+Ctrl+L - Download Manager - - - - - &Clear Private Data - &Effacer l'information privée - - - - Ctrl+Shift+Delete - Clear Private Data - - - - - ClearButton - - - Clear - Effacer - - - - ClearPrivateData - - - Clear Private Data - Effacer les informations privées - - - - Clear the following items: - Vider les items suivants: - - - - &Browsing History - Historique de navigation - - - - &Download History - Historique de téléchargement - - - - &Search History - Historique de recherche - - - - &Cookies - Fichiers témoins - - - - C&ache - Mémoire cache - - - - Website &Icons - Icônes de sites Web - - - - Clear &Private Data - Effacer les informations privées - - - - &Cancel - &Annuler - - - - CookieExceptionsModel - - - Website - Site Web - - - - Status - Statut - - - - Allow - Permettre - - - - Block - Bloquer - - - - Allow For Session - Permettre pour la session - - - - CookieModel - - - Website - Site Web - - - - Name - Nom - - - - Path - Chemin d'accès - - - - Secure - Sécure - - - - Expires - Expire - - - - Contents - Contenu - - - - CookiesDialog - - - Cookies - Fichiers témoins - - - - &Remove - &Retirer - - - - Remove &All Cookies - Retirer tous les fichiers témoins - - - - CookiesExceptionsDialog - - - Cookie Exceptions - Exceptions pour les fichiers témoins - - - - New Exception - Nouvelle exception - - - - Domain: - Domaine: - - - - Block - Bloquer - - - - Allow For Session - Permettre pour la session - - - - Allow - Permettre - - - - Exceptions - Exceptions - - - - &Remove - Retirer - - - - Remove &All - Tout retirer - - - - DownloadDialog - - - Downloads - Téléchargements - - - - Clean up - Vider la liste - - - - 0 Items - 0 items - - - - DownloadItem - - - Form - Formulaire - - - - Ico - - - - - Filename - Nom de fichier - - - - Try Again - Essayer à nouveau - - - - Stop - Interrompre - - - - Open - Ouvrir - - - - Save File - Enregistrer le fichier - - - - Download canceled: %1 - Téléchargement annulé: %1 - - - - Error opening save file: %1 - Erreur à l'ouverture du fichier destination: %1 - - - - Error saving: %1 - Erreur à l'enregistrement: %1 - - - - Network Error: %1 - Erreur réseau: %1 - - - - seconds - secondes - - - - minutes - minutes - - - - - %4 %5 remaining - - %4 %5 restant - - - - %1 of %2 (%3/sec) %4 - %1 de %2 (%3/sec) %4 - - - - ? - - - - - %1 of %2 - Stopped - %1 de %2 - Interrompu - - - - bytes - octets - - - - kB - kO - - - - MB - MO - - - - DownloadManager - - - 1 Download - 1 téléchargement - - - - %1 Downloads - %1 téléchargements - - - - HistoryDialog - - - Open - Ouvrir - - - - Copy - Copier - - - - Delete - Supprimer - - - - History - Historique - - - - &Remove - &Retirer - - - - Remove &All - Tout retirer - - - - HistoryMenu - - - Show All History - Montrer tout l'historique - - - - Clear History - Effacer l'historique - - - - HistoryModel - - - Title - Titre - - - - Address - Adresse - - - - HistoryTreeModel - - - Earlier Today - Plutôt aujourd'hui - - - - %1 items - %1 items - - - - NetworkAccessManager - - - <qt>Enter username and password for "%1" at %2</qt> - <qt>Entrer le nombre d'utilisateur et le mot de passe pour "%1" sur %2</qt> - - - - <qt>Connect to proxy "%1" using:</qt> - <qt>Se brancher au serveur mandataire "%1" en utilisant:</qt> - - - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - Erreurs SSL: -%1 -%2 -Voulez-vous ignorer ses erreurs? - - - - Do you want to accept all these certificates? - Voulez-vous accepter tous ces certificats? - - - - PasswordDialog - - - Authentication Required - Authentification requise - - - - DUMMY ICON - - - - - INTRO TEXT DUMMY - - - - - Username: - Nom d'utilisateur: - - - - Password: - Mot de passe: - - - - ProxyDialog - - - Proxy Authentication - Authentification au serveur mandataire - - - - ICON - - - - - Connect to proxy - Se brancher au serveur mandataire - - - - Username: - Nom d'utilisateur: - - - - Password: - Mot de passe: - - - - QObject - - - The file is not an XBEL version 1.0 file. - Ce fichier n'est pas un fichier XBEL version 1.0. - - - - Unknown title - Titre inconnu - - - - SearchBanner - - - Form - Fromulaire - - - - TextLabel - - - - - < - - - - - > - - - - - Done - Fermer - - - - SearchLineEdit - - - Search - Rechercher - - - - Settings - - - Settings - Paramètres - - - - General - Général - - - - Home: - Page d'accueil: - - - - Set to current page - Utiliser la page en cours - - - - Remove history items: - Retirer les éléments de l'historique: - - - - After one day - Après une journée - - - - After one week - Après une semaine - - - - After two weeks - Après 2 semaines - - - - After one month - Après un mois - - - - After one year - Après un an - - - - Manually - Manuellement - - - - Open links from applications: - Ouvrir les liens provenant d'applications: - - - - In a tab in the current window - Dans un onglet dans la fenêtre en cours - - - - In a new window - Dans une nouvelle fenêtre - - - - Appearance - Apparence - - - - Standard font: - Police par défaut: - - - - Times 16 - - - - - Select... - Sélectionner... - - - - Fixed-width font: - Police à espacement constant: - - - - Courier 13 - - - - - Privacy - Vie privée - - - - Web Content - Contenu Web - - - - Enable Plugins - Activer les plugiciels - - - - Enable Javascript - Activer le Javascript - - - - Cookies - Fichier témoins - - - - Accept Cookies: - Accepter les fichiers témoins: - - - - Always - Toujours - - - - Never - Jamais - - - - Only from sites you navigate to - Seulement des sites que vous visitez - - - - Exceptions... - Exceptions... - - - - Keep until: - Expiration: - - - - They expire - Lorsqu'ils expirent - - - - I exit the application - Lorsque je quitte l'application - - - - At most 90 days - Au plus tard dans 90 jours - - - - Cookies... - Fichiers témoins... - - - - Proxy - Serveur mandataire - - - - Enable proxy - Activer le serveur mandataire - - - - Type: - Type: - - - - Socks5 - - - - - Http - - - - - Host: - Hôte: - - - - Port: - Port: - - - - User Name: - Nom d'utilisateur: - - - - Password: - Mot de passe: - - - - Advanced - Avancé - - - - Style Sheet: - Feuille de style: - - - - Downloads - Téléchargements - - - - Ask for a destination each time - Demander le dossier de destination à chaque fois - - - - Use this destination: - Utiliser ce dossier - - - - TabBar - - - New &Tab - Nouvel onglet - - - - Duplicate Tab - Dupliquer l'onglet - - - - &Close Tab - Fermer l'onglet - - - - Close &Other Tabs - Fermer les autres onglets - - - - Reload Tab - Recharger l'onglet - - - - Reload All Tabs - Recharger tous les onglets - - - - TabWidget - - - New &Tab - Nouvel onglet - - - - &Close Tab - Fermer l'onglet - - - - Show Next Tab - Afficher l'onglet suivant - - - - Show Previous Tab - Afficher l'onglet précédent - - - - Recently Closed Tabs - Onglet récement fermés - - - - (Untitled) - (Sans titre) - - - - Do you really want to close this page? - Voulez-vous vraiment fermer cette page? - - - - You have modified this page and when closing it you would lose the modification. -Do you really want to close this page? - - Vous avez modifié cette page et en fermant l'onglet, vous allez perdre les modifications. -Voulez-vous vraiment fermer cette page? - - - - - ToolbarSearch - - - Google - - - - - No Recent Searches - Aucune recherche récente - - - - Recent Searches - Recherches récentes - - - - Clear Recent Searches - Effacer les recherches récentes - - - - WebPage - - - Error loading page: %1 - Erreur au chargement de la page: %1 - - - - WebView - - - Open in New &Window - Ouvrir dans une &nouvelle fenêtre - - - - Open in New &Tab - Ouvrir dans un nouvel &onglet - - - - Save Lin&k - Enregistrer le &lien - - - - &Bookmark This Link - Marquer le lien - - - - &Copy Link Location - Copier le lien - - - - Open Image in New &Window - Ouvrir l'image dans une nouvelle fenêtre - - - - Open Image in New &Tab - Ouvrir l'image dans un nouvel onglet - - - - &Save Image - Enregistrer l'image - - - - &Copy Image - Copier l'image - - - - C&opy Image Location - Copier l'adresse de l'image - - - - WebViewSearch - - - Not Found - Non trouvé - - - diff --git a/src/locale/fr_CA.ts b/src/locale/fr_CA.ts new file mode 100644 index 00000000..6dac0116 --- /dev/null +++ b/src/locale/fr_CA.ts @@ -0,0 +1,2249 @@ + + + + + AboutDialog + + About + À propos + + + Authors + + + + License + + + + Lightweight WebKit-based web browser + + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + + Close + + + + About %1 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + + + + Languages: in order of preference: + + + + Move &Up + + + + Move &Down + + + + &Remove + + + + Add... + + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Ajouter un marque-page + + + Type a name for the bookmark, and choose where to keep it. + Entrer un nom pour le marque-page et choisissez où le conserver. + + + Url + + + + Title + Titre + + + Add Folder + Ajouter un dossier + + + + AutoFillDialog + + Form Passwords + + + + Remove + + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Ouvrir + + + Delete + Supprimer + + + New Folder + Nouveau dossier + + + Bookmarks + Marque-pages + + + &Remove + &Retirer + + + Add Folder + Ajouter un dossier + + + Open in New Tab + Ouvrir dans un nouvel onglet + + + Edit Name + + + + Edit Address + + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Erreur pendant le chargement des marque-pages à la ligne %1, colonne %2: +%3 + + + Toolbar Bookmarks + Barre d'outils Marque-pages + + + Menu + Menu + + + Open File + Ouvrir un fichier + + + Imported %1 + %1 a été importé + + + Save File + Enregistrer le fichier + + + %1 Bookmarks.xbel + + + + Export error + Erreur d'exportation + + + error saving bookmarks + Erreur de sauvegarde des marque-pages + + + Remove Bookmark + Retirer le marque-page + + + Insert Bookmark + Insérer un marque-page + + + Name Change + Changement de nom + + + Address Change + Changement d'adresse + + + Bookmarks Bar + + + + Bookmarks Menu + + + + Name Change + Undo bookmark title change + Changement de nom + + + Address Change + Undo bookmark url change + Changement d'adresse + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + + + + + BookmarksModel + + Title + Titre + + + Address + Adresse + + + + BookmarksToolBar + + Bookmark + Marque-page + + + Open + Ouvrir + + + Open in New &Tab + Ouvrir dans un nouvel &onglet + + + Remove + + + + Add Bookmark... + Ajouter un marque-page... + + + Add Folder... + + + + Bookmarks + Marque-pages + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Il y a %1 fenêtres et %2 onglets ouverts. +Voulez-vous tout de même quitter? + + + Restore failed + + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Fichier + + + &New Window + &Nouvelle fenêtre + + + &Open File... + &Ouvrir un fichier... + + + Open &Location... + Ouvrir une &adresse... + + + &Save As... + Enregistrer &sous... + + + &Import Bookmarks... + &Importer des marque-pages... + + + &Export Bookmarks... + &Exporter les marque-pages... + + + P&rint Preview... + Ape&rçu avant impression... + + + &Print... + Im&pression + + + Private &Browsing... + Navigation en mode privé + + + &Quit + &Quitter + + + &Edit + &Édition + + + &Undo + &Annuler + + + &Redo + &Refaire + + + Cu&t + &Couper + + + &Copy + Co&pier + + + &Paste + C&oller + + + &Find + &Rechercher + + + &Find Next + Rechercher le &suivant + + + &Find Previous + Rechercher le p&récédent + + + &Preferences + &Préférences + + + Ctrl+, + + + + &View + &Affichage + + + Ctrl+| + + + + Ctrl+/ + + + + &Stop + A&rrêter + + + Reload Page + &Recharger la page + + + &Make Text Bigger + Agrandir le texte + + + &Make Text Smaller + Réduire le texte + + + &Make Content Bigger + Agrandir la page + + + &Make Content Smaller + Réduire la page + + + &Make Text Normal + Réinitialiser la taile du texte + + + &Make Content Normal + Réinitialiser la taile de la page + + + Page S&ource + Code s&ource de la page + + + Ctrl+Alt+U + + + + &Full Screen + &Plein écran + + + Hi&story + &Historique + + + Back + Page précédente + + + Forward + Page suivante + + + Home + Page d'accueil + + + Restore Last Session + Restaurer la dernière session + + + &Bookmarks + &Marque-pages + + + Manage Bookmarks... + Gérer les marque-pages + + + Add Bookmark... + Ajouter un marque-page... + + + &Window + &Fenête + + + &Tools + &Outils + + + Web &Search + &Recherche Web + + + Ctrl+K + Web Search + + + + Enable Web &Inspector + Activer l'&inspecteur Web + + + &Help + &Aide + + + About &Qt + À propos de &Qt + + + About &Arora + À propos d'&Arora + + + Navigation + + + + Show Status Bar + Afficher la barre d'état + + + Hide Status Bar + Masquer la barre d'état + + + Show Toolbar + Afficher la barre d'outils + + + Hide Toolbar + Masquer la barre d'outils + + + Show Bookmarks bar + Afficher la barre de marque-pages + + + Hide Bookmarks bar + Masquer la barre de marque-pages + + + %1 - Arora + Page title and Browser name + + + + Open Web Resource + Ouvrir un fichier Web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Fichier Web (*.html *.htm *.svg *.png *.gif *.svgz);;Tous les fichiers (*.*) + + + Print Document + Imprimer le document + + + Are you sure you want to turn on private browsing? + Êtes-vous sûr de vouloir activer la navigation en mode privé? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. + <b>%1</b><br><br>Lorsque la navigation en mode privé est activée, certaines actions concernant votre vie privée seront désactivées:<ul><li> Les pages Web ne sont pas ajoutées à l'historique.</li><li> Les téléchargements sont automatiquement retiré de la fenêtre des téléchargements.</li><li> Les nouveaux fichiers témoins ne sont pas conservés et les fichiers témoins déjà existant ne sont pas accessibles.</li><li> Les icônes de sites Web et la session ne sont pas enregistrés.</li><li> Les recherches ne sont pas ajoutées dans la liste des recherches récentes.</li></ul>Jusqu'à la fermeture de l'écran, vous pouvez encore utiliser les boutons Page précédente et Page suivante. + + + Are you sure you want to close the window? There are %1 tabs open + Êtes-vous sûr de vouloir fermer cette fenêtre? Il y a %1 onglets ouverts. + + + Page Source of %1 + Code source de %1 + + + Web Inspector + Inspecteur Web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + L'inspecteur Web ne fonctionne que pour les pages qui ont été chargées après son activation. Voulez-vous recharcher toutes les pages? + + + Stop loading the current page + Arrêter le chargement de la page en cours + + + Reload the current page + Recharger la page en cours + + + Downloads + Téléchargements + + + &Clear Private Data + &Effacer l'information privée + + + Ctrl+Shift+Delete + Clear Private Data + + + + Find P&revious + + + + &Reload Page + + + + Show Bookmarks Bar + + + + Hide Bookmarks Bar + + + + Find Nex&t + + + + Show Menu Bar + + + + Switch application language + + + + Close Window + + + + Zoom &In + + + + Zoom &Normal + + + + Zoom &Out + + + + Zoom &Text Only + + + + Show All Bookmarks... + + + + Add Folder... + + + + About &%1 + About Browser + + + + Ctrl+Y + Download Manager + + + + Default + + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Effacer + + + + ClearPrivateData + + Clear Private Data + Effacer les informations privéess + + + Clear the following items: + Vider les items suivants: + + + &Browsing History + Historique de navigation + + + &Download History + Historique de téléchargement + + + &Search History + Historique de recherche + + + &Cookies + Fichiers témoins + + + C&ache + Mémoire cache + + + Website &Icons + Icônes de sites Web + + + Clear &Private Data + Effacer les informations privéess + + + &Cancel + &Annuler + + + C&ached Web Pages + + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + Paramètres + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + Site Web + + + Status + Statut + + + Allow + Permettre + + + Block + Bloquer + + + Allow For Session + Permettre pour la session + + + Rule + + + + + CookieModel + + Website + Site Web + + + Name + Nom + + + Path + Chemin d'accès + + + Secure + Sécure + + + Expires + Expire + + + Contents + Contenu + + + true + + + + false + + + + Session cookie + + + + + CookiesDialog + + Cookies + Fichiers témoins + + + &Remove + &Retirer + + + Remove &All Cookies + Retirer tous les fichiers témoins + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + Exceptions pour les fichiers témoins + + + New Exception + Nouvelle exception + + + Domain: + Domaine: + + + Block + Bloquer + + + Allow For Session + Permettre pour la session + + + Allow + Permettre + + + Exceptions + Exceptions + + + &Remove + Retirer + + + Remove &All + Tout retirer + + + + DownloadDialog + + Downloads + Téléchargements + + + Clean up + Vider la liste + + + 0 Items + 0 items + + + + DownloadItem + + Form + Formulaire + + + Ico + + + + Filename + Nom de fichier + + + Try Again + Essayer à nouveau + + + Stop + Interrompre + + + Open + Ouvrir + + + Save File + Enregistrer le fichier + + + Download canceled: %1 + Téléchargement annulé: %1 + + + Error opening save file: %1 + Erreur à l'ouverture du fichier destination: %1 + + + Error saving: %1 + Erreur à l'enregistrement: %1 + + + Network Error: %1 + Erreur réseau: %1 + + + seconds + secondes + + + minutes + minutes + + + - %4 %5 remaining + - %4 %5 restant + + + %1 of %2 (%3/sec) %4 + %1 de %2 (%3/sec) %4 + + + ? + + + + %1 of %2 - Stopped + %1 de %2 - Interrompu + + + bytes + octets + + + kB + kO + + + MB + MO + + + Error opening output file: %1 + + + + %1 of %2 (%3/sec) - %4 + + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + 1 Download + 1 téléchargement + + + %1 Downloads + %1 téléchargements + + + %n Download(s) + + + + + + + There are %1 downloads in progress +Do you want to quit anyway? + + + + %n minutes remaining + + + + + + + %n seconds remaining + + + + + + + bytes + octets + + + kB + kO + + + MB + MO + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + Ouvrir + + + Copy + Copier + + + Delete + Supprimer + + + History + Historique + + + &Remove + &Retirer + + + Remove &All + Tout retirer + + + + HistoryMenu + + Show All History + Montrer tout l'historique + + + Clear History + Effacer l'historique + + + Clear History... + + + + Do you want to clear the history? + + + + + HistoryModel + + Title + Titre + + + Address + Adresse + + + + HistoryTreeModel + + Earlier Today + Plutôt aujourd'hui + + + %1 items + %1 items + + + %n item(s) + + + + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + Choose language + + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Entrer le nombre d'utilisateur et le mot de passe pour "%1" sur %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Se brancher au serveur mandataire "%1" en utilisant:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Erreurs SSL: +%1 +%2 +Voulez-vous ignorer ses erreurs? + + + Do you want to accept all these certificates? + Voulez-vous accepter tous ces certificats? + + + - SSL Errors + + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Nom + + + + OpenSearchDialog + + Open File + Ouvrir un fichier + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Nom + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + Authentification requise + + + DUMMY ICON + + + + INTRO TEXT DUMMY + + + + Username: + Nom d'utilisateur: + + + Password: + Mot de passe: + + + + PlainTextEditSearch + + Not Found + Non trouvé + + + + ProxyDialog + + Proxy Authentication + Authentification au serveur mandataire + + + Connect to proxy + Se brancher au serveur mandataire + + + Username: + Nom d'utilisateur: + + + Password: + Mot de passe: + + + + QObject + + The file is not an XBEL version 1.0 file. + Ce fichier n'est pas un fichier XBEL version 1.0. + + + Unknown title + Titre inconnu + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Address + Adresse + + + + SearchBanner + + Form + Fromulaire + + + Done + Fermer + + + Highlight All + + + + + SearchLineEdit + + Search + Rechercher + + + + Settings + + Settings + Paramètres + + + General + Général + + + Home: + Page d'accueil: + + + Set to current page + Utiliser la page en cours + + + Remove history items: + Retirer les éléments de l'historique: + + + After one day + Après une journée + + + After one week + Après une semaine + + + After two weeks + Après 2 semaines + + + After one month + Après un mois + + + After one year + Après un an + + + Manually + Manuellement + + + Open links from applications: + Ouvrir les liens provenant d'applications: + + + In a tab in the current window + Dans un onglet dans la fenêtre en cours + + + In a new window + Dans une nouvelle fenêtre + + + Appearance + Apparence + + + Standard font: + Police par défaut: + + + Select... + Sélectionner... + + + Fixed-width font: + Police à espacement constant: + + + Privacy + Vie privée + + + Web Content + Contenu Web + + + Enable Plugins + Activer les plugiciels + + + Enable Javascript + Activer le Javascript + + + Cookies + Fichier témoins + + + Accept Cookies: + Accepter les fichiers témoins: + + + Always + Toujours + + + Never + Jamais + + + Only from sites you navigate to + Seulement des sites que vous visitez + + + Exceptions... + Exceptions... + + + Keep until: + Expiration: + + + They expire + Lorsqu'ils expirent + + + I exit the application + Lorsque je quitte l'application + + + At most 90 days + Au plus tard dans 90 jours + + + Cookies... + Fichiers témoins... + + + Proxy + Serveur mandataire + + + Enable proxy + Activer le serveur mandataire + + + Type: + Type: + + + Socks5 + + + + Host: + Hôte: + + + Port: + Port: + + + User Name: + Nom d'utilisateur: + + + Password: + Mot de passe: + + + Advanced + Avancé + + + Style Sheet: + Feuille de style: + + + Downloads + Téléchargements + + + Ask for a destination each time + Demander le dossier de destination à chaque fois + + + Use this destination: + Utiliser ce dossier + + + On startup: + + + + Show my home page + + + + Show a blank page + + + + Restore windows and tabs from last time + + + + On application exit + + + + Tabs + + + + Select tabs and windows as they are created + + + + Preferences + + + + Home Page: + + + + View Images + + + + Keep Cookies Until: + + + + Show only one close button instead of one for each tab + + + + Use proxy server + + + + Host name: + + + + Preferred languages for viewing webpages in: + + + + Block Popup Windows + + + + Opening links + + + + Links that want to open in a new window: + + + + In a new selected tab in the current window + + + + In a new tab in the current window + + + + In the current tab + + + + Http (Secure) + + + + Http (Transparent) + + + + Use ClickToFlash on flash plugins + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + + + + &Edit + &Édition + + + &Find + &Rechercher + + + &View + &Affichage + + + Source of Page %1 + + + + + TabBar + + New &Tab + Nouvel onglet + + + Duplicate Tab + Dupliquer l'onglet + + + &Close Tab + Fermer l'onglet + + + Close &Other Tabs + Fermer les autres onglets + + + Reload Tab + Recharger l'onglet + + + Reload All Tabs + Recharger tous les onglets + + + Show Tab Bar + + + + Hide Tab Bar + + + + + TabWidget + + New &Tab + Nouvel onglet + + + &Close Tab + Fermer l'onglet + + + Show Next Tab + Afficher l'onglet suivant + + + Show Previous Tab + Afficher l'onglet précédent + + + Recently Closed Tabs + Onglet récement fermés + + + (Untitled) + (Sans titre) + + + Do you really want to close this page? + Voulez-vous vraiment fermer cette page? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Vous avez modifié cette page et en fermant l'onglet, vous allez perdre les modifications. +Voulez-vous vraiment fermer cette page? + + + + Ctrl-] + + + + Ctrl-[ + + + + Untitled + + + + Saved Tabs + + + + Loading... + + + + Loading %1% (%2 %3)... + + + + Finished loading + + + + Failed to load + + + + Bookmark All Tabs + + + + + ToolbarSearch + + No Recent Searches + Aucune recherche récente + + + Recent Searches + Recherches récentes + + + Clear Recent Searches + Effacer les recherches récentes + + + Suggestions + + + + Add '%1' + + + + + WebPage + + Error loading page: %1 + Erreur au chargement de la page: %1 + + + When connecting to: %1. + + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + + + + If the address is correct, try checking the network connection. + + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Ouvrir dans une &nouvelle fenêtre + + + Open in New &Tab + Ouvrir dans un nouvel &onglet + + + Save Lin&k + Enregistrer le &lien + + + &Bookmark This Link + Marquer le lien + + + &Copy Link Location + Copier le lien + + + Open Image in New &Window + Ouvrir l'image dans une nouvelle fenêtre + + + Open Image in New &Tab + Ouvrir l'image dans un nouvel onglet + + + &Save Image + Enregistrer l'image + + + &Copy Image + Copier l'image + + + C&opy Image Location + Copier l'adresse de l'image + + + Loading... + + + + Search with... + + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Non trouvé + + + diff --git a/src/locale/fr_FR.ts b/src/locale/fr_FR.ts new file mode 100644 index 00000000..336f1a90 --- /dev/null +++ b/src/locale/fr_FR.ts @@ -0,0 +1,2079 @@ + + + + + AboutDialog + + Authors + Auteurs + + + License + Licence + + + Lightweight WebKit-based web browser + Navigateur web léger basé sur WebKit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Fermer + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + About %1 + À propos de %1 + + + WebKit version: %1 + WebKit version %1 + + + + AcceptLanguage + + Languages + Langues + + + Languages: in order of preference: + Langues dans l'ordre de préférence : + + + Move &Up + Mo&nter + + + Move &Down + Des&cendre + + + &Remove + Sup&primer + + + Add... + Ajouter... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Bloqué par la règle AdBlock: %1 + + + + AdBlockDialog + + Add Custom Rule + Ajouter une règle personnalisée + + + Learn more about writing rules... + En savoir plus sur l'écriture de règles... + + + Update Subscription + Mettre à jour l'abonnement + + + Browse Subscriptions... + Parcourir les abonnements... + + + Remove Subscription + Supprimer un abonnement + + + AdBlock Configuration + Configuration d'AdBlock + + + Enable AdBlock + Activer AdBlock + + + Action + Action + + + + AdBlockManager + + Custom Rules + Règles personnalisées + + + + AdBlockModel + + Rule + Règle + + + + AdBlockSchemeAccessHandler + + Subscribe? + S'abonner ? + + + Subscribe to this AdBlock subscription? +%1 + Souscrire à cet abonnement AdBlock ? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Ajouter un marque-page + + + Type a name for the bookmark, and choose where to keep it. + Entrez un nom pour le marque-page et choisissez où le conserver. + + + Url + URL + + + Title + Titre + + + Add Folder + Ajouter un dossier + + + + AutoFillDialog + + Form Passwords + Mots de passe + + + Remove + Supprimer + + + Remove All + Supprimer tout + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Voulez-vous sauvegarder ce mot de passe ?</b><br> Pour voir les mots de passe que vous avez sauvegardé et en supprimer, ouvrez le panneau Complétion automatique dans les préférences. + + + Never for this site + Jamais pour ce site + + + Not now + Pas maintenant + + + + AutoFillModel + + WebSite + Site web + + + User Name + Nom d'utilisateur + + + + BookmarksDialog + + Open + Ouvrir + + + Delete + Supprimer + + + New Folder + Nouveau dossier + + + Bookmarks + Marque-pages + + + &Remove + Supp&rimer + + + Add Folder + Ajouter un dossier + + + Open in New Tab + Ouvrir dans un nouvel onglet + + + Edit Name + Renommer + + + Edit Address + Modifier l'URL + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Erreur pendant le chargement des marque-pages à la ligne %1, colonne %2: +%3 + + + Toolbar Bookmarks + Barre des marque-pages + + + Menu + Menu + + + Open File + Ouvrir un fichier + + + Imported %1 + %1 a été importé + + + Save File + Enregistrer le fichier + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Erreur lors de l'exportation + + + error saving bookmarks + Erreur lors de la sauvegarde des marque-pages + + + Remove Bookmark + Supprimer le marque-page + + + Insert Bookmark + Insérer un marque-page + + + Bookmarks Bar + Barre des marque-pages + + + Bookmarks Menu + Menu des marque-pages + + + Name Change + Undo bookmark title change + Changement de nom + + + Address Change + Undo bookmark url change + Changement d'adresse + + + XBEL bookmarks + Marque-pages XBEL + + + HTML Netscape bookmarks + Marque-pages HTML Netscape + + + htmlToXBel tool required + L'outil htmlToXBel est requis + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + L'outil htmlToXBel, fourni avec Arora et nécessaire à l'importation de marque-pages HTML, n'est pas installé ou non disponible dans les chemins de recherche. + + + Loading Bookmark + Charger des marque-pages + + + Error when loading HTML bookmarks: %1 + + Erreur lors du chargement des marque-pages HTML:%1 + + + + + BookmarksMenu + + Open in Tabs + Ouvrir dans des onglets + + + + BookmarksModel + + Title + Titre + + + Address + Adresse + + + + BookmarksToolBar + + Open + Ouvrir + + + Open in New &Tab + Ouvrir dans un nouvel &onglet + + + Remove + Retirer + + + Add Bookmark... + Ajouter un marque-page... + + + Add Folder... + Ajouter un dossier... + + + Bookmarks + Marque-pages + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Il y a %1 fenêtres et %2 onglets ouverts. +Voulez-vous tout de même quitter? + + + Restore failed + Échec de la restauration + + + The saved session will not be restored because Arora crashed while trying to restore this session. + La session enregistrée ne sera pas restaurée car Arora s'est anormalement arrêté lors de la précedente tentative de restauration. + + + Arora crashed while trying to restore this session. Should I try again? + Arora s'est planté lors de la restauration de la session. Voulez-vous réessayer ? + + + + BrowserMainWindow + + &File + &Fichier + + + &New Window + &Nouvelle fenêtre + + + &Open File... + &Ouvrir un fichier... + + + Open &Location... + Ouvrir une &adresse... + + + &Save As... + Enregistrer &sous... + + + &Import Bookmarks... + &Importer des marque-pages... + + + &Export Bookmarks... + &Exporter les marque-pages... + + + P&rint Preview... + Ape&rçu avant impression... + + + &Print... + Im&pression... + + + Private &Browsing... + Navi&gation privée... + + + &Quit + &Quitter + + + &Edit + &Édition + + + &Undo + &Annuler + + + &Redo + &Refaire + + + Cu&t + &Couper + + + &Copy + Co&pier + + + &Paste + C&oller + + + &Find + &Rechercher + + + Ctrl+, + Ctrl+, + + + &View + &Affichage + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + &Stop + A&rrêter + + + Page S&ource + Code s&ource de la page + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Plein écran + + + Hi&story + &Historique + + + Back + Page précédente + + + Forward + Page suivante + + + Home + Page d'accueil + + + Restore Last Session + Restaurer la dernière session + + + &Bookmarks + &Marque-pages + + + Add Bookmark... + Ajouter un marque-page... + + + &Window + &Fenêtre + + + &Tools + &Outils + + + Web &Search + &Recherche Web + + + Ctrl+K + Web Search + Ctrl+K + + + Enable Web &Inspector + Activer l'&inspecteur Web + + + &Help + &Aide + + + About &Qt + À propos de &Qt + + + Navigation + Navigation + + + Show Status Bar + Afficher la barre d'état + + + Hide Status Bar + Masquer la barre d'état + + + Show Toolbar + Afficher la barre d'outils + + + Hide Toolbar + Masquer la barre d'outils + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Ouvrir un fichier Web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Fichier Web (*.html *.htm *.svg *.png *.gif *.svgz);;Tous les fichiers (*.*) + + + Print Document + Imprimer le document + + + Are you sure you want to turn on private browsing? + Êtes-vous sûr de vouloir activer la navigation privée? + + + Are you sure you want to close the window? There are %1 tabs open + Êtes-vous sûr de vouloir fermer cette fenêtre ? Il y a %1 onglets ouverts + + + Web Inspector + Inspecteur Web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + L'inspecteur Web ne fonctionne que pour les pages qui ont été chargées après son activation. Voulez-vous recharcher toutes les pages ? + + + Stop loading the current page + Arrêter le chargement de la page en cours + + + Reload the current page + Recharger la page en cours + + + Downloads + Téléchargements + + + &Clear Private Data + &Effacer les informations privées + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Suppr + + + Find P&revious + P&récédent + + + &Reload Page + &Actualiser la Page + + + Show Bookmarks Bar + Afficher la Barre des Marque-pages + + + Hide Bookmarks Bar + Cacher la Barre des Marque-pages + + + Find Nex&t + &Poursuivre la recherche + + + Prefere&nces... + Préféren&ces... + + + Show Menu Bar + Afficher la barre de menus + + + Switch application language + Changer la langue de l'application + + + Close Window + Fermer la fenêtre + + + Zoom &In + Zoom ava&nt + + + Zoom &Normal + Taille r&éelle + + + Zoom &Out + &Zoom arrière + + + Zoom &Text Only + Zoomer uniquement le &texte + + + Show All Bookmarks... + Afficher tous les marque-pages... + + + Add Folder... + Ajouter un dossier... + + + About &%1 + About Browser + À propos d'&%1 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Défault + + + Text Encoding + Encodage des caractères + + + Select &All + &Tout sélectionner + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Lorsque la navigation privée est activé, certaines actions qui concernent votre vie privée seront désactivés:<ul><li> Les sites consultés ne seront pas ajoutés à l'historique.</li><li> Les téléchargements seront automatiquement supprimés de la fenêtre des téléchargements.</li><li> Les nouveaux cookies ne seront pas stockés, les cookies actuels ne peuvent pas être accédés.</li><li> Les icônes des sites web ne seront pas stockés, la session ne sera pas sauvegardé.</li><li> Les recherches effectuées ne seront pas ajoutés aux recherches récentes.</li><li>Le cache sera désactivé.</li></ul>Vous pourrez toujours utiliser les boutons Précédent et Suivant pour naviguer dans les pages que vous avez ouvert, jusqu'à ce que vous fermiez la fenêtre. + + + Options... + Options... + + + Configure Search Engines... + Configurer les moteurs de recherche... + + + &Ad Block... + &AdBlock... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Lorsque la navigation privée est activée, certaines actions concernant votre vie privée seront désactivées: + + + Webpages are not added to the history. + Les pages visitées ne sont pas ajoutées à l'historique. + + + Items are automatically removed from the Downloads window. + Les téléchargements sont automatiquement supprimés du gestionnaire de téléchargement. + + + New cookies are not stored, current cookies can't be accessed. + Aucun nouveau cookie n'est stocké, les cookies actuels ne sont pas accessibles. + + + Site icons won't be stored. + Les icônes des sites web ne sont pas stockées. + + + Session won't be saved. + La session n'est pas sauvegardée. + + + Searches are not added to the pop-up menu in the search box. + Les recherches effectuées ne sont pas ajoutées dans la liste déroulante des recherches. + + + No new network cache is written to disk. + Le cache réseau est désactivé. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Vous pourrez toujours cliquer sur Précédent et Suivant pour naviguer dans les pages web ouvertes, jusqu'à ce que vous fermiez la fenêtre. + + + Private Browsing + Navigation privée + + + + ClearButton + + Clear + Effacer + + + + ClearPrivateData + + Clear Private Data + Effacer les informations privéess + + + Clear the following items: + Vider les objets suivants: + + + &Browsing History + Historique de &Navigation + + + &Download History + Historique de &Téléchargement + + + &Search History + Historique de &Recherche + + + &Cookies + &Cookies + + + Website &Icons + &Icônes de sites web + + + Clear &Private Data + Effacer les informations &Privées + + + &Cancel + &Annuler + + + C&ached Web Pages + C&ache Web + + + + ClickToFlash + + Load + Charger + + + Load All + Tout charger + + + Add %1 to Whitelist + Ajouter %1 à la liste blanche + + + Remove from Whitelist + Supprimer de la liste blanche + + + Settings + Paramètres + + + Load Flash + Charger Flash + + + + ClickToFlashSettings + + Whitelist sites + Sites en liste blanche + + + + CookieExceptionsModel + + Website + Site Web + + + Allow + Permettre + + + Block + Bloquer + + + Allow For Session + Permettre pour la session + + + Rule + Règle + + + + CookieModel + + Website + Site Web + + + Name + Nom + + + Path + Chemin d'accès + + + Secure + Sécurisé + + + Expires + Expire + + + Contents + Contenu + + + true + vrai + + + false + faux + + + Session cookie + Cookie de session + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Effacer + + + Remove &All Cookies + Effacer &Tous les Cookies + + + Add &Rule + Ajouter une &règle + + + + CookiesExceptionsDialog + + Cookie Exceptions + Exceptions pour les cookies + + + New Exception + Nouvelle exception + + + Domain: + Domaine: + + + Block + Bloquer + + + Allow For Session + Permettre pour la session + + + Allow + Permettre + + + Exceptions + Exceptions + + + &Remove + &Supp&rimer + + + Remove &All + &Tout supprimer + + + + DownloadDialog + + Downloads + Téléchargements + + + Clean up + Vider la liste + + + 0 Items + 0 téléchargements + + + + DownloadItem + + Ico + Ico + + + Filename + Nom de fichier + + + Try Again + Essayer à nouveau + + + Stop + Interrompre + + + Open + Ouvrir + + + Save File + Enregistrer le fichier + + + Download canceled: %1 + Téléchargement annulé: %1 + + + Error saving: %1 + Erreur à l'enregistrement: %1 + + + Network Error: %1 + Erreur réseau: %1 + + + ? + ? + + + %1 of %2 - Stopped + %1 de %2 - Interrompu + + + Error opening output file: %1 + Erreur à l'ouverture du fichier:   %1 + + + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/sec) - %4 + + + Download directory (%1) couldn't be created. + Le dossier de téléchargement (%1) n'a pas pu être créé. + + + + DownloadManager + + %n Download(s) + + %n téléchargement + %n téléchargements + + + + There are %1 downloads in progress +Do you want to quit anyway? + Il y a %1 téléchargements en cours +Voulez-vous tout de même quitter? + + + %n minutes remaining + + %n minute restante + %n minutes restantes + + + + %n seconds remaining + + %n seconde restante + %n secondes restantes + + + + bytes + octets + + + kB + ko + + + MB + Mo + + + GB + Go + + + + FileAccessReply + + No Error + Pas d'erreurs + + + Error opening: %1: No such file or directory + Erreur lors de l'ouverture de %1: le fichier ou répertoire n'existe pas + + + Unable to read %1 + Impossible de lire %1 + + + Contents of %1 + Contenu de %1 + + + %1 KB + %1 ko + + + + HistoryDialog + + Open + Ouvrir + + + Copy + Copier + + + Delete + Supprimer + + + History + Historique + + + &Remove + Supp&rimer + + + Remove &All + &Tout supprimer + + + + HistoryMenu + + Show All History + Montrer tout l'historique + + + Clear History + Effacer l'historique + + + Clear History... + Effacer l'historique... + + + Do you want to clear the history? + Voulez vous effacer l'historique? + + + + HistoryModel + + Title + Titre + + + Address + Adresse + + + + HistoryTreeModel + + Earlier Today + Plus tôt aujourd'hui + + + %n item(s) + + %n objet + %n objets + + + + + JavaScriptAroraObject + + Welcome to Arora! + Bienvenue sur Arora! + + + Arora Start + Démarrage de Arora + + + Search! + Recherche! + + + Search results provided by + Résultats de recherche fournis par + + + About Arora + A propos d'Arora + + + + LanguageManager + + Choose language + Choisissez la langue + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Vous pouvez utiliser une langue différente de<br>celle du système d'exploitation par défaut.</p><p>Veuillez choisir la langue à utiliser.</p> + + + No translation files are installed. + Aucun fichier de traduction n'est installé. + + + No translation files are installed at %1. + Aucun fichier de traduction n'est installé à %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Entrez le nom d'utilisateur et le mot de passe pour "%1" sur %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Se connecter au serveur mandataire "%1" en utilisant:</qt> + + + - SSL Errors + - Erreurs SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Erreurs SSL:<br/><br/>pour: <tt>%1</tt><ul><li>%2</li></ul> + +Voulez-vous ignorer ces erreurs?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificats: <br/>%1<br/>Voulez-vous accepter ces certificats?</qt> + + + Issuer: %1 + Émetteur: %1 + + + Not valid before: %1 + Invalide avant: %1 + + + Valid until: %1 + Valide jusqu'à: %1 + + + Alternate Names: + Noms alternatifs: + + + + OpenSearchDialog + + Open File + Ouvrir un fichier + + + OpenSearch + OpenSearch + + + Error + Erreur + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 n'est pas un descripteur OpenSearch 1.1 valide ou est déjà présent dans votre liste. + + + You must have at least one search engine in here. + Vous devez avoir au moins un moteur de recherche ici. + + + OpenSearch Manager + Gestionnaire OpenSearch + + + &Restore Defaults + &Réglages par défaut + + + &Delete + Supp&rimer + + + &Add + &Ajouter + + + &Close + &Fermer + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Description :</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Afficher des suggestions contextuels</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Liste de mots clés séparés par des virgules qui pourront être tapés dans la barre d'adresse, suivi des termes à rechercher avec ce moteur + + + Name + Nom + + + Keywords + Mots clés + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Voulez-vous ajouter le moteur suivant à votre liste de moteur de recherche ?<br /><br />Nom : %1<br />Recherche sur : %2 + + + + PasswordDialog + + Authentication Required + Authentification requise + + + DUMMY ICON + + + + INTRO TEXT DUMMY + + + + Username: + Nom d'utilisateur: + + + Password: + Mot de passe: + + + + PlainTextEditSearch + + Not Found + Aucun résultat + + + + ProxyDialog + + Proxy Authentication + Authentification du serveur mandataire + + + Connect to proxy + Connexion au serveur mandataire + + + Username: + Nom d'utilisateur: + + + Password: + Mot de passe: + + + + QObject + + The file is not an XBEL version 1.0 file. + Ce fichier n'est pas un fichier XBEL version 1.0. + + + Unknown title + Titre inconnu + + + The file is not an OpenSearch 1.1 file. + Ce fichier n'est pas un fichier OpenSearch 1.1. + + + + SearchBanner + + Done + Fermer + + + Highlight All + Surligner tous + + + + SearchLineEdit + + Search + Rechercher + + + + Settings + + General + Général + + + Set to current page + Utiliser la page en cours + + + Remove history items: + Retirer les éléments de l'historique: + + + After one day + Après une journée + + + After one week + Après une semaine + + + After two weeks + Après deux semaines + + + After one month + Après un mois + + + After one year + Après un an + + + Manually + Manuellement + + + Open links from applications: + Ouvrir les liens provenant d'applications: + + + In a new window + Dans une nouvelle fenêtre + + + Appearance + Apparence + + + Standard font: + Police par défaut: + + + Select... + Sélectionner... + + + Fixed-width font: + Police à espacement constant: + + + Privacy + Vie privée + + + Web Content + Contenu Web + + + Enable Plugins + Activer les Plugins + + + Enable Javascript + Activer le Javascript + + + Cookies + Cookies + + + Accept Cookies: + Accepter les cookies: + + + Always + Toujours + + + Never + Jamais + + + Only from sites you navigate to + Seulement des sites que vous visitez + + + Exceptions... + Exceptions... + + + They expire + Lorsqu'ils expirent + + + I exit the application + Lorsque je quitte l'application + + + At most 90 days + Au plus tard dans 90 jours + + + Cookies... + Cookies... + + + Proxy + Proxy + + + Type: + Type: + + + Socks5 + Socks5 + + + Port: + Port: + + + User Name: + Nom d'utilisateur: + + + Password: + Mot de passe: + + + Advanced + Avancé + + + Style Sheet: + Feuille de style: + + + Downloads + Téléchargements + + + Ask for a destination each time + Demander le dossier de destination à chaque fois + + + Use this destination: + Utiliser ce dossier: + + + On startup: + Au démarrage: + + + Show my home page + Afficher ma page d'accueil + + + Show a blank page + Afficher une page blanche + + + Restore windows and tabs from last time + Restaurer les fenêtres et les onglets de la session précédente + + + On application exit + A la sortie de l'application + + + Tabs + Onglets + + + Select tabs and windows as they are created + Sélectionner les onglets et les fenêtres comme ils ont été créés + + + Preferences + Préférences + + + Home Page: + Page d'accueil: + + + View Images + Afficher les images + + + Keep Cookies Until: + Garder les cookies jusqu'à : + + + Show only one close button instead of one for each tab + Afficher uniquement un bouton de fermeture à la place d'un sur chaque onglet + + + Use proxy server + Utiliser le serveur proxy + + + Host name: + Nom de l'hôte: + + + Preferred languages for viewing webpages in: + Langues préférées pour visualiser les pages web: + + + Block Popup Windows + Bloquer les fenêtres popup + + + Opening links + Ouvrir les liens + + + Links that want to open in a new window: + Liens voulant s'ouvrir dans une nouvelle fenêtre: + + + In a new selected tab in the current window + Dans un nouvel onglet au premier plan dans la fenêtre courante + + + In a new tab in the current window + Dans un nouvel onglet en arrière-plan dans la fenêtre courante + + + In the current tab + Dans l'onglet courant + + + Http (Secure) + Http (Sécurisé) + + + Http (Transparent) + Http (Transparent) + + + Use ClickToFlash on flash plugins + Utiliser ClickToFlash pour les plugins flash + + + Filter Tracking Cookies + Filtrer les cookies traceurs + + + Confirm when closing multiple tabs or windows + Demander confirmation lors de la fermeture de plusieurs onglets ou fenêtres + + + Quit the application when last tab is closed + Quitter l'application quand le dernier onglet est fermé + + + Enable network cache + Activer le cache réseau + + + Maximum Size: + Taille maximum : + + + MB + Mo + + + Use the default search engine as fallback when the URL given by the user is invalid + Utiliser le moteur de recherche par défaut en secours quand l'URL donnée par l'utilisateur est invalide + + + Choose Directory... + Choisir le répertoire... + + + A cookie session ends: + Un cookie de session se termine: + + + When I exit the application + Quand je ferme l'application + + + 1 day + Après 1 jour + + + 2 days + Après 2 jours + + + 3 days + Après 3 jours + + + 7 days + Après 7 jours + + + 30 days + Après 30 jours + + + AutoFill + Complétion automatique + + + AutoFill web forms: + Formulaires complétés automatiquement: + + + User names and passwords + Noms d'utilisateur et mots de passe + + + Edit... + Édition... + + + Browse... + Parcourir... + + + + SettingsDialog + + Restart required + Redémarrage requis + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + La configuration du cache réseau a changée. Pour que ces changements soient pris en compte, le navigateur doit être redémarrer. + + + Choose Directory + Choisir le répertoire + + + Choose CSS File + Choisir le fichier CSS + + + + SourceViewer + + Loading... + Chargement... + + + &Edit + &Édition + + + &Find + &Rechercher + + + &View + &Affichage + + + &Wrap lines + Retours à la ligne &statiques + + + Source of Page %1 + Source de la page %1 + + + + TabBar + + Duplicate Tab + Dupliquer l'onglet + + + &Close Tab + &Fermer l'onglet + + + Close &Other Tabs + Fermer les &autres onglets + + + Reload Tab + Recharger l'onglet + + + Reload All Tabs + Recharger tous les onglets + + + Show Tab Bar + Afficher la barre d'onglets + + + Hide Tab Bar + Cacher la barre d'onglets + + + + TabWidget + + New &Tab + Nouvel ongle&t + + + &Close Tab + &Fermer l'onglet + + + Show Next Tab + Afficher l'onglet suivant + + + Show Previous Tab + Afficher l'onglet précédent + + + Recently Closed Tabs + Onglets récemment fermés + + + Do you really want to close this page? + Voulez-vous vraiment fermer cette page? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Vous avez modifié cette page et en fermant l'onglet, vous allez perdre les modifications. +Voulez-vous vraiment fermer cette page? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Untitled + Sans titre + + + Saved Tabs + Onglets enregistrés + + + Loading... + Chargement... + + + Loading %1% (%2 %3)... + Chargement à %1% (%2 %3)... + + + Finished loading + Terminé + + + Failed to load + Impossible de charger la page + + + Bookmark All Tabs + Ajouter tous les onglets aux marque-pages + + + + ToolbarSearch + + No Recent Searches + Aucune recherche récente + + + Recent Searches + Recherches récentes + + + Suggestions + Suggestions + + + Add '%1' + Ajouter '%1' + + + Configure Search Engines... + Configurer les moteurs de recherche... + + + Clear Recent Searches + Effacer les recherches récentes + + + + WebPage + + Error loading page: %1 + Erreur au chargement de la page: %1 + + + When connecting to: %1. + Durant la connection à: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Vérifiez que vous n'avez pas commis d'erreurs dans l'adresse tel que <b>ww</b>.arora-browser.org à la place de <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Si votre ordinateur ou votre réseau est protégé par un pare-feu ou un proxy, vérifiez que votre navigateur à le droit d'accéder au réseau. + + + If the address is correct, try checking the network connection. + Si l'adresse est correcte, vérifiez votre connexion au réseau. + + + Resending POST request + Renvoi d'une requête POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Afin d'afficher le site, la requête ainsi que toutes les données doivent être réenvoyés, ce qui peut conduire à un comportement innatendu du site, par exemple la même action peut être exécuté une nouvelle fois. Continuer quand même ? + + + + WebView + + Open in New &Window + Ouvrir dans une &nouvelle fenêtre + + + Open in New &Tab + Ouvrir dans un nouvel &onglet + + + Save Lin&k + Enregistrer le &lien + + + &Bookmark This Link + &Marque-page sur ce lien + + + &Copy Link Location + &Copier l'adresse du lien + + + Open Image in New &Window + Ouvrir l'image dans une nouvelle &fenêtre + + + Open Image in New &Tab + Ouvrir l'image dans un nouvel &onglet + + + &Save Image + Enregi&strer l'image + + + &Copy Image + &Copier l'image + + + C&opy Image Location + C&opier l'adresse de l'image + + + Loading... + Chargement... + + + Search with... + Chercher avec... + + + Add to the toolbar search + Ajouter à la barre de recherche + + + Method not supported + Méthode non supportée + + + %1 method is not supported. + La méthode %1 n'est pas supporté. + + + Search engine + Moteur de recherche + + + Choose the desired search engine + Choisir le moteur de recherche voulu + + + Engine name + Nom du moteur + + + Type in a name for the engine + Insérer un nom pour le moteur + + + Block Image + Bloquer l'image + + + + WebViewSearch + + Not Found + Non trouvé + + + diff --git a/src/locale/gl.ts b/src/locale/gl.ts new file mode 100644 index 00000000..0b706d80 --- /dev/null +++ b/src/locale/gl.ts @@ -0,0 +1,2209 @@ + + + AboutDialog + + Lightweight WebKit-based web browser + Navegador lixeiro baseado en WebKit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Authors + Autores + + + License + Licenza + + + Close + Pechar + + + About %1 + Acerca de %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">(new line) +<html><head><meta name="qrichtext" content="1" /><style type="text/css">(new line) +p, li { white-space: pre-wrap; }(new line) +</style></head><body style="font-size:9pt;">(new line) +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + WebKit versión: %1 + + + + AcceptLanguage + + Languages + Idiomas + + + Languages: in order of preference: + Idiomas: en orde de preferencia: + + + Move &Up + Mover cara &arriba + + + Move &Down + Mover cara a&baixo + + + &Remove + &Eliminar + + + Add... + Engadir... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Bloqueado pola regra AdBlock: %1 + + + + AdBlockDialog + + Add Custom Rule + Engadir regra personalizada + + + Learn more about writing rules... + Aprender máis de como escribir regras... + + + Update Subscription + Actualizar a subscripción + + + Browse Subscriptions... + Examinar as subscripcións... + + + Remove Subscription + Eliminar a subscripción + + + AdBlock Configuration + Configuración de AdBlock + + + Enable AdBlock + Activar AdBlock + + + Action + Acción + + + + AdBlockManager + + Custom Rules + Regras personalizadas + + + + AdBlockModel + + Rule + Regra + + + + AdBlockSchemeAccessHandler + + Subscribe? + Subscribir? + + + Subscribe to this AdBlock subscription? +%1 + Aceptar esta subscripción AdBlock? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Engadir marcador + + + Type a name for the bookmark, and choose where to keep it. + Introduza un nome para o marcador e elixa onde gardalo. + + + Url + Url + + + Title + Título + + + Add Folder + Engadir cartafol + + + + AutoFillDialog + + Form Passwords + Formulario de contrasinais + + + Remove + Eliminar + + + Remove All + Eliminar todo + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Desexa gardar este contrasinal?</b><br> Para revisar e eliminar os contrasinais gardados, abra o panel Autocompletar de Preferencias. + + + Never for this site + Nunca para este sitio + + + Not now + Agora non + + + + AutoFillModel + + WebSite + Páxina web + + + User Name + Nome de usuario + + + + BookmarksDialog + + Bookmarks + Marcadores + + + &Remove + &Eliminar + + + Add Folder + Engadir cartafol + + + Open + Abrir + + + Open in New Tab + Abrir nunha lingüeta nova + + + Delete + Borrar + + + New Folder + Novo cartafol + + + Edit Name + Editar nome + + + Edit Address + Editar enderezo + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Atopouse un erro cargando os marcadores na liña %1, columna %2: +%3 + + + Toolbar Bookmarks + Barra de marcadores + + + Menu + Menú + + + Open File + Abrir ficheiro + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importado %1 + + + Save File + Gardar ficheiro + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Atopouse un erro durante a exportación + + + error saving bookmarks + atopouse un erro gardando os marcadores + + + Remove Bookmark + Eliminar marcador + + + Insert Bookmark + Inserir marcador + + + Bookmarks Bar + Barra de marcadores + + + Bookmarks Menu + Menú de marcadores + + + Error when loading html bookmarks: %1 + + Atopouse un erro mentras se cargaban os marcadores html: %1 + + + + XBEL + XBEL + + + Name Change + Undo bookmark title change + Cambiar o nome + + + Address Change + Undo bookmark url change + Cambiar o enderezo + + + XBEL bookmarks + Marcadores XBEL + + + HTML Netscape bookmarks + Marcadores HTML de Netscape + + + htmlToXBel tool required + Precisase a ferramenta htmlToXBel + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + A ferramenta htmlToXBel , que se inclue con Arora e é precisa para importar os marcadores HTML, non está instalada ou non está dispoñible no camiño de buscas. + + + Loading Bookmark + Cargando marcador + + + Error when loading HTML bookmarks: %1 + + Atopouse un erro mentras se cargaban os marcadores HTML: %1 + + + + + BookmarksMenu + + Open in Tabs + Abrir en lingüetas + + + + BookmarksModel + + Title + Título + + + Address + Enderezo + + + + BookmarksToolBar + + Bookmark + Marcador + + + Open + Abrir + + + Open in New &Tab + Abrir nunha lingüe&ta nova + + + Remove + Eliminar + + + Add Bookmark... + Engadir marcador... + + + Add Folder... + Engadir cartafol... + + + Bookmarks + Marcadores + + + + BrowserApplication + + (Change: %1 %2) + (Cambio: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Hai %1 xanela e %2 lingüetas abertas +Desexa saír de todos os xeitos? + + + Restore failed + Fallou a recuperación + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Non se puido recuperar a sesión gardada xaque Arora fallou a última vez que se recuperou . + + + Arora crashed while trying to restore this session. Should I try again? + Arora pechouse inesperadamente mentres tentaba recuperar esta sesión. Tentalo de novo? + + + + BrowserMainWindow + + &File + &Ficheiro + + + &New Window + &Nova xanela + + + &Open File... + &Abrir ficheiro... + + + Open &Location... + Abrir &ubicación... + + + &Save As... + &Gardar como... + + + &Import Bookmarks... + &Importar marcadores... + + + &Export Bookmarks... + &Exportar marcadores... + + + P&rint Preview... + Vista p&revia de impresión... + + + &Print... + I&mprimir... + + + Private &Browsing... + &Navegación privada... + + + &Quit + &Saír + + + &Edit + &Editar + + + &Undo + &Desfacer + + + &Redo + &Refacer + + + Cu&t + Cor&tar + + + &Copy + &Copiar + + + &Paste + &pegar + + + &Find + &Buscar + + + Find Nex&t + Buscar &seguinte + + + Find P&revious + Buscar &anterior + + + Prefere&nces... + &Preferencias... + + + Ctrl+, + Ctrl+, + + + &View + &Ver + + + Show Menu Bar + Amosar barra de menús + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Maiús+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Deter + + + &Reload Page + &Recargar páxina + + + Page S&ource + Código f&onte + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Pantalla &completa + + + Hi&story + &Historial + + + Back + Atras + + + Forward + Adiante + + + Home + Inicio + + + Restore Last Session + Recuperar última sesión + + + &Bookmarks + &Marcadores + + + Add Bookmark... + Engadir marcador... + + + &Window + &Xanela + + + &Tools + &Ferramentas + + + Web &Search + &Busca na web + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Limpar datos privados + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Maiús+Supr + + + Enable Web &Inspector + Activar o &inspector da web + + + &Help + A&xuda + + + About &Qt + Acerca de &Qt + + + Navigation + Navegación + + + Show Status Bar + Amosar a barra de estado + + + Hide Status Bar + Agochar a barra de estado + + + Show Toolbar + Amosar a barra de ferramentas + + + Hide Toolbar + Agochar a barra de ferramentas + + + Show Bookmarks Bar + Amosar a barra de marcadores + + + Hide Bookmarks Bar + Agochar a barra de marcadores + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Abrir os recursos da web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Recursos da web (*.html *.htm *.svg *.png *.gif *.svgz);;Todos os ficheiros (*.*) + + + Print Document + Imprimir documentación + + + Are you sure you want to turn on private browsing? + Está seguro de querer activar a navegación privada? + + + Are you sure you want to close the window? There are %1 tabs open + Está seguro de que quere pechar a xanela? Hai %1 lingüetas abertas + + + Web Inspector + Inspector da web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + O inspectorda web só funcionará correctamente coas páxinas que se carguen despois de activalo. +Desexa recargar todas as páxinas? + + + Stop loading the current page + Deter a carga da páxina actual + + + Reload the current page + Recargar a páxina actual + + + Downloads + Descargas + + + Show &Network Monitor + Amosar mo&nitor de rede + + + Switch application language + Cambiar o idioma do aplicativo + + + Close Window + Pechar a xanela + + + Zoom &In + Zoom &aumentar + + + Zoom &Normal + Zoom &normal + + + Zoom &Out + Zoom &reducir + + + Zoom &Text Only + Zoom &só texto + + + About &%1 + About Browser + Acerca de &%1 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Show All Bookmarks... + Amosar todos os marcadores... + + + Add Folder... + Engadir cartafol... + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Cando se activa a navegación privada, algunhas accións relativas a súa intimidade han de ser desactivadas:<ul><li> As páxinas web non serán engadidas ao historial.</li><li> Hanse eliminar automaticamente os elementos no xestor de descargas.</li><li> Non se almacenarán as novas cookies e as actuais non estarán accesibles.</li><li> As iconas dos sitios non han ser gardadas e tampouco as sesións.</li><li> As buscas non serán engadidas no menú emerxente da caixa de buscas.</li></ul>Poderá facer clic nos botóns Adiante e Atrás para volver as páxinas visitadas, pero só mentres non peche a ventá. + + + Default + Predeterminado + + + Text Encoding + Codificación do texto + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> Network cache is disabled.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Cando se activa a navegación privada, algunhas accións relativas a súa intimidade han de ser desactivadas:<ul><li> As páxinas web non serán engadidas ao historial.</li><li> Hanse eliminar automaticamente os elementos no xestor de descargas.</li><li> Non se almacenarán as novas cookies e as actuais non estarán accesibles.</li><li> As iconas dos sitios non han ser gardadas e tampouco as sesións.</li><li>Desactivase a caché de rede.</li></ul>Poderá facer clic nos botóns Adiante e Atrás para volver as páxinas visitadas, pero só mentres non peche a ventá. + + + Select &All + Seleccionar &todo + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Cando se activa a navegación privada, algunhas accións relativas a súa intimidade han de ser desactivadas:<ul><li> As páxinas web non serán engadidas ao historial.</li><li> Hanse eliminar automaticamente os elementos no xestor de descargas.</li><li> Non se almacenarán as novas cookies e as actuais non estarán accesibles.</li><li> As iconas dos sitios non han ser gardadas e tampouco as sesións.</li><li> A nova caché de rede non se vai grabar no disco.</li></ul>Poderá facer clic nos botóns Adiante e Atrás para volver as páxinas visitadas, pero só mentres non peche a ventá. + + + Options... + Opcións... + + + Configure Search Engines... + Configurar os motores de busca... + + + &Ad Block... + &Bloquear publicidade... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Cuando se activa a navegación privada, desactivaránse algunhas accións relacionadas coa súa intimidade: + + + Webpages are not added to the history. + As páxinas web no serán engadidas ao historial. + + + Items are automatically removed from the Downloads window. + Eliminaránse automaticamente os elementos da xanela de descargas. + + + New cookies are not stored, current cookies can't be accessed. + Non se gardarán as novas cookies, no se poderá acceder as cookies actuais. + + + Site icons won't be stored. + Non se gardarán as iconas da páxina. + + + Session won't be saved. + Non se gardará a sesión. + + + Searches are not added to the pop-up menu in the search box. + As buscas non serán engadidas ao menú emerxente no cadro de buscas. + + + No new network cache is written to disk. + No se escribirá no disco a nova caché da rede. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Até que se peche a xanela, vostede poderá facer clic nos botóns Atrás e Adiante para volver ás páxinas web que teña aberto. + + + Private Browsing + Navegación privada + + + + ClearButton + + Clear + Limpar + + + + ClearPrivateData + + Clear Private Data + Limpar datos privados + + + Clear the following items: + Limpar os seguintes elementos: + + + &Browsing History + Historial de &navegación + + + &Download History + Historial de &descargas + + + &Search History + Historial de &buscas + + + &Cookies + &Cookies + + + C&ached Web Pages + C&Aché de páxinas visitadas + + + Website &Icons + &Iconas das páxinas web + + + Clear &Private Data + &Limpar datos privados + + + &Cancel + &Cancelar + + + + ClickToFlash + + Load + Cargar + + + Load All + Cargar todo + + + Add %1 to Whitelist + Engadir %1 á lista branca + + + Remove from Whitelist + Quitar da lista branca + + + Settings + Axustes + + + Load Flash + Cargar «Flash» + + + + ClickToFlashSettings + + Whitelist sites + Lista branca de sitios + + + + CookieExceptionsModel + + Website + Sitio web + + + Rule + Regra + + + Allow + Permitir + + + Block + Bloquear + + + Allow For Session + Permitir só para esta sesión + + + + CookieModel + + Website + Sitio web + + + Name + Nome + + + Path + Ruta + + + Secure + Seguro + + + Expires + Caduca + + + Contents + Contido + + + true + verdadeiro + + + false + falso + + + Session cookie + Cookie da sesión + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Eliminar + + + Remove &All Cookies + Eliminar &todas as cookies + + + Add &Rule + Engadir &regra + + + + CookiesExceptionsDialog + + Cookie Exceptions + Cookies exentas + + + New Exception + Nova excepción + + + Domain: + Dominio: + + + Block + Bloquear + + + Allow For Session + Permitir só para esta sesión + + + Allow + Permitir + + + Exceptions + Excepcións + + + &Remove + &Eliminar + + + Remove &All + Eliminar &todas + + + + DownloadDialog + + Downloads + Descargas + + + Clean up + Baleirar + + + 0 Items + 0 Elementos + + + + DownloadItem + + Form + Formulario + + + Ico + Icona + + + Filename + Nome de ficheiro + + + Try Again + Tentar de novo + + + Stop + Deter + + + Open + Abrir + + + Save File + Gardar ficheiro + + + Download canceled: %1 + Descarga cancelada: %1 + + + Error opening output file: %1 + Atopouse un erro ao abrir o ficheiro de sída: %1 + + + Error saving: %1 + Atopouse un erro gardando: %1 + + + Network Error: %1 + Atopouse un erro na rede: %1 + + + ? + ? + + + %1 of %2 - Stopped + %1 de %2 - Detida + + + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/segs.) - %4 + + + Download directory (%1) couldn't be created. + O directorio de descarga (%1)non se pode crear. + + + + DownloadManager + + %n Download(s) + %n Descarga(s) + + + + + + + + + There are %1 downloads in progress +Do you want to quit anyway? + Hai %1 descargas en proceso +Saír de todos os xeitos? + + + %n minutes remaining + Faltan %n minutos + + + + + + + %n seconds remaining + Faltan %n segundos + + + + + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Sen erro + + + Error opening: %1: No such file or directory + Atopouse un erro ao abrir: %1: Non existe o ficheiro ou directorio + + + Unable to read %1 + Non se pode ler %1 + + + Contents of %1 + Contido de %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + History + Historial + + + &Remove + &Eliminar + + + Remove &All + Eliminar &todo + + + Open + Abrir + + + Copy + Copiar + + + Delete + Borar + + + + HistoryMenu + + Show All History + Amosar todo o historial + + + Clear History... + Limpar historial... + + + Clear History + Limpar historial + + + Do you want to clear the history? + Desexa limpar todo o historial? + + + + HistoryModel + + Title + Título + + + Address + Enderezo + + + + HistoryTreeModel + + Earlier Today + No día de hoxe + + + %n item(s) + %n elemento(s) + + + + + + + + + JavaScriptAroraObject + + Welcome to Arora! + Benvido a Arora! + + + Arora Start + Iniciar Arora + + + Search! + Busca! + + + Search results provided by + Resultados da busca fornecidos por + + + About Arora + Acerca de Arora + + + + LanguageManager + + Choose language + Elixir idioma + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Pode executarse cun idioma distinto<br>ao predeterminado do sistema operativo.</p><p>Por favor, elixa o idioma que desexe empregar</p> + + + No translation files are installed. + Os ficheiros de tradución non están instalados. + + + No translation files are installed at %1. + Non hai ficheiros de tradución instalados en %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Introduza un nome de usuario e un contrasinal para "%1" at %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Conectar ao proxy "%1" usando:</qt> + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Erros SSL:<br/><br/>para: <tt>%1</tt><ul><li>%2</li></ul> + +Ignorar estes erros?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificados:<br/>%1<br/>Aceptar todos estes certificados?</qt> + + + - SSL Errors + - Erros SSL + + + Issuer: %1 + Emisor: %1 + + + Not valid before: %1 + Non é válido antes de: %1 + + + Valid until: %1 + Válido até o: %1 + + + Alternate Names: + Nomes alternativos: + + + + NetworkMonitor + + Name + Nome + + + Value + Valor + + + + NetworkMonitorDialog + + Network Monitor + Monitor de rede + + + Network Requests + Solicitudes de rede + + + Request Headers + Cabeceiras das solicitudes + + + Response Headers + Cabeceiras de resposta + + + &Remove + &Eliminar + + + Remove &All Requests + Eliminar &tódalas solicitudes + + + + OpenSearchDialog + + Open File + Abrir ficheiro + + + OpenSearch + OpenSearch + + + Error + Erro + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 non é unha descrición correcta para OpenSearch 1.1 ou xa está na súa lista. + + + You must have at least one search engine in here. + Debe ter aquí polo menos un motor de busca. + + + OpenSearch Manager + Xestor OpenSearch + + + &Restore Defaults + &Restaurar predeterminados + + + &Delete + &Borrar + + + &Add + &Engadir + + + &Close + &Pechar + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descrición:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + Fornece suxestións contextuais + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Lista separada por comas das palabras clave que se poden introducir na barra seguidas dos termos de busca para buscar con este motor + + + Name + Nome + + + Keywords + Palabras clave + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Quere engadir o seguinte motor á súa lista de motores de busca?<br /><br />Nome: %1<br />Buscas en: %2 + + + + PasswordDialog + + Authentication Required + Precisa autenticarse + + + DUMMY ICON + ICONA SIMULADA + + + INTRO TEXT DUMMY + INTRODUZA TEXTO SIMULADO + + + Username: + Nome de usuario: + + + Password: + Contrasinal: + + + + PlainTextEditSearch + + Not Found + Non atopado + + + + ProxyDialog + + Proxy Authentication + Autenticación no proxi + + + Connect to proxy + Conectar ao proxy + + + Username: + Nome de usuario: + + + Password: + Contrasinal: + + + + QObject + + The file is not an XBEL version 1.0 file. + OP ficheiro non é un ficheiro XBEL versión 1.0. + + + Unknown title + Título descoñecido + + + The file is not an OpenSearch 1.1 file. + Este ficheiro non é un ficheiro OpenSearch 1.1. + + + + RequestModel + + Redirect: %1 + Redirixe a: %1 + + + Method + Método + + + Address + Enderezo + + + Response + Resposta + + + Length + Lonxitude + + + Content Type + Tipo de contido + + + Info + Información + + + + SearchBanner + + Form + Formulario + + + Done + Feito + + + Highlight All + Destacar todo + + + + SearchLineEdit + + Search + Buscar + + + + Settings + + Preferences + Preferencias + + + General + Xeral + + + On startup: + No inicio: + + + Show my home page + Amosar a miña páxina de inicio + + + Show a blank page + Amosar a páxina en branco + + + Restore windows and tabs from last time + Recuperar as xanelas e lingüetas da última sexión + + + Home Page: + Páxina de inicio: + + + Set to current page + Páxina actual como predeterminada + + + Remove history items: + Eliminar os elementos do historial: + + + After one day + Despois de un día + + + After one week + Despois de unha semana + + + After two weeks + Despois de dúas semanas + + + After one month + Despois de un mes + + + After one year + Despois de un ano + + + Manually + Manualmente + + + On application exit + Ao sair do aplicativo + + + Open links from applications: + Abrir ligazóns de aplicativos: + + + In a new window + Nunha nova xanela + + + Downloads + Descargas + + + Ask for a destination each time + Preguntar en cada caso + + + Use this destination: + Usar este destino: + + + Appearance + Aparencia + + + Standard font: + Tipo de letra estándar: + + + Times 16 + Times 16 + + + Select... + Seleccionar... + + + Fixed-width font: + Tipo de letra de anchura fixa: + + + Privacy + Privacidade + + + Web Content + Contido da web + + + Enable Plugins + Activar extensión + + + Enable Javascript + Activar Javascript + + + View Images + Ver imaxes + + + Cookies + Cookies + + + Accept Cookies: + Aceitar cookies: + + + Always + Sempre + + + Never + Nunca + + + Only from sites you navigate to + Só dende os sitios que se visiten + + + Exceptions... + Excepcións... + + + Keep Cookies Until: + Manter até que: + + + They expire + Caduquen + + + I exit the application + Se saia do aplicativo + + + At most 90 days + Un máximo de 90 días + + + Cookies... + Cookies... + + + Tabs + Lingüetas + + + Select tabs and windows as they are created + Seleccionar lingüetas e xanelas ao ser creadas + + + Proxy + Proxy + + + Use proxy server + Usar servidor proxy + + + Type: + Tipo: + + + Socks5 + Socks5 + + + Host name: + Nome da máquina: + + + Port: + Porto: + + + User Name: + Nome de usuario: + + + Password: + Contrasinal: + + + Advanced + Avanzado + + + Style Sheet: + Estilo de folla: + + + Show only one close button instead of one for each tab + Amosar só un botón de peche no canto de un para cada lingüeta + + + Block Popup Windows + Bloquear xanelas emerxentes + + + Opening links + Abrindo ligazóns + + + Links that want to open in a new window: + Ligazóns que desexa abrir nunha nova xanela: + + + In a new selected tab in the current window + Na lingüeta seleccionada na xanela actual + + + In a new tab in the current window + Nunha nova lingüeta na xanela actual + + + In the current tab + Na lingüeta actual + + + Http (Secure) + Http (Seguro) + + + Http (Transparent) + Http (Transparente) + + + Preferred languages for viewing webpages in: + Idiomas preferidos para ver páxinas web: + + + Use ClickToFlash on flash plugins + Use ClickToFlash nas estensións flash + + + Filter Tracking Cookies + Filtrar as cookies de seguimento + + + Confirm when closing multiple tabs or windows + Pedir confirmación cando se pechen multiples lingüetas ou xanelas + + + Quit the application when last tab is closed + Sair do aplicativo cando se peche a última lingüeta + + + Enable network cache + Activar a caché de rede + + + Maximum Size: + Tamaño máximo: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Use o motor de buscas predeterminado como último recurso cando a URL dada polo usuario non é correcta + + + Choose Directory... + Escoller directorio... + + + A cookie session ends: + Unha cookie de sesión caduca: + + + When I exit the application + Cando saia do aplicativo + + + 1 day + 1 día + + + 2 days + 2 días + + + 3 days + 3 días + + + 7 days + 7 días + + + 30 days + 30 días + + + AutoFill + Autocompletado + + + AutoFill web forms: + Autocompletado de formularios web: + + + User names and passwords + Nomes de usuario e contrasinais + + + Edit... + Editar... + + + Browse... + Examinar... + + + + SettingsDialog + + Restart required + É preciso reiniciar + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + A configuración da caché de rede cambiou. A fin de que poida ser tida en conta, o navegador ten de ser reiniciado. + + + Choose Directory + Escoller directorio + + + Choose CSS File + Escoller ficheiro CSS + + + + SourceViewer + + Loading... + Cargando... + + + &Edit + &Editar + + + &Find + &Buscar + + + &View + &Ver + + + &Wrap lines + A&xustar as liñas + + + Source of Page + Código fonte da páxina + + + Source of Page %1 + Código fonte da páxina %1 + + + + TabBar + + Show Tab Bar + Amosar barra de lingüetas + + + Hide Tab Bar + Agochar barra de lingüetas + + + Duplicate Tab + Duplicar a lingüeta + + + &Close Tab + &Pechar a lingüeta + + + Close &Other Tabs + Pechar as &outras lingüetas + + + Reload Tab + Recargar lingüeta + + + Reload All Tabs + Recargar todas as lingüetas + + + + TabWidget + + New &Tab + Nova lingüe&ta + + + &Close Tab + &Pechar a lingüeta + + + Show Next Tab + Amosar a seguinte lingüeta + + + Show Previous Tab + Amosar a lingüeta anterior + + + Recently Closed Tabs + Lingüetas abertas recentemente + + + Untitled + Sin título + + + Do you really want to close this page? + Desexa realmente pechar esta páxina? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Esta páxina foi modificada e si a pecha perderá os cambios. +Está seguro de que quere pechar esta páxina? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Lingüetas gardadas + + + Loading... + Cargando... + + + Loading %1% (%2 %3)... + Cargando %1% (%2 %3)... + + + Finished loading + rematou a descarga + + + Failed to load + Atopouse un fallo duranre a descarga + + + Bookmark All Tabs + Todas as lingüetas a marcadores + + + + ToolbarSearch + + No Recent Searches + Non hai buscas recentes + + + Recent Searches + Buscas recentes + + + Clear Recent Searches + Limpar buscas recentes + + + Suggestions + Suxestions + + + Add '%1' + Engadir «%1» + + + Configure Search Engines... + Configurar motores de busca... + + + + WebPage + + Error loading page: %1 + Atopouse un erro ao cargar a páxina: %1 + + + When connecting to: %1. + Cando se conecta a: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Comprobe que non hai erros no enderezo como<b>ww</b>.arora-browser.org no canto de <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Se a súa computadora ou rede están protexidas por unha devasa ou un proxy, asegúrese de que ao navegador se lle permite o acceso á rede. + + + If the address is correct, try checking the network connection. + Se o enderezo é correcto, comprobe a conexión de rede. + + + Resending POST request + Reenviar unha solicitude POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Para amosar o sitio web, a solicitude, xunto con todos os datos deben ser enviados, unha vez máis, o que pode levar a algun comportamento inesperado do sitio por exemplo, a mesma acción pode ser realizada unha vez máis. Quere continuar igualmente? + + + + WebView + + Open in New &Window + Abrir nunha &xanela nova + + + Open in New &Tab + Abrir nunha lingüe&ta nova + + + Save Lin&k + Gardar &ligazón + + + &Bookmark This Link + Engadir esta páxina a &marcadores + + + &Copy Link Location + &Copiar o enderezo da ligazón + + + Open Image in New &Window + Abrir a imaxe nunha &xanela nova + + + Open Image in New &Tab + Abrir a imaxe nunha lingüe&ta nova + + + &Save Image + &Gardar a imaxe + + + &Copy Image + &Copiar a imaxe + + + C&opy Image Location + C&opiar a ubicación da imaxe + + + Loading... + Cargando... + + + Search with... + Buscar con... + + + Add to the toolbar search + Engadir á barra de ferramentas de busca + + + Method not supported + Método non compatible + + + %1 method is not supported. + O método %1 non é compatible. + + + Search engine + Motor de buscas + + + Choose the desired search engine + Elixir o motor de busca desexado + + + Engine name + Nome do motor + + + Type in a name for the engine + Escriba un nome para o motor + + + Block Image + Bloquear imaxe + + + + WebViewSearch + + Not Found + Non atopado + + + diff --git a/src/locale/he_IL.ts b/src/locale/he_IL.ts new file mode 100644 index 00000000..1938426e --- /dev/null +++ b/src/locale/he_IL.ts @@ -0,0 +1,2265 @@ + + + + + AboutDialog + + About + אודות + + + Authors + כותבים + + + License + רישיון + + + Lightweight WebKit-based web browser + דפדפן רשת קליל מבוסס WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body dir="RTL" style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">כל הזכויות שמורות © 2007-2008 Benjamin C. Meyer &lt;‏<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + סגור + + + About %1 + אודות %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">כל הזכויות שמורות © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + גרסת WebKit: %1 + + + + AcceptLanguage + + Languages + שפות + + + Languages: in order of preference: + שפות: בסדר המועדף: + + + Move &Up + &מעלה + + + Move &Down + מ&טה + + + &Remove + &הסר + + + Add... + הוסף... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + נחסם על ידי חוק: %1 + + + + AdBlockDialog + + Add Custom Rule + הוסף חוק מותאם אישית + + + Learn more about writing rules... + מידע נודף אודות כתיבת חוקים... + + + Update Subscription + עדכן רישום + + + Browse Subscriptions... + עדיין ברישומים... + + + Remove Subscription + הסר רישום + + + AdBlock Configuration + תצורת AdBlock + + + Enable AdBlock + אפשר AdBlock + + + Action + פעולה + + + + AdBlockManager + + Custom Rules + חוקים מותאמים אישית + + + + AdBlockModel + + Rule + חוק + + + + AdBlockSchemeAccessHandler + + Subscribe? + רישום? + + + Subscribe to this AdBlock subscription? +%1 + האים להירשם לחוק AdBlock? +%1 + + + + AddBookmarkDialog + + Add Bookmark + הוסף סימנית + + + Type a name for the bookmark, and choose where to keep it. + כתוב שם עבור הסימנית ובחר היכן לשמור אותה. + + + Url + כתובת + + + Title + כותרת + + + Add Folder + הוסף תיקייה + + + + AutoFillDialog + + Form Passwords + ססמאות של טפסים + + + Remove + הסר + + + Remove All + הסר הכל + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>האם ברצונך לשמור את הססמה הזאת?<b><br> לעיון בססמאות השמורות, ובכדי למחוק אותן, אנא פתח את חלון ההגדרות בלשונית המילוי האוטומטי. + + + Never for this site + לעולם לא עבור אתר זה + + + Not now + לא כעת + + + + AutoFillModel + + WebSite + אתר + + + User Name + שם משתמש + + + + BookmarksDialog + + Open + פתח + + + Open in New Tab + פתח בכרטיסייה חדשה + + + Delete + מחק + + + New Folder + תיקייה חדשה + + + Bookmarks + סימניות + + + &Remove + ה&סר + + + Add Folder + הוסף תיקייה + + + Edit Name + ערוך שם + + + Edit Address + ערוך כתובת + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + ארעה שגיאה בעת טעינה של סימניות בשורה %1, עמודה %2: +%3 + + + Toolbar Bookmarks + סרגל כלים של סימניות + + + Menu + תפריט + + + Open File + פתח קובץ + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + הייבוא של %1 הסתיים + + + Save File + שמור קובץ + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + שגיאת ייצוא + + + error saving bookmarks + ארעה שגיאה בעת יצוא הסימניות + + + Remove Bookmark + הסר סימנייה + + + Insert Bookmark + ייבוא של סימניות + + + Name Change + שנה שם + + + Address Change + שנה כתובת + + + Bookmarks Bar + סרגל סימניות + + + Bookmarks Menu + תפריט סימניות + + + Name Change + Undo bookmark title change + שנה שם + + + Address Change + Undo bookmark url change + שנה כתובת + + + XBEL bookmarks + סימניות XBEL + + + HTML Netscape bookmarks + סימניות HTML של נטסקייפ + + + htmlToXBel tool required + נדרש הכלי htmlToXBell + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + הכלי htmlToXBel המופץ עם הדפדפן Arora נדרש בכדי לייבא סימניות HTML, ונראה כי הוא לא מותקן או לא זמין בנתיב החיפוש PATH. + + + Loading Bookmark + טוען סימנייה + + + Error when loading HTML bookmarks: %1 + + שגיאה בעת טעינת סימניות: %1 + + + + BookmarksMenu + + Open in Tabs + פתח בלשוניות + + + + BookmarksModel + + Title + כותרת + + + Address + כתובת + + + + BookmarksToolBar + + Bookmark + סימניות + + + Open + פתח + + + Open in New &Tab + פתח ב&כרטיסייה חדשה + + + Remove + הסר + + + Add Bookmark... + הוסף סימנייה... + + + Add Folder... + הוסף תיקייה... + + + Bookmarks + סימניות + + + + BrowserApplication + + (Change: %1 %2) + (שינוי %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + ישנם %1 חלונות ו־%2 כרטיסיות פתוחות. +האם לצאת בכל זאת? + + + Restore failed + השחזרור נכשל + + + The saved session will not be restored because Arora crashed while trying to restore this session. + אין אפשרות לשחזר את ההפעלה השמורה כיוון ש־Arora קרס בזמן השיחזור של ההפעלה. + + + Arora crashed while trying to restore this session. Should I try again? + היישום קרס בעת ניסיון השחזור של ההפעלה. האם לנסות שוב? + + + + BrowserMainWindow + + &File + &קובץ + + + &New Window + &חלון חדש + + + &Open File... + &פתח קובץ... + + + Open &Location... + &פתח מיקום... + + + &Save As... + שמור &בשם... + + + &Import Bookmarks... + יי&בא סימניות... + + + &Export Bookmarks... + יי&צא סימניות... + + + P&rint Preview... + ת&צוגת הדפסה... + + + &Print... + &הדפס... + + + Private &Browsing... + &גלישה מאובטחת... + + + &Quit + &יציאה + + + &Edit + ע&ריכה + + + &Undo + &בטל + + + &Redo + &שחזר + + + Cu&t + &גזור + + + &Copy + &העתק + + + &Paste + &הדבק + + + &Find + &חפש + + + Find Nex&t + חפש ה&בא + + + Find P&revious + חפש &קודם + + + Prefere&nces... + &הגדרות... + + + Ctrl+, + Ctrl+, ‎ + + + &View + &תצוגה + + + Show Menu Bar + הצג תפריט + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &עצור + + + &Reload Page + &רענן עמוד + + + Make Text &Bigger + &הגדל גופן + + + Make Text &Normal + גופן &רגיל + + + Make Text &Smaller + ה&קטן גופן + + + Page S&ource + &הצג מקור המסמך + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &מסך מלא + + + Hi&story + &היסטוריה + + + Back + חזור + + + Forward + הבא + + + Home + עמוד הבית + + + Restore Last Session + שחזר הפעלה קודמת + + + &Bookmarks + &סימניות + + + Manage Bookmarks... + ניהול סימניות... + + + Add Bookmark... + הוסף סימנייה... + + + &Window + &חלון + + + &Tools + &כלים + + + Web &Search + חיפוש &ברשת + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &מחק מידע אישי + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + &אפשר סורק רשת + + + &Help + &עזרה + + + About &Qt + &אודות Qt + + + About &Arora + א&ודות Arora + + + Navigation + ניווט + + + Show Status Bar + הצג שורת מצב + + + Hide Status Bar + הסתר שורת מצב + + + Show Toolbar + הצג סרגל כלים + + + Hide Toolbar + הסתר סרגל כלים + + + Show Bookmarks Bar + הצג סרגל סימניות + + + Hide Bookmarks Bar + הסתר סרגל סימניות + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + ‏Arora‏ - %1 + + + Open Web Resource + פתח משאב רשת + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + משאב רשת (*.html *.htm *.svg *.png *.gif *.svgz);; כל הקבצים (*.*) + + + Print Document + הדפס מסמך + + + Are you sure you want to turn on private browsing? + האם באמת ברצונך להפעיל גלישה מאובטחת? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <span dir="rtl"><b>%1</b><br><br>כאשר מופעלת גלישה מאובטחת כמה פעולות הקשורות לפרטיות שלך לא יופעלו:<ul dir="rtl"><li> דפים לא נוספים להסטוריית הגלישה.</li><li> פריטים נמחקים באופן אוטומטי מרשימת ההורדות.</li><li> עוגיות חדשות לא נשמרות ואין אפשרות לגשת לעוגיות ישנות.</li><li> סמלים של אתרים לא נשמרים וההפעלה לא תישמר.</li><li> חיפושים לא מתווספים לתפריט המוקפץ של היסטוריית החיפוש.</li></ul>עד שתסגור את החלון, באפשרותך ללחוץ על כפתורי הניווט "קדימה" ו־"אחורה" לחזרה לעמודים שביקרת בהם. +</span> + + + Are you sure you want to close the window? There are %1 tabs open + האם אתה באמת ברצונך לסגור את החלון? ישנן %1 כרטיסיות פתוחות + + + Page Source of %1 + קוד המקור של %1 + + + Web Inspector + סורק רשת + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + סורק הרשת יעבוד נכון רק עבור דפים שנטענו אחרי ההפעלה שלו. +האם ברצונך לרענן את כל הדפים? + + + Stop loading the current page + עצור את טעינת הדף הנוכחי + + + Reload the current page + טען מחדש את הדף הנוכחי + + + Downloads + הורדות + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + Switch application language + שנה את שפת היישום + + + Close Window + סגור חלון + + + Zoom &In + הת&קרב + + + Zoom &Normal + מרחק ר&גיל + + + Zoom &Out + התר&חק + + + Zoom &Text Only + הגדל &טקסט בלבד + + + Show All Bookmarks... + הצג את כל הסימניות... + + + Add Folder... + הוסף תיקייה... + + + About &%1 + About Browser + אודות &%1 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + ברירת מחדל + + + Text Encoding + קידוד הטקסט + + + Select &All + בחר &הכל + + + Alt+Ctrl+B + Alt+Ctrl+B + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + כאשר גלישה פרטית מופעלת, כמה פעילויות הקשורות בפרטיות שלך יהיו מנוטרלות: + + + Webpages are not added to the history. + דפים לא נשמרים בהיסטוריה. + + + Items are automatically removed from the Downloads window. + פריטים מוסרים באופן אוטומטי מחלון ההורדות. + + + New cookies are not stored, current cookies can't be accessed. + עוגיות חדשות לא נשמרות, אין אפשרות לגשת אל עוגיות נוכחיות. + + + Site icons won't be stored. + סמלים של אתרים לא נשמרים. + + + Session won't be saved. + ההפעלה לא תישמר. + + + Searches are not added to the pop-up menu in the search box. + חיפושים לא נשמרים בתפריט של החיפוש. + + + No new network cache is written to disk. + מטמון רשת לא נשמר בדיסק. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + עד שתסגור את החלון, עדיין תוכל ללחוץ על הכפתור קדימה ואחורה בכדי לבקר בדפים בהם ביקרת בעבר. + + + Private Browsing + גלישה מאובטחת + + + Options... + אפשרויות... + + + Configure Search Engines... + הגדרת מנועי חיפוש... + + + &Ad Block... + &חסימת פרסומות - AdBlock + + + + ClearButton + + Clear + מחק + + + + ClearPrivateData + + Clear Private Data + מחק מידע פרטי + + + Clear the following items: + מחק את הפרטים הבאים: + + + &Browsing History + &היסטורית גלישה + + + &Download History + הסטורית הו&רדה + + + &Search History + הסיטוריית &חיפוש + + + &Cookies + &עוגיות + + + C&ached Web Pages + דפי אינטרנט ב&מטמון + + + Website &Icons + סמלים של &אתרים + + + Clear &Private Data + אפס מידע &אישי + + + &Cancel + &ביטול + + + + ClickToFlash + + Load + טען + + + Load All + טען הכל + + + Add %1 to Whitelist + הוסף %1 לרשימה הלבנה + + + Remove from Whitelist + הסר מהרשימה הלבנה + + + Settings + הגדרות + + + Load Flash + טען פלאש + + + + ClickToFlashSettings + + Whitelist sites + אתרים ברשימה לבנה + + + + CookieExceptionsModel + + Website + אתר אינטרנט + + + Rule + חוק + + + Allow + אפשר + + + Block + חסום + + + Allow For Session + אפשר להפעלה נוכחית + + + + CookieModel + + Website + כתובת + + + Name + שם + + + Path + נתיב + + + Secure + מאובטח + + + Expires + תאריך תפוגה + + + Contents + תוכן + + + true + true + + + false + false + + + Session cookie + עוגיית ההפעלה + + + + CookiesDialog + + Cookies + עוגיות + + + &Remove + &מחק + + + Remove &All Cookies + מחק את &כל העוגיות + + + Add &Rule + הוסף &חוק + + + + CookiesExceptionsDialog + + Cookie Exceptions + עוגיות יוצאות מן הכלל + + + New Exception + יוצא מן הכלל חדש + + + Domain: + מתחם: + + + Block + בלוק + + + Allow For Session + אפשר להפעלה הנוכחית + + + Allow + אפשר + + + Exceptions + יוצרים מן הכלל + + + &Remove + ה&סר + + + Remove &All + &הסר הכל + + + + DownloadDialog + + Downloads + הורדות + + + Clean up + נקה + + + 0 Items + 0 פריטים + + + &OK + &אישור + + + + DownloadItem + + Form + ממקום + + + Ico + Ico + + + Filename + שם קובץ + + + Try Again + נסה שוב + + + Stop + עצור + + + Open + פתח + + + Save File + שמור קובץ + + + Download canceled: %1 + ההורדה הופסקה: %1 + + + Error opening output file: %1 + ארעה שגיאה בעת פתיחת קובץ הפלט: %1 + + + Error saving: %1 + ארעה שגיאה בעת השמירה: %1 + + + Network Error: %1 + ארעה שגיאות רשת: %1 + + + seconds + שניות + + + - %n minutes remaining + + נשארו עוד %n שניות + + + + + - %n seconds remaining + + נשארו עוד %n דקות + + + + + %1 of %2 (%3/sec) %4 + %1 מתוך %2 (%3 קס"ש) %2 + + + ? + ? + + + %1 of %2 - Stopped + %1 מתוך %2 - נעצר + + + bytes + בתים + + + kB + ק"ב + + + MB + מ"ב + + + %1 of %2 (%3/sec) - %4 + %1 מתוך %2 (%3/שנייה) - %4 + + + Download directory (%1) couldn't be created. + אין אפשרות ליצור את תיקיית ההורדה (%1). + + + + DownloadManager + + %n Download(s) + + הורדה אחת + %n הורדות + + + + There are %1 downloads in progress +Do you want to quit anyway? + ישנן %1 הודרות פעילות. +האם לצאת בכל זאת? + + + %n minutes remaining + + חסרה דקה + חסרות %n דקות + + + + %n seconds remaining + + חסרה שנייה + חסרות %n שניות + + + + bytes + בתים + + + kB + ק"ב + + + MB + מ"ב + + + GB + ג"ב + + + + FileAccessReply + + No Error + אין שגיאה + + + Error opening: %1: No such file or directory + ארעה שגיאה בעת הפתיחה: %1 : אין קובץ או ספרייה + + + Unable to read %1 + אין אפשרות לקרוא את %1 + + + Contents of %1 + התוכן של %1 + + + %1 KB + %1 ק"ב + + + + HistoryDialog + + Open + פתח + + + Copy + העתק + + + Delete + מחק + + + History + היסטוריה + + + &Remove + ה&סר + + + Remove &All + &הסר הכל + + + + HistoryMenu + + Show All History + הצג את כל ההסטוריה + + + Clear History... + מחק את ההיסטוריה... + + + Clear History + מחק את ההיסטוריה + + + Do you want to clear the history? + האם ברצונך למחוק את ההיסטוריה? + + + + HistoryModel + + Title + כותרת + + + Address + כתובת + + + + HistoryTreeModel + + Earlier Today + מוקדם היום + + + %n item(s) + + פריט אחד + %n פריטים + + + + + JavaScriptAroraObject + + Welcome to Arora! + Please put RLE in the beginning of the translation and RLM+PDF at the end. The PushDirectionFlag is needed because of the Right(to)LftEmbeding at the beginning, and the Right(to)Leftmark is needed, to put the ! and the right of the arora name. + +Don't ask why next time, ok? :) + ‫ברוך בואך אל Arora!‏‬ + + + Arora Start + דף ההפעלה של Arora + + + Search! + חפש! + + + Search results provided by + תוצאות החיפוש מסופקות על ידי + + + About Arora + אודות Arora + + + + LanguageManager + + Choose language + בחר שפה + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>ניתן להפעיל את היישום עם ממשק בשפה שונה <br>מזאת של מערכת ההפעלה.</p><p>אנא בחר את השפה לשימוש</p> + + + No translation files are installed at %1. + לא מותקנים קבצי תרגום בתיקיות %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>הכנס את שם המשתמש והססמה עבור "%1" באתר %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>מתחבר לשרת מתווך "%1" באמצעות:<qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + שגיאות SSL:<div dir="ltr">%1 +%2 +</div> +האם ברצונך להתעלם מהשגיאות הללו? + + + Do you want to accept all these certificates? + האם ברצונך לקבל את האישורים הללו? + + + - SSL Errors + - שגיאות SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>שגיאות SSL:<br/><br/> עבור: <tt>%1</tt><ul><li>%2</li></ul> + +האם ברצונך להתעלם מהשגיאות הללו?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>תעודות:<br/>%1<br/>האם ברצונך לקבל את כל התעודות הללו?</qt> + + + Issuer: %1 + מנפיק: %1 + + + Not valid before: %1 + לא תקין לפני: %1 + + + Valid until: %1 + תקין עד: %1 + + + Alternate Names: + שמות נוספים: + + + + NetworkMonitor + + Name + שם + + + + OpenSearchDialog + + Open File + פתח קובץ + + + OpenSearch + OpenSearch + + + Error + שגיאה + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 הוא לא תיאור תקין של OpenSearch 1.1 או הוא כבר ברשימה שלך. + + + You must have at least one search engine in here. + חייב להכיל לפחות מנוע חיפוש אחד. + + + OpenSearch Manager + מנהל OpenSearch + + + &Restore Defaults + &שחזר ברירות מחדל + + + &Delete + &מחק + + + &Add + &הוסף + + + &Close + &סגור + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>תיאור:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + רשימה מופרדת פסיקים של מילות המפתח שייתכן נכנסו במיקום שלאחריה מונחי החיפוש של מנוע זה + + + Name + שם + + + Keywords + מילות מפתח + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + האם ברצונך להוסיף את המנוע הבא לרשימה של מנוע החיפוש? <br /><br />שם: %1<br />מחפש בתוך: %2 + + + + PasswordDialog + + Authentication Required + נדרש אימות + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + שם משתמש: + + + Password: + ססמה: + + + + PlainTextEditSearch + + Not Found + לא נמצא + + + + ProxyDialog + + Proxy Authentication + אימות שאת מתווך + + + ICON + ICON + + + Connect to proxy + התחבר לשרת מתווך + + + Username: + שם משתמש: + + + Password: + ססמה: + + + + QObject + + The file is not an XBEL version 1.0 file. + הקובץ הוא לא קובץ XBEL מגרסה 1.0. + + + Unknown title + כותרת לא ידועה + + + The file is not an OpenSearch 1.1 file. + הקובץ הוא לא קובץ של OpenSearch 1.1. + + + + RequestModel + + Address + כתובת + + + + SearchBanner + + Form + מאת + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + סיים + + + Highlight All + סמן הכל + + + + SearchLineEdit + + Search + חפש + + + + Settings + + Preferences + הגדרות + + + General + כללי + + + On startup: + בהפעלה: + + + Show my home page + הצג את דף הבית שלי + + + Show a blank page + הצג דף ריק + + + Restore windows and tabs from last time + שחזר חלונות וכרטיסיות מהפעם הקודמת + + + Home Page: + דף הבית: + + + Set to current page + קבע לעמוד הנוכחי + + + Remove history items: + הסר פריטי היסטוריה: + + + After one day + אחרי יום אחד + + + After one week + אחרי שבוע אחד + + + After two weeks + אחרי שבועיים + + + After one month + אחרי חודש + + + After one year + אחרי שנה + + + Manually + ידנית + + + On application exit + בעת היציאה מהיישום + + + Open links from applications: + פתח קישורים מהיישומים: + + + In a tab in the current window + בכרטיסייה בחלון הנוכחי + + + In a new window + בחלון הנוכחי + + + Downloads + הורדות + + + Ask for a destination each time + שאל היכן לשמור בכל פעם + + + Use this destination: + השתמש במקום הבא: + + + Appearance + מראה + + + Standard font: + גופן ברירת־מחדל: + + + Times 16 + Times 16 + + + Select... + בחר... + + + Fixed-width font: + גופן רוחב קבוע: + + + Courier 13 + Courier 13 + + + Privacy + פרטיות + + + Web Content + תוכן + + + Enable Plugins + אפשר תוספים + + + Enable Javascript + אפשר JavaScript + + + View Images + הצג תמונות + + + Cookies + עוגיות + + + Accept Cookies: + אפשר עוגיות: + + + Always + תמיד + + + Never + אך פעם + + + Only from sites you navigate to + רק מאתרים שאתה גולש בהם + + + Exceptions... + יוצאים מן הכלל... + + + Keep Cookies Until: + שמור עוגיות עד: + + + They expire + שהן פגות + + + I exit the application + אני יוצא מהיישום + + + At most 90 days + עד 90 יום + + + Cookies... + עוגיות... + + + Tabs + כרטיסיות + + + Select tabs and windows as they are created + בחר כרטיסיות כשהן נוצרות + + + Confirm when closing multiple tabs + וודא יציאה כאשר מספר כרטיסיות פתוחות + + + Proxy + שרת מתווך + + + Use proxy server + השתמש בשרת מתווך + + + Type: + סוג: + + + Socks5 + Socks5 + + + Http + Http + + + Host name: + שם משתמש: + + + Port: + יציאה: + + + User Name: + שם משתמש: + + + Password: + ססמה: + + + Advanced + מתקדם + + + Style Sheet: + גיליון סגנון: + + + Show only one close button instead of one for each tab + הצג רק כפתור סגירה אחד, במקום בכל כרטיסייה + + + Preferred languages for viewing webpages in: + שפות מועדפות לתצוגת דפים: + + + Block Popup Windows + חסום חלונות קופצים + + + Opening links + פתיחת קישורים + + + Links that want to open in a new window: + קישורים שרוצים להיפתח בחלון חדש: + + + In a new selected tab in the current window + בכרטיסייה חדשה בעלת פוקוס + + + In a new tab in the current window + בכרטיסייה חדשה בחלון הנוכחי + + + In the current tab + בכרטיסייה הנוכחית + + + Http (Secure) + Http (מאובטח) + + + Http (Transparent) + Http (שקוף) + + + Use ClickToFlash on flash plugins + השתמש בתוסף ClickToFlash עבור תוספי פלאש + + + Filter Tracking Cookies + מסנן עוגיות מעקב + + + Confirm when closing multiple tabs or windows + אשר בעת סגירה כאשר יש מספר כרטיסיות או חלונות + + + Quit the application when last tab is closed + סגור את היישום כאשר הלשונית האחרונה נסגרת + + + Enable network cache + אפשר מטמון רשת + + + Maximum Size: + גודל מירבי: + + + MB + מ"ב + + + Use the default search engine as fallback when the URL given by the user is invalid + השתמש במנוע החיפוש כאשר הכתובת המתקבלת על ידי המשתמש אינה תקינה + + + Choose Directory... + בחר ספרייה... + + + A cookie session ends: + עוגייה ההפעלה מסתיימת: + + + When I exit the application + כאשר אני יוצא מהיישום + + + 1 day + יום אחד + + + 2 days + שני ימים + + + 3 days + שלושה ימים + + + 7 days + שבעה ימים + + + 30 days + 30 יום + + + AutoFill + מילוי אוטומטי + + + AutoFill web forms: + מילוי אוטומטי של טפסים: + + + User names and passwords + שמות משתמשים וססמאות + + + Edit... + עריכה... + + + Browse... + עיון... + + + + SettingsDialog + + Restart required + נדרשת הפעלה מחדש + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + הגדרות מטמון הרשת שונו. בכדי שיכנסו לתוקף יש להפעיל מחדש את הדפדפן. + + + Choose Directory + בחר ספרייה + + + Choose CSS File + Please put at the start of the translation RLE and at the end PDF, k? 10x bye + ‫בחר קובץ CSS‬ + + + + SourceViewer + + Loading... + טוען... + + + &Edit + ע&ריכה + + + &Find + &חפש + + + &View + &תצוגה + + + Source of Page %1 + קוד מקור של דף %1 + + + + TabBar + + Show Tab Bar + הצג כותרת כרטיסיות + + + Hide Tab Bar + הסתר כותרת כרטיסיות + + + New &Tab + כרטיסייה &חדשה + + + Duplicate Tab + שכפל כרטיסייה + + + &Close Tab + &סגור כרטיסייה + + + Close &Other Tabs + סגור כרטיסייות &אחרות + + + Reload Tab + טען כרטיסייה מחדש + + + Reload All Tabs + רענן את כל הכרטיסיות + + + + TabWidget + + New &Tab + &כרטיסייה חדשה + + + &Close Tab + &סגור כרטיסייה + + + Show Next Tab + הצג את הכרטיסייה הבאה + + + Show Previous Tab + הצג את הכרטסייה הקודמת + + + Recently Closed Tabs + כרטיסיות שנסגרו לאחרונה + + + Untitled + ללא שם + + + Do you really want to close this page? + האם באמת ברצונך לסגור את העמוד הזה? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + אתה שינית את העמוד הזה וכאשר תסגור אותו אתה עללו לאבד מידע. +האם לסגור את העמוד בכל זאת? + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + כרטיסיות שנשמרו + + + Loading... + טוען... + + + Loading %1% (%2 %3)... + טוען %1% (%2 %3)... + + + Finished loading + הטעינה הסתיימה + + + Failed to load + הטעינה נכשלה + + + Bookmark All Tabs + שמור את כל הכרטיסיות בסימניות + + + + ToolbarSearch + + No Recent Searches + אין חיפושים אחרונים + + + Recent Searches + חיפושים אחרונים + + + Clear Recent Searches + נקה את החיפושים האחרונים + + + Suggestions + המלצות + + + Add '%1' + הוסף "%1" + + + Configure Search Engines... + הגדרת מנועי חיפוש... + + + + WebPage + + Error loading page: %1 + ארעה שגיאה באת הטעינה של העמוד: %1 + + + When connecting to: %1. + בעת החיבור אל %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + בדוק האם הכתובת מכילה שגיאות בנוסחח <b>ww</b>.arora-browse.org במקום <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + אם המחשב שלך או הרשת שלך מוגנת על ידי חומת או או שרת proxy, אנא וודא שהדפדפן מורה לגשת לרשת. + + + If the address is correct, try checking the network connection. + אם הכתובת היא נכונה, אנא בדוק את חיבור הרשת. + + + Resending POST request + שולחת מחדש בקשת POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + בכדי להציג את האתר, הבקשה וכל המידע שאיתה חייב להישלח מחדש, דבר אשר יכול לגרום להתנהגויות לא צפויות באתר. למשל ייתכן והפעולה שניסית לעשות תתבצע שוב. האם ברצונך להמשיך בכל זאת? + + + + WebView + + Open in New &Window + פתח ב&חלון חדש + + + Open in New &Tab + פתח ב&כרטיסייה חדשה + + + Save Lin&k + שמור &קישור + + + &Bookmark This Link + שים קישור ב&סימניות + + + &Copy Link Location + העתק &מיקום הקישור + + + Open Image in New &Window + פתח &תמונה בחלון חדש + + + Open Image in New &Tab + פתח תמונה ב&כרטיסייה חדשה + + + &Save Image + &שמור תמונה + + + &Copy Image + &העתק תמונה + + + C&opy Image Location + ה&עתק מיקום התמונה + + + Loading... + טוען... + + + Search with... + חפש בעזרת... + + + Add to the toolbar search + הוסף תסרגל החיפוש + + + Method not supported + לא סופקה שיטה + + + %1 method is not supported. + השיטה %1 לא נתמכת. + + + Search engine + מנוע חיפוש + + + Choose the desired search engine + בחר את מנוע החיפוש + + + Engine name + שם המנוע + + + Type in a name for the engine + אנא הקלד את שם המנוע + + + Block Image + חסום תמונה + + + + WebViewSearch + + Not Found + לא נמצא + + + diff --git a/src/locale/hu_HU.ts b/src/locale/hu_HU.ts new file mode 100644 index 00000000..224a6eaf --- /dev/null +++ b/src/locale/hu_HU.ts @@ -0,0 +1,2190 @@ + + + + + AboutDialog + + About %1 + Névjegy: %1 + + + Authors + Szerzők + + + License + Licenc + + + Lightweight WebKit-based web browser + WebKit-alapú böngésző + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Minden jog fenntartva © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Bezárás + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + Nyelvek + + + Languages: in order of preference: + Nyelvek: prferencia szerint rendezve: + + + Move &Up + &Fel + + + Move &Down + &Le + + + &Remove + &Eltávolítás + + + Add... + Hozzáadás... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Szabály + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Hozzáadás a könyvjelzőkhöz + + + Type a name for the bookmark, and choose where to keep it. + Adja meg a könyvjelző nevét és jelölje ki a helyét. + + + Url + Hivatkozás + + + Title + Cím + + + Add Folder + Új könyvjelzőmappa + + + + AutoFillDialog + + Form Passwords + + + + Remove + Eltávolítás + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Megnyitás + + + Open in New Tab + Megnyitás új lapon + + + Edit Name + Név szerkesztése + + + Edit Address + Cím szerkesztése + + + Delete + Törlés + + + New Folder + Új könyvjelzőmappa + + + Bookmarks + Könyvjelzők + + + &Remove + &Eltávolítás + + + Add Folder + Új könyvjelzőmappa + + + + BookmarksManager + + Bookmarks Bar + Könyvjelző eszköztár + + + Bookmarks Menu + Könyvjelző menü + + + Error when loading bookmarks on line %1, column %2: +%3 + Hiba a könyvjelzők betöltése közben a(z) %1. sor %2. oszlopban: +%3 + + + Toolbar Bookmarks + Könyvjelző eszköztár + + + Menu + Menü + + + Open File + Fájl megnyitása + + + XBEL + XBEL + + + Error when loading html bookmarks: %1 + + Hiba a html könyvjelzők betöltése közben: %1 + + + + Imported %1 + %1 importálva + + + Save File + Fájl mentése + + + %1 Bookmarks.xbel + %1 Konyvjelzok.xbel + + + XBEL (*.xbel *.xml) + lupdate ../src/src.pro + + + Export error + Hiba az exportálás közben + + + error saving bookmarks + Hiba a könyvjelzők mentése közben + + + Remove Bookmark + Könyvjelző eltávolítása + + + Insert Bookmark + Könyvjelző hozzáadása + + + Name Change + Undo bookmark title change + Név megváltoztatása + + + Address Change + Undo bookmark url change + Hivatkozás megváltoztatása + + + XBEL bookmarks + XBEL könyvjelzők + + + HTML Netscape bookmarks + HTML Netscape könyvjelzők + + + htmlToXBel tool required + htmlToXBel eszköz szükséges + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + A HTML könyvjelzők importálására szolgáló, az Arora részeként szállított htmlToXBel eszköz nincs telepítve, vagy nem érhető el a keresési útvonalon. + + + Loading Bookmark + Könyvjelző betöltése + + + Error when loading HTML bookmarks: %1 + + Hiba a HTML könyvjelzők betöltése közben: %1 + + + + + BookmarksMenu + + Open in Tabs + Megnyitás lapokon + + + + BookmarksModel + + Title + Cím + + + Address + Hivatkozás + + + + BookmarksToolBar + + Bookmark + Könyvjelző + + + Open + Megnyitás + + + Open in New &Tab + Megnyitás új la&pon + + + Remove + Eltávolítás + + + Add Bookmark... + Könyvjelző hozzáadása... + + + Add Folder... + Könyvjelzőmappa hozzáadása... + + + Bookmarks + Könyvjelzők + + + + BrowserApplication + + (Change: %1 %2) + (Verzió: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Jelenleg %1 böngészőablakban %2 lap van megnyitva +Biztosan ki akar lépni? + + + Restore failed + A visszaállítás sikertelen + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Az elmentett munkamenet nem kerül visszaállításra, mert az Arora összeomlott a művelet közben. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Fájl + + + &New Window + Új &ablak + + + &Open File... + &Fájl megnyitása... + + + Open &Location... + &Cím megnyitása... + + + &Save As... + Mentés más&ként... + + + &Import Bookmarks... + Könyvjelzők &importálása... + + + &Export Bookmarks... + Könyvjelzők &exportálása... + + + P&rint Preview... + Ny&omtatás előnézete... + + + &Print... + &Nyomtatás... + + + Private &Browsing... + &Privát böngészés... + + + Close Window + Ablak bezárása + + + &Quit + &Kilépés + + + &Edit + &Szerkesztés + + + &Undo + &Visszavonás + + + &Redo + Új&ra végrehajtás + + + Cu&t + Ki&vágás + + + &Copy + &Másolás + + + &Paste + &Beillesztés + + + &Find + &Keresés + + + Find Nex&t + K&övetkező keresése + + + Find P&revious + E&lőző keresése + + + Prefere&nces... + &Beállítások... + + + Ctrl+, + Ctrl+, + + + &View + &Nézet + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + Show Menu Bar + Menüsor megjelenítése + + + &Reload Page + Oldal &újratöltése + + + &Stop + Á&llj + + + Zoom &In + &Nagyítás + + + Zoom &Normal + N&ormál méret + + + Zoom &Out + &Kicsinyítés + + + Zoom &Text Only + Csak a &szöveg nagyítása + + + Page S&ource + Oldal &forrása + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Teljes képernyő + + + Hi&story + Elő&zmények + + + Back + Vissza + + + Forward + Előre + + + Home + Kezdőlap + + + Restore Last Session + Utolsó munkamenet visszaállítása + + + &Bookmarks + &Könyvjelzők + + + Show All Bookmarks... + Könyvjelzők kezelése... + + + Add Bookmark... + Hozzáadás a könyvjelzőkhöz... + + + Add Folder... + Könyvjelzőmappa hozzáadása... + + + &Window + &Ablak + + + &Tools + &Eszközök + + + Web &Search + &Webes keresés + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Személyes adatok törlése + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Show &Network Monitor + &Hálózatfigyelő megjelenítése + + + Enable Web &Inspector + Webfelügyelő &engedélyezése + + + &Help + &Súgó + + + Switch application language + Más alkalmazásnyelv + + + About &Qt + Névjegy: &Qt + + + About &%1 + About Browser + &Névjegy: %1 + + + Navigation + Navigáció + + + Show Status Bar + Állapotsor megjelenítése + + + Hide Status Bar + Állapotsor elrejtése + + + Show Toolbar + Eszköztár megjelenítése + + + Hide Toolbar + Eszköztár elrejtése + + + Show Bookmarks Bar + Könyvjelző eszköztár megjelenítése + + + Hide Bookmarks Bar + Könyvjelző eszköztár elrejtése + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Webes tartalom megnyitása + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Webes tartalom (*.html *.htm *.svg *.png *.gif *.svgz);;Minden fájl (*.*) + + + Print Document + Dokumentum nyomtatása + + + Are you sure you want to turn on private browsing? + Biztosan be akarja kapcsolni a privát böngészést? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Ha a privát böngészés be van kapcsolva, akkor néhány személyes adatokat érintő művelet tiltásra kerül:<ul><li> A meglátogatott oldalak nem kerülnek hozzáadásra az előzményekhez.</li><li> Az új elemek automatikusan eltávolításra kerülnek a letöltések listájáról.</li><li> Az új sütik nem kerülnek eltárolásra, a korábban tárolt sütik pedig nem érhetőek el.</li><li> Az oldalak ikonjai és a munkamenetek nem kerülnek mentésre.</li><li> A keresések nem kerülnek hozzáadásra a keresőmező listájához.</li></ul>A böngészőablak bezárásáig a Vissza és Előre gombokkal navigálhatunk a megnyitott oldalak között. + + + Are you sure you want to close the window? There are %1 tabs open + Biztosan be akarja zárni az ablakot? Jelenleg %1 lap van megnyitva + + + Web Inspector + Webfelügyelő + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + A webfelügyelő csak azokkal az oldalakkal fog rendeltetésszerűen működni, amelyek az aktiválása előtt kerültek megnyitásra. +Újra akar tölteni minden oldalt? + + + Stop loading the current page + Oldal letöltésének megszakítása + + + Reload the current page + Oldal újratöltése + + + Downloads + Letöltések + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Alapértelmezett + + + Text Encoding + Szövegkódolás + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + Keresőmotorok beállítása... + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Törlés + + + + ClearPrivateData + + Clear Private Data + Személyes adatok törlése + + + Clear the following items: + A következő elemek törlése: + + + &Browsing History + Böngészési &előzmények + + + &Download History + &Letöltési előzmények + + + &Search History + &Keresési előzmények + + + &Cookies + &Sütik + + + C&ached Web Pages + Kapcs&olat nélküli webhelyadatok + + + Website &Icons + Oldalak &ikonjai + + + Clear &Private Data + &Személyes adatok törlése + + + &Cancel + &Mégsem + + + + ClickToFlash + + Load + Betöltés + + + Load All + Összes betöltése + + + Add %1 to Whitelist + %1 hozzáadása az engedélyezési listához + + + Remove from Whitelist + Eltávolítás az engedélyezési listáról + + + Settings + Beállítások + + + Load Flash + Flash betöltése + + + + ClickToFlashSettings + + Whitelist sites + Engedélyezett oldalak + + + + CookieExceptionsModel + + Website + Oldal + + + Rule + Szabály + + + Allow + Engedélyezés + + + Block + Tiltás + + + Allow For Session + Engedélyezés a munkamenetre + + + + CookieModel + + Website + Oldal + + + Name + Név + + + Path + Útvonal + + + Secure + Biztonságos + + + Expires + Lejárat + + + Contents + Tartalmak + + + true + igen + + + false + nem + + + Session cookie + Ideiglenes süti + + + + CookiesDialog + + Cookies + Sütik + + + &Remove + &Eltávolítás + + + Remove &All Cookies + &Összes süti eltávolítása + + + Add &Rule + &Szabály hozzáadása + + + + CookiesExceptionsDialog + + Cookie Exceptions + Süti kivételek + + + New Exception + Új kivétel + + + Domain: + Domain: + + + Block + Tiltás + + + Allow For Session + Engedélyezés a munkamenetre + + + Allow + Engedélyezés + + + Exceptions + Kivételek + + + &Remove + &Eltávolítás + + + Remove &All + &Összes eltávolítása + + + + DownloadDialog + + Downloads + Letöltések + + + Clean up + Lista törlése + + + 0 Items + 0 elem + + + + DownloadItem + + Form + Letöltés + + + Ico + Ico + + + Filename + Fájlnév + + + Try Again + Újra + + + Stop + Állj + + + Open + Megnyitás + + + Save File + Fájl mentése + + + Download canceled: %1 + Letöltés megszakítva: %1 + + + Error opening output file: %1 + Hiba a kimeneti fájl megnyitásánál: %1 + + + Error saving: %1 + Hiba a mentésnél: %1 + + + Network Error: %1 + Hálózati hiba: %1 + + + %1 of %2 (%3/sec) - %4 + %1 / %2 (%3/mp) - %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 / %2 - Megállítva + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + Jelenleg %1 letöltés van folyamatban. +Biztosan ki akar lépni? + + + %n Download(s) + + %n letöltés + + + + %n minutes remaining + + %n perc van hátra + + + + %n seconds remaining + + %n másodperc van hátra + + + + bytes + bájt + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + Megnyitás + + + Copy + Másolás + + + Delete + Törlése + + + History + Előzmények + + + &Remove + &Eltávolítás + + + Remove &All + &Összes eltávolítása + + + + HistoryMenu + + Show All History + Összes előzmény megjelenítése + + + Clear History... + Előzmények törlése... + + + Clear History + Előzmények törlése + + + Do you want to clear the history? + Törölni akarja az előzményeket? + + + + HistoryModel + + Title + Cím + + + Address + Hivatkozás + + + + HistoryTreeModel + + Earlier Today + Korábban a mai napon + + + %n item(s) + + %n elem + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + No translation files are installed. + Nincs telepített fordítási fájl. + + + Choose language + Nyelv kiválasztása + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <b>Az operációs rendszer alapértelmezett nyelvén kívül választható további nyelv is.</p><p>Válassza ki a használni kívánt nyelvet!</p> + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Adja meg "%1" felhasználónevét és jelszavát itt: %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Csatlakozás a(z) "%1" proxyhoz:</qt> + + + - SSL Errors + - SSL hibák + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL hibák:<br/><br/> <tt>%1</tt><ul><li>%2</li></ul> + +Figyelmen kívül akarja hagyni ezeket a hibákat?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Tanúsítványok:<br/>%1<br/>El akarja fogadni ezeket a tanúsítványokat?</qt> + + + Issuer: %1 + Kibocsátó: %1 + + + Not valid before: %1 + Nem érvényes ezelőtt: %1 + + + Valid until: %1 + Érvényes eddig: %1 + + + Alternate Names: + Alternatív nevek: + + + + NetworkMonitor + + Name + Név + + + Value + Érték + + + + NetworkMonitorDialog + + Network Monitor + Hálózatfigyelő + + + Network Requests + Hálózati kérések + + + Request Headers + Kérés fejlécek + + + Response Headers + Válasz fejlécek + + + &Remove + &Eltávolítás + + + Remove &All Requests + &Összes kérés eltávolítása + + + + OpenSearchDialog + + Open File + Fájl megnyitása + + + OpenSearch + Keresőmotorok + + + Error + Hiba + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 nem érvényes OpenSearch 1.1 leírás, vagy már szerepel a listán. + + + You must have at least one search engine in here. + Legalább egy keresőmotor szükséges. + + + OpenSearch Manager + Keresőmotorok kezelése + + + &Add + &Hozzáadás + + + &Delete + &Törlés + + + &Restore Defaults + &Alapértelmezések visszaállítása + + + &Close + &Bezárás + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Leírás:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Javaslatokat szolgáltat</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Név + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Hozzá akarja adni ezt a keresőmotort a listához?<br /><br />Név: %1<br />Keresés itt: %2 + + + + PasswordDialog + + Authentication Required + Azonosítás szükséges + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Felhasználónév: + + + Password: + Jelszó: + + + + PlainTextEditSearch + + Not Found + Nincs találat + + + + ProxyDialog + + Proxy Authentication + Proxy azonosítás + + + Connect to proxy + Kapcsolódás a proxyhoz + + + Username: + Felhasználónév: + + + Password: + Jelszó: + + + + QObject + + The file is not an OpenSearch 1.1 file. + A fájl nem egy OpenSearch 1.1 fájl. + + + The file is not an XBEL version 1.0 file. + A fájl nem egy XBEL 1.0 fájl. + + + Unknown title + Ismeretlen cím + + + + RequestModel + + Redirect: %1 + Átirányítás: %1 + + + Method + Típus + + + Address + Cím + + + Response + Válasz + + + Length + Hossz + + + Content Type + Tartalom típusa + + + Info + Információ + + + Unknown + Ismeretlen + + + + SearchBanner + + Form + Keresés + + + Done + Bezárás + + + Highlight All + + + + + SearchLineEdit + + Search + Keresés + + + + Settings + + Preferences + Beállítások + + + General + Általános + + + On startup: + Induláskor: + + + Show my home page + Kezdőlap megjelenítése + + + Show a blank page + Üres oldal megjelenítése + + + Restore windows and tabs from last time + Legutóbbi ablakok és lapok visszaállítása + + + Home Page: + Kezdőlap: + + + Set to current page + Beállítás az aktuális oldalra + + + Remove history items: + Előzmények eltávolítása: + + + After one day + Egy nap után + + + After one week + Egy hét után + + + After two weeks + Két hét után + + + After one month + Egy hónap után + + + After one year + Egy év után + + + Manually + Manuálisan + + + On application exit + Kilépéskor + + + Downloads + Letöltések + + + Ask for a destination each time + Rákérdezés a letöltés helyére minden alkalommal + + + Use this destination: + Letöltések helyének megadása: + + + Appearance + Megjelenés + + + Standard font: + Általános betűtípus: + + + Select... + Kiválasztás... + + + Fixed-width font: + Rögzített szélességű betűtípus: + + + Preferred languages for viewing webpages in: + Oldalak megtekintésekor előnyben részesített nyelvek: + + + Privacy + Adatvédelem + + + Web Content + Webes tartalom + + + Block Popup Windows + Felugró ablakok blokkolása + + + Enable Plugins + Bővítmények engedélyezése + + + Use ClickToFlash on flash plugins + Flash tartalmak megjelenítése kattintásra + + + Enable Javascript + Javascript engedélyezése + + + View Images + Képek megjelenítése + + + Cookies + Sütik + + + Accept Cookies: + Sütik elfogadása: + + + Always + Mindig + + + Never + Soha + + + Only from sites you navigate to + Csak a meglátogatott oldalakon + + + Exceptions... + Kivételek... + + + Keep Cookies Until: + Sütik megtartása: + + + They expire + Lejáratig + + + I exit the application + Kilépésig + + + At most 90 days + Legfeljebb 90 napig + + + Cookies... + Sütik... + + + Filter Tracking Cookies + Nyomkövető sütik szűrése + + + Tabs + Lapok + + + Select tabs and windows as they are created + Lapok és ablakok kiválasztása megnyitáskor + + + Confirm when closing multiple tabs or windows + Megerősítés kérése több lap vagy ablak bezárásakor + + + Show only one close button instead of one for each tab + Csak egy bezárás gomb megjelenítése + + + Quit the application when last tab is closed + Kilépés az alkalmazásból az utolsó lap bezárásakor + + + Opening links + Hivatkozások megnyitása + + + Links that want to open in a new window: + Az új ablakban megnyitandó hivatkozások: + + + In a new window + Új ablakban + + + In a new selected tab in the current window + Az aktuális ablakban, új aktív lapon + + + In a new tab in the current window + Az aktuális ablakban, új lapon + + + In the current tab + Az aktuális lapon + + + Open links from applications: + Külső hivatkozások megnyitása: + + + Proxy + Proxy + + + Use proxy server + Proxy kiszolgáló használata + + + Type: + Típus: + + + Socks5 + Socks5 + + + Http (Secure) + Http (biztonságos) + + + Http (Transparent) + Http (nem biztonságos) + + + Host name: + Kiszolgáló: + + + Port: + Port: + + + User Name: + Felhasználónév: + + + Password: + Jelszó: + + + Advanced + Haladó + + + Style Sheet: + Stíluslap: + + + Enable network cache + Hálózati gyorstár engedélyezése + + + Maximum Size: + Maximális méret: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + Újraindítás szükséges + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + A hálózati gyorstárazás beállításai megváltoztak. A módosítások használatához a böngésző újraindítása szükséges. + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Betöltés... + + + &Edit + &Szerkesztés + + + &Find + &Keresés + + + &View + &Nézet + + + &Wrap lines + &Sorok tördelése + + + Source of Page + Oldal forrása + + + Source of Page %1 + %1 oldal forrása + + + + TabBar + + Show Tab Bar + Lapok megjelenítése + + + Hide Tab Bar + Lapok elrejtése + + + Duplicate Tab + Lap megkettőzése + + + &Close Tab + &Lap bezárása + + + Close &Other Tabs + &Többi lap bezárása + + + Reload Tab + Lap újratöltése + + + Reload All Tabs + Összes lap újratöltése + + + + TabWidget + + Untitled + Névtelen + + + Saved Tabs + Mentett lapok + + + Do you really want to close this page? + Biztosan be akarja zárni ezt az oldalt? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Az oldalon elvégzett módosítások bezáráskor elveszhetnek. +Biztosan be akarja zárni ezt az oldalt? + + + + Loading... + Töltés... + + + Loading %1% (%2 %3)... + Töltés %1% (%2 %3)... + + + Finished loading + A letöltés befejeződött + + + Failed to load + A letöltés sikertelen + + + Show Next Tab + Következő lap megjelenítése + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + Előző lap megjelenítése + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + Nemrég bezárt lapok + + + New &Tab + Új &lap + + + &Close Tab + Lap &bezárása + + + Bookmark All Tabs + Összes lap felvétele a könyvjelzők közé + + + + ToolbarSearch + + Suggestions + Javaslatok + + + Add '%1' + '%1' hozzáadása + + + Configure Search Engines... + Keresőmotorok beállítása... + + + Clear Recent Searches + Keresési előzmények törlése + + + No Recent Searches + Nincsenek keresési előzmények + + + Recent Searches + Keresési előzmények + + + + WebPage + + Error loading page: %1 + Hiba a következő oldal betöltésekor: %1 + + + When connecting to: %1. + Kapcsolódás: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Nem vétett hibát a hivatkozás beírásakor? (pl. "<b>ww</b>.arora-browser.org" a "<b>www</b>.arora-browser.org" helyett) + + + If the address is correct, try checking the network connection. + Amennyiben a hivatkozás helyes, próbálja ellenőrizni a hálózati kapcsolatot. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Ha a számítógép vagy a hálózat tűzfal, illetve proxy mögött van, a hálózat eléréséhez megfelelő hozzáférési jogosultság szükséges. + + + Resending POST request + POST kérés újraküldése + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Az oldal megjelenítéséhez az űrlapot minden adattal együtt újra el kell küldeni. A kétszer végrehajtott megegyező művelet az oldalon nem várt komplikációkkal járhat. Biztosan folytatni szeretné? + + + + WebView + + Open in New &Window + Megnyitás új &ablakban + + + Open in New &Tab + Megnyitás új &lapon + + + Save Lin&k + Hivatkozás &mentése + + + &Bookmark This Link + Hivatkozás &felvétele a könyvjelzők közé + + + &Copy Link Location + Hivatkozá&s másolása + + + Open Image in New &Window + &Kép megnyitása új ablakban + + + Open Image in New &Tab + Ké&p megnyitása új lapon + + + &Save Image + &Kép mentése + + + &Copy Image + Kép m&ásolása + + + C&opy Image Location + Kép &hivatkozásának másolása + + + Search with... + Keresés mással... + + + Loading... + Töltés... + + + Add to the toolbar search + Hozzáadás az eszköztár keresőmezőjéhez + + + Method not supported + Az eljárás nem támogatott + + + %1 method is not supported. + %1 eljárás nem támogatott. + + + Search engine + Keresőmotor + + + Choose the desired search engine + Válassza ki a kívánt keresőmotort + + + Engine name + Motor neve + + + Type in a name for the engine + Adjon meg egy nevet a motornak + + + Block Image + + + + + WebViewSearch + + Not Found + Nincs találat + + + diff --git a/src/locale/it.ts b/src/locale/it.ts deleted file mode 100644 index 16d166e1..00000000 --- a/src/locale/it.ts +++ /dev/null @@ -1,1502 +0,0 @@ - - - - - AboutDialog - - - About - Informazioni - - - - AddBookmarkDialog - - - Add Bookmark - Aggiungi un Segnalibro - - - - Type a name for the bookmark, and choose where to keep it. - Scrivi il nome del segnalibro, e scegli dove metterlo. - - - - BookmarksDialog - - - Open - Apri - - - - Delete - Cancella - - - - New Folder - Nuova Cartella - - - - Bookmarks - Segnalibri - - - - &Remove - &Rimuovi - - - - Add Folder - Aggiungi Cartella - - - - Open in New Tab - Apri in una nuova Scheda - - - - BookmarksManager - - - Error when loading bookmarks on line %1, column %2: -%3 - Errore durante l'appertura dei segnalibri sulla riga %1, colonna %2 -%3 - - - - Toolbar Bookmarks - Barra dei Segnalibri - - - - Menu - Menu - - - - Open File - Apri File - - - - XBEL (*.xbel *.xml) - XBEL (*.xbel *.xml) - - - - Imported %1 - Importati %1 - - - - Save File - Salva il File - - - - %1 Bookmarks.xbel - %1 Bookmarks.xbel - - - - Export error - Errore in esportazione - - - - error saving bookmarks - errore durante il salvataggio dei segnalibri - - - - Remove Bookmark - Rimuovi Segnalibro - - - - Insert Bookmark - Inserisci Segnalibro - - - - Name Change - Cambia il Nome - - - - Address Change - Cambia l'Indirizzo - - - - BookmarksModel - - - Title - Titolo - - - - Address - Indirizzo - - - - BookmarksToolBar - - - Bookmark - Segnalibro - - - - BrowserApplication - - - There are %1 windows and %2 tabs open -Do you want to quit anyway? - Ci sono %1 finestre e %2 schede aperte -Se sicuro di voler uscire? - - - - BrowserMainWindow - - - &File - &File - - - - &New Window - &Nuova Finestra - - - - &Open File... - &Apri File... - - - - Open &Location... - &Apri Indirizzo... - - - - &Save As... - &Salva Con Nome... - - - - &Import Bookmarks... - &Importa i Segnalibri... - - - - &Export Bookmarks... - &Esporta i Segnalibri... - - - - P&rint Preview... - An&teprima di Stampa... - - - - &Print... - Stam&pa... - - - - Private &Browsing... - &Navigazione Anonima... - - - - &Quit - &Esci - - - - &Edit - &Modifica - - - - &Undo - &Annulla - - - - &Redo - &Ripeti - - - - Cu&t - &Taglia - - - - &Copy - &Copia - - - - &Paste - &Incolla - - - - &Find - &Cerca - - - - &Find Next - &Cerca il Successivo - - - - &Find Previous - &Cerca il Precedente - - - - &Preferences - &Preferenze - - - - Ctrl+, - Ctrl+, - - - - &View - &Vista - - - - Shift+Ctrl+B - Shift+Ctrl+B - - - - Ctrl+| - Ctrl+| - - - - Ctrl+/ - Ctrl+/ - - - - &Stop - &Ferma - - - - Reload Page - Ricarica la Pagina - - - - &Make Text Bigger - &Ingrandisci il Testo - - - - &Make Text Normal - &Dimensione Normale - - - - &Make Text Smaller - &Rimpicciolisci il Testo - - - - Page S&ource - &Sorgente della Pagina - - - - Ctrl+Alt+U - Ctrl+Alt+U - - - - &Full Screen - &Schermo Intero - - - - Hi&story - &Cronologia - - - - Back - Indietro - - - - Forward - Avanti - - - - Home - Pagina Iniziale - - - - Restore Last Session - Ripristina la Sessione Precedente - - - - &Bookmarks - &Segnalibri - - - - Manage Bookmarks... - Gestione dei Segnalibri... - - - - Add Bookmark... - Aggiungi Segnalibro... - - - - &Window - &Finestra - - - - &Tools - &Strumenti - - - - Web &Search - &Ricerca nel Web - - - - Ctrl+K - Web Search - Ctrl+K - - - - Enable Web &Inspector - Abilita l'&Ispettore Web - - - - &Help - &Aiuto - - - - About &Qt - Informazioni su &Qt - - - - About &Arora - Informazioni su &Arora - - - - Navigation - Navigazione - - - - Show Status Bar - Mostra la Barra di Stato - - - - Hide Status Bar - Nascondi la Barra di Stato - - - - Show Toolbar - Mostra la Barra Degli Strumenti - - - - Hide Toolbar - Nascondi la Barra Degli Strumenti - - - - Show Bookmarks bar - Mostra la Barra Dei Segnalibri - - - - Hide Bookmarks bar - Nascondi la Barra Dei Segnalibri - - - - Arora - Arora - - - - %1 - Arora - Page title and Browser name - %1 - Arora - - - - Open Web Resource - Apri Risorsa Web - - - - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - Risorse Web (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - - - - Print Document - Stampa Documento - - - - Are you sure you want to turn on private browsing? - Sei sicuro di voler passare alla navigazione anonima? - - - - Are you sure you want to close the window? There are %1 tab open - Sei sicuro di voler chiudere la finestra? Ci sono %1 schede aperte - - - - Page Source of %1 - Sorgente di %1 - - - - Web Inspector - Ispettore Web - - - - The web inspector will only work correctly for pages that were loaded after enabling. -Do you want to reload all pages? - L'ispettore web funziona correttamente solo con le pagine che sono caricate dopo averlo abilitato. -Vuoi ricaricare tutte le pagine? - - - - Stop loading the current page - Ferma il caricamento della pagina corrente - - - - Reload the current page - Ricarica la pagina corrente - - - - Downloads - Scaricamenti - - - - Alt+Ctrl+L - Download Manager - Alt+Ctrl+L - - - - &Clear Private Data - &Cancella i Dati Privati - - - - Ctrl+Shift+Delete - Clear Private Data - Ctrl+Shift+Canc - - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. - <b>%1</b><br><br>Quando la navigazione anonima è attivata, alcune azioni sono disabilitate nel rispetto della tua privacy:<ul><li> Le pagine non sono aggiunte alla cronologia.</li><li> Gli elementi sono rimossi automaticamente dalla finestra degli scaricamenti.</li><li> Non vengono salvati i nuovi cookie e non è possibile accedere a quelli attuali.</li><li> Le chiavi di ricerca non sono aggiunte al menu che appare sul box di ricerca.</li></ul>Fino a che la finestra è aperta, puoi comunque usare i bottoni Avanti e Indietro per tornare alle pagine che hai già visitato. - - - - ClearButton - - - Clear - Cancella - - - - ClearPrivateData - - - Clear Private Data - Cancella i Dati Privati - - - - Clear the following items: - Cancella questi elementi: - - - - &Browsing History - Cronologia della &Navigazione - - - - &Download History - Cronologia dei &Download - - - - &Search History - Cronologia delle &Ricerche - - - - &Cookies - &Cookie - - - - C&ache - Dati della C&ache - - - - Website &Icons - &Icone dei Siti - - - - Clear &Private Data - Cancella i Dati &Privati - - - - &Cancel - &Annulla - - - - CookieExceptionsModel - - - Website - Sito - - - - Status - Stato - - - - Allow - Consenti - - - - Block - Rifiuta - - - - Allow For Session - Consenti nella Sessione - - - - CookieModel - - - Website - Sito - - - - Name - Nome - - - - Path - Percorso - - - - Secure - Sicuro - - - - Expires - Scade - - - - Contents - Contenuti - - - - CookiesDialog - - - Cookies - Cookie - - - - &Remove - &Cancella - - - - Remove &All Cookies - Cancella &Tutti i Cookie - - - - CookiesExceptionsDialog - - - Cookie Exceptions - Eccezioni - - - - New Exception - Nuova Eccezione - - - - Domain: - Dominio: - - - - Block - Rifiuta - - - - Allow For Session - Consenti nella Sessione - - - - Allow - Consenti - - - - Exceptions - Eccezioni - - - - &Remove - &Cancella - - - - Remove &All - Cancella &Tutti - - - - DownloadDialog - - - Downloads - Scaricamenti - - - - Clean up - Pulisci - - - - 0 Items - Nessun Elemento - - - - DownloadItem - - - Save File - Salva il File - - - - Download canceled: %1 - Download annullato: %1 - - - - Error opening save file: %1 - Errore salvando il file: %1 - - - - Error saving: %1 - Errore durante il salvataggio: %1 - - - - Network Error: %1 - Errore di Rete: %1 - - - - seconds - secondi - - - - minutes - minuti - - - - - %4 %5 remaining - - %4 %5 rimanenti - - - - %1 of %2 (%3/sec) %4 - %1 di %2 (%3/sec) %4 - - - - ? - ? - - - - %1 of %2 - Stopped - %1 di %2 - Fermato - - - - bytes - byte - - - - kB - kB - - - - MB - MB - - - - Form - Scheda - - - - Ico - Ico - - - - Filename - Nome del file - - - - Try Again - Riprova - - - - Stop - Ferma - - - - Open - Apri - - - - DownloadManager - - - 1 Download - 1 Scaricamento - - - - %1 Downloads - %2 Scaricamenti - - - - HistoryDialog - - - Open - Apri - - - - Copy - Copia - - - - Delete - Cancella - - - - History - Cronologia - - - - &Remove - &Cancella - - - - Remove &All - Cancella &Tutti - - - - HistoryMenu - - - Show All History - Mostra tutta la Cronologia - - - - Clear History - Cancella la Cronologia - - - - HistoryModel - - - Title - Titolo - - - - Address - Indirizzo - - - - HistoryTreeModel - - - Earlier Today - Odierni - - - - %1 items - %1 elementi - - - - NetworkAccessManager - - - <qt>Enter username and password for "%1" at %2</qt> - <qt>Inserisci nome utente e password per "%1" su %2</qt> - - - - <qt>Connect to proxy "%1" using:</qt> - <qt>Connettiti al proxy "%1" usando:</qt> - - - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - Errori SSL: - -%1 - -%2 - -Vuoi ignorare questi errori? - - - - Do you want to accept all these certificates? - Accetti tutti questi certificati? - - - - PasswordDialog - - - Authentication Required - E' Richiesta l'Autenticazione - - - - DUMMY ICON - ICONA FANTASMA - - - - INTRO TEXT DUMMY - TESTO FANTASMA - - - - Username: - Nome Utente: - - - - Password: - Password: - - - - ProxyDialog - - - Proxy Authentication - Autenticazione al Proxy - - - - ICON - ICONA - - - - Connect to proxy - Connettiti al proxy - - - - Username: - Nome Utente: - - - - Password: - Password: - - - - QObject - - - The file is not an XBEL version 1.0 file. - Questo file non è un XBEL versione 1.0. - - - - Unknown title - Titolo sconosciuto - - - - SearchBanner - - - Form - Scheda - - - - TextLabel - Etichetta - - - - < - < - - - - > - > - - - - Done - Finito - - - - SearchLineEdit - - - Search - Cerca - - - - Settings - - - Settings - Impostazioni - - - - General - Generali - - - - Home: - Pagina iniziale: - - - - Set to current page - Usa la pagina corrente - - - - Remove history items: - Cancella gli elementi dalla cronologia: - - - - After one day - Dopo un giorno - - - - After one week - Dopo una settimana - - - - After two weeks - Dopo due settimane - - - - After one month - Dopo un mese - - - - After one year - Dopo un anno - - - - Manually - Manualmente - - - - Open links from applications: - Apri i link dalle applicazioni: - - - - In a tab in the current window - In una scheda nella finestra corrente - - - - In a new window - In una nuova finestra - - - - Appearance - Aspetto - - - - Fixed-width font: - Carattere a larghezza fissa: - - - - Privacy - Riservatezza - - - - Web Content - Contenuto Web - - - - Enable Plugins - Abilita i Plugin - - - - Enable Javascript - Abilita il Javascript - - - - Cookies - Cookie - - - - Accept Cookies: - Accetta i Cookie - - - - Always - Sempre - - - - Never - Mai - - - - Only from sites you navigate to - Solo dai siti che stai navigando - - - - Exceptions... - Eccezioni... - - - - Keep until: - Mantienili fino a che: - - - - They expire - Scadono - - - - I exit the application - Esci dall'applicazione - - - - At most 90 days - Al massimo 90 giorni - - - - Cookies... - Cookie... - - - - Proxy - Proxy - - - - Enable proxy - Abilita il proxy - - - - Type: - Tipo: - - - - Socks5 - Socks5 - - - - Http - Http - - - - Host: - Host: - - - - Port: - Porta: - - - - User Name: - Nome Utente: - - - - Password: - Password: - - - - Advanced - Avanzate - - - - Style Sheet: - Stile Web: - - - - Downloads - Scaricamenti - - - - Ask for a destination each time - Chiedi la cartella di destinazione ogni volta - - - - Use this destination: - Usa questa cartella di destinazione: - - - - Standard font: - Font standard: - - - - Times 16 - Times 16 - - - - Select... - Scegli... - - - - Courier 13 - Courier 13 - - - - TabBar - - - New &Tab - &Nuova Scheda - - - - Duplicate Tab - Duplica Scheda - - - - &Close Tab - &Chiudi Scheda - - - - Close &Other Tabs - Chiudi &Altre Schede - - - - Reload Tab - Ricarica Scheda - - - - Reload All Tabs - Ricarica Tutte le Schede - - - - TabWidget - - - New &Tab - &Nuova Scheda - - - - &Close Tab - &Chiudi la Scheda - - - - Show Next Tab - Mostra la Scheda Successiva - - - - Show Previous Tab - Mostra la Scheda Precedente - - - - Recently Closed Tabs - Schede Chiuse di Recente - - - - (Untitled) - (Senza titolo) - - - - Do you really want to close this page? - Sei sicuro di voler chiudere questa pagina? - - - - You have modified this page and when closing it you would lose the modification. -Do you really want to close this page? - - Hai modificato questa pagina e chiudendola perderai la tua modifica. -Sei sicuro di volerlo fare? - - - - - ToolbarSearch - - - Google - Google - - - - No Recent Searches - Nessuna Ricerca Recente - - - - Recent Searches - Ricerche Recenti - - - - Clear Recent Searches - Cancella le Ricerche Recenti - - - - WebPage - - - Error loading page: %1 - Errore aprendo la pagina: %1 - - - - WebView - - - Open in New &Window - Apri in una Nuova &Finestra - - - - Open in New &Tab - Apri in una Nuova &Scheda - - - - Save Lin&k - Salva il Lin&k - - - - &Bookmark This Link - Salva il Link nei Segnali&bri - - - - &Copy Link Location - &Copia il link - - - - Open Image in New &Window - Apri l'Immagine un una nuova &Finestra - - - - Open Image in New &Tab - Apri l'Immagine in una nuova &Scheda - - - - &Save Image - &Salva l'Immagine - - - - &Copy Image - &Copia l'Immagine negli Appunti - - - - C&opy Image Location - C&opia l'indirizzo dell'Immagine - - - - WebViewSearch - - - Not Found - Non Trovato - - - diff --git a/src/locale/it_IT.ts b/src/locale/it_IT.ts new file mode 100644 index 00000000..36818aff --- /dev/null +++ b/src/locale/it_IT.ts @@ -0,0 +1,2256 @@ + + + + + AboutDialog + + About + Informazioni + + + Lightweight WebKit-based web browser + Browser web leggero basato su WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Authors + Autori + + + License + Licenza + + + Close + Chiudi + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + About %1 + Informazioni su %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + Versione di WebKit: %1 + + + + AcceptLanguage + + Languages + Lingue + + + Languages: in order of preference: + Lingue: in ordine di preferenza: + + + Move &Up + &Sposta in alto + + + Move &Down + Sposta in &basso + + + &Remove + &Rimuovi + + + Add... + Aggiungi... + + + + AddBookmarkDialog + + Add Bookmark + Aggiungi un segnalibro + + + Type a name for the bookmark, and choose where to keep it. + Scrivi il nome del segnalibro, e scegli dove metterlo. + + + Url + + + + Title + Titolo + + + Add Folder + Aggiungi cartella + + + + BookmarksDialog + + Open + Apri + + + Delete + Elimina + + + New Folder + Nuova cartella + + + Bookmarks + Segnalibri + + + &Remove + &Rimuovi + + + Add Folder + Aggiungi cartella + + + Open in New Tab + Apri in una nuova scheda + + + Edit Name + Modifica nome + + + Edit Address + Modifica indirizzo + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Errore durante l'apertura dei segnalibri alla riga %1, colonna %2: +%3 + + + Toolbar Bookmarks + Barra dei segnalibri + + + Menu + Menu + + + Open File + Apri file + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importati %1 + + + Save File + Salva il file + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Errore in fase di esportazione + + + error saving bookmarks + errore durante il salvataggio dei segnalibri + + + Remove Bookmark + Rimuovi segnalibro + + + Insert Bookmark + Inserisci segnalibro + + + Name Change + Cambia il nome + + + Address Change + Cambia l'indirizzo + + + Bookmarks Bar + Barra dei segnalibri + + + Bookmarks Menu + Menu Segnalibri + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Errore durante il caricamento di segnalibri html: %1 + + + + Name Change + Undo bookmark title change + Cambio nome + + + Address Change + Undo bookmark url change + Cambio indirizzo + + + XBEL bookmarks + Segnalibri XBEL + + + HTML Netscape bookmarks + Segnalibri HTML Netscape + + + htmlToXBel tool required + Strumento htmlToXBel richiesto + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Lo strumento htmlToXBel, fornito con Arora e necessario a importare segnalibri HTML, non è installato o non è disponibile nei percorsi di ricerca. + + + Loading Bookmark + Caricamento segnalibro + + + Error when loading HTML bookmarks: %1 + + Errore durante il caricamento dei segnalibri HTML: %1 + + + + + BookmarksMenu + + Open in Tabs + Apri in schede + + + + BookmarksModel + + Title + Titolo + + + Address + Indirizzo + + + + BookmarksToolBar + + Bookmark + Segnalibro + + + Open + Apri + + + Open in New &Tab + Apri in una nuova &scheda + + + Remove + Rimuovi + + + Add Bookmark... + Aggiungi segnalibro... + + + Add Folder... + Aggiungi cartella... + + + Bookmarks + Segnalibri + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Ci sono %1 finestre e %2 schede aperte +Sei sicuro di voler uscire? + + + Restore failed + Ripristino non riuscito + + + The saved session will not being restored because last time it was restored Arora crashed. + La sessione salvata non sarà ripristinata perché l'ultima volta che è stata ripristinata Arora è andato in crash. + + + (Change: %1 %2) + (Cambia: %1 %2) + + + The saved session will not be restored because Arora crashed while trying to restore this session. + La sessione salvata non sarà ripristinata perché Arora si è chiuso in modo inatteso nel tentativo di ripristinarla. + + + + BrowserMainWindow + + &File + &File + + + &New Window + &Nuova finestra + + + &Open File... + &Apri file... + + + Open &Location... + &Apri indirizzo... + + + &Save As... + &Salva come... + + + &Import Bookmarks... + &Importa i segnalibri... + + + &Export Bookmarks... + &Esporta i segnalibri... + + + P&rint Preview... + An&teprima di stampa... + + + &Print... + Stam&pa... + + + Private &Browsing... + &Navigazione anonima... + + + &Quit + &Esci + + + &Edit + &Modifica + + + &Undo + &Annulla + + + &Redo + &Ripeti + + + Cu&t + &Taglia + + + &Copy + &Copia + + + &Paste + &Incolla + + + &Find + Tro&va + + + &Find Next + Tro&va successivo + + + &Find Previous + Tro&va precedente + + + &Preferences + &Preferenze + + + Ctrl+, + Ctrl+, + + + &View + &Visualizza + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Ferma + + + Reload Page + Ricarica la pagina + + + &Make Text Bigger + &Ingrandisci il testo + + + &Make Text Normal + &Dimensione normale + + + &Make Text Smaller + &Rimpicciolisci il testo + + + Page S&ource + &Sorgente della pagina + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Schermo intero + + + Hi&story + &Cronologia + + + Back + Indietro + + + Forward + Avanti + + + Home + Pagina iniziale + + + Restore Last Session + Ripristina la sessione precedente + + + &Bookmarks + &Segnalibri + + + Manage Bookmarks... + Gestione dei segnalibri... + + + Add Bookmark... + Aggiungi segnalibro... + + + &Window + &Finestra + + + &Tools + &Strumenti + + + Web &Search + &Ricerca nel web + + + Ctrl+K + Web Search + Ctrl+K + + + Enable Web &Inspector + Abilita l'anal&izzatore web + + + &Help + &Aiuto + + + About &Qt + Informazioni su &Qt + + + About &Arora + Informazioni su &Arora + + + Navigation + Navigazione + + + Show Status Bar + Mostra la barra di stato + + + Hide Status Bar + Nascondi la barra di stato + + + Show Toolbar + Mostra la barra degli strumenti + + + Hide Toolbar + Nascondi la barra degli strumenti + + + Show Bookmarks bar + Mostra la Barra Dei Segnalibri + + + Hide Bookmarks bar + Nascondi la Barra Dei Segnalibri + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Apri risorsa web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Risorse web (*.html *.htm *.svg *.png *.gif *.svgz);;Tutti i file (*.*) + + + Print Document + Stampa documento + + + Are you sure you want to turn on private browsing? + Sei sicuro di voler passare alla navigazione anonima? + + + Are you sure you want to close the window? There are %1 tabs open + Sei sicuro di voler chiudere la finestra? Ci sono %1 schede aperte + + + Page Source of %1 + Sorgente di %1 + + + Web Inspector + Analizzatore web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + L'analizzatore web funziona correttamente solo con le pagine che sono caricate dopo averlo abilitato. +Vuoi ricaricare tutte le pagine? + + + Stop loading the current page + Ferma il caricamento della pagina attuale + + + Reload the current page + Ricarica la pagina attuale + + + Downloads + Scaricamenti + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + &Clear Private Data + &Cancella i dati privati + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Canc + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Quando la navigazione anonima è attivata, alcune azioni sono disabilitate nel rispetto della tua privacy:<ul><li> Le pagine non sono aggiunte alla cronologia.</li><li> Gli elementi sono rimossi automaticamente dalla finestra degli scaricamenti.</li><li> Non vengono salvati i nuovi cookie e non è possibile accedere a quelli attuali.</li><li> Le chiavi di ricerca non sono aggiunte al menu che appare sulla riquadro di ricerca.</li></ul>Fino a che la finestra è aperta, puoi comunque usare i pulsanti Avanti e Indietro per tornare alle pagine che hai già visitato. + + + Show Bookmarks Bar + Mostra la barra dei segnalibri + + + Hide Bookmarks Bar + Nascondi la barra dei segnalibri + + + Find Nex&t + &Trova successivo + + + Find P&revious + Trova p&recedente + + + Prefere&nces... + Prefere&nze... + + + Show Menu Bar + Mostra barra dei menu + + + &Reload Page + &Ricarica pagina + + + Make Text &Bigger + &Ingrandisci testo + + + Make Text &Normal + Ripristi&na dimensione testo + + + Make Text &Smaller + Riduci te&sto + + + Show &Network Monitor + Mostra mo&nitor di rete + + + Switch application language + Cambia lingua applicazione + + + Close Window + Chiudi finestra + + + Zoom &In + Au&menta zoom + + + Zoom &Normal + Dimensioni &normali + + + Zoom &Out + Riduci z&oom + + + Zoom &Text Only + Ingrandisci solo il &testo + + + Show All Bookmarks... + Mostra tutti i segnalibri... + + + Add Folder... + Aggiungi cartella... + + + About &%1 + About Browser + Informazioni su &%1 + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Quando la navigazione anonima è attiva, alcune azioni riguardanti la riservatezza saranno disabilitate:<ul><li> Le pagine web non sono aggiunte alla cronologia.</li><li> Gli elementi sono rimossi automaticamente dalla finestra Scaricamenti.</li><li> I nuovi cookie non sono conservati, non è possibile accedere ai cookie correnti.</li><li> Le icone dei siti non saranno memorizzate, le sessioni non saranno salvate.</li><li> Le ricerche non sono aggiunte al menu a comparsa nel riquadro di ricerca.</li></ul>Fino alla chiusura della finestra, è ancora possibile fare clic sui pulsanti Indietro e Avanti per tornare alle pagine web aperte in precedenza. + + + Ctrl+Y + Download Manager + + + + Default + Predefinita + + + Text Encoding + Codifica del testo + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> Network cache is disabled.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Quando la navigazione anonima è attivata, alcune azioni relative alla riservatezza saranno disabilitate:<ul><li> Le pagine web non saranno aggiunte alla cronologia.</li><li> Gli elementi presenti nella finestra Scaricamenti saranno rimossi automaticamente.</li><li> I nuovi cookie non sono conservati, i cookie correnti non sono accessibili.</li><li> Le icone dei siti non saranno conservate, le sessioni non saranno salvate.</li><li> Le ricerche non sono aggiunte al menu a comparsa nel riquadro di ricerca.</li><li> La cache di rete è disabilitata.</li></ul>Fino alla chiusura della finestra, potrai fare clic sui pulsanti Indietro e Avanti per tornare alle pagine precedentemente aperte. + + + Select &All + Selezion&a tutto + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Quando la navigazione anonima è abilitata, alcune azioni relative alla riservatezza saranno disabilitate:<ul><li> Le pagine web non sono aggiunte alla cronologia.</li><li> Gli elementi sono automaticamente rimossi dalla finestra Scaricamenti.</li><li> I nuovi cookie non sono salvati, i cookie attuali non sono accessibili.</li><li> Le icone dei siti non saranno salvate, come le sessioni.</li><li> Le ricerche non sono aggiunte al menu a comparsa nel riquadro di ricerca.</li><li> Nessuna cache di rete sarà scritta su disco.</li></ul>Fino alla chiusura della finestra, sarà possibile fare clic sui pulsanti Indietro e Avanti per tornare alle pagine web aperte. + + + + ClearButton + + Clear + Cancella + + + + ClearPrivateData + + Clear Private Data + Cancella i dati privati + + + Clear the following items: + Cancella questi elementi: + + + &Browsing History + Cronologia della &navigazione + + + &Download History + Cronolo&gia degli scaricamenti + + + &Search History + Cronologia delle &ricerche + + + &Cookies + &Cookie + + + C&ache + C&ache + + + Website &Icons + &Icone dei siti + + + Clear &Private Data + Cancella i dati &privati + + + &Cancel + &Annulla + + + C&ached Web Pages + Pagine web in c&ache + + + + ClickToFlash + + Load + Carica + + + Load All + Carica tutto + + + Add %1 to Whitelist + Aggiungi %1 ai siti autorizzati + + + Remove from Whitelist + Rimuovi dai siti autorizzati + + + Settings + Impostazioni + + + Load Flash + Carica Flash + + + + ClickToFlashSettings + + Whitelist sites + Siti autorizzati + + + + CookieExceptionsModel + + Website + Sito web + + + Status + Stato + + + Allow + Consenti + + + Block + Rifiuta + + + Allow For Session + Consenti nella sessione + + + Rule + Regola + + + + CookieModel + + Website + Sito web + + + Name + Nome + + + Path + Percorso + + + Secure + Sicuro + + + Expires + Scade + + + Contents + Contenuti + + + true + vero + + + false + falso + + + Session cookie + Cookie di sessione + + + + CookiesDialog + + Cookies + Cookie + + + &Remove + &Rimuovi + + + Remove &All Cookies + Rimuovi &tutti i cookie + + + Add &Rule + Aggiungi &regola + + + + CookiesExceptionsDialog + + Cookie Exceptions + Eccezioni + + + New Exception + Nuova eccezione + + + Domain: + Dominio: + + + Block + Rifiuta + + + Allow For Session + Consenti nella sessione + + + Allow + Consenti + + + Exceptions + Eccezioni + + + &Remove + &Rimuovi + + + Remove &All + Rimuovi &tutti + + + + DownloadDialog + + Downloads + Scaricamenti + + + Clean up + Pulisci + + + 0 Items + 0 elementi + + + &OK + &OK + + + + DownloadItem + + Save File + Salva il file + + + Download canceled: %1 + Scaricamento annullato: %1 + + + Error opening save file: %1 + Errore durante l'apertura del file: %1 + + + Error saving: %1 + Errore durante il salvataggio: %1 + + + Network Error: %1 + Errore di rete: %1 + + + seconds + secondi + + + minutes + minuti + + + - %4 %5 remaining + - %4 %5 rimanenti + + + %1 of %2 (%3/sec) %4 + %1 di %2 (%3/sec) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 di %2 - Fermato + + + bytes + byte + + + kB + kB + + + MB + MB + + + Form + Modulo + + + Ico + Ico + + + Filename + Nome del file + + + Try Again + Riprova + + + Stop + Ferma + + + Open + Apri + + + - %n minutes remaining + + - %n minuto rimanente + - %n minuti rimanenti + + + + - %n seconds remaining + + - %n secondo rimanente + - %n secondi rimanenti + + + + Error opening output file: %1 + Errore nel file di output: %1 + + + %1 of %2 (%3/sec) - %4 + %1 di %2 (%3/sec) - %4 + + + Download directory (%1) couldn't be created. + La cartella degli scaricamenti (%1) non può essere creata. + + + + DownloadManager + + 1 Download + 1 Scaricamento + + + %1 Downloads + %2 Scaricamenti + + + %n Download(s) + + %n scaricamento + %n scaricamenti + + + + There are %1 downloads in progress +Do you want to quit anyway? + Ci sono %1 scaricamenti in corso +Vuoi uscire comunque? + + + %n minutes remaining + + Un minuto rimanente + %n minuti rimanenti + + + + %n seconds remaining + + Un secondo rimanente + %n secondi rimanenti + + + + bytes + byte + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Nessun errore + + + Error opening: %1: No such file or directory + Errore di apertura: %1: Nessun file o cartella + + + Unable to read %1 + Impossibile leggere %1 + + + Contents of %1 + Contenuto di %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + Apri + + + Copy + Copia + + + Delete + Elimina + + + History + Cronologia + + + &Remove + &Rimuovi + + + Remove &All + Rimuovi &tutti + + + + HistoryMenu + + Show All History + Mostra tutta la cronologia + + + Clear History + Cancella la cronologia + + + Clear History... + Cancella la cronologia... + + + Do you want to clear the history? + Sei sicuro di voler cancellare la cronologia? + + + + HistoryModel + + Title + Titolo + + + Address + Indirizzo + + + + HistoryTreeModel + + Earlier Today + Prima di oggi + + + %1 items + %1 elementi + + + %n item(s) + + %n elemento + %n elementi + + + + + JavaScriptAroraObject + + Welcome to Arora! + Benvenuti in Arora! + + + Arora Start + Avvio di Arora + + + Search! + Cerca! + + + Search results provided by + Risultati di ricerca forniti da + + + About Arora + Informazioni su Arora + + + + LanguageManager + + Default + Predefinita + + + Choose language + Scegli la lingua + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Puoi utilizzare una lingua differente da<br>quella predefinita del sistema operativo.</p><p>Scegli la lingua da utilizzare</p> + + + No translation files are installed. + Nessun file di traduzione installato. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Inserisci nome utente e password per "%1" su %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Connettiti al proxy "%1" usando:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Errori SSL: + +%1 + +%2 + +Vuoi ignorare questi errori? + + + Do you want to accept all these certificates? + Vuoi accettare tutti questi certificati? + + + - SSL Errors + - Errori SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Errori SSL:<br/><br/>per: <tt>%1</tt><ul><li>%2</li></ul> + +Vuoi ignorare questi errori?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificati:<br/>%1<br/>Vuoi accettare tutti questi certificati?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificati:<br/>%1<br/>Vuoi accettare tutti questi certificati?</qt> + + + Issuer: %1 + Emittente: %1 + + + Not valid before: %1 + Non valido prima di: %1 + + + Valid until: %1 + Valido fino a: %1 + + + Alternate Names: + Nomi alternativi: + + + + NetworkMonitor + + Name + Nome + + + Value + Valore + + + + NetworkMonitorDialog + + Network Monitor + Monitor di rete + + + Network Requests + Richieste di rete + + + Request Headers + Intestazioni di richiesta + + + Response Headers + Intestazioni di risposta + + + &Remove + &Rimuovi + + + Remove &All Requests + Rimuovi &tutte le richieste + + + + OpenSearchDialog + + Open File + Apri file + + + OpenSearch + + + + Error + Errore + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 non è una descrizione OpenSearch 1.1 valida o è già nell'elenco. + + + You must have at least one search engine in here. + Devi avere almeno un motore di ricerca. + + + OpenSearch Manager + Gestore OpenSearch + + + &Restore Defaults + &Ripristina valori predefiniti + + + &Delete + &Elimina + + + &Add + &Aggiungi + + + &Close + &Chiudi + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descrizione:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Fornisce suggerimenti di contesto</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Elenco di parole chiave, separate da virgole, seguito da termini di ricerca che può essere inserito nella barra degli indirizzi per cercare con questo motore + + + Name + Nome + + + Keywords + Parole chiave + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Vuoi aggiungere il seguente motore all'elenco dei motori di ricerca?<br /><br />Nome: %1<br />Ricerca in: %2 + + + + PasswordDialog + + Authentication Required + Autenticazione richiesta + + + DUMMY ICON + ICONA FANTASMA + + + INTRO TEXT DUMMY + TESTO INTRODUTTIVO FANTASMA + + + Username: + Nome utente: + + + Password: + Password: + + + + PlainTextEditSearch + + Not Found + Non trovato + + + + ProxyDialog + + Proxy Authentication + Autenticazione al proxy + + + ICON + ICONA + + + Connect to proxy + Connettiti al proxy + + + Username: + Nome utente: + + + Password: + Password: + + + + QObject + + The file is not an XBEL version 1.0 file. + Questo file non è un XBEL versione 1.0. + + + Unknown title + Titolo sconosciuto + + + The file is not an OpenSearch 1.1 file. + Non è un file OpenSearch 1.1. + + + + RequestModel + + Redirect: %1 + Redirezione: %1 + + + Method + Metodo + + + Address + Indirizzo + + + Response + Risposta + + + Length + Lunghezza + + + Content Type + Tipo contenuto + + + Info + Info + + + + SearchBanner + + Form + Modulo + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + Finito + + + Highlight All + Seleziona tutto + + + + SearchLineEdit + + Search + Cerca + + + + Settings + + Settings + Impostazioni + + + General + Generale + + + Home: + Pagina iniziale: + + + Set to current page + Usa la pagina corrente + + + Remove history items: + Rimuovi gli elementi dalla cronologia: + + + After one day + Dopo un giorno + + + After one week + Dopo una settimana + + + After two weeks + Dopo due settimane + + + After one month + Dopo un mese + + + After one year + Dopo un anno + + + Manually + Manualmente + + + Open links from applications: + Apri i collegamenti dalle applicazioni: + + + In a tab in the current window + In una scheda nella finestra corrente + + + In a new window + In una nuova finestra + + + Appearance + Aspetto + + + Fixed-width font: + Carattere a larghezza fissa: + + + Privacy + Riservatezza + + + Web Content + Contenuto web + + + Enable Plugins + Abilita i plugin + + + Enable Javascript + Abilita Javascript + + + Cookies + Cookie + + + Accept Cookies: + Accetta cookie: + + + Always + Sempre + + + Never + Mai + + + Only from sites you navigate to + Solo dai siti che stai navigando + + + Exceptions... + Eccezioni... + + + Keep until: + Mantienili fino a che: + + + They expire + Scadono + + + I exit the application + Esci dall'applicazione + + + At most 90 days + Al massimo 90 giorni + + + Cookies... + Cookie... + + + Proxy + Proxy + + + Enable proxy + Abilita il proxy + + + Type: + Tipo: + + + Socks5 + Socks5 + + + Http + Http + + + Host: + Host: + + + Port: + Porta: + + + User Name: + Nome utente: + + + Password: + Password: + + + Advanced + Avanzate + + + Style Sheet: + Foglio di stile: + + + Downloads + Scaricamenti + + + Ask for a destination each time + Chiedi la cartella di destinazione ogni volta + + + Use this destination: + Usa questa cartella di destinazione: + + + Standard font: + Carattere standard: + + + Times 16 + Times 16 + + + Select... + Seleziona... + + + Courier 13 + Courier 13 + + + On startup: + All'avvio: + + + Show my home page + Mostra la pagina iniziale + + + Show a blank page + Mostra una pagina vuota + + + Restore windows and tabs from last time + Ripristina le finestre e le schede dell'ultima sessione + + + On application exit + All'uscita + + + Enable Images + Abilita immagini + + + Tabs + Schede + + + Select tabs and windows as they are created + Seleziona schede e finestre a seconda di come sono state create + + + Confirm when closing multiple tabs + Chiedi conferma durante la chiusura di schede multiple + + + Preferences + Preferenze + + + Home Page: + Pagina iniziale: + + + View Images + Visualizza immagini + + + Keep Cookies Until: + Mantieni i cookie fino a che: + + + Use proxy server + Utilizza server proxy + + + Host name: + Nome server: + + + Show only one close button instead of one for each tab + Mostra solo un pulsante di chiusura al posto di uno per ogni scheda + + + Preferred languages for viewing webpages in: + Lingue preferite per visualizzare le pagine web: + + + Block Popup Windows + Blocca finestre a comparsa + + + Opening links + Apertura collegamenti + + + Links that want to open in a new window: + Collegamenti da aprire in una nuova finestra: + + + In a new selected tab in the current window + In una nuova scheda selezionata nella finestra corrente + + + In a new tab in the current window + In una nuova scheda della finestra corrente + + + In the current tab + Nella scheda corrente + + + Http (Secure) + Http (Sicuro) + + + Http (Transparent) + Http (Trasparente) + + + Use ClickToFlash on flash plugins + Utilizza ClickToFlash sui plugin flash + + + Filter Tracking Cookies + Filtra i cookie traccianti + + + Confirm when closing multiple tabs or windows + Conferma in caso di chiusura di più schede o finestre + + + Quit the application when last tab is closed + Esci dall'applicazione alla chiusura dell'ultima scheda + + + Enable network cache + Abilita cache di rete + + + Maximum Size: + Dimensione massima: + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + Utilizza il motore di ricerca predefinito come ripiego quando l'URL specificato dall'utente non è valido + + + Choose Directory... + Scegli cartella... + + + + SettingsDialog + + Restart required + Riavvio necessario + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + La configurazione della cache di rete è cambiata. Affiché le modifiche abbiano effetto, è necessario riavviare il browser. + + + Choose Directory + Scegli cartella + + + + SourceViewer + + Loading... + Caricamento in corso ... + + + &Edit + &Modifica + + + &Find + Tro&va + + + &View + &Visualizza + + + &Wrap lines + Test&o a capo + + + Source of Page + Sorgente della pagina + + + Source of Page %1 + Sorgente della pagina %1 + + + + TabBar + + New &Tab + &Nuova scheda + + + Duplicate Tab + Duplica scheda + + + &Close Tab + &Chiudi scheda + + + Close &Other Tabs + Chiudi &altre schede + + + Reload Tab + Ricarica scheda + + + Reload All Tabs + Ricarica tutte le schede + + + Show Tab Bar + Mostra la barra delle schede + + + Hide Tab Bar + Nascondi la barra delle schede + + + + TabWidget + + New &Tab + &Nuova scheda + + + &Close Tab + &Chiudi la scheda + + + Show Next Tab + Mostra la scheda successiva + + + Show Previous Tab + Mostra la scheda precedente + + + Recently Closed Tabs + Schede chiuse di recente + + + (Untitled) + (Senza titolo) + + + Do you really want to close this page? + Sei sicuro di voler chiudere questa pagina? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Hai modificato questa pagina e chiudendola perderai le modifiche. +Sei sicuro di volerlo fare? + + + + Untitled + Senza titolo + + + Ctrl-] + + + + Ctrl-[ + + + + Saved Tabs + Schede salvate + + + Loading... + Caricamento in corso... + + + Loading %1% (%2 %3)... + Caricamento di %1% (%2 %3)... + + + Finished loading + Caricamento completato + + + Failed to load + Caricamento non riuscito + + + Bookmark All Tabs + Segnalibri di tutte le schede + + + + ToolbarSearch + + Google + Google + + + No Recent Searches + Nessuna ricerca recente + + + Recent Searches + Ricerche recenti + + + Clear Recent Searches + Cancella ricerche recenti + + + Suggestions + Suggerimenti + + + Add '%1' + Aggiungi '%1' + + + Configure Search Engines... + Configura motori di ricerca... + + + + WebPage + + Error loading page: %1 + Errore durante l'apertura della pagina: %1 + + + When connecting to: %1. + Durante la connessione a: %1. + + + Check the address for errors such as <b>ww</b>.trolltech.com instead of <b>www</b>.trolltech.com. + Controlla che l'indirizzo non contenga errori tipo <b>ww</b>.trolltech.com al posto di <b>www</b>.trolltech.com. + + + If the address is correct, try to check the network connection. + Se l'indirizzo è corretto, controlla il corretto funzionamento della connessione di rete. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Se il computer o la rete sono protette da un firewall o da un proxy, controlla che il browser abbia i permessi per accedere alla rete. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Controlla la presenza nell'indirizzo di errori del tipo <b>ww</b>.arora-browser.org invece che <b>www</b>.arora-browser.org + + + If the address is correct, try checking the network connection. + Se l'indirizzo è corretto, prova a verificare la connessione di rete. + + + Resending POST request + Nuovo invio della richiesta POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Per visualizzare il sito, la richiesta con tutti i dati deve essere inviata nuovamente, ciò potrebbe causare un comportamento imprevisto del sito, ad es. la stessa azione potrebbe essere eseguita due volte. Vuoi continuare comunque? + + + + WebView + + Open in New &Window + Apri in una nuova &finestra + + + Open in New &Tab + Apri in una nuova &scheda + + + Save Lin&k + Salva il colle&gamento + + + &Bookmark This Link + Salva il collegamento nei segnali&bri + + + &Copy Link Location + &Copia l'indirizzo del collegamento + + + Open Image in New &Window + Apri l'immagine un una nuova &finestra + + + Open Image in New &Tab + Apri l'immagine in una nuova &scheda + + + &Save Image + &Salva l'immagine + + + &Copy Image + &Copia l'immagine + + + C&opy Image Location + C&opia l'indirizzo dell'immagine + + + Loading... + Caricamento in corso ... + + + Search with... + Cerca con... + + + Add to the toolbar search + Aggiungi alla barra delle ricerche + + + Method not supported + Metodo non supportato + + + %1 method is not supported. + Il metodo %1 non è supportato. + + + Search engine + Motore di ricerca + + + Choose the desired search engine + Scegli il motore di ricerca desiderato + + + Engine name + Nome del motore + + + Type in a name for the engine + Digita un nome per il motore + + + + WebViewSearch + + Not Found + Non trovato + + + diff --git a/src/locale/ja_JP.ts b/src/locale/ja_JP.ts new file mode 100644 index 00000000..4f6b28be --- /dev/null +++ b/src/locale/ja_JP.ts @@ -0,0 +1,2363 @@ + + + + + AboutDialog + + About + About + + + Authors + 著作者 + + + License + ライセンス + + + Lightweight WebKit-based web browser + WebKit ベースの軽いブラウザ + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + 閉じる + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + About %1 + %1 について + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + WebKit バージョン: %1 + + + + AcceptLanguage + + Languages + 言語 + + + Languages: in order of preference: + 言語の優先順位: + + + Move &Up + 上へ(&U) + + + Move &Down + 下へ(&D) + + + &Remove + 削除(&R) + + + Add... + 追加... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + AdBlock ルール:%1 によってブロックされました + + + + AdBlockDialog + + Add Custom Rule + カスタム ルールの追加 + + + Learn more about writing rules... + ルールの書き方について... + + + Update Subscription + サブスクリプションの更新 + + + Browse Subscriptions... + サブスクリプションを参照... + + + Remove Subscription + サブスクリプションを削除 + + + AdBlock Configuration + AdBlock 設定 + + + Enable AdBlock + AdBlock を有効にする + + + Action + アクション + + + + AdBlockManager + + Custom Rules + カスタム ルール + + + + AdBlockModel + + Rule + ルール + + + + AdBlockSchemeAccessHandler + + Subscribe? + 登録しますか? + + + Subscribe to this AdBlock subscription? +%1 + この AdBlock サブスクリプションを登録しますか? +%1 + + + + AddBookmarkDialog + + Add Bookmark + ブックマークの追加 + + + Type a name for the bookmark, and choose where to keep it. + ブックマーク名を入力して、保存先を選択してください. + + + Url + URL + + + Title + 名前 + + + Add Folder + フォルダの追加 + + + + AutoFillDialog + + Form Passwords + フォーム パスワード + + + Remove + 削除 + + + Remove All + 全て削除 + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>パスワードを保存しますか?</b><br> 保存したり削除したパスワードを見直すには、オプションの自動入力タブを開いてください。 + + + Never for this site + このサイトでは記憶しない + + + Not now + 今は記憶しない + + + + AutoFillModel + + WebSite + Webサイト + + + User Name + ユーザ名 + + + + BookmarksDialog + + Open + 開く + + + Open in New Tab + 新しいタブで開く + + + Delete + 削除 + + + New Folder + 新しいフォルダ + + + Bookmarks + ブックマーク + + + &Remove + 削除(&R) + + + Add Folder + フォルダの追加 + + + Edit Name + 名前を編集 + + + Edit Address + URLを編集 + + + + BookmarksManager + + Open File + ブックマークのインポート + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + %1 をインポートしました + + + Save File + ブックマークのエクスポート + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Error when loading bookmarks on line %1, column %2: +%3 + %1 行目 %2 文字目のブックマークを読み込み中にエラー: +%3 + + + Toolbar Bookmarks + Toolbar Bookmarks + + + Menu + メニュー + + + Export error + エクスポート エラー + + + error saving bookmarks + ブックマークの保存中にエラー + + + Remove Bookmark + Remove Bookmark + + + Insert Bookmark + ブックマークの追加 + + + Name Change + 名前変更 + + + Address Change + アドレス変更 + + + Bookmarks Bar + ブックマーク バー + + + Bookmarks Menu + ブックマーク メニュー + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + HTML形式ブックマークの読み込み中にエラー: %1 + + + + XBEL + XBEL + + + Name Change + Undo bookmark title change + 名前変更 + + + Address Change + Undo bookmark url change + アドレス変更 + + + XBEL bookmarks + XBEL ブックマーク + + + HTML Netscape bookmarks + HTML Netscape ブックマーク + + + htmlToXBel tool required + htmlToXBel ツールが必要です + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + HTML ブックマークをインポートするのに必要な Arora に搭載されている htmlToXBel ツールがインストールされていないかパスが通っていません。 + + + Loading Bookmark + ブックマークを読み込んでいます + + + Error when loading HTML bookmarks: %1 + + HTML ブックマーク読込時にエラー: %1 + + + + + BookmarksMenu + + Open in Tabs + タブで開く + + + + BookmarksModel + + Title + 名前 + + + Address + アドレス + + + + BookmarksToolBar + + Bookmark + ブックマーク + + + Open + 開く + + + Open in New &Tab + 新しいタブで開く(&T) + + + Remove + 削除 + + + Add Bookmark... + ブックマークに追加... + + + Add Folder... + フォルダの追加... + + + Bookmarks + ブックマーク + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + %1 個のウィンドウと %2 個のタブが開いています. +本当に終了しますか? + + + Restore failed + 復元に失敗 + + + (Change: %1 %2) + (Change: %1 %2) + + + The saved session will not be restored because Arora crashed while trying to restore this session. + このセッションを復元を試みて Arora がクラッシュした為、保存されたセッションは復元されない可能性があります。 + + + Arora crashed while trying to restore this session. Should I try again? + Arora は、セッションの復元を試みている時にクラッシュしました。再度復元を試みますか? + + + + BrowserMainWindow + + &File + ファイル(&F) + + + &New Window + 新しいウィンドウ(&N) + + + &Open File... + 開く(&O)... + + + Open &Location... + URLを開く(&L)... + + + &Save As... + 名前をつけて保存(&A)... + + + &Import Bookmarks... + ブックマークをインポート(&I)... + + + &Export Bookmarks... + ブックマークをエクスポート(&E)... + + + P&rint Preview... + 印刷プレビュー(&R)... + + + &Print... + 印刷(&P)... + + + Private &Browsing... + プライベート ブラウジング(&B)... + + + &Quit + 終了(&Q) + + + &Edit + 編集(&E) + + + &Undo + 元に戻す(&U) + + + &Redo + やり直す(&R) + + + Cu&t + 切り取り(&T) + + + &Copy + コピー(&C) + + + &Paste + 貼り付け(&P) + + + &Find + 検索(&F) + + + Find Nex&t + 次を検索(&T) + + + Find P&revious + 前を検索(&R) + + + Prefere&nces... + 設定(&N)... + + + Ctrl+, + Ctrl+, + + + &View + 表示(&V) + + + Show Menu Bar + メニュー バーを表示 + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + 停止(&S) + + + &Reload Page + 再読込(&R) + + + Make Text &Bigger + 文字を大きくする(&B) + + + Make Text &Normal + 文字を通常サイズにする(&N) + + + Make Text &Smaller + 文字を小さくする(&S) + + + Page S&ource + ソースを表示(&O) + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + 全画面表示(&F) + + + Hi&story + 履歴(&S) + + + Back + 戻る + + + Forward + 進む + + + Home + ホーム + + + Restore Last Session + 最後のセッションを復元 + + + &Bookmarks + ブックマーク(&B) + + + Manage Bookmarks... + ブックマークの管理... + + + Add Bookmark... + ブックマークに追加... + + + &Window + ウィンドウ(&W) + + + &Tools + ツール(&T) + + + Web &Search + Web 検索(&S) + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + プライバシー情報の削除(&C) + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Web インスペクタを有効化(&I) + + + &Help + ヘルプ(&H) + + + Switch application language + 言語の切り替え + + + About &Qt + Qt について(&Q) + + + About &Arora + Arora について(&A) + + + Navigation + ナビゲーション + + + Show Status Bar + ステータス バーを表示 + + + Hide Status Bar + ステータス バーを隠す + + + Show Toolbar + ツールバーを表示 + + + Hide Toolbar + ツールバーを隠す + + + Show Bookmarks Bar + ブックマーク バーを表示 + + + Hide Bookmarks Bar + ブックマーク バーを隠す + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Web リソースを開く + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Web リソース (*.html *.htm *.svg *.png *.gif *.svgz);;全てのファイル (*.*) + + + Print Document + ドキュメントの印刷 + + + Are you sure you want to turn on private browsing? + プライベート ブラウジングを開始しますか? + + + Are you sure you want to close the window? There are %1 tabs open + %1 個のタブを開いていますが、ウィンドウを閉じますか? + + + Web Inspector + Web インスペクタ + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Web インスペクタは、ページを読み込む前から有効になっていなければ正しく動作しません. +全てのページを再読込しますか? + + + Stop loading the current page + 現在のページの読込を中止します + + + Reload the current page + 現在のページを再読込 + + + Downloads + ダウンロード + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>プライベート モードに移行した場合、あなたのプライバシーを守る為、いくつかの機能は制限されます:<ul><li> 表示したページは履歴に追加されません。</li><li> ダウンロード履歴は残りません。</li><li> 新しく受け取った Cookie は保存されません。既に保存済みの Cookie を参照する事もできません。</li><li> Web サイトのアイコンやセッションは保存されません。</li><li> 検索ボックスの検索履歴に追加されません。</li></ul>ウィンドウを閉じるまで閲覧した Web ページに戻る/進むボタンで戻る事ができます。 + + + Show &Network Monitor + ネットワーク モニタを表示(&N) + + + Close Window + ウィンドウを閉じる + + + Zoom &In + 拡大(&I) + + + Zoom &Normal + 通常サイズに戻す(&N) + + + Zoom &Out + 縮小(&O) + + + Zoom &Text Only + 文字サイズだけ変更(&T) + + + Show All Bookmarks... + ブックマークの管理... + + + Add Folder... + フォルダの追加... + + + About &%1 + About Browser + &%1 について + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>プライベート モードに移行した場合、あなたのプライバシーを守る為、いくつかの機能は制限されます:<ul><li> 表示したページは履歴に追加されません。</li><li> ダウンロード履歴は残りません。</li><li> 新しく受け取った Cookie は保存されません。既に保存済みの Cookie を参照する事もできません。</li><li> Web サイトのアイコンやセッションは保存されません。</li><li> 検索ボックスの検索履歴に追加されません。</li></ul>ウィンドウを閉じるまでに閲覧した Web ページには戻る/進むボタンで移動する事ができます。 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + デフォルト + + + Text Encoding + 文字コード + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> Network cache is disabled.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>プライベート モードに移行した場合、あなたのプライバシーを守る為、いくつかの機能は制限されます:<ul><li> 表示したページは履歴に追加されません。</li><li> ダウンロード履歴は残りません。</li><li> 新しく受け取った Cookie は保存されません。既に保存済みの Cookie を参照する事もできません。</li><li> Web サイトのアイコンやセッションは保存されません。</li><li> 検索ボックスの検索履歴に追加されません。</li><li>ネットワークキャッシュは無効です。</li></ul>ウィンドウを閉じるまで閲覧した Web ページに戻る/進むボタンで戻る事ができます。 + + + Select &All + すべてを選択(&A) + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>プライベート モードに移行した場合、あなたのプライバシーを守る為、いくつかの機能は制限されます:<ul><li> 表示したページは履歴に追加されません。</li><li> ダウンロード履歴は残りません。</li><li> 新しく受け取った Cookie は保存されません。既に保存済みの Cookie を参照する事もできません。</li><li> Web サイトのアイコンやセッションは保存されません。</li><li> 検索ボックスの検索履歴に追加されません。</li><li>新しいネットワークキャッシュをディスクに保存しません。</li></ul>ウィンドウを閉じるまで閲覧した Web ページに戻る/進むボタンで戻る事ができます。 + + + Options... + オプション... + + + Configure Search Engines... + 検索エンジンのカスタマイズ... + + + &Ad Block... + 広告ブロック(AdBlock)(&A)... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + プライベート ブラウジングを有効にすると、あなたのプライバシーを守る為、いくつかの動作が制限されます: + + + Webpages are not added to the history. + 参照したWebページが履歴に追加されなくなります。 + + + Items are automatically removed from the Downloads window. + ダウンロードが終了したものは、自動的にダウンロード ウィンドウから削除されます。 + + + New cookies are not stored, current cookies can't be accessed. + 新しく受け取った Cookie は保存されなくなり、既に保存されている Cookie へアクセスする事もできません。 + + + Site icons won't be stored. + Web サイトのアイコン(favicon)は、保存されません。 + + + Session won't be saved. + セッションは保存されません。 + + + Searches are not added to the pop-up menu in the search box. + 検索語は、検索ボックスのポップアップ メニューに追加されません。 + + + No new network cache is written to disk. + 新たにネットワーク キャッシュをディスクに保存しません。 + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + ウィンドウを閉じるまでの間に閲覧したWebページに、戻る/進むボタンで戻る事ができます。 + + + Private Browsing + プライベート ブラウジング + + + + ClearButton + + Clear + クリア + + + + ClearPrivateData + + Clear Private Data + プライバシー情報の削除 + + + Clear the following items: + 以下の項目を削除します: + + + &Browsing History + 表示したページの履歴(&B) + + + &Download History + ダウンロード履歴(&D) + + + &Search History + 検索履歴(&S) + + + &Cookies + Cookie(&C) + + + C&ached Web Pages + キャッシュされた Web ページ(&A) + + + Website &Icons + Web サイトのアイコン(&I) + + + Clear &Private Data + 削除実行(&P) + + + &Cancel + キャンセル(&C) + + + + ClickToFlash + + Load + Flash をロード + + + Load All + このページの全ての Flash をロード + + + Add %1 to Whitelist + このサイト(%1)をホワイトリストに追加 + + + Remove from Whitelist + ホワイトリストから除外 + + + Settings + 設定 + + + Load Flash + Flash のロード + + + + ClickToFlashSettings + + Whitelist sites + ホワイトリスト一覧 + + + + CookieExceptionsModel + + Website + Web サイト + + + Rule + ルール + + + Allow + 許可 + + + Block + 不許可 + + + Allow For Session + セッション内のみ許可 + + + + CookieModel + + Website + Web サイト + + + Name + 名前 + + + Path + パス + + + Secure + 安全 + + + Expires + 期限 + + + Contents + 内容 + + + true + はい + + + false + いいえ + + + Session cookie + セッション Cookie + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + 削除(&R) + + + Remove &All Cookies + 全ての Cookie を削除(&A) + + + Add &Rule + ルールを追加(&R) + + + + CookiesExceptionsDialog + + Domain: + ドメイン: + + + Block + ブロック + + + Allow For Session + セッション内のみ許可 + + + Allow + 許可 + + + &Remove + 削除(&R) + + + Remove &All + 全て削除(&A) + + + Cookie Exceptions + Cookie 例外条件 + + + New Exception + 新しい例外条件 + + + Exceptions + 例外条件 + + + + DownloadDialog + + Downloads + ダウンロード + + + Clean up + 履歴の消去 + + + 0 Items + 0 件 + + + &OK + &OK + + + + DownloadItem + + Form + Form + + + Open + 開く + + + Ico + Ico + + + Filename + Filename + + + Try Again + リトライ + + + Stop + 停止 + + + Save File + ブックマークのエクスポート + + + Download canceled: %1 + %1 のダウンロードは中止しました + + + Error opening output file: %1 + 保存ファイルの作成中にエラー:%1 + + + Error saving: %1 + 保存中にエラー:%1 + + + Network Error: %1 + ネットワーク エラー:%1 + + + seconds + + + + - %n minutes remaining + + - 残り %n 分 + + + + - %n seconds remaining + + - 残り %n 秒 + + + + %1 of %2 (%3/sec) %4 + %1 / %2 (%3/sec) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 / %2 - 停止しました + + + bytes + bytes + + + kB + kB + + + MB + MB + + + %1 of %2 (%3/sec) - %4 + %1 / %2 (%3/秒) - %4 + + + Download directory (%1) couldn't be created. + ダウンロード先ディレクトリ (%1) を作成できませんでした。 + + + + DownloadManager + + %n Download(s) + + %n 件のダウンロード アイテム + + + + There are %1 downloads in progress +Do you want to quit anyway? + %1 件の項目がダウンロード中です +本当に終了しますか? + + + %n minutes remaining + + 残り %n 分 + + + + %n seconds remaining + + 残り %n 秒 + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + エラーはありません + + + Error opening: %1: No such file or directory + ディレクトリ( %1 )読込中にエラー:ディレクトリがありません + + + Unable to read %1 + ディレクトリ( %1 )の内容を読み込めません + + + Contents of %1 + %1 の中身 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + 開く + + + Copy + コピー + + + Delete + 削除 + + + History + 履歴 + + + &Remove + 削除(&R) + + + Remove &All + 全て削除(&A) + + + + HistoryMenu + + Show All History + 全ての履歴を表示 + + + Clear History... + 履歴をクリア... + + + Clear History + 履歴をクリア + + + Do you want to clear the history? + 履歴をクリアしますか? + + + + HistoryModel + + Title + タイトル + + + Address + アドレス + + + + HistoryTreeModel + + Earlier Today + 本日 + + + %n item(s) + + %n 件 + + + + + JavaScriptAroraObject + + Welcome to Arora! + Arora にようこそ! + + + Arora Start + Arora スタート + + + Search! + 検索! + + + Search results provided by + 検索結果の提供 + + + About Arora + Arora について + + + + LanguageManager + + Default + デフォルト + + + Choose language + 言語の選択 + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>OSのデフォルト設定とは異なる言語で動作させる事ができます.</p><p>使用したい言語を選択して下さい</p> + + + No translation files are installed. + 翻訳ファイルがインストールされていません。 + + + No translation files are installed at %1. + %1 に翻訳ファイルがありません。 + + + + NetworkAccessManager + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + SSL エラー: + +%1 + +%2 + +エラーを無視しますか? + + + Do you want to accept all these certificates? + 全ての証明書を受け入れますか? + + + <qt>Enter username and password for "%1" at %2</qt> + <qt>%1(%2)にアクセスするにはユーザ名とパスワードが必要です</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>プロキシ サーバ "%1" に接続:</qt> + + + - SSL Errors + - SSL エラー + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL エラー:<br/><br/>URL: <tt>%1</tt><ul><li>%2</li></ul> + +エラーを無視しますか?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>証明書:<br/>%1<br/>全ての証明書を受け入れますか?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>証明書:<br/>%1<br/>全ての証明書を受け入れますか?</qt> + + + Issuer: %1 + 発行者: %1 + + + Not valid before: %1 + 発行日: %1 + + + Valid until: %1 + 有効期限: %1 + + + Alternate Names: + 代理名: + + + + NetworkMonitor + + Name + 名前 + + + Value + + + + + NetworkMonitorDialog + + Network Monitor + ネットワーク モニタ + + + Network Requests + ネットワーク リクエスト + + + Request Headers + リクエスト ヘッダ + + + Response Headers + レスポンス ヘッダ + + + &Remove + 削除(&R) + + + Remove &All Requests + 全てのリクエストを削除(&A) + + + + OpenSearchDialog + + Open File + ファイルを開く + + + OpenSearch + OpenSearch + + + Error + エラー + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 は有効なOpenSearch 1.1定義ではないか、既にリストに登録済みです。 + + + You must have at least one search engine in here. + 1つ以上の検索エンジンを登録して下さい。 + + + OpenSearch Manager + OpenSearch マネージャ + + + &Restore Defaults + デフォルトに戻す(&R) + + + &Delete + 削除(&D) + + + &Add + 追加(&A) + + + &Close + 閉じる(&C) + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>説明:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>文脈に沿った候補を提供する</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + カンマで区切られたキーワードのリストは、検索時にロケーション バー内の検索語に続けて渡されます + + + Name + 名前 + + + Keywords + キーワード + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + 以下の検索エンジンを追加しますか?<br /><br />検索エンジン名: %1<br />URL: %2 + + + + PasswordDialog + + Authentication Required + 認証要求 + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + ユーザ名: + + + Password: + パスワード: + + + + PlainTextEditSearch + + Not Found + 見つかりません + + + + ProxyDialog + + Proxy Authentication + プロキシ認証 + + + ICON + ICON + + + Connect to proxy + プロキシに接続 + + + Username: + ユーザ名: + + + Password: + パスワード: + + + + QObject + + The file is not an XBEL version 1.0 file. + XBEL バージョン 1.0 ファイルではありません. + + + Unknown title + 不明なタイトル + + + The file is not an OpenSearch 1.1 file. + これは OpenSearch 1.1 ファイルではありません。 + + + + RequestModel + + Redirect: %1 + リダイレクト: %1 + + + Method + メソッド + + + Address + アドレス + + + Response + レスポンス + + + Length + 長さ + + + Content Type + Content Type + + + Info + 情報 + + + + SearchBanner + + Form + Form + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + 閉じる + + + Highlight All + 全て強調表示 + + + + SearchLineEdit + + Search + 検索 + + + + Settings + + Preferences + 設定 + + + General + 全般 + + + On startup: + 起動時: + + + Show my home page + ホームページを開く + + + Show a blank page + 空白ページを開く + + + Restore windows and tabs from last time + 最後に開いていたウィンドウとタブを復元する + + + Home Page: + ホームページ: + + + Set to current page + 現在のページを使用 + + + Remove history items: + 履歴を削除するタイミング: + + + After one day + 1日後 + + + After one week + 1週間後 + + + After two weeks + 2週間後 + + + After one month + 1ヶ月後 + + + After one year + 1年後 + + + Manually + 手動 + + + On application exit + アプリケーション終了時 + + + Open links from applications: + リンクを開く時の動作: + + + In a tab in the current window + 表示しているタブで開く + + + In a new window + 新しいウィンドウで開く + + + Downloads + ダウンロード + + + Ask for a destination each time + 毎回保存先を指定する + + + Use this destination: + デフォルトの保存先: + + + Appearance + 外観 + + + Standard font: + 標準のフォント: + + + Times 16 + Times 16 + + + Select... + 選択... + + + Fixed-width font: + 固定幅フォント: + + + Courier 13 + Courier 13 + + + Privacy + プライバシー + + + Web Content + コンテンツ + + + Enable Plugins + プラグインを有効にする + + + Enable Javascript + Javascript を有効にする + + + View Images + 画像を表示 + + + Cookies + Cookie + + + Exceptions... + 例外... + + + Keep Cookies Until: + Cookie の保持期間: + + + I exit the application + arora が終了するまで + + + At most 90 days + 最長90日間 + + + Cookies... + Cookie を表示... + + + Tabs + タブ + + + Select tabs and windows as they are created + タブやウィンドウを作成した時に移動する + + + Confirm when closing multiple tabs + 複数のタブを閉じる時に確認する + + + Proxy + プロキシ + + + Use proxy server + プロキシを使用する + + + Type: + 種類: + + + Socks5 + Socks5 + + + Http + Http + + + Host name: + ホスト名: + + + Port: + ポート: + + + User Name: + ユーザ名: + + + Password: + パスワード: + + + Advanced + 拡張 + + + Style Sheet: + スタイルシート: + + + Accept Cookies: + Cookie が送られてきたら: + + + Always + 受け取る + + + Never + 受け取らない + + + Only from sites you navigate to + サードパーティの Cookie は無視 + + + They expire + Cookie の有効期限が切れるまで + + + Show only one close button instead of one for each tab + タブ毎の閉じるボタンをつけない + + + Preferred languages for viewing webpages in: + Web ページを表示する際に使用する言語の設定: + + + Block Popup Windows + ポップアップウィンドウをブロックする + + + Opening links + リンクを開く + + + Links that want to open in a new window: + リンクを新しいウィンドウで開こうとした時の動作: + + + In a new selected tab in the current window + 現在のウィンドウの新しいタブで開いて、そのタブに移動する + + + In a new tab in the current window + 現在のウィンドウの新しいタブで開く + + + In the current tab + 現在のタブで開く + + + Http (Secure) + Http (安全な) + + + Http (Transparent) + Http (透過) + + + Use ClickToFlash on flash plugins + Flash プラグインとして ClickToFlash を使う + + + Filter Tracking Cookies + 追跡用 Cookie をフィルタする + + + Confirm when closing multiple tabs or windows + 複数のタブやウィンドウを閉じる時に確認する + + + Quit the application when last tab is closed + 最後のタブを閉じる時にアプリケーションを終了する + + + Enable network cache + ネットワーク キャッシュを有功にする + + + Maximum Size: + 最大サイズ: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + 不正なURLが入力された場合、デフォルトの検索エンジンを使用する + + + Choose Directory... + ディレクトリを選択... + + + A cookie session ends: + Cookie セッションの有効期間: + + + When I exit the application + アプリケーションが終了するまで + + + 1 day + 1 日間 + + + 2 days + 2 日間 + + + 3 days + 3 日間 + + + 7 days + 7 日間 + + + 30 days + 30 日間 + + + AutoFill + 自動入力 + + + AutoFill web forms: + フォームの自動入力: + + + User names and passwords + ユーザ名とパスワード + + + Edit... + 編集... + + + Browse... + 参照... + + + + SettingsDialog + + Restart required + 再起動が必要 + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + ネットワーク キャッシュの構成を変更しました。設定を有効にするにはブラウザの再起動が必要です。 + + + Choose Directory + ディレクトリを選択 + + + Choose CSS File + CSS ファイルを選択 + + + + SourceViewer + + Loading... + 読み込んでいます... + + + &Edit + 編集(&E) + + + &Find + 検索(&F) + + + Source of Page + ソース表示 + + + &View + 表示(&V) + + + &Wrap lines + 行を折り返す(&W) + + + Source of Page %1 + ページ(%1)のソース + + + + TabBar + + Show Tab Bar + タブ バーを表示 + + + Hide Tab Bar + タブ バーを隠す + + + New &Tab + 新しいタブ(&T) + + + Duplicate Tab + タブを複製 + + + &Close Tab + タブを閉じる(&C) + + + Close &Other Tabs + 他のタブを閉じる(&O) + + + Reload Tab + タブを再読込 + + + Reload All Tabs + 全てのタブを再読込 + + + + TabWidget + + New &Tab + 新しいタブ(&T) + + + &Close Tab + タブを閉じる(&C) + + + Show Next Tab + 次のタブ + + + Show Previous Tab + 前のタブ + + + Recently Closed Tabs + 最近閉じたタブ + + + Untitled + (無題) + + + Do you really want to close this page? + 本当にこのページを閉じますか? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + このページは変更されていますが、ページを閉じると変更は失われてしまいます. +本当にこのページを閉じますか? + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + タブを保存 + + + Loading... + 読み込み中... + + + Loading %1% (%2 %3)... + 読み込み中 %1% (%2 %3)... + + + Finished loading + 読み込み完了 + + + Failed to load + 読み込み失敗 + + + Bookmark All Tabs + 全てのタブをブックマーク + + + + ToolbarSearch + + No Recent Searches + 検索履歴がありません + + + Recent Searches + 検索履歴 + + + Clear Recent Searches + 検索履歴の消去 + + + Suggestions + 候補 + + + Add '%1' + '%1' を追加 + + + Configure Search Engines... + 検索エンジンのカスタマイズ... + + + + WebPage + + Error loading page: %1 + %1 の読み込みでエラー + + + When connecting to: %1. + %1 への接続中にエラーが発生しました。 + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + <b>www</b>.arora-browser.org ではなく <b>ww</b>.arora-browser.org のような、URL誤りがないか確認してください + + + If the address is correct, try to check the network connection. + URLが正しい場合は、ネットワークの接続状況を確認してみてください。 + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + あなたのコンピュータやネットワークがファイアウォールやプロキシによって保護されている場合、Arora ブラウザにネットワークへのアクセスを許可してください。 + + + If the address is correct, try checking the network connection. + URLが正しい場合は、ネットワークの接続状況を確認してみてください。 + + + Resending POST request + POST リクエストを再送します + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + サイトを表示する為に、全てのデータを再送する必要がありますが、予期しない動作を引き起こす(例えば、注文やコメント投稿等の操作が再度行われる)可能性があります。それでも続行しますか? + + + + WebView + + Open in New &Window + 新しいウィンドウで開く(&W) + + + Open in New &Tab + 新しいタブで開く(&T) + + + Save Lin&k + 名前を付けてリンク先を保存(&K) + + + &Bookmark This Link + このリンクをブックマーク(&B) + + + &Copy Link Location + リンクのURLをコピー(&C) + + + Open Image in New &Window + 新しいウィンドウで画像を開く(&W) + + + Open Image in New &Tab + 新しいタブで画像を開く(&T) + + + &Save Image + 画像を保存(&S) + + + &Copy Image + 画像をコピー(&C) + + + C&opy Image Location + 画像のURLをコピー(&O) + + + Loading... + 読み込み中... + + + Search with... + 検索エンジンを指定して検索... + + + Add to the toolbar search + ツールバーの検索エンジンに追加する + + + Method not supported + サポートされていないメソッド + + + %1 method is not supported. + メソッド( %1 )はサポートされていません。 + + + Search engine + 検索エンジン + + + Choose the desired search engine + 使用したい検索エンジンを選んでください + + + Engine name + 検索エンジン名の入力 + + + Type in a name for the engine + 検索エンジンの名前を入力してください + + + Block Image + 画像の読み込みをブロック + + + + WebViewSearch + + Not Found + 見つかりません + + + diff --git a/src/locale/ko_KR.ts b/src/locale/ko_KR.ts new file mode 100644 index 00000000..09a5827a --- /dev/null +++ b/src/locale/ko_KR.ts @@ -0,0 +1,2604 @@ + + + + + AboutDialog + + + Lightweight WebKit-based web browser + WebKit 기반 경량 웹 브라우저 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2010 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2010 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + + + Authors + 제작자 + + + + + License + 라이센스 + + + + Close + 닫기 + + + + About %1 + %1에 대하여 + + + + WebKit version: %1 + WebKit 버전: %1 + + + + AcceptLanguage + + + Languages + 언어 + + + + Languages: in order of preference: + 언어 (선호순): + + + + Move &Up + 위로 (&U) + + + + Move &Down + 아래로 (&D) + + + + &Remove + 제거 (&R) + + + + Add... + 추가... + + + + AdBlockBlockedNetworkReply + + + Blocked by AdBlockRule: %1 + AdBlockRule 에 의해 차단됨: %1 + + + + AdBlockDialog + + + AdBlock Configuration + AdBlock 설정 + + + + Enable AdBlock + AdBlock 활성화 + + + + Action + 동작 + + + + Add Custom Rule + 개별 규칙 추가 + + + + Learn more about writing rules... + 규칙 작성하는 방법 배우기... + + + + Update Subscription + 구독 업데이트 + + + + Browse Subscriptions... + 구독 찾기... + + + + Remove Subscription + 구독 제거 + + + + AdBlockManager + + + Custom Rules + 개별 규칙 + + + + AdBlockModel + + + Rule + 규칙 + + + + AdBlockSchemeAccessHandler + + + Subscribe? + 구독 여부 확인 + + + + Subscribe to this AdBlock subscription? +%1 + 이 AdBlock 규칙을 구독할까요? +%1 + + + + AddBookmarkDialog + + + + Add Bookmark + 북마크 추가 + + + + Type a name for the bookmark, and choose where to keep it. + 북마크 이름을 입력한 후 저장할 위치를 선택하여 주십시요. + + + + Url + URL + + + + Title + 제목 + + + + Add Folder + 폴더 추가 + + + + AutoFillDialog + + + Form Passwords + 폼 비밀번호 + + + + Remove + 제거 + + + + Remove All + 모두 제거 + + + + AutoFillManager + + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill panel of preferences. + <b>이 비밀번호를 저장할까요?</b><br> 저장된 비밀번호를 확인하고 제거하려면 설정에서 자동 채움 항목을 확인하여 주십시요. + + + + Never for this site + 이 사이트에서는 안 함 + + + + Not now + 지금 안 함 + + + + AutoFillModel + + + WebSite + 웹사이트 + + + + User Name + 사용자명 + + + + BookmarksDialog + + + Bookmarks + 북마크 목록 + + + + &Remove + 제거 (&R) + + + + Add Folder + 폴더 추가 + + + + Open + 열기 + + + + Open in New Tab + 새 탭에서 열기 + + + + Edit Name + 이름 편집 + + + + Edit Address + 주소 편집 + + + + Delete + 삭제 + + + + New Folder + 새 폴더 + + + + BookmarksManager + + + Bookmarks Bar + 북마크 바 + + + + Bookmarks Menu + 북마크 메뉴 + + + + + Error when loading bookmarks on line %1, column %2: +%3 + 북마크 목록을 읽는 데에 오류가 발생하였습니다. %1 번째 줄, %2번째 열을 확인하십시오. +%3 + + + + Toolbar Bookmarks + 북마크 도구 바 + + + + Menu + 메뉴 + + + + + XBEL bookmarks + XBEL 북마크 목록 + + + + HTML Netscape bookmarks + HTML Netscape 북마크 목록 + + + + Open File + 파일 열기 + + + + htmlToXBel tool required + htmlToXBel 도구가 필요합니다 + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Arora에 포함된 htmlToXBel 도구는 HTML 북마크 목록을 가지고 오는 데 필요하지만 지정된 경로에 설치되지 않았거나 찾을 수 없습니다. + + + + Loading Bookmark + 북마크 가져오기 + + + + Error when loading HTML bookmarks: %1 + + HTML 북마크 목록을 가져오는 데에 오류가 발생하였습니다: %1 + + + + + Imported %1 + %1 을(를) 가져왔습니다 + + + + Save File + 파일로 저장 + + + + %1 Bookmarks.xbel + %1 북마크 목록.xbel + + + + Export error + 내보내기 오류 + + + + error saving bookmarks + 북마크 목록 저장에 실패함 + + + + Remove Bookmark + 북마크 제거 + + + + Insert Bookmark + 북마크 추가 + + + + Name Change + Undo bookmark title change + 이름 바꾸기 + + + + Address Change + Undo bookmark url change + 주소 바꾸기 + + + + BookmarksMenu + + + Open in Tabs + 탭에서 열기 + + + + BookmarksModel + + + Title + 제목 + + + + Address + 주소 + + + + BookmarksToolBar + + + Open + 열기 + + + + Open in New &Tab + 새 탭에서 열기 (&T) + + + + Remove + 제거 + + + + Add Bookmark... + 북마크 추가... + + + + Add Folder... + 폴더 추가... + + + + BrowserApplication + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + 지금 %1 개의 창과 %2 개의 탭이 열려 있습니다. +모든 창과 탭을 닫고 종료하시겠습니까? + + + + Restore failed + 복원 실패함 + + + + Arora crashed while trying to restore this session. Should I try again? + Arora가 세션을 복원하는 과정에서 동작을 정지하였습니다. 다시 시도할까요? + + + + BrowserMainWindow + + + Hide Toolbar + 도구 바 숨기기 + + + + Show Toolbar + 도구 바 보이기 + + + + Hide Bookmarks Bar + 북마크 바 숨기기 + + + + Show Bookmarks Bar + 북마크 바 보이기 + + + + Hide Status Bar + 상태 바 숨기기 + + + + Show Status Bar + 상태 바 보이기 + + + + Default + 기본값 + + + + &File + 파일 (&F) + + + + &New Window + 새 창 열기 (&N) + + + + &Open File... + 파일 열기 (&O)... + + + + Open &Location... + 경로 열기 (&L)... + + + + &Save As... + 새 이름으로 저장 (&S)... + + + + &Import Bookmarks... + 북마크 목록 가져오기 (&I)... + + + + &Export Bookmarks... + 북마크 목록 내보내기 (&E)... + + + + P&rint Preview... + 인쇄 미리보기 (&R)... + + + + &Print... + 인쇄 (&P)... + + + + Private &Browsing... + 개인정보 보호 브라우징 (&B)... + + + + Close Window + 창 닫기 + + + + &Quit + 종료 (&Q) + + + + &Edit + 편집 (&E) + + + + &Undo + 되돌리기 (&U) + + + + &Redo + 다시하기 (&R) + + + + Cu&t + 잘라내기 (&T) + + + + &Copy + 복사 (&C) + + + + &Paste + 붙여넣기 (&P) + + + + Select &All + 모두 선택 (&A) + + + + &Find + 찾기 (&F) + + + + Find Nex&t + 다음 항목 찾기 (&T) + + + + Find P&revious + 이전 항목 찾기 (&R) + + + + &View + 보기 (&V) + + + + Ctrl+| + Ctrl+| + + + + Alt+Ctrl+B + Alt+Ctrl+B + + + + Ctrl+/ + Ctrl+/ + + + + Show Menu Bar + 메뉴 바 보이기 + + + + &Reload Page + 페이지 새로 고침 (&R) + + + + &Stop + 중지 (&S) + + + + Zoom &In + 확대 (&I) + + + + Zoom &Normal + 기본 배율로 (&N) + + + + Zoom &Out + 축소 (&O) + + + + Zoom &Text Only + 글자만 확대 (&T) + + + + Page S&ource + 페이지 소스 (&O) + + + + Ctrl+Alt+U + Ctrl+Alt+U + + + + &Full Screen + 전체 화면 (&F) + + + + Text Encoding + 문자 인코딩 + + + + Hi&story + 기록 (&S) + + + + Back + 뒤로 + + + + Forward + 앞으로 + + + + Home + + + + + Restore Last Session + 마지막 세션 복원 + + + + + &Bookmarks + 북마크 목록 (&B) + + + + Show All Bookmarks... + 모든 북마크 목록 보기... + + + + Add Bookmark... + 북마크 추가... + + + + Add Folder... + 폴더 추가... + + + + &Window + 창 (&W) + + + + &Tools + 도구 (&T) + + + + Web &Search + 웹 검색 (&S) + + + + Ctrl+K + Web Search + Ctrl+K + + + + &Clear Private Data + 개인정보 데이터 지우기 (&C) + + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + + Enable Web &Inspector + 웹 속성 도구 활성화 (&I) + + + + Options... + 옵션... + + + + Ctrl+, + Ctrl+, + + + + Configure Search Engines... + 검색 엔진 설정... + + + + User Agent + 사용자 에이전트 + + + + &Ad Block... + 광고 차단 (&A)... + + + + &Help + 도움말 (&H) + + + + Switch application language + 응용 프로그램 언어 변경 + + + + About &Qt + Qt 에 대하여 (&Q) + + + + About &%1 + About Browser + &%1에 대하여 + + + + Navigation + 탐색 + + + + Reload / Stop + 새로 고침 / 중지 + + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + + Open Web Resource + 웹 리소스 열기 + + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + 웹 리소스 (*.html *.htm *.svg *.png *.gif *.svgz);;모든 파일 (*.*) + + + + Print Document + 문서 인쇄 + + + + Are you sure you want to turn on private browsing? + 개인정보 보호 브라우징으로 전환할까요? + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + 개인정보 보호 브라우징으로 전환하게 되면 개인정보를 침해할 수 있는 일부 기능은 비활성화됩니다. + + + + Webpages are not added to the history. + 웹 페이지가 기록에 추가되지 않습니다. + + + + Items are automatically removed from the Downloads window. + 다운로드 목록 창의 항목은 자동으로 제거됩니다. + + + + New cookies are not stored, current cookies can't be accessed. + 새 쿠키는 저장하지 않으며, 현재 쿠키도 접근할 수 없습니다. + + + + Site icons won't be stored. + 사이트 아이콘이 저장되지 않습니다. + + + + Session won't be saved. + 세션이 저장되지 않습니다. + + + + Searches are not added to the pop-up menu in the search box. + 검색 상자 안에서 이루어진 검색은 팝업 메뉴에 추가되지 않습니다. + + + + No new network cache is written to disk. + 디스크에 새로운 네트워크 캐시를 저장하지 않습니다. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + 창을 닫을 때까지 열었던 페이지는 "뒤로" "앞으로" 버튼을 클릭하면 언제든지 접근할 수 있습니다. + + + + Private Browsing + 개인정보 보호 브라우징 + + + + Are you sure you want to close the window? There are %1 tabs open + 모든 탭을 닫고 종료하시겠습니까? 지금 %1 개의 탭이 열려 있습니다. + + + + Web Inspector + 웹 속성 도구 + + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + 웹 속성 도구가 페이지를 올바르게 조사하려면 페이지가 열리기 전에 활성화되어야 합니다. +지금 모든 페이지를 새로 고칠까요? + + + + Stop loading the current page + 이 페이지를 불러오는 것을 중단합니다 + + + + Stop + 중지 + + + + Reload the current page + 이 페이지를 새로 고칩니다 + + + + Reload + 새로 고침 + + + + Downloads + 다운로드 목록 + + + + Ctrl+Y + Download Manager + Ctrl+Y + + + + ClearButton + + + Clear + 지우기 + + + + ClearPrivateData + + + Clear Private Data + 개인정보 데이터 지우기 + + + + Clear the following items: + 다음 항목이 지워집니다. + + + + &Browsing History + 웹 브라우징 기록 (&B) + + + + &Download History + 다운로드한 기록 (&D) + + + + &Search History + 검색한 기록 (&S) + + + + &Cookies + 쿠키 (&C) + + + + C&ached Web Pages + 저장된 웹 페이지 (&A) + + + + Website &Icons + 웹사이트 아이콘 (&I) + + + + Clear &Private Data + 개인정보 데이터 (&P) + + + + &Cancel + 취소 (&C) + + + + ClickToFlash + + + Load Flash + 플래시 불러오기 + + + + Load + 불러오기 + + + + Load All + 모두 불러오기 + + + + Add %1 to Whitelist + %1 을(를) 허용 목록에 추가 + + + + Remove from Whitelist + 허용 목록에서 제거 + + + + Settings + 설정 + + + + ClickToFlashSettings + + + Whitelist sites + 사이트 허용 목록 + + + + CookieExceptionsModel + + + Website + 웹사이트 + + + + Rule + 규칙 + + + + Allow + 허용 + + + + Block + 차단 + + + + Allow For Session + 이 세션에서 허용 + + + + CookieModel + + + Website + 웹사이트 + + + + Name + 이름 + + + + Path + 경로 + + + + Secure + 보안 + + + + Expires + 만료일 + + + + Contents + 내용 + + + + true + 안전함 + + + + false + 안전하지 않음 + + + + Session cookie + 세션 쿠키 + + + + CookiesDialog + + + Cookies + 쿠키 목록 + + + + &Remove + 제거 (&R) + + + + Remove &All Cookies + 모든 쿠키 제거 (&A) + + + + Add &Rule + 규칙 추가 (&R) + + + + CookiesExceptionsDialog + + + Cookie Exceptions + 쿠키 예외 목록 + + + + New Exception + 새 예외 항목 + + + + Domain: + 도메인: + + + + Block + 차단 + + + + Allow For Session + 이 세션에서 허용 + + + + Allow + 허용 + + + + Exceptions + 예외 목록 + + + + &Remove + 제거 (&R) + + + + Remove &All + 모두 제거 (&A) + + + + DownloadDialog + + + + Downloads + 다운로드 목록 + + + + Clean up + 비우기 + + + + 0 Items + 0 항목 + + + + Downloading %1 + %1 다운로드 중 + + + + DownloadItem + + + Ico + 아이콘 + + + + Filename + 파일명 + + + + Try Again + 재시도 + + + + Stop + 중지 + + + + Open + 열기 + + + + Save File + 파일 저장 + + + + Download canceled: %1 + 다운로드 취소됨: %1 + + + + Download directory (%1) couldn't be created. + 다운로드할 디렉토리 (%1) 을(를) 만들 수 없었습니다. + + + + Error opening output file: %1 + 출력 파일 열기 오류: %1 + + + + Error saving: %1 + 저장 오류: %1 + + + + Network Error: %1 + 네트워크 오류: %1 + + + + %1 of %2 (%3/sec) - %4 + %2 중 %1 (%3/초) - %4 + + + + ? + ? + + + + %1 of %2 - Download Complete + %2 중 %1 (%3/초) - 다운로드를 완료하였습니다. + + + + DownloadManager + + + There are %1 downloads in progress +Do you want to quit anyway? + 지금 %1 개의 다운로드 항목이 완료되지 않았습니다. +다운로드를 중지하고 종료하시겠습니까? + + + + %n Download(s) + + %n 개의 다운로드 항목 + + + + + %n minutes remaining + + %n 분 남음 + + + + + %n seconds remaining + + %n 초 남음 + + + + + bytes + 바이트 + + + + kB + KB + + + + MB + MB + + + + GB + GB + + + + FileAccessReply + + + No Error + 오류 없음 + + + + Error opening: %1: No such file or directory + %1 을(를) 열 수 없습니다. 파일이나 디렉토리가 아닙니다. + + + + Unable to read %1 + %1 을 읽을 수 없습니다 + + + + Contents of %1 + %1 의 내용 + + + + %1 KB + %1 KB + + + + Show Hidden Files + 숨겨진 파일 보기 + + + + HistoryDialog + + + History + 기록 + + + + &Remove + 제거 (&R) + + + + Remove &All + 모두 제거 (&A) + + + + Open + 열기 + + + + Copy + 복사 + + + + Delete + 삭제 + + + + HistoryMenu + + + Show All History + 모든 기록 보기 + + + + Clear History... + 기록 비우기... + + + + Clear History + 기록 비우기 + + + + Do you want to clear the history? + 기록을 비우시겠습니까? + + + + HistoryModel + + + Title + 제목 + + + + Address + 주소 + + + + HistoryTreeModel + + + Earlier Today + 방금 전 + + + + %n item(s) + + %n 항목 + + + + + JavaScriptAroraObject + + + Welcome to Arora! + Arora 를 사용해 주셔서 감사합니다. + + + + Arora Start + Arora 시작 + + + + Search! + 검색 + + + + Search results provided by + 검색 결과 제공자: + + + + About Arora + Arora에 대하여 + + + + LanguageManager + + + No translation files are installed at %1. + 언어 파일이 %1 에 설치되지 않았습니다. + + + + Choose language + 언어 선택 + + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>운영체제 기본 언어가 아닌 다른 언어라도<br>적용하여 실행할 수 있습니다.</p><p>사용할 언어를 선택하여 주십시요.</p> + + + + NetworkAccessManager + + + <qt>Enter username and password for "%1" at %2</qt> + <qt>"%1" 에서 사용하는 사용자명과 암호를 %2 에 입력하십시오.</qt> + + + + <qt>Connect to proxy "%1" using:</qt> + <qt>"%1" 프록시 서버에 다음을 사용하여 연결:</qt> + + + + Issuer: %1 + 발행자: %1 + + + + Not valid before: %1 + %1 부터 유효함 + + + + Valid until: %1 + %1 까지 유효함 + + + + Alternate Names: + 별칭: + + + + - SSL Errors + - SSL 오류 + + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL 오류:<br/><br/><tt>%1</tt> 에서 발생<ul><li>%2</li></ul> + +이 오류를 무시하겠습니까?</qt> + + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>인증서:<br/>%1<br/>이 인증서를 모두 허용하시겠습니까?</qt> + + + + OpenSearchDialog + + + OpenSearch Manager + OpenSearch 관리자 + + + + &Add + 추가 (&A) + + + + &Delete + 삭제 (&D) + + + + &Restore Defaults + 기본값으로 (&R) + + + + &Close + 닫기 (&C) + + + + Open File + 파일 열기 + + + + OpenSearch + OpenSearch + + + + + Error + 오류 + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 은(는) 올바른 OpenSearch 1.1 규격 파일이 아니거나 이미 목록에 있습니다. + + + + You must have at least one search engine in here. + 하나 이상의 검색 엔진이 있어야 합니다. + + + + OpenSearchEngineModel + + + <strong>Description:</strong> %1 + <strong>규격:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + <strong>문장 제안을 제공함</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + 구분점으로 구분된 단어 목록은 주소 바에 입력할 수 있고, 이 검색 엔진을 사용할 때 검색 규칙에 따라 처리됩니다 + + + + Name + 이름 + + + + Keywords + 키워드 + + + + OpenSearchManager + + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + 이 검색 엔진 목록을 브라우저에서 이용할 검색 목록에 추가하시겠습니까?<br /><br />이름: %1<br />검색 위치: %2 + + + + PasswordDialog + + + Authentication Required + 인증이 필요함 + + + + DUMMY ICON + 더미 아이콘 + + + + INTRO TEXT DUMMY + 텍스트 더미 인트로 + + + + Username: + 사용자명: + + + + Password: + 암호: + + + + PlainTextEditSearch + + + Not Found + 찾을 수 없음 + + + + ProxyDialog + + + Proxy Authentication + 프록시 서버 인증 + + + + Connect to proxy + 프록시 서버에 연결 + + + + Username: + 사용자명: + + + + Password: + 암호: + + + + QObject + + + The file is not an XBEL version 1.0 file. + 이 파일은 XBEL 1.0 규격 파일이 아닙니다. + + + + Unknown title + 제목 없음 + + + + The file is not an OpenSearch 1.1 file. + 이 파일은 OpenSearch 1.1 규격 파일이 아닙니다. + + + + SearchBanner + + + Highlight All + 모두 표시 + + + + Done + 완료 + + + + SearchLineEdit + + + Search + 검색 + + + + Settings + + + Preferences + 설정 + + + + General + 일반 + + + + On startup: + 시작할 때: + + + + Show my home page + 내 홈 페이지 보이기 + + + + Show a blank page + 빈 페이지 보이기 + + + + Restore windows and tabs from last time + 마지막으로 열었던 창과 탭 복원 + + + + Home Page: + 홈 페이지: + + + + Set to current page + 현재 페이지로 설정 + + + + Remove history items: + 기록 항목 제거: + + + + After one day + 하루마다 + + + + After one week + 1주마다 + + + + After two weeks + 2주마다 + + + + After one month + 1달마다 + + + + After one year + 1년마다 + + + + Manually + 수동으로 + + + + On application exit + 어플리케이션을 종료할 때 + + + + Use the default search engine as fallback when the URL given by the user is invalid + 입력한 URL이 올바르지 않을 때 기본 검색 엔진 사용 + + + + Enable access keys + 접근 키 활성화 + + + + Downloads + 다운로드 + + + + Ask for a destination each time + 다운로드할 경로를 매번 물어봄 + + + + Use this destination: + 이 경로를 사용: + + + + Choose Directory... + 디렉토리 선택... + + + + Use this external download program: + 다른 다운로드 프로그램 사용: + + + + Choose Program... + 프로그램 선택... + + + + Appearance + 모양새 + + + + Standard font: + 기본 글꼴: + + + + + + Select... + 선택... + + + + Fixed-width font: + 고정폭 글꼴: + + + + Preferred languages for viewing webpages in: + 웹 페이지를 볼 언어: + + + + Minimum Font size: + 글꼴 최소 크기: + + + + Privacy + 개인 정보 + + + + Web Content + 웹 항목 + + + + Block Popup Windows + 팝업 창 차단 + + + + Enable Plugins + 플러그인 활성화 + + + + If you enable this option, no flash objects will be loaded by default. Instead, each will be replaced by a button, allowing you to control which objects to load, and which not. + 이 옵션을 활성화하면 플래시 객체를 바로 불러들이지 않도록 않도록 설정됩니다. 이 플래시 객체는 각각 버튼으로 대체되며, 사용자가 버튼을 눌러 이 플래시 객체를 불러들일 것인지 선택할 수 있습니다. + + + + Use ClickToFlash on flash plugins + 플래시 플러그인에 ClickToFlash 사용 + + + + Enable Javascript + Javascript 활성화 + + + + View Images + 이미지 보기 + + + + Persistent Data Storage + 오프라인 저장소 사용 + + + + Cookies + 쿠키 + + + + Accept Cookies: + 쿠키 허용: + + + + Always + 항상 + + + + Never + 안함 + + + + Only from sites you navigate to + 방문한 사이트만 + + + + Exceptions... + 예외... + + + + Keep Cookies Until: + 쿠키 보존 기한: + + + + They expire + 사이트가 지정한 만료일 + + + + I exit the application + 어플리케이션을 닫을 때까지 + + + + At most 90 days + 90일간 + + + + Cookies... + 쿠키... + + + + Filter Tracking Cookies + 방문자 추적 쿠키 거르기 + + + + A cookie session ends: + 쿠키 세션 만료일: + + + + When I exit the application + 어플리케이션을 닫을 때 + + + + 1 day + 1일 + + + + 2 days + 2일 + + + + 3 days + 3일 + + + + 7 days + 7일 + + + + 30 days + 30일 + + + + Tabs + + + + + Select tabs and windows as they are created + 생성된 탭과 창을 보여줌 + + + + Confirm when closing multiple tabs or windows + 여러 탭과 창을 닫을 때 물어보기 + + + + Show only one close button instead of one for each tab + 각 탭의 닫기 버튼을 단일 닫기 버튼으로 대체 + + + + Quit the application when last tab is closed + 마지막 탭을 닫았을 때 어플리케이션을 종료 + + + + Opening links + 링크를 열 방법 + + + + Links that want to open in a new window: + 새 창으로 링크를 열 때: + + + + + In a new window + 새 창 열기 + + + + + In a new selected tab in the current window + 현재 창에서 새 탭을 열어 보이기 + + + + + In a new tab in the current window + 현재 창에서 새 탭으로 열기 + + + + + In the current tab + 현재 탭에서 보이기 + + + + Open links from applications: + 어플리케이션에서 링크를 열 때: + + + + Proxy + 프록시 + + + + Use proxy server + 프록시 서버 사용 + + + + Type: + 연결 종류: + + + + Socks5 + Socks5 + + + + Http (Secure) + Http (보안) + + + + Http (Transparent) + Http (투명) + + + + Host name: + 호스트: + + + + Port: + 포트: + + + + User Name: + 사용자명: + + + + Password: + 암호: + + + + AutoFill + 자동완성 + + + + AutoFill web forms: + 웹 폼 자동완성 + + + + User names and passwords + 사용자명과 암호 + + + + Edit... + 편집... + + + + Advanced + 고급 + + + + Style Sheet: + 스타일시트: + + + + Browse... + 찾기... + + + + Enable network cache + 네트워크 캐시 활성화 + + + + Maximum Size: + 용량 한도: + + + + MB + MB + + + + SettingsDialog + + + Restart required + 다시 시작이 필요함 + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + 네트워크 캐시 설정이 변경되었습니다. 변경된 설정을 적용하려면 브라우저를 다시 시작해야 합니다. + + + + Choose Directory + 디렉토리 선택 + + + + Choose Program + 프로그램 선택 + + + + Choose CSS File + CSS 파일 선택 + + + + SourceViewer + + + Loading... + 불러오는 중... + + + + &Edit + 편집 (&E) + + + + &Find + 찾기 (&F) + + + + Source of Page %1 + %1 페이지의 소스 + + + + TabBar + + + Show Tab Bar + 탭 바 보이기 + + + + Hide Tab Bar + 탭 바 숨기기 + + + + Duplicate Tab + 탭 복제 + + + + &Close Tab + 탭 닫기 (&C) + + + + Close &Other Tabs + 다른 탭 닫기 (&O) + + + + Reload Tab + 탭 새로 고침 + + + + Reload All Tabs + 모든 탭 새로 고침 + + + + TabWidget + + + Untitled + 제목 없음 + + + + Saved Tabs + 저장된 탭 목록 + + + + Do you really want to close this page? + 이 페이지를 정말 닫으시겠습니까? + + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + 이 페이지에서 편집한 내용은 페이지를 닫을 때 손실될 수 있습니다. +이 페이지를 정말 닫으시겠습니까? + + + + + Loading... + 불러오는 중... + + + + Loading %1% (%2 %3)... + %1% 불러옴 (%2 %3)... + + + + Finished loading + 불러오기 성공 + + + + Failed to load + 불러오기 실패 + + + + Show Next Tab + 다음 탭 보기 + + + + Ctrl-] + Ctrl-] + + + + Show Previous Tab + 기존 탭 보기 + + + + Ctrl-[ + Ctrl-[ + + + + Recently Closed Tabs + 이전에 닫은 탭 보기 + + + + New &Tab + 새 탭 (&T) + + + + &Close Tab + 탭 닫기 (&C) + + + + Bookmark All Tabs + 모든 탭 북마크 + + + + ToolbarSearch + + + Suggestions + 제안 + + + + Add '%1' + '%1' 추가 + + + + Clear Recent Searches + 최근 검색 기록 비우기 + + + + No Recent Searches + 최근 검색 기록 없음 + + + + Recent Searches + 최근 검색 기록 + + + + UserAgentMenu + + + Default + 기본값 + + + + Other... + 다른 설정... + + + + Custom user agent + 사용자 에이전트 지정 + + + + User agent: + 사용자 에이전트: + + + + WebPage + + + Resending POST request + POST 요청 재전송 필요함 + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + 이 사이트를 표시하려면 사이트를 요청할 때 이용한 모든 데이터를 다시 보내야 합니다. 이 작업은 사이트에서 기대하지 않은 동작을 진행할 수 있습니다. 예로, 방금 했던 작업이 다시 실행될 수 있습니다. 계속 진행하시겠습니까? + + + + Error loading page: %1 + %1 페이지 불러오기 오류 + + + + When connecting to: %1. + %1 에 접속하려고 하였습니다. + + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + 주소를 실수로 <b>www</b>.arora-browser.org 대신 <b>ww</b>.arora-browser.org 와 같이 입력하였는지 확인하여 주십시요. + + + + If the address is correct, try checking the network connection. + 주소를 제대로 입력하였다면 네트워크 연결을 확인하여 주십시요. + + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + 컴퓨터나 네트워크가 방화벽이나 프록시 서버로 보호받고 있다면 브라우저가 네트워크에 접속하는 데 제한이 있는지 확인하여 주십시요. + + + + WebView + + + Open in New &Window + 새 창에서 열기 (&N) + + + + Open in New &Tab + 새 탭에서 열기 (&T) + + + + Save Lin&k + 링크 저장 (&K) + + + + &Bookmark This Link + 이 링크를 북마크 (&B) + + + + &Copy Link Location + 링크 주소 복사 (&C) + + + + Open Image in New &Window + 새 창에 이미지 열기 (&W) + + + + Open Image in New &Tab + 새 탭에 이미지 열기 (&T) + + + + &Save Image + 이미지 저장 (&S) + + + + &Copy Image + 이미지 복사 (&C) + + + + C&opy Image Location + 이미지 주소 복사 (&O) + + + + Block Image + 이미지 차단 + + + + Search with... + 이 부분을 검색... + + + + Add to the toolbar search + 도구 검색에 추가 + + + + Method not supported + 기능 지원 안됨 + + + + %1 method is not supported. + %1 기능은 지원하지 않습니다. + + + + Search engine + 검색 엔진 + + + + Choose the desired search engine + 검색할 엔진을 선택하십시오 + + + + Engine name + 엔진 이름 + + + + Type in a name for the engine + 엔진 이름을 입력하십시오 + + + + Loading... + 불러오는 중... + + + + WebViewSearch + + + Not Found + 찾을 수 없음 + + + diff --git a/src/locale/locale.pri b/src/locale/locale.pri new file mode 100644 index 00000000..0aab5193 --- /dev/null +++ b/src/locale/locale.pri @@ -0,0 +1,53 @@ + +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +TRANSLATIONS += \ + ast.ts \ + ca.ts \ + cs_CZ.ts \ + da_DK.ts \ + de_DE.ts \ + el_GR.ts \ + es.ts \ + es_CR.ts \ + et_EE.ts \ + fi_FI.ts \ + fr_CA.ts \ + fr_FR.ts \ + gl.ts \ + he_IL.ts \ + hu_HU.ts \ + it_IT.ts \ + ja_JP.ts \ + ko_KR.ts \ + ms.ts \ + nb_NO.ts \ + nl.ts \ + pl_PL.ts \ + pt_PT.ts \ + pt_BR.ts \ + ru_RU.ts \ + sk_SK.ts \ + sr_RS.ts \ + sr_RS@latin.ts \ + tr_TR.ts \ + uk.ts \ + zh_CN.ts \ + zh_TW.ts + +isEmpty(QMAKE_LRELEASE) { + win32|os2:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe + else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease + unix { + !exists($$QMAKE_LRELEASE) { QMAKE_LRELEASE = lrelease-qt4 } + } else { + !exists($$QMAKE_LRELEASE) { QMAKE_LRELEASE = lrelease } + } +} + +updateqm.input = TRANSLATIONS +updateqm.output = .qm/locale/${QMAKE_FILE_BASE}.qm +updateqm.commands = $$QMAKE_LRELEASE -silent ${QMAKE_FILE_IN} -qm .qm/locale/${QMAKE_FILE_BASE}.qm +updateqm.CONFIG += no_link target_predeps +QMAKE_EXTRA_COMPILERS += updateqm diff --git a/src/locale/maintainers b/src/locale/maintainers new file mode 100644 index 00000000..887f008e --- /dev/null +++ b/src/locale/maintainers @@ -0,0 +1,10 @@ +The list of the maintainers for each translation. Patches should be reviewed by them before being merged in. + +cs_CZ - David Kolibáč +es - Miguel Anxo Bouzada +fr_FR - Vincent Rischmann +gl - Miguel Anxo Bouzada +it_IT - Vincenzo Reale +nl_NL - Kristof Bal +pl_PL - Jakub Wieczorek +he_IL - Diego Iastrubni diff --git a/src/locale/ms.ts b/src/locale/ms.ts new file mode 100644 index 00000000..abec27bd --- /dev/null +++ b/src/locale/ms.ts @@ -0,0 +1,2354 @@ + + + + + AboutDialog + + About + Perihal + + + Authors + Penulis + + + License + Lesen + + + Lightweight WebKit-based web browser + Pelayan web ringan berasaskan WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Tutup + + + About %1 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + Bahasa + + + Languages: in order of preference: + Bahasa di dalam turutan minat: + + + Move &Up + Naik A&tas + + + Move &Down + Turun Ba&wah + + + &Remove + &Keluarkan + + + Add... + Tambah... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Peraturan + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Tambah Tandabuku + + + Type a name for the bookmark, and choose where to keep it. + Taipkan nama tandabuku dan pilih di mana harus disimpan. + + + Url + Url + + + Title + Tajuk + + + Add Folder + Tambah Folder + + + + AutoFillDialog + + Form Passwords + + + + Remove + Buang + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Buka + + + Open in New Tab + Buka di Tab Baru + + + Delete + Padam + + + New Folder + Folder Baru + + + Bookmarks + Tandabuku + + + &Remove + &Buang + + + Add Folder + Tambah Folder + + + Edit Name + Sunting Nama + + + Edit Address + Sunting Alamat + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Ralat semasa menyimpan tanda buku pada baris %1, lajur %2: +%3 + + + Toolbar Bookmarks + Bar Alat Tandabuku + + + Menu + Menu + + + Open File + Buka Fail + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + %1 diimport + + + Save File + Simpan Fail + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Ralat eksport + + + error saving bookmarks + ralat menyimpan tandabuku + + + Remove Bookmark + Buang Tandabuku + + + Insert Bookmark + Masukkan tandabuku + + + Name Change + Perubahan Nama + + + Address Change + Alamat Berubah + + + Bookmarks Bar + Bar Tandabuku + + + Bookmarks Menu + Menu Tandabuku + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Ralat semasa memuatkan tandabuku html: %1 + + + + Name Change + Undo bookmark title change + Perubahan Nama + + + Address Change + Undo bookmark url change + Alamat Berubah + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + Buka di Tab + + + + BookmarksModel + + Title + Tajuk + + + Address + Alamat + + + + BookmarksToolBar + + Bookmark + Tandabuku + + + Open + Buka + + + Open in New &Tab + Buka di &Tab Baru + + + Remove + Buang + + + Add Bookmark... + Tambah Tandabuku... + + + Add Folder... + Tambah Folder... + + + Bookmarks + Tandabuku + + + + BrowserApplication + + (Change: %1 %2) + (Ubah: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Terdapat %1 tetingkap dan %2 tab masih terbuka +Teruskan untuk keluar? + + + Restore failed + Gagal mengembalikan + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Arora gagal berfungsi semasa cuba mengembalikan sessi yang disimpan. Sessi berkenaan tidak akan dikembalikan. + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Fail + + + &New Window + Tetin&gkap Baru + + + &Open File... + Buka &Fail... + + + Open &Location... + Buka &Lokasi... + + + &Save As... + &Simpan Sebagai... + + + &Import Bookmarks... + &Import Tandabuku... + + + &Export Bookmarks... + &Eksport Tandabuku... + + + P&rint Preview... + P&rapapar Pencetak... + + + &Print... + &Pencetak... + + + Private &Browsing... + Melungsur secara pri&vasi... + + + &Quit + &Keluar + + + &Edit + &Edit + + + &Undo + &Batal + + + &Redo + &Semula + + + Cu&t + P&otong + + + &Copy + Sa&lin + + + &Paste + Tam&pal + + + &Find + &Cari + + + Find Nex&t + Ca&ri Seterusnya + + + Find P&revious + C&ari Sebelumnya + + + Prefere&nces... + Opsye&n... + + + Ctrl+, + Ctrl+, + + + &View + &Lihat + + + Show Menu Bar + Papar Bar Menu + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Henti + + + &Reload Page + &Muatsemula Laman + + + Make Text &Bigger + &Besarkan Text + + + Make Text &Normal + &Normalkan Text + + + Make Text &Smaller + &Kecilkan Text + + + Page S&ource + S&umber Laman + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + S&krin Penuh + + + Hi&story + &Sejarah + + + Back + Undur + + + Forward + Maju + + + Home + Laman Utama + + + Restore Last Session + Kembalikan Sessi Akhir + + + &Bookmarks + Tanda&buku + + + Manage Bookmarks... + Urus Tandabuku... + + + Add Bookmark... + Tambah Tandabuku... + + + &Window + Tetin&gkap + + + &Tools + &Alatan + + + Web &Search + &Carian Web + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Hapus Data Peribadi + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Benarkan Peny&iasat Web + + + &Help + Bant&uan + + + Switch application language + Tukar bahasa aplikasi + + + About &Qt + Perihal &Qt + + + About &Arora + Perihal &Arora + + + Navigation + Navigasi + + + Show Status Bar + Papar Bar Status + + + Hide Status Bar + Sembunyi Bar Status + + + Show Toolbar + Papar Bar Alat + + + Hide Toolbar + Sembunyi Bar Alat + + + Show Bookmarks Bar + Papar Bar Tandabuku + + + Hide Bookmarks Bar + Sembunyi Bar Tandabuku + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Buka Sumber Web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Sumber Web (*.html *.htm *.svg *.png *.gif *.svgz);;Semua fail (*.*) + + + Print Document + Cetak Dokumen + + + Are you sure you want to turn on private browsing? + Anda pasti ingin membuka lungsuran secara privasi? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Apabila lungsuran secara privasi sedang dibuka, Aksi yang melibatkan privasi anda dilumpuhkan:<ul><li> Laman yang dilawati tidak ditambah ke sejarah.</li><li> Senarai muaturun dibersihkan.</li><li> Cookies baru tidak disimpan, cookies semasa tidak boleh dicapai.</li><li> Ikon laman web dan sessi tidak disimpan.</li><li> Carian tidak disimpan di menu popup kotak carian.</li></ul>Selagi tetingkap tidak ditutup, anda masih boleh klik pada butang Undur dan Maju untuk kembalik ke laman yang pernah dibuka. + + + Are you sure you want to close the window?  There are %1 tabs open + Anda pasti ingin menutup tetingkap ini? Masih ada %1 tab terbuka + + + Web Inspector + Penyiasat Web + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Penyiasat Web cuma akan berfungsi dengan baik di laman yang dibuka selepas ia dibenarkan berfungsi. +Anda mahu memuatsemula kesemua laman? + + + Stop loading the current page + Henti memuat laman semasa + + + Reload the current page + Muatsemula laman semasa + + + Downloads + Muaturun + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + Show &Network Monitor + Papar Penyelia Rangkaia&n + + + Are you sure you want to close the window? There are %1 tabs open + Anda pasti ingin menutup tetingkap ini? Masih ada %1 tab yang terbuka + + + Close Window + Tutup Tetingkap + + + Zoom &In + Zoom Ke Da&lam + + + Zoom &Normal + Zoom &Normal + + + Zoom &Out + Zoom &Keluar + + + Zoom &Text Only + Zoom &Teks Sahaja + + + Show All Bookmarks... + Papar Kesemua Tandabuku... + + + Add Folder... + Tambah Folder... + + + About &%1 + About Browser + Perihal Pelayar + Perihal &%1 + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Apabila lungsuran privasi dipasang, sebahagian tindakan melibatkan privasi akan di lumpuhkan:<ul><li> Laman web tidak disimpan di dalam sejarah.</li><li> Senarai muaturun akan dikeluarkan dari tetingkap Muaturun.</li><li> Cookies baru tidak akan disimpan dan cookies semasa tidak dapat digunakan.</li><li> Ikon laman web tidak disimpan, sessi tidak disimpan.</li><li> Carian tidak ditambah pada menu popup di kekotak carian.</li></ul>Sebelum anda menutup tetingkap, anda masih boleh menggunakan butang Undur dan Maju untuk kembali ke laman web yang pernah di buka. + + + Ctrl+Y + Download Manager + Pengurus Muaturun + Ctrl+Y + + + Default + Lalai + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Hapus + + + + ClearPrivateData + + Clear Private Data + Hapus Data Peribadi + + + Clear the following items: + Hapuskan perkara berikut: + + + &Browsing History + Sejarah &Lungsuran + + + &Download History + Sejarah &Muaturun + + + &Search History + Sejarah &Carian + + + &Cookies + Coo&kie + + + C&ached Web Pages + C&ache Laman Web + + + Website &Icons + &Ikon Laman web + + + Clear &Private Data + &Hapus Data Peribadi + + + &Cancel + &Batal + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + Laman web + + + Rule + Peraturan + + + Allow + Benar + + + Block + Larang + + + Allow For Session + Benarkan Untuk Sessi + + + + CookieModel + + Website + Laman web + + + Name + Nama + + + Path + Path + + + Secure + Selamat + + + Expires + Luput + + + Contents + Kandungan + + + true + true + + + false + false + + + Session cookie + + + + + CookiesDialog + + Cookies + Cookie + + + &Remove + &Buang + + + Remove &All Cookies + Buang Semu&a Cookie + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + Pengecualian Cookie + + + New Exception + Cookie Baru + + + Domain: + Domain: + + + Block + Larang + + + Allow For Session + Benarkan Untuk Sessi + + + Allow + Benar + + + Exceptions + Pengecualian + + + &Remove + &Buang + + + Remove &All + Buang Semu&a + + + + DownloadDialog + + Downloads + Muaturun + + + Clean up + Bersihkan + + + 0 Items + 0 perkara + + + &OK + &OK + + + + DownloadItem + + Form + Form + + + Ico + Ico + + + Filename + Nama fail + + + Try Again + Cuba Semula + + + Stop + Henti + + + Open + Buka + + + Save File + Simpan Fail + + + Download canceled: %1 + Muaturun dibatalkan: %1 + + + Error opening output file: %1 + Ralat membuka fail keluaran: %1 + + + Error saving: %1 + Ralat menyimpan: %1 + + + Network Error: %1 + Ralat Rangkaian: %1 + + + seconds + saat + + + - %n minutes remaining + + lagi %n minit + + + + + - %n seconds remaining + + lagi %n saat + + + + + %1 of %2 (%3/sec) %4 + %1 dari %2 (%3/saat) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 of %2 - Berhenti + + + bytes + byte + + + kB + kB + + + MB + MB + + + %1 of %2 (%3/sec) - %4 + %1 dari %2 (%3/saat) - %4 + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + %n Download(s) + + %n Muaturun + + + + + There are %1 downloads in progress +Do you want to quit anyway? + Masih ada %1 proses muaturun berjalan +Anda masih ingin keluar? + + + %n minutes remaining + + lagi %n minit + + + + + %n seconds remaining + + lagi %n saat + + + + + bytes + byte + + + kB + kB + + + MB + MB + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + Buka + + + Copy + Salin + + + Delete + Padam + + + History + Sejarah + + + &Remove + &Buang + + + Remove &All + Buang Semu&a + + + + HistoryMenu + + Show All History + Tunjuk Semua Sejarah + + + Clear History... + Hapus Sejarah... + + + Clear History + Hapus Sejarah + + + Do you want to clear the history? + Anda mahu hapus sejarah? + + + + HistoryModel + + Title + Tajuk + + + Address + Alamat + + + + HistoryTreeModel + + Earlier Today + Awal Hari Ini + + + %n item(s) + + %n perkara + + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + System locale (%1) %2 + Sistem Lokal (%1) %2 + + + Choose language + Pilih bahasa + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Anda boleh menggunakan bahasa selain dari<br>tetapan sistem operasi.</p><p>Sila pilih bahasa yang harus digunakan</p> + + + Default + Lalai + + + No translation files are installed. + Fail terjemahan tidak dipasang. + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Masukkan nama pengguna dan katalaluan untuk "%1" di %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Berhubung dengan proxy "%1" menggunakan:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Ralat SSL: + +%1 + +%2 + +Anda mahu abaikan ralat ini? + + + Do you want to accept all these certificates? + Anda mahu menerima kesemua sijil? + + + - SSL Errors + - Ralat SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Ralat SSL:<br/><br/>untuk: <tt>%1</tt><ul><li>%2</li></ul> + +Anda ingin abaikan ralat ini?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Sijil:<br/>%1<br/>Anda mahu menerima kesemua sijil ini?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Nama + + + Value + Nilai + + + + NetworkMonitorDialog + + Network Monitor + Penyelia Rangkaian + + + Network Requests + Permintaan Rangkaian + + + Request Headers + Pengepala Permintaan + + + Response Headers + Pengepala Balasan + + + &Remove + &Buang + + + Remove &All Requests + Buang Semu&a Permintaan + + + + OpenSearchDialog + + Open File + Buka Fail + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Nama + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + Pengesahan Diperlukan + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Nama pengguna: + + + Password: + Katalaluan: + + + + PlainTextEditSearch + + Not Found + Tiada di laman ini + + + + ProxyDialog + + Proxy Authentication + Pengesahan Proxy + + + ICON + ICON + + + Connect to proxy + Berhubung dengan proxy + + + Username: + Nama pengguna: + + + Password: + Katalaluan: + + + + QObject + + The file is not an XBEL version 1.0 file. + Ini bukan fail XBEL versi 1.0. + + + Unknown title + Tajuk tidak diketahui + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Redirect: %1 + Lencongan %1 + + + Method + Kaedah + + + Address + Alamat + + + Response + Balasan + + + Length + Panjang + + + Content Type + Jenis Kandungan + + + Info + Maklumat + + + + SearchBanner + + Form + Form + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + Sudah + + + Highlight All + + + + + SearchLineEdit + + Search + Cari + + + + Settings + + Preferences + Opsyen + + + General + Umum + + + On startup: + Bila dibuka: + + + Show my home page + Tunjuk laman utama saya + + + Show a blank page + Tunjuk laman kosong + + + Restore windows and tabs from last time + Kembalikan tetingkap dan tab dari masa lampau + + + Home Page: + Laman Utama: + + + Set to current page + Tetapkan kepada laman semasa + + + Remove history items: + Buang sejarah: + + + After one day + Selepas sehari + + + After one week + Selepas seminggu + + + After two weeks + Selepas dua minggu + + + After one month + Selepas sebulan + + + After one year + Selepas setahun + + + Manually + Secara manual + + + On application exit + Bila aplikasi keluar + + + Open links from applications: + Buka pautan dari aplikasi: + + + In a tab in the current window + Di tab pada tetingkap semasa + + + In a new window + Di tetingkap baru + + + Downloads + Muaturun + + + Ask for a destination each time + Sentiasa menanya destinasi + + + Use this destination: + Gunakan destinasi ini: + + + Appearance + Penampilan + + + Standard font: + Font Standard: + + + Times 16 + Times 16 + + + Select... + Pilih... + + + Fixed-width font: + Font lebar-tetap: + + + Courier 13 + Courier 13 + + + Privacy + Privasi + + + Web Content + Kandungan Web + + + Enable Plugins + Benarkan Plugin + + + Enable Javascript + Benarkan Javascript + + + View Images + Tunjuk Imej + + + Cookies + Cookie + + + Accept Cookies: + Terima Cookie: + + + Always + Sentiasa + + + Never + Tidak + + + Only from sites you navigate to + Cuma dari laman yang anda pergi + + + Exceptions... + Pengecualian... + + + Keep Cookies Until: + Simpan cookie sehingga: + + + They expire + ia lupus + + + I exit the application + saya keluar dari aplikasi + + + At most 90 days + sehingga 90 hari + + + Cookies... + Cookie... + + + Tabs + Tab + + + Select tabs and windows as they are created + Pilih tab dan tetingkap sebaik ia dicipta + + + Confirm when closing multiple tabs + Pastikan bila menutup berbilang tab + + + Proxy + Proxy + + + Use proxy server + Guna server proxy + + + Type: + Type: + + + Socks5 + Socks5 + + + Http + Http + + + Host name: + Host name: + + + Port: + Port: + + + User Name: + Nama pengguna: + + + Password: + Katalaluan: + + + Advanced + Lanjut + + + Style Sheet: + Style Sheet: + + + Show only one close button instead of one for each tab + Papar cuma satu butang tutup bagi keseluruhan tab + + + Preferred languages for viewing webpages in: + Bahasa digemari untuk melihat laman web: + + + Block Popup Windows + Halang Tetingkap Popup + + + Opening links + Membuka capaian + + + Links that want to open in a new window: + Capaian yang hendak dibuka di tetingkap baru: + + + In a new selected tab in the current window + Di dalam tab terpilih baru di tetingkap semasa + + + In a new tab in the current window + Di dalam tab baru di tetingkap semasa + + + In the current tab + Di dalam tab semasa + + + Http (Secure) + Http (Selamat) + + + Http (Transparent) + Http (Telus) + + + Use ClickToFlash on flash plugins + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Memuat... + + + &Edit + &Edit + + + &Find + &Cari + + + Source of Page + Sumber Laman + + + &View + &Lihat + + + &Wrap lines + &Wrap barisan + + + Source of Page %1 + + + + + TabBar + + Show Tab Bar + Tunjuk Bar Tab + + + Hide Tab Bar + Sembunyi Bar Tab + + + New &Tab + &Tab Baru + + + Duplicate Tab + Salin Tab + + + &Close Tab + T&utup Tab + + + Close &Other Tabs + Tutup &Lain-lain Tab + + + Reload Tab + Muatsemula Tab + + + Reload All Tabs + Muatsemula Semua Tab + + + + TabWidget + + New &Tab + &Tab Baru + + + &Close Tab + T&utup Tab + + + Show Next Tab + Tunjuk Tab Seterusnya + + + Show Previous Tab + Tunjuk Tab Sebelumnya + + + Recently Closed Tabs + Tab yang baru ditutup + + + Untitled + Tiada tajuk + + + Do you really want to close this page? + Anda benar-benar mahu menutup laman ini? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Anda sudah mengubah laman ini dan jika menutupnya akan menyebabkan kehilangan perubahan ini. +Anda benar-benar mahu teruskan dengan menutup laman ini? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Simpan Tab + + + Loading... + Memuat... + + + Loading %1% (%2 %3)... + Memuat %1% (%2 %3)... + + + Finished loading + Selesai dimuatkan + + + Failed to load + Gagal dimuatkan + + + Bookmark All Tabs + Tandabukukan Ke Semua Tab + + + + ToolbarSearch + + No Recent Searches + Tiada Carian Sebelum Ini + + + Recent Searches + Carian Sebelum Ini + + + Clear Recent Searches + Hapus Carian Sebelum Ini + + + Suggestions + Cadangan + + + Add '%1' + + + + + WebPage + + Error loading page: %1 + Ralat memuat laman: %1 + + + When connecting to: %1. + Semasa berhubung ke: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Periksa alamat untuk kesilapan seperti <b>ww</br>.arora-browser.org yang sepatutnya <b>www</b>.arora-browser.org + + + If the address is correct, try to check the network connection. + Jika alamatnya betul, cuba periksa sambungan rangkaian. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Jika komputer atau rangkaian dilindungi oleh firewall atau proxy, pastikan pelungsur dibenarkan mencapai rangkaian. + + + If the address is correct, try checking the network connection. + Jika alamat betul, cuba periksa sambungan rangkaian. + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Buka di Tetin&gkap Baru + + + Open in New &Tab + Buka di &Tab Baru + + + Save Lin&k + Simpan P&autan + + + &Bookmark This Link + Tanda&buku Pautan Ini + + + &Copy Link Location + &Salin Lokasi Pautan + + + Open Image in New &Window + Buka I&mej di Tetingkap Baru + + + Open Image in New &Tab + Buka &Imej di Tab Baru + + + &Save Image + S&impan Imej + + + &Copy Image + Sa&lin Imej + + + C&opy Image Location + S&alin Lokasi Imej + + + Loading... + Memuat... + + + Search with... + + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Tidak Jumpa + + + diff --git a/src/locale/nb_NO.ts b/src/locale/nb_NO.ts new file mode 100644 index 00000000..0348d48a --- /dev/null +++ b/src/locale/nb_NO.ts @@ -0,0 +1,2414 @@ + + + + + AboutDialog + + About + Om + + + Authors + Forfattere + + + License + Lisens + + + Lightweight WebKit-based web browser + Lettvekts WebKit-basert nettleser + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Opphavsrett © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Lukk + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + Update the dates in the copyright notice? + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Opphavsrett © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + About %1 + Om %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Opphavsrett © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + WebKit versjon: %1 + + + + AcceptLanguage + + Languages + Språk + + + Languages: in order of preference: + Språk: ordnet etter preferanse: + + + Move &Up + Flytt &opp + + + Move &Down + Flytt &ned + + + &Remove + &Fjern + + + Add... + Legg til... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Blokkert av AdBlockRule:%1 + + + + AdBlockDialog + + Add Custom Rule + Legg til regel + + + Learn more about writing rules... + Lær mer om å skrive regler... + + + Update Subscription + Oppdater abonement + + + Browse Subscriptions... + Bla igjennom abonementer... + + + Remove Subscription + Fjern abonement + + + AdBlock Configuration + AdBlock konfigurasjon + + + Enable AdBlock + Skru på AdBlock + + + Action + Handling + + + + AdBlockManager + + Custom Rules + Regel + + + + AdBlockModel + + Rule + Regel + + + + AdBlockSchemeAccessHandler + + Subscribe? + Abonemer? + + + Subscribe to this AdBlock subscription? +%1 + Abonemer på dette AdBlock abonementet? %1 + + + + AddBookmarkDialog + + Add Bookmark + Legg til bokmerke + + + Type a name for the bookmark, and choose where to keep it. + Gi bokmerket et navn og velg hvor du vil lagre det. + + + Url + Addresse + + + Title + Tittel + + + Add Folder + Legg til mappe + + + + AutoFillDialog + + Form Passwords + Passord + + + Remove + Fjern + + + Remove All + Fjern alle + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Vil du lagre dette passordet?</b><br> Du kan se hvilke passord du har lagret og eventuelt slette dem under Egenskaper. + + + Never for this site + Aldri for denne siden + + + Not now + Ikke nå + + + + AutoFillModel + + WebSite + Nettside + + + User Name + Brukernavn + + + + BookmarksDialog + + Open + Åpne + + + Delete + Slett + + + New Folder + Ny mappe + + + Bookmarks + Bokmerker + + + &Remove + &Fjern + + + Add Folder + Legg til mappe + + + Open in New Tab + Åpne i ny fane + + + Edit Name + Endre navn + + + Edit Address + Endre adresse + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Feil ved lasting av bokmerker på linje %1, rad %2: +%3 + + + Toolbar Bookmarks + Bokmerker + + + Menu + Meny + + + Open File + Åpne fil + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importerte %1 + + + Save File + Lagre fil + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Feil ved eksportering + + + error saving bookmarks + feil ved lagring av bokmerker + + + Remove Bookmark + Fjern bokmerke + + + Insert Bookmark + Legg til bokmerke + + + Bookmarks Bar + Bokmerkelinjen + + + Bookmarks Menu + Bokmerkemeny + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Feil ved lasting av html bokmerker: %1 + + + Name Change + Undo bookmark title change + Navneendring + + + Address Change + Undo bookmark url change + Addresseendring + + + XBEL bookmarks + XBEL bokmerker + + + HTML Netscape bookmarks + HTML Netscape bokmerker + + + htmlToXBel tool required + trenger htmlToXBel verktøy + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + htmlToXBel verktøyet som følger med Arora og som trengs for å importere HTML bokmerker, er ikke installert eller er ikke i søkebanene. + + + Loading Bookmark + Laster bokmerker + + + Error when loading HTML bookmarks: %1 + + Feil ved lasting av HTML bokmerker: %1 + + + + BookmarksMenu + + Open in Tabs + Åpne i faner + + + + BookmarksModel + + Title + Tittel + + + Address + Adresse + + + + BookmarksToolBar + + Bookmark + Bokmerker + + + Open + Åpne + + + Open in New &Tab + Åpne i ny &fane + + + Remove + Fjern + + + Add Bookmark... + Legg til bokmerke... + + + Add Folder... + Legg til mappe... + + + Bookmarks + Bokmerker + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Det er %1 vinduer og %2 faner åpne +Er du sikker på at du vil avslutte Arora? + + + Restore failed + Gjennopretningen misslyktes + + + The saved session will not being restored because last time it was restored Arora crashed. + Den lagrede økten blir ikke gjennoprettet siden forrige gang den ble gjnoprettet krasjet Arora. + + + (Change: %1 %2) + (Endring: %1 %2) + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Den lagrede økten blir ikke gjennoprettet siden det førte til at Arora krasjet. + + + Arora crashed while trying to restore this session. Should I try again? + Arora kræsjet forrige gang vi prøvde å gjennoprette denne siden. Skal vi prøve igjenn? + + + + BrowserMainWindow + + &File + &Fil + + + &New Window + &Nytt vindu + + + &Open File... + &Åpne fil... + + + Open &Location... + Åpne a&dresse... + + + &Save As... + La&gre som... + + + &Import Bookmarks... + &Importer bokmerker... + + + &Export Bookmarks... + &Eksporter bokmerker... + + + P&rint Preview... + &Forhåndsvisning... + + + &Print... + &Skriv ut... + + + Private &Browsing... + &Privat surfing... + + + &Quit + &Avslutt + + + &Edit + &Rediger + + + &Undo + &Angre + + + &Redo + &Gjennta + + + Cu&t + &Klipp + + + &Copy + K&opier + + + &Paste + &Lim + + + &Find + &Finn + + + Ctrl+, + Ctrl+, + + + &View + &Vis + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Stop + + + Page S&ource + &Kildekode + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Fullskjerm + + + Hi&story + &Historie + + + Back + Tilbake + + + Forward + Fram + + + Home + Hjem + + + Restore Last Session + Gjennoprett siste økt + + + &Bookmarks + &Bokmerker + + + Manage Bookmarks... + Håndter bokmerker... + + + Add Bookmark... + Legg til bokmerke... + + + &Window + V&indu + + + &Tools + V&erktøy + + + Web &Search + &Nettsøk + + + Ctrl+K + Web Search + Ctrl+K + + + Enable Web &Inspector + &Aktiver nettinspektøren + + + &Help + H&jelp + + + About &Qt + Om &Qt + + + About &Arora + Om &Arora + + + Navigation + Navigering + + + Show Status Bar + Vis statuslinjen + + + Hide Status Bar + Skjul statuslinjen + + + Show Toolbar + Vis verktøylinjen + + + Hide Toolbar + Skjul verktøylinjen + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Åpne nettresurs + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Nettresurser (*.html *.htm *.svg *.png *.gif *.svgz);;Alle filer (*.*) + + + Print Document + Skriv ut dokument + + + Are you sure you want to turn on private browsing? + Er du sikker på at du vil skru på privat surfing? + + + Are you sure you want to close the window? There are %1 tabs open + Er du sikker på at du vil lukke vinduet? Du har %1 faner åpne + + + Page Source of %1 + Kildekoden til %1 + + + Web Inspector + Nettinspektør + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Nettinspektøren virker kun som den skal for sider som blir lastet etter at den ble aktivert. +Vil du laste alle sider på nytt? + + + Stop loading the current page + Avbryt lasting av denne siden + + + Reload the current page + Oppdater denne siden + + + Downloads + Nedlastinger + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + &Clear Private Data + &Slett privat informasjon + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Show Bookmarks Bar + Vis bokmerkelinjen + + + Hide Bookmarks Bar + Skjul bokmerkelinjen + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Noen handlinger relatert til dine personlige opplysninger vil bli deaktiverte når privat surfing er skrudd på:<ul><li> Nettsider blir ikke lagt til i historien.</li><li> Elementer blir automatisk fjernet fra Nedlastninger vinduet.</li><li> Nye informasjonskapsler blir ikke lagret og gamle kan ikke åpnes.</li><li> Ikoner og økter blir ikke lagret.</li><li> Søk blir ikke lagt til i sprett-opp menyen i søkeboksen.</li></ul>Du kan fremdeles klikke Tilbake og Fram intill du lukker vinduet. + + + Find &Next + Finn &Neste + + + Find P&revious + Finn &forrige + + + Prefe&rences + &Instillinger + + + &Reload Page + &Last siden på nytt + + + Make Text &Bigger + Gjør teksten &større + + + Make Text &Normal + Gjør teksten &normal + + + Make Text &Smaller + Gjør teksten &mindre + + + Find Nex&t + Finn &neste + + + Prefere&nces... + &Instillinger... + + + Show Menu Bar + Vis menylinjen + + + Switch application language + Endre språk + + + Show &Network Monitor + &Vis nettverksovervåkeren + + + Close Window + Lukk vinduet + + + Zoom &In + Skaler &in + + + Zoom &Normal + &Normal skalering + + + Zoom &Out + Skaler &ut + + + Zoom &Text Only + Skaler kun &tekst + + + Show All Bookmarks... + Vis alle bokmerker... + + + Add Folder... + Legg til mappe... + + + About &%1 + About Browser + Om &%1 + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Noen handlinger relatert til dine personlige opplysninger vil bli deaktiverte når privat surfing er skrudd på:<ul><li> Nettsider blir ikke lagt til i historien.</li><li> Elementer blir automatisk fjernet fra Nedlastinger vinduet.</li><li> Nye informasjonskapsler blir ikke lagret og gamle kan ikke åpnes.</li><li> Ikoner og økter blir ikke lagret.</li><li> Søk blir ikke lagt til i sprett-opp menyen i søkeboksen.</li></ul>Du kan fremdeles klikke Tilbake og Fram intill du lukker vinduet. + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Forvalg + + + Text Encoding + Tekstkoding + + + Select &All + Velg &alt + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Noen handlinger relatert til dine personlige opplysninger vil bli deaktiverte når privat surfing er skrudd på:<ul><li> Nettsider blir ikke lagt til i historien.</li><li> Elementer blir automatisk fjernet fra Nedlastninger vinduet.</li><li> Nye informasjonskapsler blir ikke lagret og gamle kan ikke åpnes.</li><li> Ikoner og økter blir ikke lagret.</li><li> Søk blir ikke lagt til i sprett-opp menyen i søkeboksen.</li></ul>Du kan fremdeles klikke Tilbake og Fram intill du lukker vinduet. + + + Options... + Alternativer... + + + Configure Search Engines... + Konfigurer søkemotorer... + + + &Ad Block... + &AdBlock... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Så lenge privat surfing er skrudd på, vil noen handlinger være skrudd av: + + + Webpages are not added to the history. + Nettsider blir ikke lagt til i historien. + + + Items are automatically removed from the Downloads window. + Nedlastninger blir automatisk fjernet fra Nedlastninger vinduet. + + + New cookies are not stored, current cookies can't be accessed. + Nye informasjonskapsler blir ikke lagret og eksisterende informasjonskapsler kan ikke brukes. + + + Site icons won't be stored. + Nettsideikoner blir ikke lagret. + + + Session won't be saved. + Sessjoner blir ikke lagret. + + + Searches are not added to the pop-up menu in the search box. + Søk blir ikke lagt til i søkemenyen. + + + No new network cache is written to disk. + Nettverkshurtiglageret blir ikke skrevet til platelageret. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Så lenge du ikke lukker vinduet kan du fremdeles klikke Fram og Tilbake for å se sider du har åpnet. + + + Private Browsing + Privat surfing + + + + ClearButton + + Clear + Fjern + + + + ClearPrivateData + + Clear Private Data + Slett privat informasjon + + + Clear the following items: + Slett følgende elementer: + + + &Browsing History + &Surfehistorie + + + &Download History + &Nedlastingshistorie + + + &Search History + S&økehistorie + + + &Cookies + &Informasjonskapsler + + + C&ache + &Hurtiglager + + + Website &Icons + N&ettside ikoner + + + Clear &Private Data + Slett &privat informasjon + + + &Cancel + &Avbryt + + + C&ached Web Pages + &Mellomlagrede nettsider + + + + ClickToFlash + + Load + Last + + + Load All + Last alle + + + Add %1 to Whitelist + Legg til %1 i godkjentlisten + + + Remove from Whitelist + Fjern fra godkjentlisten + + + Settings + Innstilinger + + + Load Flash + Last Flash + + + + ClickToFlashSettings + + Whitelist sites + Godkjente sider + + + + CookieExceptionsModel + + Website + Nettside + + + Status + Status + + + Allow + Tillat + + + Block + Blokker + + + Allow For Session + Tillat for denne økten + + + Rule + Regel + + + + CookieModel + + Website + Nettside + + + Name + Navn + + + Path + Sti + + + Secure + Sikker + + + Expires + Utløper + + + Contents + Innhold + + + true + ja + + + false + nei + + + Session cookie + Sesjonsinformasjonskapsel + + + + CookiesDialog + + Cookies + Informasjonskapsler + + + &Remove + &Slett + + + Remove &All Cookies + Slett &alle informasjonskapslene + + + Add &Rule + Legg til &regel + + + + CookiesExceptionsDialog + + Cookie Exceptions + Unntak for informasjonskapsler + + + New Exception + Nytt unntak + + + Domain: + Domene: + + + Block + Blokker + + + Allow For Session + Tillat for økt + + + Allow + Tillat + + + Exceptions + Unntak + + + &Remove + &Fjern + + + Remove &All + Fjern &alle + + + + DownloadDialog + + Downloads + Nedlastinger + + + Clean up + Rydd opp + + + 0 Items + Ingen elementer + + + &OK + &OK + + + + DownloadItem + + Save File + Lagre fil + + + Download canceled: %1 + Nedlasting avbrutt: %1 + + + Error opening save file: %1 + Feil ved åpning av lagret fil: %1 + + + Error saving: %1 + Feil ved lagring: %1 + + + Network Error: %1 + Nettverksfeil: %1 + + + seconds + sekunder + + + %1 of %2 (%3/sec) %4 + %1 av %2 (%3/sek) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 av %2 - Stoppet + + + bytes + bytes + + + kB + kB + + + MB + MB + + + Form + Skjema + + + Ico + Ikon + + + Filename + Filnavn + + + Try Again + Prøv igjenn + + + Stop + Stopp + + + Open + Åpne + + + - %n minutes remaining + + - %n minutt gjennstår + - %n minutter gjennstår + + + + - %n seconds remaining + + - %n sekund gjennstår + - %n sekunder gjennstår + + + + Error opening output file: %1 + Feil ved skriving til fil: %1 + + + %1 of %2 (%3/sec) - %4 + %1 av %2 (%3/sek) - %4 + + + Download directory (%1) couldn't be created. + Nedlastningsbanen (%1) kunne ikke opprettes. + + + + DownloadManager + + %n Download(s) + + %n nedlasting + %n nedlastinger + + + + There are %1 downloads in progress +Do you want to quit anyway? + Det er %1 aktive nedlastinger +Er du sikker på at du vil avslutte? + + + %n minutes remaining + + %n minutt gjennstår + %n minutter gjennstår + + + + %n seconds remaining + + %n sekund gjennstår + %n sekunder gjennstår + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Ingen feil + + + Error opening: %1: No such file or directory + Feil ved åpning av: %1: Filen eller banen finnes ikke + + + Unable to read %1 + Kan ikke lese %1 + + + Contents of %1 + Innhold i %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + Åpne + + + Copy + Kopier + + + Delete + Slett + + + History + Historie + + + &Remove + &Fjern + + + Remove &All + Fjern &alle + + + + HistoryMenu + + Show All History + Vis hele historien + + + Clear History + Slett historien + + + Clear History... + Slett historien... + + + Do you want to clear the history? + Vil du slette historien? + + + + HistoryModel + + Title + Tittel + + + Address + Adresse + + + + HistoryTreeModel + + Earlier Today + I dag + + + %n item(s) + + %n element + %n elementer + + + + + JavaScriptAroraObject + + Welcome to Arora! + Velkommen til Arora! + + + Arora Start + Arora start + + + Search! + Søk! + + + Search results provided by + Søkeresultater levert av + + + About Arora + Om Arora + + + + LanguageManager + + Default + Standardspråk + + + Choose language + Velg språk + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Du kan bruke at annet språk enn<br>operativsystemets standardspråk.</p><p>Velg språk</p> + + + No translation files are installed. + Ingen oversettelses filer er installert. + + + No translation files are installed at %1. + Ingen oversettelsesfiler er installert i %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Oppgi brukernavn og passord for "%1" på %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Koble til mellomtjener "%1" ved å bruke:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + SSL Feil: + +%1 + +%2 + +Vil du ignorere disse feilene? + + + Do you want to accept all these certificates? + Vil du akseptere alle disse sertifikatene? + + + - SSL Errors + - SSL Feil + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL Feil:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Vil du ignorere disse feilene?<qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Sertifikater:<br/>%1<br/>Vil du akseptere alle disse sertifikatene?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Sertifikater:<br/>%1<br/>Vil du akseptere alle disse sertifikatene?</qt> + + + Issuer: %1 + Utsteder: %1 + + + Not valid before: %1 + Ikke gyldig før: %1 + + + Valid until: %1 + Gyldig inntil: %1 + + + Alternate Names: + Alternative navn: + + + + NetworkMonitor + + Name + Navn + + + Value + Verdi + + + + NetworkMonitorDialog + + Network Monitor + Nettverksovervåker + + + Network Requests + Nettverksforespørselser + + + Request Headers + Forespørselshode + + + Response Headers + Svarhode + + + &Remove + &Fjern + + + Remove &All Requests + Fjern &alle forespørselser + + + + OpenSearchDialog + + Open File + Åpne fil + + + OpenSearch + OpenSearch + + + Error + Feil + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 er ikke en gyldig OpenSearch 1.1 beskrivelse, eller så finnes den allerede i listen. + + + You must have at least one search engine in here. + Det må være minst en søkemotor her. + + + OpenSearch Manager + OpenSearch-behandler + + + &Restore Defaults + &Gjennoprett forvalg + + + &Delete + &Slett + + + &Add + &Legg til + + + &Close + &Lukk + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Beskrivelse:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Gir forslag</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Navn + + + Keywords + Nøkkelord + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Vil du legge til den følgende motoren i listen over søkemotorer?<br /><br />Navn: %1<br />Søker på: %2 + + + + PasswordDialog + + Authentication Required + + + + DUMMY ICON + + + + INTRO TEXT DUMMY + + + + Username: + Brukernavn: + + + Password: + Passord: + + + + PlainTextEditSearch + + Not Found + Ikke funnet + + + + ProxyDialog + + Proxy Authentication + + + + Connect to proxy + Koble til mellomtjener + + + Username: + Brukernavn: + + + Password: + Passord: + + + + QObject + + The file is not an XBEL version 1.0 file. + Filen er ikke en XBEL versjon 1.0 fil. + + + Unknown title + Ukjent tittel + + + The file is not an OpenSearch 1.1 file. + Filen er ikke en OpenSearch 1.1 fil. + + + + RequestModel + + Redirect: %1 + Videresend: %1 + + + Method + Metode + + + Address + Adresse + + + Response + Svar + + + Length + Lengde + + + Content Type + Innholdstype + + + Info + Info + + + + SearchBanner + + Done + Ferdig + + + Form + Is there a way for things like these be ommitted from translation since they are never shown in the UI? A comment would probably do, so translators don't have to figure it out :-) + Skjema + + + Highlight All + Merk alt + + + + SearchLineEdit + + Search + Søk + + + + Settings + + Settings + Innstilinger + + + General + Generelt + + + Home: + Hjem: + + + Set to current page + Sett til nåværende side + + + Remove history items: + Slett elementer fra historien: + + + After one day + Etter en dag + + + After one week + Etter en uke + + + After two weeks + Etter to uker + + + After one month + Etter en måned + + + After one year + Etter ett år + + + Manually + Manuelt + + + Open links from applications: + Åpne lenker fra andre programmer: + + + In a tab in the current window + I en fane i det nåværende vinduet + + + In a new window + I et nytt vindu + + + Appearance + Utforming + + + Fixed-width font: + Fastbreddeskrift: + + + Privacy + Personvern + + + Web Content + Nettinnhold + + + Enable Plugins + Aktiver programtillegg + + + Enable Javascript + Aktiver Javascript + + + Cookies + Informasjonskapsler + + + Accept Cookies: + Aksepter informasjonskapsler: + + + Always + Alltid + + + Never + Aldri + + + Only from sites you navigate to + Kun fra sider du surfer til + + + Exceptions... + Unntak... + + + Keep until: + Behold inntil: + + + They expire + De utløper + + + I exit the application + Jeg lukker programmet + + + At most 90 days + Høyst 90 dager + + + Cookies... + Informasjonskapsler... + + + Proxy + Mellomtjener + + + Enable proxy + Aktiver mellomtjener + + + Type: + Type: + + + Socks5 + Socks5 + + + Http + Http + + + Host: + Host: + + + Port: + Port: + + + User Name: + Brukernavn: + + + Password: + Passord: + + + Advanced + Avansert + + + Style Sheet: + Stilsett: + + + Downloads + Nedlastinger + + + Ask for a destination each time + Spørr om målkatalog hver gang + + + Use this destination: + Bruk denne katalogen: + + + Standard font: + Standard skrift: + + + Times 16 + Times 16 + + + Select... + Velg... + + + Courier 13 + Courier 13 + + + On application exit + Når programmet avsluttes + + + Enable Images + Aktiver bilder + + + Tabs + Faner + + + Select tabs and windows as they are created + Aktiver faner og vinduer når de opprettes + + + Confirm when closing multiple tabs + Be om bekreftelse for å lukke flere faner + + + On startup: + Ved oppstart: + + + Show my home page + Vis min hjemmeside + + + Show a blank page + Vis en blank side + + + Restore windows and tabs from last time + Gjennoprett vinduer og faner fra forrige gang + + + Preferences + Egenskaper + + + Home Page: + Hjemmeside: + + + View Images + Vis bilder + + + Keep Cookies Until: + Behold informasjonskapsler inntil: + + + Show only one close button instead of one for each tab + Vis kunn en lukkeknapp istedet for en per fane + + + Use proxy server + Bruk mellomtjener + + + Host name: + Vertsnavn: + + + Preferred languages for viewing webpages in: + Foretrukkne språk for visning av nettsider: + + + Block Popup Windows + Blokker sprettoppvinduer + + + Opening links + Åpning av lenker + + + Links that want to open in a new window: + Lenker som vil åpnes i et nytt vindu: + + + In a new selected tab in the current window + I en ny, aktiv fane i det aktive vinduet + + + In a new tab in the current window + I en ny fane i det aktive vinduet + + + In the current tab + I den aktive fanen + + + Http (Secure) + Http (Sikker) + + + Http (Transparent) + I don't know the Norwegian equivalent of this word in this context. + + + + Use ClickToFlash on flash plugins + Bruk ClickToFlash på flash-programtillegg + + + Filter Tracking Cookies + Filtrer ut sporingsinformasjonskapsler + + + Confirm when closing multiple tabs or windows + Be om bekreftelse for å lukke flere faner eller viduer + + + Quit the application when last tab is closed + Lukk programmet når siste fane blir lukket + + + Enable network cache + Aktiver nettverkshurtiglager + + + Maximum Size: + Maksimal størrelse: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Bruk standardsøkemotoren hvis URLen gitt av brukeren er ugyldig + + + Choose Directory... + Velg katalog... + + + A cookie session ends: + En informasjonskapselsesjon slutter: + + + When I exit the application + Når jeg skruv av programmet + + + 1 day + 1 dag + + + 2 days + 2 dager + + + 3 days + 3 dager + + + 7 days + 7 dager + + + 30 days + 30 dager + + + AutoFill + AutoFill + + + AutoFill web forms: + AutoFill skjemaer: + + + User names and passwords + Brukernavn og passord + + + Edit... + Rediger... + + + Browse... + Bla igjennom... + + + + SettingsDialog + + Restart required + Omstart påkrevd + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Nettverkshurtiglagerkonfigurasjonen har blitt endret. Nettleseren må startes på nytt for å kunne bruke endringene. + + + Choose Directory + Velg katalog + + + Choose CSS File + Velg CSS fil + + + + SourceViewer + + Loading... + Laster... + + + &Edit + &Rediger + + + &Find + &Finn + + + &View + &Vis + + + &Wrap lines + &Bryt linjer + + + Source of Page + Sidens kildekode + + + Source of Page %1 + Kildekoden til %1 + + + + TabBar + + New &Tab + Ny &fane + + + Duplicate Tab + Kopier fane + + + &Close Tab + &Lukk fane + + + Close &Other Tabs + Lukk &andre faner + + + Reload Tab + Last fane på nytt + + + Reload All Tabs + Last alle faner på nytt + + + Show Tab Bar + Vis fanelinjen + + + Hide Tab Bar + Skjul fanelinjen + + + + TabWidget + + New &Tab + N&y fane + + + &Close Tab + &Lukk fane + + + Show Next Tab + Vis neste fane + + + Show Previous Tab + Vis forrige fane + + + Recently Closed Tabs + Nylig lukkede faner + + + (Untitled) + (Uten tittel) + + + Do you really want to close this page? + Vil du virkelig lukke denne siden? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Du har gjort endringer til denne siden og når du lukker den vil du bli tapt. +Vil du virkelig lukke denne siden? + + + + Untitled + Uten tittel + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Lagrede faner + + + Loading... + Laster... + + + Loading %1% (%2 %3)... + Laster %1% (%2 %3)... + + + Finished loading + Lastet ferdig + + + Failed to load + Lasting misslyktes + + + Bookmark All Tabs + Arkiver alle faner som bokmerker + + + + ToolbarSearch + + Google + Google + + + No Recent Searches + Ingen nylige søk + + + Recent Searches + Nylige søk + + + Clear Recent Searches + Slett nylige søk + + + Suggestions + Forslag + + + Add '%1' + Legg til '%1' + + + Configure Search Engines... + Konfigurer søkemotorer... + + + + WebPage + + Error loading page: %1 + Feil ved lasting av side: %1 + + + When connecting to: %1. + Ved tilkobling til: %1. + + + Check the address for errors such as <b>ww</b>.trolltech.com instead of <b>www</b>.trolltech.com. + Sjekk adresselinjen for feil som <b>ww</b>.trolltech.com isteden for <b>www</b>.trolltech.com. + + + If the address is correct, try to check the network connection. + Hvis adressen er riktig, undersøk nettilkolingen. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Hvis datamaskinen eller nettverket ditt er beskyttet av en brannmur eller mellomtjener, sjekk at nettleseren har adgang til nettverket. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Sjekk adresselinjen for feil som <b>ww</b>.arora-browser.org isteden for <b>www</b>.arora-browser.org + + + If the address is correct, try checking the network connection. + Hvis adressen er riktig undersøk nettilkoblingen. + + + Resending POST request + Sender POST forespørsel på nytt + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Forespørselen, sammen med all dataen, må sendes på nytt for å kunne vise siden. Dette kan føre til uforutsette konsekvenser. F.eks., kan den samme handlingen bli utført flere ganger. Vil du fortsette? + + + + WebView + + Open in New &Window + Åpne i nytt &vindu + + + Open in New &Tab + Åpne i ny &fane + + + Save Lin&k + &Lagre lenke + + + &Bookmark This Link + Lag &bokmerke av denne lenken + + + &Copy Link Location + &Kopier denne lenken + + + Open Image in New &Window + Åpne bilde i nytt &vindu + + + Open Image in New &Tab + Åpne bilde i ny &fane + + + &Save Image + &Lagre bilde + + + &Copy Image + &Kopier bilde + + + C&opy Image Location + &Kopier bildeets sti + + + Loading... + Laster... + + + Search with... + Søk med... + + + Add to the toolbar search + Legg til i søkeverktøylinja + + + Method not supported + Metoden er ikke støttet + + + %1 method is not supported. + %1 metoden er ikke støttet. + + + Search engine + Søkemotor + + + Choose the desired search engine + Velg den ønskede søkemotoren + + + Engine name + Søkemotorens navn + + + Type in a name for the engine + Gi søkemotoren et navn + + + Block Image + Blokker bilde + + + + WebViewSearch + + Not Found + Ikke funnet + + + diff --git a/src/locale/nl.ts b/src/locale/nl.ts new file mode 100644 index 00000000..5e847d8c --- /dev/null +++ b/src/locale/nl.ts @@ -0,0 +1,2048 @@ + + + + + AboutDialog + + Authors + Auteurs + + + License + Licentie + + + Lightweight WebKit-based web browser + Lichte browser gebaseerd op WebKit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Sluiten + + + About %1 + Over %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + WebKit-versie: %1 + + + + AcceptLanguage + + Languages + Talen + + + Languages: in order of preference: + Talen in volgorde van voorkeur: + + + Move &Up + Om&hoog + + + Move &Down + Om&laag + + + &Remove + Ve&rwijderen + + + Add... + Toevoegen... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Geblokkeerd door regel: %1 + + + + AdBlockDialog + + Add Custom Rule + Eigen regel toevoegen + + + Learn more about writing rules... + Meer leren over regels schrijven... + + + Update Subscription + Abonnement bijwerken + + + Browse Subscriptions... + Abonnementen bekijken... + + + Remove Subscription + Abonnement verwijderen + + + AdBlock Configuration + Advertentieblokkering instellen + + + Enable AdBlock + Advertentieblokkering inschakelen + + + Action + Actie + + + + AdBlockManager + + Custom Rules + Eigen regels + + + + AdBlockModel + + Rule + Regel + + + + AdBlockSchemeAccessHandler + + Subscribe? + Abonneren? + + + Subscribe to this AdBlock subscription? +%1 + Aan dit abonnement voor advertentieblokkering abonneren? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Bladwijzer toevoegen + + + Type a name for the bookmark, and choose where to keep it. + Voer de naam voor de bladwijzer in, en kies waar op te slaan. + + + Url + Url + + + Title + Titel + + + Add Folder + Map toevoegen + + + + AutoFillDialog + + Form Passwords + Formulierwachtwoorden + + + Remove + Verwijderen + + + Remove All + Alle verwijderen + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Wilt u dit wachtwoord opslaan?</b><br> Om opgeslagen wachtwoorden na te kijken of te verwijderen, open het deel Automatisch Invullen in de voorkeuren. + + + Never for this site + Nooit voor deze site + + + Not now + Niet nu + + + + AutoFillModel + + WebSite + Website + + + User Name + Gebruikersnaam + + + + BookmarksDialog + + Open + Openen + + + Open in New Tab + Openen in nieuwe tab + + + Delete + Verwijderen + + + New Folder + Nieuwe map + + + Bookmarks + Bladwijzers + + + &Remove + Ver&wijderen + + + Add Folder + Map toevoegen + + + Edit Name + Naam bewerken + + + Edit Address + Adres bewerken + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Fout bij laden van bladwijzers op lijn %1, kolom %2: +%3 + + + Toolbar Bookmarks + Werkbalkbladwijzers + + + Menu + Menu + + + Open File + Bestand openen + + + Imported %1 + %1 geïmporteerd + + + Save File + Bestand opslaan + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Fout bij het exporteren + + + error saving bookmarks + fout bij het opslaan van de bladwijzers + + + Remove Bookmark + Bladwijzer verwijderen + + + Insert Bookmark + Bladwijzer invoegen + + + Bookmarks Bar + Bladwijzersbalk + + + Bookmarks Menu + Bladwijzersmenu + + + Name Change + Undo bookmark title change + Naam wijzigen + + + Address Change + Undo bookmark url change + Adres wijzigen + + + XBEL bookmarks + XBEL-bladwijzers + + + HTML Netscape bookmarks + HTML Netscape-bladwijzers + + + htmlToXBel tool required + htmlToXBel is nodig + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + htmlToXBel, wat wordt geleverd met Arora, is nodig om HTML-bladwijzers te importeren. Het is echter niet geïnstalleerd. + + + Loading Bookmark + Bladwijzer laden + + + Error when loading HTML bookmarks: %1 + + Fout bij het laden van HTML-bladwijzers: %1 + + + + + BookmarksMenu + + Open in Tabs + In tabs openen + + + + BookmarksModel + + Title + Titel + + + Address + Adres + + + + BookmarksToolBar + + Open + Openen + + + Open in New &Tab + In nieuwe &tab openen + + + Remove + Verwijderen + + + Add Bookmark... + Bladwijzer toevoegen... + + + Add Folder... + Map toevoegen... + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Er zijn %1 vensters en %2 tabs geopend +Wilt u toch afsluiten? + + + Restore failed + Herstellen mislukt + + + Arora crashed while trying to restore this session. Should I try again? + Arora crashte bij het herstellen van deze sessie. Opnieuw proberen? + + + + BrowserMainWindow + + &File + &Bestand + + + &New Window + &Nieuw venster + + + &Open File... + Bestand &openen... + + + Open &Location... + &Locatie openen... + + + &Save As... + O&pslaan als... + + + &Import Bookmarks... + Bladwijzers &importeren... + + + &Export Bookmarks... + Bladwijzers &exporteren... + + + P&rint Preview... + Afdruk&voorbeeld... + + + &Print... + &Afdrukken... + + + Private &Browsing... + Anoniem sur&fen... + + + &Quit + &Afsluiten + + + &Edit + &Bewerken + + + &Undo + Onge&daan maken + + + &Redo + Op&nieuw doen + + + Cu&t + Kn&ippen + + + &Copy + &Kopieren + + + &Paste + Plakk&en + + + &Find + &Zoeken + + + Ctrl+, + Ctrl+, + + + &View + Bee&ld + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Stoppen + + + Page S&ource + Paginab&ron + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Volledig s&cherm + + + Hi&story + &Geschiedenis + + + Back + Terug + + + Forward + Vooruit + + + Home + Startpagina + + + Restore Last Session + Vorige sessie herstellen + + + &Bookmarks + Bladwi&jzers + + + Add Bookmark... + Bladwijzer toevoegen... + + + &Window + &Venster + + + &Tools + H&ulpmiddelen + + + Web &Search + Web&zoeken + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + Privégegevens &wissen + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Web &Inspector inschakelen + + + &Help + &Help + + + About &Qt + Over &Qt + + + Navigation + Navigatie + + + Show Status Bar + Statusbalk tonen + + + Hide Status Bar + Statusbalk verbergen + + + Show Toolbar + Werkbalk tonen + + + Hide Toolbar + Werkbalk verbergen + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Webresources openen + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Webresources (*.html *.htm *.svg *.png *.gif *.svgz);;Alle bestanden(*.*) + + + Print Document + Document afdrukken + + + Are you sure you want to turn on private browsing? + Bent u zeker dat u anoniem surfen wilt inschakelen? + + + Are you sure you want to close the window? There are %1 tabs open + Bent u zeker dat u het venster wil sluiten? Er zijn %1 tabs geopend + + + Web Inspector + Web Inspector + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + De Web Inspector zal alleen correct werken voor pagina's die werden geladen na het inschakelen. +Wilt u alle pagina's herladen? + + + Stop loading the current page + Stop het laden van deze pagina + + + Reload the current page + Deze pagina herladen + + + Downloads + Downloads + + + Find P&revious + Vo&rige zoeken + + + &Reload Page + Pagina he&rladen + + + Show Bookmarks Bar + Bladwijzerbalk tonen + + + Hide Bookmarks Bar + Bladwijzerbalk verbergen + + + Find Nex&t + Volgend&e zoeken + + + Show Menu Bar + Menubalk tonen + + + Switch application language + Programmataal wijzigen + + + Close Window + Venster sluiten + + + Zoom &In + &Inzoomen + + + Zoom &Normal + &Normaal zoomen + + + Zoom &Out + Uitz&oomen + + + Zoom &Text Only + Alleen &tekst vergroten + + + About &%1 + About Browser + Over &%1 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Show All Bookmarks... + Alle bladwijzers tonen... + + + Add Folder... + Map toevoegen... + + + Default + Standaard + + + Text Encoding + Tekstcodering + + + Select &All + &Alle selecteren + + + Alt+Ctrl+B + Alt+Ctrl+B + + + Options... + Opties... + + + Configure Search Engines... + Zoekmachines instellen... + + + &Ad Block... + &Advertentieblokkering... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Wanneer anoniem surfen aan staat zullen sommige acties omtrent uw privacy worden uitgeschakeld: + + + Webpages are not added to the history. + Webpagina's worden niet aan de geschiedenis toegevoegd. + + + Items are automatically removed from the Downloads window. + Items worden automatisch verwijderd uit het Downloads-scherm. + + + New cookies are not stored, current cookies can't be accessed. + Nieuwe cookies worden niet opgeslagen, huidige cookies kunnen niet worden bereikt. + + + Site icons won't be stored. + Sitepictogrammen worden niet opgeslagen. + + + Session won't be saved. + De sessie wordt niet opgeslagen. + + + Searches are not added to the pop-up menu in the search box. + Zoekopdrachten worden niet toegevoegd aan het pop-upmenu in de zoekbalk. + + + No new network cache is written to disk. + Er wordt geen nieuwe cache naar de schijf geschreven. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Totdat u het venster sluit, kunt u nog altijd de Terug- en Vooruitknoppen gebruiken om terug te keren naar webpagina's die u geopend heeft. + + + Private Browsing + Anoniem surfen + + + + ClearButton + + Clear + Wissen + + + + ClearPrivateData + + Clear Private Data + Privégegevens wissen + + + Clear the following items: + Volgende items wissen: + + + &Browsing History + &Surfgeschiedenis + + + &Download History + &Downloadgeschiedenis + + + &Search History + &Zoekgeschiedenis + + + &Cookies + &Cookies + + + Website &Icons + Website&pictogrammen + + + Clear &Private Data + Privé&gegevens wissen + + + &Cancel + &Annuleren + + + C&ached Web Pages + Gec&achte pagina's + + + + ClickToFlash + + Load + Laden + + + Load All + Alles laden + + + Add %1 to Whitelist + %1 aan whitelist toevoegen + + + Remove from Whitelist + Van whitelist verwijderen + + + Settings + Instellingen + + + Load Flash + Flash laden + + + + ClickToFlashSettings + + Whitelist sites + Whitelist-sites + + + + CookieExceptionsModel + + Website + Website + + + Allow + Toestaan + + + Block + Blokkeren + + + Allow For Session + Voor deze sessie toestaan + + + Rule + Regel + + + + CookieModel + + Website + Website + + + Name + Naam + + + Path + Pad + + + Secure + Veilig + + + Expires + Vervalt + + + Contents + Inhoud + + + true + waar + + + false + fout + + + Session cookie + Sessie-cookie + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + Ver&wijderen + + + Remove &All Cookies + &Alle cookies verwijderen + + + Add &Rule + &Regel toevoegen + + + + CookiesExceptionsDialog + + Cookie Exceptions + Cookie-uitzonderingen + + + New Exception + Nieuwe uitzondering + + + Domain: + Domein: + + + Block + Blokkeren + + + Allow For Session + Toestaan voor sessie + + + Allow + Toestaan + + + Exceptions + Uitzonderingen + + + &Remove + Ver&wijderen + + + Remove &All + &Alle verwijderen + + + + DownloadDialog + + Downloads + Downloads + + + Clean up + Opschonen + + + 0 Items + 0 items + + + + DownloadItem + + Ico + Ico + + + Filename + Bestandsnaam + + + Try Again + Opnieuw proberen + + + Stop + Stoppen + + + Open + Openen + + + Save File + Bestand opslaan + + + Download canceled: %1 + Download geannuleerd: %1 + + + Error saving: %1 + Fout bij opslaan: %1 + + + Network Error: %1 + Netwerkfout: %1 + + + ? + ? + + + %1 of %2 - Stopped + %1 van %2 - Gestopt + + + Error opening output file: %1 + Fout bij het openen van het outputbestand: %1 + + + %1 of %2 (%3/sec) - %4 + %1 van %2 (%3/sec) - %4 + + + Download directory (%1) couldn't be created. + Downloadmap (%1) kon niet worden gemaakt. + + + + DownloadManager + + %n Download(s) + + 1 download + %n downloads + + + + There are %1 downloads in progress +Do you want to quit anyway? + Er zijn %1 downloads bezig +Wilt u toch afsluiten? + + + %n minutes remaining + + %n minuut resterend + %n minuten resterend + + + + %n seconds remaining + + %n seconde resterend + %n seconden resterend + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Geen fout + + + Error opening: %1: No such file or directory + Fout bij het openen: %1: is geen bestand of map + + + Unable to read %1 + Kon %1 niet lezen + + + Contents of %1 + Inhoud van %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + Openen + + + Copy + Kopieren + + + Delete + Verwijderen + + + History + Geschiedenis + + + &Remove + Ver&wijderen + + + Remove &All + &Alles verwijderen + + + + HistoryMenu + + Show All History + Volledige geschiedenis tonen + + + Clear History + Geschiedenis wissen + + + Clear History... + Geschiedenis wissen... + + + Do you want to clear the history? + Wilt u de hele geschiedenis wissen? + + + + HistoryModel + + Title + Titel + + + Address + Adres + + + + HistoryTreeModel + + Earlier Today + Eerder vandaag + + + %n item(s) + + 1 item + %n items + + + + + JavaScriptAroraObject + + Welcome to Arora! + Welkom bij Arora! + + + Arora Start + Arora Start + + + Search! + Zoeken! + + + Search results provided by + Zoekresultaten van + + + About Arora + Over Arora + + + + LanguageManager + + Choose language + Taal kiezen + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>U kan een andere taal gebruiken dan<br>de standaardtaal van het besturingssysteem.</p><p>Kies de te gebruiken taal.</p> + + + No translation files are installed at %1. + Er zijn geen vertaalbestanden geïnstalleerd op %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Voer gebruikersnaam en wachtwoord voor "%1" op %2 in</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Verbinden met proxy "%1" met:</qt> + + + - SSL Errors + - SSL-fouten + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL-fouten:<br/><br/>voor: <tt>%1</tt><ul><li>%2</li></ul> + +Wilt u deze fouten negeren?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificaten:<br/>%1<br/>Wilt u al deze certificaten accepteren?</qt> + + + Issuer: %1 + UItgever: %1 + + + Not valid before: %1 + Niet geldig voor: %1 + + + Valid until: %1 + Geldig tot: %1 + + + Alternate Names: + Alternatieve namen: + + + + OpenSearchDialog + + Open File + Bestand openen + + + OpenSearch + OpenSearch + + + Error + Fout + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 is geen geldige OpenSearch 1.1-beschrijving of staat al in uw lijst. + + + You must have at least one search engine in here. + U moet hiet tenminste één zoekmachine hebben. + + + OpenSearch Manager + OpenSearch-manager + + + &Restore Defaults + Standaa&rdwaarden herstellen + + + &Delete + Verwij&deren + + + &Add + &Toevoegen + + + &Close + &Sluiten + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Beschrijving:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Biedt contekstsuggesties</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Kommagescheiden lijst sleutelwoorden die in de zoekbalk mogen worden ingevoerd, gevolgd door zoektermen voor deze zoekmachine + + + Name + Naam + + + Keywords + Sleutelwoorden + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Wilt u de volgende zoekmachine aan uw lijst van zoekmachines toevoegen?<br /><br />Naam: %1<br />Zoekt op: %2 + + + + PasswordDialog + + Authentication Required + Authentificatie vereist + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Gebruikersnaam: + + + Password: + Wachtwoord: + + + + PlainTextEditSearch + + Not Found + Niet gevonden + + + + ProxyDialog + + Proxy Authentication + Proxy-authentificatie + + + Connect to proxy + Met proxy verbinden + + + Username: + Gebruikersnaam: + + + Password: + Wachtwoord: + + + + QObject + + The file is not an XBEL version 1.0 file. + Het bestand is geen XBEL 1.0-bestand. + + + Unknown title + Onbekende titel + + + The file is not an OpenSearch 1.1 file. + Het bestand is geen OpenSearch 1.1-bestand. + + + + SearchBanner + + Done + Klaar + + + Highlight All + + + + + SearchLineEdit + + Search + Zoeken + + + + Settings + + General + Algemeen + + + Set to current page + Huidige pagina gebruiken + + + Remove history items: + Geschiedenisitems verwijderen: + + + After one day + Na één dag + + + After one week + Na één week + + + After two weeks + Na twee weken + + + After one month + Na één maand + + + After one year + Na één jaar + + + Manually + Handmatig + + + On application exit + Bij het afsluiten van het programma + + + Open links from applications: + Links uit programma's openen: + + + In a new window + In een nieuw venster + + + Downloads + Downloads + + + Ask for a destination each time + Elke keer om een bestemming vragen + + + Use this destination: + Deze bestemming gebruiken: + + + Appearance + Uiterlijk + + + Standard font: + Standaard lettertype: + + + Select... + Selecteren... + + + Fixed-width font: + Lettertype met vaste breedte: + + + Privacy + Privacy + + + Web Content + Webinhoud + + + Enable Plugins + Plugins inschakelen + + + Enable Javascript + Javascript inschakelen + + + Cookies + Cookies + + + Accept Cookies: + Cookies accepteren: + + + Always + Altijd + + + Never + Nooit + + + Only from sites you navigate to + Alleen van sites waar u heen surft + + + Exceptions... + Uitzonderingen... + + + They expire + Ze vervallen + + + I exit the application + Ik het programma afsluit + + + At most 90 days + Maximaal 90 dagen + + + Cookies... + Cookies... + + + Tabs + Tabs + + + Select tabs and windows as they are created + Tabs en vensters selecteren als ze gemaakt worden + + + Proxy + Proxy + + + Type: + Type: + + + Socks5 + Socks5 + + + Port: + Poort: + + + User Name: + Gebruikersnaam: + + + Password: + Wachtwoord: + + + Advanced + Geavanceerd + + + Style Sheet: + Stijlblad: + + + On startup: + Bij het opstarten: + + + Show my home page + Toon mijn startpagina + + + Show a blank page + Toon een lege pagina + + + Restore windows and tabs from last time + Herstel vensters en tabs van de vorige keer + + + Preferences + Voorkeuren + + + Home Page: + Startpagina: + + + View Images + Afbeeldingen weergeven + + + Keep Cookies Until: + Cookies houden tot: + + + Use proxy server + Proxyserver gebruiken + + + Host name: + Hostnaam: + + + Show only one close button instead of one for each tab + Alleen één sluitknop tonen in plaats van één voor elke tab + + + Block Popup Windows + Popupvensters blokkeren + + + Opening links + Links openen + + + Links that want to open in a new window: + Links die in een nieuw venster geopend willen worden: + + + In a new selected tab in the current window + In een nieuwe geselecteerde tab in het huidige venster + + + In a new tab in the current window + In een nieuwe tab in het huidige venster + + + In the current tab + In de huidige tab + + + Http (Secure) + Http (veilig) + + + Http (Transparent) + Http (transparant) + + + Preferred languages for viewing webpages in: + Voorkeurstaal om webpagina's in te zien: + + + Use ClickToFlash on flash plugins + ClickToFlash gebruiken bij flashplugins + + + Filter Tracking Cookies + Opspoor-cookies filteren + + + Confirm when closing multiple tabs or windows + Bevestiging vragen bij het sluiten van meerdere tabs + + + Quit the application when last tab is closed + Het programma afsluiten indien de laatste tab wordt gesloten + + + Enable network cache + Netwerkcache inschakelen + + + Maximum Size: + Maximumgrootte: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Op de standaard zoekmachine terugvallen bij een foute URL + + + Choose Directory... + Map kiezen... + + + A cookie session ends: + Een cookiesessie eindigt: + + + When I exit the application + Wanneer ik het programma afsluit + + + 1 day + Na 1 dag + + + 2 days + Na 2 dagen + + + 3 days + Na 3 dagen + + + 7 days + Na 7 dagen + + + 30 days + Na 30 dagen + + + AutoFill + Automatisch invullen + + + AutoFill web forms: + Webformulieren automatisch invullen: + + + User names and passwords + Gebruikersnamen en wachtwoorden + + + Edit... + Bewerken... + + + Browse... + Bladeren... + + + + SettingsDialog + + Restart required + Herstart vereist + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + De configuratie van de netwerkcache is gewijzigd. Om dit effectief toe te passen moet de browser opnieuw worden opgestart. + + + Choose Directory + Map kiezen + + + Choose CSS File + Een CSS-bestand kiezen + + + + SourceViewer + + Loading... + Laden... + + + &Edit + &Bewerken + + + &Find + &Zoeken + + + Source of Page %1 + Paginabron van %1 + + + + TabBar + + Show Tab Bar + Tabbalk tonen + + + Hide Tab Bar + Tabbalk verbergen + + + Duplicate Tab + Tab klonen + + + &Close Tab + Tab &sluiten + + + Close &Other Tabs + &Andere tabs sluiten + + + Reload Tab + Tab herladen + + + Reload All Tabs + Alle tabs herladen + + + + TabWidget + + New &Tab + Nieuwe &tab + + + &Close Tab + Tab &sluiten + + + Show Next Tab + Volgende tab tonen + + + Show Previous Tab + Vorige tab tonen + + + Recently Closed Tabs + Kortgeleden gesloten tabs + + + Do you really want to close this page? + Bent u zeker dat u deze pagina wilt sluiten? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + U hebt deze pagina gewijzigd en als u deze sluit zult u de wijzigingen kwijtraken. +Bent u zeker dat u deze pagina wilt sluiten? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Untitled + Naamloos + + + Loading... + Laden... + + + Loading %1% (%2 %3)... + Laden %1% (%2 %3)... + + + Finished loading + Laden voltooid + + + Failed to load + Laden mislukt + + + Saved Tabs + Opgeslagen tabs + + + Bookmark All Tabs + Van alle tabs bladwijzers maken + + + + ToolbarSearch + + No Recent Searches + Geen recente zoekopdrachten + + + Recent Searches + Recente zoekopdrachten + + + Clear Recent Searches + Recente zoekopdrachten wissen + + + Suggestions + Suggesties + + + Add '%1' + '%1' toevoegen + + + + WebPage + + Error loading page: %1 + Fout bij het laden van de pagina: %1 + + + When connecting to: %1. + Bij het verbinden met: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Het adres controleren op fouten als <b>ww</b>.arora-browser.org in plaats van <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Indien uw computer of netwerk beschermd wordt door een firewall of proxy, zorg er dan voor dat de browser toegang krijgt tot het netwerk. + + + If the address is correct, try checking the network connection. + Indien het adres juist is, de netwerkverbinding proberen te testen. + + + Resending POST request + POST opnieuw versturen + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + In nieuw &venster openen + + + Open in New &Tab + In nieuwe &tab openen + + + Save Lin&k + L&ink opslaan + + + &Bookmark This Link + &Bladwijzer maken van deze link + + + &Copy Link Location + Linklocatie &kopieren + + + Open Image in New &Window + Afbeelding openen in nieuw &venster + + + Open Image in New &Tab + Afbeelding openen in nieuwe &tab + + + &Save Image + Afbeelding &opslaan + + + &Copy Image + Afbeelding &kopieren + + + C&opy Image Location + Afbeeldingslocatie& kopieren + + + Loading... + Laden... + + + Search with... + Zoeken met... + + + Add to the toolbar search + Aan zoekbalk toevoegen + + + Method not supported + Methode niet ondersteund + + + %1 method is not supported. + De methode %1 wordt niet ondersteund. + + + Search engine + Zoekmachine + + + Choose the desired search engine + Kies de zoekmachine + + + Engine name + Naam + + + Type in a name for the engine + Kies een naam voor de zoekmachine + + + Block Image + + + + + WebViewSearch + + Not Found + Niet gevonden + + + diff --git a/src/locale/pl.ts b/src/locale/pl.ts deleted file mode 100644 index 06ba5614..00000000 --- a/src/locale/pl.ts +++ /dev/null @@ -1,1501 +0,0 @@ - - - - - AboutDialog - - - About - O programie - - - - AddBookmarkDialog - - - Add Bookmark - Dodaj zakładkę - - - - Type a name for the bookmark, and choose where to keep it. - Podaj nazwę dla zakładki i wybierz gdzie chcesz ją umieścić. - - - - BookmarksDialog - - - Open - Otwórz - - - - Open in New Tab - Otwórz w nowej karcie - - - - Delete - Usuń - - - - New Folder - Nowy katalog - - - - Bookmarks - Zakładki - - - - &Remove - &Usuń - - - - Add Folder - Dodaj katalog - - - - BookmarksManager - - - Error when loading bookmarks on line %1, column %2: -%3 - Błąd podczas ładowania zakładek w linii %1, kolumna %2: -%3 - - - - Toolbar Bookmarks - Pasek zakładek - - - - Menu - Menu - - - - Open File - Otwórz plik - - - - XBEL (*.xbel *.xml) - XBEL (*.xbel *.xml) - - - - Imported %1 - Zaimportowano %1 - - - - Save File - Zapisz plik - - - - %1 Bookmarks.xbel - %1 Bookmarks.xbel - - - - Export error - Błąd przy eksportowaniu - - - - error saving bookmarks - Błąd przy zapisie zakładek - - - - Remove Bookmark - Usuń zakładkę - - - - Insert Bookmark - Wstaw zakładkę - - - - Name Change - Zmiana nazwy - - - - Address Change - Zmiana adresu - - - - BookmarksModel - - - Title - Tytuł - - - - Address - Adres - - - - BookmarksToolBar - - - Bookmark - Zakładka - - - - BrowserApplication - - - There are %1 windows and %2 tabs open -Do you want to quit anyway? - Obecnie otwartych jest %1 okien i %2 kart -Czy mimo to chcesz zakończyć? - - - - BrowserMainWindow - - - &File - &Plik - - - - &New Window - &Nowe okno - - - - &Open File... - &Otwórz plik... - - - - Open &Location... - Otwórz &lokację... - - - - &Save As... - Zapi&sz jako... - - - - &Import Bookmarks... - &Importuj zakładki... - - - - &Export Bookmarks... - &Eksportuj zakładki... - - - - P&rint Preview... - Podgląd wyd&ruku... - - - - &Print... - &Drukuj... - - - - Private &Browsing... - &Prywatne przeglądanie... - - - - &Quit - &Zakończ - - - - &Edit - &Edytuj - - - - &Undo - &Cofnij - - - - &Redo - &Ponów - - - - Cu&t - Wy&tnij - - - - &Copy - &Kopiuj - - - - &Paste - &Wklej - - - - &Find - &Znajdź - - - - &Find Next - &Znajdź następny - - - - &Find Previous - &Znajdź poprzedni - - - - &Preferences - &Preferencje - - - - Ctrl+, - Ctrl+, - - - - &View - &Widok - - - - Shift+Ctrl+B - Shift+Ctrl+B - - - - Ctrl+| - Ctrl+| - - - - Ctrl+/ - Ctrl+/ - - - - &Stop - &Zatrzymaj - - - - Reload Page - Odśwież stronę - - - - &Make Text Bigger - &Powiększ rozmiar tekstu - - - - &Make Text Normal - &Przywróć rozmiar tekstu - - - - &Make Text Smaller - &Zmniejsz rozmiar tekstu - - - - Page S&ource - Źródł&o strony - - - - Ctrl+Alt+U - Ctrl+Alt+U - - - - &Full Screen - &Tryb pełnoekranowy - - - - Hi&story - Hi&storia - - - - Back - Wstecz - - - - Forward - Do przodu - - - - Home - Strona domowa - - - - Restore Last Session - Odtwórz ostatnią sesję - - - - &Bookmarks - &Zakładki - - - - Manage Bookmarks... - Zarządzaj zakładkami... - - - - Add Bookmark... - Dodaj zakładkę... - - - - &Window - &Okno - - - - &Tools - &Narzędzia - - - - Web &Search - Wy&szukiwanie - - - - Ctrl+K - Web Search - Ctrl+K - - - - &Clear Private Data - Wy&czyść prywatne dane - - - - Ctrl+Shift+Delete - Clear Private Data - Ctrl+Shift+Delete - - - - Enable Web &Inspector - Włącz &inspektora stron - - - - &Help - &Pomoc - - - - About &Qt - Informacje o &Qt - - - - About &Arora - Informacje o programie &Arora - - - - Navigation - Nawigacja - - - - Show Status Bar - Pokaż pasek stanu - - - - Hide Status Bar - Schowaj pasek stanu - - - - Show Toolbar - Pokaż pasek narzędziowy - - - - Hide Toolbar - Schowaj pasek narzędziowy - - - - Show Bookmarks bar - Pokaż pasek zakładek - - - - Hide Bookmarks bar - Schowaj pasek zakładek - - - - Arora - Arora - - - - %1 - Arora - Page title and Browser name - %1 - Arora - - - - Open Web Resource - Otwórz plik internetowy - - - - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - Pliki internetowe (*.html *.htm *.svg *.png *.gif *.svgz);;Wszystkie pliki (*.*) - - - - Print Document - Drukuj dokument - - - - Are you sure you want to turn on private browsing? - Czy jesteś pewny że chcesz włączyć prywatne przeglądanie sieci? - - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. - <b>%1</b><br><br>Kiedy prywatne przeglądanie sieci jest włączone, niektóre działania dotyczące twojej prywatności są wyłączone:<ul><li> Strony internetowe nie są dodawane do historii.</li><li> Lista pobierania jest automatycznie czyszczona.</li><li> Nowe ciasteczka nie są zapisywane a dostęp do przechowywanych jest uniemożliwiony.</li><li> Ikony stron nie są przechowywane a sesje nie będą zapisane.</li><li> Wyszukiwania nie są dodawane do listy w menu pola wyszukiwania.</li></ul>Dopóki okno nie zostanie zamknięte, można używać przycisków Wstecz i Do przodu, by powrócić do wcześniej otwartych stron. - - - - Are you sure you want to close the window? There are %1 tab open - Czy jesteś pewien, że chcesz zamknąć okno? %1 kart jest otwartch - - - - Page Source of %1 - Źródło strony %1 - - - - Web Inspector - Inspektor stron - - - - The web inspector will only work correctly for pages that were loaded after enabling. -Do you want to reload all pages? - Inspektor stron porawnie działa tylko dla stron, które zostały załadowane po włączeniu inspektora. -Czy chcesz odświeżyć wszystkie strony? - - - - Stop loading the current page - Zatrzymaj ładowenie strony - - - - Reload the current page - Odśwież stronę - - - - Downloads - Pobieranie - - - - Alt+Ctrl+L - Download Manager - Alt+Ctrl+L - - - - ClearButton - - - Clear - Wyczyść - - - - ClearPrivateData - - - Clear Private Data - Wyczyść prywatne dane - - - - Clear the following items: - Wyczyść następujące elementy: - - - - &Browsing History - &Historia przeglądania - - - - &Download History - Historia po&bierania - - - - &Search History - Historia &wyszukiwania - - - - &Cookies - &Ciasteczka - - - - C&ache - P&amięć podręczną - - - - Website &Icons - &Ikony stron - - - - Clear &Private Data - Wyczyść &prywatne dane - - - - &Cancel - &Anuluj - - - - CookieExceptionsModel - - - Website - Strona - - - - Status - Stan - - - - Allow - Zezwól - - - - Block - Blokuj - - - - Allow For Session - Zezwól na czas sesji - - - - CookieModel - - - Website - Strona - - - - Name - Nazwa - - - - Path - Ścieżka - - - - Secure - Bezpieczne - - - - Expires - Wygasa - - - - Contents - Zawartość - - - - CookiesDialog - - - Cookies - Ciasteczka - - - - &Remove - &Usuń - - - - Remove &All Cookies - Usuń &wszystkie ciasteczka - - - - CookiesExceptionsDialog - - - Cookie Exceptions - Wyjątki ciasteczek - - - - New Exception - Nowy wyjątek - - - - Domain: - Domena: - - - - Block - Blokuj - - - - Allow For Session - Zezwól na czas sesji - - - - Allow - Zezwól - - - - Exceptions - Wyjątki - - - - &Remove - &Usuń - - - - Remove &All - Usuń &wszystkie - - - - DownloadDialog - - - Downloads - Pobieranie - - - - Clean up - Wyczyść - - - - 0 Items - 0 elementów - - - - DownloadItem - - - Form - Forma - - - - Ico - Ikona - - - - Filename - Nazwa pliku - - - - Try Again - Spróbuj ponownie - - - - Stop - Zatrzymaj - - - - Open - Otwórz - - - - Save File - Zapisz plik - - - - Download canceled: %1 - Pobieranie anulowane: %1 - - - - Error opening save file: %1 - Błąd przy otwieraniu zapisanego pliku: %1 - - - - Error saving: %1 - Błąd przy zapisie: %1 - - - - Network Error: %1 - Błąd sieci: %1 - - - - seconds - sekund - - - - minutes - minut - - - - - %4 %5 remaining - - %4 %5 pozostało - - - - %1 of %2 (%3/sec) %4 - %1 z %2 (%3/sek) %4 - - - - ? - ? - - - - %1 of %2 - Stopped - %1 z %2 - Zatrzymano - - - - bytes - bajtów - - - - kB - kB - - - - MB - MB - - - - DownloadManager - - - 1 Download - 1 pobieranie - - - - %1 Downloads - %1 pobierań - - - - HistoryDialog - - - Open - Otwórz - - - - Copy - Kopiuj - - - - Delete - Skasuj - - - - History - Historia - - - - &Remove - &Usuń - - - - Remove &All - Usuń &wszystkie - - - - HistoryMenu - - - Show All History - Pokaż całą historię - - - - Clear History - Wyczyść historię - - - - HistoryModel - - - Title - Tytuł - - - - Address - Adres - - - - HistoryTreeModel - - - Earlier Today - Dzisiaj - - - - %1 items - %1 elementów - - - - NetworkAccessManager - - - <qt>Enter username and password for "%1" at %2</qt> - <qt>Wpisz nazwę użytkownika i hasło dla "%1" na %2</qt> - - - - <qt>Connect to proxy "%1" using:</qt> - <qt>Połącz się z proxy "%1" używając:</qt> - - - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - Błędy SSL: - -%1 - -%2 - -Czy chcesz zignorować te błędy? - - - - Do you want to accept all these certificates? - Czy chcesz zaakceptować te certyfikaty? - - - - PasswordDialog - - - Authentication Required - Wymagane uwierzytelnienie - - - - DUMMY ICON - ATRAPA IKONY - - - - INTRO TEXT DUMMY - ATRAPA TEKSTU WSTĘPNEGO - - - - Username: - Nazwa użytkownika: - - - - Password: - Hasło: - - - - ProxyDialog - - - Proxy Authentication - Uwierzytelnienie proxy - - - - ICON - IKONA - - - - Connect to proxy - Połącz z proxy - - - - Username: - Nazwa użytkownika: - - - - Password: - Hasło: - - - - QObject - - - The file is not an XBEL version 1.0 file. - Wskazany plik nie jest plikiem XBEL w wersji 1.0. - - - - Unknown title - Nieznany tytuł - - - - SearchBanner - - - Form - Forma - - - - TextLabel - EtykietkaTekstowa - - - - < - < - - - - > - > - - - - Done - Zrobione - - - - SearchLineEdit - - - Search - Szukaj - - - - Settings - - - Settings - Ustawienia - - - - General - Ogólne - - - - Home: - Strona domowa: - - - - Set to current page - Ustaw jako obecną stronę - - - - Remove history items: - Usuń elementy historii: - - - - After one day - Po jednym dniu - - - - After one week - Po tygodniu - - - - After two weeks - Po dwóch tygodniach - - - - After one month - Po miesiącu - - - - After one year - Po roku - - - - Manually - Ręcznie - - - - Open links from applications: - Otwórz linki z aplikacji: - - - - In a tab in the current window - W karcie w obecnym oknie - - - - In a new window - W nowym oknie - - - - Downloads - Pobieranie - - - - Ask for a destination each time - Za każdym razem pytaj o miejsce do zapisu - - - - Use this destination: - Użyj następującego miejsca docelowego: - - - - Appearance - Wygląd - - - - Standard font: - Standardowa czcionka: - - - - Times 16 - Times 16 - - - - Select... - Wybierz... - - - - Fixed-width font: - O stałej szerokości: - - - - Courier 13 - Courier 13 - - - - Privacy - Prywatność - - - - Web Content - Zawartość sieci - - - - Enable Plugins - Włącz wtyczki - - - - Enable Javascript - Włącz obsługę języka Javascript - - - - Cookies - Ciasteczka - - - - Accept Cookies: - Akceptuj ciasteczka: - - - - Always - Zawsze - - - - Never - Nigdy - - - - Only from sites you navigate to - Tylko ze stron, które odwiedzasz - - - - Exceptions... - Wyjątki... - - - - Keep until: - Przechowuj: - - - - They expire - aż wygasną - - - - I exit the application - do zamknięcia programu - - - - At most 90 days - najwyżej 90 dni - - - - Cookies... - Ciasteczka... - - - - Proxy - Proxy - - - - Enable proxy - Włącz proxy - - - - Type: - Typ: - - - - Socks5 - Socks5 - - - - Http - Http - - - - Host: - Host: - - - - Port: - Port: - - - - User Name: - Nazwa użytkownika: - - - - Password: - Hasło: - - - - Advanced - Zaawansowane - - - - Style Sheet: - Arkusz stylów: - - - - TabBar - - - New &Tab - Nowa &karta - - - - Duplicate Tab - Duplikuj kartę - - - - &Close Tab - &Zamknij kartę - - - - Close &Other Tabs - Zamknij &inne karty - - - - Reload Tab - Odśwież kartę - - - - Reload All Tabs - Odśwież wszystkie karty - - - - TabWidget - - - New &Tab - Nowa &karta - - - - &Close Tab - &Zamknij kartę - - - - Show Next Tab - Pokaż następną kartę - - - - Show Previous Tab - Pokaż poprzednią kartę - - - - Recently Closed Tabs - Ostatnio zamykane karty - - - - (Untitled) - (Bez nazwy) - - - - Do you really want to close this page? - Czy na pewno chcesz zamknąć tę stronę? - - - - You have modified this page and when closing it you would lose the modification. -Do you really want to close this page? - - Wprowadziłeś modyfikacje na tej strone i kiedy ją zamkniesz to utracisz wszystkie zmiany. -Czy na pewno chcesz zamknąć tę stronę? - - - - ToolbarSearch - - - Google - Google - - - - No Recent Searches - Brak ostatnich wyszukiwań - - - - Recent Searches - Ostatnie wyszukiwań - - - - Clear Recent Searches - Wyczyść listę wyszukiwań - - - - WebPage - - - Error loading page: %1 - Błąd podczas ładowania strony: %1 - - - - WebView - - - Open in New &Window - Otwórz w nowym &oknie - - - - Open in New &Tab - Otwórz w nowej &karcie - - - - Save Lin&k - &Zapisz element docelowy - - - - &Bookmark This Link - Dodaj ten odnośnik do &zakładek - - - - &Copy Link Location - &Kopiuj adres odnośnika - - - - Open Image in New &Window - Otwórz obrazek w nowym o&knie - - - - Open Image in New &Tab - Otwórz obrazek w nowej k&arcie - - - - &Save Image - &Zapisz obrazek - - - - &Copy Image - &Kopiuj obrazek - - - - C&opy Image Location - K&opiuj adres obrazka - - - - WebViewSearch - - - Not Found - Nie znaleziono - - - diff --git a/src/locale/pl_PL.ts b/src/locale/pl_PL.ts new file mode 100644 index 00000000..bf536cc9 --- /dev/null +++ b/src/locale/pl_PL.ts @@ -0,0 +1,2065 @@ + + + + + AboutDialog + + Authors + Autorzy + + + License + Licencja + + + Lightweight WebKit-based web browser + Lekka przeglądarka internetowa bazująca na silniku WebKit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + + Close + Zamknij + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + About %1 + O programie %1 + + + WebKit version: %1 + Wersja WebKita: %1 + + + + AcceptLanguage + + Languages + Języki + + + Languages: in order of preference: + Języki: w kolejności preferencji: + + + Move &Up + Przesuń w &górę + + + Move &Down + Przesuń w &dół + + + &Remove + &Usuń + + + Add... + Dodaj... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Zablokowany przez regułę AdBlock: %1 + + + + AdBlockDialog + + Add Custom Rule + Dodaj własną regułę + + + Learn more about writing rules... + Dowiedz się więcej o tworzeniu reguł... + + + Update Subscription + Zaktualizuj subskrypcję + + + Browse Subscriptions... + Przeglądaj subskrypcje... + + + Remove Subscription + Usuń subskrypcję + + + AdBlock Configuration + Konfiguracja AdBlock + + + Enable AdBlock + Włącz AdBlock + + + Action + Akcja + + + + AdBlockManager + + Custom Rules + Własne reguły + + + + AdBlockModel + + Rule + Reguła + + + + AdBlockSchemeAccessHandler + + Subscribe? + Subskrybować? + + + Subscribe to this AdBlock subscription? +%1 + Dodać tę subskrypcję AdBlocka? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Dodaj zakładkę + + + Type a name for the bookmark, and choose where to keep it. + Podaj nazwę dla zakładki i wybierz gdzie chcesz ją umieścić. + + + Url + URL + + + Title + Tytuł + + + Add Folder + Dodaj katalog + + + + AutoFillDialog + + Form Passwords + Hasła w formularzach + + + Remove + Usuń + + + Remove All + Usuń wszystkie + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Chciałbyś zapisać to hasło?</b><br /> By przeglądać hasła, które zapisałeś i usunąć je, otwórz panel AutoFill w preferencjach. + + + Never for this site + Nigdy dla tej strony + + + Not now + Nie teraz + + + + AutoFillModel + + WebSite + Strona + + + User Name + Nazwa użytkownika + + + + BookmarksDialog + + Open + Otwórz + + + Open in New Tab + Otwórz w nowej karcie + + + Delete + Usuń + + + New Folder + Nowy katalog + + + Bookmarks + Zakładki + + + &Remove + &Usuń + + + Add Folder + Dodaj katalog + + + Edit Name + Edytuj nazwę + + + Edit Address + Edytuj adres + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Błąd podczas ładowania zakładek w linii %1, kolumna %2: +%3 + + + Toolbar Bookmarks + Pasek zakładek + + + Menu + Menu + + + Open File + Otwórz plik + + + Imported %1 + Zaimportowano %1 + + + Save File + Zapisz plik + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Błąd przy eksportowaniu + + + error saving bookmarks + Błąd przy zapisie zakładek + + + Remove Bookmark + Usuń zakładkę + + + Insert Bookmark + Wstaw zakładkę + + + Bookmarks Bar + Pasek zakładek + + + Bookmarks Menu + Menu zakładek + + + Name Change + Undo bookmark title change + Zmiana nazwy + + + Address Change + Undo bookmark url change + Zmiana adresu + + + XBEL bookmarks + Zakładki XBEL + + + HTML Netscape bookmarks + Zakładki Netscape HTML + + + htmlToXBel tool required + Narzędzie htmlToXBel + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Narzędzie htmlToXBel, które jest dostarczane z Arorą i wymagane do zaimportowania zakładek HTML, nie jest zainstalowane bądź nie jest dostępne w systemowych ścieżkach przeszukiwania. + + + Loading Bookmark + Ładowanie zakładek + + + Error when loading HTML bookmarks: %1 + + Błąd w trakcie ładowania zakładek: %1 + + + + + BookmarksMenu + + Open in Tabs + Otwórz w kartach + + + + BookmarksModel + + Title + Tytuł + + + Address + Adres + + + + BookmarksToolBar + + Open + Otwórz + + + Open in New &Tab + Otwórz w nowej &karcie + + + Remove + Usuń + + + Add Bookmark... + Dodaj zakładkę... + + + Add Folder... + Dodaj katalog... + + + Bookmarks + Zakładki + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Obecnie otwartych jest %1 okien i %2 kart +Czy mimo to chcesz zakończyć? + + + Restore failed + Przywracanie nie powiodło się + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Zapisana sesja nie mogła zostać przywrócona ponieważ Arora wysypała się. + + + Arora crashed while trying to restore this session. Should I try again? + Arora wywalila się w trakcie odzyskiwania sesji. Spróbować jeszcze raz? + + + + BrowserMainWindow + + &File + &Plik + + + &New Window + &Nowe okno + + + &Open File... + &Otwórz plik... + + + Open &Location... + Otwórz &lokację... + + + &Save As... + Zapi&sz jako... + + + &Import Bookmarks... + &Importuj zakładki... + + + &Export Bookmarks... + &Eksportuj zakładki... + + + P&rint Preview... + Podgląd wyd&ruku... + + + &Print... + &Drukuj... + + + Private &Browsing... + &Prywatne przeglądanie... + + + &Quit + &Zakończ + + + &Edit + &Edytuj + + + &Undo + &Cofnij + + + &Redo + &Ponów + + + Cu&t + Wy&tnij + + + &Copy + &Kopiuj + + + &Paste + &Wklej + + + &Find + &Znajdź + + + Ctrl+, + Ctrl+, + + + &View + &Widok + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Zatrzymaj + + + Page S&ource + Źródł&o strony + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Tryb pełnoekranowy + + + Hi&story + Hi&storia + + + Back + Wstecz + + + Forward + Do przodu + + + Home + Strona domowa + + + Restore Last Session + Odtwórz ostatnią sesję + + + &Bookmarks + &Zakładki + + + Add Bookmark... + Dodaj zakładkę... + + + &Window + &Okno + + + &Tools + &Narzędzia + + + Web &Search + Wy&szukiwanie + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + Wy&czyść prywatne dane + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Włącz &inspektora stron + + + &Help + &Pomoc + + + About &Qt + Informacje o &Qt + + + Navigation + Nawigacja + + + Show Status Bar + Pokaż pasek stanu + + + Hide Status Bar + Schowaj pasek stanu + + + Show Toolbar + Pokaż pasek narzędziowy + + + Hide Toolbar + Schowaj pasek narzędziowy + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Otwórz zasób internetowy + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Pliki internetowe (*.html *.htm *.svg *.png *.gif *.svgz);;Wszystkie pliki (*.*) + + + Print Document + Drukuj dokument + + + Are you sure you want to turn on private browsing? + Czy jesteś pewny że chcesz włączyć prywatne przeglądanie sieci? + + + Are you sure you want to close the window? There are %1 tabs open + Czy jesteś pewien, że chcesz zamknąć okno? %1 kart jest otwartych + + + Web Inspector + Inspektor stron + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Inspektor stron działa poprawnie tylko dla stron, które zostały wczytane po jego aktywowaniu. +Czy chcesz odświeżyć wszystkie strony? + + + Stop loading the current page + Zatrzymaj ładowanie strony + + + Reload the current page + Odśwież stronę + + + Downloads + Pobieranie + + + Find P&revious + Znajdź &poprzedni + + + &Reload Page + Odśwież st&ronę + + + Show Bookmarks Bar + Pokaż pasek zakładek + + + Hide Bookmarks Bar + Schowaj pasek zakładek + + + Find Nex&t + Znajdź &następny + + + Show Menu Bar + Pokaż pasek menu + + + Switch application language + Zmień język aplikacji + + + Close Window + Zamknij okno + + + Zoom &In + Pow&iększ + + + Zoom &Normal + Rozmiar pierwot&ny + + + Zoom &Out + P&omniejsz + + + Zoom &Text Only + Zwiększaj tylko &tekst + + + About &%1 + About Browser + Informacje o &%1 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Show All Bookmarks... + Pokaż wszystkie zakładki... + + + Add Folder... + Dodaj katalog... + + + Default + Domyślny + + + Text Encoding + Kodowanie znaków + + + Alt+Ctrl+B + Alt+Ctrl+B + + + Select &All + Zaznacz &wszystko + + + Options... + Opcje... + + + Configure Search Engines... + Konfiguruj wyszukiwarki... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Kiedy prywatne przeglądanie jest włączone, niektóre akcje wpływające na Twoją prywatność są wyłączone: + + + Webpages are not added to the history. + Historia nie jest uzupełniana o odwiedzane strony. + + + Items are automatically removed from the Downloads window. + Pobrane pliki są automatycznie usuwane z okna Pobierania. + + + New cookies are not stored, current cookies can't be accessed. + Nowe ciasteczka nie są przechowywane, aktualnie istniejące nie mogą być modyfikowane. + + + Site icons won't be stored. + Ikony stron nie będą zapisywane. + + + Session won't be saved. + Sesja nie jest zachowywana. + + + Searches are not added to the pop-up menu in the search box. + Wyszukiwania nie są dodawane do historii wyszukiwań. + + + No new network cache is written to disk. + Sieciowa pamięć podręczna jest tylko do odczytu. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Dopóki nie zamkniesz okna, możesz zawsze uzyć przycisków Wstecz i Do przodu, by wrócić do stron, które przeglądałeś. + + + Private Browsing + Prywatne przeglądanie + + + &Ad Block... + &AdBlock... + + + + ClearButton + + Clear + Wyczyść + + + + ClearPrivateData + + Clear Private Data + Wyczyść prywatne dane + + + Clear the following items: + Wyczyść następujące elementy: + + + &Browsing History + &Historia przeglądania + + + &Download History + Historia po&bierania + + + &Search History + Historia &wyszukiwania + + + &Cookies + &Ciasteczka + + + Website &Icons + &Ikony stron + + + Clear &Private Data + Wyczyść &prywatne dane + + + &Cancel + &Anuluj + + + C&ached Web Pages + Z&apisane w cache strony + + + + ClickToFlash + + Load + Wczytaj + + + Load All + Wczytaj wszystkie + + + Add %1 to Whitelist + Dodaj %1 do białej listy + + + Remove from Whitelist + Usuń z białej listy + + + Settings + Ustawienia + + + Load Flash + Wczytaj Flash + + + + ClickToFlashSettings + + Whitelist sites + Strony na białej liście + + + + CookieExceptionsModel + + Website + Strona + + + Allow + Zezwól + + + Block + Blokuj + + + Allow For Session + Zezwól na czas sesji + + + Rule + Zasada + + + + CookieModel + + Website + Strona + + + Name + Nazwa + + + Path + Ścieżka + + + Secure + Bezpieczne + + + Expires + Wygasa + + + Contents + Zawartość + + + true + prawda + + + false + fałsz + + + Session cookie + Ciasteczko sesji + + + + CookiesDialog + + Cookies + Ciasteczka + + + &Remove + &Usuń + + + Remove &All Cookies + Usuń &wszystkie ciasteczka + + + Add &Rule + Dodaj &regułę + + + + CookiesExceptionsDialog + + Cookie Exceptions + Wyjątki ciasteczek + + + New Exception + Nowy wyjątek + + + Domain: + Domena: + + + Block + Blokuj + + + Allow For Session + Zezwól na czas sesji + + + Allow + Zezwól + + + Exceptions + Wyjątki + + + &Remove + &Usuń + + + Remove &All + Usuń &wszystkie + + + + DownloadDialog + + Downloads + Pobieranie + + + Clean up + Wyczyść + + + 0 Items + 0 elementów + + + + DownloadItem + + Ico + Ikona + + + Filename + Nazwa pliku + + + Try Again + Spróbuj ponownie + + + Stop + Zatrzymaj + + + Open + Otwórz + + + Save File + Zapisz plik + + + Download canceled: %1 + Pobieranie anulowane: %1 + + + Error saving: %1 + Błąd przy zapisie: %1 + + + Network Error: %1 + Błąd sieci: %1 + + + ? + ? + + + %1 of %2 - Stopped + %1 z %2 - Zatrzymano + + + Error opening output file: %1 + Błąd w trakcie otwierania pliku docelowego: %1 + + + %1 of %2 (%3/sec) - %4 + %1 z %2 (%3/sek) - %4 + + + Download directory (%1) couldn't be created. + Katalog docelowy (%1) nie mógł zostać stworzony. + + + + DownloadManager + + %n Download(s) + + %n pobierany plik + %n pobierane pliki + %n pobieranych plików + + + + There are %1 downloads in progress +Do you want to quit anyway? + Trwa pobieranie %1 plików. +Czy mimo to chcesz zakończyć? + + + %n minutes remaining + + %n minuta pozostała + %n minuty pozostały + %n minut pozostało + + + + %n seconds remaining + + %n sekunda pozostała + %n sekundy pozostały + %n sekund pozostało + + + + bytes + bajtów + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Brak błędu + + + Error opening: %1: No such file or directory + Błąd w trakcie otwierania %1: Plik lub katalog nie istnieje + + + Unable to read %1 + Nie można czytać z %1 + + + Contents of %1 + Zawartość %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + Otwórz + + + Copy + Kopiuj + + + Delete + Skasuj + + + History + Historia + + + &Remove + &Usuń + + + Remove &All + Usuń &wszystkie + + + + HistoryMenu + + Show All History + Pokaż całą historię + + + Clear History + Wyczyść historię + + + Clear History... + Wyczyść historię... + + + Do you want to clear the history? + Chcesz wyczyścić historię? + + + + HistoryModel + + Title + Tytuł + + + Address + Adres + + + + HistoryTreeModel + + Earlier Today + Dzisiaj + + + %n item(s) + + %n element + %n elementy + %n elementów + + + + + JavaScriptAroraObject + + Welcome to Arora! + Witaj w Arorze! + + + Arora Start + Arora Start + + + Search! + Szukaj! + + + Search results provided by + Wyniki wyszukiwania pochodzą z + + + About Arora + O programie Arora + + + + LanguageManager + + Choose language + Wybierz język + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Możesz używać innego języka niż<br />domyślny systemowy.</p><p>Wybierz język, z którego chciałbyś korzystać.</p> + + + No translation files are installed. + Nie znaleziono żadnych plików językowych. + + + No translation files are installed at %1. + Żadne pliki językowe nie są zainstalowane w %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Wpisz nazwę użytkownika i hasło dla "%1" na %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Połącz się z proxy "%1" używając:</qt> + + + - SSL Errors + - Błędy SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Błędy SSL:<br/><br/>dla: <tt>%1</tt><ul><li>%2</li></ul> + +Czy chcesz zignorować te błędy?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certyfikaty:<br/>%1<br/>Czy chcesz zaakceptować wszystkie certyfikaty?</qt> + + + Issuer: %1 + Wydawca: %1 + + + Not valid before: %1 + Nieważny przed: %1 + + + Valid until: %1 + Ważny do: %1 + + + Alternate Names: + Alternatywne nazwy: + + + + OpenSearchDialog + + Open File + Otwórz plik + + + OpenSearch + OpenSearch + + + Error + Błąd + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 nie jest prawidłowym plikiem OpenSearch 1.1 lub jest już na Twojej liście. + + + You must have at least one search engine in here. + Musisz mieć co najmniej jedną wyszukiwarkę. + + + OpenSearch Manager + Menedżer wyszukiwarek OpenSearch + + + &Restore Defaults + &Przywróć domyślne + + + &Delete + &Usuń + + + &Add + &Dodaj + + + &Close + &Zamknij + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Opis:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Oferuje sugestie kontekstowe</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Oddzielona przecinkami lista słów kluczowych, które mogą zostać wpisane do paska wyszukiwania, wraz z wyrażeniem, które zostanie wyszukane w tej wyszukiwarce + + + Name + Nazwa + + + Keywords + Słowa kluczowe + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Czy chcesz dodać następującą wyszukiwarkę do swojej listy?<br /><br />Nazwa: %1<br />Wyszukuje na: %2 + + + + PasswordDialog + + Authentication Required + Wymagane uwierzytelnienie + + + DUMMY ICON + ATRAPA IKONY + + + INTRO TEXT DUMMY + ATRAPA TEKSTU WSTĘPNEGO + + + Username: + Nazwa użytkownika: + + + Password: + Hasło: + + + + PlainTextEditSearch + + Not Found + Nie znaleziono + + + + ProxyDialog + + Proxy Authentication + Uwierzytelnienie proxy + + + Connect to proxy + Połącz z proxy + + + Username: + Nazwa użytkownika: + + + Password: + Hasło: + + + + QObject + + The file is not an XBEL version 1.0 file. + Wskazany plik nie jest plikiem XBEL w wersji 1.0. + + + Unknown title + Nieznany tytuł + + + The file is not an OpenSearch 1.1 file. + Plik nie jest prawidłowym plikiem OpenSearch 1.1. + + + + SearchBanner + + Done + Zakończono + + + Highlight All + Podświetl wszystkie + + + + SearchLineEdit + + Search + Szukaj + + + + Settings + + General + Ogólne + + + Set to current page + Ustaw jako obecną stronę + + + Remove history items: + Usuń elementy historii: + + + After one day + Po jednym dniu + + + After one week + Po tygodniu + + + After two weeks + Po dwóch tygodniach + + + After one month + Po miesiącu + + + After one year + Po roku + + + Manually + Ręcznie + + + Open links from applications: + Otwórz linki z aplikacji: + + + In a new window + W nowym oknie + + + Downloads + Pobieranie + + + Ask for a destination each time + Za każdym razem pytaj o miejsce do zapisu + + + Use this destination: + Użyj następującego miejsca docelowego: + + + Appearance + Wygląd + + + Standard font: + Standardowa czcionka: + + + Select... + Wybierz... + + + Fixed-width font: + Czcionka o stałej szerokości: + + + Privacy + Prywatność + + + Web Content + Zawartość sieci + + + Enable Plugins + Włącz wtyczki + + + Enable Javascript + Włącz obsługę Javascript + + + Cookies + Ciasteczka + + + Accept Cookies: + Akceptuj ciasteczka: + + + Always + Zawsze + + + Never + Nigdy + + + Only from sites you navigate to + Tylko ze stron, które odwiedzasz + + + Exceptions... + Wyjątki... + + + They expire + aż wygasną + + + I exit the application + do zamknięcia programu + + + At most 90 days + najwyżej 90 dni + + + Cookies... + Ciasteczka... + + + Proxy + Proxy + + + Type: + Typ: + + + Socks5 + Socks5 + + + Port: + Port: + + + User Name: + Nazwa użytkownika: + + + Password: + Hasło: + + + Advanced + Zaawansowane + + + Style Sheet: + Arkusz stylów: + + + On startup: + Podczas uruchamiania: + + + Show my home page + Otwórz moją stronę domową + + + Show a blank page + Otwórz pustą stronę + + + Restore windows and tabs from last time + Przywróć okna i karty z poprzedniej sesji + + + On application exit + Przy zamykaniu aplikacji + + + Tabs + Karty + + + Select tabs and windows as they are created + Wybierz karty i okna tak jak zostały utworzone + + + Preferences + Ustawienia + + + Home Page: + Strona domowa: + + + View Images + Wyświetlaj obrazki + + + Keep Cookies Until: + Przechowuj ciastka: + + + Use proxy server + Użyj serwera proxy + + + Host name: + Host name: + + + Show only one close button instead of one for each tab + Wyświetlaj tylko jeden przycisk zamknięcia karty zamiast jednego dla każdej karty + + + Block Popup Windows + Blokuj wyskakujące okna + + + Opening links + Otwieraj łącza + + + Links that want to open in a new window: + Łącza, które chcą utworzyć nowe okno: + + + In a new selected tab in the current window + W nowej aktywnej karcie w bieżącym oknie + + + In a new tab in the current window + W nowej karcie w bieżącym oknie + + + In the current tab + W bieżącej karcie + + + Http (Secure) + Http (bezpieczny) + + + Http (Transparent) + Http (przejrzysty) + + + Preferred languages for viewing webpages in: + Preferowane języki do przeglądania stron: + + + Use ClickToFlash on flash plugins + not sure if ClickToFlash needs to be translated at all... + Użyj ClickToFlash dla pluginów flash + + + Filter Tracking Cookies + Odrzucaj śledzące ciastka + + + Confirm when closing multiple tabs or windows + Potwierdź zamknięcie wielu kart lub okien naraz + + + Quit the application when last tab is closed + Zamknij aplikację, gdy ostatnia karta zostanie zamknięta + + + Enable network cache + Włącz sieciową pamięć podręczną + + + Maximum Size: + Maksymalny rozmiar: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Szukaj w domyślnej wyszukiwarce kiedy tekst niebedący URL-em jest wprowadzony przez użytkownika + + + Choose Directory... + Wybierz katalog... + + + A cookie session ends: + Sesja ciasteczka kończy się: + + + When I exit the application + Podczas zamykania aplikacji + + + 1 day + 1 dzień + + + 2 days + 2 dni + + + 3 days + 3 dni + + + 7 days + 7 dni + + + 30 days + 30 dni + + + AutoFill + Autouzupełnianie formularzy + + + AutoFill web forms: + Uzupełniaj formularze: + + + User names and passwords + Nazwy użytkownika i hasła + + + Edit... + Edytuj... + + + Browse... + Przeglądaj... + + + + SettingsDialog + + Restart required + Ponowne uruchomienie wymagane + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Konfiguracja pamięci podręcznej została zmieniona. Aby została wzięta pod uwagę, przeglądarka musi być uruchomiona ponownie. + + + Choose Directory + Wybierz katalog + + + Choose CSS File + Wybierz plik CSS + + + + SourceViewer + + Loading... + Ładowanie... + + + &Edit + &Edytuj + + + &Find + &Znajdź + + + Source of Page %1 + Źródło strony %1 + + + + TabBar + + Duplicate Tab + Duplikuj kartę + + + &Close Tab + &Zamknij kartę + + + Close &Other Tabs + Zamknij &inne karty + + + Reload Tab + Odśwież kartę + + + Reload All Tabs + Odśwież wszystkie karty + + + Show Tab Bar + Pokaż pasek kart + + + Hide Tab Bar + Schowaj pasek kart + + + + TabWidget + + New &Tab + Nowa &karta + + + &Close Tab + &Zamknij kartę + + + Show Next Tab + Pokaż następną kartę + + + Show Previous Tab + Pokaż poprzednią kartę + + + Recently Closed Tabs + Ostatnio zamknięte karty + + + Do you really want to close this page? + Czy na pewno chcesz zamknąć tę stronę? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Wprowadziłeś modyfikacje na tej stronie i kiedy ją zamkniesz to utracisz wszystkie zmiany. +Czy na pewno chcesz zamknąć tę stronę? + + + + Untitled + Bez tytułu + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Loading... + Ładowanie... + + + Loading %1% (%2 %3)... + Ładowanie %1% (%2 %3)... + + + Finished loading + Zakończono ładowanie + + + Failed to load + Ładowanie nie powiodło się + + + Saved Tabs + Zapisane karty + + + Bookmark All Tabs + Dodaj wszystkie karty do zakładek + + + + ToolbarSearch + + No Recent Searches + Brak ostatnio wyszukiwanych fraz + + + Recent Searches + Ostatnio wyszukiwane frazy + + + Clear Recent Searches + Wyczyść listę ostatnio wyszukiwanych fraz + + + Suggestions + Sugestie + + + Add '%1' + Dodaj '%1' + + + + WebPage + + Error loading page: %1 + Błąd podczas ładowania strony: %1 + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Jeśli twój komputer lub sieć jest chroniona zaporą sieciową lub proxy, upewnij się, że przeglądarka ma uprawnienia do dostępu do sieci. + + + When connecting to: %1. + Podczas łączenia z: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Sprawdź adres pod kątem błędów takich jak <b>ww</b>.arora-browser.org zamiast <b>www</b>.arora-browser.org + + + If the address is correct, try checking the network connection. + Jeśli adres jest prawidłowy, sprawdź poprawność połączenia internetowego. + + + Resending POST request + Ponowne wysyłanie żądania POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Aby wyświetlić tę stronę, żądanie razem ze wszystkimi danymi musi być ponownie wysłane, co może prowadzić do nieoczekiwanego zachowania się strony np. ta sama akcja może być wykonana jeszcze raz. Czy na pewno chcesz kontynuować? + + + + WebView + + Open in New &Window + Otwórz w nowym &oknie + + + Open in New &Tab + Otwórz w nowej &karcie + + + Save Lin&k + &Zapisz element docelowy + + + &Bookmark This Link + Dodaj ten odnośnik do &zakładek + + + &Copy Link Location + &Kopiuj adres odnośnika + + + Open Image in New &Window + Otwórz obrazek w nowym o&knie + + + Open Image in New &Tab + Otwórz obrazek w nowej k&arcie + + + &Save Image + &Zapisz obrazek + + + &Copy Image + &Kopiuj obrazek + + + C&opy Image Location + K&opiuj adres obrazka + + + Loading... + Ładowanie... + + + Search with... + Szukaj z... + + + Add to the toolbar search + Dodaj do paska wyszukiwania + + + Method not supported + Metoda żądania nie wspierana + + + %1 method is not supported. + Metoda %1 jest nie wspierana. + + + Search engine + Wyszukiwarka + + + Choose the desired search engine + Wybierz żądaną wyszukiwarkę + + + Engine name + Nazwa wyszukiwarki + + + Type in a name for the engine + Podaj nazwę dla wyszukiwarki + + + Block Image + Zablokuj obrazek + + + + WebViewSearch + + Not Found + Nie znaleziono + + + diff --git a/src/locale/pt_BR.ts b/src/locale/pt_BR.ts index 2aa4fcfb..4c106af3 100644 --- a/src/locale/pt_BR.ts +++ b/src/locale/pt_BR.ts @@ -1,1224 +1,2195 @@ + - - + + AboutDialog - About - Sobre + About %1 + Sobre o %1 - - + + Authors + Autores + + + License + Licença + + + Lightweight WebKit-based web browser + Navegador web leve baseado no Webkit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Fechar + + + WebKit version: %1 + Versão do Webkit: %1 + + + + AcceptLanguage + + Languages + Idiomas + + + Languages: in order of preference: + Idiomas: em ordem de preferência: + + + Move &Up + Para &cima + + + Move &Down + Para &baixo + + + &Remove + &Remover + + + Add... + Adicionar... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Bloqueado por AdBlockRule: %1 + + + + AdBlockDialog + + Add Custom Rule + Adicionar regra personalizada + + + Learn more about writing rules... + Saiba mais sobre escrevendo regras... + + + Update Subscription + Atualizar subscrição + + + Browse Subscriptions... + Navegar nas subscrições... + + + Remove Subscription + Remover subscrição + + + AdBlock Configuration + Configuração do AdBlock + + + Enable AdBlock + Habilitar AdBlock + + + Action + Ação + + + + AdBlockManager + + Custom Rules + Personalizar regras + + + + AdBlockModel + + Rule + Regra + + + + AdBlockSchemeAccessHandler + + Subscribe? + Inscrever-se? + + + Subscribe to this AdBlock subscription? +%1 + Inscrever-se nesta subscrição AdBlock? +%1 + + + AddBookmarkDialog - Add Bookmark - Adicionar Favoritos + Add Bookmark + Adicionar favorito + + + Type a name for the bookmark, and choose where to keep it. + Escreva um nome para o favorito, e escolha onde deseja mantê-lo. + + + Url + Url + + + Title + Título + + + Add Folder + Adicionar pasta + + + + AutoFillDialog + + Form Passwords + Formulário de senhas + + + Remove + Remover + + + Remove All + Remover todos + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Gostaria de salvar esta senha?</b><br> Para rever as senhas que você salvou e removê-las, abra a aba Preenchimento automático em Ferramentas > Opções. + + + Never for this site + Nunca para este site + + + Not now + Não agora + + + + AutoFillModel + + WebSite + Site - Type a name for the bookmark, and choose where to keep it. - Digite o nome do favorito, e escolhe onde manter ele. + User Name + Usuário - - + + BookmarksDialog - Bookmarks - Favoritos + Open + Abrir + + + Open in New Tab + Abrir em nova aba + + + Edit Name + Editar nome - &Remove - &Remover + Edit Address + Editar endereço - Add Folder - Adicionar Pasta + Delete + Excluir - Open - Abrir + New Folder + Nova pasta - Open in New Tab - Abrir em nova aba + Bookmarks + Favoritos - Delete - Deletar + &Remove + &Remover - New Folder - Nova Pasta + Add Folder + Adicionar pasta - - + + BookmarksManager - Error when loading bookmarks on line %1, column %2: + Bookmarks Bar + Barra dos favoritos + + + Bookmarks Menu + Menu favoritos + + + Error when loading bookmarks on line %1, column %2: %3 - Erro ao carregar favoritos na linha %1, coluna%2: + Erro ao carregar os favoritos na linha %1, coluna %2: +%3 + + + Toolbar Bookmarks + Barra de ferramentas dos favoritos + + + Menu + Menu + + + Open File + Abrir arquivo + + + XBEL + XBEL + + + Error when loading html bookmarks: %1 + + Erro ao carregar html de favoritos: %1 + + + + Imported %1 + Importado %1 + + + Save File + Salvar arquivo + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel - Toolbar Bookmarks - + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) - Menu - Menu + Export error + Erro ao exportar - Open File - Abrir Arquivo + error saving bookmarks + Erro ao salvar favoritos - XBEL (*.xbel *.xml) - XBEL (*.xbel *.xml) + Remove Bookmark + Remover favorito - Imported %1 - Importado %1 + Insert Bookmark + Inserir favorito - Save File - Salvar Arquivo + Name Change + Undo bookmark title change + Desfazer alteração no título do favorito - %1 Bookmarks.xbel - %1 Favoritos.xbel + Address Change + Undo bookmark url change + Desfazer alteração na url do favorito - Export error - Erro na exportação + XBEL bookmarks + Favoritos XBEL - error saving bookmarks - erro salvando favoritos + HTML Netscape bookmarks + Favoritos Netscape HTML - Remove Bookmark - Remover Favorito + htmlToXBel tool required + Ferramenta htmlToXBel é requerida - Insert Bookmark - Inserir Favorito + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + A ferramenta htmlToXBel, que é expedida com o Arora e é necessária para importar os favoritos HTML, não está instalada ou disponível nos caminhos de procura. - Name Change - Troca de Nome + Loading Bookmark + Carregando favoritos - Address Change - Troca de Endereço + Error when loading HTML bookmarks: %1 + + Erro ao carregar os favoritos em HTML: %1 + + + + + BookmarksMenu + + Open in Tabs + Abrir em abas - - + + BookmarksModel - Title - Título + Title + Título - Address - Endereço + Address + Endereço - - + + BookmarksToolBar - Bookmark - Favorito + Bookmark + Favoritos + + + Open + Abrir + + + Open in New &Tab + Abrir em nova &aba + + + Remove + Remover + + + Add Bookmark... + Adicionar ao favorito... + + + Add Folder... + Adicionar pasta... + + + Bookmarks + Favoritos - - + + BrowserApplication - There are %1 windows and %2 tabs open + (Change: %1 %2) + (Alteração: %1 %2) + + + There are %1 windows and %2 tabs open Do you want to quit anyway? - Existem %1 janelas e %2 abas abertas -Você deve sair de qualquer maneira? + Existem %1 janelas e %2 abas abertas. +Você quer sair de qualquer maneira? + + + Restore failed + Falha ao restaurar + + + The saved session will not be restored because Arora crashed while trying to restore this session. + A sessão salva não será restaurada porque Arora fechou ao tentar restaurar esta sessão. - - + + Arora crashed while trying to restore this session. Should I try again? + Arora fechou durante a tentativa de restaurar essa sessão. Devo tentar novamente? + + + BrowserMainWindow - &File - &Arquivo + &File + &Arquivo + + + &New Window + &Nova janela + + + &Open File... + Abrir arquiv&o... + + + Open &Location... + Abrir &localização... + + + &Save As... + &Salvar como... - &New Window - &Nova Janela + &Import Bookmarks... + &Importar favoritos... - &Open File... - &Abrir Arquivo... + &Export Bookmarks... + &Exportar favoritos... - Open &Location... - Abrir &Endereço... + P&rint Preview... + Visualiza&r impressão... - &Save As... - &Salvar Como... + &Print... + Im&primir... - &Import Bookmarks... - &Importar Favoritos + Private &Browsing... + Navegação pri&vada... - &Export Bookmarks... - &Exportar Favoritos + Close Window + Fechar janela - P&rint Preview... - Imp&rimir Previsão + &Quit + &Sair - &Print... - Im&primir + &Edit + &Editar - Private &Browsing... - + &Undo + &Desfazer - &Quit - &Sair + &Redo + &Refazer - &Edit - &Editar + Cu&t + Cor&tar - &Undo - &Desfazer + &Copy + &Copiar - &Redo - &Refazer + &Paste + C&olar - Cu&t - &Recortar + &Find + Locali&zar - &Copy - &Colar + Find Nex&t + Pró&ximo - &Paste - &Colar + Find P&revious + Ante&rior - &Find - &Procurar + Prefere&nces... + Preferê&ncias... - &Find Next - &Procurar Próximo + Ctrl+, + Ctrl+, - &Find Previous - &Procurar Anterior + &View + E&xibir - &Preferences - &Preferências + Ctrl+| + Ctrl+| - Ctrl+, - Ctrl+, + Shift+Ctrl+B + Shift+Ctrl+B - &View - &Visualizar + Ctrl+/ + Ctrl+/ - Shift+Ctrl+B - Shift+Ctrl+B + Show Menu Bar + Mostrar barra de menu - Ctrl+| - Ctrl+| + &Reload Page + &Recarregar página - Ctrl+/ - Ctrl+/ + &Stop + &Parar - &Stop - &Parar + Zoom &In + A&umentar zoom - Reload Page - Recarregar Página + Zoom &Normal + Zoom &normal - &Make Text Bigger - &Fazer Texto Maior + Zoom &Out + Diminuir zoo&m - &Make Text Normal - &Fazer Texto Normal + Zoom &Text Only + Zoom somente do &texto - &Make Text Smaller - &Fazer Texto Menor + Page S&ource + F&onte da página - Page S&ource - Código &Fonte + Ctrl+Alt+U + Ctrl+Alt+U - Ctrl+Alt+U - Ctrl+Alt+U + &Full Screen + &Tela cheia - &Full Screen - &Tela Inteira + Hi&story + Hi&stórico - Hi&story - Hi&stórico + Back + Voltar - Back - Voltar + Forward + Avançar - Forward - Avançar + Home + Página inicial - Home - Página Inicial + Restore Last Session + Restaurar última sessão - Restore Last Session - Restaurar Última Sessão + &Bookmarks + Fa&voritos - &Bookmarks - &Favoritos + Show All Bookmarks... + Mostrar todos os favoritos... - Manage Bookmarks... - Gerenciar Favoritos + Add Bookmark... + Adicionar ao favorito... - Add Bookmark... - Adicionar Favorito... + Add Folder... + Adicionar pasta... - &Window - &Janela + &Window + &Janela - &Tools - &Ferramentas + &Tools + &Ferramentas - Web &Search - &Busca na Web + Web &Search + Pesqui&sar na web - Ctrl+K - Web Search - Ctrl+K + Ctrl+K + Web Search + Ctrl+K - &Clear Private Data - &Limpar Dados Pessoais + &Clear Private Data + Limpar &dados privados - Ctrl+Shift+Delete - Clear Private Data - Ctrl+Shift+Delete + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete - Enable Web &Inspector - Ativar Web &Inspector + Show &Network Monitor + Mostrar mo&nitor de rede - &Help - &Ajuda + Enable Web &Inspector + Habilitar &inspetor web - About &Qt - Sobre &Qt + &Help + &Ajuda - About &Arora - Sobre &Arora + Switch application language + Trocar idiomar da aplicação - Navigation - Navegação + About &Qt + Sobre &Qt - Show Status Bar - Mostrar Barra de Status + About &%1 + About Browser + Sobre o &%1 - Hide Status Bar - Esconder Barra de Status + Navigation + Navegação - Show Toolbar - Mostrar Barra de Ferramentas + Show Status Bar + Mostrar barra de status - Hide Toolbar - Esconder Barra de Ferramentas + Hide Status Bar + Ocultar barra de status - Show Bookmarks bar - Mostrar barra de Favoritos + Show Toolbar + Mostrar barra de ferramentas - Hide Bookmarks bar - Esconder barra de Favoritos + Hide Toolbar + Ocultar barra de ferramentas - Arora - Arora + Show Bookmarks Bar + Mostrar barra de favoritos - %1 - Arora - Page title and Browser name - %1 - Arora + Hide Bookmarks Bar + Ocultar barra de favoritos - Open Web Resource - Abrir Recurso Web + %1 - Arora + Page title and Browser name + %1 - Arora - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;Todos Arquivos (*.*) + Open Web Resource + Abrir recursos da web - Print Document - Imprimir Documento + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Recursos web (*.html *.htm *.svg *.png *.gif *.svgz);; Todos os arquivos (*.*) - Are you sure you want to turn on private browsing? - + Print Document + Imprimir documento - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. - + Are you sure you want to turn on private browsing? + Tem certeza que deseja ativar a navegação privada? - Are you sure you want to close the window? There are %1 tab open - + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Quando a navegação privada está ligada, algumas medidas relativas a sua privacidade serão desativadas:<ul><li> As páginas web não serão adicionadas no histórico.</li><li> Itens serão automaticamente removidos da janela de Downloads.</li><li> Novos cookies não serão armazenados, cookies atuais não podem ser acessados.</li><li> Ícones de sites não serão armazenados, sessões não serão salvas.</li><li> Pesquisas não serão adicionadas para o menu popup na caixa de pesquisa.</li></ul>Até você fechar a janela, você ainda pode clicar nos botões Voltar e Avançar para retornar às páginas que você tinha aberto. - Page Source of %1 - Código Fonte da página %1 + Are you sure you want to close the window? There are %1 tabs open + Tem certeza que deseja fechar a janela? Existem %1 abas abertas - Web Inspector - Web Inspector + Web Inspector + Inspetor web - The web inspector will only work correctly for pages that were loaded after enabling. + The web inspector will only work correctly for pages that were loaded after enabling. Do you want to reload all pages? - + O inspetor web só irá trabalhar corretamente para as páginas que foram carregadas após a habilitação. +Você deseja recarregar todas as páginas? + + + Stop loading the current page + Interromper o carregamento da página atual + + + Reload the current page + Atualizar a página atual + + + Downloads + Downloads + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Padrão + + + Text Encoding + Texto codificado + + + Select &All + Selecionar &tudo + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Quando a navegação privada estiver ligada, algumas ações a respeito de sua privacidade serão desativadas: <ul><li> As páginas web não serão adicionadas ao histórico.</li><li> Os itens serão automaticamente removidos da janela de Download.</li><li> Novos cookies não serão armazenados, e cookies atuais não poderão ser acessados.</li><li> Os ícones dos sites não serão armazenados, a sessão não será salva.</li><li> As pesquisas não serão adicionadas para o menu pop-up na caixa de pesquisa.</li><li> Nenhum novo cache de rede será escrito em disco.</li></ul> Até você fechar a janela, você ainda pode clicar nos botões Voltar e Avançar para retornar às páginas que você abriu. + + + Options... + Opções... + + + Configure Search Engines... + Configurar mecanismos de pesquisa... + + + &Ad Block... + &Ad Block... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Quando a navegação privada estiver ligada, algumas ações a respeito de sua privacidade serão desabilitadas: + + + Webpages are not added to the history. + As páginas web não serão adicionadas ao histórico. + + + Items are automatically removed from the Downloads window. + Os itens serão automaticamente removidos da janela de Download. + + + New cookies are not stored, current cookies can't be accessed. + Novos cookies não serão armazenados, e cookies atuais não poderão ser acessados. - Stop loading the current page - Parar de carregar a página atual + Site icons won't be stored. + Os ícones dos sites não serão armazenados. - Reload the current page - Recarregar página atual + Session won't be saved. + A sessão não será salva. - Downloads - Downloads + Searches are not added to the pop-up menu in the search box. + As pesquisas não serão adicionadas para o menu pop-up na caixa de pesquisa. - Alt+Ctrl+L - Download Manager - Alt+Ctrl+L + No new network cache is written to disk. + Nenhum novo cache de rede será escrito em disco. - - + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Até você fechar a janela, você ainda pode clicar nos botões Voltar e Avançar para retornar às páginas que você abriu. + + + Private Browsing + Navegação privada + + + ClearButton - Clear - Limpar + Clear + Limpar - - + + ClearPrivateData - Clear Private Data - Limpar Dados Pessoais + Clear Private Data + Limpar dados privados + + + Clear the following items: + Limpar os seguintes itens: + + + &Browsing History + &Histórico de navegação + + + &Download History + Histórico de &download + + + &Search History + Histórico de pe&squisa + + + &Cookies + &Cookies - Clear the following items: - Limpar os seguintes itens: + C&ached Web Pages + C&ache das páginas web - &Browsing History - &Navegar pelo Histórico + Website &Icons + Ícones de s&ites - &Download History - &Baixar Histórico + Clear &Private Data + Limpar dados &privados - &Search History - &Buscar Histórico + &Cancel + &Cancelar + + + ClickToFlash - &Cookies - &Cookies + Load + Carregar - C&ache - C&ache + Load All + Carregar todos - Website &Icons - &Ícones do Site + Add %1 to Whitelist + Adicionar %1 à Lista branca - Clear &Private Data - Limpar Informações &Pessoais + Remove from Whitelist + Remover da Lista branca - &Cancel - &Cancelar + Settings + Configurações - - + + Load Flash + Carregar flash + + + + ClickToFlashSettings + + Whitelist sites + Sites de Lista branca + + + CookieExceptionsModel - Website - Site + Website + Site - Status - Status + Rule + Regra - Allow - Permitir + Allow + Permitir - Block - Bloquear + Block + Bloquear - Allow For Session - Permitir Para Sessão + Allow For Session + Permitir para sessão - - + + CookieModel - Website - Site + Website + Site + + + Name + Nome + + + Path + Caminho + + + Secure + Segurança - Name - Nome + Expires + Expira - Path - Caminho + Contents + Sumário - Secure - Seguro + true + verdadeiro - Expires - Expira + false + falso - Contents - Conteúdo + Session cookie + Cookie da sessão - - + + CookiesDialog - Cookies - Cookies + Cookies + Cookies - &Remove - &Remover + &Remove + &Remover - Remove &All Cookies - Remover &Todos Cookies + Remove &All Cookies + Remover &todos os cookies - - + + Add &Rule + Adicionar &regra + + + CookiesExceptionsDialog - Cookie Exceptions - Exceção Cookie + Cookie Exceptions + Exceções do cookie - New Exception - Nova Exceção + New Exception + Nova exceção - Domain: - Domínio: + Domain: + Domínio: - Block - Bloquear + Block + Bloquear - Allow For Session - Permitir para essa Sessão + Allow For Session + Permitir para sessão - Allow - Permitir + Allow + Permitir - Exceptions - Exceções + Exceptions + Exceções - &Remove - &Remover + &Remove + &Remover - Remove &All - Remover &Todos + Remove &All + Remover &todos - - + + DownloadDialog - Downloads - Downloads + Downloads + Downloads - Clean up - Limpar + Clean up + Limpar - 0 Items - 0 itens + 0 Items + 0 itens - - + + DownloadItem - Form - Formulário + Form + De + + + Ico + Ico - Ico - Ico + Filename + Nome do arquivo - Filename - Nome do Arquivo + Try Again + Tentar novamente - Try Again - Tentar Novamente + Stop + Parar - Stop - Parar + Open + Abrir - Open - Abrir + Save File + Salvar arquivo - Save File - Salvar Arquivo + Download canceled: %1 + Download cancelado: %1 - Download canceled: %1 - Download cancelado: %1 + Error opening output file: %1 + Erro ao abrir o arquivo de saída: %1 - Error opening save file: %1 - Erro abrindo arquivo saldo: %1 + Error saving: %1 + Erro ao salvar: %1 - Error saving: %1 - Erro salvando: %1 + Network Error: %1 + Erro na rede: %1 - Network Error: %1 - Erro na Rede: %1 + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/seg) - %4 - seconds - segundos + ? + ? - minutes - minutos + %1 of %2 - Stopped + %1 de %2 - Parado - - %4 %5 remaining - - %4 %5 restante + Download directory (%1) couldn't be created. + O diretório de download (%1) não pôde ser criado. + + + DownloadManager - %1 of %2 (%3/sec) %4 - %1 de %2 (%3/segundo) %4 + There are %1 downloads in progress +Do you want to quit anyway? + Existem %1 downloads em progresso. +Você deseja sair de qualquer maneira? + + + %n Download(s) + + %n download + %n downloads + + + + %n minutes remaining + + %n minuto restante + %n minutos restantes + + + + %n seconds remaining + + %n segundo restante + %n segundos restantes + - ? - ? + bytes + bytes - %1 of %2 - Stopped - %1 de %2 - Parado + kB + kB - bytes - bytes + MB + MB - kB - kB + GB + GB + + + FileAccessReply - MB - MB + No Error + Nenhum erro + + + Error opening: %1: No such file or directory + Erro ao abrir: %1: Nenhum arquivo ou diretório encontrado + + + Unable to read %1 + Não foi possível ler %1 - - - DownloadManager - 1 Download - 1 Download + Contents of %1 + Conteúdo de %1 - %1 Downloads - %1 Downloads + %1 KB + %1 KB - - + + HistoryDialog - History - Histórico + Open + Abrir - &Remove - &Remover + Copy + Copiar - Remove &All - Remover &Todos + Delete + Excluir - Open - Abrir + History + Histórico - Copy - Copiar + &Remove + &Remover - Delete - Deletar + Remove &All + Remover &todos - - + + HistoryMenu - Show All History - Mostrar Todos Histórico + Show All History + Mostrar todos os históricos + + + Clear History... + Limpar histórico... + + + Clear History + Limpar histórico - Clear History - Limpar Histórico + Do you want to clear the history? + Você deseja limpar o histórico? - - + + HistoryModel - Title - Título + Title + Título - Address - Endereço + Address + Endereço - - + + HistoryTreeModel - Earlier Today - Hoje mais cedo + Earlier Today + Hoje cedo + + + %n item(s) + + %n item + %n itens + + + + + JavaScriptAroraObject + + Welcome to Arora! + Bem-vindoa ao Arora! + + + Arora Start + Iniciar Arora + + + Search! + Pesquisar! - %1 items - %1 itens + Search results provided by + Pesquisar resultados forneceidos por - - + + About Arora + Sobre Arora + + + + LanguageManager + + No translation files are installed. + Não estão instalados os arquivos de tradução. + + + Choose language + Escolha o idioma + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Você pode executar com um idioma diferente do que<br>o padrão do sistema operacional.</p><p>Por favor, escolha o idioma que deve ser utilizado</p> + + + No translation files are installed at %1. + Não há arquivos de tradução instalados em %1. + + + NetworkAccessManager - <qt>Enter username and password for "%1" at %2</qt> - <qt>Informe usuário e senha para \"%1\" e \"%2\"</qt> + <qt>Enter username and password for "%1" at %2</qt> + <qt>Digite o nome de usuário e senha para "%1" em %2</qt> - <qt>Connect to proxy "%1" using:</qt> - <qt>Conectar a proxy \"%1\" usando:</qt> + <qt>Connect to proxy "%1" using:</qt> + <qt>Conectar no proxy "%1" usando:</qt> - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - Erros SSL: - -%1 + - SSL Errors + - Erros SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> -%2 +Do you want to ignore these errors?</qt> + <qt>Erros SSL:<br/><br/>para: <tt>%1</tt><ul><li>%2</li></ul> -Você deseja ignorar esses erros? +Você deseja ignorar esses erros?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificados:<br/>%1<br/>Você deseja aceitar todos esses certificados?</qt> + + + Issuer: %1 + Expedido por: %1 + + + Not valid before: %1 + Sem validade não antes de: %1 + + + Valid until: %1 + Válido até: %1 + + + Alternate Names: + Nomes alternativos: + + + + NetworkMonitor + + Name + Nome + + + Value + Valor + + + + NetworkMonitorDialog + + Network Monitor + Monitor de rede + + + Network Requests + Pedidos da rede + + + Request Headers + Pedido dos cabeçalhos + + + Response Headers + Resposta dos cabeçalhos + + + &Remove + &Remover + + + Remove &All Requests + Remover &todos os pedidos + + + + OpenSearchDialog + + Open File + Abrir arquivo + + + OpenSearch + OpenSearch + + + Error + Erro + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 não é uma válida descrição OpenSearch 1.1 ou já está em sua lista. + + + You must have at least one search engine in here. + Você deve ter pelo menos um mecanismo de pesquisa aqui. + + + OpenSearch Manager + Gerenciar OpenSearch + + + &Add + &Adicionar + + + &Delete + &Excluir + + + &Restore Defaults + &Restaurar padrão + + + &Close + &Fechar + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descrição:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Exibir sugestões contextuais</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Lista separada por vírgulas de palavras-chave que podem ser inscritas na barra de endereços seguido de termos de procura para pesquisar com este mecanismo + + + Name + Nome - Do you want to accept all these certificates? - Você deseja aceitar todos esses certificados? + Keywords + Palavras-chave - - + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Você deseja adicionar o seguinte mecanismo para sua lista de mecanismos de pesquisa?<br /><br />Nome: %1<br />Pesquisar sobre: %2 + + + PasswordDialog - Authentication Required - Atenticação Requerida + Authentication Required + Requer autenticação - DUMMY ICON - + DUMMY ICON + IMITAÇÃO DE ÍCONE - INTRO TEXT DUMMY - Texto de Introdução + INTRO TEXT DUMMY + IMITAÇÃO DE INTRODUÇÃO DO TEXTO - Username: - Usuário: + Username: + Usuário: - Password: - Senha: + Password: + Senha: - - - ProxyDialog + + + PlainTextEditSearch - Proxy Authentication - Autenticação Proxy + Not Found + Não encontrado + + + ProxyDialog - ICON - ICON + Proxy Authentication + Autenticação no proxy - Connect to proxy - Conectar a proxy + Connect to proxy + Conectar-se no proxy - Username: - Usuário: + Username: + Usuário: - Password: - Senha: + Password: + Senha: - - + + QObject - The file is not an XBEL version 1.0 file. - O arquivo não é um arquivo XBEL versão 1.0 + The file is not an OpenSearch 1.1 file. + O arquivo não é um arquivo OpenSearch 1.1. - Unknown title - Título desconhecido + The file is not an XBEL version 1.0 file. + O arquivo não é um arquivo XBEL versão 1.0. + + + Unknown title + Título desconhecido + + + + RequestModel + + Redirect: %1 + Redirecionar: %1 + + + Method + Método + + + Address + Endereço + + + Response + Resposta + + + Length + Duração - - - SearchBanner - Form - Formulário + Content Type + Tipo do conteúdo - TextLabel - TextLabel + Info + Informação + + + SearchBanner - < - < + Form + De - > - > + Done + Fechar - Done - Feito + Highlight All + Testacar todos - - + + SearchLineEdit - Search - Busca + Search + Pesquisar - - + + Settings - Settings - Preferências + Preferences + Preferências - General - Geral + General + Geral - Home: - Págtina Inicial: + On startup: + Ao iniciar: - Set to current page - Setar a página atual + Show my home page + Mostrar minha página inicial - Remove history items: - Remover itens do histórico: + Show a blank page + Mostrar uma página em branco - After one day - Depois de um dia + Restore windows and tabs from last time + Restaurar janelas e abas de última hora - After one week - Depois de uma semana + Home Page: + Página inicial: - After two weeks - Depois de 2 semanas + Set to current page + Usar a página atual - After one month - Depois de um mês + Remove history items: + Remover itens do histórico: - After one year - Depois de um ano + After one day + Depois de um dia - Manually - Manualmente + After one week + Depois de uma semana - Open links from applications: - Abrir links de uma aplicação: + After two weeks + Depois de duas semanas - In a tab in the current window - Em uma aba na janela atual + After one month + Depois de um mês - In a new window - Em uma nova janela + After one year + Depois de um ano - Downloads - Downloads + Manually + Manualmente - Ask for a destination each time - Perguntar um destino todas as vezes + On application exit + Na saída da aplicação - Use this destination: - Use esse destino: + Downloads + Downloads - Appearance - Aparência + Ask for a destination each time + Perguntar para um destino de cada vez - Standard font: - Fonte padrão: + Use this destination: + Usar esse destino: - Times 16 - Times 16 + Appearance + Aparência - Select... - Selecionar... + Standard font: + Fonte padrão: - Fixed-width font: - Fonte com largura fixa: + Select... + Selecionar... - Courier 13 - Courier 13 + Fixed-width font: + Fonte com largura fixa: - Privacy - Privacidade + Preferred languages for viewing webpages in: + Idiomas preferenciais para visualização das páginas web: - Web Content - Conteúdo Web + Privacy + Privacidade - Enable Plugins - Permitir Plugins + Web Content + Conteúdo web - Enable Javascript - Permitir JavaScript + Block Popup Windows + Boquear janelas instantâneas - Cookies - Cookies + Enable Plugins + Habilitar plug-ins - Accept Cookies: - Aceitar Cookies: + Use ClickToFlash on flash plugins + Utilizar Clique para Instalar nos plug-ins flash - Always - Sempre + Enable Javascript + Habilitar javascript - Never - Nunca + View Images + Ver imagens - Only from sites you navigate to - Apenas sites que você navegar + Cookies + Cookies - Exceptions... - Exceções... + Accept Cookies: + Aceitar cookies: - Keep until: - Manter até: + Always + Sempre - They expire - Eles expirarem + Never + Nunca - I exit the application - Eu fecho a aplicação + Only from sites you navigate to + Somente de sites que você navega - At most 90 days - Mais de 90 dias + Exceptions... + Exceções... - Cookies... - Cookies... + Keep Cookies Until: + Manter cookie até: - Proxy - Proxy + They expire + Ele expirar - Enable proxy - Ativar proxy + I exit the application + Eu sair da aplicação - Type: - Tipo: + At most 90 days + No máximo 90 dias - Socks5 - Socks5 + Cookies... + Cookies... - Http - Http + Filter Tracking Cookies + Filtrar rastreamento de cookies - Host: - Host: + Tabs + Abas - Port: - Porta: + Select tabs and windows as they are created + Selecionar abas e janelas que são criadas - User Name: - Usuário: + Confirm when closing multiple tabs or windows + Confirmar quando fechar múltiplas abas e janelas - Password: - Senha: + Show only one close button instead of one for each tab + Mostrar apenas um botão fechar, em vez de um para cada aba - Advanced - Avançado + Quit the application when last tab is closed + Sair da aplicação quando a última aba for fechada - Style Sheet: - Folha de Estilo: + Opening links + Abrindo links - - - TabBar - New &Tab - Nova &Aba + Links that want to open in a new window: + Links que deseja abrir em uma nova janela: - Duplicate Tab - Duplicar Aba + In a new window + Em uma nova janela - &Close Tab - &Fechar Aba + In a new selected tab in the current window + Em uma nova aba selecionada na janela atual - Close &Other Tabs - Fechar &Outras Abas + In a new tab in the current window + Em uma nova aba na janela atual - Reload Tab - Recarregar Aba + In the current tab + Na aba atual - Reload All Tabs - Recarregar Todas as Abas + Open links from applications: + Abrir links de aplicações: + + + Proxy + Proxy + + + Use proxy server + Usar servidor proxy + + + Type: + Tipo: + + + Socks5 + Socks5 + + + Http (Secure) + Http (seguro) + + + Http (Transparent) + Http (transparente) + + + Host name: + Servidor: + + + Port: + Porta: + + + User Name: + Usuário: + + + Password: + Senha: + + + Advanced + Avançado + + + Style Sheet: + Folha de estilos: + + + Enable network cache + Habilitar cache de rede + + + Maximum Size: + Tamanho máximo: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Utilizar o mecanismo de pesquisa padrão como retorno, quando a URL fornecida pelo usuário é inválida + + + Choose Directory... + Escolher diretório... + + + A cookie session ends: + Terminar uma sessão de cookie: - - - TabWidget - New &Tab - Nova &Aba + When I exit the application + Quando eu sair do programa - &Close Tab - &Fechar Aba + 1 day + 1 dia - Show Next Tab - Mostrar Próxima Aba + 2 days + 2 dias - Show Previous Tab - Mostrar Aba Anterior + 3 days + 3 dias - Recently Closed Tabs - Abas Recentemente Fechadas + 7 days + 7 dias - (Untitled) - (Sem Título) + 30 days + 30 dias - Do you really want to close this page? - Você deseja fechar essa página? + AutoFill + Preenchimento automático - You have modified this page and when closing it you would lose the modification. + AutoFill web forms: + Preenchimento automático de formulários web: + + + User names and passwords + Usuários e senhas + + + Edit... + Editar... + + + Browse... + Procurar... + + + + SettingsDialog + + Restart required + Requer reinício + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + A configuração do cache de rede foi modificada. Então, para que possa ser efetivado, o navegador deve ser reiniciado. + + + Choose Directory + Escolher diretório + + + Choose CSS File + Escolher arquivo CSS + + + + SourceViewer + + Loading... + Carregando... + + + &Edit + &Editar + + + &Find + &Localizar + + + &View + &Ver + + + &Wrap lines + &Separador + + + Source of Page + Fonte da página + + + Source of Page %1 + Fonte da página %1 + + + + TabBar + + Show Tab Bar + Mostrar barra de abas + + + Hide Tab Bar + Ocultar barra de abas + + + Duplicate Tab + Duplicar aba + + + &Close Tab + &Fechar aba + + + Close &Other Tabs + Fechar &todas as abas + + + Reload Tab + Recarregar aba + + + Reload All Tabs + Recarregar todas as abas + + + + TabWidget + + Untitled + Sem título + + + Saved Tabs + Abas salvas + + + Do you really want to close this page? + Você realmente deseja fechar essa página? + + + You have modified this page and when closing it you would lose the modification. Do you really want to close this page? - Você modificou essa página e quando fechar você perderá as modificações. -Você realmente deseja fechar essa página? + Você modificou esta página e quando fechá-la, você perderá a modificação. +Você realmente deseja fechar esta página? + + + + Loading... + Carregando... + + + Loading %1% (%2 %3)... + Carregando %1% (%2 %3)... - - + + Finished loading + Terminado carregamento + + + Failed to load + Falha ao carregar + + + Show Next Tab + Mostrar próxima aba + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + Mostrar aba anterior + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + Abas fechadas recentemente + + + New &Tab + Nova &aba + + + &Close Tab + &Fechar aba + + + Bookmark All Tabs + Favorito de todas as abas + + + ToolbarSearch - Google - Google + Suggestions + Sugestões + + + Add '%1' + Adicionar '%1' + + + Configure Search Engines... + Configurar mecanismos de pesquisa... - No Recent Searches - Sem Pesquisas Recentes + Clear Recent Searches + Limpar pesquisas recentes - Recent Searches - Pesquisas Recentes + No Recent Searches + Sem pesquisas recentes - Clear Recent Searches - Limpar Pesquisas Recentes + Recent Searches + Pesquisas recentes - - + + WebPage - Error loading page: %1 - Erro carregando página: %1 + Error loading page: %1 + Erro ao carregar página: %1 + + + When connecting to: %1. + Ao conectar para: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Verifique o endereço se contém erros como <b>ww</b>.arora-browser.org em vez de <b>www</b>.arora-browser.org - - + + If the address is correct, try checking the network connection. + Se o endereço está correto, tente verificar a conexão de rede. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Se o seu computador ou rede estão protegidos por um firewall ou proxy, certifique-se que o navegador tem permissão para acessar a rede. + + + Resending POST request + Reenviando pedido POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Para exibir o site, o pedido juntamente com todos os dados devem ser enviados mais uma vez, o que pode levar a alguns comportamentos inesperados do site por exemplo, a mesma ação pode ser realizada mais uma vez. Você deseja continuar mesmo assim? + + + WebView - Open in New &Window - Abrir em uma Nova &Janela + Open in New &Window + Abrir em nova &janela + + + Open in New &Tab + Abrir em nova &aba + + + Save Lin&k + Salvar lin&k + + + &Bookmark This Link + &Favorito desse link + + + &Copy Link Location + &Copiar localização do link + + + Open Image in New &Window + Abrir imagem em nova &janela + + + Open Image in New &Tab + Abrir imagem em nova a&ba + + + &Save Image + &Salvar imagem + + + &Copy Image + Copiar &imagem + + + C&opy Image Location + C&opiar localização da imagem + + + Search with... + Pesquisar com... - Open in New &Tab - Abrir em uma Nova &Aba + Loading... + Carregando... - Save Lin&k - Salvar Lin&k + Add to the toolbar search + Adicionar para a barra de ferramentas de pesquisa - &Bookmark This Link - &Adicionar Link a Favoritos + Method not supported + Método não suportado - &Copy Link Location - &Copar Endereço do Link + %1 method is not supported. + %1 método não é suportado. - Open Image in New &Window - Abrir Imagem em uma Nova &Janela + Search engine + Mecanismo de pesquisa - Open Image in New &Tab - Abrir imagem em uma Nova &Aba + Choose the desired search engine + Escolha o mecanismo de pesquisa - &Save Image - &Salvar Imagem + Engine name + Nome do mecanismo - &Copy Image - &Copiar Imagem + Type in a name for the engine + Escreva um nome para o mecanismo - C&opy Image Location - C&opiar Endereço da Imagem + Block Image + Bloquear imagem - - + + WebViewSearch - Not Found - Não Encontrado + Not Found + Não encontrado - + diff --git a/src/locale/pt_PT.ts b/src/locale/pt_PT.ts new file mode 100644 index 00000000..291c3669 --- /dev/null +++ b/src/locale/pt_PT.ts @@ -0,0 +1,2037 @@ + + + AboutDialog + + Lightweight WebKit-based web browser + Navegador web leve baseado no WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Authors + Autores + + + License + Licença + + + Close + Fechar + + + About %1 + Acerca do %1 + + + WebKit version: %1 + Versão do WebKit: %1 + + + + AcceptLanguage + + Languages + Linguagens + + + Languages: in order of preference: + Linguagens: em ordem de preferência: + + + Move &Up + Mover Para &Cima + + + Move &Down + Mover Para &Baixo + + + &Remove + &Remover + + + Add... + Adicionar... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Bloqueado por AdBlockRule: %1 + + + + AdBlockDialog + + AdBlock Configuration + Configuração do AdBlock + + + Enable AdBlock + Activar o AdBlock + + + Action + Acção + + + Add Custom Rule + Adicionar Regra Personalizada + + + Learn more about writing rules... + Saiba mais acerca de como escrever regras... + + + Update Subscription + Actualizar Subscrição + + + Browse Subscriptions... + Navegar nas Subscrições... + + + Remove Subscription + Remover Subscrição + + + + AdBlockManager + + Custom Rules + Regras Personalizadas + + + + AdBlockModel + + Rule + Regra + + + + AdBlockSchemeAccessHandler + + Subscribe? + Subscrever? + + + Subscribe to this AdBlock subscription? +%1 + Subscrever a esta subscrição do AdBlock? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Adicionar Favorito + + + Type a name for the bookmark, and choose where to keep it. + Escreva um nome para o favorito, e escolha onde guardá-lo. + + + Url + Url + + + Title + Título + + + Add Folder + Adicionar Pasta + + + + AutoFillDialog + + Form Passwords + Palavras-passe de Formulários + + + Remove + Remover + + + Remove All + Remover Todas + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Deseja guardar esta palavra-passe?</b><br>(sp)(sp)(sp)(sp)(sp)(sp)(sp)(sp)(sp)Para rever as palavras-passe que guardou e removê-las, abra o painel de Preenchimento Automático das preferências. + + + Never for this site + Nunca para este site + + + Not now + Agora não + + + + AutoFillModel + + WebSite + WebSite + + + User Name + Nome de Utilizador + + + + BookmarksDialog + + Bookmarks + Favoritos + + + &Remove + &Remover + + + Add Folder + Adicionar Pasta + + + Open + Abrir + + + Open in New Tab + Abrir em Novo Separador + + + Edit Name + Editar Nome + + + Edit Address + Editar Endereço + + + Delete + Apagar + + + New Folder + Nova Pasta + + + + BookmarksManager + + Bookmarks Bar + Barra de Favoritos + + + Bookmarks Menu + Menu de Favoritos + + + Error when loading bookmarks on line %1, column %2: +%3 + Erro ao carregar favoritos na linha %1, coluna %2: +%3 + + + Toolbar Bookmarks + Barra de Ferramentas de Favoritos + + + Menu + Menu + + + XBEL bookmarks + Favoritos XBEL + + + HTML Netscape bookmarks + Favoritos HTML Netscape + + + Open File + Abrir Ficheiro + + + htmlToXBel tool required + Ferramenta htmlToXBel necessária + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + A ferramenta htmlToXBel, a qual é disponibilizada juntamente com o Arora e é necessária para importar favoritos HTML, não está instalada ou não está disponível nos caminhos de busca. + + + Loading Bookmark + A Carregar Favorito + + + Error when loading HTML bookmarks: %1 + + Erro ao carregar favoritos HTML: %1 + + + + Imported %1 + %1 Importado + + + Save File + Guardar Ficheiro + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Erro ao exportar + + + error saving bookmarks + erro ao guardar favoritos + + + Remove Bookmark + Remover Favorito + + + Insert Bookmark + Inserir Favorito + + + Name Change + Undo bookmark title change + Alteração do Nome + + + Address Change + Undo bookmark url change + Alteração do Endereço + + + + BookmarksMenu + + Open in Tabs + Abrir em Separadores + + + + BookmarksModel + + Title + Título + + + Address + Endereço + + + + BookmarksToolBar + + Open + Abrir + + + Open in New &Tab + Abrir num Novo &Separador + + + Remove + Remover + + + Add Bookmark... + Adicionar Favorito... + + + Add Folder... + Adicionar Pasta... + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Estão %1 janelas e %2 separadores abertos +Deseja sair mesmo assim? + + + Restore failed + Restauro falhado + + + Arora crashed while trying to restore this session. Should I try again? + O Arora crashou enquanto tentava restaurar esta sessão.(sp)(sp)Devo tentar de novo? + + + + BrowserMainWindow + + Hide Toolbar + Esconder Barra de Ferramentas + + + Show Toolbar + Mostar Barra de Ferramentas + + + Hide Bookmarks Bar + Esconder Barra de Favoritos + + + Show Bookmarks Bar + Mostrar Barra de Favoritos + + + Hide Status Bar + Esconder Barra de Estado + + + Show Status Bar + Mostrar Barra de Estado + + + Default + Predefinição + + + &File + &Ficheiro + + + &New Window + &Nova Janela + + + &Open File... + &Abrir Ficheiro... + + + Open &Location... + Abri &Localização... + + + &Save As... + &Guardar Como... + + + &Import Bookmarks... + &Importar Favoritos... + + + &Export Bookmarks... + &Exportar Favoritos... + + + P&rint Preview... + P&ré-visualizar Impressão... + + + &Print... + Im&primir... + + + Private &Browsing... + &Navegação Privada... + + + Close Window + Fechar Janela + + + &Quit + &Sair + + + &Edit + &Editar + + + &Undo + &Desfazer + + + &Redo + &Refazer + + + Cu&t + Cor&tar + + + &Copy + &Copiar + + + &Paste + C&olar + + + Select &All + Seleccion&ar Todos + + + &Find + &Procurar + + + Find Nex&t + Procurar Pró&ximo + + + Find P&revious + Procurar Ante&rior + + + &View + &Ver + + + Ctrl+| + Ctrl+| + + + Alt+Ctrl+B + Alt+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + Show Menu Bar + Mostrar a Barra do Menu + + + &Reload Page + &Recarregar a Página + + + &Stop + &Parar + + + Zoom &In + Zoom Aprox&imar + + + Zoom &Normal + Zoom &Normal + + + Zoom &Out + Z&oom Afastar + + + Zoom &Text Only + Zoom Apenas ao &Texto + + + Page S&ource + Códig&o Fonte da Página + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Éc&ran Completo + + + Text Encoding + Codificação do Texto + + + Hi&story + Hi&stórico + + + Back + Recuar + + + Forward + Avançar + + + Home + Página Inicial + + + Restore Last Session + Restaurar Última Sessão + + + &Bookmarks + &Favoritos + + + Show All Bookmarks... + Mostrar Todos os Favoritos... + + + Add Bookmark... + Adicionar Favorito... + + + Add Folder... + Adicionar Pasta... + + + &Window + &Janela + + + &Tools + Ferramen&tas + + + Web &Search + Pe&squisa na Web + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + Limpar &Dados Privados + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Activar o Web &Inspector + + + Options... + Opções... + + + Ctrl+, + Ctrl+, + + + Configure Search Engines... + Configurar Motores de Busca... + + + &Ad Block... + &Adicionar Bloqueio... + + + &Help + A&juda + + + Switch application language + Mudar a linguagem da aplicação(sp) + + + About &Qt + Acerca do &Qt + + + About &%1 + About Browser + Acerca do &%1 + + + Navigation + Navegação + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Abrir Recurso da Web + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Recursos da Web ((*.html *.htm *.svg *.png *.gif *.svgz);;Todos os ficheiros (*.*) + + + Print Document + Imprimir Documento + + + Are you sure you want to turn on private browsing? + Tem certeza que deseja activar a navegação privada? + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Quando a navegação privada está activa, algumas acções referentes à sua privacidade serão desactivadas: + + + Webpages are not added to the history. + Páginas Web não são adicionadas ao histórico. + + + Items are automatically removed from the Downloads window. + Items são removidos automaticamente da janela de Transferências. + + + New cookies are not stored, current cookies can't be accessed. + Novos cookies não são guardados, não se pode aceder aos cookies presentes. + + + Site icons won't be stored. + Icones do site não podem ser guardados. + + + Session won't be saved. + A sessão não será guardada. + + + Searches are not added to the pop-up menu in the search box. + Pesquisas não são guardadas no menu pop-up na caixa de pesquisas. + + + No new network cache is written to disk. + Nenhuma nova cache de rede é guardada no disco. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Até que feche a janela, você ainda pode clicar nos botões Recuar e Avançar para voltar às páginas web que abriu. + + + Private Browsing + Navegação Privada + + + Are you sure you want to close the window? There are %1 tabs open + Tem a certeza que deseja fechar a janela?(sp)(sp)Estão %1 separadores abertos + + + Web Inspector + Web Inspector + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + O web inspector apenas irá funcionar em páginas que foram carregadas após a sua activação. +Deseja recarregar todas as páginas? + + + Stop loading the current page + Parar o carregamento da página corrente + + + Reload the current page + Recarrega a página corrente + + + Downloads + Transferências + + + Ctrl+Y + Download Manager + Ctrl+Y + + + + ClearButton + + Clear + Limpar + + + + ClearPrivateData + + Clear Private Data + Limpar Dados Privados + + + Clear the following items: + Limpar os seguintes items: + + + &Browsing History + Histórico de &Navegação + + + &Download History + Histórico de &Transferências + + + &Search History + Histórico de &Pesquisas + + + &Cookies + &Cookies + + + C&ached Web Pages + Páginas Web em C&ache + + + Website &Icons + &Icones do Website + + + Clear &Private Data + Limpar &Dados Privados + + + &Cancel + &Cancelar + + + + ClickToFlash + + Load Flash + Carregar Flash + + + Load + Carregar + + + Load All + Carregar Todos + + + Add %1 to Whitelist + Adicionar %1 à Lista Branca + + + Remove from Whitelist + Remover da Lista Branca + + + Settings + Definições + + + + ClickToFlashSettings + + Whitelist sites + Sites da Lista Branca + + + + CookieExceptionsModel + + Website + Website + + + Rule + Regra + + + Allow + Permitir + + + Block + Bloquear + + + Allow For Session + Permitir Para a Sessão + + + + CookieModel + + Website + Website + + + Name + Nome + + + Path + Caminho + + + Secure + Seguro + + + Expires + Expira + + + Contents + Conteúdo + + + true + verdadeiro + + + false + falso + + + Session cookie + Cookie de sessão + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Remover + + + Remove &All Cookies + Remover &Todos os Cookies + + + Add &Rule + Adicionar &Regra + + + + CookiesExceptionsDialog + + Cookie Exceptions + Excepções de Cookies + + + New Exception + Nova Excepção + + + Domain: + Domínio: + + + Block + Bloqueio + + + Allow For Session + Permitir Para Sessão + + + Allow + Permitir + + + Exceptions + Excepções + + + &Remove + &Remover + + + Remove &All + Remover &Todos + + + + DownloadDialog + + Downloads + Transferências + + + Clean up + Limpar + + + 0 Items + 0 Items + + + + DownloadItem + + Ico + Ico + + + Filename + Nome do Ficheiro + + + Try Again + Tentar de Novo + + + Stop + Parar + + + Open + Abrir + + + Save File + Guardar Ficheiro + + + Download canceled: %1 + Transferência cancelada: %1 + + + Download directory (%1) couldn't be created. + Não foi possível criar o directório de transferência (%1). + + + Error opening output file: %1 + Erro ao abrir ficheiro de saída: %1 + + + Error saving: %1 + Erro ao guardar: %1 + + + Network Error: %1 + Erro de rede: %1 + + + %1 of %2 (%3/sec) - %4 + %1 de %2 (%3/segundo) - %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 de %2 - Parado + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + Estão %1 transferências em progresso +Deseja sair mesmo assim? + + + %n Download(s) + %n Transferência(s) + + + + %n minutes remaining + Faltam %n minutos + + + + %n seconds remaining + Faltam %n segundos + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Nenhum Erro + + + Error opening: %1: No such file or directory + Erro ao abrir: %1: Não existe tal ficheiro ou directório + + + Unable to read %1 + Incapaz de ler %1 + + + Contents of %1 + Conteúdo de %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + History + Histórico + + + &Remove + &Remover + + + Remove &All + Remover &Todos + + + Open + Abrir + + + Copy + Copiar + + + Delete + Apagar + + + + HistoryMenu + + Show All History + Mostrar Todo o Histórico + + + Clear History... + Limpar o Histórico... + + + Clear History + Limpar o Histórico + + + Do you want to clear the history? + Deseja limpar o histórico? + + + + HistoryModel + + Title + Título + + + Address + Endereço + + + + HistoryTreeModel + + Earlier Today + Hoje Cedo + + + %n item(s) + %n item(s) + + + + + JavaScriptAroraObject + + Welcome to Arora! + Bem vindo ao Arora! + + + Arora Start + Inicio do Arora + + + Search! + Pesquisa! + + + Search results provided by + Resultados de pesquisa disponibilizados por + + + About Arora + Acerca do Arora + + + + LanguageManager + + No translation files are installed at %1. + Nenhum ficheiro de tradução está instalado em %1. + + + Choose language + Escolher linguagem + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Você pode usar uma linguagem diferente daquela<br>predefinida pelo sistema operativo.</p><p>Por favor escolha a linguagem que deve ser usada</p> + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Indique o nome de utilizador e palavra-passe para "%1" em %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Ligar ao proxy "%1" usando:</qt> + + + Issuer: %1 + Emissor: %1 + + + Not valid before: %1 + Não válido antes de: %1 + + + Valid until: %1 + Válido até: %1 + + + Alternate Names: + Nomes Alternativos: + + + - SSL Errors + (sp)- Erros do SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Erros do SSL:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Deseja ignorar estes erros?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Certificados:<br/>%1<br/>Deseja aceitar todos estes certificados?</qt> + + + + OpenSearchDialog + + OpenSearch Manager + Gestor do OpenSearch + + + &Add + &Adicionar + + + &Delete + A&pagar + + + &Restore Defaults + &Restaurar Predefinições + + + &Close + &Fechar + + + Open File + Abrir Ficheiro + + + OpenSearch + OpenSearch + + + Error + Erro + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 não é uma descrição OpenSearch 1.1 válida ou já está na sua lista. + + + You must have at least one search engine in here. + Você precisa de ter aqui pelo menos um motor de busca. + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Descrição:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Disponibiliza sugestões contextuais</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Lista de palavras chave separadas por vírgulas que pode ser inserida na barra seguida por termos de pesquisa para pesquisar com este motor + + + Name + Nome + + + Keywords + Palavras Chave + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Deseja adicionar o seguinte motor à sua lista de motores de busca?<br /><br />Nome: %1<br />Pesquisa em: %2 + + + + PasswordDialog + + Authentication Required + Autenticação Necessária + + + DUMMY ICON + ÍCONE FICTÍCIO + + + INTRO TEXT DUMMY + ENTRADA DE TEXTO FICTÍCIA + + + Username: + Nome de utilizador: + + + Password: + Palavra-passe: + + + + PlainTextEditSearch + + Not Found + Não Encontrado + + + + ProxyDialog + + Proxy Authentication + Autenticação do Proxy + + + Connect to proxy + Ligar ao proxy + + + Username: + Nome de utilizador: + + + Password: + Palavra-passe: + + + + QObject + + The file is not an XBEL version 1.0 file. + O ficheiro não é um ficheiro XBEL versão 1.0. + + + Unknown title + Título desconhecido + + + The file is not an OpenSearch 1.1 file. + O ficheiro não é um ficheiro OpenSearch 1.1. + + + + SearchBanner + + Highlight All + Realçar Todos + + + Done + Feito + + + + SearchLineEdit + + Search + Pesquisar + + + + Settings + + Preferences + Preferências + + + General + Geral + + + On startup: + Ao iniciar: + + + Show my home page + Mostrar a minha página pessoal + + + Show a blank page + Mostrar uma página em branco + + + Restore windows and tabs from last time + Restaurar as janelas e separadores da última vez + + + Home Page: + Página Pessoal: + + + Set to current page + Definir para a página corrente + + + Remove history items: + Remover items do histórico: + + + After one day + Após um dia + + + After one week + Após uma semana + + + After two weeks + Após duas semanas + + + After one month + Após um mês + + + After one year + Após um ano + + + Manually + Manualmente + + + On application exit + Ao terminar a aplicação + + + Use the default search engine as fallback when the URL given by the user is invalid + Utilizar o motor de busca predefinido em caso do URL dado pelo utilizador ser inválido + + + Downloads + Transferências + + + Ask for a destination each time + Perguntar sempre por um destino + + + Use this destination: + Usar este destino: + + + Choose Directory... + Escolher Directório... + + + Appearance + Aparência + + + Standard font: + Tipo de letra standard: + + + Select... + Seleccionar... + + + Fixed-width font: + Tipo de letra de largura fixa: + + + Preferred languages for viewing webpages in: + Linguagens preferidas para visualizar páginas web em: + + + Privacy + Privacidade + + + Web Content + Conteúdo da Web + + + Block Popup Windows + Bloquear Janelas Popup + + + Enable Plugins + Activar Plugins + + + Use ClickToFlash on flash plugins + Usar o botão 'Carregar Flash' em plugins flash + + + Enable Javascript + Activar Javascript + + + View Images + Ver Imagens + + + Cookies + Cookies + + + Accept Cookies: + Aceitar Cookies: + + + Always + Sempre + + + Never + Nunca + + + Only from sites you navigate to + Apenas os originários dos sites que você visita + + + Exceptions... + Excepções... + + + Keep Cookies Until: + Manter os Cookies Até: + + + They expire + Que expirem + + + I exit the application + Eu termine a aplicação + + + At most 90 days + Durante 90 dias + + + Cookies... + Cookies... + + + Filter Tracking Cookies + Filtrar Cookies de Rastreio + + + A cookie session ends: + Uma sessão de cookie termina: + + + When I exit the application + Quando eu terminar a aplicação + + + 1 day + Em 1 dia + + + 2 days + Em 2 dias + + + 3 days + Em 3 dias + + + 7 days + Em 7 dias + + + 30 days + Em 30 dias + + + Tabs + Separadores + + + Select tabs and windows as they are created + Seleccionar separadores e janelas assim que são criadas + + + Confirm when closing multiple tabs or windows + Confirmar quando se fecha múltiplos separadores ou janelas + + + Show only one close button instead of one for each tab + Mostrar apenas um botão de fechar em vez de um para cada separador + + + Quit the application when last tab is closed + Terminar a aplicação quando o último separador é fechado + + + Opening links + Abertura de ligações + + + Links that want to open in a new window: + Ligações que querem abrir numa janela nova: + + + In a new window + Numa janela nova + + + In a new selected tab in the current window + Num novo separador seleccionado na janela corrente + + + In a new tab in the current window + Num novo separador na janela corrente + + + In the current tab + No separador corrente + + + Open links from applications: + Abrir ligações a partir de aplicações: + + + Proxy + Proxy + + + Use proxy server + Usar servidor proxy + + + Type: + Tipo: + + + Socks5 + Socks5 + + + Http (Secure) + Http (Seguro) + + + Http (Transparent) + Http (Transparente) + + + Host name: + Nome de máquina: + + + Port: + Porto: + + + User Name: + Nome de Utilizador: + + + Password: + Palavra-passe: + + + AutoFill + Preenchimento Automático + + + AutoFill web forms: + Preenchimento Automático de formulários web: + + + User names and passwords + Nomes de utilizadores e palavras-passe + + + Edit... + Editar... + + + Advanced + Avançado + + + Style Sheet: + Estilo de Folha: + + + Browse... + Navegação... + + + Enable network cache + Activar cache de rede + + + Maximum Size: + Tamanho Máximo: + + + MB + (sp)MB + + + + SettingsDialog + + Restart required + É necessário reiniciar + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + A configuração da cache de rede foi alterada. Para que a alteração funcione, o navegador tem que ser reiniciado. + + + Choose Directory + Escolher o Directório + + + Choose CSS File + Escolher o Ficheiro CSS + + + + SourceViewer + + Loading... + A carregar... + + + &Edit + &Editar + + + &Find + &Procurar + + + Source of Page %1 + Código da Página %1 + + + + TabBar + + Show Tab Bar + Mostrar a Barra de Separadores + + + Hide Tab Bar + Esconder a Barra de Separadores + + + Duplicate Tab + Duplicar Separador + + + &Close Tab + &Fechar Separador + + + Close &Other Tabs + Fechar os &Outros Separadores + + + Reload Tab + Recarregar Separador + + + Reload All Tabs + Recarregar Todos os Separadores + + + + TabWidget + + Untitled + Sem Título + + + Saved Tabs + Separadores Guardados + + + Do you really want to close this page? + Deseja mesmo fechar esta página? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Você modificou esta página e ao fechá-la você irá perder as modificações. +Deseja mesmo fechar esta página? + + + Loading... + Carregando... + + + Loading %1% (%2 %3)... + Carregando %1% (%2 %3)... + + + Finished loading + Carga completa + + + Failed to load + Falha ao carregar + + + Show Next Tab + Mostrar o Próximo Separador + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + Mostrar o Separador Anterior + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + Separadores Fechados Recentemente + + + New &Tab + Novo &Separador + + + &Close Tab + &Fechar Separador + + + Bookmark All Tabs + Colocar Todos os Separadores nos Favoritos + + + + ToolbarSearch + + Suggestions + Sugestões + + + Add '%1' + Adicionar '%1' + + + Clear Recent Searches + Limpar Pesquisas Recentes + + + No Recent Searches + Não Há Pesquisas Recentes + + + Recent Searches + Pesquisas Recentes + + + + WebPage + + Resending POST request + A enviar de novo o pedido POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + De modo a mostrar o site, o pedido junto com todos os dados deve ser enviado mais uma vez, o que pode levar a algum comportamento inesperado, por exemplo, a mesma acção pode ser executada mais uma vez. Deseja continuar mesmo assim? + + + Error loading page: %1 + Erro ao carregar página: %1 + + + When connecting to: %1. + Ao efectuar ligação a: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Verifique o endereço por erros como <b>ww</b>.arora-browser.org em vez de <b>www</b>.arora-browser.org + + + If the address is correct, try checking the network connection. + Se o endereço está correcto, tente verificar a ligação à rede. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Se o seu computador ou rede estão protegidos por uma firewall ou proxy, certifique-se que o navegador tem permissão de aceder à rede. + + + + WebView + + Open in New &Window + Abrir numa &Janela Nova + + + Open in New &Tab + Abrir num &Separador Novo + + + Save Lin&k + Guardar Li&gação + + + &Bookmark This Link + Colocar Esta &Ligação nos Favoritos + + + &Copy Link Location + &Copiar Localização da Ligação + + + Open Image in New &Window + Abrir Imagem numa &Janela Nova + + + Open Image in New &Tab + Abrir Imagem num &Separador Novo + + + &Save Image + &Guardar Imagem + + + &Copy Image + &Copiar Imagem + + + C&opy Image Location + C&opiar a Localização da Imagem + + + Block Image + Bloquear Imagem + + + Search with... + Pesquisar com... + + + Add to the toolbar search + Adicionar à barra de ferramentas da pesquisa + + + Method not supported + Método não suportado + + + %1 method is not supported. + método %1 não é suportado. + + + Search engine + Motor de Busca + + + Choose the desired search engine + Escolher o motor de busca desejado + + + Engine name + Nome do motor + + + Type in a name for the engine + Escreva um nome para o motor + + + Loading... + A carregar... + + + + WebViewSearch + + Not Found + Não Encontrado + + + diff --git a/src/locale/ru.ts b/src/locale/ru.ts deleted file mode 100644 index cc9f62b3..00000000 --- a/src/locale/ru.ts +++ /dev/null @@ -1,1275 +0,0 @@ - - - - - @default - - Error - Ошибка - - - Arora is already running. Exiting. - Arora уже запущена. Выходим. - - - - AboutDialog - - About - О программе - - - - AddBookmarkDialog - - Add Bookmark - Добавить закладку - - - Type a name for the bookmark, and choose where to keep it. - Введите имя для закладки и выберите, где сохранить её. - - - - BookmarksDialog - - Open - Открыть - - - Delete - Удалить - - - New Folder - Новая папка - - - Bookmarks - Закладки - - - &Remove - &Удалить - - - Add Folder - Добавить папку - - - Open in New Tab - Открыть в новой вкладке - - - - BookmarksManager - - Error when loading bookmarks on line %1, column %2: -%3 - Ошибка при загрузке закладок на строке %1, столбце %2: -%3 - - - Toolbar Bookmarks - Закладки панели инструментов - - - Menu - Меню - - - Open File - Открыть файл - - - XBEL (*.xbel *.xml) - XBEL (*.xbel *.xml) - - - Imported %1 - Импортировано %1 - - - Save File - Сохранить файл - - - %1 Bookmarks.xbel - %1 Bookmarks.xbel - - - Export error - Ошибка экспорта - - - error saving bookmarks - ошибка сохранения закладок - - - Remove Bookmark - Удалить закладку - - - Insert Bookmark - Добавить закладку - - - Name Change - Изменение имени - - - Address Change - Изменение адреса - - - - BookmarksModel - - Title - Название - - - Address - Адрес - - - - BookmarksToolBar - - Bookmark - Закладка - - - - BrowserApplication - - There are %1 windows and %2 tabs open -Do you want to quit anyway? - Открыто %1 окон и %2 вкладок -Вы всё равно хотите выйти? - - - - BrowserMainWindow - - &File - &Файл - - - &New Window - &Новое окно - - - &Open File... - &Открыть файл... - - - Open &Location... - Открыть &адрес... - - - &Save As... - &Сохранить как... - - - &Import Bookmarks... - &Импортировать закладки... - - - &Export Bookmarks... - &Экспортировать закладки... - - - P&rint Preview... - &Предпросмотр... - - - &Print... - Пе&чать... - - - Private &Browsing... - Режим &конфиденциальности... - - - &Quit - В&ыход... - - - &Edit - &Правка - - - &Undo - &Отменить - - - &Redo - &Повторить - - - Cu&t - &Вырезать - - - &Copy - &Копировать - - - &Paste - В&ставить - - - &Find - &Найти - - - &Find Next - Найти &далее - - - &Find Previous - Найти пред&ыдущее - - - &Preferences - &Параметры - - - Ctrl+, - Ctrl+, - - - &View - &Вид - - - Shift+Ctrl+B - Shift+Ctrl+B - - - Ctrl+| - Ctrl+| - - - Ctrl+/ - Ctrl+/ - - - &Stop - &Остановить - - - Reload Page - Обновить страницу - - - &Make Text Bigger - У&величить - - - &Make Text Normal - &Исходный размер - - - &Make Text Smaller - У&меньшить - - - Page S&ource - Исходный &код страницы - - - Ctrl+Alt+U - Ctrl+Alt+U - - - &Full Screen - Во весь &экран - - - Hi&story - &Журнал - - - Back - Назад - - - Forward - Вперёд - - - Home - Домашняя страница - - - Restore Last Session - Восстанавливать предыдущий сеанс - - - &Bookmarks - &Закладки - - - Manage Bookmarks... - Управление закладками... - - - Add Bookmark... - Добавить закладку... - - - &Window - &Окно - - - &Tools - &Инструменты - - - Web &Search - &Поиск в Интернете - - - Ctrl+K - Web Search - Ctrl+K - - - Enable Web &Inspector - Включить Web &Inspector - - - &Help - &Справка - - - About &Qt - О &Qt - - - About &Arora - О программе &Arora - - - Navigation - навигация - - - Show Status Bar - Показать строку состояния - - - Hide Status Bar - Скрыть строку состояния - - - Show Toolbar - Показать панель инструментов - - - Hide Toolbar - Скрыть панель инструментов - - - Show Bookmarks bar - Показать панель закладок - - - Hide Bookmarks bar - Скрыть панель закладок - - - Arora - Arora - - - %1 - Arora - Page title and Browser name - %1 - Arora - - - About - О программе - - - Open Web Resource - Открыть веб-ресурс - - - Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) - Веб-ресурсы (*.html *.htm *.svg *.png *.gif *.svgz);;Все файлы (*.*) - - - Print Document - Печать документа - - - Are you sure you want to turn on private browsing? - Вы уверены, что хотите включить режим конфиденциальности? - - - <b>%1</b><br><br>When private browsing in turned on, webpages are not added to the history, items are automatically removed from the Downloads window, new cookies are not stored, current cookies can't be accessed, site icons wont be stored, session wont be saved, and searches are not addded to the pop-up menu in the Google search box. Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. - <b>%1</b><br><br>В режиме конфиденциальности посещённые веб-страницы не добавляются в журнал, файлы автоматически удаляются из окна загрузок, новые cookies are не сохраняются, текущие cookies недоступны, значки сайтов и сеансы не сохраняются, и поисковые запросы не добавляются в поле поиска Google. Пока вы не закроете окно, вы всё ещё можете нажимать кнопки Назад и Вперёд для возврата к уже посещённым страницам. - - - Are you sure you want to close the window? There are %1 tab open - Вы уверены, что хотите закрыть окно? Открыты %1 вкладок - - - Page Source of %1 - Исходный код страницы %1 - - - Web Inspector - Web Inspector - - - The web inspector will only work correctly for pages that were loaded after enabling. -Do you want to reload all pages? - Web Inspector будет правильно работать только для страниц, добавленных после его включения. -Желаете ли вы обновить все страницы? - - - Stop loading the current page - Остановить загрузку текущей страницы - - - Reload the current page - Перезагрузить текущую страницу - - - Downloads - Загрузки - - - Alt+Ctrl+L - Download Manager - Alt+Ctrl+L - - - <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttonsto return to the webpages you have opened. - <b>%1</b><br><br>В режиме конфиденциальности отключаются некоторые действия, связанные с вашей анонимностью:<ul><li> Веб-страницы не добавляются в журнал.</li><li> Файлы автоматически удаляются из окна загрузок.</li><li> Новые cookies не сохраняются, текущие cookies недоступны.</li><li> Значки сайтов и сеансы не сохраняются.</li><li> Поисковые запросы не добавляются в поле поиска.</li></ul> Пока вы не закроете окно, вы всё ещё можете нажимать кнопки Назад и Вперёд для возврата к уже посещённым страницам. - - - &Clear Private Data - &Очистить личные данные - - - Ctrl+Shift+Delete - Clear Private Data - Ctrl+Shift+Delete - - - - ClearButton - - Clear - Очистить - - - - ClearPrivateData - - Clear Private Data - Очистить личные данные - - - Clear the following items: - Очистить следующие элементы: - - - &Browsing History - Журнал &посещений - - - &Download History - Журнал &загрузок - - - &Search History - Историю &поиска - - - &Cookies - &Cookies - - - C&ache - &Кэш - - - Website &Icons - З&начки веб-сайтов - - - Clear &Private Data - Очистить &личные данные - - - &Cancel - &Отмена - - - - CookieExceptionsModel - - Website - Веб-сайт - - - Status - Статус - - - Allow - Разрешить - - - Block - Блокировать - - - Allow For Session - Разрешить на время сеанса - - - - CookieModel - - Website - Веб-сайт - - - Name - Имя - - - Path - Путь - - - Secure - Безопасность - - - Expires - Истекает - - - Contents - Содержимое - - - - CookiesDialog - - Cookies - Cookies - - - &Remove - &Удалить - - - Remove &All Cookies - Удалить &все cookies - - - - CookiesExceptionsDialog - - Cookie Exceptions - Исключения cookies - - - New Exception - Новое исключение - - - Domain: - Домен - - - Block - Блокировать - - - Allow For Session - Разрешить на время сеанса - - - Allow - Разрешить - - - Exceptions - Исключения - - - &Remove - &Удалить - - - Remove &All - Удалить &все - - - - DownloadDialog - - Downloads - Загрузки - - - Clean up - Очистить - - - 0 Items - 0 элементов - - - - DownloadItem - - Save File - Сохранить файл - - - Download canceled: %1 - Загрузка отменена: %1 - - - Error opening save file: %1 - Ошибка при открытии сохранённого файла: %1 - - - Error saving: %1 - Ошибка при сохранении: %1 - - - Network Error: %1 - Ошибка сети: %1 - - - seconds - секунд - - - minutes - минут - - - - %4 %5 remaining - - %4 %5 осталось - - - %1 of %2 (%3/sec) %4 - %1 из %2 (%3/сек) %4 - - - ? - ? - - - %1 of %2 - Stopped - %1 of %2 - Остановлено - - - bytes - байт - - - kB - кБ - - - MB - МБ - - - Form - Форма - - - Ico - Ico - - - Filename - Имя файла - - - Try Again - Повторить попытку - - - Stop - Остановить - - - Open - Открыть - - - - DownloadManager - - 1 Download - 1 загрузка - - - %1 Downloads - %1 загрузок - - - - HistoryDialog - - Open - Открыть - - - Copy - Копировать - - - Delete - Удалить - - - History - Журнал - - - &Remove - &Удалить - - - Remove &All - Удалить &все - - - - HistoryMenu - - Show All History - Показать весь журнал - - - Clear History - Очистить журнал - - - - HistoryModel - - Title - Название - - - Address - Адрес - - - - HistoryTreeModel - - Earlier Today - Ранее сегодня - - - %1 items - %1 элементов - - - - NetworkAccessManager - - <qt>Enter username and password for "%1" at %2</qt> - <qt>Введите имя пользователя и пароль для "%1" на %2</qt> - - - <qt>Connect to proxy "%1" using:</qt> - <qt>Подключиться к прокси "%1", используя:</qt> - - - SSL Errors: - -%1 - -%2 - -Do you want to ignore these errors? - Ошибки SSL: - -%1 - -%2 - -Желаете ли вы игнорировать эти ошибки? - - - Do you want to accept all these certificates? - Вы желаете принять все эти сертификаты? - - - - PasswordDialog - - Authentication Required - Требуется аутентификация - - - DUMMY ICON - DUMMY ICON - - - INTRO TEXT DUMMY - INTRO TEXT DUMMY - - - Username: - Имя пользователя: - - - Password: - Пароль: - - - - ProxyDialog - - Proxy Authentication - Аутентификация прокси - - - ICON - ICON - - - Connect to proxy - Подключиться к прокси - - - Username: - Имя пользователя: - - - Password: - Пароль: - - - - QObject - - The file is not an XBEL version 1.0 file. - Файл не является файлом XBEL версии 1.0. - - - Unknown title - Неизвестный заголовок - - - - SearchBanner - - Form - Form - - - TextLabel - TextLabel - - - < - < - - - > - > - - - Done - Готово - - - - SearchLineEdit - - Search - Поиск - - - - Settings - - Settings - Параметры - - - General - Общие - - - Home: - Домашняя страница: - - - Set to current page - Использовать текущую страницу - - - Remove history items: - Удалять элементы журнала: - - - After one day - Через день - - - After one week - Через неделю - - - After two weeks - Через две недели - - - After one month - Через месяц - - - After one year - Через год - - - Manually - Вручную - - - Save downloads to: - Сохранять загрузки в: - - - Open links from applications: - Открывать ссылки из приложений: - - - In a tab in the current window - Во вкладке в текущем окне - - - In a new window - В новом окне - - - Appearance - Внешний вид - - - Standard font: - Стандартный шрифт: - - - Times 16 - Times 16 - - - Select... - Выбрать... - - - Fixed-width font: - Моноширинный шрифт: - - - Courier 13 - Courier 13 - - - Privacy - Конфиденциальность - - - Web Content - Веб-содержимое - - - Enable Plugins - Включить подключаемые модули - - - Enable Javascript - Включить JavaScript - - - Cookies - Cookies - - - Accept Cookies: - Принимать cookies: - - - Always - Всегда - - - Never - Никогда - - - Only from sites you navigate to - Только с посещённых сайтов - - - Exceptions... - Исключения... - - - Keep until: - Сохранять до: - - - They expire - Истечения срока - - - I exit the application - Выхода из приложения - - - At most 90 days - Максимум 90 дней - - - Cookies... - Cookies... - - - Proxy - Прокси - - - Enable proxy - Включить прокси - - - Type: - Тип: - - - Socks5 - Socks5 - - - Http - Http - - - Host: - Сервер: - - - Port: - Порт: - - - User Name: - Имя пользователя: - - - Password: - Пароль: - - - Advanced - Дополнительно - - - Style Sheet: - Таблица стилей: - - - Sans-serif font: - Шрифт без засечек: - - - Serif font: - Шрифт с засечками: - - - Size: - Размер: - - - Default font: - Шрифт по умолчанию: - - - Sans serif - Без засечек - - - Serif - С засечками - - - Downloads - Загрузки - - - Ask for a destination each time - Каждый раз спрашивать папку назначения - - - Use this destination: - Использовать эту папку назначения: - - - - TabBar - - New &Tab - Новая &вкладка - - - Duplicate Tab - Копировать вкладку - - - &Close Tab - &Закрыть вкладку - - - Close &Other Tabs - Закрыть &другие вкладки - - - Reload Tab - Обновить вкладку - - - Reload All Tabs - Обновить все вкладки - - - - TabWidget - - New &Tab - Новая &вкладка - - - &Close Tab - &Закрыть вкладку - - - Show Next Tab - Показать следующую вкладку - - - Show Previous Tab - Показать предыдущую вкладку - - - Recently Closed Tabs - Недавно закрытые вкладки - - - (Untitled) - (Безымянный) - - - Do you really want to close this page? - Вы действительно хотите закрыть эту страницу? - - - You have modified this page and when closing it you would lose the modification. -Do you really want to close this page? - - Вы изменили эту страницу, и вы потеряете изменения при её закрытии. -Вы действительно хотите закрыть эту страницу? - - - - - ToolbarSearch - - Google - Google - - - No Recent Searches - Нет последних слов для поиска - - - Recent Searches - Последние слова для поиска - - - Clear Recent Searches - Очистить последние слова для поиска - - - - WebPage - - Error loading page: %1 - Ошибка при загрузке страницы: %1 - - - - WebView - - Open in New &Window - Открыть в новом &окне - - - Open in New &Tab - Открыть в новой &вкладке - - - Save Lin&k - Сохранить &ссылку - - - &Bookmark This Link - Добавить ссылку в &закладки - - - &Copy Link Location - &Копировать адрес ссылки - - - Open Image in New &Window - Открыть изображение в новом &окне - - - Open Image in New &Tab - Открыть изображение в новой &вкладке - - - &Save Image - &Сохранить изображение - - - &Copy Image - &Копировать изображение - - - C&opy Image Location - Копировать &адрес изображения - - - - WebViewSearch - - Not Found - Не найдено - - - diff --git a/src/locale/ru_RU.ts b/src/locale/ru_RU.ts new file mode 100644 index 00000000..65335c23 --- /dev/null +++ b/src/locale/ru_RU.ts @@ -0,0 +1,2405 @@ + + + + + AboutDialog + + About + О программе + + + Authors + Авторы + + + License + Лицензия + + + Lightweight WebKit-based web browser + Легкий браузер на WebKit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Закрыть + + + About %1 + О %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Права принадлежат © 2007-2009 Бенжамину С. Мейеру &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + Версия WebKit: %1 + + + + AcceptLanguage + + Languages + Языки + + + Languages: in order of preference: + Языки: в порядке предпочтения: + + + Move &Up + &Вверх + + + Move &Down + &Вниз + + + &Remove + &Удалить + + + Add... + Добавить... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + Собственные правила + + + + AdBlockModel + + Rule + Правило + + + + AdBlockSchemeAccessHandler + + Subscribe? + Подписаться? + + + Subscribe to this AdBlock subscription? +%1 + Согласиться на подписку AdBlock? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Добавить закладку + + + Type a name for the bookmark, and choose where to keep it. + Введите имя для закладки и выберите, где сохранить её. + + + Url + Адрес + + + Title + Название + + + Add Folder + Добавить папку + + + + AutoFillDialog + + Form Passwords + + + + Remove + Удалить + + + Remove All + Удалить всё + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Сохранить пароль?</b><br> Чтобы увидеть сохранённые пароли и удалить их, откройте панель Автозаполнение в опциях. + + + Never for this site + Никогда для этого сайта + + + Not now + Не сейчас + + + + AutoFillModel + + WebSite + Веб-сайт + + + User Name + Имя пользователя + + + + BookmarksDialog + + Open + Открыть + + + Delete + Удалить + + + New Folder + Новая папка + + + Bookmarks + Закладки + + + &Remove + &Удалить + + + Add Folder + Добавить папку + + + Open in New Tab + Открыть в новой вкладке + + + Edit Name + Изменить имя + + + Edit Address + Изменить адрес + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Ошибка при загрузке закладок на строке %1, столбце %2: +%3 + + + Toolbar Bookmarks + Закладки панели инструментов + + + Menu + Меню + + + Open File + Открыть файл + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Импортировано %1 + + + Save File + Сохранить файл + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Ошибка экспорта + + + error saving bookmarks + ошибка сохранения закладок + + + Remove Bookmark + Удалить закладку + + + Insert Bookmark + Вставить закладку + + + Name Change + Изменение имени + + + Address Change + Изменение адреса + + + Bookmarks Bar + Панель закладок + + + Bookmarks Menu + Меню закладок + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Ошибка при загрузке HTML закладки: %1 + + + XBEL + XBEL + + + Name Change + Undo bookmark title change + Отменить изменение имени + + + Address Change + Undo bookmark url change + Изменение адреса + + + XBEL bookmarks + Закладки XBEL + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + Требуется функция htmlToXBel + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Функция htmlToXBel, которая включена в Arora и нужна для импорта закладок на HTML, не установлена или не доступна в путях поиска. + + + Loading Bookmark + Загрузка закладки + + + Error when loading HTML bookmarks: %1 + + Ошибка при загрузке HTML закладок: %1 + + + + + BookmarksMenu + + Open in Tabs + Открыть во вкладках + + + + BookmarksModel + + Title + Название + + + Address + Адрес + + + + BookmarksToolBar + + Bookmark + Закладка + + + Open + Открыть + + + Open in New &Tab + Открыть в новой &вкладке + + + Remove + Удалить + + + Add Bookmark... + Добавить закладку... + + + Add Folder... + Добавить папку... + + + Bookmarks + Закладки + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Открыто %1 окон и %2 вкладок +Всё равно выйти? + + + Restore failed + Восстановление не удалось + + + The saved session will not being restored because last time it was restored Arora crashed. + Сохраненная сессия не будет восстановлена потому что во время последнего восстановления Arora упал. + + + (Change: %1 %2) + (Change: %1 %2) + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Сохранённая сессия не будет восстановлена, так как Arora упала при попытке восстановления этой сессии. + + + Arora crashed while trying to restore this session. Should I try again? + Произошла ошибка при восстановлении сеанса. Попытаться снова? + + + + BrowserMainWindow + + &File + &Файл + + + &New Window + &Новое окно + + + &Open File... + &Открыть файл... + + + Open &Location... + Открыть &адрес... + + + &Save As... + &Сохранить как... + + + &Import Bookmarks... + &Импортировать закладки... + + + &Export Bookmarks... + &Экспортировать закладки... + + + P&rint Preview... + &Предпросмотр... + + + &Print... + Пе&чать... + + + Private &Browsing... + Режим &конфиденциальности... + + + &Quit + В&ыйти + + + &Edit + &Правка + + + &Undo + &Отменить + + + &Redo + &Повторить + + + Cu&t + &Вырезать + + + &Copy + &Копировать + + + &Paste + В&ставить + + + &Find + &Найти + + + Ctrl+, + Ctrl+, + + + &View + &Вид + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Остановить + + + Page S&ource + Исходный &код страницы + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Во весь &экран + + + Hi&story + &Журнал + + + Back + Назад + + + Forward + Вперёд + + + Home + Домашняя страница + + + Restore Last Session + Восстановить предыдущий сеанс + + + &Bookmarks + &Закладки + + + Manage Bookmarks... + Управление закладками... + + + Add Bookmark... + Добавить закладку... + + + &Window + &Окно + + + &Tools + &Инструменты + + + Web &Search + &Поиск в Интернете + + + Ctrl+K + Web Search + Поиск в Интернете + Ctrl+K + + + Enable Web &Inspector + Включить Web &Inspector + + + &Help + &Справка + + + About &Qt + О &Qt + + + About &Arora + О программе &Arora + + + Navigation + Навигация + + + Show Status Bar + Показать строку состояния + + + Hide Status Bar + Скрыть строку состояния + + + Show Toolbar + Показать панель инструментов + + + Hide Toolbar + Скрыть панель инструментов + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + Заголовок страницы и имя браузера + %1 - Arora + + + Open Web Resource + Открыть веб-ресурс + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Веб-ресурсы (*.html *.htm *.svg *.png *.gif *.svgz);;Все файлы (*.*) + + + Print Document + Печатать документ + + + Are you sure you want to turn on private browsing? + Включить режим конфиденциальности? + + + Are you sure you want to close the window? There are %1 tabs open + Закрыть окно? Открыто %1 вкладок + + + Page Source of %1 + Исходный код страницы %1 + + + Web Inspector + Web Inspector + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Web Inspector будет правильно работать только для страниц, открытых после его включения. +Обновить все страницы? + + + Stop loading the current page + Остановить загрузку текущей страницы + + + Reload the current page + Перезагрузить текущую страницу + + + Downloads + Загрузки + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + &Clear Private Data + &Очистить личные данные + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Find &Next + Найти &Следующее + + + Find P&revious + Найти &Предыдущее + + + Prefe&rences + &Настройки + + + &Reload Page + Об&новить + + + Make Text &Bigger + &Увеличенный Размер Текста + + + Make Text &Normal + &Нормальный Размер Текста + + + Make Text &Smaller + Маленький Размер Текста + + + Show Bookmarks Bar + Показать Панель Закладок + + + Hide Bookmarks Bar + Скрыть Панель Закладок + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Когда включен режим приватного браузинга, некоторые действия угрожающие безопасности будут недоступны:<ul><li> Вебстраницы не добавляются в журнал.</li><li> Записи автоматически удаляются из списка закачек.</li><li> Новые cookie не сораняются, старые cockie не доступны.</li><li> Иконки сайтов не сохраняются, сессии не сохраняются.</li><li> Поисковые запросы не добавляются во всплывающее окно при новом запросе.</li></ul>Пока вы не закроете окно вы не сможете воспользоваться кнопками Вперед и Назад для перехода на ранее открытые страницы. + + + Find Nex&t + Продолжить поис&к + + + Prefere&nces... + Настр&ойки... + + + Show Menu Bar + Показать меню + + + Show &Network Monitor + Показать &Сетевой монитор + + + Switch application language + Изменить язык приложения + + + Close Window + Закрыть окно + + + Zoom &In + &Увеличить + + + Zoom &Normal + Нормальный &размер + + + Zoom &Out + У&меньшить + + + Zoom &Text Only + Масштабировать только &текст + + + Show All Bookmarks... + Показать все закладки... + + + Add Folder... + Добавить папку... + + + About &%1 + About Browser + О &%1 + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Когда включен режим приватного браузинга, некоторые действия угрожающие безопасности будут недоступны:<ul><li> Вебстраницы не добавляются в журнал.</li><li> Записи автоматически удаляются из списка закачек.</li><li> Новые cookie не сораняются, старые cockie не доступны.</li><li> Иконки сайтов не сохраняются, сессии не сохраняются.</li><li> Поисковые запросы не добавляются во всплывающее окно при новом запросе.</li></ul>Пока вы не закроете окно вы не сможете воспользоваться кнопками Вперед и Назад для перехода на ранее открытые страницы. + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + По умолчанию + + + Text Encoding + Кодировка текста + + + Select &All + Выделить &всё + + + Alt+Ctrl+B + Alt+Ctrl+B + + + Options... + Опции... + + + Configure Search Engines... + Настроить поисковые системы... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Когда активирован конфиденциальный просмотр, некоторые действия, связанные с вашей секретностью, не будут выполняться: + + + Webpages are not added to the history. + Веб-страницы не будут добавляться в журнал. + + + Items are automatically removed from the Downloads window. + Элементы списка загрузок будут автоматически удалены из него. + + + New cookies are not stored, current cookies can't be accessed. + Новые cookies не будут храниться, текущие окажутся недоступными. + + + Site icons won't be stored. + Значки сайтов храниться не будут. + + + Session won't be saved. + Сеанс не будет сохранён. + + + Searches are not added to the pop-up menu in the search box. + Поисковые запросы не добавляются во всплывающее окно при новом запросе. + + + No new network cache is written to disk. + Новый сетевой кэш не будет записан на диск. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Пока вы не закрыли окно, вы не сможете воспользоваться кнопками Назад и Вперёд для возврата на открытые веб-страницы. + + + Private Browsing + Конфиденциальный просмотр + + + &Ad Block... + &Ad Block... + + + + ClearButton + + Clear + Очистить + + + + ClearPrivateData + + Clear Private Data + Очистить личные данные + + + Clear the following items: + Очистить следующее: + + + &Browsing History + Журнал &посещений + + + &Download History + Журнал &загрузок + + + &Search History + Историю &поиска + + + &Cookies + &Cookies + + + C&ache + &Кэш + + + Website &Icons + З&начки веб-сайтов + + + Clear &Private Data + Очистить &личные данные + + + &Cancel + &Отмена + + + C&ached Web Pages + Веб-страницы, сохранённые в &кэше + + + + ClickToFlash + + Load + Загрузить + + + Load All + Загрузить все + + + Add %1 to Whitelist + Добавить %1 в список разрешённых сайтов + + + Remove from Whitelist + Удалить из списка разрешённых сайтов + + + Settings + Параметры + + + Load Flash + Загрузить Flash + + + + ClickToFlashSettings + + Whitelist sites + Список разрешённых сайтов + + + + CookieExceptionsModel + + Website + Веб-сайт + + + Status + Статус + + + Allow + Разрешить + + + Block + Блокировать + + + Allow For Session + Разрешить на время сеанса + + + Rule + Правило + + + + CookieModel + + Website + Веб-сайт + + + Name + Имя + + + Path + Путь + + + Secure + Безопасность + + + Expires + Истекает + + + Contents + Содержимое + + + true + истина + + + false + ложь + + + Session cookie + Cookie сеанса + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Удалить + + + Remove &All Cookies + Удалить &все cookies + + + Add &Rule + Добавить &правило + + + + CookiesExceptionsDialog + + Cookie Exceptions + Исключения cookies + + + New Exception + Новое исключение + + + Domain: + Домен: + + + Block + Блокировать + + + Allow For Session + Разрешить на время сеанса + + + Allow + Разрешить + + + Exceptions + Исключения + + + &Remove + &Удалить + + + Remove &All + Удалить &все + + + + DownloadDialog + + Downloads + Загрузки + + + Clean up + Очистить + + + 0 Items + 0 элементов + + + &OK + &OK + + + + DownloadItem + + Save File + Сохранить файл + + + Download canceled: %1 + Загрузка отменена: %1 + + + Error opening save file: %1 + Ошибка при открытии сохранённого файла: %1 + + + Error saving: %1 + Ошибка при сохранении: %1 + + + Network Error: %1 + Ошибка сети: %1 + + + seconds + секунд + + + %1 of %2 (%3/sec) %4 + %1 из %2 (%3/сек) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 of %2 - Остановлено + + + bytes + байт + + + kB + кБ + + + MB + МБ + + + Form + Форма + + + Ico + Ico + + + Filename + Имя файла + + + Try Again + Повторить попытку + + + Stop + Остановить + + + Open + Открыть + + + - %n minutes remaining + + - %n минут осталось + + + + + + - %n seconds remaining + + - %n секунд осталось + + + + + + Error opening output file: %1 + Ошибка при открытии сохранённого файла: %1 + + + %1 of %2 (%3/sec) - %4 + %1 из %2 (%3/сек) - %4 + + + Download directory (%1) couldn't be created. + Директория загрузки (%1) не может быть создана. + + + + DownloadManager + + %n Download(s) + + %n Закачка + %n Закачки + %n Закачек + + + + There are %1 downloads in progress +Do you want to quit anyway? + %1 закачек ещё не окончено. +Всё равно выйти? + + + %n minutes remaining + + %n минута осталась + %n минуты осталось + %n минут осталось + + + + %n seconds remaining + + %n секунда осталась + %n секунды осталось + %n секунд осталось + + + + bytes + байт + + + kB + кБ + + + MB + МБ + + + GB + ГБ + + + + FileAccessReply + + No Error + Без ошибок + + + Error opening: %1: No such file or directory + Ошибка при открытии %1: нет такого файла или папки + + + Unable to read %1 + Невозможно прочесть %1 + + + Contents of %1 + Содержимое %1 + + + %1 KB + %1 КБ + + + + HistoryDialog + + Open + Открыть + + + Copy + Копировать + + + Delete + Удалить + + + History + Журнал + + + &Remove + &Удалить + + + Remove &All + Удалить &все + + + + HistoryMenu + + Show All History + Показать весь журнал + + + Clear History + Очистить журнал + + + Clear History... + Очистить журнал... + + + Do you want to clear the history? + Хотите очистить журнал? + + + + HistoryModel + + Title + Название + + + Address + Адрес + + + + HistoryTreeModel + + Earlier Today + Ранее сегодня + + + %n item(s) + + %n запись + %n записи + %n записей + + + + + JavaScriptAroraObject + + Welcome to Arora! + Добро пожаловать в Arora! + + + Arora Start + Запуск Arora + + + Search! + Искать! + + + Search results provided by + Результаты поика предоставлены + + + About Arora + О Arora + + + + LanguageManager + + Choose language + Выбрать язык + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Вы можеть использовать язык браузера, отличный<br>от языка операционной системы.</p><p>Выберить подходящий язык</p> + + + No translation files are installed. + Языковые файлы не установлены. + + + No translation files are installed at %1. + Языковые файлы не установлены. в %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Введите имя пользователя и пароль для "%1" на %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Подключиться к прокси "%1", используя:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Ошибки SSL: + +%1 + +%2 + +Желаете ли вы игнорировать эти ошибки? + + + Do you want to accept all these certificates? + Вы желаете принять все эти сертификаты? + + + - SSL Errors + - Ошибки SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Ошибки SSL:<br/><br/>для: <tt>%1</tt><ul><li>%2</li></ul> + +Игнорнировать эти ошибки?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Сертификаты:<br/>%1<br/>Принять эти сертификаты?</qt> + + + Issuer: %1 + Выдал: %1 + + + Not valid before: %1 + Не действует до: %1 + + + Valid until: %1 + Действует до: %1 + + + Alternate Names: + Другие имена: + + + + NetworkMonitor + + Name + Имя + + + Value + Значение + + + + NetworkMonitorDialog + + Network Monitor + Сетевой монитор + + + Network Requests + Сетевые запросы + + + Request Headers + Заголовки запроса + + + Response Headers + Заголовки ответа + + + &Remove + &Удалить + + + Remove &All Requests + Удалите &все запросы + + + + OpenSearchDialog + + Open File + Открыть файл + + + OpenSearch + OpenSearch + + + Error + Ошибка + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 не является допустимым описанием OpenSearch 1.1 или уже есть в списке. + + + You must have at least one search engine in here. + Здесь должна быть хотя бы одна поисковая система. + + + OpenSearch Manager + Управление OpenSearch + + + &Restore Defaults + &Восстановить настройки по умолчанию + + + &Delete + &Удалить + + + &Add + &Добавить + + + &Close + &Закрыть + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Описание:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Предоставляет контекстные предположения</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Имя + + + Keywords + Ключевые слова + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Добавить следующую поисковую систему в список?<br /><br />Название: %1<br />Ищет с помощью: %2 + + + + PasswordDialog + + Authentication Required + Требуется аутентификация + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Имя пользователя: + + + Password: + Пароль: + + + + PlainTextEditSearch + + Not Found + Не найдено + + + + ProxyDialog + + Proxy Authentication + Аутентификация прокси + + + ICON + ICON + + + Connect to proxy + Подключиться к прокси + + + Username: + Имя пользователя: + + + Password: + Пароль: + + + + QObject + + The file is not an XBEL version 1.0 file. + Файл не является файлом XBEL версии 1.0. + + + Unknown title + Неизвестный заголовок + + + The file is not an OpenSearch 1.1 file. + Файл не является файлом OpenSearch 1.1. + + + + RequestModel + + Redirect: %1 + Перенаправить: %1 + + + Method + Метод + + + Address + Адрес + + + Response + Ответ + + + Length + Длина + + + Content Type + Формат содержимого + + + Info + Информация + + + + SearchBanner + + Form + Form + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + Готово + + + Highlight All + Подсветить всё + + + + SearchLineEdit + + Search + Поиск + + + + Settings + + Settings + Параметры + + + General + Общие + + + Home: + Домашняя страница: + + + Set to current page + Использовать текущую страницу + + + Remove history items: + Удалять элементы журнала: + + + After one day + Через день + + + After one week + Через неделю + + + After two weeks + Через две недели + + + After one month + Через месяц + + + After one year + Через год + + + Manually + Вручную + + + Open links from applications: + Открывать ссылки из приложений: + + + In a tab in the current window + Во вкладке в текущем окне + + + In a new window + В новом окне + + + Appearance + Внешний вид + + + Standard font: + Стандартный шрифт: + + + Times 16 + Times 16 + + + Select... + Выбрать... + + + Fixed-width font: + Моноширинный шрифт: + + + Courier 13 + Courier 13 + + + Privacy + Конфиденциальность + + + Web Content + Веб-содержимое + + + Enable Plugins + Включить подключаемые модули + + + Enable Javascript + Включить JavaScript + + + Cookies + Cookies + + + Accept Cookies: + Принимать cookies: + + + Always + Всегда + + + Never + Никогда + + + Only from sites you navigate to + Только с посещённых сайтов + + + Exceptions... + Исключения... + + + Keep until: + Сохранять до: + + + They expire + Истечения срока + + + I exit the application + Выхода из приложения + + + At most 90 days + Максимум 90 дней + + + Cookies... + Cookies... + + + Proxy + Прокси + + + Enable proxy + Включить прокси + + + Type: + Тип: + + + Socks5 + Socks5 + + + Http + Http + + + Host: + Сервер: + + + Port: + Порт: + + + User Name: + Имя пользователя: + + + Password: + Пароль: + + + Advanced + Дополнительно + + + Style Sheet: + Таблица стилей: + + + Downloads + Загрузки + + + Ask for a destination each time + Каждый раз спрашивать папку назначения + + + Use this destination: + Использовать эту папку назначения: + + + On startup: + При запуске: + + + Show my home page + Показывать мою домашнюю страницу + + + Show a blank page + Показывать чистую страницу + + + Restore windows and tabs from last time + Восстанавливать окна и вкладки прошлой сессии + + + On application exit + При выходе + + + Enable Images + Включить картинки + + + Tabs + Вкладки + + + Select tabs and windows as they are created + Активировать вкладки и окна при их создании + + + Confirm when closing multiple tabs + Подтверждать закрытие нескольких вкладок + + + Preferences + Настройки + + + Home Page: + Домашняя страница: + + + View Images + Посмотреть изображения + + + Keep Cookies Until: + Хранить cookies до: + + + Show only one close button instead of one for each tab + Не показывать кнопку закрытия на каждой вкладке + + + Use proxy server + Использовать прокси-сервер + + + Host name: + Имя хоста: + + + Preferred languages for viewing webpages in: + Предпочитаемые языки для просмотра веб-страниц: + + + Block Popup Windows + Блокировать всплывающие окна + + + Opening links + Открытие ссылки + + + Links that want to open in a new window: + Ссылки, которые хотят открыть в новом окне: + + + In a new selected tab in the current window + В новой выбранной вкладке текущего окна + + + In a new tab in the current window + В новой вкладке текущего окна + + + In the current tab + В текущей вкладке + + + Http (Secure) + Http (Защищённый) + + + Http (Transparent) + Http (Прозрачный) + + + Use ClickToFlash on flash plugins + Использовать ClickToFlash для flash плагинов + + + Filter Tracking Cookies + Фильтровать отслеживающие Cookie + + + Confirm when closing multiple tabs or windows + Подтверждать закрытие нескольких вкладок или окон + + + Quit the application when last tab is closed + Выйти из программы при закрытии последней вкладки + + + Enable network cache + Включить сетевой кэш + + + Maximum Size: + Максимальный размер: + + + MB + МБ + + + Use the default search engine as fallback when the URL given by the user is invalid + Отправлять запрос в поисковую систему по умолчанию, когда набранная пользователем ссылка неверна + + + Choose Directory... + Выбрать директорию... + + + A cookie session ends: + Сеанс cookie заканчивается: + + + When I exit the application + При выходе из приложения + + + 1 day + 1 день + + + 2 days + 2 дня + + + 3 days + 3 дня + + + 7 days + 7 дней + + + 30 days + 30 дней + + + AutoFill + Автозаполнение + + + AutoFill web forms: + Автозаполнение веб-форм: + + + User names and passwords + Имена пользователей и пароли + + + Edit... + Изменить... + + + Browse... + Обзор... + + + + SettingsDialog + + Restart required + Требуется перезапустить браузер + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Параметры сетевого кэша были изменены. Чтобы они вступили в силу, нужно перезапустить браузер. + + + Choose Directory + Выбрать директорию + + + Choose CSS File + Выбрать CSS файл + + + + SourceViewer + + Loading... + Загрузка... + + + &Edit + &Правка + + + &Find + &Найти + + + &View + &Вид + + + &Wrap lines + Перносить &строки + + + Source of Page + Исходный код страницы + + + Source of Page %1 + Источник страницы %1 + + + + TabBar + + New &Tab + Новая &вкладка + + + Duplicate Tab + Копировать вкладку + + + &Close Tab + &Закрыть вкладку + + + Close &Other Tabs + Закрыть &другие вкладки + + + Reload Tab + Обновить вкладку + + + Reload All Tabs + Обновить все вкладки + + + Show Tab Bar + Показать Панель Вкладок + + + Hide Tab Bar + Скрыть Панель Вкладок + + + + TabWidget + + New &Tab + Новая &вкладка + + + &Close Tab + &Закрыть вкладку + + + Show Next Tab + Показать следующую вкладку + + + Show Previous Tab + Показать предыдущую вкладку + + + Recently Closed Tabs + Недавно закрытые вкладки + + + (Untitled) + (Безымянный) + + + Do you really want to close this page? + Действительно закрыть эту страницу? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Вы изменили эту страницу, и вы потеряете изменения при её закрытии. +Действительно закрыть эту страницу? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Untitled + Безымянный + + + Saved Tabs + Сохранённые вкладки + + + Loading... + Загрузка... + + + Loading %1% (%2 %3)... + Загрузка %1% (%2 %3)... + + + Finished loading + Загрузка окончена + + + Failed to load + Ошибка при загрузке + + + Bookmark All Tabs + Закладки для всех вкладок + + + + ToolbarSearch + + Google + Google + + + No Recent Searches + Нет последних слов для поиска + + + Recent Searches + Последние слова для поиска + + + Clear Recent Searches + Очистить последние слова для поиска + + + Suggestions + Предположения + + + Add '%1' + Добавить '%1' + + + Configure Search Engines... + Настроить поисковые системы... + + + + WebPage + + Error loading page: %1 + Ошибка при загрузке страницы: %1 + + + When connecting to: %1. + При подключении к: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Проверьте адрес на ошибки вроде <b>ww</b>.arora-browser.org вместо <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Если компьютер или сеть защищены сетевым экраном или прокси-сервером, проверьте, разрешён ли браузеру доступ к сети. + + + If the address is correct, try checking the network connection. + Если адрес введён правильно, проверьте сетевое соединение. + + + Resending POST request + Повторная отправка запроса POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Для того, чтобы отобразить этот сайт, запрос вместе со всеми данными должен быть послан ещё раз, что может привести к неожиданному поведению сайта, например одно действое может быть выполненно дважды. Всё равно продолжить? + + + + WebView + + Open in New &Window + Открыть в новом &окне + + + Open in New &Tab + Открыть в новой &вкладке + + + Save Lin&k + Сохранить &ссылку + + + &Bookmark This Link + Добавить ссылку в &закладки + + + &Copy Link Location + &Копировать адрес ссылки + + + Open Image in New &Window + Открыть изображение в новом &окне + + + Open Image in New &Tab + Открыть изображение в новой &вкладке + + + &Save Image + &Сохранить изображение + + + &Copy Image + &Копировать изображение + + + C&opy Image Location + Копировать &адрес изображения + + + Loading... + Загрузка... + + + Search with... + Искать в... + + + Add to the toolbar search + Добавит в поисковую панель + + + Method not supported + Метод не поддерживается + + + %1 method is not supported. + %1 метод не поддерживается. + + + Search engine + Поисковая система + + + Choose the desired search engine + Выберите понравившуюся поисковую систему + + + Engine name + Имя поисковой системы + + + Type in a name for the engine + Введите имя поисковой системы + + + Block Image + Блоировать изображение + + + + WebViewSearch + + Not Found + Не найдено + + + diff --git a/src/locale/sk_SK.ts b/src/locale/sk_SK.ts new file mode 100644 index 00000000..e201bf3b --- /dev/null +++ b/src/locale/sk_SK.ts @@ -0,0 +1,2264 @@ + + + + + AboutDialog + + About + O prehliadači + + + Authors + Autori + + + License + Licencia + + + Lightweight WebKit-based web browser + Jednoduchý webový prehliadač založený na WebKite + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Zavrieť + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + About %1 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + + + + Languages: in order of preference: + + + + Move &Up + + + + Move &Down + + + + &Remove + &Vymazať + + + Add... + + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + Pravidlo + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + Pridať záložku + + + Type a name for the bookmark, and choose where to keep it. + Napíšte názov záložky a vyberte, kam ju chcete uložiť. + + + Url + + + + Title + + + + Add Folder + Pridať zložku + + + + AutoFillDialog + + Form Passwords + + + + Remove + + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + Otvoriť + + + Delete + Vymazať + + + New Folder + Nová zložka + + + Bookmarks + Záložky + + + &Remove + &Vymazať + + + Add Folder + Pridať zložku + + + Open in New Tab + Otvoriť v novom paneli + + + Edit Name + + + + Edit Address + + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Chyba pri načítavaní založiek na riadku %1, stĺpci %2: %3 + + + Toolbar Bookmarks + Nástrojová lišta záložiek + + + Menu + Menu + + + Open File + Otvoriť súbor + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + Importované %1 + + + Save File + Uložiť súbor + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Chyba pri exporte + + + error saving bookmarks + chyba pri ukladaní záložiek + + + Remove Bookmark + Vymazať záložku + + + Insert Bookmark + Vložiť záložku + + + Name Change + Zmena názvu + + + Address Change + Zmena adresy + + + Bookmarks Bar + + + + Bookmarks Menu + + + + Name Change + Undo bookmark title change + Zmena názvu + + + Address Change + Undo bookmark url change + Zmena adresy + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + + + + + BookmarksModel + + Title + Titulok + + + Address + Adresa + + + + BookmarksToolBar + + Bookmark + Záložky + + + Open + Otvoriť + + + Open in New &Tab + O&tvoriť v novom paneli + + + Remove + + + + Add Bookmark... + Pridať záložku ... + + + Add Folder... + + + + Bookmarks + Záložky + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Máte otvorených %1 okien a %2 panelov +Chcete ich všetky uzavrieť? + + + Restore failed + Obnovenie zlyhalo + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Uložená relácia nebude obnovená, pretože Arora spadla pri pokuse o jej obnovenie. + + + (Change: %1 %2) + (Zmena: %1 %2) + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + &Súbor + + + &New Window + &Nové okno + + + &Open File... + Otvoriť &soubor... + + + Open &Location... + &Otvoriť adresu ... + + + &Save As... + &Uložiť ako... + + + &Import Bookmarks... + &Importovať záložky ... + + + &Export Bookmarks... + &Exportovať záložky ... + + + P&rint Preview... + Ná&hľad tlače ... + + + &Print... + &Tlač ... + + + Private &Browsing... + Súkro&mné prehliadanie ... + + + &Quit + U&končiť + + + &Edit + Úpr&avy + + + &Undo + &Späť + + + &Redo + Zn&ovu + + + Cu&t + &Vystrihnúť + + + &Copy + &Kopírovať + + + &Paste + V&ložiť + + + &Find + Ná&jsť + + + Ctrl+, + Ctrl+, + + + &View + &Zobraziť + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + &Stop + Z&astaviť + + + Page S&ource + &Zdrojový kód stránky + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Celá obrazovka + + + Hi&story + &História + + + Back + Späť + + + Forward + Vpred + + + Home + Domov + + + Restore Last Session + Obnoviť poslednú reláciu + + + &Bookmarks + Zál&ožky + + + Manage Bookmarks... + Spravovať záložky ... + + + Add Bookmark... + Pridať záložku ... + + + &Window + &Okno + + + &Tools + &Nástroje + + + Web &Search + &Hľadanie na webe + + + Ctrl+K + Web Search + Ctrl+K + + + Enable Web &Inspector + Povoliť Web &Inspector + + + &Help + Nápo&veda + + + About &Qt + O &Qt + + + About &Arora + O &Arore + + + Navigation + Navigácia + + + Show Status Bar + Zobraziť stavový riadok + + + Hide Status Bar + Skryť stavový riadok + + + Show Toolbar + Zobraziť panel nástrojov + + + Hide Toolbar + Skryť panel nástrojov + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Otvoriť webovú stránku + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Webové dokumenty (*.html *.htm *.svg *.png *.gif *.svgz);;Všetky súbory (*.*) + + + Print Document + Vytlačiť dokument + + + Are you sure you want to turn on private browsing? + Naozaj chcete zapnúť súkromné prehliadanie? + + + Are you sure you want to close the window? There are %1 tabs open + Naozaj chcete zavrieť okno? Je v nom otvorených %1 panelov + + + Web Inspector + Webový inšpektor + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Webový inšpektor bude fungovať iba pre stránky načítané po jeho povoleni. +Chcete znovu načítať všetky stránky? + + + Stop loading the current page + Zastaví načítanie aktuálnej stránky + + + Reload the current page + Znovu načíta aktuálnu stránku + + + Downloads + Preberanie + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + &Clear Private Data + Zmazaž &súkromné dáta + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Ak je zapnuté súkromné prehliadanie, niektoré akcie narušujúce tvoje súkromie budú zakázané:<ul><li> Stránky nie sú pridávané do histórie.</li><li> Položky sú automaticky vymazané z okna preberania.</li><li> Nové cookies nie sú uložené, aktuálne nebudú prístupné.</li><li> Ikony stránek nie sú ukládané, podobne ako relácie.</li><li> Hľadané výrazy nie sú pridávané do menu v políčku hľadania.</li></ul>Pokiaľ nie je okno zavrené, je možné klikať Späť a Vpred pre vrátenie na skôr otvorené stránky. + + + Show Bookmarks Bar + Zobraziť panel záložiek + + + Hide Bookmarks Bar + Skryť panel záložiek + + + Find P&revious + Nájsť &predošlé + + + &Reload Page + O&bnoviť stránku + + + Make Text &Bigger + Z&väčšiť text + + + Make Text &Normal + &Normálna veľkosť textu + + + Make Text &Smaller + Z&menšiť text + + + Find Nex&t + Náj&sť dalšie + + + Prefere&nces... + Nasta&venia ... + + + Show Menu Bar + Ukázať menu + + + Switch application language + Vybrať jazyk + + + Close Window + + + + Zoom &In + + + + Zoom &Normal + + + + Zoom &Out + + + + Zoom &Text Only + + + + Show All Bookmarks... + + + + Add Folder... + + + + About &%1 + About Browser + + + + Ctrl+Y + Download Manager + + + + Default + Prednastavený + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + Vyčistiť + + + + ClearPrivateData + + Clear Private Data + Vymazať súkromné dáta + + + Clear the following items: + Vymazať tieto položky: + + + &Browsing History + &História prehliadania + + + &Download History + História &preberania + + + &Search History + História hľa&dania + + + &Cookies + &Cookies + + + Website &Icons + Ikony stránok + + + Clear &Private Data + &Vyčistiť súkromné dáta + + + &Cancel + &Zrušiť + + + C&ached Web Pages + Stránky v &cache + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + Adresa + + + Allow + Povoliť + + + Block + Blokovať + + + Allow For Session + Povoliť pre reláciu + + + Rule + Pravidlo + + + + CookieModel + + Website + Adresa + + + Name + Názov + + + Path + Cesta + + + Secure + Zabezpečené + + + Expires + Vyprší + + + Contents + Obsah + + + true + áno + + + false + nie + + + Session cookie + + + + + CookiesDialog + + Cookies + Cookies + + + &Remove + &Vymazať + + + Remove &All Cookies + Vymazať &všetky + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + Výnimky pre cookies + + + New Exception + Nová výnimka + + + Domain: + Doména: + + + Block + Blokovať + + + Allow For Session + Povoliť pre reláciu + + + Allow + Povoliť + + + Exceptions + Výnimky + + + &Remove + &Vymazať + + + Remove &All + Vymazať &všetky + + + + DownloadDialog + + Downloads + Preberanie + + + Clean up + Vyčistiť + + + 0 Items + 0 položiek + + + &OK + &OK + + + + DownloadItem + + Form + Form + + + Ico + Ico + + + Filename + Názov súboru + + + Try Again + Skúsiť znova + + + Stop + Zastaviť + + + Open + Otvoriť + + + Save File + Uložiť súbor + + + Download canceled: %1 + Preberanie zrušené: %1 + + + Error saving: %1 + Chyba pri ukladaní: %1 + + + Network Error: %1 + Chyba siete: %1 + + + seconds + sekúnd + + + %1 of %2 (%3/sec) %4 + %1 z %2 (%3/s) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 z %2 - Zastavené + + + bytes + bajtov + + + kB + KiB + + + MB + MiB + + + - %n minutes remaining + + - %n minúta ostáva + - %n minúty ostávajú + - %n minút ostáva + + + + - %n seconds remaining + + - %n sekunda ostáva + - %n sekundy ostávajú + - %n sekúnd ostáva + + + + Error opening output file: %1 + Chyba pri otváraní výstupného súboru: %1 + + + %1 of %2 (%3/sec) - %4 + + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + %n Download(s) + + %n preberanie + %n preberania + %n preberaní + + + + There are %1 downloads in progress +Do you want to quit anyway? + + + + %n minutes remaining + + + + + + + + %n seconds remaining + + + + + + + + bytes + bajtov + + + kB + KiB + + + MB + MiB + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + Otvoriť + + + Copy + Kopírovať + + + Delete + Vymazať + + + History + História + + + &Remove + &Vymazať + + + Remove &All + Vymazať &všetky + + + + HistoryMenu + + Show All History + Zobraziť celú históriu + + + Clear History + Vymazať históriu + + + Clear History... + Vymazať históriu ... + + + Do you want to clear the history? + Chcete vymazať históriu? + + + + HistoryModel + + Title + Názov + + + Address + Adresa + + + + HistoryTreeModel + + Earlier Today + Dnes + + + %n item(s) + + %n položka + %n položky + %n položiek + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + Default + Prednastavený + + + Choose language + Vybrať jazyk + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Aroru je možné používať v inom jazyku ako v tom,<br>ktorý je prednastavený v operačnom systéme.</p><p>Vybete si jazyk, ktorý má byť použitý</p> + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Zadajte užívateľské meno a heslo pre "%1" na %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Pripojiť sa k proxy "%1" použitím:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Chyby SSL: + +%1 + +%2 + +Chcete ignorovať tieto chyby? + + + Do you want to accept all these certificates? + Chcete prijať všetky tieto certifikáty? + + + - SSL Errors + + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + Názov + + + + NetworkMonitorDialog + + &Remove + &Vymazať + + + + OpenSearchDialog + + Open File + Otvoriť súbor + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + Názov + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + Vyžadované prihlásenie + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Užívateľské meno: + + + Password: + Heslo: + + + + PlainTextEditSearch + + Not Found + Neexistuje + + + + ProxyDialog + + Proxy Authentication + Prihlásenie k proxy + + + ICON + ICON + + + Connect to proxy + Pripojiť k proxy + + + Username: + Užívateľské meno: + + + Password: + Heslo: + + + + QObject + + The file is not an XBEL version 1.0 file. + Súbor nie je XBEL verzie 1.0. + + + Unknown title + Neznámý titulok + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Address + Adresa + + + + SearchBanner + + Form + Form + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + Hotovo + + + Highlight All + + + + + SearchLineEdit + + Search + Hľadať + + + + Settings + + General + Hlavné + + + Set to current page + Nastav na aktuálnu stránku + + + Remove history items: + Odstrániť položky histórie: + + + After one day + Po jednom dni + + + After one week + Po jednom týždni + + + After two weeks + Po dvoch týždňoch + + + After one month + Po mesiaci + + + After one year + Po roku + + + Manually + Ručne + + + Open links from applications: + Otvoriť odkazy z aplikácií: + + + In a tab in the current window + V paneli v aktuálnom okne + + + In a new window + V novom okne + + + Appearance + Vzhľad + + + Standard font: + Štandardné písmo: + + + Times 16 + Times 16 + + + Select... + Vybrať ... + + + Fixed-width font: + Písmo s pevnou šírkou: + + + Courier 13 + Courier 13 + + + Privacy + Súkromie + + + Web Content + Obsah webu + + + Enable Plugins + Povoliť plug-iny + + + Enable Javascript + Povoliť JavaScript + + + Cookies + Cookies + + + Accept Cookies: + Prijímať cookies: + + + Always + Vždy + + + Never + Nikdy + + + Only from sites you navigate to + Iba z navštívených stránok + + + Exceptions... + Výnimky ... + + + They expire + Vyprší + + + I exit the application + Ukončenie aplikácie + + + At most 90 days + Maximálne 90 dní + + + Cookies... + Cookies ... + + + Proxy + Proxy + + + Type: + Typ: + + + Socks5 + Socks5 + + + Http + Http + + + Port: + Port: + + + User Name: + Uživatelské meno: + + + Password: + Heslo: + + + Advanced + Rozšírené + + + Style Sheet: + CSS štýl: + + + Downloads + Preberanie + + + Ask for a destination each time + Vždy sa pýtať na umiestnenie preberania + + + Use this destination: + Použiť toto umiestnenie: + + + On application exit + Pri ukončení aplikácie + + + Tabs + Panely + + + Select tabs and windows as they are created + Prepínať na okná a panely keď sú vytvorené + + + Confirm when closing multiple tabs + Vyžadovať potvrdenie pri zatváraní viacerých panelov + + + On startup: + Po spustení: + + + Show my home page + Zobraziť moju domovskú stránku + + + Show a blank page + Zobraziť prázdnu stránku + + + Restore windows and tabs from last time + Obnoviť okná a panely z poslednej relácie + + + Preferences + Nastavenia + + + Home Page: + Domovská stránka: + + + View Images + Zobraziť obrázky + + + Keep Cookies Until: + Ponechat cookies pokiaľ: + + + Use proxy server + Použiť proxy server + + + Host name: + Meno hostiteľa: + + + Show only one close button instead of one for each tab + + + + Preferred languages for viewing webpages in: + + + + Block Popup Windows + + + + Opening links + + + + Links that want to open in a new window: + + + + In a new selected tab in the current window + + + + In a new tab in the current window + + + + In the current tab + + + + Http (Secure) + + + + Http (Transparent) + + + + Use ClickToFlash on flash plugins + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + Nahrávam ... + + + &Edit + Úpr&avy + + + &Find + Ná&jsť + + + Source of Page + Zdrojový súbor + + + &View + &Zobraziť + + + Source of Page %1 + + + + + TabBar + + New &Tab + &Nový panel + + + Duplicate Tab + Duplikovať panel + + + &Close Tab + &Zavrieť panel + + + Close &Other Tabs + Zavrieť o&statné panely + + + Reload Tab + &Obnoviť panel + + + Reload All Tabs + O&bnoviť všetky panely + + + Show Tab Bar + Zobraziť lištu panelov + + + Hide Tab Bar + Skryť lištu panelov + + + + TabWidget + + New &Tab + &Nový panel + + + &Close Tab + &Zavrieť panel + + + Show Next Tab + Ukázať ďalší panel + + + Show Previous Tab + Ukázať predchádzajúci panel + + + Recently Closed Tabs + Zatvorené panely + + + Do you really want to close this page? + Naozaj chcete zatvoriť tento panel? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Stránka bola zmenená a pri zatvorení budu všetky zmeny stratené. +Ste si istý, že chcete zavrieť túto stránku? + + + + Untitled + Nepomenovaný + + + Ctrl-] + + + + Ctrl-[ + + + + Saved Tabs + + + + Loading... + Nahrávam ... + + + Loading %1% (%2 %3)... + + + + Finished loading + + + + Failed to load + + + + Bookmark All Tabs + + + + + ToolbarSearch + + No Recent Searches + Žiadne posledné hľadania + + + Recent Searches + Posledné hľadania + + + Clear Recent Searches + Vymazať posledné hľadania + + + Suggestions + + + + Add '%1' + + + + + WebPage + + Error loading page: %1 + Chyba pri načítavaní stránky: %1 + + + When connecting to: %1. + + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + + + + If the address is correct, try checking the network connection. + + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + Otvoriť v &novom okne + + + Open in New &Tab + O&tvoriť v novom paneli + + + Save Lin&k + Uložiť o&dkaz + + + &Bookmark This Link + &Vytvoriť záložku pre tento odkaz + + + &Copy Link Location + &Kopírovať adresu odkazu + + + Open Image in New &Window + Otvoriť obrázok v novom okne + + + Open Image in New &Tab + Otvoriť obrázok v novom paneli + + + &Save Image + Uložiť obrázok + + + &Copy Image + Kopírovať o&brázok + + + C&opy Image Location + Kopírovať adresu ob&rázka + + + Loading... + Nahrávam ... + + + Search with... + + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + Neexistuje + + + diff --git a/src/locale/sr_RS.ts b/src/locale/sr_RS.ts new file mode 100644 index 00000000..e29b3e2c --- /dev/null +++ b/src/locale/sr_RS.ts @@ -0,0 +1,2051 @@ + + + + + AboutDialog + + About %1 + О %1 + + + Authors + Аутори + + + License + Лиценца + + + Lightweight WebKit-based web browser + Лагани веб прегледач базиран на Вебкиту + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org/</a> + + + Close + Затвори + + + WebKit version: %1 + Верзија Вебкита: %1 + + + + AcceptLanguage + + Languages + Језици + + + Languages: in order of preference: + Језици према редоследу пожељности: + + + Move &Up + &Горе + + + Move &Down + &Доле + + + &Remove + &Уклони + + + Add... + Додај... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Заустављено Адблоковим правилом: %1 + + + + AdBlockDialog + + Add Custom Rule + Додај прилагођено правило + + + Learn more about writing rules... + Научите више о писању правила... + + + Update Subscription + Ажурирај претплате + + + Browse Subscriptions... + Прегледај претплате... + + + Remove Subscription + Уклони претплату + + + AdBlock Configuration + Подешавање Адблока + + + Enable AdBlock + Омогући Адблок + + + Action + Радња + + + + AdBlockManager + + Custom Rules + Прилагођена правила + + + + AdBlockModel + + Rule + Правило + + + + AdBlockSchemeAccessHandler + + Subscribe? + Претплати се? + + + Subscribe to this AdBlock subscription? +%1 + Претпалтити се на ову Адблок претплату? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Додај маркер + + + Type a name for the bookmark, and choose where to keep it. + Унесите име маркера и изаберите где га сачувати. + + + Url + УРЛ + + + Title + Наслов + + + Add Folder + Додај фасциклу + + + + AutoFillDialog + + Form Passwords + Лозинке за обрасце + + + Remove + Уклони + + + Remove All + Уклони све + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Желите ли да сачувате ову лозинку?</b><br> Да би прегледали или уклонили сачуване лозинке користите панел самопопуњавања у подешавањима. + + + Never for this site + Никад за овај сајт + + + Not now + Не сад + + + + AutoFillModel + + WebSite + Веб сајт + + + User Name + Корисничко име + + + + BookmarksDialog + + Open + Отвори + + + Open in New Tab + Отвори у новом језичку + + + Edit Name + Уреди име + + + Edit Address + Уреди адресу + + + Delete + Обриши + + + New Folder + Нова фасцикла + + + Bookmarks + Маркери + + + &Remove + &Уклони + + + Add Folder + Додај фасциклу + + + + BookmarksManager + + Bookmarks Bar + Трака маркера + + + Bookmarks Menu + Мени маркера + + + Error when loading bookmarks on line %1, column %2: +%3 + Грешка при учитавању маркера у реду %1, колона %2: +%3 + + + Toolbar Bookmarks + Маркери у траци алатки + + + Menu + Мени + + + Open File + Отвори фајл + + + Imported %1 + Увезено %1 + + + Save File + Сачувај фајл + + + %1 Bookmarks.xbel + %1 Маркери.xbel + + + Export error + Грешка при извозу + + + error saving bookmarks + грешка при чувању маркера + + + Remove Bookmark + Уклони маркер + + + Insert Bookmark + Унеси маркер + + + Name Change + Undo bookmark title change + Промена имена + + + Address Change + Undo bookmark url change + Промена адресе + + + XBEL bookmarks + ИксБЕЛ маркери + + + HTML Netscape bookmarks + ХТМЛ Нетскејп маркери + + + htmlToXBel tool required + Неопходна је Хтмл-У-ИксБЕЛ алатка + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Хтмл-У-ИксБЕЛ алатка, која се деставља са Арором и неопходна је за увоз ХТМЛ маркера, није инсталирана или се не налази у претраженим путањама. + + + Loading Bookmark + Учитавам маркер + + + Error when loading HTML bookmarks: %1 + + Грешка при учитавању ХТМЛ маркера: %1 + + + + + BookmarksMenu + + Open in Tabs + Отвори у језичцима + + + + BookmarksModel + + Title + Наслов + + + Address + Адреса + + + + BookmarksToolBar + + Open + Отвори + + + Open in New &Tab + Отвори у новом &језичку + + + Remove + Уклони + + + Add Bookmark... + Додај маркер... + + + Add Folder... + Додај фасциклу... + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Отворено је %1 прозор(а) и %2 језичак(а) +Свеједно напустити? + + + Restore failed + Повраћај није успео + + + Arora crashed while trying to restore this session. Should I try again? + Арора се срушила у покушају да поврати сесију. Покушати поново? + + + + BrowserMainWindow + + &File + &Фајл + + + &New Window + Нови &прозор + + + &Open File... + &Отвори фајл... + + + Open &Location... + Отвори &локацију... + + + &Save As... + &Сачувај као... + + + &Import Bookmarks... + &Увези маркере... + + + &Export Bookmarks... + &Извези маркере... + + + P&rint Preview... + П&реглед штампе... + + + &Print... + Ш&тампа... + + + Private &Browsing... + &Приватно прегледање... + + + Close Window + Затвори прозор + + + &Quit + &Напусти + + + &Edit + &Уређивање + + + &Undo + &Опозови + + + &Redo + &Понови + + + Cu&t + Исе&ци + + + &Copy + &Копирај + + + &Paste + &Налепи + + + &Find + Нађ&и + + + Find Nex&t + Нађи &следеће + + + Find P&revious + Нађи &претходно + + + Ctrl+, + Ctrl+, + + + &View + Прика&з + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + Show Menu Bar + Прикажи траку менија + + + &Reload Page + Поново &учитај страницу + + + &Stop + &Заустави + + + Zoom &In + &Увећај + + + Zoom &Normal + По&дразумевано увећање + + + Zoom &Out + &Умањи + + + Zoom &Text Only + Увећај само &текст + + + Page S&ource + И&зворни код странице + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Цео екран + + + Hi&story + Ист&оријат + + + Back + Назад + + + Forward + Напред + + + Home + Моја страница + + + Restore Last Session + Поврати претходну сесију + + + &Bookmarks + &Маркери + + + Show All Bookmarks... + Прикажи све маркере... + + + Add Bookmark... + Додај маркер... + + + Add Folder... + Додај фасциклу... + + + &Window + &Прозор + + + &Tools + &Алатке + + + Web &Search + &Веб претрага + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + Очисти п&риватне податке + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Омогући &веб инспектор + + + &Help + По&моћ + + + Switch application language + Промени језик програма + + + About &Qt + О &Qt-у + + + About &%1 + About Browser + О &Арори + + + Navigation + Навигација + + + Show Status Bar + Прикажи траку стања + + + Hide Status Bar + Сакриј траку стања + + + Show Toolbar + Прикажи траку алатки + + + Hide Toolbar + Сакриј траку алатки + + + Show Bookmarks Bar + Прикажи траку маркера + + + Hide Bookmarks Bar + Сакриј траку маркера + + + %1 - Arora + Page title and Browser name + %1 - Aрора + + + Open Web Resource + Отвори веб ресурс + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Веб ресурси (*.html *.htm *.svg *.png *.gif *.svgz);;Сви фајлови (*.*) + + + Print Document + Штампај документ + + + Are you sure you want to turn on private browsing? + Да ли сте сигурни да желите да укључите приватно прегледање? + + + Are you sure you want to close the window? There are %1 tabs open + Да ли сте сигурни да желите да затворите прозор? Отворен(о) је %1 језичак(а) + + + Web Inspector + Веб инспектор + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Веб инспектор ће исправно радити само на страницама учитаним након његовог укључивања. +Да ли желите да поново учитате све странице? + + + Stop loading the current page + Заустави учитавање тренутне странице + + + Reload the current page + Поново учитај тренутну страницу + + + Downloads + Пријеми + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Подразумевано + + + Text Encoding + Кодирање текста + + + Alt+Ctrl+B + Alt+Ctrl+B + + + Select &All + Изабери &све + + + Options... + Опције... + + + Configure Search Engines... + Подеси моторе претраге... + + + &Ad Block... + &Адблок... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Кад је укључено приватно прегледање онемогућене су неке радње које се тичу ваше приватности: + + + Webpages are not added to the history. + Веб стране се не додају у историјат. + + + Items are automatically removed from the Downloads window. + Ставке се аутоматски уклањају из прозора пријема. + + + New cookies are not stored, current cookies can't be accessed. + Нови колачићи се не чувају, постојећим се не може приступити. + + + Site icons won't be stored. + Иконе сајтова се не чувају. + + + Session won't be saved. + Сесије се не снимају. + + + Searches are not added to the pop-up menu in the search box. + Претраге се не додају у искачући мени прозорчића претраге. + + + No new network cache is written to disk. + Мрежни кеш се не дописује на диск. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Док не затворите прозор и даље можете кликнути на „Напред“ и „Назад“ да би сте се вратили на претходно отваране странице. + + + Private Browsing + Приватно прегледање + + + + ClearButton + + Clear + Очисти + + + + ClearPrivateData + + Clear Private Data + Очисти приватне податке + + + Clear the following items: + Очисти следеће ставке: + + + &Browsing History + историјат &претраге + + + &Download History + историјат п&реузимања + + + &Search History + историјат пр&етраге + + + &Cookies + &колачиће + + + C&ached Web Pages + кеширане &веб странице + + + Website &Icons + &иконе веб сајтова + + + Clear &Private Data + Очисти приватне по&датке + + + &Cancel + &Одустани + + + + ClickToFlash + + Load + Учитај + + + Load All + Учитај све + + + Add %1 to Whitelist + Додај %1 на белу листу + + + Remove from Whitelist + Уклони са беле листе + + + Settings + Подешавање + + + Load Flash + Учитај флеш + + + + ClickToFlashSettings + + Whitelist sites + Сајтови на белој листи + + + + CookieExceptionsModel + + Website + Веб сајт + + + Rule + Правило + + + Allow + Дозволи + + + Block + Блокирај + + + Allow For Session + Дозволи у току сесије + + + + CookieModel + + Website + Веб сајт + + + Name + Име + + + Path + Путања + + + Secure + Сигурно + + + Expires + Истиче + + + Contents + Садржај + + + true + тачно + + + false + нетачно + + + Session cookie + Колачић сесије + + + + CookiesDialog + + Cookies + Колачићи + + + &Remove + &Уклони + + + Remove &All Cookies + Уклони &све колачиће + + + Add &Rule + Додај &правило + + + + CookiesExceptionsDialog + + Cookie Exceptions + Изузеци за колачиће + + + New Exception + Нови изузетак + + + Domain: + Домен: + + + Block + Блокирај + + + Allow For Session + Дозволи у току сесије + + + Allow + Дозволи + + + Exceptions + Изузеци + + + &Remove + &Уклони + + + Remove &All + Уклони &све + + + + DownloadDialog + + Downloads + Преузимања + + + Clean up + Очисти + + + 0 Items + Нема ставки + + + + DownloadItem + + Ico + Икона + + + Filename + Име фајла + + + Try Again + Покушајте поново + + + Stop + Заустави + + + Open + Отвори + + + Save File + Сачувај фајл + + + Download canceled: %1 + Преузимање отказано: %1 + + + Error opening output file: %1 + Грешка при отварању излазног фајла: %1 + + + Error saving: %1 + Грешка при чувању: %1 + + + Network Error: %1 + Грешка на мрежи: %1 + + + %1 of %2 (%3/sec) - %4 + %1 од %2 (%3/сек) - %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 од %2 - Заустављено + + + Download directory (%1) couldn't be created. + Фасцикла за преузимања (%1) не може бити направљена. + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + У току су %1 преузимања +Свеједно напустити? + + + %n Download(s) + + %n преузимање + %n преузимања + %n преузимања + + + + %n minutes remaining + + %n минут је преостао + %n минуте су преостале + %n минута је преостало + + + + %n seconds remaining + + %n секунда је преостала + %n секунде су преостале + %n секунди је преостало + + + + bytes + бајтова + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Без грешке + + + Error opening: %1: No such file or directory + Грешка при отварању: %1: Не постоји такав фајл или фасцикла + + + Unable to read %1 + Немогуће читање %1 + + + Contents of %1 + Садржај %1 + + + %1 KB + %1 КБ + + + + HistoryDialog + + Open + Отвори + + + Copy + Копирај + + + Delete + Обриши + + + History + Историјат + + + &Remove + &Уклони + + + Remove &All + Уклони &све + + + + HistoryMenu + + Show All History + Прикажи цео историјат + + + Clear History... + Очисти историјат... + + + Clear History + Очисти историјат + + + Do you want to clear the history? + Желите ли да очистите историјат? + + + + HistoryModel + + Title + Назив + + + Address + Адреса + + + + HistoryTreeModel + + Earlier Today + Раније у току дана + + + %n item(s) + + %n ставка + %n ставке + %n ставки + + + + + JavaScriptAroraObject + + Welcome to Arora! + Добродошли у Арору ! + + + Arora Start + Aрорина почетна + + + Search! + Претражи! + + + Search results provided by + Резултате претраге омогућује + + + About Arora + О Арори + + + + LanguageManager + + Choose language + Изаберите језик + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Можете поставити различит језик од оног<br>који оперативни систем подразумева.</p><p>Изаберите језик који ћете користити</p> + + + No translation files are installed at %1. + Нема инсталираних фајлова превода у %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Уреди корисничко име и лозинку за "%1" на %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Повежи се на прокси "%1" користећи: </qt> + + + - SSL Errors + - SSL грешке + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Сертификати:<br/>%1<br/>Да ли желите да прихватите све ове сертификате?</qt> + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL грешке:<br/><br/>за: <tt>%1</tt><ul><li>%2</li></ul> +Да ли желите да занемарите ове грешке?</qt> + + + Issuer: %1 + Издавач: %1 + + + Not valid before: %1 + Није валидо пре: %1 + + + Valid until: %1 + Валидно до: %1 + + + Alternate Names: + Алтернативни називи: + + + + OpenSearchDialog + + Open File + Отвори фајл + + + OpenSearch + Отвори претрагу + + + Error + Грешка + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 није исправан OpenSearch 1.1 опис или се већ налази на вашој листи. + + + You must have at least one search engine in here. + Мора постојати барем један мотор претраге. + + + OpenSearch Manager + Овори управник претраге + + + &Restore Defaults + &Подразумевано + + + &Delete + &Обриши + + + &Add + &Додај + + + &Close + &Затвори + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Опис:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Даје предлоге из садржаја</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Списак зарезом раздвојених кључних речи које могу бити унете у траку локације заједно са изразима са претрагу у овом мотору претраге + + + Name + Име + + + Keywords + Кључне речи + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Желите ли да додате следећи мотор на вашу листу мотора претраге? <br /><br />Име: %1<br />Претражује на: %2 + + + + PasswordDialog + + Authentication Required + Неопходна аутентификација + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Корисничко име: + + + Password: + Лозинка: + + + + PlainTextEditSearch + + Not Found + Не постоји + + + + ProxyDialog + + Proxy Authentication + Аутентификација проксија + + + Connect to proxy + Повежи се на прокси + + + Username: + Корисничко име: + + + Password: + Лозинка: + + + + QObject + + The file is not an XBEL version 1.0 file. + Фајл није типа ИксБЕЛ 1.0. + + + Unknown title + Непознат назив + + + The file is not an OpenSearch 1.1 file. + Фајл није OpenSearch 1.1 типа. + + + + SearchBanner + + Done + Завршено + + + Highlight All + Истакни све + + + + SearchLineEdit + + Search + Претражи + + + + Settings + + Preferences + Поставке + + + General + Опште + + + On startup: + При покретању: + + + Show my home page + прикажи домаћу страницу + + + Show a blank page + прикажи празну страницу + + + Restore windows and tabs from last time + поврати прозоре и језичке од прошлог пута + + + Home Page: + Домаћа страница: + + + Set to current page + Постави текућу страницу + + + Remove history items: + Уклони ставке историјата: + + + After one day + после једног дана + + + After one week + после једне седмице + + + After two weeks + после две седмице + + + After one month + после једног месеца + + + After one year + после једне године + + + Manually + ручно + + + On application exit + при напуштању програма + + + Downloads + Преузимања + + + Ask for a destination each time + Увек питај за одредиште + + + Use this destination: + Користи следеће одредиште: + + + Appearance + Изглед + + + Standard font: + Стандардни фонт: + + + Select... + Изаберите... + + + Fixed-width font: + Фиксни фонт: + + + Preferred languages for viewing webpages in: + Пожељни језици за прегледање веб страница: + + + Privacy + Приватност + + + Web Content + Веб садржај + + + Block Popup Windows + Блокирај искачуће прозоре + + + Enable Plugins + Омогући прикључке + + + Use ClickToFlash on flash plugins + Користи "Кликни за флеш" за флеш прикључке + + + Enable Javascript + Омогући Јаваскрипт + + + View Images + Прикажи слике + + + Cookies + Колачићи + + + Accept Cookies: + Прихвати колачиће: + + + Always + увек + + + Never + никад + + + Only from sites you navigate to + само са веб сајтова које посећујем + + + Exceptions... + Изузеци... + + + Keep Cookies Until: + Задржи колачиће док не: + + + They expire + истекну + + + I exit the application + напустим програм + + + At most 90 days + истекне највише 90 дана + + + Cookies... + Колачићи... + + + Filter Tracking Cookies + Филтрирај колачиће пратиоце + + + Tabs + Језичци + + + Select tabs and windows as they are created + Одабери језичке и прозоре при њиховом настајању + + + Confirm when closing multiple tabs or windows + Потврда при затварању више прозора или језичака + + + Show only one close button instead of one for each tab + Прикажи само једно дугме за затварање уместо једног по сваком језичку + + + Quit the application when last tab is closed + Напусти програм кад је последњи језичак затворен + + + Opening links + Отварам везе + + + Links that want to open in a new window: + Везе које желе да се отворе у новом прозору: + + + In a new window + у новом прозору + + + In a new selected tab in the current window + у изабраном новом језичку тренутног прозора + + + In a new tab in the current window + у новом језичку тренутног прозора + + + In the current tab + у тренутном језичку + + + Open links from applications: + Отварај везе из програма: + + + Proxy + Прокси + + + Use proxy server + Користи прокси сервер + + + Type: + Тип: + + + Socks5 + СОКС5 + + + Http (Secure) + ХТТП (Безбедно) + + + Http (Transparent) + ХТТП (Транспарентно) + + + Host name: + Име домаћина: + + + Port: + Порт: + + + User Name: + Корисничко име: + + + Password: + Лозинка: + + + Advanced + Напредно + + + Style Sheet: + Опис стила: + + + Enable network cache + Омогући мрежни кеш + + + Maximum Size: + Максимална величина: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Користи подразумевани мотор претраге као испомоћ уколико је УРЛ задат од стране корисника неисправан + + + Choose Directory... + Изаберите фасциклу... + + + A cookie session ends: + Колачић сесије истиче: + + + When I exit the application + кад напустим програм + + + 1 day + за 1 дан + + + 2 days + за 2 дана + + + 3 days + за 3 дана + + + 7 days + за 7 дана + + + 30 days + за 30 дана + + + AutoFill + Смопопуњавање + + + AutoFill web forms: + Самопопуњавање веб образаца: + + + User names and passwords + Корисничка имена и лозинке + + + Edit... + Уреди... + + + Browse... + Прегледај... + + + + SettingsDialog + + Restart required + Захтева се поновно покретање + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Подешавање мрежног кеша је промењено. Да би било узето у обзир прегледач мора бити поново покренут. + + + Choose Directory + Изаберите фасциклу + + + Choose CSS File + Изаберите ЦСС фајл + + + + SourceViewer + + Loading... + Учитавање... + + + &Edit + &Уређивање + + + &Find + Нађ&и + + + Source of Page %1 + Изворни код странице %1 + + + + TabBar + + Show Tab Bar + Прикажи траку језичака + + + Hide Tab Bar + Сакриј траку језичака + + + Duplicate Tab + Дуплирај језичак + + + &Close Tab + &Затвори језичак + + + Close &Other Tabs + Затвори &остале језичке + + + Reload Tab + Поново учитај језичак + + + Reload All Tabs + Поново учитај све језичке + + + + TabWidget + + Untitled + Неименовано + + + Saved Tabs + Сачувај језичке + + + Do you really want to close this page? + Да ли заиста желите да затворите ову страницу? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Изменили сте ову страницу и њеним затварањем ћете изгубити измене. +Да ли заиста желите да затворите ову страницу? + + + + Loading... + Учитавање... + + + Loading %1% (%2 %3)... + Учитавам %1% (%2 %3)... + + + Finished loading + Учитавање завршено + + + Failed to load + Грешка при учитавању + + + Show Next Tab + Прикажи наредни језичак + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + Прикажи претходни језичак + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + Недавно затворени језичци + + + New &Tab + Нови &језичак + + + &Close Tab + &Затвори језичак + + + Bookmark All Tabs + Маркирај све језичке + + + + ToolbarSearch + + Suggestions + Предлози + + + No Recent Searches + Нема скорашњих претрага + + + Recent Searches + Скорашње претраге + + + Add '%1' + Додај '%1' + + + Clear Recent Searches + Уклони скорашње претраге + + + + WebPage + + Error loading page: %1 + Грешка при учитавању странице: %1 + + + When connecting to: %1. + При повезивању на: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Проверите адресу за грешке попут <b>ww/</b>.arora-browser.org/ /уместо <b>www/</b>.arora-browser.org/ + + + If the address is correct, try checking the network connection. + Уколико је адреса исправна, покушајте провером мрежне повезаности. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Уколико су ваш рачунар или мрежа заштићени фајерволом или проксијем постарајте се да прегледач има дозволе за приступ мрежи. + + + Resending POST request + Поново шаљем ПОСТ захтев + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Да би сајт био приказан, захтев заједно са свим подацима мора бити поново послат, што може довести до непредвидљивог понашања самог сајта, нпр. иста радња може бити поново изведена. Да ли свеједно желите да наставите? + + + + WebView + + Open in New &Window + Отвори у новом &прозору + + + Open in New &Tab + Отвори у новом &језичку + + + Save Lin&k + Сачувај &везу + + + &Bookmark This Link + &Маркирај ову везу + + + &Copy Link Location + &Копирај адресу везе + + + Open Image in New &Window + Отвори слику у новом &прозору + + + Open Image in New &Tab + Отвори слику у новом &језичку + + + &Save Image + &Сачувај слику + + + &Copy Image + &Копирај слику + + + C&opy Image Location + Kо&пирај адресу слике + + + Loading... + Учитавање... + + + Search with... + Претражи помоћу... + + + Add to the toolbar search + Додај у траку претраге + + + Method not supported + Метод није подржан + + + %1 method is not supported. + %1 метод није подржан. + + + Search engine + Мотор претраге + + + Choose the desired search engine + Изаберите жељени мотор претраге + + + Engine name + Назив мотора + + + Type in a name for the engine + Унесите назив за мотор + + + Block Image + Блокирај слику + + + + WebViewSearch + + Not Found + Не постоји + + + diff --git a/src/locale/sr_RS@latin.ts b/src/locale/sr_RS@latin.ts new file mode 100644 index 00000000..669ee89a --- /dev/null +++ b/src/locale/sr_RS@latin.ts @@ -0,0 +1,2050 @@ + + + + + AboutDialog + + About %1 + O %1 + + + Authors + Autori + + + License + Licenca + + + Lightweight WebKit-based web browser + Lagani web pregledač baziran na Webkit-u + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org/</a> + + + Close + Zatvori + + + WebKit version: %1 + Verzija Webkit-a: %1 + + + + AcceptLanguage + + Languages + Jezici + + + Languages: in order of preference: + Jezici prema redosledu poželjnosti: + + + Move &Up + &Gore + + + Move &Down + &Dole + + + &Remove + &Ukloni + + + Add... + Dodaj... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + Blokirano AdBlockovim pravilom: %1 + + + + AdBlockDialog + + Add Custom Rule + Dodaj prilagođeno pravilo + + + Learn more about writing rules... + Naučite više o pisanju pravila... + + + Update Subscription + Ažuriraj pretplatu + + + Browse Subscriptions... + Pregledaj pretplate... + + + Remove Subscription + Ukloni pretplatu + + + AdBlock Configuration + Podešavanje AdBlocka + + + Enable AdBlock + Omogući AdBlock + + + Action + Radnja + + + + AdBlockManager + + Custom Rules + Prilagođena pravila + + + + AdBlockModel + + Rule + Pravilo + + + + AdBlockSchemeAccessHandler + + Subscribe? + Pertplati se? + + + Subscribe to this AdBlock subscription? +%1 + Pretplati se na ovu AdBlockovu pretplatu? %1 + + + + AddBookmarkDialog + + Add Bookmark + Dodaj marker + + + Type a name for the bookmark, and choose where to keep it. + Unesite ime markera i izaberite gde ga sačuvati. + + + Url + URL + + + Title + Naslov + + + Add Folder + Dodaj fasciklu + + + + AutoFillDialog + + Form Passwords + Lozinke obrazaca + + + Remove + Ukloni + + + Remove All + Ukloni sve + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Želite li da sačuvate ovu lozinku</b><br> Da bi ste pregledali ili uklonili sačuvane lozinke koristite panel samopopunjavanja u podešavanjima. + + + Never for this site + Nikad za ovaj sajt + + + Not now + Ne sad + + + + AutoFillModel + + WebSite + Web sajt + + + User Name + Korisničko ime + + + + BookmarksDialog + + Open + Otvori + + + Open in New Tab + Otvori u novom jezičku + + + Edit Name + Uredi ime + + + Edit Address + Uredi adresu + + + Delete + Obriši + + + New Folder + Nova fascikla + + + Bookmarks + Markeri + + + &Remove + &Ukloni + + + Add Folder + Dodaj fasciklu + + + + BookmarksManager + + Bookmarks Bar + Traka markera + + + Bookmarks Menu + Meni markera + + + Error when loading bookmarks on line %1, column %2: +%3 + Greška pri učitavanju markera u redu %1, kolona %2: +%3 + + + Toolbar Bookmarks + Markeri u traci alatki + + + Menu + Meni + + + Open File + Otvori fajl + + + Imported %1 + Uvezeno %1 + + + Save File + Sačuvaj fajl + + + %1 Bookmarks.xbel + %1 Markeri.xbel + + + Export error + Greška pri izvozu + + + error saving bookmarks + greška pri čuvanju markera + + + Remove Bookmark + Ukloni marker + + + Insert Bookmark + Unesi marker + + + Name Change + Undo bookmark title change + Promena imena + + + Address Change + Undo bookmark url change + Promena adrese + + + XBEL bookmarks + XBEL markeri + + + HTML Netscape bookmarks + HTML Netscape markeri + + + htmlToXBel tool required + Neophodna je Html-U-XBEL alatka + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Html-U-XBEL alatka, koja se destavlja sa Arorom i neophodna je za uvoz HTML markera, nije instalirana ili se ne nalazi u pretraženim putanjama. + + + Loading Bookmark + Učitavam marker + + + Error when loading HTML bookmarks: %1 + + Greška pri učitavanju HTML markera: %1 + + + + + BookmarksMenu + + Open in Tabs + Otvori u jezičcima + + + + BookmarksModel + + Title + Naslov + + + Address + Adresa + + + + BookmarksToolBar + + Open + Otvori + + + Open in New &Tab + Otvori u novom &jezičku + + + Remove + Ukloni + + + Add Bookmark... + Dodaj marker... + + + Add Folder... + Dodaj fasciklu... + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Otvoreno je %1 prozor(a) i %2 jezičak(a) +Svejedno napustiti? + + + Restore failed + Povraćaj nije uspeo + + + Arora crashed while trying to restore this session. Should I try again? + Arora se srušila u pokušaju da povrati prethodnu sesiju. Pokušati ponovo? + + + + BrowserMainWindow + + &File + &Fajl + + + &New Window + Novi &prozor + + + &Open File... + &Otvori fajl... + + + Open &Location... + Otvori &lokaciju... + + + &Save As... + &Sačuvaj kao... + + + &Import Bookmarks... + &Uvezi markere... + + + &Export Bookmarks... + &Izvezi markere... + + + P&rint Preview... + P&regled štampe... + + + &Print... + Š&tampa... + + + Private &Browsing... + &Privatno pregledanje... + + + Close Window + Zatvori prozor + + + &Quit + &Napusti + + + &Edit + &Uređivanje + + + &Undo + &Opozovi + + + &Redo + &Ponovi + + + Cu&t + Ise&ci + + + &Copy + &Kopiraj + + + &Paste + &Nalepi + + + &Find + Nađ&i + + + Find Nex&t + Nađi &sledeće + + + Find P&revious + Nađi &prethodno + + + Ctrl+, + Ctrl+, + + + &View + Prika&z + + + Ctrl+| + Ctrl+| + + + Ctrl+/ + Ctrl+/ + + + Show Menu Bar + Prikaži traku menija + + + &Reload Page + Ponovo &učitaj stranicu + + + &Stop + &Zaustavi + + + Zoom &In + &Uvećaj + + + Zoom &Normal + Po&drazumevano uvećanje + + + Zoom &Out + &Umanji + + + Zoom &Text Only + Uvećaj samo &tekst + + + Page S&ource + I&zvorni kod stranice + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + &Ceo ekran + + + Hi&story + Ist&orijat + + + Back + Nazad + + + Forward + Napred + + + Home + Moja stranica + + + Restore Last Session + Povrati prethodnu sesiju + + + &Bookmarks + &Markeri + + + Show All Bookmarks... + Prikaži sve markere... + + + Add Bookmark... + Dodaj marker... + + + Add Folder... + Dodaj fasciklu... + + + &Window + &Prozor + + + &Tools + &Alatke + + + Web &Search + &Web pretraga + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + Očisti p&rivatne podatke + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Omogući &Web inspektor + + + &Help + Po&moć + + + Switch application language + Promeni jezik programa + + + About &Qt + O &Qt-u + + + About &%1 + About Browser + O &Arori + + + Navigation + Navigacija + + + Show Status Bar + Prikaži traku stanja + + + Hide Status Bar + Sakrij traku stanja + + + Show Toolbar + Prikaži traku alatki + + + Hide Toolbar + Sakrij traku alatki + + + Show Bookmarks Bar + Prikaži traku markera + + + Hide Bookmarks Bar + Sakrij traku markera + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Otvori web resurs + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Web resursi (*.html *.htm *.svg *.png *.gif *.svgz);;Svi fajlovi (*.*) + + + Print Document + Štampaj dokument + + + Are you sure you want to turn on private browsing? + Da li ste sigurni da želite da uključite privatno pregledanje? + + + Are you sure you want to close the window? There are %1 tabs open + Da li ste sigurni da želite da zatvorite prozor? Otvoren(o) je %1 jezičak(a) + + + Web Inspector + Web inspektor + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Web inspektor će ispravno raditi samo na stranicama učitanim nakon njegovog uključivanja. +Da li želite da ponovo učitate sve stranice? + + + Stop loading the current page + Zaustavi učitavanje trenutne stranice + + + Reload the current page + Ponovo učitaj trenutnu stranicu + + + Downloads + Prijemi + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Podrazumevano + + + Text Encoding + Kodiranje teksta + + + Alt+Ctrl+B + Alt+Ctrl+B + + + Select &All + Izaberi &sve + + + Options... + Opcije... + + + Configure Search Engines... + Podesi motore pretrage... + + + &Ad Block... + &AdBlock... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Kada je uključeno privatno pregledanje onemogućene su neke radnje koje se tiču vaše privatnosti: + + + Webpages are not added to the history. + Web stranice se ne dodaju u istorijat. + + + Items are automatically removed from the Downloads window. + Stavke se automatski uklanjaju iz prozora prijema. + + + New cookies are not stored, current cookies can't be accessed. + Novi kolačići se ne čuvaju, postojećim se ne može pristupiti. + + + Site icons won't be stored. + Ikone sajtova se ne čuvaju. + + + Session won't be saved. + Sesije se snimaju. + + + Searches are not added to the pop-up menu in the search box. + Pretrage se ne dodaju u iskačući meni prozorčića pretrage. + + + No new network cache is written to disk. + Mrežni keš se ne dopisuje na disk. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Dok ne zatvorite prozor i dalje možete kliknuti na „Napred“ i „Nazad“ da bi ste se vratili na prethodno otvarane stranice. + + + Private Browsing + Privatno pregledanje + + + + ClearButton + + Clear + Očisti + + + + ClearPrivateData + + Clear Private Data + Očisti privatne podatke + + + Clear the following items: + Očisti sledeće stavke: + + + &Browsing History + istorijat &pretrage + + + &Download History + istorijat p&reuzimanja + + + &Search History + istorijat pr&etrage + + + &Cookies + &kolačiće + + + C&ached Web Pages + Keširane &web stranice + + + Website &Icons + &ikone web sajtova + + + Clear &Private Data + Očisti privatne po&datke + + + &Cancel + &Odustani + + + + ClickToFlash + + Load + Učitaj + + + Load All + Učitaj sve + + + Add %1 to Whitelist + Dodaj %1 na belu listu + + + Remove from Whitelist + Ukloni sa bele liste + + + Settings + Podešavanje + + + Load Flash + Učitaj fleš + + + + ClickToFlashSettings + + Whitelist sites + Sajtovi na beloj listi + + + + CookieExceptionsModel + + Website + Web sajt + + + Rule + Pravilo + + + Allow + Dozvoli + + + Block + Blokiraj + + + Allow For Session + Dozvoli u toku sesije + + + + CookieModel + + Website + Web sajt + + + Name + Ime + + + Path + Putanja + + + Secure + Sigurno + + + Expires + Ističe + + + Contents + Sadržaj + + + true + tačno + + + false + netačno + + + Session cookie + Kolačić sesije + + + + CookiesDialog + + Cookies + Kolačići + + + &Remove + &Ukloni + + + Remove &All Cookies + Ukloni &sve kolačiće + + + Add &Rule + Dodaj &pravilo + + + + CookiesExceptionsDialog + + Cookie Exceptions + Izuzeci za kolačiće + + + New Exception + Novi izuzetak + + + Domain: + Domen: + + + Block + Blokiraj + + + Allow For Session + Dozvoli u toku sesije + + + Allow + Dozvoli + + + Exceptions + Izuzeci + + + &Remove + &Ukloni + + + Remove &All + Ukloni &sve + + + + DownloadDialog + + Downloads + Preuzimanja + + + Clean up + Očisti + + + 0 Items + Nema stavki + + + + DownloadItem + + Ico + Ikona + + + Filename + Ime fajla + + + Try Again + Pokušajte ponovo + + + Stop + Zaustavi + + + Open + Otvori + + + Save File + Sačuvaj fajl + + + Download canceled: %1 + Preuzimanje otkazano: %1 + + + Error opening output file: %1 + Greška pri otvaranju izlaznog fajla: %1 + + + Error saving: %1 + Greška pri čuvanju: %1 + + + Network Error: %1 + Greška na mreži: %1 + + + %1 of %2 (%3/sec) - %4 + %1 od %2 (%3/sek) - %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 od %2 - Zaustavljeno + + + Download directory (%1) couldn't be created. + Fascikla za preuzimanja (%1) ne može biti napravljena. + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + U toku su %1 preuzimanja +Svejedno napustiti? + + + %n Download(s) + + %n preuzimanje + %n preuzimanja + %n preuzimanja + + + + %n minutes remaining + + %n minut je preostao + %n minute su preostale + %n minuta je preostalo + + + + %n seconds remaining + + %n sekunda je preostala + %n sekunde su preostale + %n sekundi je preostalo + + + + bytes + bajtova + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Bez greške + + + Error opening: %1: No such file or directory + Greška pri otvaranju: %1: Ne postoji takav fajl ili fascikla + + + Unable to read %1 + Nemoguće čitanje %1 + + + Contents of %1 + Sadržaj %1 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + Otvori + + + Copy + Kopiraj + + + Delete + Obriši + + + History + Istorijat + + + &Remove + &Ukloni + + + Remove &All + Ukloni &sve + + + + HistoryMenu + + Show All History + Prikaži ceo istorijat + + + Clear History... + Očisti istorijat... + + + Clear History + Očisti istorijat + + + Do you want to clear the history? + Želite li da očistite istorijat? + + + + HistoryModel + + Title + Naziv + + + Address + Adresa + + + + HistoryTreeModel + + Earlier Today + Ranije u toku dana + + + %n item(s) + + %n stavka + %n stavke + %n stavki + + + + + JavaScriptAroraObject + + Welcome to Arora! + Dobrodošli u Aroru ! + + + Arora Start + Arorina početna + + + Search! + Pretraži! + + + Search results provided by + Rezultate pretrage omogućuje + + + About Arora + O Arori + + + + LanguageManager + + Choose language + Izaberite jezik + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Možete postaviti različit jezik od onog<br>koji operativni sistem podrazumeva.</p><p>Izaberite jezik koji ćete koristiti</p> + + + No translation files are installed at %1. + Nema instaliranih fajlova prevoda u %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Uredi korisničko ime i lozinku za "%1" na %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Poveži se na proksi "%1" koristeći: </qt> + + + - SSL Errors + - SSL greške + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Sertifikati:<br/>%1<br/>Da li želite da prihvatite sve ove sertifikate?</qt> + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL greške:<br/><br/>za: <tt>%1</tt><ul><li>%2</li></ul> +Da li želite da zanemarite ove greške?</qt> + + + Issuer: %1 + Izdavač: %1 + + + Not valid before: %1 + Nije valido pre: %1 + + + Valid until: %1 + Validno do: %1 + + + Alternate Names: + Alternativni nazivi: + + + + OpenSearchDialog + + Open File + Otvori fajl + + + OpenSearch + Otvori pretragu + + + Error + Greška + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 nije ispravan OpenSearch 1.1 opis ili se već nalazi na vašoj listi. + + + You must have at least one search engine in here. + Mora postojati barem jedan motor pretrage. + + + OpenSearch Manager + Ovori upravnik pretrage + + + &Restore Defaults + &Podrazumevano + + + &Delete + &Obriši + + + &Add + &Dodaj + + + &Close + &Zatvori + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Opis:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Daje predloge iz sadržaja</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Spisak zarezom razdvojenih ključnih reči koje mogu biti unete u traku lokacije zajedno sa izrazima sa pretragu u ovom motoru pretrage + + + Name + Ime + + + Keywords + Ključne reči + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Želite li da dodate sledeći motor na vašu listu motora pretrage? <br /><br />Ime: %1<br />Pretražuje na: %2 + + + + PasswordDialog + + Authentication Required + Neophodna autentifikacija + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Korisničko ime: + + + Password: + Lozinka: + + + + PlainTextEditSearch + + Not Found + Ne postoji + + + + ProxyDialog + + Proxy Authentication + Autentifikacija proksija + + + Connect to proxy + Poveži se na proksi + + + Username: + Korisničko ime: + + + Password: + Lozinka: + + + + QObject + + The file is not an XBEL version 1.0 file. + Fajl nije tipa XBEL 1.0. + + + Unknown title + Nepoznat naziv + + + The file is not an OpenSearch 1.1 file. + Fajl nije OpenSearch 1.1 tipa. + + + + SearchBanner + + Done + Završeno + + + Highlight All + Istakni sve + + + + SearchLineEdit + + Search + Pretraži + + + + Settings + + Preferences + Postavke + + + General + Opšte + + + On startup: + Pri pokretanju: + + + Show my home page + prikaži domaću stranicu + + + Show a blank page + prikaži praznu stranicu + + + Restore windows and tabs from last time + povrati prozore i jezičke od prošlog puta + + + Home Page: + Domaća stranica: + + + Set to current page + Postavi tekuću stranicu + + + Remove history items: + Ukloni stavke istorijata: + + + After one day + posle jednog dana + + + After one week + posle jedne sedmice + + + After two weeks + posle dve sedmice + + + After one month + posle jednog meseca + + + After one year + posle jedne godine + + + Manually + ručno + + + On application exit + pri napuštanju programa + + + Downloads + Preuzimanja + + + Ask for a destination each time + Uvek pitaj za odredište + + + Use this destination: + Koristi sledeće odredište: + + + Appearance + Izgled + + + Standard font: + Standardni font: + + + Select... + Izaberite... + + + Fixed-width font: + Fiksni font: + + + Preferred languages for viewing webpages in: + Poželjni jezici za pregledanje web stranica: + + + Privacy + Privatnost + + + Web Content + Web sadržaj + + + Block Popup Windows + Blokiraj iskačuće prozore + + + Enable Plugins + Omogući priključke + + + Use ClickToFlash on flash plugins + Koristi "Klikni za fleš" za fleš priključke + + + Enable Javascript + Omogući Javascript + + + View Images + Prikaži slike + + + Cookies + Kolačići + + + Accept Cookies: + Prihvati kolačiće: + + + Always + uvek + + + Never + nikad + + + Only from sites you navigate to + samo sa veb sajtova koje posećujem + + + Exceptions... + Izuzeci... + + + Keep Cookies Until: + Zadrži kolačiće dok ne: + + + They expire + isteknu + + + I exit the application + napustim program + + + At most 90 days + istekne najviše 90 dana + + + Cookies... + Kolačići... + + + Filter Tracking Cookies + Filtriraj kolačiće pratioce + + + Tabs + Jezičci + + + Select tabs and windows as they are created + Odaberi jezičke i prozore pri njihovom nastajanju + + + Confirm when closing multiple tabs or windows + Potvrda pri zatvaranju više prozora ili jezičaka + + + Show only one close button instead of one for each tab + Prikaži samo jedno dugme za zatvaranje umesto jednog po svakom jezičku + + + Quit the application when last tab is closed + Napusti program kad je poslednji jezičak zatvoren + + + Opening links + Otvaram veze + + + Links that want to open in a new window: + Veze koje žele da se otvore u novom prozoru: + + + In a new window + u novom prozoru + + + In a new selected tab in the current window + u izabranom novom jezičku trenutnog prozora + + + In a new tab in the current window + u novom jezičku trenutnog prozora + + + In the current tab + u trenutnom jezičku + + + Open links from applications: + Otvaraj veze iz programa: + + + Proxy + Proksi + + + Use proxy server + Koristi proksi server + + + Type: + Tip: + + + Socks5 + Socks5 + + + Http (Secure) + Http (Bezbedno) + + + Http (Transparent) + Http (Transparentno) + + + Host name: + Ime domaćina: + + + Port: + Port: + + + User Name: + Korisničko ime: + + + Password: + Lozinka: + + + Advanced + Napredno + + + Style Sheet: + Opis stila: + + + Enable network cache + Omogući mrežni keš + + + Maximum Size: + Maksimalna veličina: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Koristi podrazumevani motor pretrage kao ispomoć ukoliko je URL zadat od strane korisnika neispravan + + + Choose Directory... + Izaberite fasciklu... + + + A cookie session ends: + Sesija kolačića ističe: + + + When I exit the application + kad napustim program + + + 1 day + za 1 dan + + + 2 days + za 2 dana + + + 3 days + za 3 dana + + + 7 days + za 7 dana + + + 30 days + za 30 dana + + + AutoFill + Samopopunjavanje + + + AutoFill web forms: + Samopopunjavanje web obrazaca: + + + User names and passwords + Korisnička imena i lozinke + + + Edit... + Uredi... + + + Browse... + Pregledaj... + + + + SettingsDialog + + Restart required + Zahteva se ponovno pokretanje + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Podešavanje mrežnog keša je promenjeno. Da bi bilo uzeto u obzir pregledač mora biti ponovo pokrenut. + + + Choose Directory + Izaberite fasciklu + + + Choose CSS File + Izaberite CSS fajl + + + + SourceViewer + + Loading... + Učitavanje... + + + &Edit + &Uređivanje + + + &Find + Nađ&i + + + Source of Page %1 + Izvorni kod stranice %1 + + + + TabBar + + Show Tab Bar + Prikaži traku jezičaka + + + Hide Tab Bar + Sakrij traku jezičaka + + + Duplicate Tab + Dupliraj jezičak + + + &Close Tab + &Zatvori jezičak + + + Close &Other Tabs + Zatvori &ostale jezičke + + + Reload Tab + Ponovo učitaj jezičak + + + Reload All Tabs + Ponovo učitaj sve jezičke + + + + TabWidget + + Untitled + Neimenovano + + + Saved Tabs + Sačuvaj jezičke + + + Do you really want to close this page? + Da li zaista želite da zatvorite ovu stranicu? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Izmenili ste ovu stranicu i njenim zatvaranjem ćete izgubiti izmene. +Da li zaista želite da zatvorite ovu stranicu? + + + + Loading... + Učitavanje... + + + Loading %1% (%2 %3)... + Učitavam %1% (%2 %3)... + + + Finished loading + Učitavanje završeno + + + Failed to load + Greška pri učitavanju + + + Show Next Tab + Prikaži naredni jezičak + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + Prikaži prethodni jezičak + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + Nedavno zatvoreni jezičci + + + New &Tab + Novi &jezičak + + + &Close Tab + &Zatvori jezičak + + + Bookmark All Tabs + Markiraj sve jezičke + + + + ToolbarSearch + + Suggestions + Predlozi + + + No Recent Searches + Nema skorašnjih pretraga + + + Recent Searches + Skorašnje pretrage + + + Add '%1' + Dodaj '%1' + + + Clear Recent Searches + Ukloni skorašnje pretrage + + + + WebPage + + Error loading page: %1 + Greška pri učitavanju stranice: %1 + + + When connecting to: %1. + Pri povezivanju na: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Proverite adresu za greške poput <b>ww/</b>.arora-browser.org/ /umesto <b>www/</b>.arora-browser.org/ + + + If the address is correct, try checking the network connection. + Ukoliko je adresa ispravna, pokušajte proverom mrežne povezanosti. + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Ukoliko su vaš računar ili mreža zaštićeni fajervolom ili proksijem postarajte se da pregledač ima dozvole za pristup mreži. + + + Resending POST request + Ponovo šaljem POST zahtev + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Da bi sajt bio prikazan, zahtev zajedno sa svim podacima mora biti ponovo poslat, što može dovesti do nepredvidljivog ponašanja samog sajta, npr. ista radnja može biti ponovo izvedena. Da li svejedno želite da nastavite? + + + + WebView + + Open in New &Window + Otvori u novom &prozoru + + + Open in New &Tab + Otvori u novom &jezičku + + + Save Lin&k + Sačuvaj &vezu + + + &Bookmark This Link + &Markiraj ovu vezu + + + &Copy Link Location + &Kopiraj adresu veze + + + Open Image in New &Window + Otvori sliku u novom &prozoru + + + Open Image in New &Tab + Otvori sliku u novom &jezičku + + + &Save Image + &Sačuvaj sliku + + + &Copy Image + &Kopiraj sliku + + + C&opy Image Location + Ko&piraj adresu slike + + + Loading... + Učitavanje... + + + Search with... + Pretraži pomoću... + + + Add to the toolbar search + Dodaj u traku pretrage + + + Method not supported + Metod nije podržan + + + %1 method is not supported. + %1 metod nije podržan. + + + Search engine + Motor pretrage + + + Choose the desired search engine + Izaberite željeni motor pretrage + + + Engine name + Naziv motora + + + Type in a name for the engine + Unesite naziv za motor + + + Block Image + Blokiraj sliku + + + + WebViewSearch + + Not Found + Ne postoji + + + diff --git a/src/locale/tr_TR.ts b/src/locale/tr_TR.ts new file mode 100644 index 00000000..f7a91cb5 --- /dev/null +++ b/src/locale/tr_TR.ts @@ -0,0 +1,2372 @@ + + + + + AboutDialog + + Lightweight WebKit-based web browser + Webkit tabanlı hafif bir web tarayıcı + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Authors + Yazarlar + + + License + Lisans + + + Close + Kapat + + + About + Hakkında + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + About %1 + %1 Hakkında + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + WebKit sürümü: %1 + + + + AcceptLanguage + + Languages + Diller + + + Languages: in order of preference: + Diller: tercih sırasına göre: + + + Move &Up + &Yukarı Taşı + + + Move &Down + &Aşağı Taşı + + + &Remove + &Kaldır + + + Add... + Ekle... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + AdBlockRule: %1 tarafından engellendi + + + + AdBlockDialog + + Add Custom Rule + Özel Kural Ekle + + + Learn more about writing rules... + Kural oluşturmak hakkında daha fazla bilgi... + + + Update Subscription + Aboneliği Güncelle + + + Browse Subscriptions... + Aboneliklere Gözat... + + + Remove Subscription + Aboneliği Kaldır + + + AdBlock Configuration + AdBlock Tercihleri + + + Enable AdBlock + AdBlock Kullan + + + Action + Eylem + + + + AdBlockManager + + Custom Rules + Özel Kurallar + + + + AdBlockModel + + Rule + Kural + + + + AdBlockSchemeAccessHandler + + Subscribe? + Abone Ol? + + + Subscribe to this AdBlock subscription? +%1 + Bu AdBlock aboneliğini kullan ? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Yer İmlerine Ekle + + + Type a name for the bookmark, and choose where to keep it. + Yer imi için bir ad girin ve nerede saklanacağını belirtin. + + + Url + Url + + + Title + Başlık + + + Add Folder + Dizin Ekle + + + + AutoFillDialog + + Form Passwords + Form Parolaları + + + Remove + Kaldır + + + Remove All + Hepsini Kaldır + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Bu parolayı saklamak ister misiniz?</b><br> Kayıtlı parolalarınızı düzenlemek için Otomatik Doldur seçeneklerinne gidin. + + + Never for this site + Bu site için hiç bir zaman + + + Not now + Şimdi değil + + + + AutoFillModel + + WebSite + Site + + + User Name + Kullanıcı Adı + + + + BookmarksDialog + + Bookmarks + Yer İmleri + + + &Remove + &Sil + + + Add Folder + Dizin Ekle + + + Open + + + + Open in New Tab + Yeni Sekmede Aç + + + Delete + Sil + + + New Folder + Yeni Dizin + + + Edit Name + İsmi Düzenle + + + Edit Address + Adresi Düzenle + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Satır %1, sütun %2'deki yerimini yüklerken hata oluştu: +%3 + + + Toolbar Bookmarks + Yer İmleri Araç Çubuğu + + + Menu + Menü + + + Open File + Dosya Aç + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + %1 İçe Aktarıldı + + + Save File + Dosyayı Kaydet + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Dışa aktarım hatası + + + error saving bookmarks + yer imlerini saklarken hata oluştu + + + Remove Bookmark + Yer İmini Sil + + + Insert Bookmark + Yer İmini Araya Ekle + + + Name Change + İsim Değiştir + + + Address Change + Adres Değiştir + + + Bookmarks Bar + Yerimleri Çubuğu + + + Bookmarks Menu + Yerimleri Menüsü + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Html yerimlerini yüklerken hata: %1 + + + + XBEL + XBEL + + + Name Change + Undo bookmark title change + İsim Değiştir + + + Address Change + Undo bookmark url change + Adres Değiştir + + + XBEL bookmarks + XBEL yerimleri + + + HTML Netscape bookmarks + HTML Netscape yerimleri + + + htmlToXBel tool required + htmlToXBel aracı gerekli + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + HTML yerimlerini içe aktarmak için Arora ile dağıtılan gerekli htmlToXBel aracı yüklü değil ya da bulunamadı. + + + Loading Bookmark + Yerimleri Yükleniyor + + + Error when loading HTML bookmarks: %1 + + HTML yerimleri yüklenirken bir hata oluştu: %1 + + + + + BookmarksMenu + + Open in Tabs + Sekmede Aç + + + + BookmarksModel + + Title + Başlık + + + Address + Adres + + + + BookmarksToolBar + + Bookmark + Yer İmi + + + Open + + + + Open in New &Tab + &Yeni Sekmede Aç + + + Remove + Kaldır + + + Add Bookmark... + Yer İmi Ekle... + + + Add Folder... + Dizin Ekle... + + + Bookmarks + Yer İmleri + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + %1 pencere ve %2 sekme açık bulunuyor +Yinede çıkmak istiyor musunuz? + + + Restore failed + Geri yükleme başarısız + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Kaydolan oturum geri yüklenemeyecek çünkü Arora oturumu geri yüklerken çöktü. + + + (Change: %1 %2) + (Değişim: %1 %2) + + + Arora crashed while trying to restore this session. Should I try again? + Arora bu oturumu kurtarmaya çalışırken çöktü. Tekrar denensin mi? + + + + BrowserMainWindow + + &File + Do&sya + + + &New Window + &Yeni Pencere + + + &Open File... + Dosya &Aç... + + + Open &Location... + Kon&umu Aç... + + + &Save As... + &Farklı Kaydet... + + + &Import Bookmarks... + Yeri&mlerini İçe Aktar... + + + &Export Bookmarks... + Yerimlerini Dı&şa Aktar... + + + P&rint Preview... + Baskı &Önizleme... + + + &Print... + Ya&zdır... + + + Private &Browsing... + Özel Gez&inme... + + + &Quit + &Çıkış + + + &Edit + D&üzenle + + + &Undo + &Geri Al + + + &Redo + &İleri Al + + + Cu&t + &Kes + + + &Copy + K&opyala + + + &Paste + &Yapıştır + + + &Find + &Bul + + + Find &Next + &Sonrakini Bul + + + Find P&revious + &Öncekini Bul + + + Prefe&rences + Te&rcihler + + + Ctrl+, + Ctrl+, + + + &View + &Görünüm + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Dur + + + &Reload Page + &Sayfayı Yeniden Yükle + + + Make Text &Bigger + &Yazıyı Büyüt + + + Make Text &Normal + Yazıyı &Normal Yap + + + Make Text &Smaller + Yazıyı K&üçült + + + Page S&ource + Sayfa Kayna&ğı + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + Tam Ek&ran + + + Hi&story + Ge&çmiş + + + Back + Geri + + + Forward + İleri + + + Home + Ev + + + Restore Last Session + En Son Oturumu Geri Yükle + + + &Bookmarks + &Yer İmleri + + + Manage Bookmarks... + Yer İmlerini Düzenle... + + + Add Bookmark... + Yer İmi Ekle... + + + &Window + &Pencere + + + &Tools + &Araçlar + + + Web &Search + &Arama + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Özel Verileri Temizle + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Ağ Denet&çisini Aktif Et + + + &Help + Yard&ım + + + About &Qt + &Qt Hakkında + + + About &Arora + &Arora Hakkında + + + Navigation + Gezinme + + + Show Status Bar + Durum Çubuğunu Göster + + + Hide Status Bar + Durum Çubuğunu Gizle + + + Show Toolbar + Araç Çubuğunu Göster + + + Hide Toolbar + Araç Çubuğunu Gizle + + + Show Bookmarks Bar + Yerimi Araç Çubuğunu Göster + + + Hide Bookmarks Bar + Yerimi Araç Çubuğunu Gizle + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + Ağ Kaynağını Aç + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Sayfa Kaynakları (*.html *.htm *.svg *.png *.gif *.svgz);;Tüm Dosyalar (*.*) + + + Print Document + Belgeyi Yazdır + + + Are you sure you want to turn on private browsing? + Gizli gezinmeyi açmak istediğinizden emin misiniz? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Gizli gezinme aktifken, sizin gizliliğinizle bağlantılı olan bazı davranışlar iptal edilecektir:<ul><li> Web sayfaları geçmişe eklenmeyecekler.</li><li> İndirme penceresindeki öğeler otomatik olarak silinecekler.</li><li> Yeni çerezler saklanmayacak, mevcut çerezlere erişim sağlanmayacaktır.</li><li> Sayfa ikonları saklanmayacak, oturum kaydedilmeyecektir.</li><li> Aramalar, arama kutusundaki açılır menüye eklenmeyecektir.</li></ul>Siz pencereyi kapatana kadar, açtığınız web sayfasına geri dönmek için İleri ve Geri düğmelerine tıklayabileceksiniz. + + + Are you sure you want to close the window? There are %1 tabs open + Pencereyi kapatmak istediğinizden emin misiniz? %1 sekme açık + + + Page Source of %1 + %1'in Sayfa Kaynağı + + + Web Inspector + Ağ Denetçisi + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Ağ Denetçisi sadece aktif edildikten sonra yüklenen sayfalarda düzgün çalışacaktır. +Tüm sayfaları yenilemeyi istiyor musunuz? + + + Stop loading the current page + Mevcut sayfayı yüklemeyi durdur + + + Reload the current page + Mevcut sayfayı yenile + + + Downloads + İndirilenler + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + Find Nex&t + Sonra&kini Bul + + + Prefere&nces... + Se&çenekler... + + + Show Menu Bar + Menü Çubuğunu Göster + + + Switch application language + Uygulama dilini değiştir + + + Show &Network Monitor + A&ğ İzleyicisini Göster + + + Close Window + Pencereyi Kapat + + + Zoom &In + &Yaklaş + + + Zoom &Normal + &Normal + + + Zoom &Out + &Uzaklaş + + + Zoom &Text Only + Sadece &Metni Yakınlaştır + + + Show All Bookmarks... + Tüm Yerimlerini Göster... + + + Add Folder... + Dizin Ekle... + + + About &%1 + About Browser + &%1 Hakkında + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Özel gezinme aktif olduğunda, gizliliğinizle ilgili bazı eylemler etkisizleştirilecek:<ul><li> Web sayfaları geçmişe eklenmeyecek.</li><li> İndirme penceresindeki öğeler otomatik olarak kaldırılacak.</li><li> Yeni çerezler saklanmayacak, mevcut çerezlere erişilemeyecek.</li><li> Sayfa simgeleri saklanmayacak, oturum kaydedilmeyecek.</li><li> Aramalarınız arama kutusundaki açılır menüye eklenmeyecek.</li></ul>Siz pencereyi kapatana kadar, açmış olduğunu web sayfalarına Geri ve İleri düğmelerine tıklayarak geri dönebileceksiniz. + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Varsayılan + + + Text Encoding + Karakter Kodlaması + + + Select &All + Hepsini &Seç + + + Alt+Ctrl+B + Alt+Ctrl+B + + + Options... + Tercihler... + + + Configure Search Engines... + Arama Motorlarını Yapılandır... + + + &Ad Block... + &Ad Block... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Özel gezinme açıkken gizliliğinizle ilgili bazı eylemler kaydedilmeyecektir: + + + Webpages are not added to the history. + Sayfalar geçmişe eklenmeyecek. + + + Items are automatically removed from the Downloads window. + İndirilen öğeler otomatik olarak kaldırılacak. + + + New cookies are not stored, current cookies can't be accessed. + Yeni çerezler kaydedilmeyecek, mevcut çerezler kullanılmayacak. + + + Site icons won't be stored. + Site ikonları kaydedilmeyecek. + + + Session won't be saved. + Oturumunuz kaydedilmeyecek. + + + Searches are not added to the pop-up menu in the search box. + Arama kaydınız tutulmayacak. + + + No new network cache is written to disk. + Ağ önbelleği tutulmayacak. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Pencereyi kapatana kadar, İleri ve Geri tuşları ile açtığınız sayfalar arasında gezinmeye devam edebilirsiniz. + + + Private Browsing + Özel Gezinme + + + + ClearButton + + Clear + Temizle + + + + ClearPrivateData + + Clear Private Data + Özel Verileri Temizle + + + Clear the following items: + Aşağıdaki öğeleri temizle: + + + &Browsing History + &Gezinme Geçmişi + + + &Download History + &İndirilenler Geçmişi + + + &Search History + &Arama Geçmişi + + + &Cookies + &Çerezler + + + C&ached Web Pages + &Önbelleğe alınmış Web Sayfaları + + + Website &Icons + Web Sayfası S&imgeleri + + + Clear &Private Data + Özel Verileri Te&mizle + + + &Cancel + &İptal + + + + ClickToFlash + + Load + Yükle + + + Load All + Hepsini Yükle + + + Add %1 to Whitelist + %1 i aklisteye ekle + + + Remove from Whitelist + Aklisteden kaldır + + + Settings + Ayarlar + + + Load Flash + Flash Yükle + + + + ClickToFlashSettings + + Whitelist sites + Akliste siteleri + + + + CookieExceptionsModel + + Website + Web Sayfası + + + Rule + Kural + + + Allow + İzin Ver + + + Block + Kısıtla + + + Allow For Session + Bu Oturum İçin İzin Ver + + + + CookieModel + + Website + Web Sayfası + + + Name + İsim + + + Path + Yol + + + Secure + Güvenli + + + Expires + Sonlanma + + + Contents + İçerik + + + true + doğru + + + false + yanlış + + + Session cookie + Oturum çerezi + + + + CookiesDialog + + Cookies + Çerezler + + + &Remove + &Kaldır + + + Remove &All Cookies + Tüm Çerezleri Kaldı&r + + + Add &Rule + &Kural Ekle + + + + CookiesExceptionsDialog + + Cookie Exceptions + Çerez İstisnaları + + + New Exception + Yeni İstisna + + + Domain: + Etki Alanı: + + + Block + Blok + + + Allow For Session + Bu Oturuma İzin Ver + + + Allow + İzin Ver + + + Exceptions + İstisnalar + + + &Remove + &Kaldır + + + Remove &All + Hepsini Kaldı&r + + + + DownloadDialog + + Downloads + İndirilenler + + + Clean up + Temizle + + + 0 Items + 0 Öğe + + + &OK + &Tamam + + + + DownloadItem + + Form + Form + + + Ico + Ico + + + Filename + Dosyaadı + + + Try Again + Yeniden Dene + + + Stop + Dur + + + Open + + + + Save File + Dosyayı Kaydet + + + Download canceled: %1 + İndirme iptal edildi: %1 + + + Error opening output file: %1 + Çıktı dosyası açılırken hata oluştu: %1 + + + Error saving: %1 + Kaydederken hata oluştu: %1 + + + Network Error: %1 + Ağ Hatası: %1 + + + seconds + saniye + + + %1 of %2 (%3/sec) %4 + %2'nin %1'i (%3/sn) %4 + + + ? + ? + + + %1 of %2 - Stopped + %2'nin %1'i - Durdu + + + bytes + byte + + + kB + kB + + + MB + MB + + + - %n minutes remaining + + - %n dakika kaldı + + + + - %n seconds remaining + + - %n saniye kaldı + + + + %1 of %2 (%3/sec) - %4 + %1 / %2 (%3/sn) - %4 + + + Download directory (%1) couldn't be created. + İndirilenler klasörü (%1) oluşturulamadı. + + + + DownloadManager + + %n Download(s) + + %n İndirilen + + + + There are %1 downloads in progress +Do you want to quit anyway? + %1 indirme işlemi var +Yine de çıkmak istiyor musunuz? + + + %n minutes remaining + + %n dakika kaldı + + + + %n seconds remaining + + %n saniye kaldı + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + Hata Yok + + + Error opening: %1: No such file or directory + Hata ! Böyle bir dosya ya da dizin bulunamadı: %1 + + + Unable to read %1 + %1 Okunamıyor + + + Contents of %1 + %1 İçeriği + + + %1 KB + %1 KB + + + + HistoryDialog + + History + Geçmiş + + + &Remove + &Kaldır + + + Remove &All + &Hepsini Kaldır + + + Open + + + + Copy + Kopyala + + + Delete + Sil + + + + HistoryMenu + + Show All History + Tüm Geçmişi Göster + + + Clear History + Geçmişi Temizle + + + Clear History... + Geçmişi Temizle... + + + Do you want to clear the history? + Geçmişi temizlemek istiyor musunuz? + + + + HistoryModel + + Title + Başlık + + + Address + Adres + + + + HistoryTreeModel + + Earlier Today + Bugünden Önce + + + %n item(s) + + %n öğe + + + + + JavaScriptAroraObject + + Welcome to Arora! + Arora'ya Hoş Geldiniz! + + + Arora Start + Arora Başlangıç + + + Search! + Ara! + + + Search results provided by + Arama sonuçlarını sağlayan + + + About Arora + Arora Hakkında + + + + LanguageManager + + System locale (%1) %2 + Sistem yereli (%1) %2 + + + Choose language + Dil Seçiniz + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>İşletim sisteminin varsayılan dilinden<br>başka bir dil seçebilirsiniz.</p><p>Lütfen kullanılacak dili seçini</p> + + + No translation files are installed. + Hiç çeviri dosyası yüklenmemiş. + + + No translation files are installed at %1. + %1 konumunda herhangi bir dil dosyası bulunamadı. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>%2 deki %1 için kullanıcı adı ve parola girin</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>Vekil "%1" 'e bunu kullanarak bağlan:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + SSL Hataları: + +%1 + +%2 + +Bu hataları gözardı etmek istiyor musunuz? + + + Do you want to accept all these certificates? + Tüm bu sertifikaları kabul etmek istiyor musunuz? + + + - SSL Errors + - SSL Hataları + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL Hataları:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Bu hataları görmezden gelmek istiyor musunuz?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Sertifikalar:<br/>%1<br/>Tüm bu sertifikaları kabul etmek istiyor musunuz?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Sertifikalar:<br/>%1<br/>Tüm bu sertifikaları kabul etmek istiyor musunuz?</qt> + + + Issuer: %1 + Hata: %1 + + + Not valid before: %1 + Şundan önce geçersiz: %1 + + + Valid until: %1 + Şuna kadar geçerli: %1 + + + Alternate Names: + Alternatif İsimler: + + + + NetworkMonitor + + Name + İsim + + + Value + Değer + + + + NetworkMonitorDialog + + Network Monitor + Ağ İzleyici + + + Network Requests + Ağ İstekleri + + + Request Headers + İstek Başlıkları + + + Response Headers + Yanıt Başlıkları + + + &Remove + &Kaldır + + + Remove &All Requests + &Tüm İstekleri Kaldır + + + + OpenSearchDialog + + Open File + Dosya Aç + + + OpenSearch + OpenSearch + + + Error + Hata + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 geçerli bir OpenSearch 1.1 açıklaması değil ya da zaten listenizde bulunuyor. + + + You must have at least one search engine in here. + Burada en az bir arama motoru olmalı. + + + OpenSearch Manager + OpenSearch Yöneticisi + + + &Restore Defaults + &Öntanımlıları Geri Yükle + + + &Delete + &Sil + + + &Add + &Ekle + + + &Close + &Kapat + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Açıklama:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>İçeriksel öneriler sağlar</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + İsim + + + Keywords + Anahtar Kelimeler + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Aşağıdaki motoru arama motoru listenize eklemek istiyor musunuz?<br /><br />İsim: %1<br />Şurada arar: %2 + + + + PasswordDialog + + Authentication Required + Kimlik Denetimi Gerekli + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Kullanıcı Adı: + + + Password: + Parola: + + + + PlainTextEditSearch + + Not Found + Bulunamadı + + + + ProxyDialog + + Proxy Authentication + Vekil Kimlik Denetimi + + + ICON + ICON + + + Connect to proxy + Proxy'e bağlan + + + Username: + Kullanıcı adı: + + + Password: + Parola: + + + + QObject + + The file is not an XBEL version 1.0 file. + Dosya bir XBEL sürüm 1.0 dosyası değil. + + + Unknown title + Bilinmeyen başlık + + + The file is not an OpenSearch 1.1 file. + Bu dosya bir OpenSearch 1.1 dosyası değil. + + + + RequestModel + + Redirect: %1 + Yönlendir: %1 + + + Method + Metod + + + Address + Adres + + + Response + Yanıt + + + Length + Uzunluk + + + Content Type + İçerik Türü + + + Info + Bilgi + + + + SearchBanner + + Form + Form + + + TextLabel + TextLabel + + + < + < + + + > + > + + + Done + Bitti + + + Highlight All + Hepsini Vurgula + + + + SearchLineEdit + + Search + Ara + + + + Settings + + Preferences + Tercihler + + + General + Genel + + + On startup: + Açılışta: + + + Show my home page + Giriş sayfamı göster + + + Show a blank page + Boş bir sayfa göster + + + Restore windows and tabs from last time + En son açık olan pencere ve sekmeleri geri yükle + + + Home Page: + Giriş Sayfası: + + + Set to current page + Mevcut sayfayı ayarla + + + Remove history items: + Geçmiş öğeleri kaldır: + + + After one day + Bir gün sonra + + + After one week + Bir hafta sonra + + + After two weeks + İki hafta sonra + + + After one month + Bir ay sonra + + + After one year + Bir yıl sonra + + + Manually + Elle + + + On application exit + Uygulama kapanırken + + + Open links from applications: + Uygulamalardaki bağlantıları aç: + + + In a tab in the current window + Mevcut penceredeki bir sekmede + + + In a new window + Yeni pencerede + + + Downloads + İndirilenler + + + Ask for a destination each time + Her seferinde hedefi sor + + + Use this destination: + Bu hedefi kullan: + + + Appearance + Görünüm + + + Standard font: + Standart yazıtipi: + + + Times 16 + Times 16 + + + Select... + Seç... + + + Fixed-width font: + Sabit-genişlikli yazıtipi: + + + Courier 13 + Courier 13 + + + Privacy + Gizlilik + + + Web Content + Web İçeriği + + + Enable Plugins + Eklentileri Aktif Et + + + Enable Javascript + Javascript'i Aktif Et + + + View Images + Görüntüleri Göster + + + Cookies + Çerezler + + + Accept Cookies: + Çerezleri Kabul Et: + + + Always + Herzaman + + + Never + Asla + + + Only from sites you navigate to + Sadece şu sayfalarda gezinirken + + + Exceptions... + İstisnalar... + + + Keep Cookies Until: + Çerezleri Tut: + + + They expire + Süresi dolunca + + + I exit the application + Uygulamadan çıkarken + + + At most 90 days + En fazla 90 gün + + + Cookies... + Çerezler... + + + Tabs + Sekmeler + + + Select tabs and windows as they are created + Pencere ve sekmeleri oluşturulduklarında seç + + + Confirm when closing multiple tabs + Çoklu sekmeleri kapatırken onay iste + + + Proxy + Vekil Sunucu + + + Use proxy server + Vekil sunucu kullan + + + Type: + Tür: + + + Socks5 + Socks5 + + + Http + Http + + + Host name: + Sunucu adı: + + + Port: + Port: + + + User Name: + Kullanıcı Adı: + + + Password: + Parola: + + + Advanced + Gelişmiş + + + Style Sheet: + Style Sheet: + + + Show only one close button instead of one for each tab + Her sekmede göstermek yerine tek bir kapatma düğmesi göster + + + Preferred languages for viewing webpages in: + Web sayfalarını gezinirken tercih edilecek dil: + + + Block Popup Windows + Açılır Pencereleri Engelle + + + Opening links + Bağlantıların açılması + + + Links that want to open in a new window: + Yeni pencerede açılması istenilen bağlantılar: + + + In a new selected tab in the current window + Mevcut pencerede seçilmiş yeni bir sekmede + + + In a new tab in the current window + Mevcut pencerede yeni bir sekmede + + + In the current tab + Mevcut sekmede + + + Http (Secure) + Http (Güvenli) + + + Http (Transparent) + Http (Transparent) + + + Use ClickToFlash on flash plugins + Flash eklentilerinde ClickToFlash kullan + + + Filter Tracking Cookies + Çerezleri Filtrele + + + Confirm when closing multiple tabs or windows + Birden çok pencere ve sekme kapatılırken doğrula + + + Quit the application when last tab is closed + Son sekme kapatıldığında uygulamayı kapat + + + Enable network cache + Ağ önbelleğini etkinleştir + + + Maximum Size: + Azami Boyut: + + + MB + MB + + + Use the default search engine as fallback when the URL given by the user is invalid + Girilen adres geçersizse varsayılan arama motoru ile arama yap + + + Choose Directory... + Dizin Seç... + + + A cookie session ends: + Çerez Oturumlarını Sil: + + + When I exit the application + Uygulama kapanınca + + + 1 day + 1 gün sonra + + + 2 days + 2 gün sonra + + + 3 days + 3 gün sonra + + + 7 days + 7 gün sonra + + + 30 days + 30 gün sonra + + + AutoFill + Otomatik Doldur + + + AutoFill web forms: + Formları Otomatik Doldur: + + + User names and passwords + Kullanıcı adları ve parolalar + + + Edit... + Düzenle... + + + Browse... + Gözat... + + + + SettingsDialog + + Restart required + Yeniden başlatmak gerekiyor + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Ağ önbelleği yapılandırması değişti. İşleme alınması için tarayıcının yeniden başlatılması gerekiyor. + + + Choose Directory + Dizin Seç + + + Choose CSS File + CSS Dosyası Seç + + + + SourceViewer + + Loading... + Yükleniyor... + + + &Edit + D&üzenle + + + &Find + &Bul + + + Source of Page + Sayfanın Kaynağı + + + &View + &Görünüm + + + &Wrap lines + Satırları &kaydır + + + Source of Page %1 + %1 Sayfasının Kaynağı + + + + TabBar + + Show Tab Bar + Sekme Çubuğunu Göster + + + Hide Tab Bar + Sekme Çubuğunu Gizle + + + New &Tab + Yeni Se&kme + + + Duplicate Tab + Sekmeyi Kopyala + + + &Close Tab + Sekmeyi K&apat + + + Close &Other Tabs + Diğer Sekmeleri Kapa&t + + + Reload Tab + Sekmeyi Yeniden Yükle + + + Reload All Tabs + Tüm Sekmeleri Yeniden Yükle + + + + TabWidget + + New &Tab + Yeni Sek&me + + + &Close Tab + Sekmeyi K&apat + + + Show Next Tab + Sonraki Sekmeyi Göster + + + Show Previous Tab + Önceki Sekmeyi Göster + + + Recently Closed Tabs + Yeni Kapatılan Sekmeler + + + (Untitled) + (Başlıksız) + + + Do you really want to close this page? + Bu sayfayı gerçekten kapatmayı istiyor musunuz? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Bu sayfada düzenleme yaptınız ve eğer kapatırsanız tüm düzenlemelerinizi kaybedeceksiniz. +Bu sayfayı gerçekten kapatmayı istiyor musunuz? + + + + Untitled + Başlıksız + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Saklanan Sekmeler + + + Loading... + Yükleniyor... + + + Loading %1% (%2 %3)... + Yükleniyor %1% (%2 %3)... + + + Finished loading + Yükleme bitti + + + Failed to load + Yükleme başarısız + + + Bookmark All Tabs + Tüm Sekmeleri Yerimlerine Ekle + + + + ToolbarSearch + + No Recent Searches + Yeni Arama Yok + + + Recent Searches + Yeni Aramalar + + + Clear Recent Searches + En Son Aramaları Temizle + + + Suggestions + Öneriler + + + Add '%1' + %1 Ekle + + + Configure Search Engines... + Arama Motorlarını Yapılandır... + + + + WebPage + + Error loading page: %1 + Sayfayı yüklerken hata: %1 + + + When connecting to: %1. + Bağlanırken: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + <b>www</b>.arora-browser.org yerine <b>ww</b>.arora-browser.org şeklindeki adres hatalarını kontrol edin + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Ağınız ya da bilgisayarınız güvenlik duvarı veya vekil sunucu ile korunuyorsa, tarayıcınızın ağ erişimine izin verildiğinden emin olunuz. + + + If the address is correct, try checking the network connection. + Adres doğruysa, ağ bağlantınızı kontrol etmeyi deneyin. + + + Resending POST request + POST isteği yeniden gönderiliyor + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Bu sayfayı göstermek için daha önce gerçekleştirilen eylemler (ör. arama emri ) tekrarlanacak ve bilgiler yeniden gönderilecek. Devam etmek istiyor musunuz ? + + + + WebView + + Open in New &Window + Yeni &Pencerede Aç + + + Open in New &Tab + &Yeni Sekmede Aç + + + Save Lin&k + &Bağlantıyı Kaydet + + + &Bookmark This Link + &Bu Bağlantıyı Yerimlerine Ekle + + + &Copy Link Location + Bağlantının Konumunu &Kopyala + + + Open Image in New &Window + Görüntüyü Yeni &Pencerede Aç + + + Open Image in New &Tab + &Görüntüyü Yeni Sekmede Aç + + + &Save Image + G&örüntüyü Kaydet + + + &Copy Image + G&örüntüyü Kopyala + + + C&opy Image Location + Gö&rüntünün Konumunu Kopyala + + + Loading... + Yükleniyor... + + + Search with... + Şununla ara... + + + Add to the toolbar search + Araç çubuğu aramasına ekle + + + Method not supported + Metod desteklenmiyor + + + %1 method is not supported. + method desteklenmiyor: %1 . + + + Search engine + Arama motoru + + + Choose the desired search engine + Kullanmak istediğiniz arama motorunu seçin + + + Engine name + Arama motoru adı + + + Type in a name for the engine + Arama motoru için bir ad belirtin + + + Block Image + Resimleri Engelle + + + + WebViewSearch + + Not Found + Bulunamadı + + + diff --git a/src/locale/uk.ts b/src/locale/uk.ts new file mode 100644 index 00000000..85c9bcb1 --- /dev/null +++ b/src/locale/uk.ts @@ -0,0 +1,2444 @@ + + + + + AboutDialog + + About + Про програму + + + Authors + Автори + + + License + Ліцензія + + + Lightweight WebKit-based web browser + Легкий переглядач тенет, оснований на WebKit + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2008 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + Закрити + + + About %1 + Про %1 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"><html><head><meta name="qrichtext" content="1" /><style type="text/css">p, li { white-space: pre-wrap; }</style></head><body style="font-size:9pt;"><p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + WebKit version: %1 + Версія WebKit: %1 + + + + AcceptLanguage + + Languages + Мови + + + Languages: in order of preference: + Мови: в порядку застосування: + + + Move &Up + Перемістити &вище + + + Move &Down + Перемістити &нижче + + + &Remove + &Вилучити + + + Add... + Додати... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + AdBlockRule заборонив: %1 + + + + AdBlockDialog + + Add Custom Rule + Додати спеціальне правило + + + Learn more about writing rules... + Дізнатись детальніше щодо написання правил... + + + Update Subscription + Оновити підписку + + + Browse Subscriptions... + Переглянути підписки... + + + Remove Subscription + Вилучити підписку + + + AdBlock Configuration + Налаштування AdBlock + + + Enable AdBlock + Увімкнути AdBlock + + + Action + Дія + + + + AdBlockManager + + Custom Rules + Спеціальні правила + + + + AdBlockModel + + Rule + Правило + + + + AdBlockSchemeAccessHandler + + Subscribe? + Підписатись? + + + Subscribe to this AdBlock subscription? +%1 + Підписатись до цієї підписки AdBlock? +%1 + + + + AddBookmarkDialog + + Add Bookmark + Закласти + + + Type a name for the bookmark, and choose where to keep it. + Введіть назву закладки та виберіть куди її додати. + + + Url + Посилання + + + Title + Заголовок + + + Add Folder + Додати теку + + + + AutoFillDialog + + Form Passwords + Форма паролів + + + Remove + Вилучити + + + Remove All + Вилучити всі + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + <b>Бажаєте зберегти цей пароль?</b><br> Щоб переглядати і вилучати збережені паролі, відкрийте налаштування автоматичного заповнення. + + + Never for this site + Ніколи для цього сайта + + + Not now + Не зараз + + + + AutoFillModel + + WebSite + Сайт + + + User Name + Ім'я користувача + + + + BookmarksDialog + + Open + Відкрити + + + Open in New Tab + Відкрити в новій вкладці + + + Delete + Вилучити + + + New Folder + Нова тека + + + Bookmarks + Закладки + + + &Remove + &Вилучити + + + Add Folder + Додати теку + + + Edit Name + Редагувати назву + + + Edit Address + Редагувати адресу + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + Помилка завантаження закладок у рядку %1, стовпець %2: +%3 + + + Toolbar Bookmarks + Панель закладок + + + Menu + Меню + + + Open File + Відкрити файл + + + XBEL (*.xbel *.xml) + XBEL (*.xbel *.xml) + + + Imported %1 + %1 імпортована + + + Save File + Зберегти файл + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + Помилка експорту + + + error saving bookmarks + Помилка збереження закладок + + + Remove Bookmark + Вилучити закладку + + + Insert Bookmark + Вставити закладку + + + Name Change + Зміна назви + + + Address Change + Зміна адреси + + + Bookmarks Bar + Панель закладок + + + Bookmarks Menu + Меню закладок + + + XBEL (*.xbel *.xml *.html) + XBEL (*.xbel *.xml *.html) + + + Error when loading html bookmarks: %1 + + Помилка під час завантаження закладки html: %1 + + + XBEL + XBEL + + + Name Change + Undo bookmark title change + Зміна назви + + + Address Change + Undo bookmark url change + Зміна адреси + + + XBEL bookmarks + Закладки XBEL + + + HTML Netscape bookmarks + Закладки HTML Netscape + + + htmlToXBel tool required + Інструмент запиту htmlToXBel + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + Інструмент htmlToXBel, який поставляється з Arora і потрібний для імпорту закладок у HTML, не встановлено або недоступний в шляхах пошуку. + + + Loading Bookmark + Завантаження закладки + + + Error when loading HTML bookmarks: %1 + + Помилка при завантажені закладок HTML: %1 + + + + BookmarksMenu + + Open in Tabs + Відкрити у вкладках + + + + BookmarksModel + + Title + Заголовок + + + Address + Адреса + + + + BookmarksToolBar + + Bookmark + Закладка + + + Open + Відкрити + + + Open in New &Tab + Відкрити в новій &вкладці + + + Remove + Вилучити + + + Add Bookmark... + Закласти... + + + Add Folder... + Додати теку... + + + Bookmarks + Закладки + + + + BrowserApplication + + (Change: %1 %2) + (Змінити: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + Відкрито %1 вікон та %2 вкладок +Бажаєте вийти попри все? + + + Restore failed + Невдале відновлення + + + The saved session will not be restored because Arora crashed while trying to restore this session. + Збережений сеанс не буде відновлена, оскільки Arora аварійно завершується при спробі відновити її. + + + Arora crashed while trying to restore this session. Should I try again? + Arora зазнала краху протягом відновлення цього сеансу. Спробувати ще раз? + + + + BrowserMainWindow + + &File + &Файл + + + &New Window + Нове &вікно + + + &Open File... + Відкрити &файл... + + + Open &Location... + Відкрити &місце... + + + &Save As... + &Зберегти як... + + + &Import Bookmarks... + &Імпортувати закладки... + + + &Export Bookmarks... + &Експортувати закладки... + + + P&rint Preview... + &Попередній перегляд друку... + + + &Print... + &Друк... + + + Private &Browsing... + П&риватне переглядання... + + + &Quit + &Вийти + + + &Edit + &Правка + + + &Undo + &Повернути + + + &Redo + &Повторити + + + Cu&t + &Вирізати + + + &Copy + &Скопіювати + + + &Paste + &Вставити + + + &Find + &Знайти + + + Find Nex&t + &Знайти наступне + + + Find P&revious + &Знайти попереднє + + + Prefere&nces... + &Налаштування... + + + Ctrl+, + Ctrl+, + + + &View + &Огляд + + + Show Menu Bar + Показати панель меню + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + &Stop + &Зупинити + + + &Reload Page + &Перезавантажити сторінку + + + Make Text &Bigger + З&більшити шрифт + + + Make Text &Normal + &Звичайний шрифт + + + Make Text &Smaller + З&меншити шрифт + + + Page S&ource + &Код сторінки + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + На весь &екран + + + Hi&story + &Журнал + + + Back + Назад + + + Forward + Вперед + + + Home + Домівка + + + Restore Last Session + Відновити попередній сеанс + + + &Bookmarks + &Закладки + + + Manage Bookmarks... + Впорядкувати закладинки... + + + Add Bookmark... + Закласти... + + + &Window + &Вікно + + + &Tools + &Інструменти + + + Web &Search + &Пошук в тенетах + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + &Очистити особисті дані + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + Ввімкнути Web &Inspector + + + &Help + &Довідка + + + Switch application language + Перемкнути мову програми + + + About &Qt + Про &Qt + + + About &Arora + Про &Arora + + + Navigation + Навігація + + + Show Status Bar + Показати панель стану + + + Hide Status Bar + Сховати панель стану + + + Show Toolbar + Показати панель інструментів + + + Hide Toolbar + Сховати панель інструментів + + + Show Bookmarks Bar + Показати панель закладок + + + Hide Bookmarks Bar + Сховати панель закладок + + + Arora + Arora + + + %1 - Arora + Page title and Browser name + %1 — Arora + + + Open Web Resource + Відкрити ресурс тенет + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Ресурс тенет (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + + + Print Document + Надрукувати документ + + + Are you sure you want to turn on private browsing? + Ви впевнені, що бажаєте ввімкнути приватне переглядання? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Коли приватне переглядання ввімкнене, деякі дії, що стосуються вашої приватності, будуть вимкнені:<ul><li> Сторінки тенет не додаються до журналу.</li><li> Елементи автоматично видаляються з вікна звантажень.</li><li> Нові коржики не зберігаються, поточні недоступні.</li><li> Піктограми сайтів не зберігаються, сесії не можуть бути збережені.</li><li> Пошуки не додаються до виринаючого меню в панелі пошуку.</li></ul>Поки ви не закриєте вікно, можете все ще напискати кнопки "Вперід" та "Назад", щоб повернутися до відкритих сторінок. + + + Are you sure you want to close the window? There are %1 tabs open + Ви впевнені, що бажаєте закрити вікно? Відкрито %1 вкладок + + + Web Inspector + Інспектор тенет + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + Інспектор тенет буде працювати правильно лише для сторінок, які завантажені після його вмикання. +Ви бажаєте перезавантажити всі сторінки? + + + Stop loading the current page + Зупинити завантаження поточної сторінки + + + Reload the current page + Перезавантажити поточну сторінку + + + Downloads + Звантаження + + + Alt+Ctrl+L + Download Manager + Alt+Ctrl+L + + + Show &Network Monitor + Показати &монітор мережі + + + Close Window + Закрити вікно + + + Zoom &In + З&більшити масштаб + + + Zoom &Normal + &Нормальний масштаб + + + Zoom &Out + З&меншити масштаб + + + Zoom &Text Only + Масштабувати тільки &текст + + + Show All Bookmarks... + Показати всі закладки... + + + Add Folder... + Додати теку... + + + About &%1 + About Browser + Про &%1 + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Якщо приватний перегляд увімкнено, деякі дії, що стосуються вашої приватності, будуть вимкнені:<ul><li> Сторінки тенет не додаються до історії.</li><li> Елементи автоматично вилучаються з вікна звантажень</li><li> Нові куки не зберігаються, до поточних немає доступу.</li><li> Піктограми сайтів не зберігатимуться, сесії не будуть збережені.</li><li> Пошуки не додані до виринаючого меню в панелі пошуку.</li></ul>Поки не закриєте вікно, ви все ще можете натискати кнопки „Назад“ та „Вперед“, щоб повернутись до сторінок, які ви відкривали. + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Default + Типове + + + Text Encoding + Кодування тексту + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> Network cache is disabled.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Коли увімкнуто приватне переглядання, деякі дії стосовно вашої приватності будуть вимкнуті:<ul><li> Сторінки не реєструються в журналі.</li><li> Звантаження автоматично вилучатимуться зі списку.</li><li> Нові куки не зберігатимуться, поточні куки будуть недоступні.</li><li> Піктограми сайтів не зберігатимуться, сеанси також.</li><li> Пошуки не додаватимуться до виринного меню в коробці пошуку.</li><li> Мережевий кеш буде вимкнено.</li></ul>Допоки не закриті вікна, ви можете продовжувати натискати кнопки Назад і Вперед, щоб повертатись до сторінок, які ви повідкивали. + + + Select &All + Вибрати в&се + + + Alt+Ctrl+B + Alt+Ctrl+B + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> No new network cache is written to disk.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>Коли увімкнуто приватне переглядання, деякі дії стосовно вашої приватності будуть вимкнуті:<ul><li> Сторінки не реєструються в журналі.</li><li> Звантаження автоматично вилучатимуться зі списку.</li><li> Нові куки не зберігатимуться, поточні куки будуть недоступні.</li><li> Піктограми сайтів не зберігатимуться, сеанси також.</li><li> Пошуки не додаватимуться до виринного меню в коробці пошуку.</li><li> Мережевий кеш буде вимкнено.</li></ul>Допоки не закриті вікна, ви можете продовжувати натискати кнопки Назад і Вперед, щоб повертатись до сторінок, які ви повідкривали. + + + Options... + Варіанти... + + + Configure Search Engines... + Налаштувати рушії пошуку... + + + &Ad Block... + &Ad Block... + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + Коли приватне переглядання ввімкнуто, деякі дії, стосовно ваших приватних вподобань, буде вимкнуто: + + + Webpages are not added to the history. + Сторінки не записуються в журналі. + + + Items are automatically removed from the Downloads window. + Пункти звантажень автоматично вилучаються з вікна звантажень. + + + New cookies are not stored, current cookies can't be accessed. + Нові куки не зберігаються, і їх неможливо дозволити. + + + Site icons won't be stored. + Піктограми сайтів не будуть зберігатись. + + + Session won't be saved. + Сеанс не буде зберігатись. + + + Searches are not added to the pop-up menu in the search box. + Пошуки не долучаються до виринного меню в коробці пошуку. + + + No new network cache is written to disk. + Новий мережевий кеш не зберігається на диск. + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + Ви можете натискати кнопки Назад та Вперед, щоб повертатись до сторінок, котрі ви повідкривали, поки не ви не закриєте саме вікно. + + + Private Browsing + Приватне переглядання + + + + ClearButton + + Clear + Очистити + + + + ClearPrivateData + + Clear Private Data + Очистити особисті дані + + + Clear the following items: + Очистити такі елементи: + + + &Browsing History + Журнал &переглядання + + + &Download History + Журнал &звантажень + + + &Search History + Журнал п&ошуку + + + &Cookies + &Куки + + + C&ached Web Pages + За&кешовані сторінки + + + Website &Icons + &Піктограми сайтів + + + Clear &Private Data + &Очистити особисті дані + + + &Cancel + &Скасувати + + + + ClickToFlash + + Load + Завантажити + + + Load All + Завантажити все + + + Add %1 to Whitelist + Долучити %1 до рекомендаційного списку + + + Remove from Whitelist + Вилучити з рекомендаційного списку + + + Settings + Налаштування + + + Load Flash + Завантажити Flash + + + + ClickToFlashSettings + + Whitelist sites + Сайти, які рекомендовано до списку + + + + CookieExceptionsModel + + Website + Сайт + + + Rule + Правило + + + Allow + Дозволити + + + Block + Заборонити + + + Allow For Session + Дозволити для сеансу + + + + CookieModel + + Website + Сайт + + + Name + Назва + + + Path + Шлях + + + Secure + Безпечно + + + Expires + Спливає + + + Contents + Вміст + + + true + так + + + false + ні + + + Session cookie + Сеанс куки + + + + CookiesDialog + + Cookies + Куки + + + &Remove + &Вилучити + + + Remove &All Cookies + Вилучити &всі куки + + + Add &Rule + Додати &правило + + + + CookiesExceptionsDialog + + Cookie Exceptions + Винятки куки + + + New Exception + Новий виняток + + + Domain: + Домен: + + + Block + Заборонити + + + Allow For Session + Дозволити для сеансу + + + Allow + Дозволити + + + Exceptions + Винятки + + + &Remove + &Вилучити + + + Remove &All + Вилучити &все + + + + Dialog + + Dialog + Діалог + + + Left: + Ліворуч: + + + Foo Bar Baz Arora LineEdit Manual Test This is the end + Foo Bar Baz Arora LineEdit Manual Test This is the end + + + Right: + Праворуч: + + + Empty: + Порожньо: + + + Foo Bar Baz Arora LineEdit Manual Test + Foo Bar Baz Arora LineEdit Manual Test + + + Widget + Віджет + + + Site Icon + Піктограма сайту + + + RSS + RSS + + + Bookmark + Закладинки + + + Position + Розміщення + + + Left + Ліворуч + + + Right + Праворуч + + + Add + Додати + + + Remove + Вилучити + + + Swap Visibility + Перемкнути видимість + + + Add ToolButton + Додати кнопку інструмента + + + + DownloadDialog + + Downloads + Звантаження + + + Clean up + Очистити + + + 0 Items + 0 пунктів + + + &OK + &Гаразд + + + + DownloadItem + + Form + Форма + + + Ico + Піктограма + + + Filename + Назва файла + + + Try Again + Спробувати знову + + + Stop + Зупинити + + + Open + Відкрити + + + Save File + Зберегти файл + + + Download canceled: %1 + Звантаження скасовано: %1 + + + Error opening output file: %1 + Помилка відкриття вихідного файла: %1 + + + Error saving: %1 + Помилка збереження: %1 + + + Network Error: %1 + Помилка мережі: %1 + + + seconds + с + + + - %n minutes remaining + + - залишилась %n хвилина + - залишилось %n хвилини + - залишилось %n хвилин + + + + - %n seconds remaining + + - залишилась %n секунда + - залишилось %n секунди + - залишилось %n секунд + + + + %1 of %2 (%3/sec) %4 + %1 з %2 (%3/с) %4 + + + ? + ? + + + %1 of %2 - Stopped + %1 з %2 — Зупинено + + + bytes + байт + + + kB + кбайт + + + MB + Мбайт + + + %1 of %2 (%3/sec) - %4 + %1 з %2 (%3/с) — %4 + + + Download directory (%1) couldn't be created. + Неможливо створити теку звантаження (%1). + + + + DownloadManager + + %n Download(s) + + %n звантаження + %n звантаження + %n звантажень + + + + There are %1 downloads in progress +Do you want to quit anyway? + Звантажень в поступі: %1 +Бажаєте вийти попри все? + + + %n minutes remaining + + Залишилась %n хвилина + Залишилось %n хвилини + Залишилась %n хвилин + + + + %n seconds remaining + + Залишилась %n секунда + Залишилось %n секунди + Залишилось %n секунд + + + + bytes + байт + + + kB + кБ + + + MB + МБ + + + GB + ГБ + + + + FileAccessReply + + No Error + Без помилок + + + Error opening: %1: No such file or directory + Помилка відкриття: %1: Немає такого файла або теки + + + Unable to read %1 + Неможливо прочитати %1 + + + Contents of %1 + Зміст %1 + + + %1 KB + %1 КБ + + + + HistoryDialog + + Open + Відкрити + + + Copy + Копіювати + + + Delete + Вилучити + + + History + Журнал + + + &Remove + &Вилучити + + + Remove &All + Вилучити &все + + + + HistoryMenu + + Show All History + Показати всю історію + + + Clear History... + Очистити історію... + + + Clear History + Очистити історію + + + Do you want to clear the history? + Ви бажаєте очистити історію? + + + + HistoryModel + + Title + Заголовок + + + Address + Адреса + + + + HistoryTreeModel + + Earlier Today + Раніше сьогодні + + + %n item(s) + + %n елемент + %n елемента + %n елементів + + + + + JavaScriptAroraObject + + Welcome to Arora! + Ласкаво просимо до Arora! + + + Arora Start + Запуск Arora + + + Search! + Пошук! + + + Search results provided by + Результати пошуку надаються + + + About Arora + Про Arora + + + + LanguageManager + + System locale (%1) %2 + Системна локаль (%1) %2 + + + Choose language + Вибрати мову + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>Ви можете працювати з іншою мовою,<br>що типово не є системною.</p><p>Будь ласка, виберіть мову, яку слід використовувати</p> + + + No translation files are installed. + Не встановлено файли перекладів. + + + No translation files are installed at %1. + Немає файлів перекладів у %1. + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>Введіть ім'я користувача та пароль для "%1" на %2</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>З'єднатись зі проксі "%1", використовуючи:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + Помилки SSL: + +%1 + +%2 + +Ви хочете нехтувати ці помилки? + + + Do you want to accept all these certificates? + Ви хочете прийняти всі ці сертифікати? + + + - SSL Errors + — помилки SSL + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>Помилки SSL:<br/><br/>для: <tt>%1</tt><ul><li>%2</li></ul> + +Ви бажаєте нехтувати цими помилками?</qt> + + + <qt>Certifactes:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Сертифікати:<br/>%1<br/>Ви хочете прийняти всі ці сертифікати?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>Сертифікати:<br/>%1<br/>Ви бажаєте дозволити всі оці сертифікати?</qt> + + + Issuer: %1 + Видавець: %1 + + + Not valid before: %1 + Неправильно перед: %1 + + + Valid until: %1 + Правильно допоки: %1 + + + Alternate Names: + Альтернативні назви: + + + + NetworkMonitor + + Name + Назва + + + Value + Значення + + + + NetworkMonitorDialog + + Network Monitor + Монітор мережі + + + Network Requests + Запити мережі + + + Request Headers + Заголовки запитів + + + Response Headers + Заголовки відповідей + + + &Remove + &Вилучити + + + Remove &All Requests + Вилучити &всі запити + + + + OpenSearchDialog + + Open File + Відкрити файл + + + OpenSearch + OpenSearch + + + Error + Помилка + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 — не OpenSearch 1.1 або він вже є у вашому списку. + + + You must have at least one search engine in here. + Ви змушені мати тут щонайменше один рушій пошуку. + + + OpenSearch Manager + Керування OpenSearch + + + &Restore Defaults + &Відновити до типових + + + &Delete + В&илучити + + + &Add + &Додати + + + &Close + &Закрити + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>Опис:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>Забезпечує контекстові поради</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + Список відокремлених комами ключових слів, які можна ввести для пошуку термінів з цим рушієм + + + Name + Назва + + + Keywords + Ключові слова + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + Ви бажаєте додати такий рушій пошуку до вашого списку?<br /><br />Назва: %1<br />Шукає в: %2 + + + + PasswordDialog + + Authentication Required + Необхідне засвідчення + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMMY + + + Username: + Ім'я користувача: + + + Password: + Пароль: + + + + PlainTextEditSearch + + Not Found + Не знайдено + + + + ProxyDialog + + Proxy Authentication + Засвідчення на проксі + + + ICON + ICON + + + Connect to proxy + З'єднання з проксі + + + Username: + Ім'я користувача: + + + Password: + Пароль: + + + + QObject + + The file is not an XBEL version 1.0 file. + Це не файл XBEL версії 1.0. + + + Unknown title + Невідомий заголовок + + + The file is not an OpenSearch 1.1 file. + Це не файл OpenSearch 1.1. + + + + RequestModel + + Redirect: %1 + Перенаправлення: %1 + + + Method + Спосіб + + + Address + Адреса + + + Response + Відповідь + + + Length + Довжина + + + Content Type + Тип вмісту + + + Info + Інформація + + + + SearchBanner + + Form + Форма + + + TextLabel + ТекстоваМітка + + + < + < + + + > + > + + + Done + Виконано + + + Highlight All + Виділити все + + + + SearchLineEdit + + Search + Пошук + + + + Settings + + Preferences + Налаштування + + + General + Загальні + + + On startup: + При запуску: + + + Show my home page + Показувати мою домашню сторінку + + + Show a blank page + Показувати порожню сторінку + + + Restore windows and tabs from last time + Відновлювати попередні вікна і вкладки + + + Home Page: + Домашня сторінка: + + + Set to current page + Встановити поточну сторінку + + + Remove history items: + Вилучати з журналу: + + + After one day + Після однієї доби + + + After one week + Після одного тижня + + + After two weeks + Після двох тижнів + + + After one month + Після одного місяця + + + After one year + Після одного року + + + Manually + Вручну + + + On application exit + При виході з програми + + + Open links from applications: + Відкривати посилання з програм: + + + In a tab in the current window + У вкладці в поточному вікні + + + In a new window + У новому вікні + + + Downloads + Звантаження + + + Ask for a destination each time + Запитувати кожного разу, куди зберігати + + + Use this destination: + Використовувати це місце: + + + Appearance + Зовнішній вигляд + + + Standard font: + Звичайний шрифт: + + + Times 16 + Times 16 + + + Select... + Вибрати... + + + Fixed-width font: + Шрифт фіксованої ширини: + + + Courier 13 + Courier 13 + + + Privacy + Приватність + + + Web Content + Зміст тенет + + + Enable Plugins + Ввімкнути модулі + + + Enable Javascript + Ввімкнути Javascript + + + View Images + Переглянути зображення + + + Cookies + Куки + + + Accept Cookies: + Дозволяти куки: + + + Always + Завжди + + + Never + Ніколи + + + Only from sites you navigate to + Тільки для сайтів, які ви переглядаєте + + + Exceptions... + Винятки... + + + Keep Cookies Until: + Зберігати куки допоки: + + + They expire + Вони не застаріють + + + I exit the application + Я не вийду з програми + + + At most 90 days + Не більше 90 діб + + + Cookies... + Куки... + + + Tabs + Вкладки + + + Select tabs and windows as they are created + Вибрати вкладки та вікна щойно вони створені + + + Confirm when closing multiple tabs + Запитувати перед закриттям багатьох вкладок + + + Proxy + Проксі + + + Use proxy server + Використовувати проксі-сервер + + + Type: + Тип: + + + Socks5 + Socks5 + + + Http + Http + + + Host name: + Назва хосту: + + + Port: + Порт: + + + User Name: + Ім'я користувача: + + + Password: + Пароль: + + + Advanced + Додатково + + + Style Sheet: + Шаблон стилю: + + + Show only one close button instead of one for each tab + Показувати тільки одну кнопку для закривання, замість по одній на кожній вкладці + + + Preferred languages for viewing webpages in: + Бажана мова для перегляду сторінок тенет у: + + + Block Popup Windows + Заборонити виринні вікна + + + Opening links + Відкриття посилань + + + Links that want to open in a new window: + Посилання, які бажаєте відкрити у новому вікні: + + + In a new selected tab in the current window + У новій вибраній вкладці поточного вікна + + + In a new tab in the current window + У новій вкладці поточного вікна + + + In the current tab + У поточній вкладці + + + Http (Secure) + Http (безпечне) + + + Http (Transparent) + Http (прозоре) + + + Use ClickToFlash on flash plugins + Використовувати ClickToFlash для модулів Flash + + + Filter Tracking Cookies + Фільтр відстежування кук + + + Confirm when closing multiple tabs or windows + Запитувати перед закриттям багатьох вкладок і вікон + + + Quit the application when last tab is closed + Вимкнути програму, коли остання вкладка закрита + + + Enable network cache + Увімкнути мережевий кеш + + + Maximum Size: + Максимальний розмір: + + + MB + МБ + + + Use the default search engine as fallback when the URL given by the user is invalid + Використовувати типовий рушій пошуку для помилкових посилань, котрі вводить користувач + + + Choose Directory... + Вибрати теку... + + + A cookie session ends: + Сеанс куки закінчився: + + + When I exit the application + Коли я виходжу з програми + + + 1 day + 1 день + + + 2 days + 2 дні + + + 3 days + 3 дні + + + 7 days + 7 днів + + + 30 days + 30 днів + + + AutoFill + Автоматичне заповнення + + + AutoFill web forms: + Автоматичне заповнення форм у тенетах: + + + User names and passwords + Псевдоніми і паролі користувача + + + Edit... + Правка... + + + Browse... + Огляд... + + + + SettingsDialog + + Restart required + Потрібно перезапустити + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + Налаштування мережевого кеша змінено. Але переглядач потрібно перезапустити, щоб налаштування набрали чинності. + + + Choose Directory + Вибрати теку + + + Choose CSS File + Вибрати файл CSS + + + + SourceViewer + + Loading... + Завантажується... + + + &Edit + &Правка + + + &Find + &Знайти + + + Source of Page + Код сторінки + + + &View + &Переглянути + + + &Wrap lines + &Перенести рядки + + + Source of Page %1 + Код сторінки %1 + + + + TabBar + + Show Tab Bar + Показати панель вкладок + + + Hide Tab Bar + Сховати панель вкладок + + + New &Tab + Нова &вкладка + + + Duplicate Tab + Дублювати вкладку + + + &Close Tab + &Закрити вкладку + + + Close &Other Tabs + Закрити &інші вкладки + + + Reload Tab + Перезавантажити вкладку + + + Reload All Tabs + Перезавантажити всі вкладки + + + + TabWidget + + New &Tab + Нова &вкладка + + + &Close Tab + &Закрити вкладку + + + Show Next Tab + Показати наступну вкладку + + + Show Previous Tab + Показати попередню вкладку + + + Recently Closed Tabs + Нещодавно закриті вкладки + + + Untitled + Без назви + + + Do you really want to close this page? + Ви справді бажаєте закрити цю сторінку? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + Ви змінили цю сторінку і коли закриєте її, втратите зміни. +Ви справді бажаєте закрити цю сторінку? + + + + Ctrl-] + Ctrl-] + + + Ctrl-[ + Ctrl-[ + + + Saved Tabs + Збережені вкладки + + + Loading... + Завантажується... + + + Loading %1% (%2 %3)... + Завантажується %1% (%2 %3)... + + + Finished loading + Завантаження закінчилось + + + Failed to load + Неможливо завантажити + + + Bookmark All Tabs + Закласти всі вкладки + + + + ToolbarSearch + + No Recent Searches + Немає нещодавніх пошуків + + + Recent Searches + Нещодавні пошуки + + + Clear Recent Searches + Очистити нещодавні пошуки + + + Suggestions + Поради + + + Add '%1' + Додати '%1' + + + Configure Search Engines... + Налаштувати рушії пошуку... + + + + WebPage + + Error loading page: %1 + Помилка під час завантаження сторінки: %1 + + + When connecting to: %1. + Коли з'єднуємся з: %1. + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + Перевірте адресу на помилки такі, як <b>ww</b>.arora-browser.org замість <b>www</b>.arora-browser.org + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + Якщо ваш комп'ютер або мережа захищена вогняною стінкою(firewall) або проксі, впевніться, що переглядачеві дозволений доступ до мережі. + + + If the address is correct, try checking the network connection. + Якщо адреса правильна, спробуйте перевірити з'єднання з мережею. + + + Resending POST request + Повторне передавання запиту POST + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + Для того, щоб показати сайт, запит всіх даних потрібно відправити ще раз, що може призвести до несподіваної поведінки сайта, наприклад, ті самі дії виконаються ще раз.Бажаєте продовжити попри все? + + + + WebView + + Open in New &Window + Відкрити в новому &вікні + + + Open in New &Tab + Відкрити в новій &вкладці + + + Save Lin&k + Зберегти &посилання + + + &Bookmark This Link + &Додати посилання до закладок + + + &Copy Link Location + &Скопіювати посилання + + + Open Image in New &Window + Відкрити зображення в новому &вікні + + + Open Image in New &Tab + Відкрити зобаження в новій в&кладці + + + &Save Image + &Зберегти зображення + + + &Copy Image + &Копіювати зображення + + + C&opy Image Location + К&опіювати посилання на зображення + + + Loading... + Завантаження... + + + Search with... + Шукати з... + + + Add to the toolbar search + Додати до панелі інструментів пошуку + + + Method not supported + Спосіб не підтримується + + + %1 method is not supported. + Спосіб %1 не підтримується. + + + Search engine + Рушій пошуку + + + Choose the desired search engine + Вибрати потрібний рушій пошуку + + + Engine name + Назва рушія + + + Type in a name for the engine + Введіть назву для рушія + + + Block Image + Заборонити зображення + + + + WebViewSearch + + Not Found + Не знайдено + + + + tst_SearchLineEdit + + Search + Пошук + + + diff --git a/src/locale/zh_CN.ts b/src/locale/zh_CN.ts new file mode 100644 index 00000000..34eab3b6 --- /dev/null +++ b/src/locale/zh_CN.ts @@ -0,0 +1,2196 @@ + + + + + AboutDialog + + About + 关于 + + + Authors + 作者 + + + License + 许可证 + + + Lightweight WebKit-based web browser + 轻快的浏览器-基于Webkit + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + + Close + 关闭 + + + About %1 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + + + + Languages: in order of preference: + + + + Move &Up + + + + Move &Down + + + + &Remove + 移除(&R) + + + Add... + + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + 规则 + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Add Bookmark + 添加书签 + + + Type a name for the bookmark, and choose where to keep it. + 请输入书签名,并选择保存位置 + + + Url + + + + Title + 标题 + + + Add Folder + 添加文件夹 + + + + AutoFillDialog + + Form Passwords + + + + Remove + + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + 打开 + + + Open in New Tab + 在新标签页中打开 + + + Delete + 删除 + + + New Folder + 新建文件夹 + + + Bookmarks + 书签 + + + &Remove + 移除(&R) + + + Add Folder + 添加文件夹 + + + Edit Name + + + + Edit Address + + + + + BookmarksManager + + Error when loading bookmarks on line %1, column %2: +%3 + 在行%1,列%2: +%3导入书签时出错 + + + Toolbar Bookmarks + 工具栏书签 + + + Menu + 菜单 + + + Open File + 打开文件 + + + Imported %1 + 导入的%1 + + + Save File + 保存文件 + + + %1 Bookmarks.xbel + + + + Export error + 导出错误 + + + error saving bookmarks + 保存书签出错 + + + Remove Bookmark + 移除书签 + + + Insert Bookmark + 插入书签 + + + Name Change + 名字变更 + + + Address Change + 地址变更 + + + Bookmarks Bar + + + + Bookmarks Menu + + + + Name Change + Undo bookmark title change + 名字变更 + + + Address Change + Undo bookmark url change + 地址变更 + + + XBEL bookmarks + + + + HTML Netscape bookmarks + + + + htmlToXBel tool required + + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + + + + Loading Bookmark + + + + Error when loading HTML bookmarks: %1 + + + + + + BookmarksMenu + + Open in Tabs + + + + + BookmarksModel + + Title + 标题 + + + Address + 地址 + + + + BookmarksToolBar + + Bookmark + 书签 + + + Open + 打开 + + + Open in New &Tab + 在新标签页中打开(&T) + + + Remove + + + + Add Bookmark... + 添加标签... + + + Add Folder... + + + + Bookmarks + 书签 + + + + BrowserApplication + + (Change: %1 %2) + (变更: %1 %2) + + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + 有%1个窗口和%2个标签为打开状态 +仍旧确认退出吗? + + + Restore failed + 恢复失败 + + + The saved session will not be restored because Arora crashed while trying to restore this session. + 保存的会话不会恢复,因为Arora在尝试恢复该会话时已崩溃。 + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + &File + 文件(&F) + + + &New Window + 新窗口(&N) + + + &Open File... + 打开文件(&O)... + + + Open &Location... + 打开位置(&L)... + + + &Save As... + 另存为(&S)... + + + &Import Bookmarks... + 导入书签(&I)... + + + &Export Bookmarks... + 导出书签(&E)... + + + P&rint Preview... + 打印预览(&P)... + + + &Print... + 打印(&P)... + + + Private &Browsing... + 隐私浏览(&B)... + + + &Quit + 退出(&Q) + + + &Edit + 编辑(&E) + + + &Undo + 撤销(&U) + + + &Redo + 重做(&R) + + + Cu&t + 剪切(&t) + + + &Copy + 复制(&C) + + + &Paste + 粘帖(&P) + + + &Find + 查找(&F) + + + Find Nex&t + 查找下一个(&t) + + + Find P&revious + 查找前一个(&r) + + + Prefere&nces... + 选项(&r)... + + + Ctrl+, + + + + &View + 查看(&V) + + + Show Menu Bar + 显示菜单栏 + + + Ctrl+| + + + + Ctrl+/ + + + + &Stop + 停止(&S) + + + &Reload Page + 重新加载页面(&R) + + + Make Text &Bigger + 字体放大(&B) + + + Make Text &Normal + 普通字体(&N) + + + Make Text &Smaller + 字体缩小(&S) + + + Page S&ource + 页面源码(&o) + + + Ctrl+Alt+U + + + + &Full Screen + 全屏(&F) + + + Hi&story + 历史(&s) + + + Back + 后退 + + + Forward + 前进 + + + Home + 主页 + + + Restore Last Session + 恢复最后一次会话 + + + &Bookmarks + 标签(&B) + + + Manage Bookmarks... + 管理标签... + + + Add Bookmark... + 添加标签... + + + &Window + 窗口(&W) + + + &Tools + 工具(&T) + + + Web &Search + Web搜索(&S) + + + Ctrl+K + Web Search + + + + &Clear Private Data + 清除隐私数据(&C) + + + Ctrl+Shift+Delete + Clear Private Data + + + + Enable Web &Inspector + 允许Web &Inspector + + + &Help + 帮助(&H) + + + Switch application language + 切换应用程序语言 + + + About &Qt + 关于&Qt + + + About &Arora + 关于&Arora + + + Navigation + 导航 + + + Show Status Bar + 显示状态栏 + + + Hide Status Bar + 隐藏状态栏 + + + Show Toolbar + 显示工具栏 + + + Hide Toolbar + 隐藏工具栏 + + + Show Bookmarks Bar + 显示标签栏 + + + Hide Bookmarks Bar + 隐藏标签栏 + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + 打开Web资源 + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + Web资源 (*.html *.htm *.svg *.png *.gif *.svgz);;所有文件 (*.*) + + + Print Document + 打印文档 + + + Are you sure you want to turn on private browsing? + 是否确认打开隐私浏览? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not addded to the pop-up menu in the search box.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>当开启隐私浏览时,关于你的某些隐私动作不会被记录:<ul><li> 页面不会被添加到历史中。</li><li>下载项会自动从下载窗口移除。 </li><li> 新的cookies不会被存储,当前的cookies也不会被访问。</li><li>站点图标不会被存储,会话也不会被保存。 </li><li>搜索动作不会被添加到搜索框的弹出菜单中。</li></ul>在关闭窗口之前,你可以一直通过点击后退和前进按钮来浏览已打开过的页面。 + + + Are you sure you want to close the window? There are %1 tabs open + 是否确认关闭窗口?还有%1个标签打开着 + + + Web Inspector + + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + web inspector只在页面被允许且被加载后才能正常运行。 +希望重新加载所有页面吗? + + + Stop loading the current page + 停止加载当前页面 + + + Reload the current page + 重新加载当前页面 + + + Downloads + 下载 + + + Close Window + + + + Zoom &In + + + + Zoom &Normal + + + + Zoom &Out + + + + Zoom &Text Only + + + + Show All Bookmarks... + + + + Add Folder... + + + + About &%1 + About Browser + + + + Ctrl+Y + Download Manager + + + + Default + 缺省 + + + Text Encoding + + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + 清除 + + + + ClearPrivateData + + Clear Private Data + 清除隐私数据 + + + Clear the following items: + 清除以下项: + + + &Browsing History + 浏览历史(&B) + + + &Download History + 下载历史(&D) + + + &Search History + 搜索历史(&S) + + + &Cookies + + + + C&ached Web Pages + 缓存的页面(&a) + + + Website &Icons + 网站图标(&I) + + + Clear &Private Data + 清除隐私数据(&P) + + + &Cancel + 取消(&C) + + + + ClickToFlash + + Load + + + + Load All + + + + Add %1 to Whitelist + + + + Remove from Whitelist + + + + Settings + + + + Load Flash + + + + + ClickToFlashSettings + + Whitelist sites + + + + + CookieExceptionsModel + + Website + 网站 + + + Rule + 规则 + + + Allow + 允许 + + + Block + 阻挡 + + + Allow For Session + 会话中允许 + + + + CookieModel + + Website + 网站 + + + Name + 名字 + + + Path + 路径 + + + Secure + 安全 + + + Expires + 失效 + + + Contents + 内容 + + + true + + + + false + + + + Session cookie + + + + + CookiesDialog + + Cookies + + + + &Remove + 移除(&R) + + + Remove &All Cookies + 移除所有Cookies(&A) + + + Add &Rule + + + + + CookiesExceptionsDialog + + Cookie Exceptions + Cookie例外 + + + New Exception + 新建例外 + + + Domain: + 域: + + + Block + 阻挡 + + + Allow For Session + 会话中允许 + + + Allow + 允许 + + + Exceptions + 例外 + + + &Remove + 移除(&R) + + + Remove &All + 移除所有(&A) + + + + DownloadDialog + + Downloads + 下载 + + + Clean up + 清除 + + + 0 Items + 0项 + + + + DownloadItem + + Form + 表单 + + + Ico + + + + Filename + 文件名 + + + Try Again + 重新尝试 + + + Stop + 停止 + + + Open + 打开 + + + Save File + 保存文件 + + + Download canceled: %1 + 下载取消: %1 + + + Error opening output file: %1 + 打开输出文件出错: %1 + + + Error saving: %1 + 保存出错: %1 + + + Network Error: %1 + 网络出错: %1 + + + seconds + + + + - %n minutes remaining + + - 还有 %n 分钟 + + + + - %n seconds remaining + + - 还有 %n 秒 + + + + %1 of %2 (%3/sec) %4 + %1 of %2 (%3/秒) %4 + + + ? + + + + %1 of %2 - Stopped + %1 of %2 - 停止 + + + bytes + 字节 + + + %1 of %2 (%3/sec) - %4 + + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + %n Download(s) + + %n 下载 + + + + There are %1 downloads in progress +Do you want to quit anyway? + + + + %n minutes remaining + + + + + + %n seconds remaining + + + + + + bytes + 字节 + + + kB + + + + MB + + + + GB + + + + + FileAccessReply + + No Error + + + + Error opening: %1: No such file or directory + + + + Unable to read %1 + + + + Contents of %1 + + + + %1 KB + + + + + HistoryDialog + + Open + 打开 + + + Copy + 复制 + + + Delete + 删除 + + + History + 历史 + + + &Remove + 移除(&R) + + + Remove &All + 移除所有(&A) + + + + HistoryMenu + + Show All History + 显示所有历史 + + + Clear History... + 清除历史... + + + Clear History + 清除历史 + + + Do you want to clear the history? + 希望清除历史吗? + + + + HistoryModel + + Title + 标题 + + + Address + 地址 + + + + HistoryTreeModel + + Earlier Today + 早些时候 + + + %n item(s) + + %n 项 + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + Default + 缺省 + + + Choose language + 选择语言 + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>你可以运行在其它语言环境下<br>而不采用操作系统所缺省的语言环境</p><p>请选择应该使用的语言环境</p> + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>为 "%1" 在 %2 输入用户名和密码</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>连接到代理 "%1" 使用:</qt> + + + SSL Errors: + +%1 + +%2 + +Do you want to ignore these errors? + SSL 错误:%1%2希望忽略该错误吗? + + + Do you want to accept all these certificates? + 确认接受所有证书吗? + + + - SSL Errors + + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + + + + Issuer: %1 + + + + Not valid before: %1 + + + + Valid until: %1 + + + + Alternate Names: + + + + + NetworkMonitor + + Name + 名字 + + + + NetworkMonitorDialog + + &Remove + 移除(&R) + + + + OpenSearchDialog + + Open File + 打开文件 + + + OpenSearch + + + + Error + + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + + + + You must have at least one search engine in here. + + + + OpenSearch Manager + + + + &Restore Defaults + + + + &Delete + + + + &Add + + + + &Close + + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + + + + <strong>Provides contextual suggestions</strong> + + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + 名字 + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + + + + + PasswordDialog + + Authentication Required + 需要验证 + + + DUMMY ICON + + + + INTRO TEXT DUMMY + + + + Username: + 用户名: + + + Password: + 密码: + + + + PlainTextEditSearch + + Not Found + 未找到 + + + + ProxyDialog + + Proxy Authentication + 代理验证 + + + Connect to proxy + 连接到代理 + + + Username: + 用户名: + + + Password: + 密码: + + + + QObject + + The file is not an XBEL version 1.0 file. + 该文件不是版本为1.0的XBEL文件 + + + Unknown title + 未知文件 + + + The file is not an OpenSearch 1.1 file. + + + + + RequestModel + + Address + 地址 + + + + SearchBanner + + Form + 表单 + + + TextLabel + 文本标签 + + + Done + 完成 + + + Highlight All + + + + + SearchLineEdit + + Search + 搜索 + + + + Settings + + Preferences + 选项 + + + General + 常规 + + + On startup: + 启动时: + + + Show my home page + 显示我的主页 + + + Show a blank page + 显示空白页 + + + Restore windows and tabs from last time + 恢复最后一次的窗口和标签 + + + Home Page: + 主页: + + + Set to current page + 设置为当前页面 + + + Remove history items: + 移除历史项: + + + After one day + 一天后 + + + After one week + 一周后 + + + After two weeks + 两周后 + + + After one month + 一个月后 + + + After one year + 一年后 + + + Manually + 手工 + + + On application exit + 应用退出 + + + Open links from applications: + 从应用程序打开链接: + + + In a tab in the current window + 在当前窗口的标签中 + + + In a new window + 在新窗口中 + + + Downloads + 下载 + + + Ask for a destination each time + 每次均询问目的地 + + + Use this destination: + 使用该目的地: + + + Appearance + 外观 + + + Standard font: + 标准字体: + + + Select... + 选择... + + + Fixed-width font: + 定宽字体: + + + Privacy + 隐私 + + + Web Content + Web内容 + + + Enable Plugins + 允许插件 + + + Enable Javascript + 允许Javascript + + + View Images + 查看图片 + + + Cookies + + + + Accept Cookies: + 接受Cookies: + + + Always + 总是 + + + Never + 从不 + + + Only from sites you navigate to + 只允许从浏览过的站点 + + + Exceptions... + 例外... + + + Keep Cookies Until: + 保持Cookies直到: + + + They expire + 它们失效 + + + I exit the application + 退出应用程序 + + + At most 90 days + 最多90天 + + + Cookies... + + + + Tabs + 标签 + + + Select tabs and windows as they are created + 在标签和窗口被创建后选择它们 + + + Confirm when closing multiple tabs + 关闭多个标签时进行确认 + + + Proxy + 代理 + + + Use proxy server + 使用代理服务器 + + + Type: + 类型: + + + Socks5 + + + + Host name: + 主机名: + + + Port: + 端口: + + + User Name: + 用户名: + + + Password: + 密码: + + + Advanced + 高级 + + + Style Sheet: + 样式表: + + + Show only one close button instead of one for each tab + 只显示一个关闭按钮,而不是在每个标签上都显示一个关闭按钮 + + + Preferred languages for viewing webpages in: + + + + Block Popup Windows + + + + Opening links + + + + Links that want to open in a new window: + + + + In a new selected tab in the current window + + + + In a new tab in the current window + + + + In the current tab + + + + Http (Secure) + + + + Http (Transparent) + + + + Use ClickToFlash on flash plugins + + + + Filter Tracking Cookies + + + + Confirm when closing multiple tabs or windows + + + + Quit the application when last tab is closed + + + + Enable network cache + + + + Maximum Size: + + + + MB + + + + Use the default search engine as fallback when the URL given by the user is invalid + + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + 加载... + + + &Edit + 编辑(&E) + + + &Find + 查找(&F) + + + Source of Page + 页面源码 + + + &View + 查看(&V) + + + &Wrap lines + 折叠行(&W) + + + Source of Page %1 + + + + + TabBar + + Show Tab Bar + 显示标签栏 + + + Hide Tab Bar + 隐藏标签栏 + + + New &Tab + 新标签页(&T) + + + Duplicate Tab + 复制标签 + + + &Close Tab + 关闭标签(&C) + + + Close &Other Tabs + 关闭其它标签(&O) + + + Reload Tab + 重新加载标签 + + + Reload All Tabs + 重新加载所有标签 + + + + TabWidget + + New &Tab + 新标签页(&T) + + + &Close Tab + 关闭标签(&C) + + + Show Next Tab + 显示下一个标签 + + + Show Previous Tab + 显示前一个标签 + + + Recently Closed Tabs + 最近关闭的标签 + + + Untitled + 无标题 + + + Do you really want to close this page? + 确认关闭该页面? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + 页面已被修改,如果关闭,将丢失所有修改。确认关闭该页面? + + + Ctrl-] + + + + Ctrl-[ + + + + Saved Tabs + + + + Loading... + 加载... + + + Loading %1% (%2 %3)... + + + + Finished loading + + + + Failed to load + + + + Bookmark All Tabs + + + + + ToolbarSearch + + No Recent Searches + 无最近搜索 + + + Recent Searches + 最近搜索 + + + Clear Recent Searches + 清除最近搜索 + + + Suggestions + + + + Add '%1' + + + + + WebPage + + Error loading page: %1 + 加载页面出错: %1 + + + When connecting to: %1. + 当连接至:%1 + + + Check the address for errors such as <b>ww</b>.trolltech.com instead of <b>www</b>.trolltech.com. + 检查地址是否错误,比如输入的是 <b>ww</b>.trolltech.com 而不是 <b>www</b>.trolltech.com. + + + If the address is correct, try to check the network connection. + 如果地址正确,那么请检查网络是否连接。 + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + 如果计算机或网络被防火墙或代理所保护,请确认浏览器被允许访问网络。 + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + + + + If the address is correct, try checking the network connection. + + + + Resending POST request + + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + + + + + WebView + + Open in New &Window + 在新窗口中打开(&W) + + + Open in New &Tab + 在新标签页中打开(&T) + + + Save Lin&k + 保存链接(&k) + + + &Bookmark This Link + 添加该链接到书签(&B) + + + &Copy Link Location + 复制链接地址(&C) + + + Open Image in New &Window + 在新窗口中打开图片(&W) + + + Open Image in New &Tab + 在新标签页中打开图片(&T) + + + &Save Image + 保存图片(&S) + + + &Copy Image + 复制图片(&C) + + + C&opy Image Location + 复制图片地址(&o) + + + Loading... + 加载... + + + Search with... + + + + Add to the toolbar search + + + + Method not supported + + + + %1 method is not supported. + + + + Search engine + + + + Choose the desired search engine + + + + Engine name + + + + Type in a name for the engine + + + + Block Image + + + + + WebViewSearch + + Not Found + 未找到 + + + diff --git a/src/locale/zh_TW.ts b/src/locale/zh_TW.ts new file mode 100644 index 00000000..39b59920 --- /dev/null +++ b/src/locale/zh_TW.ts @@ -0,0 +1,2077 @@ + + + + + AboutDialog + + About %1 + 關於 %1 + + + Authors + 作者 + + + License + 授權書 + + + Lightweight WebKit-based web browser + 基於 WebKit 的輕量級瀏覽器 + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Copyright © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style="font-size:9pt;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">版權所有 © 2007-2009 Benjamin C. Meyer &lt;<a href="mailto:ben@meyerhome.net"><span style=" text-decoration: underline; color:#0057ae;">ben@meyerhome.net</span></a>&gt;</p></body></html> + + + <a href="http://arora-browser.org">http://arora-browser.org</a> + <a href="http://arora-browser.org">http://arora-browser.org</a> + + + Close + 關閉 + + + WebKit version: %1 + + + + + AcceptLanguage + + Languages + 語言 + + + Languages: in order of preference: + 語言:偏好順序: + + + Move &Up + 移上(&U) + + + Move &Down + 移下(&D) + + + &Remove + 移除(&R) + + + Add... + 加入... + + + + AdBlockBlockedNetworkReply + + Blocked by AdBlockRule: %1 + + + + + AdBlockDialog + + Add Custom Rule + + + + Learn more about writing rules... + + + + Update Subscription + + + + Browse Subscriptions... + + + + Remove Subscription + + + + AdBlock Configuration + + + + Enable AdBlock + + + + Action + + + + + AdBlockManager + + Custom Rules + + + + + AdBlockModel + + Rule + 規則 + + + + AdBlockSchemeAccessHandler + + Subscribe? + + + + Subscribe to this AdBlock subscription? +%1 + + + + + AddBookmarkDialog + + Url + 網址 + + + Title + 標題 + + + Add Folder + 加入資料夾 + + + Add Bookmark + 加入書籤 + + + Type a name for the bookmark, and choose where to keep it. + 輸入書籤的名稱,或是選擇它要放在那裡。 + + + + AutoFillDialog + + Form Passwords + + + + Remove + 移除 + + + Remove All + + + + + AutoFillManager + + <b>Would you like to save this password?</b><br> To review passwords you have saved and remove them, open the AutoFill pane of preferences. + + + + Never for this site + + + + Not now + + + + + AutoFillModel + + WebSite + + + + User Name + + + + + BookmarksDialog + + Open + 開啟 + + + Open in New Tab + 在新的分頁開啟 + + + Edit Name + 修改名稱 + + + Edit Address + 修改網址 + + + Delete + 刪除 + + + New Folder + 新增資料夾 + + + Bookmarks + 書籤 + + + &Remove + 移除(&R) + + + Add Folder + 加入資料夾 + + + + BookmarksManager + + Bookmarks Bar + 書籤列 + + + Bookmarks Menu + 書籤選單 + + + Error when loading bookmarks on line %1, column %2: +%3 + 開啟書籤中的行 %1,欄 %2 時發生錯誤: +%3 + + + Toolbar Bookmarks + 工具列書籤 + + + Menu + 選單 + + + XBEL bookmarks + XBEL 書籤 + + + HTML Netscape bookmarks + HTML Netscape 書籤 + + + Open File + 開啟檔案 + + + htmlToXBel tool required + 需要 htmlToXBel 工具 + + + htmlToXBel tool, which is shipped with Arora and is needed to import HTML bookmarks, is not installed or not available in the search paths. + htmlToXBel 工具,附於 Arora 中,用作匯入 HTML 書籤,但是卻沒有安裝或是在路徑中找不到。 + + + Loading Bookmark + 正在載入書籤 + + + Error when loading HTML bookmarks: %1 + + 載入 HTML 書籤時發生錯誤:%1 + + + Imported %1 + 已匯入 %1 + + + Save File + 儲存檔案 + + + %1 Bookmarks.xbel + %1 Bookmarks.xbel + + + Export error + 匯出錯誤 + + + error saving bookmarks + 儲存書籤發生錯誤 + + + Remove Bookmark + 移除書籤 + + + Insert Bookmark + 插入書籤 + + + Name Change + Undo bookmark title change + 名稱變更 + + + Address Change + Undo bookmark url change + 網址變更 + + + + BookmarksMenu + + Open in Tabs + 在分頁中開啟 + + + + BookmarksModel + + Title + 標題 + + + Address + 網址 + + + + BookmarksToolBar + + Bookmarks + 書籤 + + + Open + 開啟 + + + Open in New &Tab + 在新的分頁中開啟(&T) + + + Remove + 移除 + + + Add Bookmark... + 加入書籤... + + + Add Folder... + 加入資料夾... + + + + BrowserApplication + + There are %1 windows and %2 tabs open +Do you want to quit anyway? + 還有 %1 個視窗及 %2 分頁在開啟, +您仍然要離開嗎? + + + Restore failed + 回復失敗 + + + The saved session will not be restored because Arora crashed while trying to restore this session. + 已儲存的階段不能回復;因為當 Arora 嘗試回復該階段時發生錯誤。 + + + Arora crashed while trying to restore this session. Should I try again? + + + + + BrowserMainWindow + + Default + 預設 + + + &File + 檔案(&F) + + + &New Window + 新增視窗(&N) + + + &Open File... + 開啟檔案(&O)... + + + Open &Location... + 開啟位置(&L)... + + + &Save As... + 另存新檔(&S)... + + + &Import Bookmarks... + 匯入書籤(&I)... + + + &Export Bookmarks... + 匯出書籤(&E)... + + + P&rint Preview... + 預覽列印(&R)... + + + &Print... + 列印(&P)... + + + Private &Browsing... + 私密瀏覽(&B)... + + + Close Window + 關閉視窗 + + + &Quit + 離開(&Q) + + + &Edit + 編輯(&E) + + + &Undo + 復原(&U) + + + &Redo + 取消復原(&R) + + + Cu&t + 剪下(&T) + + + &Copy + 複製(&C) + + + &Paste + 貼上(&P) + + + &Find + 尋找(&F) + + + Find Nex&t + 找下一個(&T) + + + Find P&revious + 找上一個(&R) + + + Prefere&nces... + 偏好設定(&N)... + + + Ctrl+, + Ctrl+, + + + &View + 檢視(&V) + + + Ctrl+| + Ctrl+| + + + Shift+Ctrl+B + Shift+Ctrl+B + + + Ctrl+/ + Ctrl+/ + + + Show Menu Bar + 顯示選單列 + + + &Reload Page + 重新載入頁面(&R) + + + &Stop + 停止(&S) + + + Zoom &In + 放大(&I) + + + Zoom &Normal + 正常(&N) + + + Zoom &Out + 縮小(&O) + + + Zoom &Text Only + 只縮放文字(&T) + + + Page S&ource + 頁面原始碼(&O) + + + Ctrl+Alt+U + Ctrl+Alt+U + + + &Full Screen + 全螢幕(&F) + + + Text Encoding + 文字編碼 + + + Hi&story + 歷史(&S) + + + Back + 上一頁 + + + Forward + 下一頁 + + + Home + 首頁 + + + Restore Last Session + 回復上一個階段 + + + &Bookmarks + 書籤(&B) + + + Show All Bookmarks... + 顯示所有書籤... + + + Add Bookmark... + 加入書籤... + + + Add Folder... + 加入資料夾... + + + &Window + 視窗(&W) + + + &Tools + 工具(&T) + + + Web &Search + 網頁搜尋(&S) + + + Ctrl+K + Web Search + Ctrl+K + + + &Clear Private Data + 清除私隱資料(&C) + + + Ctrl+Shift+Delete + Clear Private Data + Ctrl+Shift+Delete + + + Enable Web &Inspector + 啟用網頁檢閱器(&I) + + + &Help + 說明(&H) + + + Switch application language + 切換程式語言 + + + About &Qt + 關於 &Qt + + + About &%1 + About Browser + 關於 &%1 + + + Navigation + 工具列 + + + Show Status Bar + 顯示狀態列 + + + Hide Status Bar + 隱藏狀態列 + + + Show Toolbar + 顯示工具列 + + + Hide Toolbar + 隱藏工具列 + + + Show Bookmarks Bar + 顯示書籤列 + + + Hide Bookmarks Bar + 隱藏書籤列 + + + %1 - Arora + Page title and Browser name + %1 - Arora + + + Open Web Resource + 開啟網頁資源 + + + Web Resources (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*) + 開啟網頁資源 (*.html *.htm *.svg *.png *.gif *.svgz);;所有檔案 (*.*) + + + Print Document + 列印文件 + + + Are you sure you want to turn on private browsing? + 您確定要啟用私密瀏覽? + + + <b>%1</b><br><br>When private browsing is turned on, some actions concerning your privacy will be disabled:<ul><li> Webpages are not added to the history.</li><li> Items are automatically removed from the Downloads window.</li><li> New cookies are not stored, current cookies can't be accessed.</li><li> Site icons won't be stored, session won't be saved.</li><li> Searches are not added to the pop-up menu in the search box.</li><li> Network cache is disabled.</li></ul>Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + <b>%1</b><br><br>當啟用私密瀏覽後,一些關於私隱的功能將會被停用:<ul><li> 網頁不會加入歷史記錄中。</li><li> 項目會自動從下載視窗中移除。</li><li> 不會儲存新的 cookie,亦不會存取目前的 cookie。</li><li> 網站的圖示不會儲存,階段不會儲存。</li><li>搜尋不會加入到搜尋方塊中的彈出式選單。</li><li> 網路快取已被停用。</li></ul>當你關閉視窗時,您仍可按上一頁及下一頁來回到您剛才開啟的網頁。 + + + Are you sure you want to close the window? There are %1 tabs open + 您確定要關閉視窗?還有 %1 個分頁正在開啟 + + + Web Inspector + 網頁檢閱器 + + + The web inspector will only work correctly for pages that were loaded after enabling. +Do you want to reload all pages? + 網頁檢閱器只會在啟用後載入的網頁才會生效。 +您要重新載入全部網頁嗎? + + + Stop loading the current page + 停止載入目前的網頁 + + + Reload the current page + 重新載入目前的網頁 + + + Downloads + 下載 + + + Ctrl+Y + Download Manager + Ctrl+Y + + + Select &All + + + + Alt+Ctrl+B + + + + Options... + + + + Configure Search Engines... + 設定搜索引擎 + + + &Ad Block... + + + + When private browsing is turned on, some actions concerning your privacy will be disabled: + + + + Webpages are not added to the history. + + + + Items are automatically removed from the Downloads window. + + + + New cookies are not stored, current cookies can't be accessed. + + + + Site icons won't be stored. + + + + Session won't be saved. + + + + Searches are not added to the pop-up menu in the search box. + + + + No new network cache is written to disk. + + + + Until you close the window, you can still click the Back and Forward buttons to return to the webpages you have opened. + + + + Private Browsing + + + + + ClearButton + + Clear + 清除 + + + + ClearPrivateData + + Clear Private Data + 清除私隱資料 + + + Clear the following items: + 清除以下項目: + + + &Browsing History + 瀏覽記錄(&B) + + + &Download History + 下載記錄(&D) + + + &Search History + 搜尋記錄(&S) + + + &Cookies + &Cookie + + + C&ached Web Pages + 網頁快取(&A) + + + Website &Icons + 網站圖示(&I) + + + Clear &Private Data + 清除個人私隱資料(&P) + + + &Cancel + 取消(&C) + + + + ClickToFlash + + Load + 載入 + + + Load All + 全部載入 + + + Add %1 to Whitelist + 加入 %1 至白名單 + + + Remove from Whitelist + 從白名單中移除 + + + Settings + 設定 + + + Load Flash + 載入 Flash + + + + ClickToFlashSettings + + Whitelist sites + 白名單網站 + + + + CookieExceptionsModel + + Website + 網站 + + + Rule + 規則 + + + Allow + 允許 + + + Block + 禁止 + + + Allow For Session + 在此階段中允許 + + + + CookieModel + + Website + 網站 + + + Name + 名稱 + + + Path + 路徑 + + + Secure + 安全 + + + Expires + 有效期限 + + + Contents + 內容 + + + true + + + + false + + + + Session cookie + 階段 cookie + + + + CookiesDialog + + Cookies + Cookie + + + &Remove + 移除(&R) + + + Remove &All Cookies + 移除所有 Cookie (&A) + + + Add &Rule + 加入規則(&R) + + + + CookiesExceptionsDialog + + Cookie Exceptions + Cookie 例外 + + + New Exception + 新增例外 + + + Domain: + 網域: + + + Block + 禁止 + + + Allow For Session + 在此階段中允許 + + + Allow + 允許 + + + Exceptions + 例外 + + + &Remove + 移除(&R) + + + Remove &All + 全部移除(&A) + + + + DownloadDialog + + Downloads + 下載 + + + Clean up + 清除 + + + 0 Items + 0 個項目 + + + + DownloadItem + + Ico + Ico + + + Filename + 檔案名稱 + + + Try Again + 再試 + + + Stop + 停止 + + + Open + 開啟 + + + Save File + 儲存檔案 + + + Download canceled: %1 + 下載已取消:%1 + + + Error opening output file: %1 + 開啟輸出檔案時發生錯誤:%1 + + + Error saving: %1 + 儲存時發生錯誤:%1 + + + Network Error: %1 + 網路錯誤:%1 + + + %1 of %2 (%3/sec) - %4 + 已下載%1,共有 %2(%3/秒) - %4 + + + ? + ? + + + %1 of %2 - Stopped + 已下載%1,共有 %2 - 已停止 + + + Download directory (%1) couldn't be created. + + + + + DownloadManager + + There are %1 downloads in progress +Do you want to quit anyway? + 還在 %1 個下載正在進行中 +您還是要離開嗎? + + + %n Download(s) + + %n 個下載 + + + + %n minutes remaining + + 還剩餘 %n 分鐘 + + + + %n seconds remaining + + 還剩餘 %n 秒 + + + + bytes + bytes + + + kB + kB + + + MB + MB + + + GB + GB + + + + FileAccessReply + + No Error + 沒有錯誤 + + + Error opening: %1: No such file or directory + 開啟錯誤:%1:沒有該檔案或目錄 + + + Unable to read %1 + 無法讀取 %1 + + + Contents of %1 + %1 的內容 + + + %1 KB + %1 KB + + + + HistoryDialog + + Open + 開啟 + + + Copy + 複製 + + + Delete + 刪除 + + + History + 歷史記錄 + + + &Remove + 移除(&R) + + + Remove &All + 全部移除(&A) + + + + HistoryMenu + + Show All History + 顯示所有歷史記錄 + + + Clear History... + 清除歷史記錄... + + + Clear History + 清除歷史記錄 + + + Do you want to clear the history? + 您要清除歷史記錄嗎? + + + + HistoryModel + + Title + 標題 + + + Address + 網址 + + + + HistoryTreeModel + + Earlier Today + 今天早前 + + + %n item(s) + + %n 個項目 + + + + + JavaScriptAroraObject + + Welcome to Arora! + + + + Arora Start + + + + Search! + + + + Search results provided by + + + + About Arora + + + + + LanguageManager + + No translation files are installed. + 沒有安裝任何翻譯檔。 + + + Choose language + 選擇語言 + + + <p>You can run with a different language than<br>the operating system default.</p><p>Please choose the language which should be used</p> + <p>您可以系統預設語言外的其它語言來執行。</p><br><p>請選擇語言</p> + + + No translation files are installed at %1. + + + + + NetworkAccessManager + + <qt>Enter username and password for "%1" at %2</qt> + <qt>於%2 輸入“%1”的使用者名稱及密碼</qt> + + + <qt>Connect to proxy "%1" using:</qt> + <qt>連接代理伺服器“%1”使用:</qt> + + + Issuer: %1 + 簽發者:%1 + + + Not valid before: %1 + 在此日期前無效:%1 + + + Valid until: %1 + 有效期至:%1 + + + Alternate Names: + 其它名稱: + + + - SSL Errors + - SSL 錯誤 + + + <qt>SSL Errors:<br/><br/>for: <tt>%1</tt><ul><li>%2</li></ul> + +Do you want to ignore these errors?</qt> + <qt>SSL 錯誤:<br/><br/>因為:<tt>%1</tt><ul><li>%2</li></ul> + +您要忽略此錯誤嗎?</qt> + + + <qt>Certificates:<br/>%1<br/>Do you want to accept all these certificates?</qt> + <qt>憑證:<br/>%1<br/>您要接受全部憑證?</qt> + + + + OpenSearchDialog + + Open File + 開啟檔案 + + + OpenSearch + OpenSearch + + + Error + 錯誤 + + + %1 is not a valid OpenSearch 1.1 description or is already on your list. + %1 不是有效的 OpenSearch 1.1 描述或是已經在您的清單中。 + + + You must have at least one search engine in here. + 在這裡最少要有一個搜索引擎。 + + + OpenSearch Manager + OpenSearch 管理員 + + + &Add + 加入(&A) + + + &Delete + 刪除(&D) + + + &Restore Defaults + 回復預設(&R) + + + &Close + 關閉(&C) + + + + OpenSearchEngineModel + + <strong>Description:</strong> %1 + <strong>描述:</strong> %1 + + + <strong>Provides contextual suggestions</strong> + <strong>提供範圍內的建議</strong> + + + Comma-separated list of keywords that may be entered in the location barfollowed by search terms to search with this engine + + + + Name + 名稱 + + + Keywords + + + + + OpenSearchManager + + Do you want to add the following engine to your list of search engines?<br /><br />Name: %1<br />Searches on: %2 + 您想將以下的搜索引擎加入您的搜索引擎清單嗎?<br /><br />名稱:%1<br />搜尋於:%2 + + + + PasswordDialog + + Authentication Required + 需要認證 + + + DUMMY ICON + DUMMY ICON + + + INTRO TEXT DUMMY + INTRO TEXT DUMM + + + Username: + 使用者名稱: + + + Password: + 密碼: + + + + PlainTextEditSearch + + Not Found + 找不到 + + + + ProxyDialog + + Proxy Authentication + 代理伺服器認證 + + + Connect to proxy + 連接代理伺服器 + + + Username: + 使用者名稱: + + + Password: + 密碼: + + + + QObject + + The file is not an XBEL version 1.0 file. + 檔案不是 XBEL 1.0 版檔案。 + + + Unknown title + 不明的標題 + + + The file is not an OpenSearch 1.1 file. + 檔案不是 OpenSearch 1.1 檔案。 + + + + SearchBanner + + Highlight All + 全部標示 + + + Done + 完成 + + + + SearchLineEdit + + Search + 搜尋 + + + + Settings + + Preferences + 偏好設定 + + + General + 一般 + + + On startup: + 於啟動時: + + + Show my home page + 顯示我的首頁 + + + Show a blank page + 顯示空白頁 + + + Restore windows and tabs from last time + 回復上次的視窗及分頁 + + + Home Page: + 首頁: + + + Set to current page + 設定為目前的網頁 + + + Remove history items: + 移除歷史記錄項目: + + + After one day + 一天後 + + + After one week + 一星期後 + + + After two weeks + 兩星期後 + + + After one month + 一個月後 + + + After one year + 一年後 + + + Manually + 手動 + + + On application exit + 程式離開時 + + + Use the default search engine as fallback when the URL given by the user is invalid + 當使用者輸入的網址無效時,以預設的搜索引擎作為後備 + + + Downloads + 下載 + + + Ask for a destination each time + 每次都詢問目的地 + + + Use this destination: + 使用此目的地 + + + Appearance + 顯示 + + + Standard font: + 標準字型: + + + Select... + 選擇... + + + Fixed-width font: + 固定寬度字型: + + + Preferred languages for viewing webpages in: + 在網頁中偏好使用的語言: + + + Privacy + 私隱 + + + Web Content + 網頁內容 + + + Block Popup Windows + 禁止彈出式視窗 + + + Enable Plugins + 啟用外掛程式 + + + Use ClickToFlash on flash plugins + 在 Flash 加上「載入 flash」按鈕 + + + Enable Javascript + 啟用 Javascript + + + View Images + 顯示圖片 + + + Cookies + Cookie + + + Accept Cookies: + 接受 Cookie + + + Always + 總是 + + + Never + 永不 + + + Only from sites you navigate to + 只有您瀏覽過的網站 + + + Exceptions... + 例外... + + + Keep Cookies Until: + 保留 Cookie 直至: + + + They expire + 它們過期 + + + I exit the application + 我離開程式 + + + At most 90 days + 最多 90 日 + + + Cookies... + Cookie... + + + Filter Tracking Cookies + 過濾追蹤 Cookie + + + Tabs + 分頁 + + + Select tabs and windows as they are created + 當分頁及視窗建立後才選擇它們 + + + Confirm when closing multiple tabs or windows + 關閉多個分頁或視窗時需要確認 + + + Show only one close button instead of one for each tab + 只顯示一個關閉按鈕,而非每個分頁都顯示 + + + Quit the application when last tab is closed + 關閉最後一個分頁時離開程式 + + + Opening links + 開啟連結 + + + Links that want to open in a new window: + 要在新的視窗中開啟的連結: + + + In a new window + 在新的視窗 + + + In a new selected tab in the current window + 在目前視窗中已選的分頁 + + + In a new tab in the current window + 在目前視窗中新的分頁 + + + In the current tab + 在目前的分頁 + + + Open links from applications: + 以其它程式開啟連結: + + + Proxy + 代理伺服器 + + + Use proxy server + 使用代理伺服器 + + + Type: + 類型: + + + Socks5 + Socks5 + + + Http (Secure) + Http(安全) + + + Http (Transparent) + Http(透明) + + + Host name: + 主機名稱: + + + Port: + 連接埠: + + + User Name: + 使用者名稱: + + + Password: + 密碼: + + + Advanced + 進階 + + + Style Sheet: + 樣式表: + + + Enable network cache + 啟用網路快取 + + + Maximum Size: + 大小上限: + + + MB + MB + + + Choose Directory... + + + + A cookie session ends: + + + + When I exit the application + + + + 1 day + + + + 2 days + + + + 3 days + + + + 7 days + + + + 30 days + + + + AutoFill + + + + AutoFill web forms: + + + + User names and passwords + + + + Edit... + + + + Browse... + + + + + SettingsDialog + + Restart required + 須要重新啟動 + + + The network cache configuration has changed. So that it can be taken into account, the browser has to be restarted. + 網路快取設定已經修改。瀏覽器需要重新啟動才能使其生效。 + + + Choose Directory + + + + Choose CSS File + + + + + SourceViewer + + Loading... + 正在載入... + + + &Edit + 編輯(&E) + + + &Find + 尋找(&F) + + + &View + 檢視(&V) + + + &Wrap lines + 自動斷行 + + + Source of Page %1 + %1 的原始碼 + + + + TabBar + + Show Tab Bar + 顯示分頁列 + + + Hide Tab Bar + 隱藏分頁列 + + + Duplicate Tab + 複製分頁 + + + &Close Tab + 關閉分頁(&C) + + + Close &Other Tabs + 關閉其它分頁(&O) + + + Reload Tab + 重新載入分頁 + + + Reload All Tabs + 重新載入所有分頁 + + + + TabWidget + + Untitled + 沒有標題 + + + Saved Tabs + 儲存分頁 + + + Do you really want to close this page? + 您真的要關閉此網頁嗎? + + + You have modified this page and when closing it you would lose the modification. +Do you really want to close this page? + + 您已經修改此網頁及如果關閉它將會失去所有已作的修改。 +您真的要關閉此網頁? + + + Loading... + 正在載入... + + + Loading %1% (%2 %3)... + 正在載入 %1% (%2 %3)... + + + Finished loading + 載入完成 + + + Failed to load + 載入失敗 + + + Show Next Tab + 顯示下一個分頁 + + + Ctrl-] + Ctrl-] + + + Show Previous Tab + 顯示上一個分頁 + + + Ctrl-[ + Ctrl-[ + + + Recently Closed Tabs + 最近關閉分頁 + + + New &Tab + 新增分頁(&T) + + + &Close Tab + 關閉分頁(&C) + + + Bookmark All Tabs + 將所有分頁加入書籤 + + + + ToolbarSearch + + Suggestions + 建議 + + + Add '%1' + 加入‘%1’ + + + Configure Search Engines... + 設定搜索引擎 + + + Clear Recent Searches + 清除最近搜尋 + + + No Recent Searches + 最近沒有搜尋 + + + Recent Searches + 最近搜尋 + + + + WebPage + + Resending POST request + 再送出 POST 要求 + + + In order to display the site, the request along with all the data must be sent once again, which may lead to some unexpected behaviour of the site e.g. the same action might be performed once again. Do you want to continue anyway? + 要顯示此網站,所有的請求都要重新送出,這可能會導致一些無法預料的行為,例如某些會再做一次。您要繼續嗎? + + + Error loading page: %1 + 載入網頁發生錯誤:%1 + + + When connecting to: %1. + 當連線到:%1。 + + + Check the address for errors such as <b>ww</b>.arora-browser.org instead of <b>www</b>.arora-browser.org + 檢查網址錯誤,例如是<b>ww</b>.arora-browser.org,而不是<b>www</b>.arora-browser.org + + + If the address is correct, try checking the network connection. + 如果網址正確,請檢查網路連線。 + + + If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network. + 如果您的電腦受防火牆或代理伺服器保護,請確定您的瀏覽器允許存取網路。 + + + + WebView + + Open in New &Window + 在新的視窗中開啟(&W) + + + Open in New &Tab + 在新的分頁中開啟(&T) + + + Save Lin&k + 儲存連結(&K) + + + &Bookmark This Link + 將此連結加入書籤(&B) + + + &Copy Link Location + 複製連結位置(&C) + + + Open Image in New &Window + 在新的視窗開啟圖片(&W) + + + Open Image in New &Tab + 在新的分頁開啟圖片(&T) + + + &Save Image + 儲存圖片(&S) + + + &Copy Image + 複製圖片(&C) + + + C&opy Image Location + 複製圖片位置(&O) + + + Search with... + 搜尋於... + + + Add to the toolbar search + 加入至工具列搜尋 + + + Method not supported + 方法不支援 + + + %1 method is not supported. + % 的方法不支援。 + + + Search engine + 搜索引擎 + + + Choose the desired search engine + 選擇搜索引擎 + + + Engine name + 引擎名稱 + + + Type in a name for the engine + 輸入搜索引擎的名稱 + + + Loading... + 正在載入... + + + Block Image + + + + + WebViewSearch + + Not Found + 找不到 + + + diff --git a/src/locationbar/locationbar.cpp b/src/locationbar/locationbar.cpp new file mode 100644 index 00000000..c9f53358 --- /dev/null +++ b/src/locationbar/locationbar.cpp @@ -0,0 +1,195 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "locationbar.h" + +#include "browserapplication.h" +#include "clearbutton.h" +#include "locationbarsiteicon.h" +#include "privacyindicator.h" +#include "searchlineedit.h" +#include "webview.h" + +#include +#include +#include +#include + +#include + +LocationBar::LocationBar(QWidget *parent) + : LineEdit(parent) + , m_webView(0) + , m_siteIcon(0) + , m_privacyIndicator(0) +{ + // Urls are always LeftToRight + setLayoutDirection(Qt::LeftToRight); + + setUpdatesEnabled(false); + // site icon on the left + m_siteIcon = new LocationBarSiteIcon(this); + addWidget(m_siteIcon, LeftSide); + + // privacy indicator at rightmost position + m_privacyIndicator = new PrivacyIndicator(this); + addWidget(m_privacyIndicator, RightSide); + + // clear button on the right + ClearButton *m_clearButton = new ClearButton(this); + connect(m_clearButton, SIGNAL(clicked()), + this, SLOT(clear())); + connect(this, SIGNAL(textChanged(const QString&)), + m_clearButton, SLOT(textChanged(const QString&))); + addWidget(m_clearButton, RightSide); + + updateTextMargins(); + setUpdatesEnabled(true); +} + +void LocationBar::setWebView(WebView *webView) +{ + Q_ASSERT(webView); + m_webView = webView; + m_siteIcon->setWebView(webView); + connect(webView, SIGNAL(urlChanged(const QUrl &)), + this, SLOT(webViewUrlChanged(const QUrl &))); + connect(webView, SIGNAL(loadProgress(int)), + this, SLOT(update())); +} + +WebView *LocationBar::webView() const +{ + return m_webView; +} + +void LocationBar::webViewUrlChanged(const QUrl &url) +{ + if (hasFocus()) + return; + setText(QString::fromUtf8(url.toEncoded())); + setCursorPosition(0); +} + +void LocationBar::paintEvent(QPaintEvent *event) +{ + QPalette p = palette(); + QColor defaultBaseColor = QApplication::palette().color(QPalette::Base); + QColor backgroundColor = defaultBaseColor; + if (m_webView && m_webView->url().scheme() == QLatin1String("https") + && p.color(QPalette::Text).value() < 128) { + QColor lightYellow(248, 248, 210); + backgroundColor = lightYellow; + } + + // set the progress bar + if (m_webView) { + int progress = m_webView->progress(); + if (progress == 0) { + p.setBrush(QPalette::Base, backgroundColor); + } else { + QColor loadingColor = QColor(116, 192, 250); + if (p.color(QPalette::Text).value() >= 128) + loadingColor = defaultBaseColor.darker(200); + + QLinearGradient gradient(0, 0, width(), 0); + gradient.setColorAt(0, loadingColor); + gradient.setColorAt(((double)progress)/100, backgroundColor); + p.setBrush(QPalette::Base, gradient); + } + setPalette(p); + } + + LineEdit::paintEvent(event); +} + +void LocationBar::focusOutEvent(QFocusEvent *event) +{ + if (text().isEmpty() && m_webView) + webViewUrlChanged(m_webView->url()); + QLineEdit::focusOutEvent(event); +} + +void LocationBar::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + selectAll(); + else + QLineEdit::mouseDoubleClickEvent(event); +} + +void LocationBar::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && m_webView) { + setText(QString::fromUtf8(m_webView->url().toEncoded())); + selectAll(); + return; + } + + QString currentText = text().trimmed(); + if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) + && !currentText.startsWith(QLatin1String("http://"), Qt::CaseInsensitive)) { + QString append; + if (event->modifiers() == Qt::ControlModifier) + append = QLatin1String(".com"); + else if (event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) + append = QLatin1String(".org"); + else if (event->modifiers() == Qt::ShiftModifier) + append = QLatin1String(".net"); + QUrl url(QLatin1String("http://") + currentText); + QString host = url.host(); + if (!host.endsWith(append, Qt::CaseInsensitive)) { + host += append; + url.setHost(host); + setText(url.toString()); + } + } + + LineEdit::keyPressEvent(event); +} + +void LocationBar::dragEnterEvent(QDragEnterEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + if (mimeData->hasUrls() || mimeData->hasText()) + event->acceptProposedAction(); + + LineEdit::dragEnterEvent(event); +} + +void LocationBar::dropEvent(QDropEvent *event) +{ + const QMimeData *mimeData = event->mimeData(); + + QUrl url; + if (mimeData->hasUrls()) + url = mimeData->urls().at(0); + else if (mimeData->hasText()) + url = QUrl::fromEncoded(mimeData->text().toUtf8(), QUrl::TolerantMode); + + if (url.isEmpty() || !url.isValid()) { + LineEdit::dropEvent(event); + return; + } + + setText(QString::fromUtf8(url.toEncoded())); + selectAll(); + + event->acceptProposedAction(); +} diff --git a/src/locationbar/locationbar.h b/src/locationbar/locationbar.h new file mode 100644 index 00000000..c54401be --- /dev/null +++ b/src/locationbar/locationbar.h @@ -0,0 +1,59 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LOCATIONBAR_H +#define LOCATIONBAR_H + +#include "lineedit.h" + +#include +#include + +class WebView; +class LocationBarSiteIcon; +class PrivacyIndicator; +class LocationBar : public LineEdit +{ + Q_OBJECT + +public: + LocationBar(QWidget *parent = 0); + void setWebView(WebView *webView); + WebView *webView() const; + +protected: + void paintEvent(QPaintEvent *event); + void focusOutEvent(QFocusEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + +private slots: + void webViewUrlChanged(const QUrl &url); + +private: + QPointer m_webView; + + LocationBarSiteIcon *m_siteIcon; + PrivacyIndicator *m_privacyIndicator; +}; + +#endif // LOCATIONBAR_H + diff --git a/src/locationbar/locationbar.pri b/src/locationbar/locationbar.pri new file mode 100644 index 00000000..ba33005d --- /dev/null +++ b/src/locationbar/locationbar.pri @@ -0,0 +1,13 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + locationbar.h \ + locationbarsiteicon.h \ + privacyindicator.h + +SOURCES += \ + locationbar.cpp \ + locationbarsiteicon.cpp \ + privacyindicator.cpp + diff --git a/src/locationbar/locationbarsiteicon.cpp b/src/locationbar/locationbarsiteicon.cpp new file mode 100644 index 00000000..f5947006 --- /dev/null +++ b/src/locationbar/locationbarsiteicon.cpp @@ -0,0 +1,82 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "locationbarsiteicon.h" + +#include +#include + +#include "browserapplication.h" +#include "webview.h" + +LocationBarSiteIcon::LocationBarSiteIcon(QWidget *parent) + : QLabel(parent) + , m_webView(0) +{ + resize(QSize(16, 16)); + webViewSiteIconChanged(); + setCursor(Qt::ArrowCursor); + show(); +} + +void LocationBarSiteIcon::setWebView(WebView *webView) +{ + m_webView = webView; + connect(webView, SIGNAL(loadFinished(bool)), + this, SLOT(webViewSiteIconChanged())); + connect(webView, SIGNAL(iconChanged()), + this, SLOT(webViewSiteIconChanged())); +} + +void LocationBarSiteIcon::webViewSiteIconChanged() +{ + QUrl url; + if (m_webView) + url = m_webView->url(); + setPixmap(BrowserApplication::instance()->icon(url).pixmap(16, 16)); +} + +void LocationBarSiteIcon::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + m_dragStartPos = event->pos(); + QLabel::mousePressEvent(event); +} + +void LocationBarSiteIcon::mouseMoveEvent(QMouseEvent *event) +{ + if (event->buttons() == Qt::LeftButton + && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance() + && m_webView) { + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + QString title = m_webView->title(); + if (title.isEmpty()) + title = QString::fromUtf8(m_webView->url().toEncoded()); + mimeData->setText(title); + QList urls; + urls.append(m_webView->url()); + mimeData->setUrls(urls); + const QPixmap *p = pixmap(); + if (p) + drag->setPixmap(*p); + drag->setMimeData(mimeData); + drag->exec(); + } +} diff --git a/src/locationbar/locationbarsiteicon.h b/src/locationbar/locationbarsiteicon.h new file mode 100644 index 00000000..60fedf62 --- /dev/null +++ b/src/locationbar/locationbarsiteicon.h @@ -0,0 +1,48 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef LOCATIONBARSITEICON_H +#define LOCATIONBARSITEICON_H + +#include + +class WebView; +class LocationBarSiteIcon : public QLabel +{ + Q_OBJECT + +public: + LocationBarSiteIcon(QWidget *parent = 0); + void setWebView(WebView *webView); + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +private slots: + void webViewSiteIconChanged(); + +private: + WebView *m_webView; + QPoint m_dragStartPos; + +}; + +#endif // LOCATIONBARSITEICON_H + diff --git a/src/locationbar/privacyindicator.cpp b/src/locationbar/privacyindicator.cpp new file mode 100644 index 00000000..7e17b175 --- /dev/null +++ b/src/locationbar/privacyindicator.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2009-2010 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "privacyindicator.h" + +#include "browserapplication.h" + +PrivacyIndicator::PrivacyIndicator(QWidget *parent) + : QLabel(parent) +{ + setPixmap(QPixmap(QLatin1String(":graphics/private.png"))); + connect(BrowserApplication::instance(), SIGNAL(privacyChanged(bool)), + this, SLOT(setVisible(bool))); + setCursor(Qt::ArrowCursor); + setVisible(BrowserApplication::isPrivate()); +} + +void PrivacyIndicator::mousePressEvent(QMouseEvent *event) +{ + Q_UNUSED(event) + BrowserApplication::instance()->setPrivate(false); +} diff --git a/src/locationbar/privacyindicator.h b/src/locationbar/privacyindicator.h new file mode 100644 index 00000000..45d89ffb --- /dev/null +++ b/src/locationbar/privacyindicator.h @@ -0,0 +1,38 @@ +/* + * Copyright 2009-2010 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PRIVACYINDICATOR_H +#define PRIVACYINDICATOR_H + +#include + +class PrivacyIndicator : public QLabel +{ + Q_OBJECT + +public: + PrivacyIndicator(QWidget *parent = 0); + +protected: + void mousePressEvent(QMouseEvent *event); + +}; + +#endif // PRIVACYINDICATOR_H + diff --git a/src/main.cpp b/src/main.cpp index c1134128..a5405d56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,54 +1,41 @@ -/**************************************************************************** -** -** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ #include "browserapplication.h" +#ifdef Q_OS_WIN +#include "explorerstyle.h" +#endif + int main(int argc, char **argv) { + Q_INIT_RESOURCE(htmls); Q_INIT_RESOURCE(data); +#ifdef Q_WS_X11 + QApplication::setGraphicsSystem(QString::fromLatin1("raster")); +#endif BrowserApplication application(argc, argv); - if (!application.isTheOnlyBrowser()) + if (!application.isRunning()) return 0; +#ifdef Q_OS_WIN + application.setStyle(new ExplorerStyle); +#endif application.newMainWindow(); return application.exec(); } diff --git a/src/modelmenu.cpp b/src/modelmenu.cpp index e256667f..4f95d090 100644 --- a/src/modelmenu.cpp +++ b/src/modelmenu.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,20 +63,27 @@ #include "modelmenu.h" +#include "browserapplication.h" + #include +#include +#include #include -ModelMenu::ModelMenu(QWidget * parent) +ModelMenu::ModelMenu(QWidget *parent) : QMenu(parent) - , m_maxRows(7) + , m_maxRows(-1) , m_firstSeparator(-1) , m_maxWidth(-1) , m_statusBarTextRole(0) , m_separatorRole(0) , m_model(0) { + setAcceptDrops(true); + connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); + connect(this, SIGNAL(triggered(QAction*)), this, SLOT(actionTriggered(QAction*))); } bool ModelMenu::prePopulated() @@ -150,17 +158,8 @@ int ModelMenu::separatorRole() const Q_DECLARE_METATYPE(QModelIndex) void ModelMenu::aboutToShow() { - if (QMenu *menu = qobject_cast(sender())) { - QVariant v = menu->menuAction()->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); - createMenu(idx, -1, menu, menu); - disconnect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); - return; - } - } - clear(); + if (prePopulated()) addSeparator(); int max = m_maxRows; @@ -170,26 +169,38 @@ void ModelMenu::aboutToShow() postPopulated(); } +ModelMenu *ModelMenu::createBaseMenu() +{ + return new ModelMenu(this); +} + void ModelMenu::createMenu(const QModelIndex &parent, int max, QMenu *parentMenu, QMenu *menu) { if (!menu) { - QString title = parent.data().toString(); - menu = new QMenu(title, this); - QIcon icon = qvariant_cast(parent.data(Qt::DecorationRole)); - menu->setIcon(icon); - parentMenu->addMenu(menu); QVariant v; v.setValue(parent); - menu->menuAction()->setData(v); - connect(menu, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); + + QString title = parent.data().toString(); + ModelMenu *modelMenu = createBaseMenu(); + // triggered goes all the way up the menu structure + disconnect(modelMenu, SIGNAL(triggered(QAction*)), + modelMenu, SLOT(actionTriggered(QAction*))); + modelMenu->setTitle(title); + QIcon icon = qvariant_cast(parent.data(Qt::DecorationRole)); + modelMenu->setIcon(icon); + parentMenu->addMenu(modelMenu)->setData(v); + modelMenu->setRootIndex(parent); + modelMenu->setModel(m_model); return; } + if (!m_model) + return; + int end = m_model->rowCount(parent); if (max != -1) end = qMin(max, end); - connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*))); for (int i = 0; i < end; ++i) { QModelIndex idx = m_model->index(i, 0, parent); @@ -228,12 +239,115 @@ QAction *ModelMenu::makeAction(const QIcon &icon, const QString &text, QObject * return new QAction(icon, smallText, parent); } -void ModelMenu::triggered(QAction *action) +void ModelMenu::actionTriggered(QAction *action) { - QVariant v = action->data(); - if (v.canConvert()) { - QModelIndex idx = qvariant_cast(v); + QModelIndex idx = index(action); + if (idx.isValid()) emit activated(idx); +} + +QModelIndex ModelMenu::index(QAction *action) +{ + if (!action) + return QModelIndex(); + QVariant variant = action->data(); + if (!variant.canConvert()) + return QModelIndex(); + + return qvariant_cast(variant); +} + +void ModelMenu::dragEnterEvent(QDragEnterEvent *event) +{ + if (!m_model) { + QMenu::dragEnterEvent(event); + return; + } + + QStringList mimeTypes = m_model->mimeTypes(); + foreach (const QString &mimeType, mimeTypes) { + if (event->mimeData()->hasFormat(mimeType)) + event->acceptProposedAction(); + } + + QMenu::dragEnterEvent(event); +} + +void ModelMenu::dropEvent(QDropEvent *event) +{ + if (!m_model) { + QMenu::dropEvent(event); + return; + } + + int row; + QAction *action = actionAt(mapFromGlobal(QCursor::pos())); + QModelIndex index; + QModelIndex parentIndex = m_root; + if (!action) { + row = m_model->rowCount(m_root); + } else { + index = this->index(action); + Q_ASSERT(index.isValid()); + row = index.row(); + + if (m_model->hasChildren(index)) + parentIndex = index; + } + + event->acceptProposedAction(); + m_model->dropMimeData(event->mimeData(), event->dropAction(), row, 0, parentIndex); + QMenu::dropEvent(event); +} + +void ModelMenu::mousePressEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + m_dragStartPos = event->pos(); + QMenu::mousePressEvent(event); +} + +void ModelMenu::mouseReleaseEvent(QMouseEvent *event) +{ + BrowserApplication::instance()->setEventMouseButtons(event->button()); + BrowserApplication::instance()->setEventKeyboardModifiers(event->modifiers()); + QMenu::mouseReleaseEvent(event); +} + +void ModelMenu::mouseMoveEvent(QMouseEvent *event) +{ + int manhattanLength = (event->pos() - m_dragStartPos).manhattanLength(); + + if (manhattanLength <= QApplication::startDragDistance()) { + QMenu::mouseMoveEvent(event); + return; + } + + if (!(event->buttons() & Qt::LeftButton)) { + QMenu::mouseMoveEvent(event); + return; + } + + QAction *action = actionAt(m_dragStartPos); + QModelIndex idx = index(action); + + if (!idx.isValid()) { + QMenu::mouseMoveEvent(event); + return; + } + + QDrag *drag = new QDrag(this); + drag->setMimeData(m_model->mimeData((QModelIndexList() << idx))); + QRect actionRect = actionGeometry(action); + drag->setPixmap(QPixmap::grabWidget(this, actionRect)); + + if (drag->exec() == Qt::MoveAction) { + m_model->removeRow(idx.row(), m_root); + + if (!this->isAncestorOf(drag->target())) + close(); + else + aboutToShow(); } } diff --git a/src/modelmenu.h b/src/modelmenu.h index a5dd4612..801fa8c6 100644 --- a/src/modelmenu.h +++ b/src/modelmenu.h @@ -1,5 +1,6 @@ /* * Copyright 2008 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -96,18 +97,29 @@ class ModelMenu : public QMenu int separatorRole() const; QAction *makeAction(const QIcon &icon, const QString &text, QObject *parent); + QModelIndex index(QAction *action); protected: // add any actions before the tree, return true if any actions are added. virtual bool prePopulated(); // add any actions after the tree virtual void postPopulated(); + // return the QMenu that is used to populate sub menu's + virtual ModelMenu *createBaseMenu(); + // put all of the children of parent into menu up to max void createMenu(const QModelIndex &parent, int max, QMenu *parentMenu = 0, QMenu *menu = 0); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + private slots: void aboutToShow(); - void triggered(QAction *action); + void actionTriggered(QAction *action); private: QAction *makeAction(const QModelIndex &index); @@ -118,6 +130,7 @@ private slots: int m_separatorRole; QAbstractItemModel *m_model; QPersistentModelIndex m_root; + QPoint m_dragStartPos; }; #endif // MODELMENU_H diff --git a/src/modeltoolbar.cpp b/src/modeltoolbar.cpp new file mode 100644 index 00000000..12b77b9c --- /dev/null +++ b/src/modeltoolbar.cpp @@ -0,0 +1,259 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "modeltoolbar.h" + +#include "browserapplication.h" +#include "modelmenu.h" + +#include +#include + +ModelToolBar::ModelToolBar(QWidget *parent) + : QToolBar(parent) + , m_model(0) +{ + if (isVisible()) + build(); + + setAcceptDrops(true); +} + +ModelToolBar::ModelToolBar(const QString &title, QWidget *parent) + : QToolBar(title, parent) + , m_model(0) +{ + if (isVisible()) + build(); + + setAcceptDrops(true); +} + +void ModelToolBar::setModel(QAbstractItemModel *model) +{ + if (m_model) { + disconnect(m_model, SIGNAL(modelReset()), + this, SLOT(build())); + disconnect(m_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(build())); + disconnect(m_model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(build())); + disconnect(m_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(build())); + } + + m_model = model; + + if (m_model) { + connect(m_model, SIGNAL(modelReset()), + this, SLOT(build())); + connect(m_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(build())); + connect(m_model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(build())); + connect(m_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(build())); + } +} + +QAbstractItemModel *ModelToolBar::model() const +{ + return m_model; +} + +void ModelToolBar::setRootIndex(const QModelIndex &index) +{ + m_rootIndex = index; +} + +QModelIndex ModelToolBar::rootIndex() const +{ + return m_rootIndex; +} + +void ModelToolBar::build() +{ + Q_ASSERT(m_model); + + clear(); + + for (int i = 0; i < m_model->rowCount(m_rootIndex); ++i) { + QModelIndex index = m_model->index(i, 0, m_rootIndex); + QVariant variant; + variant.setValue(index); + + QString title = index.data(Qt::DisplayRole).toString(); + QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); + bool hasChildren = m_model->hasChildren(index); + + QAction *action = addAction(icon, title); + action->setData(variant); + + QWidget *actionWidget = widgetForAction(action); + QToolButton *button = qobject_cast(actionWidget); + Q_ASSERT(button); + button->installEventFilter(this); + + if (hasChildren) { + ModelMenu *menu = createMenu(); + menu->setModel(m_model); + menu->setRootIndex(index); + action->setMenu(menu); + button->setPopupMode(QToolButton::InstantPopup); + button->setArrowType(Qt::DownArrow); + } + } +} + +QModelIndex ModelToolBar::index(QAction *action) +{ + if (!action) + return QModelIndex(); + + QVariant variant = action->data(); + if (!variant.canConvert()) + return QModelIndex(); + + QModelIndex index = qvariant_cast(variant); + return index; +} + +ModelMenu *ModelToolBar::createMenu() +{ + return new ModelMenu(this); +} + +bool ModelToolBar::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::MouseButtonRelease) { + QToolButton *button = static_cast(object); + Q_ASSERT(button); + + QMouseEvent *mouseEvent = static_cast(event); + + BrowserApplication::instance()->setEventMouseButtons(mouseEvent->button()); + BrowserApplication::instance()->setEventKeyboardModifiers(mouseEvent->modifiers()); + QAction *action = button->defaultAction(); + Q_ASSERT(action); + QModelIndex index = this->index(action); + Q_ASSERT(this->index(action).isValid()); + emit activated(index); + } else if (event->type() == QEvent::MouseButtonPress) { + Q_ASSERT(static_cast(object)); + + QMouseEvent *mouseEvent = static_cast(event); + + if (mouseEvent->buttons() & Qt::LeftButton) + m_dragStartPos = mapFromGlobal(mouseEvent->globalPos()); + } + + return false; +} + +void ModelToolBar::dragEnterEvent(QDragEnterEvent *event) +{ + if (!m_model) { + QToolBar::dragEnterEvent(event); + return; + } + + QStringList mimeTypes = m_model->mimeTypes(); + foreach (const QString &mimeType, mimeTypes) { + if (event->mimeData()->hasFormat(mimeType)) + event->acceptProposedAction(); + } + + QToolBar::dragEnterEvent(event); +} + +void ModelToolBar::hideEvent(QHideEvent *event) +{ + clear(); + QToolBar::hideEvent(event); +} + +void ModelToolBar::showEvent(QShowEvent *event) +{ + if (actions().isEmpty()) + build(); + QToolBar::showEvent(event); +} + +void ModelToolBar::dropEvent(QDropEvent *event) +{ + if (!m_model) { + QToolBar::dropEvent(event); + return; + } + + int row; + QAction *action = actionAt(mapFromGlobal(QCursor::pos())); + QModelIndex index; + QModelIndex parentIndex = m_rootIndex; + if (!action) { + row = m_model->rowCount(m_rootIndex); + } else { + index = this->index(action); + Q_ASSERT(index.isValid()); + row = index.row(); + + if (m_model->hasChildren(index)) + parentIndex = index; + } + + event->acceptProposedAction(); + m_model->dropMimeData(event->mimeData(), event->dropAction(), row, 0, parentIndex); + QToolBar::dropEvent(event); +} + +void ModelToolBar::mouseMoveEvent(QMouseEvent *event) +{ + if (!m_model) { + QToolBar::mouseMoveEvent(event); + return; + } + + if (!(event->buttons() & Qt::LeftButton)) { + QToolBar::mouseMoveEvent(event); + return; + } + + int manhattanLength = (event->pos() - m_dragStartPos).manhattanLength(); + if (manhattanLength <= QApplication::startDragDistance()) { + QToolBar::mouseMoveEvent(event); + return; + } + + QAction *action = actionAt(m_dragStartPos); + if (!action) { + QToolBar::mouseMoveEvent(event); + return; + } + + QPersistentModelIndex index = this->index(action); + Q_ASSERT(index.isValid()); + + QDrag *drag = new QDrag(this); + drag->setMimeData(m_model->mimeData(QModelIndexList() << index)); + QRect actionRect = actionGeometry(action); + drag->setPixmap(QPixmap::grabWidget(this, actionRect)); + + if (drag->exec() == Qt::MoveAction) + m_model->removeRow(index.row(), m_rootIndex); +} diff --git a/src/modeltoolbar.h b/src/modeltoolbar.h new file mode 100644 index 00000000..820b7a77 --- /dev/null +++ b/src/modeltoolbar.h @@ -0,0 +1,70 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef MODELTOOLBAR_H +#define MODELTOOLBAR_H + +#include + +#include + +Q_DECLARE_METATYPE(QModelIndex) + +class QEvent; +class ModelMenu; +class ModelToolBar : public QToolBar +{ + Q_OBJECT + +signals: + void activated(const QModelIndex &index); + +public: + ModelToolBar(QWidget *parent = 0); + ModelToolBar(const QString &title, QWidget *parent = 0); + + void setModel(QAbstractItemModel *model); + QAbstractItemModel *model() const; + + void setRootIndex(const QModelIndex &index); + QModelIndex rootIndex() const; + + static QModelIndex index(QAction *action); + +protected: + virtual ModelMenu *createMenu(); + + bool eventFilter(QObject *object, QEvent *event); + + void hideEvent(QHideEvent *event); + void showEvent(QShowEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dropEvent(QDropEvent *event); + void mouseMoveEvent(QMouseEvent *event); + +protected slots: + void build(); + +private: + QAbstractItemModel *m_model; + QPersistentModelIndex m_rootIndex; + QPoint m_dragStartPos; +}; + +#endif // MODELTOOLBAR_H diff --git a/src/network/cookiejar/cookiedialog.cpp b/src/network/cookiejar/cookiedialog.cpp new file mode 100644 index 00000000..5056147d --- /dev/null +++ b/src/network/cookiejar/cookiedialog.cpp @@ -0,0 +1,133 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "cookiedialog.h" + +#include +#include +#include + +#include "cookiemodel.h" +#include "cookieexceptionsdialog.h" + +CookieDialog::CookieDialog(CookieJar *cookieJar, QWidget *parent) + : QDialog(parent) + , m_cookieJar(cookieJar) +{ + setupUi(this); + setWindowFlags(Qt::Sheet); + CookieModel *model = new CookieModel(cookieJar, this); + m_proxyModel = new QSortFilterProxyModel(this); + connect(search, SIGNAL(textChanged(QString)), + m_proxyModel, SLOT(setFilterFixedString(QString))); + connect(removeButton, SIGNAL(clicked()), cookiesTable, SLOT(removeSelected())); + connect(removeAllButton, SIGNAL(clicked()), cookiesTable, SLOT(removeAll())); + connect(addRuleButton, SIGNAL(clicked()), this, SLOT(addRule())); + m_proxyModel->setSourceModel(model); + m_proxyModel->setSortRole(CookieModel::SortRole); + cookiesTable->verticalHeader()->hide(); + cookiesTable->setSelectionBehavior(QAbstractItemView::SelectRows); + cookiesTable->setModel(m_proxyModel); + cookiesTable->setAlternatingRowColors(true); + cookiesTable->setTextElideMode(Qt::ElideMiddle); + cookiesTable->setShowGrid(false); + cookiesTable->setSortingEnabled(true); + QFont f = font(); + f.setPointSize(10); + QFontMetrics fm(f); + int height = fm.height() + fm.height() / 3; + cookiesTable->verticalHeader()->setDefaultSectionSize(height); + cookiesTable->verticalHeader()->setMinimumSectionSize(-1); + for (int i = 0; i < model->columnCount(); ++i) { + int header = cookiesTable->horizontalHeader()->sectionSizeHint(i); + switch (i) { + case 0: + header = fm.width(QLatin1String("averagehost.domain.com")); + break; + case 1: + header = fm.width(QLatin1String("_session_id")); + break; + case 4: + header = fm.width(QDateTime::currentDateTime().toString(Qt::LocalDate)); + break; + } + int buffer = fm.width(QLatin1String("xx")); + header += buffer; + cookiesTable->horizontalHeader()->resizeSection(i, header); + } + cookiesTable->horizontalHeader()->setStretchLastSection(true); +} + +void CookieDialog::addRule() +{ + const QModelIndexList selection = cookiesTable->selectionModel()->selectedRows(); + if (selection.isEmpty()) + return; + QModelIndex firstSelected = selection.at(0); + QModelIndex domainSelection = firstSelected.sibling(firstSelected.row(), 0); + QString domain = m_proxyModel->data(domainSelection, Qt::DisplayRole).toString(); + CookieExceptionsDialog dialog(m_cookieJar, this); + dialog.setDomainName(domain); + dialog.exec(); +} + + diff --git a/src/edittableview.h b/src/network/cookiejar/cookiedialog.h similarity index 86% rename from src/edittableview.h rename to src/network/cookiejar/cookiedialog.h index e7c95f95..abdbd4b3 100644 --- a/src/edittableview.h +++ b/src/network/cookiejar/cookiedialog.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,23 +60,29 @@ ** ****************************************************************************/ -#ifndef EDITTABLEVIEW_H -#define EDITTABLEVIEW_H +#ifndef COOKIEDIALOG_H +#define COOKIEDIALOG_H -#include +#include -class EditTableView : public QTableView +#include "ui_cookies.h" + +class CookieJar; +class QSortFilterProxyModel; +class CookieDialog : public QDialog, public Ui_CookiesDialog { Q_OBJECT public: - EditTableView(QWidget *parent = 0); - void keyPressEvent(QKeyEvent *event); + CookieDialog(CookieJar *cookieJar, QWidget *parent = 0); + +private: + QSortFilterProxyModel *m_proxyModel; + CookieJar *m_cookieJar; -public slots: - void removeSelected(); - void removeAll(); +private slots: + void addRule(); }; -#endif // EDITTABLEVIEW_H +#endif // COOKIEDIALOG_H diff --git a/src/network/cookiejar/cookieexceptionsdialog.cpp b/src/network/cookiejar/cookieexceptionsdialog.cpp new file mode 100644 index 00000000..4e9dcb78 --- /dev/null +++ b/src/network/cookiejar/cookieexceptionsdialog.cpp @@ -0,0 +1,160 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "cookieexceptionsdialog.h" + +#include + +#include +#include +#include "cookiemodel.h" +#include "cookiejar.h" +#include "cookieexceptionsmodel.h" + +CookieExceptionsDialog::CookieExceptionsDialog(CookieJar *cookieJar, QWidget *parent) + : QDialog(parent) + , m_cookieJar(cookieJar) +{ + setupUi(this); + setWindowFlags(Qt::Sheet); + connect(removeButton, SIGNAL(clicked()), exceptionTable, SLOT(removeSelected())); + connect(removeAllButton, SIGNAL(clicked()), exceptionTable, SLOT(removeAll())); + exceptionTable->verticalHeader()->hide(); + exceptionTable->setSelectionBehavior(QAbstractItemView::SelectRows); + exceptionTable->setAlternatingRowColors(true); + exceptionTable->setTextElideMode(Qt::ElideMiddle); + exceptionTable->setShowGrid(false); + exceptionTable->setSortingEnabled(true); + m_exceptionsModel = new CookieExceptionsModel(cookieJar, this); + m_proxyModel = new QSortFilterProxyModel(this); + m_proxyModel->setSourceModel(m_exceptionsModel); + connect(search, SIGNAL(textChanged(QString)), + m_proxyModel, SLOT(setFilterFixedString(QString))); + exceptionTable->setModel(m_proxyModel); + + CookieModel *cookieModel = new CookieModel(cookieJar, this); + domainLineEdit->setCompleter(new QCompleter(cookieModel, domainLineEdit)); + + connect(domainLineEdit, SIGNAL(textChanged(const QString &)), + this, SLOT(textChanged(const QString &))); + connect(blockButton, SIGNAL(clicked()), this, SLOT(block())); + connect(allowButton, SIGNAL(clicked()), this, SLOT(allow())); + connect(allowForSessionButton, SIGNAL(clicked()), this, SLOT(allowForSession())); + + QFont f = font(); + f.setPointSize(10); + QFontMetrics fm(f); + int height = fm.height() + fm.height() / 3; + exceptionTable->verticalHeader()->setDefaultSectionSize(height); + exceptionTable->verticalHeader()->setMinimumSectionSize(-1); + for (int i = 0; i < m_exceptionsModel->columnCount(); ++i) { + int header = exceptionTable->horizontalHeader()->sectionSizeHint(i); + switch (i) { + case 0: + header = fm.width(QLatin1String("averagebiglonghost.domain.com")); + break; + case 1: + header = fm.width(QLatin1String("Allow For Session")); + break; + } + int buffer = fm.width(QLatin1String("xx")); + header += buffer; + exceptionTable->horizontalHeader()->resizeSection(i, header); + } +} + +void CookieExceptionsDialog::textChanged(const QString &text) +{ + bool enabled = !text.isEmpty(); + blockButton->setEnabled(enabled); + allowButton->setEnabled(enabled); + allowForSessionButton->setEnabled(enabled); +} + +void CookieExceptionsDialog::setDomainName(const QString &domainName) +{ + domainLineEdit->setText(domainName); +} + +void CookieExceptionsDialog::block() +{ + m_exceptionsModel->addRule(domainLineEdit->text(), CookieJar::Block); +} + +void CookieExceptionsDialog::allow() +{ + m_exceptionsModel->addRule(domainLineEdit->text(), CookieJar::Allow); +} + +void CookieExceptionsDialog::allowForSession() +{ + m_exceptionsModel->addRule(domainLineEdit->text(), CookieJar::AllowForSession); +} + +void CookieExceptionsDialog::accept() +{ + m_cookieJar->setBlockedCookies(m_exceptionsModel->m_blockedCookies); + m_cookieJar->setAllowedCookies(m_exceptionsModel->m_allowedCookies); + m_cookieJar->setAllowForSessionCookies(m_exceptionsModel->m_sessionCookies); + QDialog::accept(); +} + diff --git a/src/networkaccessmanager.h b/src/network/cookiejar/cookieexceptionsdialog.h similarity index 79% rename from src/networkaccessmanager.h rename to src/network/cookiejar/cookieexceptionsdialog.h index 05352ba9..0e2176dc 100644 --- a/src/networkaccessmanager.h +++ b/src/network/cookiejar/cookieexceptionsdialog.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,27 +60,36 @@ ** ****************************************************************************/ -#ifndef NETWORKACCESSMANAGER_H -#define NETWORKACCESSMANAGER_H +#ifndef COOKIEEXCEPTIONSDIALOG_H +#define COOKIEEXCEPTIONSDIALOG_H -#include +#include -class NetworkAccessManager : public QNetworkAccessManager +#include "ui_cookiesexceptions.h" + +class CookieJar; +class QSortFilterProxyModel; +class CookieExceptionsModel; +class CookieExceptionsDialog : public QDialog, public Ui_CookiesExceptionsDialog { Q_OBJECT public: - NetworkAccessManager(QObject *parent = 0); - -public slots: - void loadSettings(); + CookieExceptionsDialog(CookieJar *cookieJar, QWidget *parent = 0); + void accept(); + void setDomainName(const QString &domainName); private slots: - void authenticationRequired(QNetworkReply *reply, QAuthenticator *auth); - void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); -#ifndef QT_NO_OPENSSL - void sslErrors(QNetworkReply *reply, const QList &error); -#endif + void block(); + void allow(); + void allowForSession(); + void textChanged(const QString &text); + +private: + CookieExceptionsModel *m_exceptionsModel; + QSortFilterProxyModel *m_proxyModel; + CookieJar *m_cookieJar; }; -#endif // NETWORKACCESSMANAGER_H +#endif // COOKIEEXCEPTIONSDIALOG_H + diff --git a/src/network/cookiejar/cookieexceptionsmodel.cpp b/src/network/cookiejar/cookieexceptionsmodel.cpp new file mode 100644 index 00000000..6e45d2aa --- /dev/null +++ b/src/network/cookiejar/cookieexceptionsmodel.cpp @@ -0,0 +1,222 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "cookieexceptionsmodel.h" + +#include "cookiejar.h" + +#include + +CookieExceptionsModel::CookieExceptionsModel(CookieJar *cookiejar, QObject *parent) + : QAbstractTableModel(parent) + , m_cookieJar(cookiejar) +{ + m_allowedCookies = m_cookieJar->allowedCookies(); + m_blockedCookies = m_cookieJar->blockedCookies(); + m_sessionCookies = m_cookieJar->allowForSessionCookies(); +} + +QVariant CookieExceptionsModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::SizeHintRole) { + QFont font; + font.setPointSize(10); + QFontMetrics fm(font); + int height = fm.height() + fm.height() / 3; + int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); + return QSize(width, height); + } + + if (orientation == Qt::Horizontal + && role == Qt::DisplayRole) { + switch (section) { + case 0: + return tr("Website"); + case 1: + return tr("Rule"); + } + } + return QAbstractTableModel::headerData(section, orientation, role); +} + +QVariant CookieExceptionsModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < 0 || index.row() >= rowCount()) + return QVariant(); + + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: { + int row = index.row(); + if (row < m_allowedCookies.count()) { + switch (index.column()) { + case 0: + return m_allowedCookies.at(row); + case 1: + return tr("Allow"); + } + } + row = row - m_allowedCookies.count(); + if (row < m_blockedCookies.count()) { + switch (index.column()) { + case 0: + return m_blockedCookies.at(row); + case 1: + return tr("Block"); + } + } + row = row - m_blockedCookies.count(); + if (row < m_sessionCookies.count()) { + switch (index.column()) { + case 0: + return m_sessionCookies.at(row); + case 1: + return tr("Allow For Session"); + } + } + } + case Qt::FontRole: { + QFont font; + font.setPointSize(10); + return font; + } + } + return QVariant(); +} + +int CookieExceptionsModel::columnCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : 2; +} + +int CookieExceptionsModel::rowCount(const QModelIndex &parent) const +{ + return (parent.isValid() || !m_cookieJar) ? 0 : m_allowedCookies.count() + m_blockedCookies.count() + m_sessionCookies.count(); +} + +bool CookieExceptionsModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid() || !m_cookieJar) + return false; + + int lastRow = row + count - 1; + beginRemoveRows(parent, row, lastRow); + + for (int i = lastRow; i >= row; --i) { + int rowToRemove = i; + if (rowToRemove < m_allowedCookies.count()) { + m_allowedCookies.removeAt(rowToRemove); + continue; + } + rowToRemove = rowToRemove - m_allowedCookies.count(); + if (rowToRemove < m_blockedCookies.count()) { + m_blockedCookies.removeAt(rowToRemove); + continue; + } + rowToRemove = rowToRemove - m_blockedCookies.count(); + if (rowToRemove < m_sessionCookies.count()) { + m_sessionCookies.removeAt(rowToRemove); + continue; + } + } + endRemoveRows(); + return true; +} + +void CookieExceptionsModel::addRule(QString host, CookieJar::CookieRule rule) +{ + if (host.isEmpty()) + return; + switch (rule) { + case CookieJar::Allow : + addHost(host, m_allowedCookies, m_blockedCookies, m_sessionCookies); + return; + case CookieJar::Block : + addHost(host, m_blockedCookies, m_allowedCookies, m_sessionCookies); + return; + case CookieJar::AllowForSession : + addHost(host, m_sessionCookies, m_allowedCookies, m_blockedCookies); + return; + } +} + +void CookieExceptionsModel::addHost(QString host, QStringList &add, QStringList &remove1, QStringList &remove2) +{ + if (!add.contains(host)) { + add.append(host); + remove1.removeOne(host); + remove2.removeOne(host); + } + // avoid to have similar rules, with or without starting dot, eg "arora-browser.org" and ".arora-browser.org" + // means the same domain. + QString otherRule; + if (host.startsWith(QLatin1Char('.'))) { + otherRule = host.mid(1); + } else { + otherRule = QLatin1String(".") + host; + } + add.removeOne(otherRule); + remove1.removeOne(otherRule); + remove2.removeOne(otherRule); + reset(); +} + diff --git a/src/edittableview.cpp b/src/network/cookiejar/cookieexceptionsmodel.h similarity index 70% rename from src/edittableview.cpp rename to src/network/cookiejar/cookieexceptionsmodel.h index 0ec583f1..169e35e1 100644 --- a/src/edittableview.cpp +++ b/src/network/cookiejar/cookieexceptionsmodel.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,46 +60,42 @@ ** ****************************************************************************/ -#include "edittableview.h" +#ifndef COOKIEEXCEPTIONSMODEL_H +#define COOKIEEXCEPTIONSMODEL_H -#include +#include "cookiejar.h" -EditTableView::EditTableView(QWidget *parent) - : QTableView(parent) -{ -} +#include +#include -void EditTableView::keyPressEvent(QKeyEvent *event) -{ - if ((event->key() == Qt::Key_Delete - || event->key() == Qt::Key_Backspace) - && model()) { - removeSelected(); - } else { - QAbstractItemView::keyPressEvent(event); - } -} -void EditTableView::removeSelected() +class CookieExceptionsModel : public QAbstractTableModel { - if (!model() || !selectionModel()) - return; - QModelIndexList selectedRows = selectionModel()->selectedRows(); - int row = 0; - for (int i = selectedRows.count() - 1; i >= 0; --i) { - row = selectedRows.at(i).row(); - model()->removeRow(row, rootIndex()); - } - QModelIndex idx = model()->index(row, 0, rootIndex()); - if (!idx.isValid()) - idx = model()->index(row - 1, 0, rootIndex()); - selectionModel()->select(idx, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); - setCurrentIndex(idx); -} + Q_OBJECT + friend class CookieExceptionsDialog; -void EditTableView::removeAll() -{ - if (model()) - model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); -} +public: + CookieExceptionsModel(CookieJar *cookieJar, QObject *parent = 0); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + + + void addRule(QString host, CookieJar::CookieRule rule); + +private: + CookieJar *m_cookieJar; + + // Domains we allow, Domains we block, Domains we allow for this session + QStringList m_allowedCookies; + QStringList m_blockedCookies; + QStringList m_sessionCookies; + + void addHost(QString host, QStringList &add, QStringList &remove1, QStringList &remove2); + +}; + +#endif // COOKIEEXCEPTIONSMODEL_H diff --git a/src/network/cookiejar/cookiejar.cpp b/src/network/cookiejar/cookiejar.cpp new file mode 100644 index 00000000..532600a2 --- /dev/null +++ b/src/network/cookiejar/cookiejar.cpp @@ -0,0 +1,492 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "cookiejar.h" + +#include "autosaver.h" +#include "browserapplication.h" + +#include +#include +#include +#include +#include + +#include + +static const unsigned int JAR_VERSION = 23; + +QT_BEGIN_NAMESPACE +QDataStream &operator<<(QDataStream &stream, const QList &list) +{ + stream << JAR_VERSION; + stream << quint32(list.size()); + for (int i = 0; i < list.size(); ++i) + stream << list.at(i).toRawForm(); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QList &list) +{ + list.clear(); + + quint32 version; + stream >> version; + + if (version != JAR_VERSION) + return stream; + + quint32 count; + stream >> count; + for (quint32 i = 0; i < count; ++i) { + QByteArray value; + stream >> value; + QList newCookies = QNetworkCookie::parseCookies(value); + if (newCookies.count() == 0 && value.length() != 0) { + qWarning() << "CookieJar: Unable to parse saved cookie:" << value; + } + for (int j = 0; j < newCookies.count(); ++j) + list.append(newCookies.at(j)); + if (stream.atEnd()) + break; + } + return stream; +} +QT_END_NAMESPACE + +CookieJar::CookieJar(QObject *parent) + : NetworkCookieJar(parent) + , m_loaded(false) + , m_saveTimer(new AutoSaver(this)) + , m_filterTrackingCookies(false) + , m_acceptCookies(AcceptOnlyFromSitesNavigatedTo) + , m_isPrivate(false) +{ +} + +CookieJar::~CookieJar() +{ + if (m_loaded && m_keepCookies == KeepUntilExit) + clear(); + m_saveTimer->saveIfNeccessary(); +} + +void CookieJar::setPrivate(bool isPrivate) +{ + m_isPrivate = isPrivate; +} + +void CookieJar::clear() +{ + if (!m_loaded) + load(); + setAllCookies(QList()); + m_saveTimer->changeOccurred(); + emit cookiesChanged(); +} + +void CookieJar::load() +{ + if (m_loaded) + return; + // load cookies and exceptions + qRegisterMetaTypeStreamOperators >("QList"); + QSettings cookieSettings(BrowserApplication::dataFilePath(QLatin1String("cookies.ini")), QSettings::IniFormat); + if (!m_isPrivate) { + setAllCookies(qvariant_cast >(cookieSettings.value(QLatin1String("cookies")))); + } + cookieSettings.beginGroup(QLatin1String("Exceptions")); + m_exceptions_block = cookieSettings.value(QLatin1String("block")).toStringList(); + m_exceptions_allow = cookieSettings.value(QLatin1String("allow")).toStringList(); + m_exceptions_allowForSession = cookieSettings.value(QLatin1String("allowForSession")).toStringList(); + qSort(m_exceptions_block.begin(), m_exceptions_block.end()); + qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); + qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); + + loadSettings(); +} + +void CookieJar::loadSettings() +{ + QSettings settings; + settings.beginGroup(QLatin1String("cookies")); + QByteArray value = settings.value(QLatin1String("acceptCookies"), + QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray(); + QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); + m_acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? + AcceptOnlyFromSitesNavigatedTo : + static_cast(acceptPolicyEnum.keyToValue(value)); + + value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("KeepUntilExpire")).toByteArray(); + QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); + m_keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? + KeepUntilExpire : + static_cast(keepPolicyEnum.keyToValue(value)); + + if (m_keepCookies == KeepUntilExit) + setAllCookies(QList()); + + m_loaded = true; + m_filterTrackingCookies = settings.value(QLatin1String("filterTrackingCookies"), m_filterTrackingCookies).toBool(); + m_sessionLength = settings.value(QLatin1String("sessionLength"), -1).toInt(); + emit cookiesChanged(); +} + +void CookieJar::save() +{ + if (!m_loaded || m_isPrivate) + return; + purgeOldCookies(); + + QSettings cookieSettings(BrowserApplication::dataFilePath(QLatin1String("cookies.ini")), QSettings::IniFormat); + + QList cookies = allCookies(); + for (int i = cookies.count() - 1; i >= 0; --i) { + if (cookies.at(i).isSessionCookie()) + cookies.removeAt(i); + } + cookieSettings.setValue(QLatin1String("cookies"), qVariantFromValue >(cookies)); + cookieSettings.beginGroup(QLatin1String("Exceptions")); + cookieSettings.setValue(QLatin1String("block"), m_exceptions_block); + cookieSettings.setValue(QLatin1String("allow"), m_exceptions_allow); + cookieSettings.setValue(QLatin1String("allowForSession"), m_exceptions_allowForSession); + + // save cookie settings + QSettings settings; + settings.beginGroup(QLatin1String("cookies")); + QMetaEnum acceptPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("AcceptPolicy")); + settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(m_acceptCookies))); + + QMetaEnum keepPolicyEnum = staticMetaObject.enumerator(staticMetaObject.indexOfEnumerator("KeepPolicy")); + settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(m_keepCookies))); + + settings.setValue(QLatin1String("filterTrackingCookies"), m_filterTrackingCookies); + settings.setValue(QLatin1String("sessionLength"), m_sessionLength); +} + +void CookieJar::purgeOldCookies() +{ + QList cookies = allCookies(); + if (cookies.isEmpty()) + return; + int oldCount = cookies.count(); + QDateTime now = QDateTime::currentDateTime(); + for (int i = cookies.count() - 1; i >= 0; --i) { + if (!cookies.at(i).isSessionCookie() && cookies.at(i).expirationDate() < now) + cookies.removeAt(i); + } + if (oldCount == cookies.count()) + return; + setAllCookies(cookies); + emit cookiesChanged(); +} + +QList CookieJar::cookiesForUrl(const QUrl &url) const +{ + CookieJar *that = const_cast(this); + if (!m_loaded) + that->load(); + + return NetworkCookieJar::cookiesForUrl(url); +} + +bool CookieJar::setCookiesFromUrl(const QList &cookieList, const QUrl &url) +{ + if (!m_loaded) + load(); + + QString host = url.host(); + bool eBlock = isOnDomainList(m_exceptions_block, host); + bool eAllow = !eBlock && isOnDomainList(m_exceptions_allow, host); + bool eAllowSession = !eBlock && !eAllow && isOnDomainList(m_exceptions_allowForSession, host); + + bool addedCookies = false; + // pass exceptions + bool acceptInitially = (m_acceptCookies != AcceptNever); + if ((acceptInitially && !eBlock) + || (!acceptInitially && (eAllow || eAllowSession))) { + // pass url domain == cookie domain + QDateTime soon = QDateTime::currentDateTime(); + soon = soon.addDays(90); + foreach (QNetworkCookie cookie, cookieList) { + if (cookie.isSessionCookie() && m_sessionLength != -1) { + QDateTime now = QDateTime::currentDateTime(); + cookie.setExpirationDate(now.addDays(m_sessionLength)); + } + + QList lst; + if (!(m_filterTrackingCookies && cookie.name().startsWith("__utm"))) { + + + if (eAllowSession) { + cookie.setExpirationDate(QDateTime()); + } + if (m_keepCookies == KeepUntilTimeLimit + && !cookie.isSessionCookie() + && cookie.expirationDate() > soon) { + cookie.setExpirationDate(soon); + } + lst += cookie; + if (NetworkCookieJar::setCookiesFromUrl(lst, url)) { + addedCookies = true; + } else { + // finally force it in if wanted + if (m_acceptCookies == AcceptAlways) { + QList cookies = allCookies(); + QList::Iterator it = cookies.begin(), + end = cookies.end(); + for (; it != end; ++it) { + // does this cookie already exist? + if (cookie.name() == it->name() && + cookie.domain() == it->domain() && + cookie.path() == it->path()) { + // found a match + cookies.erase(it); + break; + } + } + + cookies += cookie; + setAllCookies(cookies); + addedCookies = true; + } + #if 0 + else + qWarning() << "setCookiesFromUrl failed" << url << cookieList.value(0).toRawForm(); + #endif + } +#if 0 + } else { + qWarning() << "cookie treated as tracking cookie" << cookie; +#endif + } + } + } + + if (addedCookies) { + m_saveTimer->changeOccurred(); + emit cookiesChanged(); + } + return addedCookies; +} + +QList CookieJar::cookies() const +{ + CookieJar *that = const_cast(this); + if (!m_loaded) + that->load(); + + return allCookies(); +} + +void CookieJar::setCookies(const QList &cookies) +{ + if (!m_loaded) + load(); + setAllCookies(cookies); + m_saveTimer->changeOccurred(); + emit cookiesChanged(); +} + +bool CookieJar::isOnDomainList(const QStringList &rules, const QString &domain) +{ + // Either the rule matches the domain exactly + // or the domain ends with ".rule" + foreach (const QString &rule, rules) { + if (rule.startsWith(QLatin1String("."))) { + if (domain.endsWith(rule)) + return true; + + QStringRef withoutDot = rule.rightRef(rule.size() - 1); + if (domain == withoutDot) + return true; + } else { + QStringRef domainEnding = domain.rightRef(rule.size() + 1); + if (!domainEnding.isEmpty() + && domainEnding.at(0) == QLatin1Char('.') + && domain.endsWith(rule)) { + return true; + } + + if (rule == domain) + return true; + } + } + return false; +} + +CookieJar::AcceptPolicy CookieJar::acceptPolicy() const +{ + if (!m_loaded) + (const_cast(this))->load(); + return m_acceptCookies; +} + +void CookieJar::setAcceptPolicy(AcceptPolicy policy) +{ + if (!m_loaded) + load(); + if (policy == m_acceptCookies) + return; + m_acceptCookies = policy; + m_saveTimer->changeOccurred(); +} + +CookieJar::KeepPolicy CookieJar::keepPolicy() const +{ + if (!m_loaded) + (const_cast(this))->load(); + return m_keepCookies; +} + +void CookieJar::setKeepPolicy(KeepPolicy policy) +{ + if (!m_loaded) + load(); + if (policy == m_keepCookies) + return; + m_keepCookies = policy; + m_saveTimer->changeOccurred(); +} + +QStringList CookieJar::blockedCookies() const +{ + if (!m_loaded) + (const_cast(this))->load(); + return m_exceptions_block; +} + +QStringList CookieJar::allowedCookies() const +{ + if (!m_loaded) + (const_cast(this))->load(); + return m_exceptions_allow; +} + +QStringList CookieJar::allowForSessionCookies() const +{ + if (!m_loaded) + (const_cast(this))->load(); + return m_exceptions_allowForSession; +} + +void CookieJar::setBlockedCookies(const QStringList &list) +{ + if (!m_loaded) + load(); + m_exceptions_block = list; + qSort(m_exceptions_block.begin(), m_exceptions_block.end()); + applyRules(); + m_saveTimer->changeOccurred(); +} + +void CookieJar::setAllowedCookies(const QStringList &list) +{ + if (!m_loaded) + load(); + m_exceptions_allow = list; + qSort(m_exceptions_allow.begin(), m_exceptions_allow.end()); + applyRules(); + m_saveTimer->changeOccurred(); +} + +void CookieJar::setAllowForSessionCookies(const QStringList &list) +{ + if (!m_loaded) + load(); + m_exceptions_allowForSession = list; + qSort(m_exceptions_allowForSession.begin(), m_exceptions_allowForSession.end()); + applyRules(); + m_saveTimer->changeOccurred(); +} + +void CookieJar::applyRules() +{ + QList cookies = allCookies(); + bool changed = false; + for (int i = cookies.count() - 1; i >= 0; --i) { + const QNetworkCookie &cookie = cookies.at(i); + if (isOnDomainList(m_exceptions_block, cookie.domain())) { + cookies.removeAt(i); + changed = true; + } else if (isOnDomainList(m_exceptions_allowForSession, cookie.domain())) { + const_cast(cookie).setExpirationDate(QDateTime()); + changed = true; + } + } + if (changed) { + setAllCookies(cookies); + m_saveTimer->changeOccurred(); + emit cookiesChanged(); + } +} + +bool CookieJar::filterTrackingCookies() const +{ + return this->m_filterTrackingCookies; +} + +void CookieJar::setFilterTrackingCookies(bool filterTrackingCookies) +{ + this->m_filterTrackingCookies = filterTrackingCookies; +} + diff --git a/src/cookiejar.h b/src/network/cookiejar/cookiejar.h similarity index 66% rename from src/cookiejar.h rename to src/network/cookiejar/cookiejar.h index 0fa4aaf3..4825681d 100644 --- a/src/cookiejar.h +++ b/src/network/cookiejar/cookiejar.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -63,23 +63,13 @@ #ifndef COOKIEJAR_H #define COOKIEJAR_H -#include +#include "networkcookiejar.h" -#include -#include #include -#include - -QT_BEGIN_NAMESPACE -class QSortFilterProxyModel; -class QKeyEvent; -QT_END_NAMESPACE class AutoSaver; - -class CookieJar : public QNetworkCookieJar +class CookieJar : public NetworkCookieJar { - friend class CookieModel; Q_OBJECT Q_PROPERTY(AcceptPolicy acceptPolicy READ acceptPolicy WRITE setAcceptPolicy) Q_PROPERTY(KeepPolicy keepPolicy READ keepPolicy WRITE setKeepPolicy) @@ -88,6 +78,7 @@ class CookieJar : public QNetworkCookieJar Q_PROPERTY(QStringList allowForSessionCookies READ allowForSessionCookies WRITE setAllowForSessionCookies) Q_ENUMS(KeepPolicy) Q_ENUMS(AcceptPolicy) + Q_ENUMS(CookieRule) signals: void cookiesChanged(); @@ -105,12 +96,22 @@ class CookieJar : public QNetworkCookieJar KeepUntilTimeLimit }; + enum CookieRule { + Allow, + AllowForSession, + Block + }; + + CookieJar(QObject *parent = 0); ~CookieJar(); QList cookiesForUrl(const QUrl &url) const; bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); + QList cookies() const; + void setCookies(const QList &cookies); + AcceptPolicy acceptPolicy() const; void setAcceptPolicy(AcceptPolicy policy); @@ -125,6 +126,11 @@ class CookieJar : public QNetworkCookieJar void setAllowedCookies(const QStringList &list); void setAllowForSessionCookies(const QStringList &list); + bool filterTrackingCookies() const; + void setFilterTrackingCookies(bool filterTrackingCookies); + + void setPrivate(bool isPrivate); + public slots: void clear(); void loadSettings(); @@ -132,11 +138,16 @@ public slots: private slots: void save(); +protected: + static bool isOnDomainList(const QStringList &rules, const QString &domain); + private: + void applyRules(); void purgeOldCookies(); void load(); bool m_loaded; AutoSaver *m_saveTimer; + bool m_filterTrackingCookies; AcceptPolicy m_acceptCookies; KeepPolicy m_keepCookies; @@ -144,80 +155,8 @@ private slots: QStringList m_exceptions_block; QStringList m_exceptions_allow; QStringList m_exceptions_allowForSession; -}; - -class CookieModel : public QAbstractTableModel -{ - Q_OBJECT - -public: - CookieModel(CookieJar *jar, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private slots: - void cookiesChanged(); - -private: - CookieJar *m_cookieJar; -}; - -#include "ui_cookies.h" -#include "ui_cookiesexceptions.h" - -class CookiesDialog : public QDialog, public Ui_CookiesDialog -{ - Q_OBJECT - -public: - CookiesDialog(CookieJar *cookieJar, QWidget *parent = 0); - -private: - QSortFilterProxyModel *m_proxyModel; -}; - -class CookieExceptionsModel : public QAbstractTableModel -{ - Q_OBJECT - friend class CookiesExceptionsDialog; - -public: - CookieExceptionsModel(CookieJar *cookieJar, QObject *parent = 0); - QVariant headerData(int section, Qt::Orientation orientation, int role) const; - QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; - int columnCount(const QModelIndex &parent = QModelIndex()) const; - int rowCount(const QModelIndex &parent = QModelIndex()) const; - bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); - -private: - CookieJar *m_cookieJar; - - // Domains we allow, Domains we block, Domains we allow for this session - QStringList m_allowedCookies; - QStringList m_blockedCookies; - QStringList m_sessionCookies; -}; - -class CookiesExceptionsDialog : public QDialog, public Ui_CookiesExceptionsDialog -{ - Q_OBJECT - -public: - CookiesExceptionsDialog(CookieJar *cookieJar, QWidget *parent = 0); - -private slots: - void block(); - void allow(); - void allowForSession(); - void textChanged(const QString &text); - -private: - CookieExceptionsModel *m_exceptionsModel; - QSortFilterProxyModel *m_proxyModel; - CookieJar *m_cookieJar; + bool m_isPrivate; + int m_sessionLength; }; #endif // COOKIEJAR_H diff --git a/src/network/cookiejar/cookiejar.pri b/src/network/cookiejar/cookiejar.pri new file mode 100644 index 00000000..8ecf5338 --- /dev/null +++ b/src/network/cookiejar/cookiejar.pri @@ -0,0 +1,23 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + cookiedialog.h \ + cookieexceptionsdialog.h \ + cookieexceptionsmodel.h \ + cookiejar.h \ + cookiemodel.h + +SOURCES += \ + cookiedialog.cpp \ + cookieexceptionsmodel.cpp \ + cookiemodel.cpp \ + cookieexceptionsdialog.cpp \ + cookiejar.cpp + +FORMS += \ + cookies.ui \ + cookiesexceptions.ui + +include($$PWD/networkcookiejar/networkcookiejar.pri) + diff --git a/src/network/cookiejar/cookiemodel.cpp b/src/network/cookiejar/cookiemodel.cpp new file mode 100644 index 00000000..391e2cc7 --- /dev/null +++ b/src/network/cookiejar/cookiemodel.cpp @@ -0,0 +1,200 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "cookiemodel.h" + +#include "cookiejar.h" +#include "autosaver.h" + +#include +#include + +CookieModel::CookieModel(CookieJar *cookieJar, QObject *parent) + : QAbstractTableModel(parent) + , m_cookieJar(cookieJar) +{ + connect(m_cookieJar, SIGNAL(cookiesChanged()), this, SLOT(cookiesChanged())); + m_cookies = m_cookieJar->cookies(); +} + +QVariant CookieModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role == Qt::SizeHintRole) { + QFont font; + font.setPointSize(10); + QFontMetrics fm(font); + int height = fm.height() + fm.height() / 3; + int width = fm.width(headerData(section, orientation, Qt::DisplayRole).toString()); + return QSize(width, height); + } + + if (orientation == Qt::Horizontal) { + if (role != Qt::DisplayRole) + return QVariant(); + + switch (section) { + case 0: + return tr("Website"); + case 1: + return tr("Name"); + case 2: + return tr("Path"); + case 3: + return tr("Secure"); + case 4: + return tr("Expires"); + case 5: + return tr("Contents"); + default: + return QVariant(); + } + } + return QAbstractTableModel::headerData(section, orientation, role); +} + +QVariant CookieModel::data(const QModelIndex &index, int role) const +{ + if (index.row() < 0 || index.row() >= m_cookies.size()) + return QVariant(); + + switch (role) { + case CookieModel::SortRole: + { + QNetworkCookie cookie = m_cookies.at(index.row()); + switch (index.column()) { + case 0: + return cookie.domain(); + case 1: + return cookie.name(); + case 2: + return cookie.path(); + case 3: + return cookie.isSecure(); + case 4: + return cookie.expirationDate(); + case 5: + return cookie.value(); + } + } + case Qt::DisplayRole: + case Qt::EditRole: { + QNetworkCookie cookie = m_cookies.at(index.row()); + switch (index.column()) { + case 0: + return cookie.domain(); + case 1: + return cookie.name(); + case 2: + return cookie.path(); + case 3: + return cookie.isSecure() ? tr("true") : tr("false"); + case 4: + return cookie.isSessionCookie() ? tr("Session cookie") : cookie.expirationDate().toString(); + case 5: + return cookie.value(); + } + } + case Qt::FontRole: { + QFont font; + font.setPointSize(10); + return font; + } + } + + return QVariant(); +} + +int CookieModel::columnCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : 6; +} + +int CookieModel::rowCount(const QModelIndex &parent) const +{ + return (parent.isValid() || !m_cookieJar) ? 0 : m_cookies.count(); +} + +bool CookieModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid() || !m_cookieJar) + return false; + int lastRow = row + count - 1; + beginRemoveRows(parent, row, lastRow); + QList lst = m_cookies; + for (int i = lastRow; i >= row; --i) { + lst.removeAt(i); + } + disconnect(m_cookieJar, SIGNAL(cookiesChanged()), this, SLOT(cookiesChanged())); + m_cookieJar->setCookies(lst); + connect(m_cookieJar, SIGNAL(cookiesChanged()), this, SLOT(cookiesChanged())); + + m_cookies = lst; + endRemoveRows(); + return true; +} + +void CookieModel::cookiesChanged() +{ + if (m_cookieJar) + m_cookies = m_cookieJar->cookies(); + reset(); +} diff --git a/src/edittreeview.h b/src/network/cookiejar/cookiemodel.h similarity index 76% rename from src/edittreeview.h rename to src/network/cookiejar/cookiemodel.h index d62e76fb..cef244d2 100644 --- a/src/edittreeview.h +++ b/src/network/cookiejar/cookiemodel.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -60,23 +60,37 @@ ** ****************************************************************************/ -#ifndef EDITTREEVIEW_H -#define EDITTREEVIEW_H +#ifndef COOKIEMODEL_H +#define COOKIEMODEL_H -#include +#include -class EditTreeView : public QTreeView +#include + +class CookieJar; +class CookieModel : public QAbstractTableModel { Q_OBJECT public: - EditTreeView(QWidget *parent = 0); - void keyPressEvent(QKeyEvent *event); + enum DisplayRole + { + SortRole = Qt::UserRole + }; + CookieModel(CookieJar *jar, QObject *parent = 0); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + +private slots: + void cookiesChanged(); -public slots: - void removeSelected(); - void removeAll(); +private: + QList m_cookies; + CookieJar *m_cookieJar; }; -#endif // EDITTREEVIEW_H +#endif // COOKIEMODEL_H diff --git a/src/cookies.ui b/src/network/cookiejar/cookies.ui similarity index 54% rename from src/cookies.ui rename to src/network/cookiejar/cookies.ui index c4bccc54..fda5c2d5 100644 --- a/src/cookies.ui +++ b/src/network/cookiejar/cookies.ui @@ -1,7 +1,8 @@ - + + CookiesDialog - - + + 0 0 @@ -9,16 +10,16 @@ 370 - + Cookies - - + + - + Qt::Horizontal - + 252 20 @@ -26,34 +27,41 @@ - - + + - - + + - - + + - - + + &Remove - - + + Remove &All Cookies + + + + Add &Rule + + + - + Qt::Horizontal - + 40 20 @@ -62,9 +70,9 @@ - - - QDialogButtonBox::Ok + + + QDialogButtonBox::Close @@ -88,15 +96,15 @@ buttonBox - accepted() + rejected() CookiesDialog - accept() + close() - + 472 329 - + 461 356 diff --git a/src/cookiesexceptions.ui b/src/network/cookiejar/cookiesexceptions.ui similarity index 100% rename from src/cookiesexceptions.ui rename to src/network/cookiejar/cookiesexceptions.ui diff --git a/src/network/cookiejar/networkcookiejar/MOZILLA_LICENSE.txt b/src/network/cookiejar/networkcookiejar/MOZILLA_LICENSE.txt new file mode 100644 index 00000000..18f8109b --- /dev/null +++ b/src/network/cookiejar/networkcookiejar/MOZILLA_LICENSE.txt @@ -0,0 +1,567 @@ + MOZILLA PUBLIC LICENSE + Version 1.1 + + --------------- + +1. Definitions. + + 1.0.1. "Commercial Use" means distribution or otherwise making the + Covered Code available to a third party. + + 1.1. "Contributor" means each entity that creates or contributes to + the creation of Modifications. + + 1.2. "Contributor Version" means the combination of the Original + Code, prior Modifications used by a Contributor, and the Modifications + made by that particular Contributor. + + 1.3. "Covered Code" means the Original Code or Modifications or the + combination of the Original Code and Modifications, in each case + including portions thereof. + + 1.4. "Electronic Distribution Mechanism" means a mechanism generally + accepted in the software development community for the electronic + transfer of data. + + 1.5. "Executable" means Covered Code in any form other than Source + Code. + + 1.6. "Initial Developer" means the individual or entity identified + as the Initial Developer in the Source Code notice required by Exhibit + A. + + 1.7. "Larger Work" means a work which combines Covered Code or + portions thereof with code not governed by the terms of this License. + + 1.8. "License" means this document. + + 1.8.1. "Licensable" means having the right to grant, to the maximum + extent possible, whether at the time of the initial grant or + subsequently acquired, any and all of the rights conveyed herein. + + 1.9. "Modifications" means any addition to or deletion from the + substance or structure of either the Original Code or any previous + Modifications. When Covered Code is released as a series of files, a + Modification is: + A. Any addition to or deletion from the contents of a file + containing Original Code or previous Modifications. + + B. Any new file that contains any part of the Original Code or + previous Modifications. + + 1.10. "Original Code" means Source Code of computer software code + which is described in the Source Code notice required by Exhibit A as + Original Code, and which, at the time of its release under this + License is not already Covered Code governed by this License. + + 1.10.1. "Patent Claims" means any patent claim(s), now owned or + hereafter acquired, including without limitation, method, process, + and apparatus claims, in any patent Licensable by grantor. + + 1.11. "Source Code" means the preferred form of the Covered Code for + making modifications to it, including all modules it contains, plus + any associated interface definition files, scripts used to control + compilation and installation of an Executable, or source code + differential comparisons against either the Original Code or another + well known, available Covered Code of the Contributor's choice. The + Source Code can be in a compressed or archival form, provided the + appropriate decompression or de-archiving software is widely available + for no charge. + + 1.12. "You" (or "Your") means an individual or a legal entity + exercising rights under, and complying with all of the terms of, this + License or a future version of this License issued under Section 6.1. + For legal entities, "You" includes any entity which controls, is + controlled by, or is under common control with You. For purposes of + this definition, "control" means (a) the power, direct or indirect, + to cause the direction or management of such entity, whether by + contract or otherwise, or (b) ownership of more than fifty percent + (50%) of the outstanding shares or beneficial ownership of such + entity. + +2. Source Code License. + + 2.1. The Initial Developer Grant. + The Initial Developer hereby grants You a world-wide, royalty-free, + non-exclusive license, subject to third party intellectual property + claims: + (a) under intellectual property rights (other than patent or + trademark) Licensable by Initial Developer to use, reproduce, + modify, display, perform, sublicense and distribute the Original + Code (or portions thereof) with or without Modifications, and/or + as part of a Larger Work; and + + (b) under Patents Claims infringed by the making, using or + selling of Original Code, to make, have made, use, practice, + sell, and offer for sale, and/or otherwise dispose of the + Original Code (or portions thereof). + + (c) the licenses granted in this Section 2.1(a) and (b) are + effective on the date Initial Developer first distributes + Original Code under the terms of this License. + + (d) Notwithstanding Section 2.1(b) above, no patent license is + granted: 1) for code that You delete from the Original Code; 2) + separate from the Original Code; or 3) for infringements caused + by: i) the modification of the Original Code or ii) the + combination of the Original Code with other software or devices. + + 2.2. Contributor Grant. + Subject to third party intellectual property claims, each Contributor + hereby grants You a world-wide, royalty-free, non-exclusive license + + (a) under intellectual property rights (other than patent or + trademark) Licensable by Contributor, to use, reproduce, modify, + display, perform, sublicense and distribute the Modifications + created by such Contributor (or portions thereof) either on an + unmodified basis, with other Modifications, as Covered Code + and/or as part of a Larger Work; and + + (b) under Patent Claims infringed by the making, using, or + selling of Modifications made by that Contributor either alone + and/or in combination with its Contributor Version (or portions + of such combination), to make, use, sell, offer for sale, have + made, and/or otherwise dispose of: 1) Modifications made by that + Contributor (or portions thereof); and 2) the combination of + Modifications made by that Contributor with its Contributor + Version (or portions of such combination). + + (c) the licenses granted in Sections 2.2(a) and 2.2(b) are + effective on the date Contributor first makes Commercial Use of + the Covered Code. + + (d) Notwithstanding Section 2.2(b) above, no patent license is + granted: 1) for any code that Contributor has deleted from the + Contributor Version; 2) separate from the Contributor Version; + 3) for infringements caused by: i) third party modifications of + Contributor Version or ii) the combination of Modifications made + by that Contributor with other software (except as part of the + Contributor Version) or other devices; or 4) under Patent Claims + infringed by Covered Code in the absence of Modifications made by + that Contributor. + +3. Distribution Obligations. + + 3.1. Application of License. + The Modifications which You create or to which You contribute are + governed by the terms of this License, including without limitation + Section 2.2. The Source Code version of Covered Code may be + distributed only under the terms of this License or a future version + of this License released under Section 6.1, and You must include a + copy of this License with every copy of the Source Code You + distribute. You may not offer or impose any terms on any Source Code + version that alters or restricts the applicable version of this + License or the recipients' rights hereunder. However, You may include + an additional document offering the additional rights described in + Section 3.5. + + 3.2. Availability of Source Code. + Any Modification which You create or to which You contribute must be + made available in Source Code form under the terms of this License + either on the same media as an Executable version or via an accepted + Electronic Distribution Mechanism to anyone to whom you made an + Executable version available; and if made available via Electronic + Distribution Mechanism, must remain available for at least twelve (12) + months after the date it initially became available, or at least six + (6) months after a subsequent version of that particular Modification + has been made available to such recipients. You are responsible for + ensuring that the Source Code version remains available even if the + Electronic Distribution Mechanism is maintained by a third party. + + 3.3. Description of Modifications. + You must cause all Covered Code to which You contribute to contain a + file documenting the changes You made to create that Covered Code and + the date of any change. You must include a prominent statement that + the Modification is derived, directly or indirectly, from Original + Code provided by the Initial Developer and including the name of the + Initial Developer in (a) the Source Code, and (b) in any notice in an + Executable version or related documentation in which You describe the + origin or ownership of the Covered Code. + + 3.4. Intellectual Property Matters + (a) Third Party Claims. + If Contributor has knowledge that a license under a third party's + intellectual property rights is required to exercise the rights + granted by such Contributor under Sections 2.1 or 2.2, + Contributor must include a text file with the Source Code + distribution titled "LEGAL" which describes the claim and the + party making the claim in sufficient detail that a recipient will + know whom to contact. If Contributor obtains such knowledge after + the Modification is made available as described in Section 3.2, + Contributor shall promptly modify the LEGAL file in all copies + Contributor makes available thereafter and shall take other steps + (such as notifying appropriate mailing lists or newsgroups) + reasonably calculated to inform those who received the Covered + Code that new knowledge has been obtained. + + (b) Contributor APIs. + If Contributor's Modifications include an application programming + interface and Contributor has knowledge of patent licenses which + are reasonably necessary to implement that API, Contributor must + also include this information in the LEGAL file. + + (c) Representations. + Contributor represents that, except as disclosed pursuant to + Section 3.4(a) above, Contributor believes that Contributor's + Modifications are Contributor's original creation(s) and/or + Contributor has sufficient rights to grant the rights conveyed by + this License. + + 3.5. Required Notices. + You must duplicate the notice in Exhibit A in each file of the Source + Code. If it is not possible to put such notice in a particular Source + Code file due to its structure, then You must include such notice in a + location (such as a relevant directory) where a user would be likely + to look for such a notice. If You created one or more Modification(s) + You may add your name as a Contributor to the notice described in + Exhibit A. You must also duplicate this License in any documentation + for the Source Code where You describe recipients' rights or ownership + rights relating to Covered Code. You may choose to offer, and to + charge a fee for, warranty, support, indemnity or liability + obligations to one or more recipients of Covered Code. However, You + may do so only on Your own behalf, and not on behalf of the Initial + Developer or any Contributor. You must make it absolutely clear than + any such warranty, support, indemnity or liability obligation is + offered by You alone, and You hereby agree to indemnify the Initial + Developer and every Contributor for any liability incurred by the + Initial Developer or such Contributor as a result of warranty, + support, indemnity or liability terms You offer. + + 3.6. Distribution of Executable Versions. + You may distribute Covered Code in Executable form only if the + requirements of Section 3.1-3.5 have been met for that Covered Code, + and if You include a notice stating that the Source Code version of + the Covered Code is available under the terms of this License, + including a description of how and where You have fulfilled the + obligations of Section 3.2. The notice must be conspicuously included + in any notice in an Executable version, related documentation or + collateral in which You describe recipients' rights relating to the + Covered Code. You may distribute the Executable version of Covered + Code or ownership rights under a license of Your choice, which may + contain terms different from this License, provided that You are in + compliance with the terms of this License and that the license for the + Executable version does not attempt to limit or alter the recipient's + rights in the Source Code version from the rights set forth in this + License. If You distribute the Executable version under a different + license You must make it absolutely clear that any terms which differ + from this License are offered by You alone, not by the Initial + Developer or any Contributor. You hereby agree to indemnify the + Initial Developer and every Contributor for any liability incurred by + the Initial Developer or such Contributor as a result of any such + terms You offer. + + 3.7. Larger Works. + You may create a Larger Work by combining Covered Code with other code + not governed by the terms of this License and distribute the Larger + Work as a single product. In such a case, You must make sure the + requirements of this License are fulfilled for the Covered Code. + +4. Inability to Comply Due to Statute or Regulation. + + If it is impossible for You to comply with any of the terms of this + License with respect to some or all of the Covered Code due to + statute, judicial order, or regulation then You must: (a) comply with + the terms of this License to the maximum extent possible; and (b) + describe the limitations and the code they affect. Such description + must be included in the LEGAL file described in Section 3.4 and must + be included with all distributions of the Source Code. Except to the + extent prohibited by statute or regulation, such description must be + sufficiently detailed for a recipient of ordinary skill to be able to + understand it. + +5. Application of this License. + + This License applies to code to which the Initial Developer has + attached the notice in Exhibit A and to related Covered Code. + +6. Versions of the License. + + 6.1. New Versions. + Netscape Communications Corporation ("Netscape") may publish revised + and/or new versions of the License from time to time. Each version + will be given a distinguishing version number. + + 6.2. Effect of New Versions. + Once Covered Code has been published under a particular version of the + License, You may always continue to use it under the terms of that + version. You may also choose to use such Covered Code under the terms + of any subsequent version of the License published by Netscape. No one + other than Netscape has the right to modify the terms applicable to + Covered Code created under this License. + + 6.3. Derivative Works. + If You create or use a modified version of this License (which you may + only do in order to apply it to code which is not already Covered Code + governed by this License), You must (a) rename Your license so that + the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape", + "MPL", "NPL" or any confusingly similar phrase do not appear in your + license (except to note that your license differs from this License) + and (b) otherwise make it clear that Your version of the license + contains terms which differ from the Mozilla Public License and + Netscape Public License. (Filling in the name of the Initial + Developer, Original Code or Contributor in the notice described in + Exhibit A shall not of themselves be deemed to be modifications of + this License.) + +7. DISCLAIMER OF WARRANTY. + + COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF + DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE + IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, + YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE + COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER + OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF + ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER. + +8. TERMINATION. + + 8.1. This License and the rights granted hereunder will terminate + automatically if You fail to comply with terms herein and fail to cure + such breach within 30 days of becoming aware of the breach. All + sublicenses to the Covered Code which are properly granted shall + survive any termination of this License. Provisions which, by their + nature, must remain in effect beyond the termination of this License + shall survive. + + 8.2. If You initiate litigation by asserting a patent infringement + claim (excluding declatory judgment actions) against Initial Developer + or a Contributor (the Initial Developer or Contributor against whom + You file such action is referred to as "Participant") alleging that: + + (a) such Participant's Contributor Version directly or indirectly + infringes any patent, then any and all rights granted by such + Participant to You under Sections 2.1 and/or 2.2 of this License + shall, upon 60 days notice from Participant terminate prospectively, + unless if within 60 days after receipt of notice You either: (i) + agree in writing to pay Participant a mutually agreeable reasonable + royalty for Your past and future use of Modifications made by such + Participant, or (ii) withdraw Your litigation claim with respect to + the Contributor Version against such Participant. If within 60 days + of notice, a reasonable royalty and payment arrangement are not + mutually agreed upon in writing by the parties or the litigation claim + is not withdrawn, the rights granted by Participant to You under + Sections 2.1 and/or 2.2 automatically terminate at the expiration of + the 60 day notice period specified above. + + (b) any software, hardware, or device, other than such Participant's + Contributor Version, directly or indirectly infringes any patent, then + any rights granted to You by such Participant under Sections 2.1(b) + and 2.2(b) are revoked effective as of the date You first made, used, + sold, distributed, or had made, Modifications made by that + Participant. + + 8.3. If You assert a patent infringement claim against Participant + alleging that such Participant's Contributor Version directly or + indirectly infringes any patent where such claim is resolved (such as + by license or settlement) prior to the initiation of patent + infringement litigation, then the reasonable value of the licenses + granted by such Participant under Sections 2.1 or 2.2 shall be taken + into account in determining the amount or value of any payment or + license. + + 8.4. In the event of termination under Sections 8.1 or 8.2 above, + all end user license agreements (excluding distributors and resellers) + which have been validly granted by You or any distributor hereunder + prior to termination shall survive termination. + +9. LIMITATION OF LIABILITY. + + UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT + (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL + DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, + OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR + ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY + CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, + WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER + COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN + INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF + LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY + RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW + PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE + EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO + THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. + +10. U.S. GOVERNMENT END USERS. + + The Covered Code is a "commercial item," as that term is defined in + 48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer + software" and "commercial computer software documentation," as such + terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 + C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995), + all U.S. Government End Users acquire Covered Code with only those + rights set forth herein. + +11. MISCELLANEOUS. + + This License represents the complete agreement concerning subject + matter hereof. If any provision of this License is held to be + unenforceable, such provision shall be reformed only to the extent + necessary to make it enforceable. This License shall be governed by + California law provisions (except to the extent applicable law, if + any, provides otherwise), excluding its conflict-of-law provisions. + With respect to disputes in which at least one party is a citizen of, + or an entity chartered or registered to do business in the United + States of America, any litigation relating to this License shall be + subject to the jurisdiction of the Federal Courts of the Northern + District of California, with venue lying in Santa Clara County, + California, with the losing party responsible for costs, including + without limitation, court costs and reasonable attorneys' fees and + expenses. The application of the United Nations Convention on + Contracts for the International Sale of Goods is expressly excluded. + Any law or regulation which provides that the language of a contract + shall be construed against the drafter shall not apply to this + License. + +12. RESPONSIBILITY FOR CLAIMS. + + As between Initial Developer and the Contributors, each party is + responsible for claims and damages arising, directly or indirectly, + out of its utilization of rights under this License and You agree to + work with Initial Developer and Contributors to distribute such + responsibility on an equitable basis. Nothing herein is intended or + shall be deemed to constitute any admission of liability. + +13. MULTIPLE-LICENSED CODE. + + Initial Developer may designate portions of the Covered Code as + "Multiple-Licensed". "Multiple-Licensed" means that the Initial + Developer permits you to utilize portions of the Covered Code under + Your choice of the NPL or the alternative licenses, if any, specified + by the Initial Developer in the file described in Exhibit A. + +EXHIBIT A -Mozilla Public License. + + ``The contents of this file are subject to the Mozilla Public License + Version 1.1 (the "License"); you may not use this file except in + compliance with the License. You may obtain a copy of the License at + http://www.mozilla.org/MPL/ + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the + License for the specific language governing rights and limitations + under the License. + + The Original Code is ______________________________________. + + The Initial Developer of the Original Code is ________________________. + Portions created by ______________________ are Copyright (C) ______ + _______________________. All Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the terms + of the _____ license (the "[___] License"), in which case the + provisions of [______] License are applicable instead of those + above. If you wish to allow use of your version of this file only + under the terms of the [____] License and not to allow others to use + your version of this file under the MPL, indicate your decision by + deleting the provisions above and replace them with the notice and + other provisions required by the [___] License. If you do not delete + the provisions above, a recipient may use your version of this file + under either the MPL or the [___] License." + + [NOTE: The text of this Exhibit A may differ slightly from the text of + the notices in the Source Code files of the Original Code. You should + use the text of this Exhibit A rather than the text found in the + Original Code Source Code for Your Modifications.] + + ---------------------------------------------------------------------- + + AMENDMENTS + + The Netscape Public License Version 1.1 ("NPL") consists of the + Mozilla Public License Version 1.1 with the following Amendments, + including Exhibit A-Netscape Public License. Files identified with + "Exhibit A-Netscape Public License" are governed by the Netscape + Public License Version 1.1. + + Additional Terms applicable to the Netscape Public License. + I. Effect. + These additional terms described in this Netscape Public + License -- Amendments shall apply to the Mozilla Communicator + client code and to all Covered Code under this License. + + II. "Netscape's Branded Code" means Covered Code that Netscape + distributes and/or permits others to distribute under one or more + trademark(s) which are controlled by Netscape but which are not + licensed for use under this License. + + III. Netscape and logo. + This License does not grant any rights to use the trademarks + "Netscape", the "Netscape N and horizon" logo or the "Netscape + lighthouse" logo, "Netcenter", "Gecko", "Java" or "JavaScript", + "Smart Browsing" even if such marks are included in the Original + Code or Modifications. + + IV. Inability to Comply Due to Contractual Obligation. + Prior to licensing the Original Code under this License, Netscape + has licensed third party code for use in Netscape's Branded Code. + To the extent that Netscape is limited contractually from making + such third party code available under this License, Netscape may + choose to reintegrate such code into Covered Code without being + required to distribute such code in Source Code form, even if + such code would otherwise be considered "Modifications" under + this License. + + V. Use of Modifications and Covered Code by Initial Developer. + V.1. In General. + The obligations of Section 3 apply to Netscape, except to + the extent specified in this Amendment, Section V.2 and V.3. + + V.2. Other Products. + Netscape may include Covered Code in products other than the + Netscape's Branded Code which are released by Netscape + during the two (2) years following the release date of the + Original Code, without such additional products becoming + subject to the terms of this License, and may license such + additional products on different terms from those contained + in this License. + + V.3. Alternative Licensing. + Netscape may license the Source Code of Netscape's Branded + Code, including Modifications incorporated therein, without + such Netscape Branded Code becoming subject to the terms of + this License, and may license such Netscape Branded Code on + different terms from those contained in this License. + + VI. Litigation. + Notwithstanding the limitations of Section 11 above, the + provisions regarding litigation in Section 11(a), (b) and (c) of + the License shall apply to all disputes relating to this License. + + EXHIBIT A-Netscape Public License. + + "The contents of this file are subject to the Netscape Public + License Version 1.1 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at http://www.mozilla.org/NPL/ + + Software distributed under the License is distributed on an "AS + IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + implied. See the License for the specific language governing + rights and limitations under the License. + + The Original Code is Mozilla Communicator client code, released + March 31, 1998. + + The Initial Developer of the Original Code is Netscape + Communications Corporation. Portions created by Netscape are + Copyright (C) 1998-1999 Netscape Communications Corporation. All + Rights Reserved. + + Contributor(s): ______________________________________. + + Alternatively, the contents of this file may be used under the + terms of the _____ license (the "[___] License"), in which case + the provisions of [______] License are applicable instead of + those above. If you wish to allow use of your version of this + file only under the terms of the [____] License and not to allow + others to use your version of this file under the NPL, indicate + your decision by deleting the provisions above and replace them + with the notice and other provisions required by the [___] + License. If you do not delete the provisions above, a recipient + may use your version of this file under either the NPL or the + [___] License." diff --git a/src/network/cookiejar/networkcookiejar/networkcookiejar.cpp b/src/network/cookiejar/networkcookiejar/networkcookiejar.cpp new file mode 100644 index 00000000..940269d5 --- /dev/null +++ b/src/network/cookiejar/networkcookiejar/networkcookiejar.cpp @@ -0,0 +1,375 @@ +/* + Copyright (C) 2009, Torch Mobile Inc. and Linden Research, Inc. All rights reserved. +*/ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Torch Mobile Inc. (http://www.torchmobile.com/) code + * + * The Initial Developer of the Original Code is: + * Benjamin Meyer (benjamin.meyer@torchmobile.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "networkcookiejar.h" +#include "networkcookiejar_p.h" +#include "twoleveldomains_p.h" + +//#define NETWORKCOOKIEJAR_DEBUG + +#ifndef QT_NO_DEBUG +// ^ Prevent being left on in a released product by accident +// qDebug any cookies that are rejected for further inspection +#define NETWORKCOOKIEJAR_LOGREJECTEDCOOKIES +#include +#endif + +#include +#include + +#if defined(NETWORKCOOKIEJAR_DEBUG) +#include +#endif + + +NetworkCookieJar::NetworkCookieJar(QObject *parent) + : QNetworkCookieJar(parent) +{ + d = new NetworkCookieJarPrivate; +} + +NetworkCookieJar::~NetworkCookieJar() +{ + delete d; +} + +static QStringList splitHost(const QString &host) { + QStringList parts = host.split(QLatin1Char('.'), QString::KeepEmptyParts); + // Remove empty components that are on the start and end + while (!parts.isEmpty() && parts.last().isEmpty()) + parts.removeLast(); + while (!parts.isEmpty() && parts.first().isEmpty()) + parts.removeFirst(); + return parts; +} + +inline static bool shorterPaths(const QNetworkCookie &c1, const QNetworkCookie &c2) +{ + return c2.path().length() < c1.path().length(); +} + +QList NetworkCookieJar::cookiesForUrl(const QUrl &url) const +{ +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << "NetworkCookieJar::" << __FUNCTION__ << url; +#endif + // Generate split host + QString host = url.host(); + if (url.scheme().toLower() == QLatin1String("file")) + host = QLatin1String("localhost"); + QStringList urlHost = splitHost(host); + + // Get all the cookies for url + QList cookies = d->tree.find(urlHost); + if (urlHost.count() > 2) { + int top = 2; + if (d->matchesBlacklist(urlHost.last())) + top = 3; + + urlHost.removeFirst(); + while (urlHost.count() >= top) { + cookies += d->tree.find(urlHost); + urlHost.removeFirst(); + } + } + + // Prevent doing anything expensive in the common case where + // there are no cookies to check + if (cookies.isEmpty()) + return cookies; + + QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC); + const QString urlPath = d->urlPath(url); + const bool isSecure = url.scheme().toLower() == QLatin1String("https"); + QList::iterator i = cookies.begin(); + for (; i != cookies.end();) { + if (!d->matchingPath(*i, urlPath)) { +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << __FUNCTION__ << "Ignoring cookie, path does not match" << *i << urlPath; +#endif + i = cookies.erase(i); + continue; + } + if (!isSecure && i->isSecure()) { + i = cookies.erase(i); +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << __FUNCTION__ << "Ignoring cookie, security mismatch" + << *i << !isSecure; +#endif + continue; + } + if (!i->isSessionCookie() && now > i->expirationDate()) { + // remove now (expensive short term) because there will + // probably be many more cookiesForUrl calls for this host + d->tree.remove(splitHost(i->domain()), *i); +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << __FUNCTION__ << "Ignoring cookie, expiration issue" + << *i << now; +#endif + i = cookies.erase(i); + continue; + } + ++i; + } + + // shorter paths should go first + qSort(cookies.begin(), cookies.end(), shorterPaths); +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << "NetworkCookieJar::" << __FUNCTION__ << "returning" << cookies.count(); + qDebug() << cookies; +#endif + return cookies; +} + +static const qint32 NetworkCookieJarMagic = 0xae; + +QByteArray NetworkCookieJar::saveState () const +{ + int version = 1; + QByteArray data; + QDataStream stream(&data, QIODevice::WriteOnly); + + stream << qint32(NetworkCookieJarMagic); + stream << qint32(version); + stream << d->tree; + return data; +} + +bool NetworkCookieJar::restoreState(const QByteArray &state) +{ + int version = 1; + QByteArray sd = state; + QDataStream stream(&sd, QIODevice::ReadOnly); + if (stream.atEnd()) + return false; + qint32 marker; + qint32 v; + stream >> marker; + stream >> v; + if (marker != NetworkCookieJarMagic || v != version) + return false; + stream >> d->tree; + return true; +} + +/*! + Remove any session cookies or cookies that have expired. + */ +void NetworkCookieJar::endSession() +{ + const QList cookies = d->tree.all(); + QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC); + QList::const_iterator i = cookies.constBegin(); + for (; i != cookies.constEnd();) { + if (i->isSessionCookie() + || (!i->isSessionCookie() && now > i->expirationDate())) { + d->tree.remove(splitHost(i->domain()), *i); + } + ++i; + } +} + +static const int maxCookiePathLength = 1024; + +bool NetworkCookieJar::setCookiesFromUrl(const QList &cookieList, const QUrl &url) +{ +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << "NetworkCookieJar::" << __FUNCTION__ << url; + qDebug() << cookieList; +#endif + QDateTime now = QDateTime::currentDateTime().toTimeSpec(Qt::UTC); + bool changed = false; + QString fullUrlPath = url.path(); + QString defaultPath = fullUrlPath.mid(0, fullUrlPath.lastIndexOf(QLatin1Char('/')) + 1); + if (defaultPath.isEmpty()) + defaultPath = QLatin1Char('/'); + + QString urlPath = d->urlPath(url); + foreach (QNetworkCookie cookie, cookieList) { + if (cookie.path().length() > maxCookiePathLength) + continue; + + bool alreadyDead = !cookie.isSessionCookie() && cookie.expirationDate() < now; + + if (cookie.path().isEmpty()) { + cookie.setPath(defaultPath); + } + // Matching the behavior of Firefox, no path checking is done when setting cookies + // Safari does something even odder, when that paths don't match it keeps + // the cookie, but changes the paths to the default path +#if 0 + else if (!d->matchingPath(cookie, urlPath)) { +#ifdef NETWORKCOOKIEJAR_LOGREJECTEDCOOKIES + qDebug() << "NetworkCookieJar::" << __FUNCTION__ + << "Blocked cookie because: path doesn't match: " << cookie << url; +#endif + continue; + } +#endif + + if (cookie.domain().isEmpty()) { + QString host = url.host().toLower(); + if (host.isEmpty()) + continue; + cookie.setDomain(host); + } else if (!d->matchingDomain(cookie, url)) { +#ifdef NETWORKCOOKIEJAR_LOGREJECTEDCOOKIES + qDebug() << "NetworkCookieJar::" << __FUNCTION__ + << "Blocked cookie because: domain doesn't match: " << cookie << url; +#endif + continue; + } + + // replace/remove existing cookies + QString domain = cookie.domain(); + Q_ASSERT(!domain.isEmpty()); + QStringList urlHost = splitHost(domain); + + QList cookies = d->tree.find(urlHost); + QList::const_iterator it = cookies.constBegin(); + for (; it != cookies.constEnd(); ++it) { + if (cookie.name() == it->name() && + cookie.domain() == it->domain() && + cookie.path() == it->path()) { + d->tree.remove(urlHost, *it); + break; + } + } + + if (alreadyDead) + continue; + + changed = true; + d->tree.insert(urlHost, cookie); + } + + return changed; +} + +QList NetworkCookieJar::allCookies() const +{ +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << "NetworkCookieJar::" << __FUNCTION__; +#endif + return d->tree.all(); +} + +void NetworkCookieJar::setAllCookies(const QList &cookieList) +{ +#if defined(NETWORKCOOKIEJAR_DEBUG) + qDebug() << "NetworkCookieJar::" << __FUNCTION__ << cookieList.count(); +#endif + d->tree.clear(); + foreach (const QNetworkCookie &cookie, cookieList) { + QString domain = cookie.domain(); + d->tree.insert(splitHost(domain), cookie); + } +} + +QString NetworkCookieJarPrivate::urlPath(const QUrl &url) const +{ + QString urlPath = url.path(); + if (!urlPath.endsWith(QLatin1Char('/'))) + urlPath += QLatin1Char('/'); + return urlPath; +} + +bool NetworkCookieJarPrivate::matchingPath(const QNetworkCookie &cookie, const QString &urlPath) const +{ + QString cookiePath = cookie.path(); + if (!cookiePath.endsWith(QLatin1Char('/'))) + cookiePath += QLatin1Char('/'); + + return urlPath.startsWith(cookiePath); +} + +bool NetworkCookieJarPrivate::matchesBlacklist(const QString &string) const +{ + if (!setSecondLevelDomain) { + // Alternatively to save a little bit of ram we could just + // use bsearch on twoLevelDomains in place + for (int j = 0; twoLevelDomains[j]; ++j) + secondLevelDomains += QLatin1String(twoLevelDomains[j]); + setSecondLevelDomain = true; + } + QStringList::const_iterator i = + qBinaryFind(secondLevelDomains.constBegin(), secondLevelDomains.constEnd(), string); + return (i != secondLevelDomains.constEnd()); +} + +bool NetworkCookieJarPrivate::matchingDomain(const QNetworkCookie &cookie, const QUrl &url) const +{ + QString domain = cookie.domain().simplified().toLower(); + domain.remove(QLatin1Char(' ')); + QStringList parts = splitHost(domain); + if (parts.isEmpty()) + return false; + + // When there is only one part only file://localhost/ is accepted + if (parts.count() == 1) { + QString s = parts.first(); + if (parts.first() != QLatin1String("localhost")) + return false; + if (url.scheme().toLower() == QLatin1String("file")) + return true; + } + + // Check for blacklist + if (parts.count() == 2 && matchesBlacklist(parts.last())) + return false; + + QStringList urlParts = url.host().toLower().split(QLatin1Char('.'), QString::SkipEmptyParts); + if (urlParts.isEmpty()) + return false; + while (urlParts.count() > parts.count()) + urlParts.removeFirst(); + + for (int j = 0; j < urlParts.count(); ++j) { + if (urlParts.at(j) != parts.at(j)) { + return false; + } + } + + return true; +} + +void NetworkCookieJar::setSecondLevelDomains(const QStringList &secondLevelDomains) +{ + d->setSecondLevelDomain = true; + d->secondLevelDomains = secondLevelDomains; + qSort(d->secondLevelDomains); +} + diff --git a/src/network/cookiejar/networkcookiejar/networkcookiejar.h b/src/network/cookiejar/networkcookiejar/networkcookiejar.h new file mode 100644 index 00000000..365b4a32 --- /dev/null +++ b/src/network/cookiejar/networkcookiejar/networkcookiejar.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2009, Torch Mobile Inc. and Linden Research, Inc. All rights reserved. +*/ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Torch Mobile Inc. (http://www.torchmobile.com/) code + * + * The Initial Developer of the Original Code is: + * Benjamin Meyer (benjamin.meyer@torchmobile.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef NETWORKCOOKIEJAR_H +#define NETWORKCOOKIEJAR_H + +#include + +class NetworkCookieJarPrivate; +class NetworkCookieJar : public QNetworkCookieJar { + Q_OBJECT +public: + NetworkCookieJar(QObject *parent = 0); + ~NetworkCookieJar(); + + virtual QList cookiesForUrl(const QUrl & url) const; + virtual bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); + +protected: + QByteArray saveState() const; + bool restoreState(const QByteArray &state); + void endSession(); + + QList allCookies() const; + void setAllCookies(const QList &cookieList); + void setSecondLevelDomains(const QStringList &secondLevelDomains); + +private: + NetworkCookieJarPrivate *d; +}; + +#endif + diff --git a/src/network/cookiejar/networkcookiejar/networkcookiejar.pri b/src/network/cookiejar/networkcookiejar/networkcookiejar.pri new file mode 100644 index 00000000..78ac273a --- /dev/null +++ b/src/network/cookiejar/networkcookiejar/networkcookiejar.pri @@ -0,0 +1,5 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += trie_p.h networkcookiejar.h twoleveldomains_p.h networkcookiejar_p.h +SOURCES += networkcookiejar.cpp diff --git a/src/network/cookiejar/networkcookiejar/networkcookiejar_p.h b/src/network/cookiejar/networkcookiejar/networkcookiejar_p.h new file mode 100644 index 00000000..ea357375 --- /dev/null +++ b/src/network/cookiejar/networkcookiejar/networkcookiejar_p.h @@ -0,0 +1,77 @@ +/* + Copyright (C) 2009, Torch Mobile Inc. and Linden Research, Inc. All rights reserved. +*/ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Torch Mobile Inc. (http://www.torchmobile.com/) code + * + * The Initial Developer of the Original Code is: + * Benjamin Meyer (benjamin.meyer@torchmobile.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef NETWORKCOOKIEJARPRIVATE_H +#define NETWORKCOOKIEJARPRIVATE_H + +#include "trie_p.h" + +QT_BEGIN_NAMESPACE +QDataStream &operator<<(QDataStream &stream, const QNetworkCookie &cookie) +{ + stream << cookie.toRawForm(); + return stream; +} + +QDataStream &operator>>(QDataStream &stream, QNetworkCookie &cookie) +{ + QByteArray value; + stream >> value; + QList newCookies = QNetworkCookie::parseCookies(value); + if (!newCookies.isEmpty()) + cookie = newCookies.first(); + return stream; +} +QT_END_NAMESPACE + +class NetworkCookieJarPrivate { +public: + NetworkCookieJarPrivate() + : setSecondLevelDomain(false) + {} + + Trie tree; + mutable bool setSecondLevelDomain; + mutable QStringList secondLevelDomains; + + bool matchesBlacklist(const QString &string) const; + bool matchingDomain(const QNetworkCookie &cookie, const QUrl &url) const; + QString urlPath(const QUrl &url) const; + bool matchingPath(const QNetworkCookie &cookie, const QString &urlPath) const; +}; + +#endif + diff --git a/src/network/cookiejar/networkcookiejar/trie_p.h b/src/network/cookiejar/networkcookiejar/trie_p.h new file mode 100644 index 00000000..926632b0 --- /dev/null +++ b/src/network/cookiejar/networkcookiejar/trie_p.h @@ -0,0 +1,255 @@ +/* + Copyright (C) 2009, Torch Mobile Inc. and Linden Research, Inc. All rights reserved. +*/ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Torch Mobile Inc. (http://www.torchmobile.com/) code + * + * The Initial Developer of the Original Code is: + * Benjamin Meyer (benjamin.meyer@torchmobile.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef TRIE_H +#define TRIE_H + +//#define TRIE_DEBUG + +#include + +#if defined(TRIE_DEBUG) +#include +#endif + +/* + A Trie tree (prefix tree) where the lookup takes m in the worst case. + + The key is stored in _reverse_ order + + Example: + Keys: x,a y,a + + Trie: + a + | \ + x y +*/ + +template +class Trie { +public: + Trie(); + ~Trie(); + + void clear(); + void insert(const QStringList &key, const T &value); + bool remove(const QStringList &key, const T &value); + QList find(const QStringList &key) const; + QList all() const; + + inline bool contains(const QStringList &key) const; + inline bool isEmpty() const { return children.isEmpty() && values.isEmpty(); } + +private: + const Trie* walkTo(const QStringList &key) const; + Trie* walkTo(const QStringList &key, bool create = false); + + template friend QDataStream &operator<<(QDataStream &, const Trie&); + template friend QDataStream &operator>>(QDataStream &, Trie&); + + QList values; + QStringList childrenKeys; + QList > children; +}; + +template +Trie::Trie() { +} + +template +Trie::~Trie() { +} + +template +void Trie::clear() { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__; +#endif + values.clear(); + childrenKeys.clear(); + children.clear(); +} + +template +bool Trie::contains(const QStringList &key) const { + return walkTo(key); +} + +template +void Trie::insert(const QStringList &key, const T &value) { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__ << key << value; +#endif + Trie *node = walkTo(key, true); + if (node) + node->values.append(value); +} + +template +bool Trie::remove(const QStringList &key, const T &value) { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__ << key << value; +#endif + Trie *node = walkTo(key, true); + if (node) { + bool removed = node->values.removeOne(value); + if (!removed) + return false; + + // A faster implementation of removing nodes up the tree + // can be created if profile shows this to be slow + QStringList subKey = key; + while (node->values.isEmpty() + && node->children.isEmpty() + && !subKey.isEmpty()) { + QString currentLevelKey = subKey.first(); + QStringList parentKey = subKey.mid(1); + Trie *parent = walkTo(parentKey, false); + Q_ASSERT(parent); + QStringList::iterator iterator; + iterator = qBinaryFind(parent->childrenKeys.begin(), + parent->childrenKeys.end(), + currentLevelKey); + Q_ASSERT(iterator != parent->childrenKeys.end()); + int index = iterator - parent->childrenKeys.begin(); + parent->children.removeAt(index); + parent->childrenKeys.removeAt(index); + + node = parent; + subKey = parentKey; + } + return removed; + } + return false; +} + +template +QList Trie::find(const QStringList &key) const { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__ << key; +#endif + const Trie *node = walkTo(key); + if (node) + return node->values; + return QList(); +} + +template +QList Trie::all() const { +#if defined(TRIE_DEBUG) + qDebug() << "Trie::" << __FUNCTION__; +#endif + QList all = values; + for (int i = 0; i < children.count(); ++i) + all += children[i].all(); + return all; +} + +template +QDataStream &operator<<(QDataStream &out, const Trie&trie) { + out << trie.values; + out << trie.childrenKeys; + out << trie.children; + Q_ASSERT(trie.childrenKeys.count() == trie.children.count()); + return out; +} + +template +QDataStream &operator>>(QDataStream &in, Trie &trie) { + trie.clear(); + in >> trie.values; + in >> trie.childrenKeys; + in >> trie.children; + Q_ASSERT(trie.childrenKeys.count() == trie.children.count()); + return in; +} + +// Very fast const walk +template +const Trie* Trie::walkTo(const QStringList &key) const { + const Trie *node = this; + QStringList::const_iterator childIterator; + QStringList::const_iterator begin, end; + + int depth = key.count() - 1; + while (depth >= 0) { + const QString currentLevelKey = key.at(depth--); + begin = node->childrenKeys.constBegin(); + end = node->childrenKeys.constEnd(); + childIterator = qBinaryFind(begin, end, currentLevelKey); + if (childIterator == end) + return 0; + node = &node->children.at(childIterator - begin); + } + return node; +} + +template +Trie* Trie::walkTo(const QStringList &key, bool create) { + QStringList::iterator iterator; + Trie *node = this; + QStringList::iterator begin, end; + int depth = key.count() - 1; + while (depth >= 0) { + const QString currentLevelKey = key.at(depth--); + begin = node->childrenKeys.begin(); + end = node->childrenKeys.end(); + iterator = qBinaryFind(begin, end, currentLevelKey); +#if defined(TRIE_DEBUG) + qDebug() << "\t" << node << key << currentLevelKey << node->childrenKeys; +#endif + int index = -1; + if (iterator == end) { + if (!create) + return 0; + iterator = qLowerBound(begin, + end, + currentLevelKey); + index = iterator - begin; + node->childrenKeys.insert(iterator, currentLevelKey); + node->children.insert(index, Trie()); + } else { + index = iterator - begin; + } + Q_ASSERT(index >= 0 && index < node->children.count()); + node = &node->children[index]; + } + return node; +} + +#endif + diff --git a/src/network/cookiejar/networkcookiejar/twoleveldomains_p.h b/src/network/cookiejar/networkcookiejar/twoleveldomains_p.h new file mode 100644 index 00000000..25e15339 --- /dev/null +++ b/src/network/cookiejar/networkcookiejar/twoleveldomains_p.h @@ -0,0 +1,103 @@ +/* + Copyright (C) 2009, Torch Mobile Inc. and Linden Research, Inc. All rights reserved. +*/ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Torch Mobile Inc. (http://www.torchmobile.com/) code + * + * The Initial Developer of the Original Code is: + * Benjamin Meyer (benjamin.meyer@torchmobile.com) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Updated from https://wiki.mozilla.org/TLD_List#External_Links +// To set a custom list use NetworkCookieJar::setSecondLevelDomains() +static const char *const twoLevelDomains[] = { + "ao", + "ar", + "arpa", + "bd", + "bn", + "br", + "co", + "cr", + "cy", + "do", + "eg", + "et", + "fj", + "fk", + "gh", + "gn", + "gu", + "id", + "il", + "jm", + "ke", + "kh", + "ki", + "kw", + "kz", + "lb", + "lc", + "lr", + "ls", + "ml", + "mm", + "mv", + "mw", + "mx", + "my", + "ng", + "ni", + "np", + "nz", + "om", + "pa", + "pe", + "pg", + "pw", + "py", + "qa", + "sa", + "sb", + "sv", + "sy", + "th", + "tn", + "tz", + "uk", + "uy", + "va", + "ve", + "ye", + "yu", + "za", + "zm", + "zw", + 0 +}; diff --git a/src/network/fileaccesshandler.cpp b/src/network/fileaccesshandler.cpp new file mode 100644 index 00000000..de65abe7 --- /dev/null +++ b/src/network/fileaccesshandler.cpp @@ -0,0 +1,216 @@ +/* + * Copyright 2009 Jonas Gehring + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "fileaccesshandler.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +FileAccessHandler::FileAccessHandler(QObject *parent) + : SchemeAccessHandler(parent) +{ +} + +QNetworkReply *FileAccessHandler::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) +{ + Q_UNUSED(outgoingData); + + switch (op) { + case QNetworkAccessManager::GetOperation: + break; + default: + return 0; + } + + // This handler can only list directories yet, so pass anything + // else back to the manager + QString path = request.url().toLocalFile(); + if (!QFileInfo(path).isDir()) { + return 0; + } + + FileAccessReply *reply = new FileAccessReply(request, this); + return reply; +} + + +FileAccessReply::FileAccessReply(const QNetworkRequest &request, QObject *parent) + : QNetworkReply(parent) +{ + setOperation(QNetworkAccessManager::GetOperation); + setRequest(request); + setUrl(request.url()); + + buffer.open(QIODevice::ReadWrite); + setError(QNetworkReply::NoError, tr("No Error")); + + QTimer::singleShot(0, this, SLOT(listDirectory())); + + open(QIODevice::ReadOnly); +} + +FileAccessReply::~FileAccessReply() +{ + close(); +} + +qint64 FileAccessReply::bytesAvailable() const +{ + return buffer.bytesAvailable() + QNetworkReply::bytesAvailable(); +} + +void FileAccessReply::close() +{ + buffer.close(); +} + +static QString cssLinkClass(const QIcon &icon, int size = 32) +{ + // The CSS class generation is a bit tricky, because QIcon/QPixmap's + // cacheKey() returns the different values for the same icons on my Windows + // box (tested with XP). Thus, the checksum of the actual text of the CSS class + // is used for the class name. + QString data = QLatin1String("a.%3 {\n\ + padding-left: %1px;\n\ + background: transparent url(data:image/png;base64,%2) no-repeat center left;\n\ + font-weight: bold;\n\ +}\n"); + QPixmap pixmap = icon.pixmap(QSize(size, size)); + QBuffer imageBuffer; + imageBuffer.open(QBuffer::ReadWrite); + if (!pixmap.save(&imageBuffer, "PNG")) { + // If an error occured, write a blank pixmap + pixmap = QPixmap(size, size); + pixmap.fill(Qt::transparent); + imageBuffer.buffer().clear(); + pixmap.save(&imageBuffer, "PNG"); + } + return data.arg(size+4).arg(QLatin1String(imageBuffer.buffer().toBase64())); +} + +void FileAccessReply::listDirectory() +{ + QDir dir(url().toLocalFile()); + if (!dir.exists()) { + setError(QNetworkReply::ContentNotFoundError, tr("Error opening: %1: No such file or directory").arg(dir.absolutePath())); + emit error(QNetworkReply::ContentNotFoundError); + emit finished(); + return; + } + if (!dir.isReadable()) { + setError(QNetworkReply::ContentAccessDenied, tr("Unable to read %1").arg(dir.absolutePath())); + emit error(QNetworkReply::ContentAccessDenied); + emit finished(); + return; + } + + // Format a html page for the directory contents + QFile dirlistFile(QLatin1String(":/dirlist.html")); + if (!dirlistFile.open(QIODevice::ReadOnly)) + return; + QString html = QLatin1String(dirlistFile.readAll()); + html = html.arg(dir.absolutePath(), tr("Contents of %1").arg(dir.absolutePath())); + + // Templates for the listing + QString link = QLatin1String("%3"); + QString row = QLatin1String(" %2 %3 %4 \n"); + + QFileIconProvider iconProvider; + QHash existingClasses; + int iconSize = QWebSettings::globalSettings()->fontSize(QWebSettings::DefaultFontSize); + QFileInfoList list = dir.entryInfoList(QDir::AllEntries | QDir::Hidden, QDir::Name | QDir::DirsFirst); + QString dirlist, classes; + + // Write link to parent directory first + if (!dir.isRoot()) { + QIcon icon = qApp->style()->standardIcon(QStyle::SP_FileDialogToParent); + classes += cssLinkClass(icon, iconSize).arg(QLatin1String("link_parent")); + + QString addr = QString::fromUtf8(QUrl::fromLocalFile(QFileInfo(dir.absoluteFilePath(QLatin1String(".."))).canonicalFilePath()).toEncoded()); + QString size, modified; // Empty by intention + dirlist += row.arg(QString()).arg(link.arg(QLatin1String("link_parent")).arg(addr).arg(QLatin1String(".."))).arg(size).arg(modified); + } + + for (int i = 0; i < list.count(); ++i) { + // Skip '.' and '..' + if (list[i].fileName() == QLatin1String(".") || list[i].fileName() == QLatin1String("..")) { + continue; + } + + // Fetch file icon and generate a corresponding CSS class if neccessary + QIcon icon = iconProvider.icon(list[i]); + QString cssClass = cssLinkClass(icon, iconSize); + QByteArray cssData = cssClass.toLatin1(); + QString className = QString(QLatin1String("link_%1")).arg(QLatin1String(QCryptographicHash::hash(cssData, QCryptographicHash::Md4).toHex())); + if (!existingClasses.contains(className)) { + classes += cssClass.arg(className); + existingClasses.insert(className, true); + } + + QString addr = QString::fromUtf8(QUrl::fromLocalFile(list[i].canonicalFilePath()).toEncoded()); + QString size, modified; + if (list[i].fileName() != QLatin1String("..")) { + if (list[i].isFile()) + size = tr("%1 KB").arg(QString::number(list[i].size()/1024)); + modified = list[i].lastModified().toString(Qt::SystemLocaleShortDate); + } + + QString classes; + if (list[i].isHidden()) + classes = QLatin1String(" class=\"hidden\""); + dirlist += row.arg(classes).arg(link.arg(className).arg(addr).arg(list[i].fileName())).arg(size).arg(modified); + } + + html = html.arg(classes).arg(dirlist).arg(tr("Show Hidden Files")); + + // Save result to buffer + QTextStream stream(&buffer); + stream << html; + stream.flush(); + buffer.reset(); + + // Publish result + setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("text/html")); + setHeader(QNetworkRequest::ContentLengthHeader, buffer.bytesAvailable()); + setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200); + setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, QByteArray("Ok")); + emit metaDataChanged(); + emit downloadProgress(buffer.size(), buffer.size()); + QNetworkReply::NetworkError errorCode = error(); + if (errorCode != QNetworkReply::NoError) { + emit error(errorCode); + } else if (buffer.size() > 0) { + emit readyRead(); + } + + emit finished(); +} + +qint64 FileAccessReply::readData(char *data, qint64 maxSize) +{ + return buffer.read(data, maxSize); +} diff --git a/src/network/fileaccesshandler.h b/src/network/fileaccesshandler.h new file mode 100644 index 00000000..1c887ff3 --- /dev/null +++ b/src/network/fileaccesshandler.h @@ -0,0 +1,58 @@ +/* + * Copyright 2009 Jonas Gehring + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef FILEACCESSHANDLER_H +#define FILEACCESSHANDLER_H + +#include "schemeaccesshandler.h" + +#include +#include + +class FileAccessHandler : public SchemeAccessHandler +{ +public: + FileAccessHandler(QObject *parent = 0); + + virtual QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0); +}; + +class FileAccessReply : public QNetworkReply +{ + Q_OBJECT + +public: + FileAccessReply(const QNetworkRequest &request, QObject *parent = 0); + ~FileAccessReply(); + + virtual qint64 bytesAvailable() const; + virtual void abort() { }; + virtual void close(); + +protected: + virtual qint64 readData(char *data, qint64 maxSize); + +private slots: + void listDirectory(); + +private: + QBuffer buffer; +}; + +#endif // FILEACCESSHANDLER_H diff --git a/src/network/network.pri b/src/network/network.pri new file mode 100644 index 00000000..5c912f44 --- /dev/null +++ b/src/network/network.pri @@ -0,0 +1,22 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +FORMS += \ + passworddialog.ui \ + proxy.ui + +HEADERS += \ + fileaccesshandler.h \ + networkaccessmanager.h \ + networkdiskcache.h \ + networkproxyfactory.h \ + schemeaccesshandler.h + +SOURCES += \ + fileaccesshandler.cpp \ + networkaccessmanager.cpp \ + networkdiskcache.cpp \ + networkproxyfactory.cpp \ + schemeaccesshandler.cpp + +include(cookiejar/cookiejar.pri) diff --git a/src/networkaccessmanager.cpp b/src/network/networkaccessmanager.cpp similarity index 56% rename from src/networkaccessmanager.cpp rename to src/network/networkaccessmanager.cpp index 2ee56641..56fb343d 100644 --- a/src/networkaccessmanager.cpp +++ b/src/network/networkaccessmanager.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,8 +62,18 @@ #include "networkaccessmanager.h" +#include "adblockmanager.h" +#include "adblocknetwork.h" +#include "adblockschemeaccesshandler.h" +#include "acceptlanguagedialog.h" +#include "autofillmanager.h" #include "browserapplication.h" #include "browsermainwindow.h" +#include "cookiejar.h" +#include "schemeaccesshandler.h" +#include "fileaccesshandler.h" +#include "networkproxyfactory.h" +#include "networkdiskcache.h" #include "ui_passworddialog.h" #include "ui_proxy.h" @@ -74,13 +84,15 @@ #include #include -#include -#include #include #include +#include + +// #define NETWORKACCESSMANAGER_DEBUG NetworkAccessManager::NetworkAccessManager(QObject *parent) - : QNetworkAccessManager(parent) + : NetworkAccessManagerProxy(parent) + , m_adblockNetwork(0) { connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*))); @@ -90,7 +102,33 @@ NetworkAccessManager::NetworkAccessManager(QObject *parent) connect(this, SIGNAL(sslErrors(QNetworkReply*, const QList&)), SLOT(sslErrors(QNetworkReply*, const QList&))); #endif + connect(BrowserApplication::instance(), SIGNAL(privacyChanged(bool)), + this, SLOT(privacyChanged(bool))); loadSettings(); + + // Register custom scheme handlers + setSchemeHandler(QLatin1String("file"), new FileAccessHandler(this)); + setSchemeHandler(QLatin1String("abp"), new AdBlockSchemeAccessHandler(this)); + setCookieJar(new CookieJar); +} + +void NetworkAccessManager::privacyChanged(bool isPrivate) +{ + // Create a new CookieJar that has the privacy flag set so the old cookies + // are not loaded and the cookies are not saved on exit + if (isPrivate) { + CookieJar *cookieJar = new CookieJar; + cookieJar->setPrivate(isPrivate); + setCookieJar(cookieJar); + } else { + // it will delete the old one + setCookieJar(new CookieJar); + } +} + +void NetworkAccessManager::setSchemeHandler(const QString &scheme, SchemeAccessHandler *handler) +{ + m_schemeHandlers.insert(scheme, handler); } void NetworkAccessManager::loadSettings() @@ -99,16 +137,29 @@ void NetworkAccessManager::loadSettings() settings.beginGroup(QLatin1String("proxy")); QNetworkProxy proxy; if (settings.value(QLatin1String("enabled"), false).toBool()) { - if (settings.value(QLatin1String("type"), 0).toInt() == 0) - proxy.setType(QNetworkProxy::Socks5Proxy); - else - proxy.setType(QNetworkProxy::HttpProxy); + int proxyType = settings.value(QLatin1String("type"), 0).toInt(); + if (proxyType == 0) + proxy = QNetworkProxy::Socks5Proxy; + else if (proxyType == 1) + proxy = QNetworkProxy::HttpProxy; + else { // 2 + proxy.setType(QNetworkProxy::HttpCachingProxy); + proxy.setCapabilities(QNetworkProxy::CachingCapability | QNetworkProxy::HostNameLookupCapability); + } proxy.setHostName(settings.value(QLatin1String("hostName")).toString()); proxy.setPort(settings.value(QLatin1String("port"), 1080).toInt()); proxy.setUser(settings.value(QLatin1String("userName")).toString()); proxy.setPassword(settings.value(QLatin1String("password")).toString()); } - setProxy(proxy); + NetworkProxyFactory *proxyFactory = new NetworkProxyFactory; + if (proxy.type() == QNetworkProxy::HttpCachingProxy) { + proxyFactory->setHttpProxy(proxy); + proxyFactory->setGlobalProxy(QNetworkProxy::DefaultProxy); + } else { + proxyFactory->setHttpProxy(QNetworkProxy::DefaultProxy); + proxyFactory->setGlobalProxy(proxy); + } + setProxyFactory(proxyFactory); settings.endGroup(); #ifndef QT_NO_OPENSSL @@ -116,14 +167,40 @@ void NetworkAccessManager::loadSettings() QList ca_list = sslCfg.caCertificates(); QList ca_new = QSslCertificate::fromData(settings.value(QLatin1String("CaCertificates")).toByteArray()); ca_list += ca_new; - sslCfg.setCaCertificates(ca_list); + sslCfg.setProtocol(QSsl::AnyProtocol); QSslConfiguration::setDefaultConfiguration(sslCfg); #endif + + settings.beginGroup(QLatin1String("network")); + QStringList acceptList = settings.value(QLatin1String("acceptLanguages"), + AcceptLanguageDialog::defaultAcceptList()).toStringList(); + m_acceptLanguage = AcceptLanguageDialog::httpString(acceptList); + + bool cacheEnabled = settings.value(QLatin1String("cacheEnabled"), true).toBool(); + if (QLatin1String(qVersion()) == QLatin1String("4.5.1")) + cacheEnabled = false; + + if (cacheEnabled) { + NetworkDiskCache *diskCache; + if (cache()) + diskCache = qobject_cast(cache()); + else + diskCache = new NetworkDiskCache(this); + setCache(diskCache); + diskCache->loadSettings(); + } else { + if (QLatin1String(qVersion()) > QLatin1String("4.5.1")) + setCache(0); + } + settings.endGroup(); } void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth) { +#ifdef NETWORKACCESSMANAGER_DEBUG + qDebug() << __FUNCTION__ << reply; +#endif BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); QDialog dialog(mainWindow); @@ -136,7 +213,7 @@ void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthent passwordDialog.iconLabel->setPixmap(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow).pixmap(32, 32)); QString introMessage = tr("Enter username and password for \"%1\" at %2"); - introMessage = introMessage.arg(Qt::escape(reply->url().toString())).arg(Qt::escape(reply->url().toString())); + introMessage = introMessage.arg(Qt::escape(auth->realm())).arg(Qt::escape(reply->url().toString())); passwordDialog.introLabel->setText(introMessage); passwordDialog.introLabel->setWordWrap(true); @@ -148,6 +225,9 @@ void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthent void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth) { +#ifdef NETWORKACCESSMANAGER_DEBUG + qDebug() << __FUNCTION__; +#endif BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); QDialog dialog(mainWindow); @@ -171,8 +251,35 @@ void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &prox } #ifndef QT_NO_OPENSSL +QString NetworkAccessManager::certToFormattedString(QSslCertificate cert) +{ + QStringList message; + message << cert.subjectInfo(QSslCertificate::CommonName); + message << tr("Issuer: %1").arg(cert.issuerInfo(QSslCertificate::CommonName)); + message << tr("Not valid before: %1").arg(cert.effectiveDate().toString()); + message << tr("Valid until: %1").arg(cert.expiryDate().toString()); + + QMultiMap names = cert.alternateSubjectNames(); + if (names.count() > 0) { + QString list; + list += QLatin1String("
    "); + list += tr("Alternate Names:"); + list += QLatin1String("
    • "); + list += QStringList(names.values(QSsl::DnsEntry)).join(QLatin1String("
    • ")); + list += QLatin1String("
    "); + message << list; + } + + QString result = QLatin1String("

    ") + message.join(QLatin1String("
    ")) + QLatin1String("

    "); + + return result; +} + void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QList &error) { +#ifdef NETWORKACCESSMANAGER_DEBUG + qDebug() << __FUNCTION__; +#endif BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); QSettings settings; @@ -193,17 +300,26 @@ void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QListurl().toString()).arg(errors), + QString errors = errorStrings.join(QLatin1String("
  • ")); + int ret = QMessageBox::warning(mainWindow, + QCoreApplication::applicationName() + tr(" - SSL Errors"), + tr("SSL Errors:" + "

    for: %1" + "
    • %2
    \n\n" + "Do you want to ignore these errors?
    ").arg(reply->url().toString()).arg(errors), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (ret == QMessageBox::Yes) { if (ca_new.count() > 0) { + QStringList certinfos; + for (int i = 0; i < ca_new.count(); ++i) + certinfos += certToFormattedString(ca_new.at(i)); ret = QMessageBox::question(mainWindow, QCoreApplication::applicationName(), - tr("Do you want to accept all these certificates?"), + tr("Certificates:
    " + "%1
    " + "Do you want to accept all these certificates?
    ") + .arg(certinfos.join(QString())), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); if (ret == QMessageBox::Yes) { ca_merge += ca_new; @@ -212,6 +328,7 @@ void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QList ca_list = sslCfg.caCertificates(); ca_list += ca_new; sslCfg.setCaCertificates(ca_list); + sslCfg.setProtocol(QSsl::AnyProtocol); QSslConfiguration::setDefaultConfiguration(sslCfg); reply->setSslConfiguration(sslCfg); @@ -225,3 +342,39 @@ void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QListpeek(1024 * 1024); + BrowserApplication::autoFillManager()->post(request, outgoingDataByteArray); + } + + QNetworkReply *reply = 0; + // Check if there is a valid handler registered for the requested URL scheme + if (m_schemeHandlers.contains(request.url().scheme())) + reply = m_schemeHandlers[request.url().scheme()]->createRequest(op, request, outgoingData); + if (reply) + return reply; + + QNetworkRequest req = request; +#if QT_VERSION >= 0x040600 + req.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); +#endif + if (!m_acceptLanguage.isEmpty()) + req.setRawHeader("Accept-Language", m_acceptLanguage); + + // Adblock + if (op == QNetworkAccessManager::GetOperation) { + if (!m_adblockNetwork) + m_adblockNetwork = AdBlockManager::instance()->network(); + reply = m_adblockNetwork->block(req); + if (reply) + return reply; + } + + reply = QNetworkAccessManager::createRequest(op, req, outgoingData); + emit requestCreated(op, req, reply); + return reply; +} + diff --git a/src/network/networkaccessmanager.h b/src/network/networkaccessmanager.h new file mode 100644 index 00000000..930aa0ce --- /dev/null +++ b/src/network/networkaccessmanager.h @@ -0,0 +1,116 @@ +/* + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/**************************************************************************** +** +** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the demonstration applications of the Qt Toolkit. +** +** This file may be used under the terms of the GNU General Public +** License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Alternatively you may (at +** your option) use any later version of the GNU General Public +** License if such license has been publicly approved by Trolltech ASA +** (or its successors, if any) and the KDE Free Qt Foundation. In +** addition, as a special exception, Trolltech gives you certain +** additional rights. These rights are described in the Trolltech GPL +** Exception version 1.2, which can be found at +** http://www.trolltech.com/products/qt/gplexception/ and in the file +** GPL_EXCEPTION.txt in this package. +** +** Please review the following information to ensure GNU General +** Public Licensing requirements will be met: +** http://trolltech.com/products/qt/licenses/licensing/opensource/. If +** you are unsure which license is appropriate for your use, please +** review the following information: +** http://trolltech.com/products/qt/licenses/licensing/licensingoverview +** or contact the sales department at sales@trolltech.com. +** +** In addition, as a special exception, Trolltech, as the sole +** copyright holder for Qt Designer, grants users of the Qt/Eclipse +** Integration plug-in the right for the Qt/Eclipse Integration to +** link to functionality provided by Qt Designer and its related +** libraries. +** +** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, +** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR +** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly +** granted herein. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#ifndef NETWORKACCESSMANAGER_H +#define NETWORKACCESSMANAGER_H + +#include +#include +#include +#include "networkaccessmanagerproxy.h" + +class SchemeAccessHandler; + +class AdBlockNetwork; +class NetworkAccessManager : public NetworkAccessManagerProxy +{ + Q_OBJECT + +signals: + void requestCreated(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QNetworkReply *reply); + +public: + NetworkAccessManager(QObject *parent = 0); + void setSchemeHandler(const QString &scheme, SchemeAccessHandler *handler); + + inline QNetworkReply *createRequestProxy(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) + { + return createRequest(op, request, outgoingData); + } + +protected: + QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0); + +public slots: + void loadSettings(); + +private slots: + void authenticationRequired(QNetworkReply *reply, QAuthenticator *auth); + void proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth); +#ifndef QT_NO_OPENSSL + void sslErrors(QNetworkReply *reply, const QList &error); +#endif + void privacyChanged(bool isPrivate); + +private: +#ifndef QT_NO_OPENSSL + static QString certToFormattedString(QSslCertificate cert); +#endif + + QByteArray m_acceptLanguage; + QHash m_schemeHandlers; + + QNetworkCookieJar *m_privateCookieJar; + AdBlockNetwork *m_adblockNetwork; +}; + +#endif // NETWORKACCESSMANAGER_H diff --git a/src/network/networkdiskcache.cpp b/src/network/networkdiskcache.cpp new file mode 100644 index 00000000..cfd0d77b --- /dev/null +++ b/src/network/networkdiskcache.cpp @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "networkdiskcache.h" + +#include "browserapplication.h" + +#include +#include + +NetworkDiskCache::NetworkDiskCache(QObject *parent) + : QNetworkDiskCache(parent) + , m_private(false) +{ + QString diskCacheDirectory = QDesktopServices::storageLocation(QDesktopServices::CacheLocation) + + QLatin1String("/browser"); + setCacheDirectory(diskCacheDirectory); + connect(BrowserApplication::instance(), SIGNAL(privacyChanged(bool)), + this, SLOT(privacyChanged(bool))); +} + +void NetworkDiskCache::loadSettings() +{ + QSettings settings; + settings.beginGroup(QLatin1String("network")); + qint64 maximumCacheSize = settings.value(QLatin1String("maximumCacheSize"), 50).toInt(); + maximumCacheSize = maximumCacheSize * 1024 * 1024; + setMaximumCacheSize(maximumCacheSize); +} + +void NetworkDiskCache::privacyChanged(bool isPrivate) +{ + m_private = isPrivate; +} + +QIODevice *NetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData) +{ + if (m_private) + return 0; + return QNetworkDiskCache::prepare(metaData); +} + diff --git a/src/network/networkdiskcache.h b/src/network/networkdiskcache.h new file mode 100644 index 00000000..f61977d8 --- /dev/null +++ b/src/network/networkdiskcache.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NETWORKDISKCACHE_H +#define NETWORKDISKCACHE_H + +#include + +class NetworkDiskCache : public QNetworkDiskCache +{ + Q_OBJECT + +public: + NetworkDiskCache(QObject *parent = 0); + + void loadSettings(); + + QIODevice *prepare(const QNetworkCacheMetaData &metaData); + +private slots: + void privacyChanged(bool isPrivate); + +private: + bool m_private; +}; + +#endif // NETWORKDISKCACHE_H + diff --git a/src/network/networkproxyfactory.cpp b/src/network/networkproxyfactory.cpp new file mode 100644 index 00000000..9cda8092 --- /dev/null +++ b/src/network/networkproxyfactory.cpp @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Benjamin K. Stuhl + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "networkproxyfactory.h" + +NetworkProxyFactory::NetworkProxyFactory() + : QNetworkProxyFactory() +{ +} + +void NetworkProxyFactory::setHttpProxy(const QNetworkProxy &proxy) +{ + m_httpProxy = proxy; +} + +void NetworkProxyFactory::setGlobalProxy(const QNetworkProxy &proxy) +{ + m_globalProxy = proxy; +} + +QList NetworkProxyFactory::queryProxy(const QNetworkProxyQuery &query) +{ + QList ret; + + if (query.protocolTag() == QLatin1String("http") && m_httpProxy.type() != QNetworkProxy::DefaultProxy) + ret << m_httpProxy; + ret << m_globalProxy; + + return ret; +} + diff --git a/src/network/networkproxyfactory.h b/src/network/networkproxyfactory.h new file mode 100644 index 00000000..9f692aa7 --- /dev/null +++ b/src/network/networkproxyfactory.h @@ -0,0 +1,40 @@ +/* + * Copyright 2009 Benjamin K. Stuhl + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef NETWORKPROXYFACTORY_H +#define NETWORKPROXYFACTORY_H + +#include + +class NetworkProxyFactory : public QNetworkProxyFactory +{ +public: + NetworkProxyFactory(); + + void setHttpProxy(const QNetworkProxy &proxy); + void setGlobalProxy(const QNetworkProxy &proxy); + + virtual QList queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()); + +private: + QNetworkProxy m_httpProxy; + QNetworkProxy m_globalProxy; +}; + +#endif // NETWORKPROXYFACTORY_H diff --git a/src/passworddialog.ui b/src/network/passworddialog.ui similarity index 100% rename from src/passworddialog.ui rename to src/network/passworddialog.ui diff --git a/src/proxy.ui b/src/network/proxy.ui similarity index 52% rename from src/proxy.ui rename to src/network/proxy.ui index 62a8be62..33fa25f7 100644 --- a/src/proxy.ui +++ b/src/network/proxy.ui @@ -1,7 +1,8 @@ - + + ProxyDialog - - + + 0 0 @@ -9,57 +10,57 @@ 144 - + Proxy Authentication - - - - - ICON + + + + + ICON - - - + + + Connect to proxy - + true - - - + + + Username: - - + + - - - + + + Password: - - - + + + QLineEdit::Password - - - + + + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok @@ -74,11 +75,11 @@ ProxyDialog accept() - + 248 254 - + 157 274 @@ -90,11 +91,11 @@ ProxyDialog reject() - + 316 260 - + 286 274 diff --git a/src/network/schemeaccesshandler.cpp b/src/network/schemeaccesshandler.cpp new file mode 100644 index 00000000..1e4a8294 --- /dev/null +++ b/src/network/schemeaccesshandler.cpp @@ -0,0 +1,26 @@ +/* + * Copyright 2009 Jonas Gehring + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "schemeaccesshandler.h" + +SchemeAccessHandler::SchemeAccessHandler(QObject *parent) + : QObject(parent) +{ +} + diff --git a/src/network/schemeaccesshandler.h b/src/network/schemeaccesshandler.h new file mode 100644 index 00000000..c2310b05 --- /dev/null +++ b/src/network/schemeaccesshandler.h @@ -0,0 +1,36 @@ +/* + * Copyright 2009 Jonas Gehring + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef SCHEMEACCESSHANDLER_H +#define SCHEMEACCESSHANDLER_H + +#include + +#include + +class QNetworkReply; +class SchemeAccessHandler : public QObject +{ +public: + SchemeAccessHandler(QObject *parent = 0); + + virtual QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0) = 0; +}; + +#endif // SCHEMEACCESSHANDLER_H diff --git a/src/opensearch/opensearch.pri b/src/opensearch/opensearch.pri new file mode 100644 index 00000000..dbace745 --- /dev/null +++ b/src/opensearch/opensearch.pri @@ -0,0 +1,26 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + opensearchdialog.h \ + opensearchengine.h \ + opensearchenginedelegate.h \ + opensearchengineaction.h \ + opensearchenginemodel.h \ + opensearchmanager.h \ + opensearchreader.h \ + opensearchwriter.h + +SOURCES += \ + opensearchdialog.cpp \ + opensearchengine.cpp \ + opensearchenginedelegate.cpp \ + opensearchengineaction.cpp \ + opensearchenginemodel.cpp \ + opensearchmanager.cpp \ + opensearchreader.cpp \ + opensearchwriter.cpp + +FORMS += opensearchdialog.ui + +QT += script diff --git a/src/opensearch/opensearchdialog.cpp b/src/opensearch/opensearchdialog.cpp new file mode 100644 index 00000000..94fdf8d8 --- /dev/null +++ b/src/opensearch/opensearchdialog.cpp @@ -0,0 +1,88 @@ +/* + * Copyright 2009 Christian Franke + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchdialog.h" + +#include "browserapplication.h" +#include "opensearchenginemodel.h" +#include "opensearchmanager.h" +#include "toolbarsearch.h" + +#include +#include + +OpenSearchDialog::OpenSearchDialog(QWidget *parent) + : QDialog(parent) + , m_model(0) +{ + setModal(true); + setupUi(this); + + m_model = new OpenSearchEngineModel(ToolbarSearch::openSearchManager(), this); + m_tableView->setModel(m_model); + m_tableView->horizontalHeader()->resizeSection(0, 200); + m_tableView->horizontalHeader()->setStretchLastSection(true); + m_tableView->verticalHeader()->hide(); + m_tableView->verticalHeader()->setDefaultSectionSize(1.2 * fontMetrics().height()); + m_tableView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_tableView->setShowGrid(false); + m_tableView->setAlternatingRowColors(true); + + connect(m_closeButton, SIGNAL(clicked()), + this, SLOT(close())); + connect(m_addButton, SIGNAL(clicked()), + this, SLOT(addButtonClicked())); + connect(m_deleteButton, SIGNAL(clicked()), + this, SLOT(deleteButtonClicked())); + connect(m_restoreButton, SIGNAL(clicked()), + this, SLOT(restoreButtonClicked())); +} + +void OpenSearchDialog::addButtonClicked() +{ + QStringList fileNames = QFileDialog::getOpenFileNames(this, + tr("Open File"), + QString(), + tr("OpenSearch") + QLatin1String(" (*.xml)")); + + foreach (const QString &fileName, fileNames) { + if (!ToolbarSearch::openSearchManager()->addEngine(fileName)) { + QMessageBox::critical(this, tr("Error"), + tr("%1 is not a valid OpenSearch 1.1 description or is already on your list.").arg(fileName)); + } + } +} + +void OpenSearchDialog::deleteButtonClicked() +{ + if (m_tableView->model()->rowCount() == 1) { + QMessageBox::critical(this, tr("Error"), + tr("You must have at least one search engine in here.")); + return; + } + + m_tableView->removeSelected(); +} + +void OpenSearchDialog::restoreButtonClicked() +{ + ToolbarSearch::openSearchManager()->restoreDefaults(); +} + diff --git a/src/opensearch/opensearchdialog.h b/src/opensearch/opensearchdialog.h new file mode 100644 index 00000000..5f50e974 --- /dev/null +++ b/src/opensearch/opensearchdialog.h @@ -0,0 +1,47 @@ +/* + * Copyright 2009 Christian Franke + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHDIALOG_H +#define OPENSEARCHDIALOG_H + +#include + +#include "ui_opensearchdialog.h" + +class OpenSearchEngineModel; + +class OpenSearchDialog : public QDialog, public Ui_OpenSearchDialog +{ + Q_OBJECT + +public: + OpenSearchDialog(QWidget *parent = 0); + +protected slots: + void addButtonClicked(); + void deleteButtonClicked(); + void restoreButtonClicked(); + +private: + OpenSearchEngineModel *m_model; +}; + +#endif //OPENSEARCHDIALOG_H + diff --git a/src/opensearch/opensearchdialog.ui b/src/opensearch/opensearchdialog.ui new file mode 100644 index 00000000..1e503e51 --- /dev/null +++ b/src/opensearch/opensearchdialog.ui @@ -0,0 +1,81 @@ + + + OpenSearchDialog + + + + 0 + 0 + 500 + 250 + + + + OpenSearch Manager + + + + + + + 400 + + + + + + + + + + &Add + + + + + + + &Delete + + + + + + + &Restore Defaults + + + + + + + Qt::Horizontal + + + + 50 + + + + + + + + &Close + + + + + + + + + + EditTableView + QTableView +
    edittableview.h
    +
    +
    + + +
    diff --git a/src/opensearch/opensearchengine.cpp b/src/opensearch/opensearchengine.cpp new file mode 100644 index 00000000..0332fc16 --- /dev/null +++ b/src/opensearch/opensearchengine.cpp @@ -0,0 +1,609 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchengine.h" + +#include "opensearchenginedelegate.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + \class OpenSearchEngine + \brief A class representing a single search engine described in OpenSearch format + + OpenSearchEngine is a class that represents a single search engine based on + the OpenSearch format. + For more information about the format, see http://www.opensearch.org/. + + Instances of the class hold all the data associated with the corresponding search + engines, such as name(), description() and also URL templates that are used + to construct URLs, which can be used later to perform search queries. Search engine + can also have an image, even an external one, in this case it will be downloaded + automatically from the network. + + OpenSearchEngine instances can be constructed from scratch but also read from + external sources and written back to them. OpenSearchReader and OpenSearchWriter + are the classes provided for reading and writing OpenSearch descriptions. + + Default constructed engines need to be filled with the necessary information before + they can be used to peform search requests. First of all, a search engine should have + the metadata including the name and the description. + However, the most important are URL templates, which are the construction of URLs + but can also contain template parameters, that are replaced with corresponding values + at the time of constructing URLs. + + There are two types of URL templates: search URL template and suggestions URL template. + Search URL template is needed for constructing search URLs, which point directly to + search results. Suggestions URL template is necessary to construct suggestion queries + URLs, which are then used for requesting contextual suggestions, a popular service + offered along with search results that provides search terms related to what has been + supplied by the user. + + Both types of URLs are constructed by the class, by searchUrl() and suggestionsUrl() + functions respectively. However, search requests are supposed to be performed outside + the class, while suggestion queries can be executed using the requestSuggestions() + method. The class will take care of peforming the network request and parsing the + JSON response. + + Both the image request and suggestion queries need network access. The class can + perform network requests on its own, though the client application needs to provide + a network access manager, which then will to be used for network operations. + Without that, both images delivered from remote locations and contextual suggestions + will be disabled. + + \sa OpenSearchReader, OpenSearchWriter +*/ + +/*! + Constructs an engine with a given \a parent. +*/ +OpenSearchEngine::OpenSearchEngine(QObject *parent) + : QObject(parent) + , m_searchMethod(QLatin1String("get")) + , m_suggestionsMethod(QLatin1String("get")) + , m_networkAccessManager(0) + , m_suggestionsReply(0) + , m_scriptEngine(0) + , m_delegate(0) +{ + m_requestMethods.insert(QLatin1String("get"), QNetworkAccessManager::GetOperation); + m_requestMethods.insert(QLatin1String("post"), QNetworkAccessManager::PostOperation); +} + +/*! + A destructor. +*/ +OpenSearchEngine::~OpenSearchEngine() +{ + if (m_scriptEngine) + m_scriptEngine->deleteLater(); +} + +QString OpenSearchEngine::parseTemplate(const QString &searchTerm, const QString &searchTemplate) +{ + QString language = QLocale().name(); + // Simple conversion to RFC 3066. + language = language.replace(QLatin1Char('_'), QLatin1Char('-')); + + QString result = searchTemplate; + result.replace(QLatin1String("{count}"), QLatin1String("20")); + result.replace(QLatin1String("{startIndex}"), QLatin1String("0")); + result.replace(QLatin1String("{startPage}"), QLatin1String("0")); + result.replace(QLatin1String("{language}"), language); + result.replace(QLatin1String("{inputEncoding}"), QLatin1String("UTF-8")); + result.replace(QLatin1String("{outputEncoding}"), QLatin1String("UTF-8")); + result.replace(QRegExp(QLatin1String("\\{([^\\}]*:|)source\\??\\}")), QCoreApplication::applicationName()); + result.replace(QLatin1String("{searchTerms}"), QLatin1String(QUrl::toPercentEncoding(searchTerm))); + + return result; +} + +/*! + \property OpenSearchEngine::name + \brief the name of the engine + + \sa description() +*/ +QString OpenSearchEngine::name() const +{ + return m_name; +} + +void OpenSearchEngine::setName(const QString &name) +{ + m_name = name; +} + +/*! + \property OpenSearchEngine::description + \brief the description of the engine + + \sa name() +*/ +QString OpenSearchEngine::description() const +{ + return m_description; +} + +void OpenSearchEngine::setDescription(const QString &description) +{ + m_description = description; +} + +/*! + \property OpenSearchEngine::searchUrlTemplate + \brief the template of the search URL + + \sa searchUrl(), searchParameters(), suggestionsUrlTemplate() +*/ +QString OpenSearchEngine::searchUrlTemplate() const +{ + return m_searchUrlTemplate; +} + +void OpenSearchEngine::setSearchUrlTemplate(const QString &searchUrlTemplate) +{ + m_searchUrlTemplate = searchUrlTemplate; +} + +/*! + Constructs and returns a search URL with a given \a searchTerm. + + The URL template is processed according to the specification: + http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax + + A list of template parameters currently supported and what they are replaced with: + \table + \header \o parameter + \o value + \row \o "{count}" + \o "20" + \row \o "{startIndex}" + \o "0" + \row \o "{startPage}" + \o "0" + \row \o "{language}" + \o "the default language code (RFC 3066)" + \row \o "{inputEncoding}" + \o "UTF-8" + \row \o "{outputEncoding}" + \o "UTF-8" + \row \o "{*:source}" + \o "application name, QCoreApplication::applicationName()" + \row \o "{searchTerms}" + \o "the string supplied by the user" + \endtable + + \sa searchUrlTemplate(), searchParameters(), suggestionsUrl() +*/ +QUrl OpenSearchEngine::searchUrl(const QString &searchTerm) const +{ + if (m_searchUrlTemplate.isEmpty()) + return QUrl(); + + QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_searchUrlTemplate).toUtf8()); + + if (m_searchMethod != QLatin1String("post")) { + Parameters::const_iterator end = m_searchParameters.constEnd(); + Parameters::const_iterator i = m_searchParameters.constBegin(); + for (; i != end; ++i) + retVal.addQueryItem(i->first, parseTemplate(searchTerm, i->second)); + } + + return retVal; +} + +/*! + \property providesSuggestions + \brief indicates whether the engine supports contextual suggestions +*/ +bool OpenSearchEngine::providesSuggestions() const +{ + return !m_suggestionsUrlTemplate.isEmpty(); +} + +/*! + \property OpenSearchEngine::suggestionsUrlTemplate + \brief the template of the suggestions URL + + \sa suggestionsUrl(), suggestionsParameters(), searchUrlTemplate() +*/ +QString OpenSearchEngine::suggestionsUrlTemplate() const +{ + return m_suggestionsUrlTemplate; +} + +void OpenSearchEngine::setSuggestionsUrlTemplate(const QString &suggestionsUrlTemplate) +{ + m_suggestionsUrlTemplate = suggestionsUrlTemplate; +} + +/*! + Constructs a suggestions URL with a given \a searchTerm. + + The URL template is processed according to the specification: + http://www.opensearch.org/Specifications/OpenSearch/1.1#OpenSearch_URL_template_syntax + + See searchUrl() for more information about processing template parameters. + + \sa suggestionsUrlTemplate(), suggestionsParameters(), searchUrl() +*/ +QUrl OpenSearchEngine::suggestionsUrl(const QString &searchTerm) const +{ + if (m_suggestionsUrlTemplate.isEmpty()) + return QUrl(); + + QUrl retVal = QUrl::fromEncoded(parseTemplate(searchTerm, m_suggestionsUrlTemplate).toUtf8()); + + if (m_suggestionsMethod != QLatin1String("post")) { + Parameters::const_iterator end = m_suggestionsParameters.constEnd(); + Parameters::const_iterator i = m_suggestionsParameters.constBegin(); + for (; i != end; ++i) + retVal.addQueryItem(i->first, parseTemplate(searchTerm, i->second)); + } + + return retVal; +} + +/*! + \property searchParameters + \brief additional parameters that will be included in the search URL + + For more information see: + http://www.opensearch.org/Specifications/OpenSearch/Extensions/Parameter/1.0 +*/ +OpenSearchEngine::Parameters OpenSearchEngine::searchParameters() const +{ + return m_searchParameters; +} + +void OpenSearchEngine::setSearchParameters(const Parameters &searchParameters) +{ + m_searchParameters = searchParameters; +} + +/*! + \property suggestionsParameters + \brief additional parameters that will be included in the suggestions URL + + For more information see: + http://www.opensearch.org/Specifications/OpenSearch/Extensions/Parameter/1.0 +*/ +OpenSearchEngine::Parameters OpenSearchEngine::suggestionsParameters() const +{ + return m_suggestionsParameters; +} + +void OpenSearchEngine::setSuggestionsParameters(const Parameters &suggestionsParameters) +{ + m_suggestionsParameters = suggestionsParameters; +} + +/*! + \property searchMethod + \brief HTTP request method that will be used to perform search requests +*/ +QString OpenSearchEngine::searchMethod() const +{ + return m_searchMethod; +} + +void OpenSearchEngine::setSearchMethod(const QString &method) +{ + QString requestMethod = method.toLower(); + if (!m_requestMethods.contains(requestMethod)) + return; + + m_searchMethod = requestMethod; +} + +/*! + \property suggestionsMethod + \brief HTTP request method that will be used to perform suggestions requests +*/ +QString OpenSearchEngine::suggestionsMethod() const +{ + return m_suggestionsMethod; +} + +void OpenSearchEngine::setSuggestionsMethod(const QString &method) +{ + QString requestMethod = method.toLower(); + if (!m_requestMethods.contains(requestMethod)) + return; + + m_suggestionsMethod = requestMethod; +} + +/*! + \property imageUrl + \brief the image URL of the engine + + When setting a new image URL, it won't be loaded immediately. The first request will be + deferred until image() is called for the first time. + + \note To be able to request external images, you need to provide a network access manager, + which will be used for network operations. + + \sa image(), networkAccessManager() +*/ +QString OpenSearchEngine::imageUrl() const +{ + return m_imageUrl; +} + +void OpenSearchEngine::setImageUrl(const QString &imageUrl) +{ + m_imageUrl = imageUrl; +} + +void OpenSearchEngine::loadImage() const +{ + if (!m_networkAccessManager || m_imageUrl.isEmpty()) + return; + + QNetworkReply *reply = m_networkAccessManager->get(QNetworkRequest(QUrl::fromEncoded(m_imageUrl.toUtf8()))); + connect(reply, SIGNAL(finished()), this, SLOT(imageObtained())); +} + +void OpenSearchEngine::imageObtained() +{ + QNetworkReply *reply = qobject_cast(sender()); + + if (!reply) + return; + + QByteArray response = reply->readAll(); + + reply->close(); + reply->deleteLater(); + + if (response.isEmpty()) + return; + + m_image.loadFromData(response); + emit imageChanged(); +} + +/*! + \property image + \brief the image of the engine + + When no image URL has been set and an image will be set explicitly, a new data URL + will be constructed, holding the image data encoded with Base64. + + \sa imageUrl() +*/ +QImage OpenSearchEngine::image() const +{ + if (m_image.isNull()) + loadImage(); + return m_image; +} + +void OpenSearchEngine::setImage(const QImage &image) +{ + if (m_imageUrl.isEmpty()) { + QBuffer imageBuffer; + imageBuffer.open(QBuffer::ReadWrite); + if (image.save(&imageBuffer, "PNG")) { + m_imageUrl = QString(QLatin1String("data:image/png;base64,%1")) + .arg(QLatin1String(imageBuffer.buffer().toBase64())); + } + } + + m_image = image; + emit imageChanged(); +} + +/*! + \property valid + \brief indicates whether the engine is valid i.e. the description was properly formed and included all necessary information +*/ +bool OpenSearchEngine::isValid() const +{ + return (!m_name.isEmpty() && !m_searchUrlTemplate.isEmpty()); +} + +bool OpenSearchEngine::operator==(const OpenSearchEngine &other) const +{ + return (m_name == other.m_name + && m_description == other.m_description + && m_imageUrl == other.m_imageUrl + && m_searchUrlTemplate == other.m_searchUrlTemplate + && m_suggestionsUrlTemplate == other.m_suggestionsUrlTemplate + && m_searchParameters == other.m_searchParameters + && m_suggestionsParameters == other.m_suggestionsParameters); +} + +bool OpenSearchEngine::operator<(const OpenSearchEngine &other) const +{ + return (m_name < other.m_name); +} + +/*! + Requests contextual suggestions on the search engine, for a given \a searchTerm. + + If succeeded, suggestions() signal will be emitted once the suggestions are received. + + \note To be able to request suggestions, you need to provide a network access manager, + which will be used for network operations. + + \sa requestSearchResults() +*/ +void OpenSearchEngine::requestSuggestions(const QString &searchTerm) +{ + if (searchTerm.isEmpty() || !providesSuggestions()) + return; + + Q_ASSERT(m_networkAccessManager); + + if (!m_networkAccessManager) + return; + + if (m_suggestionsReply) { + m_suggestionsReply->disconnect(this); + m_suggestionsReply->abort(); + m_suggestionsReply->deleteLater(); + m_suggestionsReply = 0; + } + + Q_ASSERT(m_requestMethods.contains(m_suggestionsMethod)); + if (m_suggestionsMethod == QLatin1String("get")) { + m_suggestionsReply = m_networkAccessManager->get(QNetworkRequest(suggestionsUrl(searchTerm))); + } else { + QStringList parameters; + Parameters::const_iterator end = m_suggestionsParameters.constEnd(); + Parameters::const_iterator i = m_suggestionsParameters.constBegin(); + for (; i != end; ++i) + parameters.append(i->first + QLatin1String("=") + i->second); + + QByteArray data = parameters.join(QLatin1String("&")).toUtf8(); + m_suggestionsReply = m_networkAccessManager->post(QNetworkRequest(suggestionsUrl(searchTerm)), data); + } + + connect(m_suggestionsReply, SIGNAL(finished()), this, SLOT(suggestionsObtained())); +} + +/*! + Requests search results on the search engine, for a given \a searchTerm. + + The default implementation does nothing, to supply your own you need to create your own + OpenSearchEngineDelegate subclass and supply it to the engine. Then the function will call + the performSearchRequest() method of the delegate, which can then handle the request + in a custom way. + + \sa requestSuggestions(), delegate() +*/ +void OpenSearchEngine::requestSearchResults(const QString &searchTerm) +{ + if (!m_delegate || searchTerm.isEmpty()) + return; + + Q_ASSERT(m_requestMethods.contains(m_searchMethod)); + + QNetworkRequest request(QUrl(searchUrl(searchTerm))); + QByteArray data; + QNetworkAccessManager::Operation operation = m_requestMethods.value(m_searchMethod); + + if (operation == QNetworkAccessManager::PostOperation) { + QStringList parameters; + Parameters::const_iterator end = m_searchParameters.constEnd(); + Parameters::const_iterator i = m_searchParameters.constBegin(); + for (; i != end; ++i) + parameters.append(i->first + QLatin1String("=") + i->second); + + data = parameters.join(QLatin1String("&")).toUtf8(); + } + + m_delegate->performSearchRequest(request, operation, data); +} + +void OpenSearchEngine::suggestionsObtained() +{ + QString response(QString::fromUtf8(m_suggestionsReply->readAll())); + response = response.trimmed(); + + m_suggestionsReply->close(); + m_suggestionsReply->deleteLater(); + m_suggestionsReply = 0; + + if (response.isEmpty()) + return; + + if (!response.startsWith(QLatin1Char('[')) || !response.endsWith(QLatin1Char(']'))) + return; + + if (!m_scriptEngine) + m_scriptEngine = new QScriptEngine(); + + // Evaluate the JSON response using QtScript. + if (!m_scriptEngine->canEvaluate(response)) + return; + + QScriptValue responseParts = m_scriptEngine->evaluate(response); + + if (!responseParts.property(1).isArray()) + return; + + QStringList suggestionsList; + qScriptValueToSequence(responseParts.property(1), suggestionsList); + + emit suggestions(suggestionsList); +} + +/*! + \property networkAccessManager + \brief the network access manager that is used to perform network requests + + It is required for network operations: loading external images and requesting + contextual suggestions. +*/ +QNetworkAccessManager *OpenSearchEngine::networkAccessManager() const +{ + return m_networkAccessManager; +} + +void OpenSearchEngine::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager) +{ + m_networkAccessManager = networkAccessManager; +} + +/*! + \property delegate + \brief the delegate that is used to perform specific tasks. + + It can be currently supplied to provide a custom behaviour ofthe requetSearchResults() method. + The default implementation does nothing. +*/ +OpenSearchEngineDelegate *OpenSearchEngine::delegate() const +{ + return m_delegate; +} + +void OpenSearchEngine::setDelegate(OpenSearchEngineDelegate *delegate) +{ + m_delegate = delegate; +} + +/*! + \fn void OpenSearchEngine::imageChanged() + + This signal is emitted whenever the image of the engine changes. + + \sa image(), imageUrl() +*/ + +/*! + \fn void OpenSearchEngine::suggestions(const QStringList &suggestions) + + This signal is emitted whenever new contextual suggestions have been provided + by the search engine. To request suggestions, use requestSuggestions(). + The suggestion set is specified by \a suggestions. + + \sa requestSuggestions() +*/ diff --git a/src/opensearch/opensearchengine.h b/src/opensearch/opensearchengine.h new file mode 100644 index 00000000..3ec63d22 --- /dev/null +++ b/src/opensearch/opensearchengine.h @@ -0,0 +1,144 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHENGINE_H +#define OPENSEARCHENGINE_H + +#include +#include +#include +#include +#include +#include + +class QNetworkReply; +class QScriptEngine; + +class OpenSearchEngineDelegate; +class OpenSearchEngine : public QObject +{ + Q_OBJECT + +signals: + void imageChanged(); + void suggestions(const QStringList &suggestions); + +public: + typedef QPair Parameter; + typedef QList Parameters; + + Q_PROPERTY(QString name READ name WRITE setName) + Q_PROPERTY(QString description READ description WRITE setDescription) + Q_PROPERTY(QString searchUrlTemplate READ searchUrlTemplate WRITE setSearchUrlTemplate) + Q_PROPERTY(Parameters searchParameters READ searchParameters WRITE setSearchParameters) + Q_PROPERTY(QString searchMethod READ searchMethod WRITE setSearchMethod) + Q_PROPERTY(QString suggestionsUrlTemplate READ suggestionsUrlTemplate WRITE setSuggestionsUrlTemplate) + Q_PROPERTY(Parameters suggestionsParameters READ suggestionsParameters WRITE setSuggestionsParameters) + Q_PROPERTY(QString suggestionsMethod READ suggestionsMethod WRITE setSuggestionsMethod) + Q_PROPERTY(bool providesSuggestions READ providesSuggestions) + Q_PROPERTY(QString imageUrl READ imageUrl WRITE setImageUrl) + Q_PROPERTY(bool valid READ isValid) + Q_PROPERTY(QNetworkAccessManager *networkAccessManager READ networkAccessManager WRITE setNetworkAccessManager) + + OpenSearchEngine(QObject *parent = 0); + ~OpenSearchEngine(); + + QString name() const; + void setName(const QString &name); + + QString description() const; + void setDescription(const QString &description); + + QString searchUrlTemplate() const; + void setSearchUrlTemplate(const QString &searchUrl); + QUrl searchUrl(const QString &searchTerm) const; + + bool providesSuggestions() const; + + QString suggestionsUrlTemplate() const; + void setSuggestionsUrlTemplate(const QString &suggestionsUrl); + QUrl suggestionsUrl(const QString &searchTerm) const; + + Parameters searchParameters() const; + void setSearchParameters(const Parameters &searchParameters); + + Parameters suggestionsParameters() const; + void setSuggestionsParameters(const Parameters &suggestionsParameters); + + QString searchMethod() const; + void setSearchMethod(const QString &method); + + QString suggestionsMethod() const; + void setSuggestionsMethod(const QString &method); + + QString imageUrl() const; + void setImageUrl(const QString &url); + + QImage image() const; + void setImage(const QImage &image); + + bool isValid() const; + + QNetworkAccessManager *networkAccessManager() const; + void setNetworkAccessManager(QNetworkAccessManager *networkAccessManager); + + OpenSearchEngineDelegate *delegate() const; + void setDelegate(OpenSearchEngineDelegate *delegate); + + bool operator==(const OpenSearchEngine &other) const; + bool operator<(const OpenSearchEngine &other) const; + +public slots: + void requestSuggestions(const QString &searchTerm); + void requestSearchResults(const QString &searchTerm); + +protected: + static QString parseTemplate(const QString &searchTerm, const QString &searchTemplate); + void loadImage() const; + +private slots: + void imageObtained(); + void suggestionsObtained(); + +private: + QString m_name; + QString m_description; + + QString m_imageUrl; + QImage m_image; + + QString m_searchUrlTemplate; + QString m_suggestionsUrlTemplate; + Parameters m_searchParameters; + Parameters m_suggestionsParameters; + QString m_searchMethod; + QString m_suggestionsMethod; + + QMap m_requestMethods; + + QNetworkAccessManager *m_networkAccessManager; + QNetworkReply *m_suggestionsReply; + + QScriptEngine *m_scriptEngine; + + OpenSearchEngineDelegate *m_delegate; +}; + +#endif // OPENSEARCHENGINE_H + diff --git a/src/opensearch/opensearchengineaction.cpp b/src/opensearch/opensearchengineaction.cpp new file mode 100644 index 00000000..66740229 --- /dev/null +++ b/src/opensearch/opensearchengineaction.cpp @@ -0,0 +1,46 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchengineaction.h" + +#include "browserapplication.h" +#include "networkaccessmanager.h" +#include "opensearchengine.h" + +OpenSearchEngineAction::OpenSearchEngineAction(OpenSearchEngine *engine, QObject *parent) + : QAction(parent) + , m_engine(engine) +{ + if (!engine->networkAccessManager()) + engine->setNetworkAccessManager(BrowserApplication::networkAccessManager()); + + setText(engine->name()); + imageChanged(); + connect(engine, SIGNAL(imageChanged()), this, SLOT(imageChanged())); +} + +void OpenSearchEngineAction::imageChanged() +{ + QImage image = m_engine->image(); + if (image.isNull()) + setIcon(BrowserApplication::icon(m_engine->imageUrl())); + else + setIcon(QIcon(QPixmap::fromImage(image))); +} + diff --git a/src/opensearch/opensearchengineaction.h b/src/opensearch/opensearchengineaction.h new file mode 100644 index 00000000..aeb93b2c --- /dev/null +++ b/src/opensearch/opensearchengineaction.h @@ -0,0 +1,41 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHENGINEACTION_H +#define OPENSEARCHENGINEACTION_H + +#include + +class OpenSearchEngine; +class OpenSearchEngineAction : public QAction +{ + Q_OBJECT + +public: + OpenSearchEngineAction(OpenSearchEngine *engine, QObject *parent = 0); + +private slots: + void imageChanged(); + +private: + OpenSearchEngine *m_engine; +}; + +#endif // OPENSEARCHENGINEACTION_H + diff --git a/src/opensearch/opensearchenginedelegate.cpp b/src/opensearch/opensearchenginedelegate.cpp new file mode 100644 index 00000000..d31569a5 --- /dev/null +++ b/src/opensearch/opensearchenginedelegate.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchenginedelegate.h" + +/*! + \class OpenSearchEngineDelegate + \brief An abstract class providing custom processing of specific activities. + + OpenSearchEngineDelegate is an abstract class that can be subclassed and set on + an OpenSearchEngine. It allows to customize some parts of the default implementation + or even extend it with missing bits. + + Currently subclasses can only provide a custom way of handling search requests by + reimplementing the performSearchRequest() method. + + \sa OpenSearchEngine +*/ + +/*! + Constructs the delegate. +*/ +OpenSearchEngineDelegate::OpenSearchEngineDelegate() +{ +} + +/*! + Destructs the delegate. +*/ +OpenSearchEngineDelegate::~OpenSearchEngineDelegate() +{ +} + +/*! + \fn void performSearchRequest(const QNetworkRequest &request, + QNetworkAccessManager::Operation operation, const QByteArray &data) = 0 + + This method will be used after OpenSearchEngine::requestResults() is called. + + For example, a console application that uses the OpenSearchEngine class to generate + a search URL for a search term supplied by the user would reimplement the function + and forward the request to e.g. a web browser. + + Likewise, a web browser that uses the OpenSearchEngine class to support multiple search + engines e.g. in a toolbar would perform the request and navigate to the search results site. +*/ diff --git a/src/opensearch/opensearchenginedelegate.h b/src/opensearch/opensearchenginedelegate.h new file mode 100644 index 00000000..5de3c598 --- /dev/null +++ b/src/opensearch/opensearchenginedelegate.h @@ -0,0 +1,37 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHENGINEDELEGATE_H +#define OPENSEARCHENGINEDELEGATE_H + +#include +#include + +class OpenSearchEngineDelegate +{ +public: + OpenSearchEngineDelegate(); + virtual ~OpenSearchEngineDelegate(); + + virtual void performSearchRequest(const QNetworkRequest &request, + QNetworkAccessManager::Operation operation, + const QByteArray &data) = 0; +}; + +#endif // OPENSEARCHENGINEDELEGATE_H diff --git a/src/opensearch/opensearchenginemodel.cpp b/src/opensearch/opensearchenginemodel.cpp new file mode 100644 index 00000000..a35f1bba --- /dev/null +++ b/src/opensearch/opensearchenginemodel.cpp @@ -0,0 +1,177 @@ +/* + * Copyright 2009 Christian Franke + * Copyright 2009 Jakub Wieczorek + * Copyright 2009 Christopher Eby + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchenginemodel.h" + +#include "browserapplication.h" +#include "opensearchengine.h" +#include "opensearchmanager.h" + +#include +#include + +OpenSearchEngineModel::OpenSearchEngineModel(OpenSearchManager *manager, QObject *parent) + : QAbstractTableModel(parent) + , m_manager(manager) +{ + connect(manager, SIGNAL(changed()), + this, SLOT(enginesChanged())); +} + +bool OpenSearchEngineModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid()) + return false; + + if (count <= 0) + return false; + + if (rowCount() <= 1) + return false; + + int lastRow = row + count - 1; + + beginRemoveRows(parent, row, lastRow); + + QStringList nameList = m_manager->allEnginesNames(); + for (int i = row; i <= lastRow; ++i) + m_manager->removeEngine(nameList.at(i)); + + // removeEngine emits changed + //endRemoveRows(); + + return true; +} + +int OpenSearchEngineModel::rowCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : m_manager->enginesCount(); +} + +int OpenSearchEngineModel::columnCount(const QModelIndex &parent) const +{ + Q_UNUSED(parent); + return 2; +} + +Qt::ItemFlags OpenSearchEngineModel::flags(const QModelIndex &index) const +{ + switch (index.column()) { + case 1: + return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable; + default: + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; + } +} + +QVariant OpenSearchEngineModel::data(const QModelIndex &index, int role) const +{ + if (index.row() >= m_manager->enginesCount() || index.row() < 0) + return QVariant(); + + OpenSearchEngine *engine = m_manager->engine(m_manager->allEnginesNames().at(index.row())); + + if (!engine) + return QVariant(); + + switch (index.column()) { + case 0: + switch (role) { + case Qt::DisplayRole: + return engine->name(); + break; + case Qt::DecorationRole: { + QImage image = engine->image(); + if (image.isNull()) + return BrowserApplication::icon(engine->imageUrl()); + return image; + break; + } + case Qt::ToolTipRole: + QString description = tr("Description: %1").arg(engine->description()); + + if (engine->providesSuggestions()) { + description += QLatin1String("
    "); + description += tr("Provides contextual suggestions"); + } + + return description; + break; + } + break; + + case 1: + switch (role) { + case Qt::EditRole: + case Qt::DisplayRole: + return QStringList(m_manager->keywordsForEngine(engine)).join(QLatin1String(",")); + case Qt::ToolTipRole: + return tr("Comma-separated list of keywords that may be entered in the location bar" + "followed by search terms to search with this engine"); + } + break; + } + + return QVariant(); +} + +bool OpenSearchEngineModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (index.column() != 1) + return false; + + if (index.row() >= rowCount() || index.row() < 0) + return false; + + if (role != Qt::EditRole) + return false; + + QString engineName = m_manager->allEnginesNames().at(index.row()); + QStringList keywords = value.toString().split(QRegExp(QLatin1String("[ ,]+")), QString::SkipEmptyParts); + + m_manager->setKeywordsForEngine(m_manager->engine(engineName), keywords); + + return true; +} + +QVariant OpenSearchEngineModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Vertical) + return QVariant(); + + if (role != Qt::DisplayRole) + return QVariant(); + + switch (section) { + case 0: + return tr("Name"); + case 1: + return tr("Keywords"); + } + + return QVariant(); +} + +void OpenSearchEngineModel::enginesChanged() +{ + QAbstractTableModel::reset(); +} + diff --git a/src/opensearch/opensearchenginemodel.h b/src/opensearch/opensearchenginemodel.h new file mode 100644 index 00000000..23001cfd --- /dev/null +++ b/src/opensearch/opensearchenginemodel.h @@ -0,0 +1,52 @@ +/* + * Copyright 2009 Christian Franke + * Copyright 2009 Jakub Wieczorek + * Copyright 2009 Christopher Eby + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHENGINEMODEL_H +#define OPENSEARCHENGINEMODEL_H + +#include + +class OpenSearchEngine; +class OpenSearchManager; + +class OpenSearchEngineModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + OpenSearchEngineModel(OpenSearchManager *manager, QObject *parent = 0); + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + +protected slots: + void enginesChanged(); + +private: + OpenSearchManager *m_manager; +}; + +#endif //OPENSEARCHENGINEMODEL_H + diff --git a/src/opensearch/opensearchmanager.cpp b/src/opensearch/opensearchmanager.cpp new file mode 100644 index 00000000..d9bb0a28 --- /dev/null +++ b/src/opensearch/opensearchmanager.cpp @@ -0,0 +1,418 @@ +/* + * Copyright 2009 Jakub Wieczorek + * Copyright 2009 Christian Franke + * Copyright 2009 Christopher Eby + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchmanager.h" + +#include "autosaver.h" +#include "browserapplication.h" +#include "networkaccessmanager.h" +#include "opensearchengine.h" +#include "opensearchreader.h" +#include "opensearchwriter.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +OpenSearchManager::OpenSearchManager(QObject *parent) + : QObject(parent) + , m_autoSaver(new AutoSaver(this)) +{ + connect(this, SIGNAL(changed()), + m_autoSaver, SLOT(changeOccurred())); + + load(); +} + +OpenSearchManager::~OpenSearchManager() +{ + m_autoSaver->saveIfNeccessary(); + qDeleteAll(m_engines.values()); + m_engines.clear(); +} + +QString OpenSearchManager::currentEngineName() const +{ + return m_current; +} + +void OpenSearchManager::setCurrentEngineName(const QString &name) +{ + if (!m_engines.contains(name)) + return; + + m_current = name; + emit currentEngineChanged(); + emit changed(); +} + +OpenSearchEngine *OpenSearchManager::currentEngine() const +{ + if (m_current.isEmpty() || !m_engines.contains(m_current)) + return 0; + + return m_engines[m_current]; +} + +void OpenSearchManager::setCurrentEngine(OpenSearchEngine *engine) +{ + if (!engine) + return; + + setCurrentEngineName(m_engines.key(engine)); +} + +OpenSearchEngine *OpenSearchManager::engine(const QString &name) +{ + if (!m_engines.contains(name)) + return 0; + + return m_engines[name]; +} + +bool OpenSearchManager::engineExists(const QString &name) +{ + return m_engines.contains(name); +} + +QStringList OpenSearchManager::allEnginesNames() const +{ + return m_engines.keys(); +} + +int OpenSearchManager::enginesCount() const +{ + return m_engines.count(); +} + +void OpenSearchManager::addEngine(const QUrl &url) +{ + if (!url.isValid()) + return; + + QNetworkReply *reply = BrowserApplication::networkAccessManager()->get(QNetworkRequest(url)); + connect(reply, SIGNAL(finished()), this, SLOT(engineFromUrlAvailable())); + reply->setParent(this); +} + +bool OpenSearchManager::addEngine(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + return false; + + OpenSearchReader reader; + OpenSearchEngine *engine = reader.read(&file); + + if (!addEngine(engine)) { + delete engine; + return false; + } + + return true; +} + +bool OpenSearchManager::addEngine(OpenSearchEngine *engine) +{ + if (!engine) + return false; + + if (!engine->isValid()) + return false; + + if (m_engines.contains(engine->name())) + return false; + + m_engines[engine->name()] = engine; + + emit changed(); + + return true; +} + +void OpenSearchManager::removeEngine(const QString &name) +{ + if (m_engines.count() <= 1) + return; + + if (!m_engines.contains(name)) + return; + + OpenSearchEngine *engine = m_engines[name]; + foreach (const QString &keyword, m_keywords.keys(engine)) + m_keywords.remove(keyword); + engine->deleteLater(); + + m_engines[name] = 0; + m_engines.remove(name); + + QString file = QDir(enginesDirectory()).filePath(generateEngineFileName(name)); + QFile::remove(file); + + if (name == m_current) + setCurrentEngineName(m_engines.keys().at(0)); + + emit changed(); +} + +QString OpenSearchManager::generateEngineFileName(const QString &engineName) const +{ + QString fileName; + + // Strip special characters from the name. + for (int i = 0; i < engineName.count(); ++i) { + if (engineName.at(i).isSpace()) { + fileName.append(QLatin1Char('_')); + continue; + } + + if (engineName.at(i).isLetterOrNumber()) + fileName.append(engineName.at(i)); + } + + fileName.append(QLatin1String(".xml")); + + return fileName; +} + +void OpenSearchManager::saveDirectory(const QString &dirName) +{ + QDir dir; + if (!dir.mkpath(dirName)) + return; + dir.setPath(dirName); + + OpenSearchWriter writer; + + foreach (OpenSearchEngine *engine, m_engines.values()) { + QString name = generateEngineFileName(engine->name()); + QString fileName = dir.filePath(name); + + QFile file(fileName); + if (!file.open(QIODevice::WriteOnly)) + continue; + + writer.write(&file, engine); + } +} + +void OpenSearchManager::save() +{ + saveDirectory(enginesDirectory()); + + QSettings settings; + settings.beginGroup(QLatin1String("openSearch")); + settings.setValue(QLatin1String("engine"), m_current); + + settings.beginWriteArray(QLatin1String("keywords"), m_keywords.count()); + QHash::const_iterator i = m_keywords.constBegin(); + QHash::const_iterator end = m_keywords.constEnd(); + int j = 0; + for (; i != end; ++i) { + settings.setArrayIndex(j++); + settings.setValue(QLatin1String("keyword"), i.key()); + settings.setValue(QLatin1String("engine"), i.value()->name()); + } + settings.endArray(); + + settings.endGroup(); +} + +bool OpenSearchManager::loadDirectory(const QString &dirName) +{ + if (!QFile::exists(dirName)) + return false; + + QDirIterator iterator(dirName, QStringList() << QLatin1String("*.xml")); + + if (!iterator.hasNext()) + return false; + + bool success = false; + + while (iterator.hasNext()) { + if (addEngine(iterator.next())) + success = true; + } + + return success; +} + +void OpenSearchManager::load() +{ + if (!loadDirectory(enginesDirectory())) + loadDirectory(QLatin1String(":/searchengines")); + + // get current engine + QSettings settings; + settings.beginGroup(QLatin1String("openSearch")); + m_current = settings.value(QLatin1String("engine"), QLatin1String("Google")).toString(); + + int size = settings.beginReadArray(QLatin1String("keywords")); + for (int i = 0; i < size; ++i) { + settings.setArrayIndex(i); + QString keyword = settings.value(QLatin1String("keyword")).toString(); + QString engineName = settings.value(QLatin1String("engine")).toString(); + m_keywords.insert(keyword, engine(engineName)); + } + settings.endArray(); + + settings.endGroup(); + + if (!m_engines.contains(m_current) && m_engines.count() > 0) + m_current = m_engines.keys().at(0); + + emit currentEngineChanged(); +} + +void OpenSearchManager::restoreDefaults() +{ + loadDirectory(QLatin1String(":/searchengines")); +} + +QString OpenSearchManager::enginesDirectory() const +{ + QDir directory(QDesktopServices::storageLocation(QDesktopServices::DataLocation)); + return directory.filePath(QLatin1String("searchengines")); +} + +bool OpenSearchManager::confirmAddition(OpenSearchEngine *engine) +{ + if (!engine || !engine->isValid()) + return false; + + QString host = QUrl(engine->searchUrlTemplate()).host(); + + QMessageBox::StandardButton button = QMessageBox::question(0, QString(), + tr("Do you want to add the following engine to your list of search engines?

    " + "Name: %1
    Searches on: %2").arg(engine->name(), host), + QMessageBox::Yes | QMessageBox::No, QMessageBox::No); + return (button == QMessageBox::Yes); +} + +void OpenSearchManager::engineFromUrlAvailable() +{ + QNetworkReply *reply = qobject_cast(sender()); + + if (!reply) + return; + + if (reply->error() != QNetworkReply::NoError) { + reply->close(); + reply->deleteLater(); + return; + } + + OpenSearchReader reader; + OpenSearchEngine *engine = reader.read(reply); + + reply->close(); + reply->deleteLater(); + + if (!engine->isValid()) { + delete engine; + return; + } + + if (engineExists(engine->name())) { + delete engine; + return; + } + + if (!confirmAddition(engine)) { + delete engine; + return; + } + + if (!addEngine(engine)) { + delete engine; + return; + } +} + +QUrl OpenSearchManager::convertKeywordSearchToUrl(const QString &string) +{ + int i = string.indexOf(QLatin1Char(' ')); + if (i <= 0) + return QUrl(); + + const QString keyword = string.left(i); + const QString terms = string.mid(i + 1); + if (terms.isEmpty()) + return QUrl(); + + if (OpenSearchEngine *engine = engineForKeyword(keyword)) + return engine->searchUrl(terms); + + return QUrl(); +} + +OpenSearchEngine *OpenSearchManager::engineForKeyword(const QString &keyword) const +{ + if (keyword.isEmpty()) + return 0; + if (!m_keywords.contains(keyword)) + return 0; + return m_keywords.value(keyword); +} + +void OpenSearchManager::setEngineForKeyword(const QString &keyword, OpenSearchEngine *engine) +{ + if (keyword.isEmpty()) + return; + + if (!engine) + m_keywords.remove(keyword); + else + m_keywords.insert(keyword, engine); + + emit changed(); +} + +QStringList OpenSearchManager::keywordsForEngine(OpenSearchEngine *engine) const +{ + return m_keywords.keys(engine); +} + +void OpenSearchManager::setKeywordsForEngine(OpenSearchEngine *engine, const QStringList &keywords) +{ + if (!engine) + return; + + foreach (const QString &keyword, keywordsForEngine(engine)) + m_keywords.remove(keyword); + + foreach (const QString &keyword, keywords) { + if (keyword.isEmpty()) + continue; + + m_keywords.insert(keyword, engine); + } + + emit changed(); +} diff --git a/src/opensearch/opensearchmanager.h b/src/opensearch/opensearchmanager.h new file mode 100644 index 00000000..1d3f33c9 --- /dev/null +++ b/src/opensearch/opensearchmanager.h @@ -0,0 +1,101 @@ +/* + * Copyright 2009 Jakub Wieczorek + * Copyright 2009 Christian Franke + * Copyright 2009 Christopher Eby + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHMANAGER_H +#define OPENSEARCHMANAGER_H + +#include + +#include +#include +#include + +class QNetworkReply; +class QNetworkRequest; + +class AutoSaver; +class OpenSearchEngine; +class OpenSearchEngineModel; + +class OpenSearchManager : public QObject +{ + Q_OBJECT + +signals: + void changed(); + void currentEngineChanged(); + +public: + OpenSearchManager(QObject *parent = 0); + ~OpenSearchManager(); + + QStringList allEnginesNames() const; + int enginesCount() const; + + QString currentEngineName() const; + void setCurrentEngineName(const QString ¤tName); + + OpenSearchEngine *currentEngine() const; + void setCurrentEngine(OpenSearchEngine *current); + + OpenSearchEngine *engine(const QString &name); + + bool engineExists(const QString &name); + + QUrl convertKeywordSearchToUrl(const QString &string); + OpenSearchEngine *engineForKeyword(const QString &keyword) const; + void setEngineForKeyword(const QString &keyword, OpenSearchEngine *engine); + + QStringList keywordsForEngine(OpenSearchEngine *engine) const; + void setKeywordsForEngine(OpenSearchEngine *engine, const QStringList &keywords); + + void addEngine(const QUrl &url); + bool addEngine(const QString &fileName); + bool addEngine(OpenSearchEngine *engine); + void removeEngine(const QString &name); + void restoreDefaults(); + +public slots: + void save(); + +protected: + void load(); + bool loadDirectory(const QString &dirName); + void saveDirectory(const QString &dirName); + QString enginesDirectory() const; + QString generateEngineFileName(const QString &engineName) const; + +private: + bool confirmAddition(OpenSearchEngine *engine); + +protected slots: + void engineFromUrlAvailable(); + +private: + AutoSaver *m_autoSaver; + + QHash m_engines; + QHash m_keywords; + QString m_current; +}; + +#endif //OPENSEARCHMANAGER_H + diff --git a/src/opensearch/opensearchreader.cpp b/src/opensearch/opensearchreader.cpp new file mode 100644 index 00000000..7b88578a --- /dev/null +++ b/src/opensearch/opensearchreader.cpp @@ -0,0 +1,166 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchreader.h" + +#include "opensearchengine.h" + +#include + +/*! + \class OpenSearchReader + \brief A class reading a search engine description from an external source + + OpenSearchReader is a class that can be used to read search engine descriptions + formed using the OpenSearch format. + + It inherits QXmlStreamReader and thus provides additional functions, such as + QXmlStreamReader::error(), QXmlStreamReader::hasError() that can be used to make sure + the reading procedure succeeded. + + For more information see: + http://www.opensearch.org/Specifications/OpenSearch/1.1/Draft_4#OpenSearch_description_document + + \sa OpenSearchEngine, OpenSearchWriter +*/ + +/*! + Constructs a new reader. + + \note One instance can be used to read multiple files, one by one. +*/ +OpenSearchReader::OpenSearchReader() + : QXmlStreamReader() +{ +} + +/*! + Reads an OpenSearch engine from the \a device and returns an OpenSearchEngine object, + filled in with all the data that has been retrieved from the document. + + If the \a device is closed, it will be opened. + + To make sure if the procedure succeeded, check QXmlStreamReader::error(). + + \return a new constructed OpenSearchEngine object + + \note The function returns an object of the OpenSearchEngine class even if the document + is bad formed or doesn't conform to the specification. It needs to be manually + deleted afterwards, if intended. + \note The lifetime of the returned OpenSearchEngine object is up to the user. + The object should be deleted once it is not used anymore to avoid memory leaks. +*/ +OpenSearchEngine *OpenSearchReader::read(QIODevice *device) +{ + clear(); + + if (!device->isOpen()) + device->open(QIODevice::ReadOnly); + + setDevice(device); + return read(); +} + +OpenSearchEngine *OpenSearchReader::read() +{ + OpenSearchEngine *engine = new OpenSearchEngine(); + + while (!isStartElement() && !atEnd()) + readNext(); + + if (name() != QLatin1String("OpenSearchDescription") + || namespaceUri() != QLatin1String("http://a9.com/-/spec/opensearch/1.1/")) { + raiseError(QObject::tr("The file is not an OpenSearch 1.1 file.")); + return engine; + } + + while (!atEnd()) { + readNext(); + + if (!isStartElement()) + continue; + + if (name() == QLatin1String("ShortName")) { + engine->setName(readElementText()); + } else if (name() == QLatin1String("Description")) { + engine->setDescription(readElementText()); + } else if (name() == QLatin1String("Url")) { + + QString type = attributes().value(QLatin1String("type")).toString(); + QString url = attributes().value(QLatin1String("template")).toString(); + QString method = attributes().value(QLatin1String("method")).toString(); + + if (type == QLatin1String("application/x-suggestions+json") + && !engine->suggestionsUrlTemplate().isEmpty()) + continue; + + if ((type.isEmpty() + || type == QLatin1String("text/html") + || type == QLatin1String("application/xhtml+xml")) + && !engine->searchUrlTemplate().isEmpty()) + continue; + + if (url.isEmpty()) + continue; + + QList parameters; + + readNext(); + + while (!(isEndElement() && name() == QLatin1String("Url"))) { + if (!isStartElement() || (name() != QLatin1String("Param") && name() != QLatin1String("Parameter"))) { + readNext(); + continue; + } + + QString key = attributes().value(QLatin1String("name")).toString(); + QString value = attributes().value(QLatin1String("value")).toString(); + + if (!key.isEmpty() && !value.isEmpty()) + parameters.append(OpenSearchEngine::Parameter(key, value)); + + while (!isEndElement()) + readNext(); + } + + if (type == QLatin1String("application/x-suggestions+json")) { + engine->setSuggestionsUrlTemplate(url); + engine->setSuggestionsParameters(parameters); + engine->setSuggestionsMethod(method); + } else if (type.isEmpty() || type == QLatin1String("text/html") || type == QLatin1String("application/xhtml+xml")) { + engine->setSearchUrlTemplate(url); + engine->setSearchParameters(parameters); + engine->setSearchMethod(method); + } + + } else if (name() == QLatin1String("Image")) { + engine->setImageUrl(readElementText()); + } + + if (!engine->name().isEmpty() + && !engine->description().isEmpty() + && !engine->suggestionsUrlTemplate().isEmpty() + && !engine->searchUrlTemplate().isEmpty() + && !engine->imageUrl().isEmpty()) + break; + } + + return engine; +} + diff --git a/src/opensearch/opensearchreader.h b/src/opensearch/opensearchreader.h new file mode 100644 index 00000000..a4f11bc9 --- /dev/null +++ b/src/opensearch/opensearchreader.h @@ -0,0 +1,40 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHREADER_H +#define OPENSEARCHREADER_H + +#include + +class OpenSearchEngine; + +class OpenSearchReader : public QXmlStreamReader +{ +public: + OpenSearchReader(); + + OpenSearchEngine *read(QIODevice *device); + +private: + OpenSearchEngine *read(); + +}; + +#endif // OPENSEARCHREADER_H + diff --git a/src/opensearch/opensearchwriter.cpp b/src/opensearch/opensearchwriter.cpp new file mode 100644 index 00000000..10b7c548 --- /dev/null +++ b/src/opensearch/opensearchwriter.cpp @@ -0,0 +1,136 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "opensearchwriter.h" + +#include "opensearchengine.h" + +#include +#include + +/*! + \class OpenSearchWriter + \brief A class writing a search engine description to an external source + + OpenSearchReader is a class that can be used to write search engine descriptions + using the OpenSearch format. + + For more information see: + http://www.opensearch.org/Specifications/OpenSearch/1.1/Draft_4#OpenSearch_description_document + + \sa OpenSearchEngine, OpenSearchReader +*/ + +/*! + Constructs a new writer. + + \note One instance can be used to write multiple search engine descriptions, one by one. +*/ +OpenSearchWriter::OpenSearchWriter() + : QXmlStreamWriter() +{ + setAutoFormatting(true); +} + +/*! + Writes an OpenSearch engine description to the \a device, filling the output document + with all the necessary data. + + If the \a device is closed, it will be opened. + + \return true on success and false on failure. +*/ +bool OpenSearchWriter::write(QIODevice *device, OpenSearchEngine *engine) +{ + if (!engine) + return false; + + if (!device->isOpen()) { + if (!device->open(QIODevice::WriteOnly)) + return false; + } + + setDevice(device); + write(engine); + return true; +} + +void OpenSearchWriter::write(OpenSearchEngine *engine) +{ + writeStartDocument(); + writeStartElement(QLatin1String("OpenSearchDescription")); + writeDefaultNamespace(QLatin1String("http://a9.com/-/spec/opensearch/1.1/")); + + if (!engine->name().isEmpty()) + writeTextElement(QLatin1String("ShortName"), engine->name()); + + if (!engine->description().isEmpty()) + writeTextElement(QLatin1String("Description"), engine->description()); + + if (!engine->searchUrlTemplate().isEmpty()) { + writeStartElement(QLatin1String("Url")); + writeAttribute(QLatin1String("method"), engine->searchMethod()); + writeAttribute(QLatin1String("type"), QLatin1String("text/html")); + writeAttribute(QLatin1String("template"), engine->searchUrlTemplate()); + + if (!engine->searchParameters().empty()) { + writeNamespace(QLatin1String("http://a9.com/-/spec/opensearch/extensions/parameters/1.0/"), QLatin1String("p")); + + QList::const_iterator end = engine->searchParameters().constEnd(); + QList::const_iterator i = engine->searchParameters().constBegin(); + for (; i != end; ++i) { + writeStartElement(QLatin1String("p:Parameter")); + writeAttribute(QLatin1String("name"), i->first); + writeAttribute(QLatin1String("value"), i->second); + writeEndElement(); + } + } + + writeEndElement(); + } + + if (!engine->suggestionsUrlTemplate().isEmpty()) { + writeStartElement(QLatin1String("Url")); + writeAttribute(QLatin1String("method"), engine->suggestionsMethod()); + writeAttribute(QLatin1String("type"), QLatin1String("application/x-suggestions+json")); + writeAttribute(QLatin1String("template"), engine->suggestionsUrlTemplate()); + + if (!engine->suggestionsParameters().empty()) { + writeNamespace(QLatin1String("http://a9.com/-/spec/opensearch/extensions/parameters/1.0/"), QLatin1String("p")); + + QList::const_iterator end = engine->suggestionsParameters().constEnd(); + QList::const_iterator i = engine->suggestionsParameters().constBegin(); + for (; i != end; ++i) { + writeStartElement(QLatin1String("p:Parameter")); + writeAttribute(QLatin1String("name"), i->first); + writeAttribute(QLatin1String("value"), i->second); + writeEndElement(); + } + } + + writeEndElement(); + } + + if (!engine->imageUrl().isEmpty()) + writeTextElement(QLatin1String("Image"), engine->imageUrl()); + + writeEndElement(); + writeEndDocument(); +} + diff --git a/src/opensearch/opensearchwriter.h b/src/opensearch/opensearchwriter.h new file mode 100644 index 00000000..ab7fd615 --- /dev/null +++ b/src/opensearch/opensearchwriter.h @@ -0,0 +1,40 @@ +/* + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef OPENSEARCHWRITER_H +#define OPENSEARCHWRITER_H + +#include + +class OpenSearchEngine; + +class OpenSearchWriter : public QXmlStreamWriter +{ +public: + OpenSearchWriter(); + + bool write(QIODevice *device, OpenSearchEngine *engine); + +private: + void write(OpenSearchEngine *engine); + +}; + +#endif // OPENSEARCHWRITER_H + diff --git a/src/plaintexteditsearch.cpp b/src/plaintexteditsearch.cpp new file mode 100644 index 00000000..04c900d6 --- /dev/null +++ b/src/plaintexteditsearch.cpp @@ -0,0 +1,69 @@ +/* + * Copyright 2008 Christian Franke + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "plaintexteditsearch.h" + +#include +#include + +PlainTextEditSearch::PlainTextEditSearch(QPlainTextEdit *plainTextEdit, QWidget *parent) + : SearchBar(parent) + , m_edit(plainTextEdit) +{ + setSearchObject(plainTextEdit); +} + +void PlainTextEditSearch::findNext() +{ + find(0); +} + +void PlainTextEditSearch::findPrevious() +{ + find(QTextDocument::FindBackward); +} + +void PlainTextEditSearch::find(QTextDocument::FindFlags flags) +{ + QString searchString = ui.searchLineEdit->text(); + if (!m_edit || searchString.isEmpty()) + return; + if (searchString != m_lastSearchTerm) { + QTextCursor cursor = m_edit->textCursor(); + cursor.setPosition(cursor.selectionStart()); + cursor.clearSelection(); + m_edit->setTextCursor(cursor); + m_lastSearchTerm = searchString; + } + QString infoString; + if (!m_edit->find(searchString, flags)) { + /* no support for wrapping so we set the cursor to start */ + QTextCursor cursor = m_edit->textCursor(); + m_edit->moveCursor(QTextCursor::Start); + /* ...search again from the beginning */ + if (!m_edit->find(searchString,flags)) { + /* and if there's still nothing, we revert the cursor */ + infoString = tr("Not Found"); + cursor.clearSelection(); + m_edit->setTextCursor(cursor); + } + } + ui.searchInfo->setText(infoString); +} + diff --git a/src/plaintexteditsearch.h b/src/plaintexteditsearch.h new file mode 100644 index 00000000..95527517 --- /dev/null +++ b/src/plaintexteditsearch.h @@ -0,0 +1,46 @@ +/* + * Copyright 2008 ChriChristian Franke > + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef PLAINTEXTEDITSEARCH_H +#define PLAINTEXTEDITSEARCH_H + +#include "searchbar.h" + +#include + +class QPlainTextEdit; +class PlainTextEditSearch : public SearchBar +{ + Q_OBJECT + +public: + PlainTextEditSearch(QPlainTextEdit *plainTextEdit, QWidget *parent = 0); + +public slots: + void findNext(); + void findPrevious(); + +private: + void find(QTextDocument::FindFlags flags); + QPlainTextEdit *m_edit; + QString m_lastSearchTerm; +}; + +#endif // PLAINTEXTEDITSEARCH_H + diff --git a/src/qwebplugins/arorawebplugin.cpp b/src/qwebplugins/arorawebplugin.cpp new file mode 100644 index 00000000..2d15788c --- /dev/null +++ b/src/qwebplugins/arorawebplugin.cpp @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "arorawebplugin.h" + +AroraWebPlugin::AroraWebPlugin() +{ +} + +AroraWebPlugin::~AroraWebPlugin() +{ +} + +bool AroraWebPlugin::isAnonymous() const +{ + return false; +} diff --git a/src/qwebplugins/arorawebplugin.h b/src/qwebplugins/arorawebplugin.h new file mode 100644 index 00000000..64090951 --- /dev/null +++ b/src/qwebplugins/arorawebplugin.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ARORAWEBPLUGIN_H +#define ARORAWEBPLUGIN_H + +#include + +class AroraWebPlugin +{ + +public: + AroraWebPlugin(); + virtual ~AroraWebPlugin(); + + virtual QWebPluginFactory::Plugin metaPlugin() = 0; + virtual QWidget *create(const QString &mimeType, const QUrl &url, + const QStringList &argumentNames, const QStringList &argumentValues) = 0; + virtual void configure() = 0; + virtual bool isAnonymous() const; +}; + +#endif // ARORAWEBPLUGIN_H + diff --git a/src/qwebplugins/clicktoflash/clicktoflash.cpp b/src/qwebplugins/clicktoflash/clicktoflash.cpp new file mode 100644 index 00000000..697e4754 --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflash.cpp @@ -0,0 +1,162 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "clicktoflash.h" + +#include +#include +#include +#include + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +#include +#endif + +#include + +ClickToFlash::ClickToFlash(ClickToFlashPlugin *plugin, QWidget *parent) + : QWidget(parent) + , m_swapping(false) + , m_plugin(plugin) +{ + setContextMenuPolicy(Qt::CustomContextMenu); + connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), + this, SLOT(showContextMenu())); + setupUi(this); + connect(loadFlashButton, SIGNAL(clicked()), + this, SLOT(load())); + setToolTip(url.toString()); +} + +void ClickToFlash::showContextMenu() +{ + QMenu menu; + menu.addAction(tr("Load"), this, SLOT(load())); + menu.addAction(tr("Load All"), this, SLOT(loadAll())); + menu.addSeparator(); + QString host = url.host(); + QAction *add = menu.addAction(tr("Add %1 to Whitelist").arg(host), this, SLOT(addToWhitelist())); + QAction *remove = menu.addAction(tr("Remove from Whitelist"), this, SLOT(removeFromWhitelist())); + bool onWhitelist = m_plugin->onWhitelist(host); + add->setEnabled(!onWhitelist); + remove->setEnabled(onWhitelist); + menu.addSeparator(); + menu.addAction(tr("Settings"), this, SLOT(configure())); + menu.exec(QCursor::pos()); +} + +void ClickToFlash::addToWhitelist() +{ + m_plugin->addToWhitelist(url.host()); +} + +void ClickToFlash::removeFromWhitelist() +{ + m_plugin->removeFromWhitelist(url.host()); +} + +void ClickToFlash::configure() +{ + m_plugin->configure(); +} + +void ClickToFlash::loadAll() +{ + load(true); +} + +void ClickToFlash::load(bool loadAll) +{ + QWidget *parent = parentWidget(); + QWebView *view = 0; + while (parent) { + if (QWebView *aView = qobject_cast(parent)) { + view = aView; + break; + } + parent = parent->parentWidget(); + } + if (!view) + return; + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + const QString selector = QLatin1String("%1[type=\"application/x-shockwave-flash\"]"); + const QString mime = QLatin1String("application/futuresplash"); + + hide(); + m_swapping = true; + QList frames; + frames.append(view->page()->mainFrame()); + while (!frames.isEmpty()) { + QWebFrame *frame = frames.takeFirst(); + QWebElement docElement = frame->documentElement(); + + QWebElementCollection elements; + elements.append(docElement.findAll(selector.arg(QLatin1String("object")))); + elements.append(docElement.findAll(selector.arg(QLatin1String("embed")))); + + QWebElement element; + foreach (element, elements) { + if (!loadAll) { + if (!element.evaluateJavaScript(QLatin1String("this.swapping")).toBool()) + continue; + } + + QWebElement substitute = element.clone(); + substitute.setAttribute(QLatin1String("type"), mime); + element.replace(substitute); + } + + frames += frame->childFrames(); + } + m_swapping = false; +#else + QString fileName = QLatin1String(":clicktoflash/swap.js"); + QFile jsFile(fileName); + if (!jsFile.open(QFile::ReadOnly)) { + qWarning() << __FUNCTION__ << "Unable to load javascript" << fileName; + return; + } + + QString javaScript = QLatin1String(jsFile.readAll()); + QString processedJavaScript = QString(javaScript).arg(loadAll ? QString() : url.toString()); + + hide(); + m_swapping = true; + QList frames; + frames.append(view->page()->mainFrame()); + while (!frames.isEmpty()) { + QWebFrame *frame = frames.takeFirst(); + frame->evaluateJavaScript(processedJavaScript); + frames += frame->childFrames(); + } + m_swapping = false; +#endif +} + + diff --git a/src/qwebplugins/clicktoflash/clicktoflash.h b/src/qwebplugins/clicktoflash/clicktoflash.h new file mode 100644 index 00000000..ea2ae8a2 --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflash.h @@ -0,0 +1,63 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef CLICKTOFLASH_H +#define CLICKTOFLASH_H + +#include "clicktoflashplugin.h" +#include "ui_clicktoflash.h" + +#include + +class ClickToFlash : public QWidget, public Ui_ClickToFlash +{ + Q_OBJECT + Q_PROPERTY(bool swapping READ swapping) + +public: + ClickToFlash(ClickToFlashPlugin *plugin, QWidget *parent = 0); + QUrl url; + QStringList argumentNames; + QStringList argumentValues; + bool swapping() const { return m_swapping; } + +private slots: + void configure(); + void addToWhitelist(); + void removeFromWhitelist(); + void showContextMenu(); + void loadAll(); + void load(bool loadAll = false); + +private: + bool m_swapping; + ClickToFlashPlugin *m_plugin; +}; + +#endif // CLICKTOFLASH_H + diff --git a/src/qwebplugins/clicktoflash/clicktoflash.pri b/src/qwebplugins/clicktoflash/clicktoflash.pri new file mode 100644 index 00000000..2033e59b --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflash.pri @@ -0,0 +1,15 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + clicktoflash.h \ + clicktoflashplugin.h + +SOURCES += \ + clicktoflash.cpp \ + clicktoflashplugin.cpp + +FORMS += clicktoflash.ui clicktoflashsettings.ui + +RESOURCES += clicktoflash.qrc + diff --git a/src/qwebplugins/clicktoflash/clicktoflash.qrc b/src/qwebplugins/clicktoflash/clicktoflash.qrc new file mode 100644 index 00000000..2f1883b7 --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflash.qrc @@ -0,0 +1,6 @@ + + + swap.js + + + diff --git a/src/qwebplugins/clicktoflash/clicktoflash.ui b/src/qwebplugins/clicktoflash/clicktoflash.ui new file mode 100644 index 00000000..7d626acc --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflash.ui @@ -0,0 +1,77 @@ + + + ClickToFlash + + + + 0 + 0 + 172 + 114 + + + + + + + Qt::Vertical + + + + 20 + 16 + + + + + + + + Qt::Horizontal + + + + 8 + 20 + + + + + + + + Load Flash + + + + + + + Qt::Horizontal + + + + 9 + 20 + + + + + + + + Qt::Vertical + + + + 20 + 17 + + + + + + + + + diff --git a/src/qwebplugins/clicktoflash/clicktoflashplugin.cpp b/src/qwebplugins/clicktoflash/clicktoflashplugin.cpp new file mode 100644 index 00000000..6a1cf21e --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflashplugin.cpp @@ -0,0 +1,127 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "clicktoflashplugin.h" + +#include "clicktoflash.h" + +#include "ui_clicktoflashsettings.h" +#include +#include + +#include + +ClickToFlashPlugin::ClickToFlashPlugin() + : m_loaded(false) + , m_enabled(false) +{ +} + +void ClickToFlashPlugin::load() +{ + if (m_loaded) + return; + m_loaded = true; + QSettings settings; + settings.beginGroup(QLatin1String("webplugin/clicktoflash")); + m_whitelist = settings.value(QLatin1String("whitelist")).toStringList(); + settings.endGroup(); + settings.beginGroup(QLatin1String("websettings")); + m_enabled = settings.value(QLatin1String("enableClickToFlash"), false).toBool(); +} + +void ClickToFlashPlugin::save() +{ + QSettings settings; + settings.beginGroup(QLatin1String("webplugin/clicktoflash")); + settings.setValue(QLatin1String("whitelist"), m_whitelist); +} + +QWidget *ClickToFlashPlugin::create(const QString &mimeType, const QUrl &url, + const QStringList &argumentNames, const QStringList &argumentValues) +{ + load(); + if (!m_enabled) + return 0; + Q_UNUSED(mimeType); + if (m_whitelist.contains(url.host())) + return 0; + + ClickToFlash *ctf = new ClickToFlash(this); + ctf->url = url; + ctf->argumentNames = argumentNames; + ctf->argumentValues = argumentValues; + return ctf; +} + +QWebPluginFactory::Plugin ClickToFlashPlugin::metaPlugin() +{ + QWebPluginFactory::Plugin plugin; + plugin.name = QLatin1String("ClickToFlashPlugin"); + QWebPluginFactory::MimeType mimeType; + mimeType.fileExtensions << QLatin1String("swf"); + mimeType.name = QLatin1String("application/x-shockwave-flash"); + plugin.mimeTypes.append(mimeType); + return plugin; +} + +void ClickToFlashPlugin::configure() +{ + QDialog dialog; + Ui_ClickToFlashSettings ui; + ui.setupUi(&dialog); + QStringListModel *model = new QStringListModel(m_whitelist, ui.whitelist); + ui.whitelist->setModel(model); + if (dialog.exec() == QDialog::Accepted) { + m_whitelist = model->stringList(); + save(); + } +} + +bool ClickToFlashPlugin::isAnonymous() const +{ + return true; +} + +bool ClickToFlashPlugin::onWhitelist(const QString &host) const +{ + return m_whitelist.contains(host); +} + +void ClickToFlashPlugin::addToWhitelist(const QString &host) +{ + m_whitelist.append(host); + save(); +} + +void ClickToFlashPlugin::removeFromWhitelist(const QString &host) +{ + m_whitelist.removeOne(host); + save(); +} + diff --git a/src/qwebplugins/clicktoflash/clicktoflashplugin.h b/src/qwebplugins/clicktoflash/clicktoflashplugin.h new file mode 100644 index 00000000..1e6b258e --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflashplugin.h @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef CLICKTOFLASHPLUGIN_H +#define CLICKTOFLASHPLUGIN_H + +#include "arorawebplugin.h" + +class ClickToFlashPlugin : public AroraWebPlugin +{ + +public: + ClickToFlashPlugin(); + + QWebPluginFactory::Plugin metaPlugin(); + QWidget *create(const QString &mimeType, const QUrl &url, + const QStringList &argumentNames, const QStringList &argumentValues); + void configure(); + bool isAnonymous() const; + + bool onWhitelist(const QString &host) const; + void addToWhitelist(const QString &host); + void removeFromWhitelist(const QString &host); + +private: + void load(); + void save(); + + bool m_loaded; + bool m_enabled; + QStringList m_whitelist; +}; + +#endif // CLICKTOFLASHPLUGIN_H + diff --git a/src/qwebplugins/clicktoflash/clicktoflashsettings.ui b/src/qwebplugins/clicktoflash/clicktoflashsettings.ui new file mode 100644 index 00000000..d4660add --- /dev/null +++ b/src/qwebplugins/clicktoflash/clicktoflashsettings.ui @@ -0,0 +1,81 @@ + + + ClickToFlashSettings + + + + 0 + 0 + 400 + 300 + + + + + + + Whitelist sites + + + Qt::AlignCenter + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + EditListView + QListView +
    editlistview.h
    +
    +
    + + + + buttonBox + accepted() + ClickToFlashSettings + accept() + + + 342 + 274 + + + 335 + 253 + + + + + buttonBox + rejected() + ClickToFlashSettings + reject() + + + 254 + 274 + + + 242 + 254 + + + + +
    diff --git a/src/qwebplugins/clicktoflash/swap.js b/src/qwebplugins/clicktoflash/swap.js new file mode 100644 index 00000000..747da9a5 --- /dev/null +++ b/src/qwebplugins/clicktoflash/swap.js @@ -0,0 +1,20 @@ +function swapFlashObjects() { + var src = "%1"; + var type = "application/x-shockwave-flash"; + var objects = arguments[0]; + for (var i = 0; i < objects.length; ++i) { + if (type != objects[i].getAttribute("type")) + continue; + if (src != "") { + if (!objects[i].swapping) + continue; + } + var newObject = objects[i].cloneNode(true); + newObject.setAttribute("type", "application/futuresplash"); + var parent = objects[i].parentNode; + parent.replaceChild(newObject, objects[i]); + } +} + +swapFlashObjects(document.getElementsByTagName("object")); +swapFlashObjects(document.getElementsByTagName("embed")); diff --git a/src/qwebplugins/qwebplugins.pri b/src/qwebplugins/qwebplugins.pri new file mode 100644 index 00000000..d3d9cb72 --- /dev/null +++ b/src/qwebplugins/qwebplugins.pri @@ -0,0 +1,13 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + arorawebplugin.h \ + webpluginfactory.h + +SOURCES += \ + arorawebplugin.cpp \ + webpluginfactory.cpp + +include(clicktoflash/clicktoflash.pri) + diff --git a/src/qwebplugins/webpluginfactory.cpp b/src/qwebplugins/webpluginfactory.cpp new file mode 100644 index 00000000..c12fe727 --- /dev/null +++ b/src/qwebplugins/webpluginfactory.cpp @@ -0,0 +1,95 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "webpluginfactory.h" + +#include "clicktoflashplugin.h" + +#include +#include +#include + +// #define WEBPLUGINFACTORY_DEBUG + +WebPluginFactory::WebPluginFactory(QObject *parent) + : QWebPluginFactory(parent) + , m_loaded(false) +{ +} + +WebPluginFactory::~WebPluginFactory() +{ + qDeleteAll(m_plugins); + m_plugins.clear(); +} + +QObject *WebPluginFactory::create(const QString &mimeType, const QUrl &url, const QStringList &argumentNames, const QStringList &argumentValues) const +{ + if (!m_loaded) + init(); + +#ifdef WEBPLUGINFACTORY_DEBUG + qDebug() << "WebPluginFactory::" << __FUNCTION__ << mimeType << url << argumentNames << argumentValues; +#endif + AroraWebPlugin *plugin = m_pluginsCache[mimeType]; + if (plugin) + return plugin->create(mimeType, url, argumentNames, argumentValues); +#ifdef WEBPLUGINFACTORY_DEBUG + qDebug() << "WebPluginFactory::" << __FUNCTION__ << "No match"; +#endif + return 0; +} + +QList WebPluginFactory::plugins() const +{ +#ifdef WEBPLUGINFACTORY_DEBUG + qDebug() << "WebPluginFactory::" << __FUNCTION__; +#endif + if (!m_loaded) + init(); + QList plugins; + foreach (AroraWebPlugin *plugin, m_plugins) { + QWebPluginFactory::Plugin pluginInfo = plugin->metaPlugin(); + if (!plugin->isAnonymous()) + plugins.append(pluginInfo); + } + return plugins; +} + +void WebPluginFactory::refreshPlugins() +{ +#ifdef WEBPLUGINFACTORY_DEBUG + qDebug() << "WebPluginFactory::" << __FUNCTION__; +#endif + init(); + QWebPluginFactory::refreshPlugins(); +} + +void WebPluginFactory::init() const +{ + m_loaded = true; + m_pluginsCache.clear(); + qDeleteAll(m_plugins); + m_plugins.clear(); + m_plugins.append(new ClickToFlashPlugin); + foreach (AroraWebPlugin *plugin, m_plugins) { + foreach (const QWebPluginFactory::MimeType &pluginMimeType, plugin->metaPlugin().mimeTypes) + m_pluginsCache.insert(pluginMimeType.name, plugin); + } +} diff --git a/src/qwebplugins/webpluginfactory.h b/src/qwebplugins/webpluginfactory.h new file mode 100644 index 00000000..8d06ec9f --- /dev/null +++ b/src/qwebplugins/webpluginfactory.h @@ -0,0 +1,49 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef WEBPLUGINFACTORY_H +#define WEBPLUGINFACTORY_H + +#include +#include + +#include "arorawebplugin.h" + +class WebPluginFactory : public QWebPluginFactory +{ + Q_OBJECT + +public: + WebPluginFactory(QObject *parent = 0); + ~WebPluginFactory(); + + QObject *create(const QString &mimeType, const QUrl &url, + const QStringList &argumentNames, const QStringList &argumentValues) const; + QList plugins() const; + void refreshPlugins(); + +private: + void init() const; + mutable bool m_loaded; + mutable QList m_plugins; + mutable QHash m_pluginsCache; +}; + +#endif // WEBPLUGINFACTORY_H + diff --git a/src/searchbanner.ui b/src/searchbanner.ui index 5a54614f..062ad8d7 100644 --- a/src/searchbanner.ui +++ b/src/searchbanner.ui @@ -1,7 +1,8 @@ - + + SearchBanner - - + + 0 0 @@ -9,34 +10,31 @@ 36 - - + + 0 0 - - Form - - - + + -1 - + 12 - + 0 - + 0 - - + + Qt::Horizontal - + 26 20 @@ -45,32 +43,41 @@ - - - TextLabel + + + + + + Highlight All + + + false + + + true - - - < + + + < - - - > + + + > - + - - + + Done diff --git a/src/searchbar.cpp b/src/searchbar.cpp new file mode 100644 index 00000000..bd5cb691 --- /dev/null +++ b/src/searchbar.cpp @@ -0,0 +1,124 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "searchbar.h" + +#include +#include +#include + +#include + +SearchBar::SearchBar(QWidget *parent) + : QWidget(parent) + , m_object(0) + , m_widget(0) + , m_timeLine(new QTimeLine(150, this)) +{ + initializeSearchWidget(); + + // we start off hidden + setMaximumHeight(0); + m_widget->setGeometry(0, -1 * m_widget->height(), + m_widget->width(), m_widget->height()); + hide(); + + connect(ui.nextButton, SIGNAL(clicked()), + this, SLOT(findNext())); + connect(ui.previousButton, SIGNAL(clicked()), + this, SLOT(findPrevious())); + connect(ui.searchLineEdit, SIGNAL(returnPressed()), + this, SLOT(findNext())); + connect(ui.searchLineEdit, SIGNAL(textEdited(const QString &)), + this, SLOT(findNext())); + connect(ui.doneButton, SIGNAL(clicked()), + this, SLOT(animateHide())); + connect(m_timeLine, SIGNAL(frameChanged(int)), + this, SLOT(frameChanged(int))); + + new QShortcut(QKeySequence(Qt::Key_Escape), this, SLOT(animateHide())); +} + +void SearchBar::initializeSearchWidget() +{ + m_widget = new QWidget(this); + m_widget->setContentsMargins(0, 0, 0, 0); + ui.setupUi(m_widget); + ui.previousButton->setText(m_widget->layoutDirection() + == Qt::LeftToRight? QChar(9664): QChar(9654)); + ui.nextButton->setText(m_widget->layoutDirection() + == Qt::LeftToRight? QChar(9654): QChar(9664)); + ui.searchInfo->setText(QString()); + setMinimumWidth(m_widget->minimumWidth()); + setMaximumWidth(m_widget->maximumWidth()); + setMinimumHeight(m_widget->minimumHeight()); +} + +void SearchBar::setSearchObject(QObject *object) +{ + m_object = object; +} + +QObject *SearchBar::searchObject() const +{ + return m_object; +} + +void SearchBar::clear() +{ + ui.searchLineEdit->setText(QString()); +} + +void SearchBar::showFind() +{ + if (!isVisible()) { + show(); + m_timeLine->setFrameRange(-1 * m_widget->height(), 0); + m_timeLine->setDirection(QTimeLine::Forward); + disconnect(m_timeLine, SIGNAL(finished()), + this, SLOT(hide())); + m_timeLine->start(); + } + ui.searchLineEdit->setFocus(); + ui.searchLineEdit->selectAll(); +} + +void SearchBar::resizeEvent(QResizeEvent *event) +{ + if (event->size().width() != m_widget->width()) + m_widget->resize(event->size().width(), m_widget->height()); + QWidget::resizeEvent(event); +} + +void SearchBar::animateHide() +{ + m_timeLine->setDirection(QTimeLine::Backward); + m_timeLine->start(); + connect(m_timeLine, SIGNAL(finished()), this, SLOT(hide())); +} + +void SearchBar::frameChanged(int frame) +{ + if (!m_widget) + return; + m_widget->move(0, frame); + int height = qMax(0, m_widget->y() + m_widget->height()); + setMinimumHeight(height); + setMaximumHeight(height); +} diff --git a/src/searchbar.h b/src/searchbar.h new file mode 100644 index 00000000..3e2bb124 --- /dev/null +++ b/src/searchbar.h @@ -0,0 +1,62 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef SEARCHBAR_H +#define SEARCHBAR_H + +#include + +#include "ui_searchbanner.h" + +QT_BEGIN_NAMESPACE +class QTimeLine; +QT_END_NAMESPACE + +class SearchBar : public QWidget +{ + Q_OBJECT + +public: + SearchBar(QWidget *parent = 0); + void setSearchObject(QObject *object); + QObject *searchObject() const; + +public slots: + void animateHide(); + void clear(); + void showFind(); + virtual void findNext() = 0; + virtual void findPrevious() = 0; + +protected: + void resizeEvent(QResizeEvent *event); + Ui_SearchBanner ui; + +private slots: + void frameChanged(int frame); + +private: + void initializeSearchWidget(); + QObject *m_object; + QWidget *m_widget; + QTimeLine *m_timeLine; +}; + +#endif + diff --git a/src/searchbutton.cpp b/src/searchbutton.cpp new file mode 100644 index 00000000..eae90911 --- /dev/null +++ b/src/searchbutton.cpp @@ -0,0 +1,115 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "searchbutton.h" + +#include +#include +#include +#include + +SearchButton::SearchButton(QWidget *parent) + : QAbstractButton(parent) + , m_showMenuTriangle(false) +{ + setFocusPolicy(Qt::NoFocus); + setCursor(Qt::ArrowCursor); + setMinimumSize(sizeHint()); +} + +QSize SearchButton::sizeHint() const +{ + if (!m_cache.isNull()) + return m_cache.size(); + if (m_showMenuTriangle) + return QSize(16, 16); + return QSize(12, 16); +} + +QImage SearchButton::generateSearchImage(bool dropDown) +{ + QImage image(dropDown ? 16 : 12, 16, QImage::Format_ARGB32); + image.fill(qRgba(0, 0, 0, 0)); + QPainterPath path; + + // draw magnify glass circle + int radius = image.height() / 2; + QRect circle(1, 1, radius, radius); + path.addEllipse(circle); + + // draw handle + path.arcMoveTo(circle, 300); + QPointF currentPosition = path.currentPosition(); + path.moveTo(currentPosition.x() + 1, currentPosition.y() + 1); + if (dropDown) + path.lineTo(image.width()-6, image.height()-4); + else + path.lineTo(image.width()-2, image.height()-4); + + QPainter painter(&image); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setPen(QPen(Qt::darkGray, 2)); + painter.drawPath(path); + + if (dropDown) { + // draw the dropdown triangle + QPainterPath dropPath; + dropPath.arcMoveTo(circle, 320); + QPointF currentPosition = dropPath.currentPosition(); + currentPosition = QPointF(currentPosition.x() + 2, currentPosition.y() + 0.5); + dropPath.moveTo(currentPosition); + dropPath.lineTo(currentPosition.x() + 4, currentPosition.y()); + dropPath.lineTo(currentPosition.x() + 2, currentPosition.y() + 2); + dropPath.closeSubpath(); + painter.setPen(Qt::darkGray); + painter.setBrush(Qt::darkGray); + painter.setRenderHint(QPainter::Antialiasing, false); + painter.drawPath(dropPath); + } + painter.end(); + return image; +} + +void SearchButton::setImage(const QImage &image) +{ + m_cache = image; + setMinimumSize(sizeHint()); + update(); +} + +void SearchButton::setShowMenuTriangle(bool show) +{ + m_showMenuTriangle = show; + setMinimumSize(sizeHint()); +} + +bool SearchButton::showMenuTriangle() const +{ + return m_showMenuTriangle; +} + +void SearchButton::paintEvent(QPaintEvent *event) +{ + Q_UNUSED(event); + if (m_cache.isNull()) + m_cache = generateSearchImage(m_showMenuTriangle); + QPainter painter(this); + painter.drawImage(QPoint(0, 0), m_cache); +} + diff --git a/src/searchbutton.h b/src/searchbutton.h new file mode 100644 index 00000000..3f9c0ac9 --- /dev/null +++ b/src/searchbutton.h @@ -0,0 +1,45 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef SEARCHBUTTON_H +#define SEARCHBUTTON_H + +#include + +class QCompleter; +class SearchButton : public QAbstractButton +{ + Q_OBJECT + +public: + SearchButton(QWidget *parent = 0); + void setImage(const QImage &image); + void setShowMenuTriangle(bool show); + bool showMenuTriangle() const; + void paintEvent(QPaintEvent *event); + QSize sizeHint() const; + +private: + QImage generateSearchImage(bool dropDown); + QImage m_cache; + bool m_showMenuTriangle; +}; + +#endif // SEARCHBUTTON_H + diff --git a/src/searchlineedit.cpp b/src/searchlineedit.cpp index 758891c6..683e6e13 100644 --- a/src/searchlineedit.cpp +++ b/src/searchlineedit.cpp @@ -1,260 +1,68 @@ -/* - * Copyright 2008 Benjamin C. Meyer +/** + * Copyright (c) 2009, Benjamin C. Meyer * - * This program 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; either version 2 of the License, or - * (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ -/**************************************************************************** -** -** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - #include "searchlineedit.h" -#include -#include -#include -#include - -ClearButton::ClearButton(QWidget *parent) - : QAbstractButton(parent) -{ - setCursor(Qt::ArrowCursor); - setToolTip(tr("Clear")); - setVisible(false); - setFocusPolicy(Qt::NoFocus); -} - -void ClearButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainter painter(this); - int height = this->height(); - - painter.setRenderHint(QPainter::Antialiasing, true); - QColor color = palette().color(QPalette::Mid); - painter.setBrush(isDown() - ? palette().color(QPalette::Dark) - : palette().color(QPalette::Mid)); - painter.setPen(painter.brush().color()); - int size = width(); - int offset = size / 5; - int radius = size - offset * 2; - painter.drawEllipse(offset, offset, radius, radius); - - painter.setPen(palette().color(QPalette::Base)); - int border = offset * 2; - painter.drawLine(border, border, width() - border, height - border); - painter.drawLine(border, height - border, width() - border, border); -} - -void ClearButton::textChanged(const QString &text) -{ - setVisible(!text.isEmpty()); -} - -/* - Search icon on the left hand side of the search widget - When a menu is set a down arrow appears - */ -class SearchButton : public QAbstractButton -{ -public: - SearchButton(QWidget *parent = 0); - void paintEvent(QPaintEvent *event); - QMenu *m_menu; - -protected: - void mousePressEvent(QMouseEvent *event); -}; - -SearchButton::SearchButton(QWidget *parent) - : QAbstractButton(parent) - , m_menu(0) -{ - setObjectName(QLatin1String("SearchButton")); - setCursor(Qt::ArrowCursor); - setFocusPolicy(Qt::NoFocus); -} - -void SearchButton::mousePressEvent(QMouseEvent *event) -{ - if (m_menu && event->button() == Qt::LeftButton) { - QWidget *p = parentWidget(); - if (p) { - QPoint r = p->mapToGlobal(QPoint(0, p->height())); - m_menu->exec(QPoint(r.x() + height() / 2, r.y())); - } - event->accept(); - } - QAbstractButton::mousePressEvent(event); -} - -void SearchButton::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); - QPainterPath myPath; - - int radius = (height() / 5) * 2; - QRect circle(height() / 3 - 1, height() / 4, radius, radius); - myPath.addEllipse(circle); - - myPath.arcMoveTo(circle, 300); - QPointF c = myPath.currentPosition(); - int diff = height() / 7; - myPath.lineTo(qMin(width() - 2, (int)c.x() + diff), c.y() + diff); - - QPainter painter(this); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setPen(QPen(Qt::darkGray, 2)); - painter.drawPath(myPath); +#include "clearbutton.h" +#include "searchbutton.h" - if (m_menu) { - QPainterPath dropPath; - dropPath.arcMoveTo(circle, 320); - QPointF c = dropPath.currentPosition(); - c = QPointF(c.x() + 3.5, c.y() + 0.5); - dropPath.moveTo(c); - dropPath.lineTo(c.x() + 4, c.y()); - dropPath.lineTo(c.x() + 2, c.y() + 2); - dropPath.closeSubpath(); - painter.setPen(Qt::darkGray); - painter.setBrush(Qt::darkGray); - painter.setRenderHint(QPainter::Antialiasing, false); - painter.drawPath(dropPath); - } - painter.end(); -} - -/* - SearchLineEdit is an enhanced QLineEdit - - A Search icon on the left with optional menu - - When there is no text and doesn't have focus an "inactive text" is displayed - - When there is text a clear button is displayed on the right hand side - */ SearchLineEdit::SearchLineEdit(QWidget *parent) - : ExLineEdit(parent) - , m_searchButton(new SearchButton(this)) -{ - connect(lineEdit(), SIGNAL(textChanged(const QString &)), - this, SIGNAL(textChanged(const QString &))); - setLeftWidget(m_searchButton); - m_inactiveText = tr("Search"); - - QSizePolicy policy = sizePolicy(); - setSizePolicy(QSizePolicy::Preferred, policy.verticalPolicy()); -} - -void SearchLineEdit::paintEvent(QPaintEvent *event) -{ - if (lineEdit()->text().isEmpty() && !hasFocus() && !m_inactiveText.isEmpty()) { - ExLineEdit::paintEvent(event); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - QFontMetrics fm = fontMetrics(); - int horizontalMargin = lineEdit()->x(); - QRect lineRect(horizontalMargin + r.x(), r.y() + (r.height() - fm.height() + 1) / 2, - r.width() - 2 * horizontalMargin, fm.height()); - QPainter painter(this); - painter.setPen(palette().brush(QPalette::Disabled, QPalette::Text).color()); - painter.drawText(lineRect, Qt::AlignLeft | Qt::AlignVCenter, m_inactiveText); - } else { - ExLineEdit::paintEvent(event); - } -} - -void SearchLineEdit::resizeEvent(QResizeEvent *event) -{ - updateGeometries(); - ExLineEdit::resizeEvent(event); -} - -void SearchLineEdit::updateGeometries() -{ - int menuHeight = height(); - int menuWidth = menuHeight + 1; - if (!m_searchButton->m_menu) - menuWidth = (menuHeight / 5) * 4; - m_searchButton->resize(QSize(menuWidth, menuHeight)); -} - -QString SearchLineEdit::inactiveText() const + : LineEdit(parent) { - return m_inactiveText; + init(); } -void SearchLineEdit::setInactiveText(const QString &text) +void SearchLineEdit::init() { - m_inactiveText = text; + // search button on the left + m_searchButton = new SearchButton(this); + addWidget(m_searchButton, LeftSide); + + // clear button on the right + m_clearButton = new ClearButton(this); + connect(m_clearButton, SIGNAL(clicked()), + this, SLOT(clear())); + connect(this, SIGNAL(textChanged(const QString&)), + m_clearButton, SLOT(textChanged(const QString&))); + addWidget(m_clearButton, RightSide); + m_clearButton->hide(); + + updateTextMargins(); + setInactiveText(tr("Search")); } -void SearchLineEdit::setMenu(QMenu *menu) +ClearButton *SearchLineEdit::clearButton() const { - if (m_searchButton->m_menu) - m_searchButton->m_menu->deleteLater(); - m_searchButton->m_menu = menu; - updateGeometries(); + return m_clearButton; } -QMenu *SearchLineEdit::menu() const +SearchButton *SearchLineEdit::searchButton() const { - if (!m_searchButton->m_menu) { - m_searchButton->m_menu = new QMenu(m_searchButton); - if (isVisible()) - (const_cast(this))->updateGeometries(); - } - return m_searchButton->m_menu; + return m_searchButton; } diff --git a/src/searchlineedit.h b/src/searchlineedit.h index 9a931811..bdfeddc9 100644 --- a/src/searchlineedit.h +++ b/src/searchlineedit.h @@ -1,123 +1,53 @@ -/* - * Copyright 2008 Benjamin C. Meyer +/** + * Copyright (c) 2009, Benjamin C. Meyer * - * This program 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; either version 2 of the License, or - * (at your option) any later version. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ -/**************************************************************************** -** -** Copyright (C) 2007-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - #ifndef SEARCHLINEEDIT_H #define SEARCHLINEEDIT_H -#include "urllineedit.h" - -#include -#include - -QT_BEGIN_NAMESPACE -class QMenu; -QT_END_NAMESPACE +#include "lineedit.h" +class ClearButton; class SearchButton; - -/* - Clear button on the right hand side of the search widget. - Hidden by default - "A circle with an X in it" - */ -class ClearButton : public QAbstractButton +class SearchLineEdit : public LineEdit { Q_OBJECT -public: - ClearButton(QWidget *parent = 0); - void paintEvent(QPaintEvent *event); - -public slots: - void textChanged(const QString &text); -}; - - -class SearchLineEdit : public ExLineEdit -{ - Q_OBJECT - Q_PROPERTY(QString inactiveText READ inactiveText WRITE setInactiveText) - -signals: - void textChanged(const QString &text); - public: SearchLineEdit(QWidget *parent = 0); - QString inactiveText() const; - void setInactiveText(const QString &text); - - QMenu *menu() const; - void setMenu(QMenu *menu); - -protected: - void resizeEvent(QResizeEvent *event); - void paintEvent(QPaintEvent *event); + ClearButton *clearButton() const; + SearchButton *searchButton() const; private: - void updateGeometries(); - + void init(); + ClearButton *m_clearButton; SearchButton *m_searchButton; - QString m_inactiveText; + }; #endif // SEARCHLINEEDIT_H diff --git a/src/settings.cpp b/src/settings.cpp index a3532a51..3cbe7e86 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -62,21 +62,32 @@ #include "settings.h" +#include "acceptlanguagedialog.h" +#include "autofilldialog.h" +#include "autofillmanager.h" #include "browserapplication.h" #include "browsermainwindow.h" +#include "cookiedialog.h" +#include "cookieexceptionsdialog.h" #include "cookiejar.h" -#include "history.h" +#include "historymanager.h" #include "networkaccessmanager.h" +#include "tabwidget.h" +#include "webpluginfactory.h" +#include "webpage.h" #include "webview.h" #include #include #include #include +#include #include +#include SettingsDialog::SettingsDialog(QWidget *parent) : QDialog(parent) + , m_cacheEnabled(false) { setupUi(this); connect(exceptionsButton, SIGNAL(clicked()), this, SLOT(showExceptions())); @@ -84,6 +95,16 @@ SettingsDialog::SettingsDialog(QWidget *parent) connect(cookiesButton, SIGNAL(clicked()), this, SLOT(showCookies())); connect(standardFontButton, SIGNAL(clicked()), this, SLOT(chooseFont())); connect(fixedFontButton, SIGNAL(clicked()), this, SLOT(chooseFixedFont())); + connect(languageButton, SIGNAL(clicked()), this, SLOT(chooseAcceptLanguage())); + connect(downloadDirectoryButton, SIGNAL(clicked()), this, SLOT(chooseDownloadDirectory())); + connect(externalDownloadBrowse, SIGNAL(clicked()), this, SLOT(chooseDownloadProgram())); + connect(styleSheetBrowseButton, SIGNAL(clicked()), this, SLOT(chooseStyleSheet())); + + connect(editAutoFillUserButton, SIGNAL(clicked()), this, SLOT(editAutoFillUser())); + + // As network cache has too many bugs in 4.5.1, do not allow to enable it. + if (QLatin1String(qVersion()) == QLatin1String("4.5.1")) + networkCache->setVisible(false); loadDefaults(); loadFromSettings(); @@ -94,27 +115,41 @@ void SettingsDialog::loadDefaults() QWebSettings *defaultSettings = QWebSettings::globalSettings(); QString standardFontFamily = defaultSettings->fontFamily(QWebSettings::StandardFont); int standardFontSize = defaultSettings->fontSize(QWebSettings::DefaultFontSize); - standardFont = QFont(standardFontFamily, standardFontSize); - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(standardFont.family()).arg(standardFont.pointSize())); + m_standardFont = QFont(standardFontFamily, standardFontSize); + standardLabel->setText(QString(QLatin1String("%1 %2")).arg(m_standardFont.family()).arg(m_standardFont.pointSize())); QString fixedFontFamily = defaultSettings->fontFamily(QWebSettings::FixedFont); int fixedFontSize = defaultSettings->fontSize(QWebSettings::DefaultFixedFontSize); - fixedFont = QFont(fixedFontFamily, fixedFontSize); - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(fixedFont.family()).arg(fixedFont.pointSize())); + m_fixedFont = QFont(fixedFontFamily, fixedFontSize); + fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(m_fixedFont.family()).arg(m_fixedFont.pointSize())); downloadsLocation->setText(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation)); + blockPopupWindows->setChecked(!defaultSettings->testAttribute(QWebSettings::JavascriptCanOpenWindows)); enableJavascript->setChecked(defaultSettings->testAttribute(QWebSettings::JavascriptEnabled)); enablePlugins->setChecked(defaultSettings->testAttribute(QWebSettings::PluginsEnabled)); enableImages->setChecked(defaultSettings->testAttribute(QWebSettings::AutoLoadImages)); + enableLocalStorage->setChecked(defaultSettings->testAttribute(QWebSettings::LocalStorageEnabled)); + clickToFlash->setChecked(false); + cookieSessionCombo->setCurrentIndex(0); + filterTrackingCookiesCheckbox->setChecked(false); + + autoFillPasswordFormsCheckBox->setChecked(false); + minimFontSizeCheckBox->setChecked(false); + minimumFontSizeSpinBox->setValue(9); } void SettingsDialog::loadFromSettings() { QSettings settings; + settings.beginGroup(QLatin1String("Settings")); + tabWidget->setCurrentIndex(settings.value(QLatin1String("currentTab"), 0).toInt()); + settings.endGroup(); + settings.beginGroup(QLatin1String("MainWindow")); - QString defaultHome = QLatin1String("http://www.arora-browser.org"); + QString defaultHome = QLatin1String("about:home"); homeLineEdit->setText(settings.value(QLatin1String("home"), defaultHome).toString()); + startupBehavior->setCurrentIndex(settings.value(QLatin1String("startupBehavior"), 0).toInt()); settings.endGroup(); settings.beginGroup(QLatin1String("history")); @@ -134,43 +169,50 @@ void SettingsDialog::loadFromSettings() expireHistory->setCurrentIndex(idx); settings.endGroup(); + settings.beginGroup(QLatin1String("urlloading")); + bool search = settings.value(QLatin1String("searchEngineFallback"), false).toBool(); + searchEngineFallback->setChecked(search); + settings.endGroup(); + settings.beginGroup(QLatin1String("downloadmanager")); bool alwaysPromptForFileName = settings.value(QLatin1String("alwaysPromptForFileName"), false).toBool(); - if (alwaysPromptForFileName) - downloadAsk->setChecked(true); + downloadAsk->setChecked(alwaysPromptForFileName); QString downloadDirectory = settings.value(QLatin1String("downloadDirectory"), downloadsLocation->text()).toString(); downloadsLocation->setText(downloadDirectory); - settings.endGroup(); - - settings.beginGroup(QLatin1String("general")); - openLinksIn->setCurrentIndex(settings.value(QLatin1String("openLinksIn"), openLinksIn->currentIndex()).toInt()); - + externalDownloadButton->setChecked(settings.value(QLatin1String("external"), false).toBool()); + externalDownloadPath->setText(settings.value(QLatin1String("externalPath")).toString()); settings.endGroup(); // Appearance settings.beginGroup(QLatin1String("websettings")); - fixedFont = qVariantValue(settings.value(QLatin1String("fixedFont"), fixedFont)); - standardFont = qVariantValue(settings.value(QLatin1String("standardFont"), standardFont)); + m_fixedFont = qVariantValue(settings.value(QLatin1String("fixedFont"), m_fixedFont)); + m_standardFont = qVariantValue(settings.value(QLatin1String("standardFont"), m_standardFont)); - standardLabel->setText(QString(QLatin1String("%1 %2")).arg(standardFont.family()).arg(standardFont.pointSize())); - fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(fixedFont.family()).arg(fixedFont.pointSize())); + standardLabel->setText(QString(QLatin1String("%1 %2")).arg(m_standardFont.family()).arg(m_standardFont.pointSize())); + fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(m_fixedFont.family()).arg(m_fixedFont.pointSize())); + blockPopupWindows->setChecked(settings.value(QLatin1String("blockPopupWindows"), blockPopupWindows->isChecked()).toBool()); enableJavascript->setChecked(settings.value(QLatin1String("enableJavascript"), enableJavascript->isChecked()).toBool()); enablePlugins->setChecked(settings.value(QLatin1String("enablePlugins"), enablePlugins->isChecked()).toBool()); enableImages->setChecked(settings.value(QLatin1String("enableImages"), enableImages->isChecked()).toBool()); - userStyleSheet->setText(settings.value(QLatin1String("userStyleSheet")).toUrl().toString()); + enableLocalStorage->setChecked(settings.value(QLatin1String("enableLocalStorage"), enableLocalStorage->isChecked()).toBool()); + userStyleSheet->setText(QString::fromUtf8(settings.value(QLatin1String("userStyleSheet")).toUrl().toEncoded())); + clickToFlash->setChecked(settings.value(QLatin1String("enableClickToFlash"), clickToFlash->isChecked()).toBool()); + int minimumFontSize = settings.value(QLatin1String("minimumFontSize"), 0).toInt(); + minimFontSizeCheckBox->setChecked(minimumFontSize != 0); + if (minimumFontSize != 0) + minimumFontSizeSpinBox->setValue(minimumFontSize); settings.endGroup(); // Privacy settings.beginGroup(QLatin1String("cookies")); - CookieJar *jar = BrowserApplication::cookieJar(); QByteArray value = settings.value(QLatin1String("acceptCookies"), QLatin1String("AcceptOnlyFromSitesNavigatedTo")).toByteArray(); - QMetaEnum acceptPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("AcceptPolicy")); + QMetaEnum acceptPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("AcceptPolicy")); CookieJar::AcceptPolicy acceptCookies = acceptPolicyEnum.keyToValue(value) == -1 ? CookieJar::AcceptOnlyFromSitesNavigatedTo : static_cast(acceptPolicyEnum.keyToValue(value)); - switch(acceptCookies) { + switch (acceptCookies) { case CookieJar::AcceptAlways: acceptCombo->setCurrentIndex(0); break; @@ -183,11 +225,11 @@ void SettingsDialog::loadFromSettings() } value = settings.value(QLatin1String("keepCookiesUntil"), QLatin1String("Expire")).toByteArray(); - QMetaEnum keepPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("KeepPolicy")); + QMetaEnum keepPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("KeepPolicy")); CookieJar::KeepPolicy keepCookies = keepPolicyEnum.keyToValue(value) == -1 ? CookieJar::KeepUntilExpire : static_cast(keepPolicyEnum.keyToValue(value)); - switch(keepCookies) { + switch (keepCookies) { case CookieJar::KeepUntilExpire: keepUntilCombo->setCurrentIndex(0); break; @@ -198,8 +240,25 @@ void SettingsDialog::loadFromSettings() keepUntilCombo->setCurrentIndex(2); break; } + int sessionLength = settings.value(QLatin1String("sessionLength"), -1).toInt(); + switch (sessionLength) { + case 1: cookieSessionCombo->setCurrentIndex(1); break; + case 2: cookieSessionCombo->setCurrentIndex(2); break; + case 3: cookieSessionCombo->setCurrentIndex(3); break; + case 7: cookieSessionCombo->setCurrentIndex(4); break; + case 30: cookieSessionCombo->setCurrentIndex(5); break; + default: + case 0: cookieSessionCombo->setCurrentIndex(0); break; + } + filterTrackingCookiesCheckbox->setChecked(settings.value(QLatin1String("filterTrackingCookies"), false).toBool()); settings.endGroup(); + // Network + settings.beginGroup(QLatin1String("network")); + m_cacheEnabled = settings.value(QLatin1String("cacheEnabled"), true).toBool(); + networkCache->setChecked(m_cacheEnabled); + networkCacheMaximumSizeSpinBox->setValue(settings.value(QLatin1String("maximumCacheSize"), 50).toInt()); + settings.endGroup(); // Proxy settings.beginGroup(QLatin1String("proxy")); @@ -215,23 +274,43 @@ void SettingsDialog::loadFromSettings() settings.beginGroup(QLatin1String("tabs")); selectTabsWhenCreated->setChecked(settings.value(QLatin1String("selectNewTabs"), false).toBool()); confirmClosingMultipleTabs->setChecked(settings.value(QLatin1String("confirmClosingMultipleTabs"), true).toBool()); + oneCloseButton->setChecked(settings.value(QLatin1String("oneCloseButton"),false).toBool()); + quitAsLastTabClosed->setChecked(settings.value(QLatin1String("quitAsLastTabClosed"), true).toBool()); + openTargetBlankLinksIn->setCurrentIndex(settings.value(QLatin1String("openTargetBlankLinksIn"), TabWidget::NewSelectedTab).toInt()); + openLinksFromAppsIn->setCurrentIndex(settings.value(QLatin1String("openLinksFromAppsIn"), TabWidget::NewSelectedTab).toInt()); + settings.endGroup(); + + // Accessibility +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + settings.beginGroup(QLatin1String("WebView")); + enableAccessKeys->setChecked(settings.value(QLatin1String("enableAccessKeys"), true).toBool()); + settings.endGroup(); +#else + enableAccessKeys->setEnabled(false); +#endif + + settings.beginGroup(QLatin1String("autofill")); + autoFillPasswordFormsCheckBox->setChecked(settings.value(QLatin1String("passwordForms"), true).toBool()); settings.endGroup(); } void SettingsDialog::saveToSettings() { QSettings settings; + settings.beginGroup(QLatin1String("Settings")); + settings.setValue(QLatin1String("currentTab"), tabWidget->currentIndex()); + settings.endGroup(); + settings.beginGroup(QLatin1String("MainWindow")); settings.setValue(QLatin1String("home"), homeLineEdit->text()); + settings.setValue(QLatin1String("startupBehavior"), startupBehavior->currentIndex()); settings.endGroup(); settings.beginGroup(QLatin1String("downloadmanager")); settings.setValue(QLatin1String("alwaysPromptForFileName"), downloadAsk->isChecked()); settings.setValue(QLatin1String("downloadDirectory"), downloadsLocation->text()); - settings.endGroup(); - - settings.beginGroup(QLatin1String("general")); - settings.setValue(QLatin1String("openLinksIn"), openLinksIn->currentIndex()); + settings.setValue(QLatin1String("external"), externalDownloadButton->isChecked()); + settings.setValue(QLatin1String("externalPath"), externalDownloadPath->text()); settings.endGroup(); settings.beginGroup(QLatin1String("history")); @@ -249,43 +328,55 @@ void SettingsDialog::saveToSettings() settings.setValue(QLatin1String("historyLimit"), idx); settings.endGroup(); + settings.beginGroup(QLatin1String("urlloading")); + settings.setValue(QLatin1String("searchEngineFallback"), searchEngineFallback->isChecked()); + settings.endGroup(); + // Appearance settings.beginGroup(QLatin1String("websettings")); - settings.setValue(QLatin1String("fixedFont"), fixedFont); - settings.setValue(QLatin1String("standardFont"), standardFont); + settings.setValue(QLatin1String("fixedFont"), m_fixedFont); + settings.setValue(QLatin1String("standardFont"), m_standardFont); + + settings.setValue(QLatin1String("blockPopupWindows"), blockPopupWindows->isChecked()); settings.setValue(QLatin1String("enableJavascript"), enableJavascript->isChecked()); settings.setValue(QLatin1String("enablePlugins"), enablePlugins->isChecked()); settings.setValue(QLatin1String("enableImages"), enableImages->isChecked()); + settings.setValue(QLatin1String("enableLocalStorage"), enableLocalStorage->isChecked()); QString userStyleSheetString = userStyleSheet->text(); if (QFile::exists(userStyleSheetString)) settings.setValue(QLatin1String("userStyleSheet"), QUrl::fromLocalFile(userStyleSheetString)); else - settings.setValue(QLatin1String("userStyleSheet"), QUrl(userStyleSheetString)); + settings.setValue(QLatin1String("userStyleSheet"), QUrl::fromEncoded(userStyleSheetString.toUtf8())); + settings.setValue(QLatin1String("enableClickToFlash"), clickToFlash->isChecked()); + + if (minimFontSizeCheckBox->isChecked()) + settings.setValue(QLatin1String("minimumFontSize"), minimumFontSizeSpinBox->value()); + else + settings.setValue(QLatin1String("minimumFontSize"), 0); settings.endGroup(); - //Privacy + // Privacy settings.beginGroup(QLatin1String("cookies")); - - CookieJar::KeepPolicy keepCookies; - switch(acceptCombo->currentIndex()) { + CookieJar::AcceptPolicy acceptCookies; + switch (acceptCombo->currentIndex()) { default: case 0: - keepCookies = CookieJar::KeepUntilExpire; + acceptCookies = CookieJar::AcceptAlways; break; case 1: - keepCookies = CookieJar::KeepUntilExit; + acceptCookies = CookieJar::AcceptNever; break; case 2: - keepCookies = CookieJar::KeepUntilTimeLimit; + acceptCookies = CookieJar::AcceptOnlyFromSitesNavigatedTo; break; } - CookieJar *jar = BrowserApplication::cookieJar(); - QMetaEnum acceptPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("AcceptPolicy")); - settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(keepCookies))); + + QMetaEnum acceptPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("AcceptPolicy")); + settings.setValue(QLatin1String("acceptCookies"), QLatin1String(acceptPolicyEnum.valueToKey(acceptCookies))); CookieJar::KeepPolicy keepPolicy; - switch(keepUntilCombo->currentIndex()) { - default: + switch (keepUntilCombo->currentIndex()) { + default: case 0: keepPolicy = CookieJar::KeepUntilExpire; break; @@ -297,9 +388,26 @@ void SettingsDialog::saveToSettings() break; } - QMetaEnum keepPolicyEnum = jar->staticMetaObject.enumerator(jar->staticMetaObject.indexOfEnumerator("KeepPolicy")); + QMetaEnum keepPolicyEnum = CookieJar::staticMetaObject.enumerator(CookieJar::staticMetaObject.indexOfEnumerator("KeepPolicy")); settings.setValue(QLatin1String("keepCookiesUntil"), QLatin1String(keepPolicyEnum.valueToKey(keepPolicy))); + int sessionLength = cookieSessionCombo->currentIndex(); + switch (sessionLength) { + case 1: sessionLength = 1; break; + case 2: sessionLength = 2; break; + case 3: sessionLength = 3; break; + case 4: sessionLength = 7; break; + case 5: sessionLength = 30; break; + default: + case 0: sessionLength = -1; break; + } + settings.setValue(QLatin1String("sessionLength"), sessionLength); + settings.setValue(QLatin1String("filterTrackingCookies"), filterTrackingCookiesCheckbox->isChecked()); + settings.endGroup(); + // Network + settings.beginGroup(QLatin1String("network")); + settings.setValue(QLatin1String("cacheEnabled"), networkCache->isChecked()); + settings.setValue(QLatin1String("maximumCacheSize"), networkCacheMaximumSizeSpinBox->value()); settings.endGroup(); // proxy @@ -316,38 +424,81 @@ void SettingsDialog::saveToSettings() settings.beginGroup(QLatin1String("tabs")); settings.setValue(QLatin1String("selectNewTabs"), selectTabsWhenCreated->isChecked()); settings.setValue(QLatin1String("confirmClosingMultipleTabs"), confirmClosingMultipleTabs->isChecked()); + settings.setValue(QLatin1String("oneCloseButton"), oneCloseButton->isChecked()); + settings.setValue(QLatin1String("quitAsLastTabClosed"), quitAsLastTabClosed->isChecked()); + settings.setValue(QLatin1String("openTargetBlankLinksIn"), openTargetBlankLinksIn->currentIndex()); + settings.setValue(QLatin1String("openLinksFromAppsIn"), openLinksFromAppsIn->currentIndex()); + settings.endGroup(); + + settings.beginGroup(QLatin1String("autofill")); + settings.setValue(QLatin1String("passwordForms"), autoFillPasswordFormsCheckBox->isChecked()); + settings.endGroup(); + + // Accessibility +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + settings.beginGroup(QLatin1String("WebView")); + settings.setValue(QLatin1String("enableAccessKeys"), enableAccessKeys->isChecked()); settings.endGroup(); +#endif BrowserApplication::instance()->loadSettings(); BrowserApplication::networkAccessManager()->loadSettings(); BrowserApplication::cookieJar()->loadSettings(); BrowserApplication::historyManager()->loadSettings(); + BrowserApplication::autoFillManager()->loadSettings(); + + WebPage::webPluginFactory()->refreshPlugins(); + + QList list = BrowserApplication::instance()->mainWindows(); + foreach (BrowserMainWindow *mainWindow, list) { + mainWindow->tabWidget()->loadSettings(); + } } void SettingsDialog::accept() { saveToSettings(); + // Due to a bug in Qt <= 4.5.1, enabling/disabling cache requires the browser to be restarted. + if (QLatin1String(qVersion()) <= QLatin1String("4.5.1") && networkCache->isChecked() != m_cacheEnabled) { + QMessageBox::information(this, tr("Restart required"), + tr("The network cache configuration has changed. " + "So that it can be taken into account, the browser has to be restarted.")); + } QDialog::accept(); } void SettingsDialog::showCookies() { - CookiesDialog *dialog = new CookiesDialog(BrowserApplication::cookieJar(), this); - dialog->exec(); + CookieDialog dialog(BrowserApplication::cookieJar(), this); + dialog.exec(); } void SettingsDialog::showExceptions() { - CookiesExceptionsDialog *dialog = new CookiesExceptionsDialog(BrowserApplication::cookieJar(), this); - dialog->exec(); + CookieExceptionsDialog dialog(BrowserApplication::cookieJar(), this); + dialog.exec(); +} + +void SettingsDialog::chooseDownloadDirectory() +{ + QString fileName = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), downloadsLocation->text()); + downloadsLocation->setText(fileName); +} + +void SettingsDialog::chooseDownloadProgram() +{ + QString fileName = QFileDialog::getOpenFileName(this, tr("Choose Program"), externalDownloadPath->text()); + if (fileName.contains(QLatin1Char(' '))) + fileName = QString(QLatin1String("\"%1\"")).arg(fileName); + externalDownloadPath->setText(fileName); } void SettingsDialog::chooseFont() { bool ok; - QFont font = QFontDialog::getFont(&ok, standardFont, this); + QFont font = QFontDialog::getFont(&ok, m_standardFont, this); if (ok) { - standardFont = font; + m_standardFont = font; standardLabel->setText(QString(QLatin1String("%1 %2")).arg(font.family()).arg(font.pointSize())); } } @@ -355,9 +506,9 @@ void SettingsDialog::chooseFont() void SettingsDialog::chooseFixedFont() { bool ok; - QFont font = QFontDialog::getFont(&ok, fixedFont, this); + QFont font = QFontDialog::getFont(&ok, m_fixedFont, this); if (ok) { - fixedFont = font; + m_fixedFont = font; fixedLabel->setText(QString(QLatin1String("%1 %2")).arg(font.family()).arg(font.pointSize())); } } @@ -367,6 +518,25 @@ void SettingsDialog::setHomeToCurrentPage() BrowserMainWindow *mw = static_cast(parent()); WebView *webView = mw->currentTab(); if (webView) - homeLineEdit->setText(webView->url().toString()); + homeLineEdit->setText(QString::fromUtf8(webView->url().toEncoded())); +} + +void SettingsDialog::chooseAcceptLanguage() +{ + AcceptLanguageDialog dialog; + dialog.exec(); +} + +void SettingsDialog::chooseStyleSheet() +{ + QUrl url = QUrl::fromEncoded(userStyleSheet->text().toUtf8()); + QString fileName = QFileDialog::getOpenFileName(this, tr("Choose CSS File"), url.toLocalFile()); + userStyleSheet->setText(QString::fromUtf8(QUrl::fromLocalFile(fileName).toEncoded())); +} + +void SettingsDialog::editAutoFillUser() +{ + AutoFillDialog dialog; + dialog.exec(); } diff --git a/src/settings.h b/src/settings.h index af673703..5df57235 100644 --- a/src/settings.h +++ b/src/settings.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -83,12 +83,19 @@ private slots: void showCookies(); void showExceptions(); + void chooseDownloadDirectory(); + void chooseDownloadProgram(); void chooseFont(); void chooseFixedFont(); + void chooseAcceptLanguage(); + + void chooseStyleSheet(); + void editAutoFillUser(); private: - QFont standardFont; - QFont fixedFont; + QFont m_standardFont; + QFont m_fixedFont; + bool m_cacheEnabled; }; #endif // SETTINGS_H diff --git a/src/settings.ui b/src/settings.ui index 4362da1a..43275b52 100644 --- a/src/settings.ui +++ b/src/settings.ui @@ -1,278 +1,349 @@ - + + Settings - - + + 0 0 - 577 - 342 + 677 + 442 - - Settings + + Preferences - - - - + + + + Qt::Horizontal - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - 0 + + + + 2 - - + + General - - - - - Qt::Horizontal + + + + + On startup: - - - 280 - 18 - + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - + + + + + + + Show my home page + + + + + Show a blank page + + + + + Restore windows and tabs from last time + + + - - - - Home: + + + + Home Page: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + Qt::LeftToRight + + - - - + + + Set to current page - - - + + + + Qt::Horizontal + + + + 280 + 18 + + + + + + + Remove history items: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - + After one day - + After one week - + After two weeks - + After one month - + After one year - + Manually - + On application exit - - - - Open links from applications: + + + + Use the default search engine as fallback when the URL given by the user is invalid - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + false - - - - - In a tab in the current window - - - - - In a new window - - - - - - - - Qt::Vertical - - - - 391 - 262 - + + + + Enable access keys - + - - - + + + Downloads - + - - + + Ask for a destination each time - + - - + + Use this destination: - + true - + + + Qt::LeftToRight + + + + + + + Choose Directory... + + + + + + + + + + + Use this external download program: + + + + + + + + + + Choose Program... + + + + + + Qt::Vertical + + + + 608 + 15 + + + + - label_3 - homeLineEdit - setHomeToCurrentPageButton - label_4 - expireHistory - label_8 - openLinksIn - - groupBox_2 - - + + Appearance - - - - + + + + Standard font: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - + + + + 0 0 - + QFrame::StyledPanel - - Times 16 + + Times 16 - + Qt::AlignCenter - - - + + + Select... - - - + + + Fixed-width font: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - + + + QFrame::StyledPanel - - Courier 13 + + Courier 13 - + Qt::AlignCenter - - - + + + + Select... + + + + + + + Preferred languages for viewing webpages in: + + + + + + Select... - - - + + + + Minimum Font size: + + + + + + Qt::Vertical - + 20 93 @@ -280,45 +351,113 @@ + + + + false + + + 1 + + + 9 + + + - - + + Privacy - + - - + + Web Content - - - - + + + + + Block Popup Windows + + + true + + + + + + Enable Plugins - + true - - - + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + If you enable this option, no flash objects will be loaded by default. Instead, each will be replaced by a button, allowing you to control which objects to load, and which not. + + + Use ClickToFlash on flash plugins + + + true + + + + + + Enable Javascript - + true - - - - Enable Images + + + + View Images - + + true + + + + + + + Persistent Data Storage + + true @@ -327,92 +466,156 @@ - - + + Cookies - - - - + + + + Accept Cookies: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - + Always - + Never - + Only from sites you navigate to - - - + + + Exceptions... - - - - Keep until: + + + + Keep Cookies Until: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - + They expire - + I exit the application - + At most 90 days - - - + + + Cookies... + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Filter Tracking Cookies + + + + + + + A cookie session ends: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + When I exit the application + + + + + 1 day + + + + + 2 days + + + + + 3 days + + + + + 7 days + + + + + 30 days + + + + - + Qt::Vertical - + 371 177 @@ -422,34 +625,131 @@ - - + + Tabs - + - - + + Select tabs and windows as they are created - - - Confirm when closing multiple tabs + + + Confirm when closing multiple tabs or windows - + true - - + + + Show only one close button instead of one for each tab + + + false + + + + + + + Quit the application when last tab is closed + + + true + + + + + + + Opening links + + + + + + Links that want to open in a new window: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + In a new window + + + + + In a new selected tab in the current window + + + + + In a new tab in the current window + + + + + In the current tab + + + + + + + + Open links from applications: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + In a new window + + + + + In a new selected tab in the current window + + + + + In a new tab in the current window + + + + + In the current tab + + + + + + + + + + Qt::Vertical - + 20 182 @@ -459,83 +759,92 @@ - - + + Proxy - + - - - Enable proxy + + + Use proxy server - + true - - - - + + + + Type: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + - + Socks5 - - Http + + Http (Secure) + + + + + Http (Transparent) - - - - Host: + + + + Host name: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + Qt::LeftToRight + + - - - + + + Port: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - 10000 + + + + 65535 - + 1080 - - - + + + Qt::Horizontal - + 293 20 @@ -543,42 +852,49 @@ - - - + + + User Name: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - + + + + Qt::LeftToRight + + - - - + + + Password: - + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - + + + + Qt::LeftToRight + + QLineEdit::Password - - - + + + Qt::Vertical - + 20 8 @@ -591,27 +907,146 @@ - - + + + AutoFill + + + + + + AutoFill web forms: + + + + + + + + 0 + 0 + + + + User names and passwords + + + + + + + Edit... + + + + + + + Qt::Vertical + + + + 20 + 244 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Advanced - - - - + + + + Style Sheet: - - + + + + Qt::LeftToRight + + + + + + + Browse... + + - - - + + + + Enable network cache + + + true + + + true + + + + + + Maximum Size: + + + + + + + MB + + + 0 + + + 9999999 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Qt::Vertical - + 20 176 @@ -626,22 +1061,33 @@ - tabWidget + startupBehavior homeLineEdit setHomeToCurrentPageButton expireHistory - openLinksIn + searchEngineFallback downloadAsk downloadDestination - downloadsLocation + downloadDirectoryButton standardFontButton fixedFontButton + languageButton + blockPopupWindows enablePlugins + clickToFlash enableJavascript + enableImages acceptCombo exceptionsButton keepUntilCombo cookiesButton + filterTrackingCookiesCheckbox + selectTabsWhenCreated + confirmClosingMultipleTabs + oneCloseButton + quitAsLastTabClosed + openLinksFromAppsIn + openTargetBlankLinksIn proxySupport proxyType proxyHostName @@ -649,6 +1095,8 @@ proxyUserName proxyPassword userStyleSheet + networkCache + networkCacheMaximumSizeSpinBox buttonBox @@ -659,11 +1107,11 @@ Settings accept() - - 254 - 311 + + 269 + 447 - + 157 274 @@ -675,11 +1123,11 @@ Settings reject() - - 322 - 311 + + 337 + 447 - + 286 274 @@ -691,13 +1139,157 @@ downloadsLocation setEnabled(bool) - - 262 - 223 + + 79 + 289 + + + 280 + 291 + + + + + enablePlugins + toggled(bool) + clickToFlash + setEnabled(bool) + + + 104 + 125 + + + 162 + 154 + + + + + minimFontSizeCheckBox + toggled(bool) + minimumFontSizeSpinBox + setEnabled(bool) + + + 31 + 153 + + + 189 + 151 + + + + + downloadDestination + toggled(bool) + downloadDirectoryButton + setEnabled(bool) + + + 182 + 282 + + + 620 + 292 + + + + + externalDownloadButton + toggled(bool) + externalDownloadPath + setEnabled(bool) + + + 161 + 315 + + + 388 + 315 + + + + + externalDownloadButton + toggled(bool) + externalDownloadBrowse + setEnabled(bool) + + + 161 + 315 + + + 554 + 315 + + + + + externalDownloadButton + toggled(bool) + downloadAsk + setDisabled(bool) + + + 102 + 311 + + + 105 + 252 + + + + + externalDownloadButton + toggled(bool) + downloadsLocation + setDisabled(bool) + + + 198 + 315 + + + 386 + 279 + + + + + externalDownloadButton + toggled(bool) + downloadDestination + setDisabled(bool) + + + 170 + 313 + + + 169 + 285 + + + + + externalDownloadButton + toggled(bool) + downloadDirectoryButton + setDisabled(bool) + + + 194 + 311 - - 348 - 223 + + 569 + 276 diff --git a/src/sourcehighlighter.cpp b/src/sourcehighlighter.cpp new file mode 100644 index 00000000..d61ffa07 --- /dev/null +++ b/src/sourcehighlighter.cpp @@ -0,0 +1,173 @@ +/* + * Copyright 2008 Christian Franke + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "sourcehighlighter.h" + +#include + +SourceHighlighter::SourceHighlighter(QTextDocument *document) + : QSyntaxHighlighter(document) +{ + QPalette palette; + QColor foreground = palette.text().color(); + QColor background = palette.base().color(); + + QTextCharFormat entityFormat; + QColor entityColor; + entityColor.setRed((foreground.red() + background.red()) / 2); + entityColor.setGreen( + (foreground.green() + background.green()) / 2); + entityColor.setBlue( + (foreground.blue() + background.blue()) / 2); + if (abs(entityColor.red() - background.red()) > 80) + entityColor.setRed(foreground.red()); + else if (abs(entityColor.green()-background.green()) > 80) + entityColor.setGreen(foreground.green()); + else entityColor.setBlue(foreground.blue()); + entityFormat.setForeground(entityColor); + entityFormat.setFontWeight(QFont::Normal); + setFormatFor(Entity, entityFormat); + + QTextCharFormat tagFormat; + QColor tagColor; + tagColor.setRed(foreground.red() + (background.red() - foreground.red()) / 4); + tagColor.setGreen( + foreground.green() + (background.green() - foreground.green()) / 4); + tagColor.setBlue( + foreground.blue() + (background.blue() - foreground.blue()) / 4); + tagFormat.setForeground(tagColor); + tagFormat.setFontWeight(QFont::Bold); + setFormatFor(Tag, tagFormat); + + QTextCharFormat commentFormat; + QColor commentColor; + commentColor.setRed(background.red() + (foreground.red() - background.red()) / 3); + commentColor.setGreen( + background.green() + (foreground.green() - background.green()) / 3); + commentColor.setBlue( + background.blue() + (foreground.blue() - background.blue()) / 3); + commentFormat.setForeground(commentColor); + commentFormat.setFontWeight(QFont::Normal); + setFormatFor(Comment, commentFormat); + + QTextCharFormat attributeFormat; + QColor attributeColor; + attributeColor.setRed((foreground.red() + background.red()) / 2); + attributeColor.setGreen( + (foreground.green() + background.green()) / 2); + attributeColor.setBlue( + (foreground.blue() + background.blue()) / 2); + if (abs(attributeColor.red() - background.red()) > 80) + attributeColor.setRed(background.red()); + else if (abs(attributeColor.green() - background.green()) > 80) + attributeColor.setGreen(background.green()); + else attributeColor.setBlue(background.blue()); + attributeFormat.setForeground(attributeColor); + attributeFormat.setFontWeight(QFont::Normal); + setFormatFor(Attribute, attributeFormat); +} + +QTextCharFormat SourceHighlighter::getFormatFor(Construct construct) +{ + return formats[construct]; +} + +void SourceHighlighter::setFormatFor(Construct construct, + QTextCharFormat &format) +{ + formats[construct] = format; +} + +void SourceHighlighter::highlightBlock(const QString &text) +{ + int state = previousBlockState(); + int len = text.length(); + int start = 0; + int pos = 0; + QRegExp regex; + + while (pos >= 0 && pos < len && len > 0) { + switch (state) { + default: + case Normal: + regex.setPattern(QLatin1String("[<&]")); + pos = regex.indexIn(text, pos); + if (pos >= 0) { + if (text.at(pos) == QLatin1Char('<')) { + start = pos; + if (text.mid(pos, 4) == QLatin1String("")); + pos = regex.indexIn(text, pos); + if (pos >= 0) { + state = Normal; + pos += 3; + setFormat(start, pos - start, formats[Comment]); + ++pos; + } else { + setFormat(start, len - start, formats[Comment]); + } + break; + case InTag: + regex.setPattern(QLatin1String("[>\"]")); + pos = regex.indexIn(text, pos); + if (pos >= 0) { + if (text.at(pos) == QLatin1Char('>')) { + state = Normal; + ++pos; + setFormat(start, pos - start, formats[Tag]); + } else if (text.at(pos) == QLatin1Char('"')) { + setFormat(start, pos - start, formats[Tag]); + start = pos; + state = InAttribute; + ++pos; + } + } else { + setFormat(start, len-start, formats[Tag]); + } + break; + case InAttribute: + regex.setPattern(QLatin1String("\"")); + pos = regex.indexIn(text, pos); + if (pos >= 0) { + setFormat(start, pos - start, formats[Attribute]); + state = InTag; + start = ++pos; + } else { + setFormat(start, len - start, formats[Attribute]); + } + break; + } + } + setCurrentBlockState(state); +} diff --git a/src/sourcehighlighter.h b/src/sourcehighlighter.h new file mode 100644 index 00000000..d6783e68 --- /dev/null +++ b/src/sourcehighlighter.h @@ -0,0 +1,55 @@ +/* + * Copyright 2008 Christian Franke + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef SOURCEHIGHLIGHTER_H +#define SOURCEHIGHLIGHTER_H + +#include + +class SourceHighlighter : public QSyntaxHighlighter +{ + Q_OBJECT + +public: + enum Construct { + Entity, + Tag, + Comment, + Attribute, + LastConstruct = Attribute + }; + SourceHighlighter(QTextDocument *document); + + QTextCharFormat getFormatFor(Construct construct); + void setFormatFor(Construct construct, QTextCharFormat &format); + +protected: + enum State { + Normal = -1, + InComment, + InTag, + InAttribute + }; + void highlightBlock(const QString &text); + +private: + QTextCharFormat formats[LastConstruct + 1]; +}; + +#endif diff --git a/src/sourceviewer.cpp b/src/sourceviewer.cpp new file mode 100644 index 00000000..ff8541d0 --- /dev/null +++ b/src/sourceviewer.cpp @@ -0,0 +1,107 @@ +/* + * Copyright 2008 Christian Franke + * Copyright 2008-2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "sourceviewer.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "browserapplication.h" +#include "networkaccessmanager.h" +#include "plaintexteditsearch.h" +#include "sourcehighlighter.h" + +SourceViewer::SourceViewer(const QString &source, const QString &title, + const QUrl &url, QWidget *parent) + : QDialog(parent) + , m_edit(new QPlainTextEdit(tr("Loading..."), this)) + , m_highlighter(new SourceHighlighter(m_edit->document())) + , m_plainTextEditSearch(new PlainTextEditSearch(m_edit, this)) + , m_layout(new QVBoxLayout(this)) + , m_menuBar(new QMenuBar(this)) + , m_editMenu(new QMenu(tr("&Edit"), m_menuBar)) + , m_findAction(new QAction(tr("&Find"), m_editMenu)) + , m_source(source) +{ + setWindowTitle(tr("Source of Page %1").arg(title)); + + QSettings settings; + settings.beginGroup(QLatin1String("SourceViewer")); + QSize size = settings.value(QLatin1String("size"), QSize(640, 480)).toSize(); + resize(size); + + m_edit->setLineWrapMode(QPlainTextEdit::WidgetWidth); + m_edit->setReadOnly(true); + QFont font = m_edit->font(); + font.setFamily(QLatin1String("Monospace")); + m_edit->setFont(font); + m_edit->setLineWidth(0); + m_edit->setFrameShape(QFrame::NoFrame); + + m_menuBar->addMenu(m_editMenu); + m_editMenu->addAction(m_findAction); + m_findAction->setShortcuts(QKeySequence::Find); + connect(m_findAction, SIGNAL(triggered()), + m_plainTextEditSearch, SLOT(showFind())); + + m_layout->setSpacing(0); + m_layout->setContentsMargins(0, 0, 0, 0); + m_layout->addWidget(m_menuBar); + m_layout->addWidget(m_plainTextEditSearch); + m_layout->addWidget(m_edit); + setLayout(m_layout); + + QNetworkRequest request(url); + request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); + m_reply = BrowserApplication::networkAccessManager()->get(request); + connect(m_reply, SIGNAL(finished()), this, SLOT(loadingFinished())); + m_reply->setParent(this); +} + +SourceViewer::~SourceViewer() +{ + QSettings settings; + settings.beginGroup(QLatin1String("SourceViewer")); + settings.setValue(QLatin1String("size"), size()); +} + +void SourceViewer::loadingFinished() +{ + QWebPage page; + QByteArray response = m_reply->readAll(); + page.mainFrame()->setContent(response, QString(), m_reply->request().url()); + + /* If original request was POST or a different problem is there, fall + back to modified version of QWebFrame.toHtml() */ + if (page.mainFrame()->toHtml() != m_source) + m_edit->setPlainText(m_source); + else + m_edit->setPlainText(QLatin1String(response)); + + m_reply->close(); +} diff --git a/src/sourceviewer.h b/src/sourceviewer.h new file mode 100644 index 00000000..a4b654a3 --- /dev/null +++ b/src/sourceviewer.h @@ -0,0 +1,59 @@ +/* + * Copyright 2008 Christian Franke + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef SOURCEVIEWER_H +#define SOURCEVIEWER_H + +#include + +class QVBoxLayout; +class SourceHighlighter; +class PlainTextEditSearch; +class QPlainTextEdit; +class QMenuBar; +class QMenu; +class QUrl; +class QAction; +class QNetworkReply; +class SourceViewer : public QDialog +{ + Q_OBJECT + +public: + SourceViewer(const QString &source, const QString &title, + const QUrl &url, QWidget *parent = 0); + ~SourceViewer(); + +private: + QPlainTextEdit *m_edit; + SourceHighlighter *m_highlighter; + PlainTextEditSearch *m_plainTextEditSearch; + QVBoxLayout *m_layout; + QMenuBar *m_menuBar; + QMenu *m_editMenu; + QAction *m_findAction; + QMenu *m_viewMenu; + QNetworkReply *m_reply; + QString m_source; + +private slots: + void loadingFinished(); +}; + +#endif diff --git a/src/squeezelabel.cpp b/src/squeezelabel.cpp deleted file mode 100644 index e2aad27a..00000000 --- a/src/squeezelabel.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "squeezelabel.h" - -SqueezeLabel::SqueezeLabel(QWidget *parent) : QLabel(parent) -{ -} - -void SqueezeLabel::paintEvent(QPaintEvent *event) -{ - QFontMetrics fm = fontMetrics(); - if (fm.width(text()) > contentsRect().width()) { - QString elided = fm.elidedText(text(), Qt::ElideMiddle, width()); - QString oldText = text(); - setText(elided); - QLabel::paintEvent(event); - setText(oldText); - } else { - QLabel::paintEvent(event); - } -} - diff --git a/src/src.pri b/src/src.pri index 4ca1e450..7c1a0e34 100644 --- a/src/src.pri +++ b/src/src.pri @@ -2,91 +2,108 @@ CONFIG += qt warn_on contains(QT_BUILD_PARTS, tools): CONFIG += uitools else : DEFINES += QT_NO_UITOOLS -win32 : Debug : CONFIG += console +win32|os2 : Debug : CONFIG += console INCLUDEPATH += $$PWD DEPENDPATH += $$PWD -RCC_DIR = .rcc -UI_DIR = .ui -MOC_DIR = .moc -OBJECTS_DIR = .obj - QT += webkit network -GITVERSION=$$system(git log -n1 --pretty=format:%h) -GITCHANGENUMBER=$$system(git log --pretty=format:%h | wc -l) -DEFINES += GITVERSION=\"\\\"$$GITVERSION\\\"\" -DEFINES += GITCHANGENUMBER=\"\\\"$$GITCHANGENUMBER\\\"\" +# Share object files for faster compiling +RCC_DIR = $$PWD/.rcc +UI_DIR = $$PWD/.ui +MOC_DIR = $$PWD/.moc +OBJECTS_DIR = $$PWD/.obj + +exists(../.git/HEAD) { + GITVERSION=$$system(git log -n1 --pretty=format:%h) + !isEmpty(GITVERSION) { + GITCHANGENUMBER=$$system(git log --pretty=format:%h | wc -l) + DEFINES += GITVERSION=\"\\\"$$GITVERSION\\\"\" + DEFINES += GITCHANGENUMBER=\"\\\"$$GITCHANGENUMBER\\\"\" + } +} FORMS += \ aboutdialog.ui \ - addbookmarkdialog.ui \ - bookmarks.ui \ - cookies.ui \ - cookiesexceptions.ui \ + autofilldialog.ui \ + acceptlanguagedialog.ui \ downloaditem.ui \ downloads.ui \ - history.ui \ - passworddialog.ui \ - proxy.ui \ searchbanner.ui \ settings.ui HEADERS += \ aboutdialog.h \ + acceptlanguagedialog.h \ autosaver.h \ - bookmarks.h \ + autofilldialog.h \ + autofillmanager.h \ browserapplication.h \ browsermainwindow.h \ clearprivatedata.h \ - cookiejar.h \ + clearbutton.h \ downloadmanager.h \ - edittableview.h \ - edittreeview.h \ - history.h \ modelmenu.h \ - networkaccessmanager.h \ + modeltoolbar.h \ + plaintexteditsearch.h \ + searchbar.h \ + searchbutton.h \ searchlineedit.h \ settings.h \ - squeezelabel.h \ + sourcehighlighter.h \ + sourceviewer.h \ tabbar.h \ tabwidget.h \ toolbarsearch.h \ - urllineedit.h \ webactionmapper.h \ + webpage.h \ webview.h \ - webviewsearch.h \ - xbel.h + webviewsearch.h SOURCES += \ aboutdialog.cpp \ + acceptlanguagedialog.cpp \ autosaver.cpp \ - bookmarks.cpp \ + autofilldialog.cpp \ + autofillmanager.cpp \ browserapplication.cpp \ browsermainwindow.cpp \ clearprivatedata.cpp \ - cookiejar.cpp \ + clearbutton.cpp \ downloadmanager.cpp \ - edittableview.cpp \ - edittreeview.cpp \ - history.cpp \ modelmenu.cpp \ - networkaccessmanager.cpp \ + modeltoolbar.cpp \ + plaintexteditsearch.cpp \ + searchbar.cpp \ + searchbutton.cpp \ searchlineedit.cpp \ settings.cpp \ - squeezelabel.cpp \ + sourcehighlighter.cpp \ + sourceviewer.cpp \ tabbar.cpp \ tabwidget.cpp \ toolbarsearch.cpp \ - urllineedit.cpp \ webactionmapper.cpp \ + webpage.cpp \ webview.cpp \ - webviewsearch.cpp \ - xbel.cpp - -RESOURCES += data/data.qrc \ - htmls/htmls.qrc + webviewsearch.cpp + +include(adblock/adblock.pri) +include(bookmarks/bookmarks.pri) +include(history/history.pri) +include(locationbar/locationbar.pri) +include(network/network.pri) +include(opensearch/opensearch.pri) +include(qwebplugins/qwebplugins.pri) +include(utils/utils.pri) +include(useragent/useragent.pri) + +RESOURCES += \ + $$PWD/data/data.qrc \ + $$PWD/data/graphics/graphics.qrc \ + $$PWD/data/searchengines/searchengines.qrc \ + $$PWD/htmls/htmls.qrc DISTFILES += ../AUTHORS \ ../ChangeLog \ @@ -95,7 +112,12 @@ DISTFILES += ../AUTHORS \ ../README win32 { - RC_FILE = browser.rc + RC_FILE = $$PWD/browser.rc + LIBS += -luser32 +} + +os2 { + RC_FILE = $$PWD/browser_os2.rc } mac { @@ -103,16 +125,13 @@ mac { QMAKE_INFO_PLIST = Info_mac.plist } -unix { - isEmpty(PREFIX){ - PREFIX = /usr/local - } +include(../webkittrunk.pri) - BINDIR = $$PREFIX/bin - DATADIR = $$PREFIX/share +unix { PKGDATADIR = $$DATADIR/arora - DEFINES += DATADIR=\\\"$$DATADIR\\\" PKGDATADIR=\\\"$$PKGDATADIR\\\" } -include(webkittrunk.pri) +win32 { + LIBS += -ladvapi32 +} diff --git a/src/src.pro b/src/src.pro index 63fcc0ff..dab73ffb 100644 --- a/src/src.pro +++ b/src/src.pro @@ -3,46 +3,63 @@ TEMPLATE = app TARGET = arora mac { TARGET = Arora + QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4 } +DEFINES += \ + QT_NO_CAST_FROM_ASCII \ + QT_NO_CAST_TO_ASCII \ + QT_STRICT_ITERATORS \ + +include(../install.pri) + include(src.pri) SOURCES += main.cpp DESTDIR = ../ -isEmpty(QMAKE_LRELEASE) { - win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe - else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease -} - -TRANSLATIONS += \ - locale/cs_CZ.ts \ - locale/de.ts \ - locale/en.ts \ - locale/es.ts \ - locale/fr.ts \ - locale/it.ts \ - locale/pl.ts \ - locale/pt_BR.ts \ - locale/ru.ts - -updateqm.input = TRANSLATIONS -updateqm.output = .qm/locale/${QMAKE_FILE_BASE}.qm -updateqm.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm .qm/locale/${QMAKE_FILE_BASE}.qm -updateqm.CONFIG += no_link -QMAKE_EXTRA_COMPILERS += updateqm - -PRE_TARGETDEPS += compiler_updateqm_make_all +include(locale/locale.pri) +!mac { unix { - INSTALLS += target translations desktop - - target.path = $$BINDIR + INSTALLS += translations desktop iconxpm iconsvg icon16 icon32 icon128 man man-compress translations.path = $$PKGDATADIR translations.files += .qm/locale desktop.path = $$DATADIR/applications desktop.files += arora.desktop + + iconxpm.path = $$DATADIR/pixmaps + iconxpm.files += data/arora.xpm + + iconsvg.path = $$DATADIR/icons/hicolor/scalable/apps + iconsvg.files += data/arora.svg + + icon16.path = $$DATADIR/icons/hicolor/16x16/apps + icon16.files += data/16x16/arora.png + + icon32.path = $$DATADIR/icons/hicolor/32x32/apps + icon32.files += data/32x32/arora.png + + icon128.path = $$DATADIR/icons/hicolor/128x128/apps + icon128.files += data/128x128/arora.png + + man.path = $$DATADIR/man/man1 + man.files += data/arora.1 + + man-compress.path = $$DATADIR/man/man1 + man-compress.extra = "" "gzip -9 -f \$(INSTALL_ROOT)/$$DATADIR/man/man1/arora.1" "" + man-compress.depends = install_man + + GNOME_DEFAULT_APPS_PATH = $$system(pkg-config --variable=defappsdir gnome-default-applications) + + !isEmpty(GNOME_DEFAULT_APPS_PATH) { + INSTALLS += gnome-default-app + + gnome-default-app.path = $$GNOME_DEFAULT_APPS_PATH + gnome-default-app.files = data/arora.xml + } +} } diff --git a/src/tabbar.cpp b/src/tabbar.cpp index bd898c13..b684be1a 100644 --- a/src/tabbar.cpp +++ b/src/tabbar.cpp @@ -62,6 +62,8 @@ #include "tabbar.h" +#include "tabwidget.h" + #include #include #include @@ -96,8 +98,8 @@ TabBar::TabBar(QWidget *parent) this, SLOT(contextMenuRequested(const QPoint &))); QString alt = QLatin1String("Ctrl+%1"); - for (int i = 0; i < 10; ++i) { - int key = i == 9 ? 0 : i + 1; + for (int i = 0; i < 9; ++i) { + int key = i + 1; TabShortcut *tabShortCut = new TabShortcut(i, alt.arg(key), this); connect(tabShortCut, SIGNAL(activated()), this, SLOT(selectTabAction())); } @@ -106,6 +108,8 @@ TabBar::TabBar(QWidget *parent) updateViewToolBarAction(); connect(m_viewTabBarAction, SIGNAL(triggered()), this, SLOT(viewTabBar())); + + setMovable(true); } bool TabBar::showTabBarWhenOneTab() const @@ -124,14 +128,12 @@ QAction *TabBar::viewTabBarAction() const return m_viewTabBarAction; } -#if QT_VERSION >= 0x040500 QTabBar::ButtonPosition TabBar::freeSide() { QTabBar::ButtonPosition side = (QTabBar::ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, this); side = (side == QTabBar::LeftSide) ? QTabBar::RightSide : QTabBar::LeftSide; return side; } -#endif void TabBar::updateViewToolBarAction() { @@ -156,7 +158,11 @@ void TabBar::selectTabAction() void TabBar::contextMenuRequested(const QPoint &position) { QMenu menu; - menu.addAction(tr("New &Tab"), this, SIGNAL(newTab()), QKeySequence::AddTab); + TabWidget *tabWidget = qobject_cast(parentWidget()); + if (!tabWidget) + return; + + menu.addAction(tabWidget->newTabAction()); int index = tabAt(position); if (-1 != index) { QAction *action = menu.addAction(tr("Duplicate Tab"), @@ -182,6 +188,8 @@ void TabBar::contextMenuRequested(const QPoint &position) menu.addSeparator(); } menu.addAction(tr("Reload All Tabs"), this, SIGNAL(reloadAllTabs())); + menu.addSeparator(); + menu.addAction(tabWidget->bookmarkTabsAction()); menu.exec(QCursor::pos()); } @@ -211,9 +219,8 @@ void TabBar::closeOtherTabs() void TabBar::mouseDoubleClickEvent(QMouseEvent *event) { - if (!childAt(event->pos()) - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (y() + height())) { + if (event->button() == Qt::LeftButton + && tabAt(event->pos()) == -1) { emit newTab(); return; } @@ -222,47 +229,48 @@ void TabBar::mouseDoubleClickEvent(QMouseEvent *event) void TabBar::mouseReleaseEvent(QMouseEvent *event) { - if (event->button() == Qt::MidButton - // Remove the line below when QTabWidget does not have a one pixel frame - && event->pos().y() < (y() + height())) { + if (event->button() == Qt::MidButton) { int index = tabAt(event->pos()); - if (index == -1) { + if (index != -1) { + emit closeTab(index); + return; + } else { QUrl url(QApplication::clipboard()->text(QClipboard::Selection)); - if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { + if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) emit loadUrl(url, TabWidget::NewTab); - } } } + QTabBar::mouseReleaseEvent(event); } void TabBar::mousePressEvent(QMouseEvent *event) { - if (event->button() == Qt::LeftButton) { + if (event->button() == Qt::LeftButton) m_dragStartPos = event->pos(); - } else if (event->button() == Qt::MidButton) { - int index = tabAt(event->pos()); - if (index != -1) - emit closeTab(index); - } QTabBar::mousePressEvent(event); } void TabBar::mouseMoveEvent(QMouseEvent *event) { - if (event->buttons() == Qt::LeftButton - && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance()) { - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - QList urls; - int index = tabAt(event->pos()); - QUrl url = tabData(index).toUrl(); - urls.append(url); - mimeData->setUrls(urls); - mimeData->setText(tabText(index)); - mimeData->setData(QLatin1String("action"), "tab-reordering"); - drag->setMimeData(mimeData); - drag->exec(); + if (event->buttons() == Qt::LeftButton) { + int diffX = event->pos().x() - m_dragStartPos.x(); + int diffY = event->pos().y() - m_dragStartPos.y(); + if ((event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance() + && diffX < 3 && diffX > -3 + && diffY < -10) { + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + QList urls; + int index = tabAt(event->pos()); + QUrl url = tabData(index).toUrl(); + urls.append(url); + mimeData->setUrls(urls); + mimeData->setText(tabText(index)); + mimeData->setData(QLatin1String("action"), "tab-reordering"); + drag->setMimeData(mimeData); + drag->exec(); + } } QTabBar::mouseMoveEvent(event); } @@ -270,29 +278,40 @@ void TabBar::mouseMoveEvent(QMouseEvent *event) void TabBar::dragEnterEvent(QDragEnterEvent *event) { const QMimeData *mimeData = event->mimeData(); - QStringList formats = mimeData->formats(); - if (formats.contains(QLatin1String("action")) - && (mimeData->data(QLatin1String("action")) == "tab-reordering")) { + if (mimeData->hasUrls() || mimeData->hasText()) event->acceptProposedAction(); - } + QTabBar::dragEnterEvent(event); } void TabBar::dropEvent(QDropEvent *event) { - int fromIndex = tabAt(m_dragStartPos); - int toIndex = tabAt(event->pos()); - if (fromIndex != toIndex) { - emit tabMoveRequested(fromIndex, toIndex); + const QMimeData *mimeData = event->mimeData(); + QUrl url; + if (mimeData->hasUrls()) + url = mimeData->urls().at(0); + else if (mimeData->hasText()) + url = QUrl::fromEncoded(mimeData->text().toUtf8()); + + if (!url.isEmpty() && url.isValid()) { event->acceptProposedAction(); + int index = tabAt(event->pos()); + if (-1 != index) { + setCurrentIndex(index); + emit loadUrl(url, TabWidget::CurrentTab); + } else { + emit loadUrl(url, TabWidget::NewSelectedTab); + } } + QTabBar::dropEvent(event); } QSize TabBar::tabSizeHint(int index) const { QSize sizeHint = QTabBar::tabSizeHint(index); - return sizeHint.boundedTo(QSize(250, sizeHint.height())); + QFontMetrics fm = fontMetrics(); + return sizeHint.boundedTo(QSize(fm.width(QLatin1Char('M')) * 18, sizeHint.height())); } void TabBar::reloadTab() @@ -318,7 +337,9 @@ void TabBar::tabRemoved(int position) void TabBar::updateVisibility() { setVisible((count()) > 1 || m_showTabBarWhenOneTab); - m_viewTabBarAction->setEnabled(count() == 1); + bool enabled = (count() == 1); + if (m_viewTabBarAction->isEnabled() != enabled) + m_viewTabBarAction->setEnabled(enabled); updateViewToolBarAction(); } diff --git a/src/tabbar.h b/src/tabbar.h index a76ca61e..3fd8f0d3 100644 --- a/src/tabbar.h +++ b/src/tabbar.h @@ -65,7 +65,7 @@ #include -#include +#include "tabwidget.h" /* Tab bar with a few more features such as a context menu and shortcuts @@ -81,8 +81,7 @@ class TabBar : public QTabBar void closeOtherTabs(int index); void reloadTab(int index); void reloadAllTabs(); - void tabMoveRequested(int fromIndex, int toIndex); - void loadUrl(const QUrl &url, TabWidget::Tab type); + void loadUrl(const QUrl &url, TabWidget::OpenUrlIn tab); public: TabBar(QWidget *parent = 0); @@ -90,15 +89,13 @@ class TabBar : public QTabBar bool showTabBarWhenOneTab() const; void setShowTabBarWhenOneTab(bool enabled); QAction *viewTabBarAction() const; -#if QT_VERSION >= 0x040500 QTabBar::ButtonPosition freeSide(); -#endif protected: void mouseDoubleClickEvent(QMouseEvent *event); void mouseReleaseEvent(QMouseEvent *event); - void mousePressEvent(QMouseEvent* event); - void mouseMoveEvent(QMouseEvent* event); + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); void dragEnterEvent(QDragEnterEvent *event); void dropEvent(QDropEvent *event); QSize tabSizeHint(int index) const; @@ -120,7 +117,6 @@ private slots: friend class TabWidget; QPoint m_dragStartPos; - int m_dragCurrentIndex; QAction *m_viewTabBarAction; bool m_showTabBarWhenOneTab; }; diff --git a/src/tabwidget.cpp b/src/tabwidget.cpp index 7182b8f1..7e5b0bf8 100644 --- a/src/tabwidget.cpp +++ b/src/tabwidget.cpp @@ -7,7 +7,7 @@ * (at your option) any later version. * * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of + * but WITHOUT ANY WARRANTY; without even the iQ_WS_X11mplied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * @@ -62,16 +62,27 @@ #include "tabwidget.h" +#include "addbookmarkdialog.h" +#include "bookmarknode.h" +#include "bookmarksmanager.h" +#include "bookmarksmodel.h" #include "browserapplication.h" #include "browsermainwindow.h" #include "history.h" +#include "historycompleter.h" +#include "historymanager.h" +#include "locationbar.h" +#include "opensearchengine.h" +#include "opensearchmanager.h" #include "tabbar.h" -#include "urllineedit.h" +#include "toolbarsearch.h" #include "webactionmapper.h" +#include "webpage.h" #include "webview.h" #include "webviewsearch.h" #include +#include #include #include #include @@ -81,118 +92,121 @@ #include #include #include +#include #include +//#define USERMODIFIEDBEHAVIOR_DEBUG + TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) , m_recentlyClosedTabsAction(0) , m_newTabAction(0) , m_closeTabAction(0) + , m_bookmarkTabsAction(0) , m_nextTabAction(0) , m_previousTabAction(0) , m_recentlyClosedTabsMenu(0) , m_lineEditCompleter(0) - , m_lineEdits(0) + , m_locationBars(0) , m_tabBar(new TabBar(this)) + , addTabButton(0) + , closeTabButton(0) { -#if QT_VERSION >= 0x040500 - setDocumentMode(true); -#endif setElideMode(Qt::ElideRight); - new QShortcut(QKeySequence("Ctrl+Shift+T"), this, SLOT(openLastTab())); + new QShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_T), this, SLOT(openLastTab())); + new QShortcut(QKeySequence::Undo, this, SLOT(openLastTab())); - connect(m_tabBar, SIGNAL(loadUrl(const QUrl&, TabWidget::Tab)), - this, SLOT(loadUrl(const QUrl&, TabWidget::Tab))); + connect(m_tabBar, SIGNAL(loadUrl(const QUrl&, TabWidget::OpenUrlIn)), + this, SLOT(loadUrl(const QUrl&, TabWidget::OpenUrlIn))); connect(m_tabBar, SIGNAL(newTab()), this, SLOT(newTab())); connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(closeTab(int))); connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(cloneTab(int))); connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(closeOtherTabs(int))); connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs())); - connect(m_tabBar, SIGNAL(tabMoveRequested(int, int)), this, SLOT(moveTab(int, int))); setTabBar(m_tabBar); + setDocumentMode(true); + connect(m_tabBar, SIGNAL(tabMoved(int, int)), + this, SLOT(moveTab(int, int))); // Actions - m_newTabAction = new QAction(tr("New &Tab"), this); + m_newTabAction = new QAction(this); m_newTabAction->setShortcuts(QKeySequence::AddTab); connect(m_newTabAction, SIGNAL(triggered()), this, SLOT(newTab())); - m_closeTabAction = new QAction(tr("&Close Tab"), this); + m_closeTabAction = new QAction(this); m_closeTabAction->setShortcuts(QKeySequence::Close); + m_closeTabAction->setIcon(QIcon(QLatin1String(":graphics/closetab.png"))); +#if QT_VERSION < 0x040600 || (QT_VERSION >= 0x040600 && !defined(Q_WS_X11)) + m_closeTabAction->setIconVisibleInMenu(false); +#endif connect(m_closeTabAction, SIGNAL(triggered()), this, SLOT(closeTab())); -#if QT_VERSION < 0x040500 - m_newTabAction->setIcon(QIcon(QLatin1String(":addtab.png"))); - m_newTabAction->setIconVisibleInMenu(false); + m_bookmarkTabsAction = new QAction(this); + connect(m_bookmarkTabsAction, SIGNAL(triggered()), this, SLOT(bookmarkTabs())); - m_closeTabAction->setIcon(QIcon(QLatin1String(":closetab.png"))); - m_closeTabAction->setIconVisibleInMenu(false); + m_newTabAction->setIcon(QIcon(QLatin1String(":graphics/addtab.png"))); +#if QT_VERSION < 0x040600 || (QT_VERSION >= 0x040600 && !defined(Q_WS_X11)) + m_newTabAction->setIconVisibleInMenu(false); #endif - m_nextTabAction = new QAction(tr("Show Next Tab"), this); - QList shortcuts; - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketRight)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Tab)); - m_nextTabAction->setShortcuts(shortcuts); + m_nextTabAction = new QAction(this); connect(m_nextTabAction, SIGNAL(triggered()), this, SLOT(nextTab())); - m_previousTabAction = new QAction(tr("Show Previous Tab"), this); - shortcuts.clear(); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BracketLeft)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater)); - shortcuts.append(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Tab)); - m_previousTabAction->setShortcuts(shortcuts); + m_previousTabAction = new QAction(this); connect(m_previousTabAction, SIGNAL(triggered()), this, SLOT(previousTab())); +#if QT_VERSION >= 0x040600 && defined(Q_WS_X11) + m_previousTabAction->setIcon(QIcon::fromTheme(QLatin1String("go-previous"))); + m_nextTabAction->setIcon(QIcon::fromTheme(QLatin1String("go-next"))); +#endif m_recentlyClosedTabsMenu = new QMenu(this); connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentTabsMenu())); connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)), this, SLOT(aboutToShowRecentTriggeredAction(QAction *))); - m_recentlyClosedTabsAction = new QAction(tr("Recently Closed Tabs"), this); + m_recentlyClosedTabsAction = new QAction(this); m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu); m_recentlyClosedTabsAction->setEnabled(false); -#if QT_VERSION >= 0x040500 - m_tabBar->setTabsClosable(true); - connect(m_tabBar, SIGNAL(tabCloseRequested(int)), - this, SLOT(closeTab(int))); - m_tabBar->setSelectionBehaviorOnRemove(QTabBar::SelectPreviousTab); -#else - // corner buttons - QToolButton *addTabButton = new QToolButton(this); +#ifndef Q_WS_MAC // can't seem to figure out the background color :( + addTabButton = new QToolButton(this); addTabButton->setDefaultAction(m_newTabAction); addTabButton->setAutoRaise(true); addTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); - setCornerWidget(addTabButton, Qt::TopLeftCorner); - - QToolButton *closeTabButton = new QToolButton(this); - closeTabButton->setDefaultAction(m_closeTabAction); - closeTabButton->setAutoRaise(true); - closeTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); - setCornerWidget(closeTabButton, Qt::TopRightCorner); #endif + connect(m_tabBar, SIGNAL(tabCloseRequested(int)), + this, SLOT(closeTab(int))); connect(this, SIGNAL(currentChanged(int)), this, SLOT(currentChanged(int))); - m_lineEdits = new QStackedWidget(this); + m_locationBars = new QStackedWidget(this); + + connect(BrowserApplication::historyManager(), SIGNAL(historyCleared()), + this, SLOT(historyCleared())); + + // Initialize Actions' labels + retranslate(); + loadSettings(); +} + +void TabWidget::historyCleared() +{ + m_recentlyClosedTabs.clear(); + m_recentlyClosedTabsAction->setEnabled(false); } void TabWidget::clear() { // clear the recently closed tabs m_recentlyClosedTabs.clear(); + m_recentlyClosedTabsAction->setEnabled(false); // clear the line edit history - for (int i = 0; i < m_lineEdits->count(); ++i) { - QLineEdit *qLineEdit = lineEdit(i); + for (int i = 0; i < m_locationBars->count(); ++i) { + QLineEdit *qLineEdit = locationBar(i); qLineEdit->setText(qLineEdit->text()); webViewSearch(i)->clear(); } @@ -206,29 +220,16 @@ void TabWidget::reloadTab(int index) if (index < 0 || index >= count()) return; - QWidget *widget = this->widget(index); - if (WebView *tab = qobject_cast(widget)) + if (WebView *tab = webView(index)) { tab->reload(); + } } void TabWidget::moveTab(int fromIndex, int toIndex) { - disconnect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - - QWidget *tabWidget = widget(fromIndex); - QWidget *lineEdit = m_lineEdits->widget(fromIndex); - QIcon icon = tabIcon(fromIndex); - QString text = tabText(fromIndex); - QVariant data = m_tabBar->tabData(fromIndex); - removeTab(fromIndex); - m_lineEdits->removeWidget(lineEdit); - insertTab(toIndex, tabWidget, icon, text); - m_lineEdits->insertWidget(toIndex, lineEdit); - m_tabBar->setTabData(toIndex, data); - connect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - setCurrentIndex(toIndex); + QWidget *lineEdit = m_locationBars->widget(fromIndex); + m_locationBars->removeWidget(lineEdit); + m_locationBars->insertWidget(toIndex, lineEdit); } void TabWidget::addWebAction(QAction *action, QWebPage::WebAction webAction) @@ -244,9 +245,9 @@ void TabWidget::currentChanged(int index) if (!webView) return; - Q_ASSERT(m_lineEdits->count() == count()); + Q_ASSERT(m_locationBars->count() == count()); - WebView *oldWebView = this->webView(m_lineEdits->currentIndex()); + WebView *oldWebView = this->webView(m_locationBars->currentIndex()); if (oldWebView) { disconnect(oldWebView, SIGNAL(statusBarMessage(const QString&)), this, SIGNAL(showStatusBarMessage(const QString&))); @@ -268,13 +269,14 @@ void TabWidget::currentChanged(int index) mapper->updateCurrent(webView->page()); } emit setCurrentTitle(webView->title()); - m_lineEdits->setCurrentIndex(index); + m_locationBars->setCurrentIndex(index); emit loadProgress(webView->progress()); emit showStatusBarMessage(webView->lastStatusBarText()); - if (webView->url().isEmpty()) - m_lineEdits->currentWidget()->setFocus(); - else + if (webView->url().isEmpty() && webView->hasFocus()) { + m_locationBars->currentWidget()->setFocus(); + } else if (!webView->url().isEmpty()) { webView->setFocus(); + } } QAction *TabWidget::newTabAction() const @@ -287,6 +289,11 @@ QAction *TabWidget::closeTabAction() const return m_closeTabAction; } +QAction *TabWidget::bookmarkTabsAction() const +{ + return m_bookmarkTabsAction; +} + QAction *TabWidget::recentlyClosedTabsAction() const { return m_recentlyClosedTabsAction; @@ -302,14 +309,14 @@ QAction *TabWidget::previousTabAction() const return m_previousTabAction; } -QWidget *TabWidget::lineEditStack() const +QWidget *TabWidget::locationBarStack() const { - return m_lineEdits; + return m_locationBars; } -QLineEdit *TabWidget::currentLineEdit() const +QLineEdit *TabWidget::currentLocationBar() const { - return lineEdit(m_lineEdits->currentIndex()); + return locationBar(m_locationBars->currentIndex()); } WebView *TabWidget::currentWebView() const @@ -317,12 +324,9 @@ WebView *TabWidget::currentWebView() const return webView(currentIndex()); } -QLineEdit *TabWidget::lineEdit(int index) const +QLineEdit *TabWidget::locationBar(int index) const { - UrlLineEdit *urlLineEdit = qobject_cast(m_lineEdits->widget(index)); - if (urlLineEdit) - return urlLineEdit->lineEdit(); - return 0; + return qobject_cast(m_locationBars->widget(index)); } WebView *TabWidget::webView(int index) const @@ -330,25 +334,12 @@ WebView *TabWidget::webView(int index) const QWidget *widget = this->widget(index); if (WebViewWithSearch *webViewWithSearch = qobject_cast(widget)) { return webViewWithSearch->m_webView; - } else { - // optimization to delay creating the first webview - if (count() == 1) { - TabWidget *that = const_cast(this); - that->setUpdatesEnabled(false); - that->newTab(); - that->closeTab(0); - that->setUpdatesEnabled(true); - return currentWebView(); - } } return 0; } WebViewSearch *TabWidget::webViewSearch(int index) const { - // so the optimization can be performed - webView(index); - QWidget *widget = this->widget(index); if (WebViewWithSearch *webViewWithSearch = qobject_cast(widget)) { return webViewWithSearch->m_webViewSearch; @@ -375,78 +366,67 @@ void TabWidget::newTab() WebView *TabWidget::makeNewTab(bool makeCurrent) { - if (!makeCurrent) { - QSettings settings; - settings.beginGroup(QLatin1String("tabs")); - makeCurrent = settings.value(QLatin1String("selectNewTabs"), false).toBool(); - } - // line edit - UrlLineEdit *urlLineEdit = new UrlLineEdit; - QLineEdit *lineEdit = urlLineEdit->lineEdit(); - if (!m_lineEditCompleter && count() > 0) { + LocationBar *locationBar = new LocationBar; + if (!m_lineEditCompleter) { HistoryCompletionModel *completionModel = new HistoryCompletionModel(this); completionModel->setSourceModel(BrowserApplication::historyManager()->historyFilterModel()); - m_lineEditCompleter = new QCompleter(completionModel, this); + m_lineEditCompleter = new HistoryCompleter(completionModel, this); + connect(m_lineEditCompleter, SIGNAL(activated(const QString &)), + this, SLOT(loadString(const QString &))); // Should this be in Qt by default? QAbstractItemView *popup = m_lineEditCompleter->popup(); QListView *listView = qobject_cast(popup); - if (listView) + if (listView) { + // Urls are always LeftToRight + listView->setLayoutDirection(Qt::LeftToRight); listView->setUniformItemSizes(true); + } } - lineEdit->setCompleter(m_lineEditCompleter); - connect(lineEdit, SIGNAL(returnPressed()), this, SLOT(lineEditReturnPressed())); - m_lineEdits->addWidget(urlLineEdit); - m_lineEdits->setSizePolicy(lineEdit->sizePolicy()); - - // optimization to delay creating the more expensive WebView, history, etc - if (count() == 0) { - QWidget *emptyWidget = new QWidget; - QPalette p = emptyWidget->palette(); - p.setColor(QPalette::Window, palette().color(QPalette::Base)); - emptyWidget->setPalette(p); - emptyWidget->setAutoFillBackground(true); - disconnect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - addTab(emptyWidget, tr("(Untitled)")); - connect(this, SIGNAL(currentChanged(int)), - this, SLOT(currentChanged(int))); - return 0; - } + locationBar->setCompleter(m_lineEditCompleter); + connect(locationBar, SIGNAL(returnPressed()), this, SLOT(lineEditReturnPressed())); + m_locationBars->addWidget(locationBar); + m_locationBars->setSizePolicy(locationBar->sizePolicy()); + +#ifndef AUTOTESTS + QWidget::setTabOrder(locationBar, qFindChild(BrowserMainWindow::parentWindow(this))); +#endif // webview WebView *webView = new WebView; - urlLineEdit->setWebView(webView); + locationBar->setWebView(webView); connect(webView, SIGNAL(loadStarted()), this, SLOT(webViewLoadStarted())); + connect(webView, SIGNAL(loadProgress(int)), + this, SLOT(webViewLoadProgress(int))); connect(webView, SIGNAL(loadFinished(bool)), - this, SLOT(webViewLoadFinished())); + this, SLOT(webViewLoadFinished(bool))); connect(webView, SIGNAL(iconChanged()), this, SLOT(webViewIconChanged())); connect(webView, SIGNAL(titleChanged(const QString &)), this, SLOT(webViewTitleChanged(const QString &))); connect(webView, SIGNAL(urlChanged(const QUrl &)), this, SLOT(webViewUrlChanged(const QUrl &))); + connect(webView, SIGNAL(search(const QUrl&, TabWidget::OpenUrlIn)), + this, SLOT(loadUrl(const QUrl&, TabWidget::OpenUrlIn))); connect(webView->page(), SIGNAL(windowCloseRequested()), this, SLOT(windowCloseRequested())); - connect(webView->page(), SIGNAL(geometryChangeRequested(const QRect &)), - this, SIGNAL(geometryChangeRequested(const QRect &))); connect(webView->page(), SIGNAL(printRequested(QWebFrame *)), this, SIGNAL(printRequested(QWebFrame *))); + connect(webView->page(), SIGNAL(geometryChangeRequested(const QRect &)), + this, SLOT(geometryChangeRequestedCheck(const QRect &))); connect(webView->page(), SIGNAL(menuBarVisibilityChangeRequested(bool)), - this, SIGNAL(menuBarVisibilityChangeRequested(bool))); + this, SLOT(menuBarVisibilityChangeRequestedCheck(bool))); connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)), - this, SIGNAL(statusBarVisibilityChangeRequested(bool))); + this, SLOT(statusBarVisibilityChangeRequestedCheck(bool))); connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)), - this, SIGNAL(toolBarVisibilityChangeRequested(bool))); + this, SLOT(toolBarVisibilityChangeRequestedCheck(bool))); WebViewWithSearch *webViewWithSearch = new WebViewWithSearch(webView, this); - addTab(webViewWithSearch, tr("(Untitled)")); + addTab(webViewWithSearch, tr("Untitled")); if (makeCurrent) setCurrentWidget(webViewWithSearch); - QWidget::setTabOrder(this, urlLineEdit); - // webview actions for (int i = 0; i < m_actions.count(); ++i) { WebActionMapper *mapper = m_actions[i]; @@ -459,21 +439,73 @@ WebView *TabWidget::makeNewTab(bool makeCurrent) return webView; } +void TabWidget::geometryChangeRequestedCheck(const QRect &geometry) +{ + if (count() == 1) + emit geometryChangeRequested(geometry); +} + +void TabWidget::menuBarVisibilityChangeRequestedCheck(bool visible) +{ + if (count() == 1) + emit menuBarVisibilityChangeRequested(visible); +} + +void TabWidget::statusBarVisibilityChangeRequestedCheck(bool visible) +{ + if (count() == 1) + emit statusBarVisibilityChangeRequested(visible); +} + +void TabWidget::toolBarVisibilityChangeRequestedCheck(bool visible) +{ + if (count() == 1) + emit toolBarVisibilityChangeRequested(visible); +} + void TabWidget::reloadAllTabs() { for (int i = 0; i < count(); ++i) { - QWidget *tabWidget = widget(i); - if (WebView *tab = qobject_cast(tabWidget)) { + if (WebView *tab = webView(i)) { tab->reload(); } } } +void TabWidget::bookmarkTabs() +{ + AddBookmarkDialog dialog; + dialog.setFolder(true); + dialog.setTitle(tr("Saved Tabs")); + dialog.exec(); + + BookmarkNode *folder = dialog.addedNode(); + if (!folder) + return; + + for (int i = 0; i < count(); ++i) { + WebView *tab = webView(i); + if (!tab) + continue; + + QString title = tab->title(); + QString url = QString::fromUtf8(tab->url().toEncoded()); + BookmarkNode *bookmark = new BookmarkNode(BookmarkNode::Bookmark); + bookmark->url = url; + bookmark->title = title; + BrowserApplication::bookmarksManager()->addBookmark(folder, bookmark); + } +} + void TabWidget::lineEditReturnPressed() { if (QLineEdit *lineEdit = qobject_cast(sender())) { - emit loadPage(lineEdit->text()); - if (m_lineEdits->currentWidget() == lineEdit) + OpenUrlIn tab = CurrentTab; + if (qApp->keyboardModifiers() == Qt::AltModifier) + tab = NewSelectedTab; + + loadString(lineEdit->text(), tab); + if (m_locationBars->currentWidget() == lineEdit) currentWebView()->setFocus(); } } @@ -481,11 +513,13 @@ void TabWidget::lineEditReturnPressed() void TabWidget::windowCloseRequested() { WebPage *webPage = qobject_cast(sender()); + if (!webPage) + return; WebView *webView = qobject_cast(webPage->view()); int index = webViewIndex(webView); if (index >= 0) { if (count() == 1) - webView->webPage()->mainWindow()->close(); + BrowserMainWindow::parentWindow(this)->close(); else closeTab(index); } @@ -508,8 +542,9 @@ void TabWidget::cloneTab(int index) index = currentIndex(); if (index < 0 || index >= count()) return; + QUrl url = webView(index)->url(); WebView *tab = makeNewTab(); - tab->setUrl(webView(index)->url()); + tab->loadUrl(url); } // When index is -1 index chooses the current tab @@ -521,7 +556,9 @@ void TabWidget::closeTab(int index) return; bool hasFocus = false; - if (WebView *tab = webView(index)) { + WebView *tab = webView(index); + + if (tab && !tab->url().isEmpty()) { if (tab->isModified()) { QMessageBox closeConfirmation(tab); closeConfirmation.setWindowFlags(Qt::Sheet); @@ -539,11 +576,19 @@ void TabWidget::closeTab(int index) m_recentlyClosedTabsAction->setEnabled(true); m_recentlyClosedTabs.prepend(tab->url()); +#if QT_VERSION >= 0x040600 + QByteArray tabHistory; + QDataStream tabHistoryStream(&tabHistory, QIODevice::WriteOnly); + tabHistoryStream << *tab->history(); + m_recentlyClosedTabsHistory.prepend(tabHistory); +#else + m_recentlyClosedTabsHistory.prepend(QByteArray()); +#endif if (m_recentlyClosedTabs.size() >= TabWidget::m_recentlyClosedTabsSize) m_recentlyClosedTabs.removeLast(); } - QWidget *lineEdit = m_lineEdits->widget(index); - m_lineEdits->removeWidget(lineEdit); + QWidget *lineEdit = m_locationBars->widget(index); + m_locationBars->removeWidget(lineEdit); lineEdit->deleteLater(); QWidget *webViewWithSearch = widget(index); @@ -552,7 +597,7 @@ void TabWidget::closeTab(int index) webViewWithSearch->deleteLater(); emit tabsChanged(); - if (hasFocus && count() > 0) + if (hasFocus && count() > 0 && currentWebView()) currentWebView()->setFocus(); if (count() == 0) emit lastTabClosed(); @@ -560,7 +605,6 @@ void TabWidget::closeTab(int index) QLabel *TabWidget::animationLabel(int index, bool addMovie) { -#if QT_VERSION >= 0x040500 if (-1 == index) return 0; QTabBar::ButtonPosition side = m_tabBar->freeSide(); @@ -569,15 +613,14 @@ QLabel *TabWidget::animationLabel(int index, bool addMovie) loadingAnimation = new QLabel(this); } if (addMovie && !loadingAnimation->movie()) { - QMovie *movie = new QMovie(":loading.gif", QByteArray(), loadingAnimation); + QMovie *movie = new QMovie(QLatin1String(":graphics/loading.gif"), QByteArray(), loadingAnimation); + movie->setSpeed(50); loadingAnimation->setMovie(movie); movie->start(); } - loadingAnimation->show(); m_tabBar->setTabButton(index, side, 0); m_tabBar->setTabButton(index, side, loadingAnimation); return loadingAnimation; -#endif } void TabWidget::webViewLoadStarted() @@ -585,29 +628,56 @@ void TabWidget::webViewLoadStarted() WebView *webView = qobject_cast(sender()); int index = webViewIndex(webView); if (-1 != index) { -#if QT_VERSION >= 0x040500 QLabel *label = animationLabel(index, true); if (label->movie()) label->movie()->start(); -#else - QIcon icon(QLatin1String(":loading.gif")); - setTabIcon(index, icon); -#endif } + + if (index != currentIndex()) + return; + + emit showStatusBarMessage(tr("Loading...")); } -void TabWidget::webViewLoadFinished() +void TabWidget::webViewLoadProgress(int progress) { -#if QT_VERSION >= 0x040500 WebView *webView = qobject_cast(sender()); int index = webViewIndex(webView); + + if (index != currentIndex() + || index < 0) + return; + + double totalBytes = (double) webView->webPage()->totalBytes() / 1024; + + QString message = tr("Loading %1% (%2 %3)...").arg(progress).arg(totalBytes, 0, 'f', 2).arg(QLatin1String("kB")); + emit showStatusBarMessage(message); +} + +void TabWidget::webViewLoadFinished(bool ok) +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) { QLabel *label = animationLabel(index, true); if (label->movie()) label->movie()->stop(); - } +#if defined(Q_WS_MAC) + QTabBar::ButtonPosition side = m_tabBar->freeSide(); + m_tabBar->setTabButton(index, side, 0); + delete label; #endif + } webViewIconChanged(); + + if (index != currentIndex()) + return; + + if (ok) + emit showStatusBarMessage(tr("Finished loading")); + else + emit showStatusBarMessage(tr("Failed to load")); } void TabWidget::webViewIconChanged() @@ -615,16 +685,13 @@ void TabWidget::webViewIconChanged() WebView *webView = qobject_cast(sender()); int index = webViewIndex(webView); if (-1 != index) { +#if !defined(Q_WS_MAC) QIcon icon = BrowserApplication::instance()->icon(webView->url()); -#if QT_VERSION >= 0x040500 QLabel *label = animationLabel(index, false); QMovie *movie = label->movie(); delete movie; label->setMovie(0); label->setPixmap(icon.pixmap(16, 16)); - label->show(); -#else - setTabIcon(index, icon); #endif } } @@ -633,24 +700,26 @@ void TabWidget::webViewTitleChanged(const QString &title) { WebView *webView = qobject_cast(sender()); int index = webViewIndex(webView); - if (-1 != index) { - if (title.isEmpty()) - setTabText(index, webView->url().toString()); - else - setTabText(index, title); - } + if (-1 == index) + return; + QString tabTitle = title; + if (title.isEmpty()) + tabTitle = QString::fromUtf8(webView->url().toEncoded()); + tabTitle.replace(QLatin1Char('&'), QLatin1String("&&")); + setTabText(index, tabTitle); + setTabToolTip(index, tabTitle); if (currentIndex() == index) emit setCurrentTitle(title); - BrowserApplication::historyManager()->updateHistoryItem(webView->url(), title); + BrowserApplication::historyManager()->updateHistoryEntry(webView->url(), title); } void TabWidget::webViewUrlChanged(const QUrl &url) { WebView *webView = qobject_cast(sender()); int index = webViewIndex(webView); - if (-1 != index) { - m_tabBar->setTabData(index, url); - } + if (-1 == index) + return; + m_tabBar->setTabData(index, url); emit tabsChanged(); } @@ -659,7 +728,12 @@ void TabWidget::openLastTab() if (m_recentlyClosedTabs.isEmpty()) return; QUrl url = m_recentlyClosedTabs.takeFirst(); + QByteArray historyState = m_recentlyClosedTabsHistory.takeFirst(); +#if QT_VERSION >= 0x040600 + createTab(historyState, NewTab); +#else loadUrl(url, NewTab); +#endif m_recentlyClosedTabsAction->setEnabled(!m_recentlyClosedTabs.isEmpty()); } @@ -668,7 +742,11 @@ void TabWidget::aboutToShowRecentTabsMenu() m_recentlyClosedTabsMenu->clear(); for (int i = 0; i < m_recentlyClosedTabs.count(); ++i) { QAction *action = new QAction(m_recentlyClosedTabsMenu); +#if QT_VERSION >= 0x040600 + action->setData(m_recentlyClosedTabsHistory.at(i)); +#else action->setData(m_recentlyClosedTabs.at(i)); +#endif QIcon icon = BrowserApplication::instance()->icon(m_recentlyClosedTabs.at(i)); action->setIcon(icon); action->setText(m_recentlyClosedTabs.at(i).toString()); @@ -678,72 +756,244 @@ void TabWidget::aboutToShowRecentTabsMenu() void TabWidget::aboutToShowRecentTriggeredAction(QAction *action) { + if (!action) + return; + +#if QT_VERSION >= 0x040600 + QByteArray historyState = action->data().toByteArray(); + createTab(historyState, NewTab); +#else QUrl url = action->data().toUrl(); loadUrl(url, NewTab); +#endif } +void TabWidget::retranslate() +{ + m_nextTabAction->setText(tr("Show Next Tab")); + QList shortcuts; + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceRight)); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageDown)); + shortcuts.append(tr("Ctrl-]")); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Less)); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Tab)); + m_nextTabAction->setShortcuts(shortcuts); + m_previousTabAction->setText(tr("Show Previous Tab")); + shortcuts.clear(); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_BraceLeft)); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_PageUp)); + shortcuts.append(tr("Ctrl-[")); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::Key_Greater)); + shortcuts.append(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Tab)); + m_previousTabAction->setShortcuts(shortcuts); + m_recentlyClosedTabsAction->setText(tr("Recently Closed Tabs")); + m_newTabAction->setText(tr("New &Tab")); + m_closeTabAction->setText(tr("&Close Tab")); + m_bookmarkTabsAction->setText(tr("Bookmark All Tabs")); + m_tabBar->updateViewToolBarAction(); +} -void TabWidget::contextMenuEvent(QContextMenuEvent *event) +void TabWidget::changeEvent(QEvent *event) { - if (!childAt(event->pos())) { - m_tabBar->contextMenuRequested(event->pos()); + if (event->type() == QEvent::LanguageChange) + retranslate(); + QTabWidget::changeEvent(event); +} + +/* + Transform string into a QUrl and then load it. + + When you already have a QUrl call loadUrl() + */ +void TabWidget::loadString(const QString &string, OpenUrlIn tab) +{ + if (string.isEmpty()) return; - } - QTabWidget::contextMenuEvent(event); + + QUrl url = guessUrlFromString(string); + loadUrl(url, tab); } -#if QT_VERSION < 0x040500 -void TabWidget::mouseDoubleClickEvent(QMouseEvent *event) +QUrl TabWidget::guessUrlFromString(const QString &string) { - m_tabBar->mouseDoubleClickEvent(event); - QTabWidget::mouseDoubleClickEvent(event); + OpenSearchManager *manager = ToolbarSearch::openSearchManager(); + QUrl url = manager->convertKeywordSearchToUrl(string); + if (url.isValid()) + return url; + +#if QT_VERSION >= 0x040600 + url = QUrl::fromUserInput(string); +#else + url = WebView::guessUrlFromString(string); +#endif + + if (url.scheme() == QLatin1String("about") + && url.path() == QLatin1String("home")) + url = QUrl(QLatin1String("qrc:/startpage.html")); + + // QUrl::isValid() is too much tolerant. + // We actually want to check if the url conforms to the RFC, which QUrl::isValid() doesn't state. + if (!url.scheme().isEmpty() && (!url.host().isEmpty() || !url.path().isEmpty())) + return url; + + QSettings settings; + settings.beginGroup(QLatin1String("urlloading")); + bool search = settings.value(QLatin1String("searchEngineFallback"), false).toBool(); + + if (search) { + url = ToolbarSearch::openSearchManager()->currentEngine()->searchUrl(string.trimmed()); + } else { + QString urlString = QLatin1String("http://") + string.trimmed(); + url = QUrl::fromEncoded(urlString.toUtf8(), QUrl::TolerantMode); + } + + return url; } -void TabWidget::mouseReleaseEvent(QMouseEvent *event) +/* + Somewhere in the browser interface a users wants to open a url + + By default open this url in the current tab, unless mouse or keyboard + modifiers are set. + */ +void TabWidget::loadUrlFromUser(const QUrl &url, const QString &title) { - if (event->button() == Qt::MidButton && !childAt(event->pos())) - m_tabBar->mouseReleaseEvent(event); - QTabWidget::mouseReleaseEvent(event); + loadUrl(url, modifyWithUserBehavior(CurrentTab), title); } -void TabWidget::wheelEvent(QWheelEvent *event) +void TabWidget::loadSettings() { - if (event->y() > tabBar()->height()) { - // Don't change the active tab if the user scrolls the webview - return; + for (int i = 0; i < count(); ++i) { + WebView *v = webView(i); + if (v && v->page()) + v->loadSettings(); } - if ((event->orientation() == Qt::Vertical && event->delta() < 0) - || (event->orientation() == Qt::Horizontal && event->delta() > 0)) { - if (currentIndex() < count()) { - setCurrentIndex(currentIndex() + 1); + + QSettings settings; + settings.beginGroup(QLatin1String("tabs")); + bool newTabButtonInRightCorner = settings.value(QLatin1String("newTabButtonInRightCorner"), true).toBool(); +#ifndef Q_WS_MAC + setCornerWidget(addTabButton, newTabButtonInRightCorner ? Qt::TopRightCorner : Qt::TopLeftCorner); + addTabButton->show(); +#endif + + bool oneCloseButton = settings.value(QLatin1String("oneCloseButton"), false).toBool(); + if (oneCloseButton) { + if (!closeTabButton) { + closeTabButton = new QToolButton(this); + closeTabButton->setDefaultAction(m_closeTabAction); + closeTabButton->setAutoRaise(true); + closeTabButton->setToolButtonStyle(Qt::ToolButtonIconOnly); } + setCornerWidget(closeTabButton, newTabButtonInRightCorner ? Qt::TopLeftCorner : Qt::TopRightCorner); + closeTabButton->setVisible(oneCloseButton); } else { - if (currentIndex() > 0) { - setCurrentIndex(currentIndex() - 1); - } + setCornerWidget(0, newTabButtonInRightCorner ? Qt::TopLeftCorner : Qt::TopRightCorner); } + m_tabBar->setTabsClosable(!oneCloseButton); } + +/* + Replace the openIn behavior with the behavior the user wants. + + // ctrl open in new tab + // ctrl-shift open in new tab and select + // ctrl-alt open in new window + */ +TabWidget::OpenUrlIn TabWidget::modifyWithUserBehavior(OpenUrlIn tab) { + Qt::KeyboardModifiers modifiers = BrowserApplication::instance()->eventKeyboardModifiers(); + Qt::MouseButtons buttons = BrowserApplication::instance()->eventMouseButtons(); +#ifdef USERMODIFIEDBEHAVIOR_DEBUG + qDebug() << __FUNCTION__ << "start" << modifiers << buttons << tab; #endif + if (modifiers & Qt::ControlModifier || buttons == Qt::MidButton) { + if (modifiers & Qt::AltModifier) { + tab = NewWindow; + } else { + QSettings settings; + settings.beginGroup(QLatin1String("tabs")); + bool select = settings.value(QLatin1String("selectNewTabs"), false).toBool(); + if (modifiers & Qt::ShiftModifier) + tab = !select ? NewSelectedTab : NewNotSelectedTab; + else + tab = select ? NewSelectedTab : NewNotSelectedTab; + } + } +#ifdef USERMODIFIEDBEHAVIOR_DEBUG + qDebug() << __FUNCTION__ << "end" << modifiers << buttons << tab; +#endif + BrowserApplication::instance()->setEventKeyboardModifiers(0); + BrowserApplication::instance()->setEventMouseButtons(Qt::NoButton); + return tab; +} -void TabWidget::loadUrl(const QUrl &url, Tab type, const QString &title) +/* + Somewhere in the browser interface a users wants to open a url in a specific tab. + */ +void TabWidget::loadUrl(const QUrl &url, OpenUrlIn tab, const QString &title) { - WebView *webView; - if (NewTab == type) { - webView = makeNewTab(); - if (count() == 1) - webView = this->webView(0); - } else { - webView = currentWebView(); + if (tab == UserOrCurrent) { + loadUrlFromUser(url, title); + return; } - + if (!url.isValid()) + return; + WebView *webView = getView(tab, currentWebView()); if (webView) { - webView->loadUrl(url); - webView->setFocus(); - if (!title.isEmpty()) { - int tabIndex = webViewIndex(webView); - setTabText(tabIndex, title); + int index = webViewIndex(webView); + if (index != -1) + locationBar(index)->setText(QString::fromUtf8(url.toEncoded())); + webView->loadUrl(url, title); + } +} + +/* + Return the view that matches the openIn behavior creating + a new view/window if necessary. + */ +WebView *TabWidget::getView(OpenUrlIn tab, WebView *currentView) +{ + WebView *webView = 0; + switch (tab) { + case NewWindow: { +#ifdef USERMODIFIEDBEHAVIOR_DEBUG + qDebug() << __FUNCTION__ << "NewWindow"; +#endif + BrowserMainWindow *newMainWindow = BrowserApplication::instance()->newMainWindow(); + webView = newMainWindow->currentTab(); + webView->setFocus(); + break; + } + + case NewSelectedTab: { +#ifdef USERMODIFIEDBEHAVIOR_DEBUG + qDebug() << __FUNCTION__ << "NewSelectedTab"; +#endif + webView = makeNewTab(true); + webView->setFocus(); + break; } + + case NewNotSelectedTab: { +#ifdef USERMODIFIEDBEHAVIOR_DEBUG + qDebug() << __FUNCTION__ << "NewNotSelectedTab"; +#endif + webView = makeNewTab(false); + break; + } + + case CurrentTab: + default: +#ifdef USERMODIFIEDBEHAVIOR_DEBUG + qDebug() << __FUNCTION__ << "CurrentTab"; +#endif + webView = currentView; + if (!webView) + return 0; + webView->setFocus(); + break; } + return webView; } void TabWidget::nextTab() @@ -774,15 +1024,31 @@ QByteArray TabWidget::saveState() const stream << qint32(version); QStringList tabs; + QList tabsHistory; for (int i = 0; i < count(); ++i) { if (WebView *tab = webView(i)) { - tabs.append(tab->url().toString()); + tabs.append(QString::fromUtf8(tab->url().toEncoded())); +#if QT_VERSION >= 0x040600 + if (tab->history()->count() != 0) { + QByteArray tabHistory; + QDataStream tabHistoryStream(&tabHistory, QIODevice::WriteOnly); + tabHistoryStream << *tab->history(); + tabsHistory.append(tabHistory); + } else { + tabsHistory << QByteArray(); + } +#else + tabsHistory.append(QByteArray()); +#endif } else { tabs.append(QString::null); + tabsHistory.append(QByteArray()); } } stream << tabs; stream << currentIndex(); + stream << tabsHistory; + return data; } @@ -803,13 +1069,43 @@ bool TabWidget::restoreState(const QByteArray &state) QStringList openTabs; stream >> openTabs; - for (int i = 0; i < openTabs.count(); ++i) - loadUrl(openTabs.at(i), i == 0 ? CurrentTab : NewTab); int currentTab; stream >> currentTab; setCurrentIndex(currentTab); + QList tabHistory; + stream >> tabHistory; + + for (int i = 0; i < openTabs.count(); ++i) { + QUrl url = QUrl::fromEncoded(openTabs.at(i).toUtf8()); + TabWidget::OpenUrlIn tab = i == 0 && currentWebView()->url() == QUrl() ? CurrentTab : NewTab; +#if QT_VERSION >= 0x040600 + QByteArray historyState = tabHistory.value(i); + if (!historyState.isEmpty()) { + createTab(historyState, tab); + } else { +#endif + if (WebView *webView = getView(tab, currentWebView())) + webView->loadUrl(url); +#if QT_VERSION >= 0x040600 + } +#endif + } return true; } +void TabWidget::createTab(const QByteArray &historyState, TabWidget::OpenUrlIn tab) +{ +#if QT_VERSION >= 0x040600 + if (WebView *webView = getView(tab, currentWebView())) { + QDataStream historyStream(historyState); + historyStream >> *webView->history(); + } +#else + qWarning() << "Warning: TabWidget::createTab should not be called, but it is..."; + Q_UNUSED(historyState); + Q_UNUSED(tab); +#endif +} + diff --git a/src/tabwidget.h b/src/tabwidget.h index 67a4bcd0..6ceff10d 100644 --- a/src/tabwidget.h +++ b/src/tabwidget.h @@ -76,10 +76,12 @@ class QMenu; class QStackedWidget; QT_END_NAMESPACE +class BrowserMainWindow; class TabBar; class WebView; class WebActionMapper; class WebViewSearch; +class QToolButton; /*! TabWidget that contains WebViews and a stack widget of associated line edits. @@ -93,7 +95,6 @@ class TabWidget : public QTabWidget signals: // tab widget signals - void loadPage(const QString &url); void tabsChanged(); void lastTabClosed(); @@ -109,44 +110,52 @@ class TabWidget : public QTabWidget void printRequested(QWebFrame *frame); public: - enum Tab { + enum OpenUrlIn { + NewWindow, + NewSelectedTab, + NewNotSelectedTab, CurrentTab, - NewTab + UserOrCurrent, + NewTab = NewNotSelectedTab }; TabWidget(QWidget *parent = 0); + + void loadSettings(); TabBar *tabBar() { return m_tabBar; } void clear(); void addWebAction(QAction *action, QWebPage::WebAction webAction); QAction *newTabAction() const; QAction *closeTabAction() const; + QAction *bookmarkTabsAction() const; QAction *recentlyClosedTabsAction() const; QAction *nextTabAction() const; QAction *previousTabAction() const; - QWidget *lineEditStack() const; - QLineEdit *currentLineEdit() const; + QWidget *locationBarStack() const; + QLineEdit *currentLocationBar() const; WebView *currentWebView() const; WebView *webView(int index) const; WebViewSearch *webViewSearch(int index) const; - QLineEdit *lineEdit(int index) const; + QLineEdit *locationBar(int index) const; int webViewIndex(WebView *webView) const; WebView *makeNewTab(bool makeCurrent = false); QByteArray saveState() const; bool restoreState(const QByteArray &state); + static OpenUrlIn modifyWithUserBehavior(OpenUrlIn tab); + WebView *getView(OpenUrlIn tab, WebView *currentView); + protected: - void contextMenuEvent(QContextMenuEvent *event); -#if QT_VERSION < 0x040500 - void mouseDoubleClickEvent(QMouseEvent *event); - void mouseReleaseEvent(QMouseEvent *event); - void wheelEvent(QWheelEvent *event); -#endif + void changeEvent(QEvent *event); public slots: - void loadUrl(const QUrl &url, TabWidget::Tab type = CurrentTab, const QString &title = QString()); + void loadString(const QString &string, OpenUrlIn tab = CurrentTab); + void loadUrlFromUser(const QUrl &url, const QString &title = QString()); + void loadUrl(const QUrl &url, TabWidget::OpenUrlIn tab = CurrentTab, const QString &title = QString()); + void createTab(const QByteArray &historyState, TabWidget::OpenUrlIn tab = CurrentTab); void newTab(); void cloneTab(int index = -1); void closeTab(int index = -1); @@ -155,6 +164,7 @@ public slots: void reloadAllTabs(); void nextTab(); void previousTab(); + void bookmarkTabs(); private slots: void currentChanged(int index); @@ -162,31 +172,43 @@ private slots: void aboutToShowRecentTabsMenu(); void aboutToShowRecentTriggeredAction(QAction *action); void webViewLoadStarted(); - void webViewLoadFinished(); + void webViewLoadProgress(int progress); + void webViewLoadFinished(bool ok); void webViewIconChanged(); void webViewTitleChanged(const QString &title); void webViewUrlChanged(const QUrl &url); void lineEditReturnPressed(); void windowCloseRequested(); void moveTab(int fromIndex, int toIndex); + void geometryChangeRequestedCheck(const QRect &geometry); + void menuBarVisibilityChangeRequestedCheck(bool visible); + void statusBarVisibilityChangeRequestedCheck(bool visible); + void toolBarVisibilityChangeRequestedCheck(bool visible); + void historyCleared(); private: + static QUrl guessUrlFromString(const QString &url); QLabel *animationLabel(int index, bool addMovie); + void retranslate(); QAction *m_recentlyClosedTabsAction; QAction *m_newTabAction; QAction *m_closeTabAction; + QAction *m_bookmarkTabsAction; QAction *m_nextTabAction; QAction *m_previousTabAction; QMenu *m_recentlyClosedTabsMenu; static const int m_recentlyClosedTabsSize = 10; QList m_recentlyClosedTabs; + QList m_recentlyClosedTabsHistory; QList m_actions; QCompleter *m_lineEditCompleter; - QStackedWidget *m_lineEdits; + QStackedWidget *m_locationBars; TabBar *m_tabBar; + QToolButton *addTabButton; + QToolButton *closeTabButton; }; #endif // TABWIDGET_H diff --git a/src/toolbarsearch.cpp b/src/toolbarsearch.cpp index 93a42098..59079200 100644 --- a/src/toolbarsearch.cpp +++ b/src/toolbarsearch.cpp @@ -1,5 +1,6 @@ /* * Copyright 2008 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,38 +62,127 @@ ****************************************************************************/ #include "toolbarsearch.h" + #include "autosaver.h" +#include "browserapplication.h" +#include "browsermainwindow.h" +#include "networkaccessmanager.h" +#include "opensearchengine.h" +#include "opensearchengineaction.h" +#include "opensearchmanager.h" +#include "searchbutton.h" +#include "webpage.h" +#include "webview.h" +#include #include #include #include #include -#include +#include +#include #include - #include +OpenSearchManager *ToolbarSearch::s_openSearchManager = 0; + /* - ToolbarSearch is a very basic search widget that also contains a small history. - Searches are turned into urls that use Google to perform search + ToolbarSearch is a search widget that also contains a small history + and uses open-search for searching. */ ToolbarSearch::ToolbarSearch(QWidget *parent) : SearchLineEdit(parent) + , m_suggestionsEnabled(true) , m_autosaver(new AutoSaver(this)) , m_maxSavedSearches(10) - , m_stringListModel(new QStringListModel(this)) + , m_model(new QStandardItemModel(this)) + , m_suggestionsItem(0) + , m_recentSearchesItem(0) + , m_suggestTimer(0) + , m_completer(0) { - QMenu *m = menu(); - connect(m, SIGNAL(aboutToShow()), this, SLOT(aboutToShowMenu())); - connect(m, SIGNAL(triggered(QAction*)), this, SLOT(triggeredMenuAction(QAction*))); + connect(openSearchManager(), SIGNAL(currentEngineChanged()), + this, SLOT(currentEngineChanged())); - QCompleter *completer = new QCompleter(m_stringListModel, this); - completer->setCompletionMode(QCompleter::InlineCompletion); - lineEdit()->setCompleter(completer); + m_completer = new QCompleter(m_model, this); + m_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion); + setCompleter(m_completer); + + searchButton()->setShowMenuTriangle(true); + + connect(searchButton(), SIGNAL(clicked()), + this, SLOT(showEnginesMenu())); + connect(this, SIGNAL(returnPressed()), + this, SLOT(searchNow())); - connect(lineEdit(), SIGNAL(returnPressed()), SLOT(searchNow())); - setInactiveText(tr("Google")); load(); + + currentEngineChanged(); +} + +OpenSearchManager *ToolbarSearch::openSearchManager() +{ + if (!s_openSearchManager) + s_openSearchManager = new OpenSearchManager; + return s_openSearchManager; +} + +void ToolbarSearch::currentEngineChanged() +{ + OpenSearchEngine *newEngine = openSearchManager()->currentEngine(); + Q_ASSERT(newEngine); + if (!newEngine) + return; + + if (m_suggestionsEnabled) { + if (openSearchManager()->engineExists(m_currentEngine)) { + OpenSearchEngine *oldEngine = openSearchManager()->engine(m_currentEngine); + disconnect(oldEngine, SIGNAL(suggestions(const QStringList &)), + this, SLOT(newSuggestions(const QStringList &))); + } + + connect(newEngine, SIGNAL(suggestions(const QStringList &)), + this, SLOT(newSuggestions(const QStringList &))); + } + + setInactiveText(newEngine->name()); + m_currentEngine = newEngine->name(); + m_suggestions.clear(); + setupList(); +} + +void ToolbarSearch::completerActivated(const QModelIndex &index) +{ + if (completerHighlighted(index)) + searchNow(); +} + +bool ToolbarSearch::completerHighlighted(const QModelIndex &index) +{ + if (m_suggestionsItem && m_suggestionsItem->index().row() == index.row()) + return false; + if (m_recentSearchesItem && m_recentSearchesItem->index().row() == index.row()) + return false; + setText(index.data().toString()); + return true; +} + +void ToolbarSearch::focusInEvent(QFocusEvent *event) +{ + SearchLineEdit::focusInEvent(event); + + // Every time we get a focus in event QLineEdit re-connects... + disconnect(completer(), SIGNAL(activated(QString)), + this, SLOT(setText(QString))); + disconnect(completer(), SIGNAL(highlighted(QString)), + this, SLOT(_q_completionHighlighted(QString))); + + // And every time it gets a focus out it disconnects everything from the completer to this :( + // So we have to re-connect + connect(completer(), SIGNAL(activated(const QModelIndex &)), + this, SLOT(completerActivated(const QModelIndex &))); + connect(completer(), SIGNAL(highlighted(const QModelIndex &)), + this, SLOT(completerHighlighted(const QModelIndex &))); } ToolbarSearch::~ToolbarSearch() @@ -104,7 +194,7 @@ void ToolbarSearch::save() { QSettings settings; settings.beginGroup(QLatin1String("toolbarsearch")); - settings.setValue(QLatin1String("recentSearches"), m_stringListModel->stringList()); + settings.setValue(QLatin1String("recentSearches"), m_recentSearches); settings.setValue(QLatin1String("maximumSaved"), m_maxSavedSearches); settings.endGroup(); } @@ -113,72 +203,229 @@ void ToolbarSearch::load() { QSettings settings; settings.beginGroup(QLatin1String("toolbarsearch")); - QStringList list = settings.value(QLatin1String("recentSearches")).toStringList(); + m_recentSearches = settings.value(QLatin1String("recentSearches")).toStringList(); m_maxSavedSearches = settings.value(QLatin1String("maximumSaved"), m_maxSavedSearches).toInt(); - m_stringListModel->setStringList(list); + + m_suggestionsEnabled = settings.value(QLatin1String("useSuggestions"), true).toBool(); + if (m_suggestionsEnabled) { + connect(this, SIGNAL(textEdited(const QString &)), + this, SLOT(textEdited(const QString &))); + } + settings.endGroup(); + setupList(); +} + +void ToolbarSearch::textEdited(const QString &text) +{ + Q_UNUSED(text); + // delay settings this to prevent BrowserApplication from creating + // the object when it isn't needed on startup + if (!m_suggestTimer) { + m_suggestTimer = new QTimer(this); + m_suggestTimer->setSingleShot(true); + m_suggestTimer->setInterval(200); + connect(m_suggestTimer, SIGNAL(timeout()), + this, SLOT(getSuggestions())); + } + m_suggestTimer->start(); +} + +void ToolbarSearch::getSuggestions() +{ + OpenSearchEngine *engine = openSearchManager()->currentEngine(); + Q_ASSERT(engine); + if (!engine) + return; + + if (!engine->networkAccessManager()) + engine->setNetworkAccessManager(BrowserApplication::networkAccessManager()); + + engine->requestSuggestions(text()); } void ToolbarSearch::searchNow() { - QString searchText = lineEdit()->text(); - QStringList newList = m_stringListModel->stringList(); - if (newList.contains(searchText)) - newList.removeAt(newList.indexOf(searchText)); - newList.prepend(searchText); - if (newList.size() >= m_maxSavedSearches) - newList.removeLast(); + OpenSearchEngine *engine = openSearchManager()->currentEngine(); + Q_ASSERT(engine); + if (!engine) + return; + + QString searchText = text(); QWebSettings *globalSettings = QWebSettings::globalSettings(); if (!globalSettings->testAttribute(QWebSettings::PrivateBrowsingEnabled)) { - m_stringListModel->setStringList(newList); + QStringList newList = m_recentSearches; + if (newList.contains(searchText)) + newList.removeAt(newList.indexOf(searchText)); + newList.prepend(searchText); + if (newList.size() >= m_maxSavedSearches) + newList.removeLast(); + + m_recentSearches = newList; m_autosaver->changeOccurred(); } - QUrl url(QLatin1String("http://www.google.com/search")); - url.addQueryItem(QLatin1String("q"), searchText); - url.addQueryItem(QLatin1String("ie"), QLatin1String("UTF-8")); - url.addQueryItem(QLatin1String("oe"), QLatin1String("UTF-8")); - url.addQueryItem(QLatin1String("client"), QCoreApplication::applicationName()); - emit search(url); + QUrl searchUrl = engine->searchUrl(searchText); + TabWidget::OpenUrlIn tab = TabWidget::CurrentTab; + if (qApp->keyboardModifiers() == Qt::AltModifier) + tab = TabWidget::NewSelectedTab; + emit search(searchUrl, tab); +} + +void ToolbarSearch::newSuggestions(const QStringList &suggestions) +{ + m_suggestions = suggestions; + setupList(); +} + +void ToolbarSearch::changeEvent(QEvent *event) +{ + if (event->type() == QEvent::LanguageChange) + retranslate(); + SearchLineEdit::changeEvent(event); +} + +void ToolbarSearch::retranslate() +{ + if (m_suggestionsItem) + m_suggestionsItem->setText(tr("Suggestions")); } -void ToolbarSearch::aboutToShowMenu() +void ToolbarSearch::showEnginesMenu() { - lineEdit()->selectAll(); - QMenu *m = menu(); - m->clear(); - QStringList list = m_stringListModel->stringList(); - if (list.isEmpty()) { - m->addAction(tr("No Recent Searches")); + QMenu menu; + + QWidget *parent = searchButton()->parentWidget(); + if (!parent) return; - } - QAction *recent = m->addAction(tr("Recent Searches")); - recent->setEnabled(false); + QPoint pos = parent->mapToGlobal(QPoint(0, parent->height())); + + QList list = openSearchManager()->allEnginesNames(); for (int i = 0; i < list.count(); ++i) { - QString text = list.at(i); - m->addAction(text)->setData(text); + QString name = list.at(i); + OpenSearchEngine *engine = openSearchManager()->engine(name); + OpenSearchEngineAction *action = new OpenSearchEngineAction(engine, &menu); + action->setData(name); + connect(action, SIGNAL(triggered()), this, SLOT(changeCurrentEngine())); + menu.addAction(action); + + if (openSearchManager()->currentEngineName() == name) { + action->setCheckable(true); + action->setChecked(true); + } + } + + WebView *webView = BrowserMainWindow::parentWindow(this)->currentTab(); + QList engines = webView->webPage()->linkedResources(QLatin1String("search")); + + if (!engines.empty()) + menu.addSeparator(); + + for (int i = 0; i < engines.count(); ++i) { + WebPageLinkedResource engine = engines.at(i); + + QUrl url = engine.href; + QString title = engine.title; + QString mimetype = engine.type; + + if (mimetype != QLatin1String("application/opensearchdescription+xml")) + continue; + if (url.isEmpty()) + continue; + + if (title.isEmpty()) + title = webView->title().isEmpty() ? url.host() : webView->title(); + + QAction *action = menu.addAction(tr("Add '%1'").arg(title), this, SLOT(addEngineFromUrl())); + action->setData(url); + action->setIcon(webView->icon()); } - m->addSeparator(); - m->addAction(tr("Clear Recent Searches"), this, SLOT(clear())); + + menu.addSeparator(); + if (BrowserMainWindow *window = BrowserMainWindow::parentWindow(this)) + menu.addAction(window->searchManagerAction()); + + if (!m_recentSearches.empty()) + menu.addAction(tr("Clear Recent Searches"), this, SLOT(clear())); + + menu.exec(pos); } -void ToolbarSearch::triggeredMenuAction(QAction *action) +void ToolbarSearch::changeCurrentEngine() { - QVariant v = action->data(); - if (v.canConvert()) { - QString text = v.toString(); - lineEdit()->setText(text); - searchNow(); + if (QAction *action = qobject_cast(sender())) { + QString name = action->data().toString(); + openSearchManager()->setCurrentEngineName(name); } } +void ToolbarSearch::addEngineFromUrl() +{ + QAction *action = qobject_cast(sender()); + if (!action) + return; + QVariant variant = action->data(); + if (!variant.canConvert()) + return; + QUrl url = variant.toUrl(); + + openSearchManager()->addEngine(url); +} + +void ToolbarSearch::setupList() +{ + if (m_suggestions.isEmpty() + || (m_model->rowCount() > 0 + && m_model->item(0) != m_suggestionsItem)) { + m_model->clear(); + m_suggestionsItem = 0; + } else { + m_model->removeRows(1, m_model->rowCount() - 1); + } + + QFont lightFont; + lightFont.setWeight(QFont::Light); + if (!m_suggestions.isEmpty()) { + if (m_model->rowCount() == 0) { + if (!m_suggestionsItem) { + m_suggestionsItem = new QStandardItem(); + m_suggestionsItem->setFont(lightFont); + retranslate(); + } + m_model->appendRow(m_suggestionsItem); + } + for (int i = 0; i < m_suggestions.count(); ++i) { + const QString &text = m_suggestions.at(i); + m_model->appendRow(new QStandardItem(text)); + } + } + + if (m_recentSearches.isEmpty()) { + m_recentSearchesItem = new QStandardItem(tr("No Recent Searches")); + m_recentSearchesItem->setFont(lightFont); + m_model->appendRow(m_recentSearchesItem); + } else { + m_recentSearchesItem = new QStandardItem(tr("Recent Searches")); + m_recentSearchesItem->setFont(lightFont); + m_model->appendRow(m_recentSearchesItem); + for (int i = 0; i < m_recentSearches.count(); ++i) { + QString text = m_recentSearches.at(i); + m_model->appendRow(new QStandardItem(text)); + } + } + + QAbstractItemView *view = completer()->popup(); + view->setFixedHeight(view->sizeHintForRow(0) * m_model->rowCount() + view->frameWidth() * 2); +} + void ToolbarSearch::clear() { - m_stringListModel->setStringList(QStringList()); + m_recentSearches.clear(); m_autosaver->changeOccurred(); - ExLineEdit::clear(); + setupList(); + QLineEdit::clear(); clearFocus(); } diff --git a/src/toolbarsearch.h b/src/toolbarsearch.h index 005daae4..a09a18db 100644 --- a/src/toolbarsearch.h +++ b/src/toolbarsearch.h @@ -65,40 +65,68 @@ #include "searchlineedit.h" -QT_BEGIN_NAMESPACE -class QUrl; -class QAction; -class QStringListModel; -QT_END_NAMESPACE +#include "tabwidget.h" class AutoSaver; - +class OpenSearchManager; +class QCompleter; +class QModelIndex; +class QStandardItem; +class QStandardItemModel; +class QTimer; +class QUrl; class ToolbarSearch : public SearchLineEdit { Q_OBJECT signals: - void search(const QUrl &url); + void search(const QUrl &url, TabWidget::OpenUrlIn tab); public: ToolbarSearch(QWidget *parent = 0); ~ToolbarSearch(); + static OpenSearchManager *openSearchManager(); public slots: void clear(); void searchNow(); private slots: + void currentEngineChanged(); void save(); - void aboutToShowMenu(); - void triggeredMenuAction(QAction *action); + void textEdited(const QString &); + void newSuggestions(const QStringList &suggestions); + void completerActivated(const QModelIndex &index); + bool completerHighlighted(const QModelIndex &index); + void getSuggestions(); + void showEnginesMenu(); + void changeCurrentEngine(); + void addEngineFromUrl(); + +protected: + void changeEvent(QEvent *event); + void focusInEvent(QFocusEvent *event); private: void load(); + void setupList(); + void retranslate(); + + static OpenSearchManager *s_openSearchManager; + QString m_currentEngine; + bool m_suggestionsEnabled; AutoSaver *m_autosaver; int m_maxSavedSearches; - QStringListModel *m_stringListModel; + QStringList m_recentSearches; + QStringList m_suggestions; + QStandardItemModel *m_model; + + QStandardItem *m_suggestionsItem; + QStandardItem *m_recentSearchesItem; + QTimer *m_suggestTimer; + + QCompleter *m_completer; }; #endif // TOOLBARSEARCH_H diff --git a/src/urllineedit.cpp b/src/urllineedit.cpp deleted file mode 100644 index b9c77dfb..00000000 --- a/src/urllineedit.cpp +++ /dev/null @@ -1,388 +0,0 @@ -/* - * Copyright 2008 Benjamin C. Meyer - * Copyright 2008 Ariya Hidayat - * - * This program 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; either version 2 of the License, or - * (at your option) any later version. - * - * This program 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, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301 USA - */ - -/**************************************************************************** -** -** Copyright (C) 2008-2008 Trolltech ASA. All rights reserved. -** -** This file is part of the demonstration applications of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License versions 2.0 or 3.0 as published by the Free Software -** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Alternatively you may (at -** your option) use any later version of the GNU General Public -** License if such license has been publicly approved by Trolltech ASA -** (or its successors, if any) and the KDE Free Qt Foundation. In -** addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.2, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** Please review the following information to ensure GNU General -** Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/. If -** you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech, as the sole -** copyright holder for Qt Designer, grants users of the Qt/Eclipse -** Integration plug-in the right for the Qt/Eclipse Integration to -** link to functionality provided by Qt Designer and its related -** libraries. -** -** This file is provided "AS IS" with NO WARRANTY OF ANY KIND, -** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE. Trolltech reserves all rights not expressly -** granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include "urllineedit.h" - -#include "browserapplication.h" -#include "searchlineedit.h" -#include "webview.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -ExLineEdit::ExLineEdit(QWidget *parent) - : QWidget(parent) - , m_leftWidget(0) - , m_lineEdit(new QLineEdit(this)) - , m_clearButton(0) -{ - setFocusPolicy(m_lineEdit->focusPolicy()); - setAttribute(Qt::WA_InputMethodEnabled); - setSizePolicy(m_lineEdit->sizePolicy()); - setBackgroundRole(m_lineEdit->backgroundRole()); - setMouseTracking(true); - setAcceptDrops(true); - setAttribute(Qt::WA_MacShowFocusRect, true); - QPalette p = m_lineEdit->palette(); - setPalette(p); - - // line edit - m_lineEdit->setFrame(false); - m_lineEdit->setFocusProxy(this); - m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false); - QPalette clearPalette = m_lineEdit->palette(); - clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent)); - m_lineEdit->setPalette(clearPalette); - - // clearButton - m_clearButton = new ClearButton(this); - connect(m_clearButton, SIGNAL(clicked()), - m_lineEdit, SLOT(clear())); - connect(m_lineEdit, SIGNAL(textChanged(const QString&)), - m_clearButton, SLOT(textChanged(const QString&))); -} - -void ExLineEdit::setLeftWidget(QWidget *widget) -{ - m_leftWidget = widget; -} - -QWidget *ExLineEdit::leftWidget() const -{ - return m_leftWidget; -} - -void ExLineEdit::resizeEvent(QResizeEvent *event) -{ - Q_ASSERT(m_leftWidget); - updateGeometries(); - QWidget::resizeEvent(event); -} - -void ExLineEdit::updateGeometries() -{ - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - - int height = rect.height(); - int width = rect.width(); - - int m_leftWidgetHeight = m_leftWidget->height(); - int clearButtonWidth = this->height(); - - switch (layoutDirection()) { - case Qt::RightToLeft: - m_clearButton->setGeometry(rect.x(), rect.y() + (height - clearButtonWidth) / 2, - clearButtonWidth, this->height()); - - m_lineEdit->setGeometry(m_clearButton->x() + m_clearButton->width(), 0, - width - clearButtonWidth - m_leftWidget->width() - 2, this->height()); - - m_leftWidget->setGeometry(this->width() - m_leftWidget->width() - 2, rect.y() + (height - m_leftWidgetHeight) / 2, - m_leftWidget->width(), m_leftWidget->height()); - - break; - - case Qt::LeftToRight: - default: - m_leftWidget->setGeometry(rect.x() + 2,rect.y() + (height - m_leftWidgetHeight) / 2, - m_leftWidget->width(), m_leftWidget->height()); - - m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(), 0, - width - clearButtonWidth - m_leftWidget->width(), this->height()); - - m_clearButton->setGeometry(this->width() - clearButtonWidth, 0, - clearButtonWidth, this->height()); - break; - } -} - -void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const -{ - option->initFrom(this); - option->rect = contentsRect(); - option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this); - option->midLineWidth = 0; - option->state |= QStyle::State_Sunken; - if (m_lineEdit->isReadOnly()) - option->state |= QStyle::State_ReadOnly; -#ifdef QT_KEYPAD_NAVIGATION - if (hasEditFocus()) - option->state |= QStyle::State_HasEditFocus; -#endif - option->features = QStyleOptionFrameV2::None; -} - -QSize ExLineEdit::sizeHint() const -{ - m_lineEdit->setFrame(true); - QSize size = m_lineEdit->sizeHint(); - m_lineEdit->setFrame(false); - return size; -} - -void ExLineEdit::focusInEvent(QFocusEvent *event) -{ - m_lineEdit->event(event); - QWidget::focusInEvent(event); -} - -void ExLineEdit::focusOutEvent(QFocusEvent *event) -{ - m_lineEdit->event(event); - - if (m_lineEdit->completer()) { - connect(m_lineEdit->completer(), SIGNAL(activated(QString)), - m_lineEdit, SLOT(setText(QString))); - connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)), - m_lineEdit, SLOT(_q_completionHighlighted(QString))); - } - QWidget::focusOutEvent(event); -} - -void ExLineEdit::keyPressEvent(QKeyEvent *event) -{ - m_lineEdit->event(event); - QWidget::keyPressEvent(event); -} - -bool ExLineEdit::event(QEvent *event) -{ - if (event->type() == QEvent::ShortcutOverride) - m_lineEdit->event(event); - return QWidget::event(event); -} - -void ExLineEdit::paintEvent(QPaintEvent *) -{ - QPainter p(this); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this); -} - -void ExLineEdit::clear() -{ - m_lineEdit->clear(); -} - - -class UrlIconLabel : public QLabel -{ - -public: - UrlIconLabel(QWidget *parent); - - WebView *m_webView; - -protected: - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); - -private: - QPoint m_dragStartPos; - -}; - -UrlIconLabel::UrlIconLabel(QWidget *parent) - : QLabel(parent) - , m_webView(0) -{ - setMinimumWidth(16); - setMinimumHeight(16); -} - -void UrlIconLabel::mousePressEvent(QMouseEvent *event) -{ - if (event->button() == Qt::LeftButton) - m_dragStartPos = event->pos(); - QLabel::mousePressEvent(event); -} - -void UrlIconLabel::mouseMoveEvent(QMouseEvent *event) -{ - if (event->buttons() == Qt::LeftButton - && (event->pos() - m_dragStartPos).manhattanLength() > QApplication::startDragDistance() - && m_webView) { - QDrag *drag = new QDrag(this); - QMimeData *mimeData = new QMimeData; - mimeData->setText(m_webView->url().toString()); - QList urls; - urls.append(m_webView->url()); - mimeData->setUrls(urls); - drag->setMimeData(mimeData); - drag->exec(); - } -} - -UrlLineEdit::UrlLineEdit(QWidget *parent) - : ExLineEdit(parent) - , m_webView(0) - , m_iconLabel(0) -{ - // Urls are always LeftToRight - setLayoutDirection(Qt::LeftToRight); - - // icon - m_iconLabel = new UrlIconLabel(this); - m_iconLabel->resize(16, 16); - setLeftWidget(m_iconLabel); - m_defaultBaseColor = palette().color(QPalette::Base); - - webViewIconChanged(); -} - -void UrlLineEdit::setWebView(WebView *webView) -{ - Q_ASSERT(!m_webView); - m_webView = webView; - m_iconLabel->m_webView = webView; - connect(webView, SIGNAL(urlChanged(const QUrl &)), - this, SLOT(webViewUrlChanged(const QUrl &))); - connect(webView, SIGNAL(loadFinished(bool)), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(iconChanged()), - this, SLOT(webViewIconChanged())); - connect(webView, SIGNAL(loadProgress(int)), - this, SLOT(update())); -} - -void UrlLineEdit::webViewUrlChanged(const QUrl &url) -{ - m_lineEdit->setText(url.toString()); - m_lineEdit->setCursorPosition(0); -} - -void UrlLineEdit::webViewIconChanged() -{ - QUrl url = (m_webView) ? m_webView->url() : QUrl(); - QIcon icon = BrowserApplication::instance()->icon(url); - QPixmap pixmap(icon.pixmap(16, 16)); - m_iconLabel->setPixmap(pixmap); -} - -QLinearGradient UrlLineEdit::generateGradient(const QColor &color) const -{ - QLinearGradient gradient(0, 0, 0, height()); - gradient.setColorAt(0, m_defaultBaseColor); - gradient.setColorAt(0.15, color.lighter(120)); - gradient.setColorAt(0.5, color); - gradient.setColorAt(0.85, color.lighter(120)); - gradient.setColorAt(1, m_defaultBaseColor); - return gradient; -} - -void UrlLineEdit::focusOutEvent(QFocusEvent *event) -{ - if (m_lineEdit->text().isEmpty() && m_webView) - m_lineEdit->setText(m_webView->url().toString()); - ExLineEdit::focusOutEvent(event); -} - -void UrlLineEdit::paintEvent(QPaintEvent *event) -{ - QPalette p = palette(); - if (m_webView && m_webView->url().scheme() == QLatin1String("https")) { - QColor lightYellow(248, 248, 210); - p.setBrush(QPalette::Base, generateGradient(lightYellow)); - } else { - p.setBrush(QPalette::Base, m_defaultBaseColor); - } - setPalette(p); - ExLineEdit::paintEvent(event); - - QPainter painter(this); - QStyleOptionFrameV2 panel; - initStyleOption(&panel); - QRect backgroundRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); - if (m_webView && !hasFocus()) { - int progress = m_webView->progress(); - QColor loadingColor = QColor(116, 192, 250); - painter.setBrush(generateGradient(loadingColor)); - painter.setPen(Qt::transparent); - - int mid = backgroundRect.width() / 100 * progress; - QRect progressRect; - switch (layoutDirection()) { - case Qt::RightToLeft: - progressRect = QRect(backgroundRect.width() - mid, backgroundRect.y(), mid, backgroundRect.height()); - break; - - case Qt::LeftToRight: - default: - progressRect = QRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height()); - break; - } - painter.drawRect(progressRect); - } -} - diff --git a/src/useragent/useragent.pri b/src/useragent/useragent.pri new file mode 100644 index 00000000..78f1c485 --- /dev/null +++ b/src/useragent/useragent.pri @@ -0,0 +1,11 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + useragentmenu.h + +SOURCES += \ + useragentmenu.cpp + +RESOURCES += \ + useragents.qrc diff --git a/src/useragent/useragentmenu.cpp b/src/useragent/useragentmenu.cpp new file mode 100644 index 00000000..d37ada37 --- /dev/null +++ b/src/useragent/useragentmenu.cpp @@ -0,0 +1,139 @@ +/** + * Copyright (c) 2010, William C. Witt + * Copyright (c) 2010, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Arora nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "useragentmenu.h" + +#include "webpage.h" + +#include +#include +#include +#include + +#include + +UserAgentMenu::UserAgentMenu(QWidget *parent) + : QMenu(parent) +{ + connect(this, SIGNAL(aboutToShow()), this, SLOT(populateMenu())); +} + +void UserAgentMenu::populateMenu() +{ + disconnect(this, SIGNAL(aboutToShow()), this, SLOT(populateMenu())); + + // Add default action + QAction *defaultUserAgent = new QAction(this); + defaultUserAgent->setText(tr("Default")); + defaultUserAgent->setCheckable(true); + connect(defaultUserAgent, SIGNAL(triggered()), this, SLOT(switchToDefaultUserAgent())); + QSettings settings; + defaultUserAgent->setChecked(settings.value(QLatin1String("userAgent")).toString().isEmpty()); + addAction(defaultUserAgent); + + // Add default extra user agents + addActionsFromFile(QLatin1String(":/useragents/useragents.xml")); + + // Add other action + addSeparator(); + QAction *otherUserAgent = new QAction(this); + otherUserAgent->setCheckable(true); + otherUserAgent->setText(tr("Other...")); + connect(otherUserAgent, SIGNAL(triggered()), this, SLOT(switchToOtherUserAgent())); + addAction(otherUserAgent); + + bool usingCustomUserAgent = true; + QActionGroup *actionGroup = new QActionGroup(this); + foreach (QAction *action, actions()) { + actionGroup->addAction(action); + if (action->isChecked()) { + usingCustomUserAgent = false; + } + } + otherUserAgent->setChecked(usingCustomUserAgent); +} + +void UserAgentMenu::addActionsFromFile(const QString &fileName) +{ + QFile file(fileName); + if (!file.open(QFile::ReadOnly)) + return; + + QString currentUserAgentString = WebPage::userAgent(); + QXmlStreamReader xml(&file); + while (!xml.atEnd()) { + xml.readNext(); + if (xml.isStartElement() && xml.name() == QLatin1String("separator")) { + addSeparator(); + continue; + } + if (xml.isStartElement() && xml.name() == QLatin1String("useragent")) { + QXmlStreamAttributes attributes = xml.attributes(); + QString title = attributes.value(QLatin1String("description")).toString(); + QString userAgent = attributes.value(QLatin1String("useragent")).toString(); + + QAction *action = new QAction(this); + action->setText(title); + action->setData(userAgent); + action->setToolTip(userAgent); + action->setCheckable(true); + action->setChecked(userAgent == currentUserAgentString); + connect(action, SIGNAL(triggered()), this, SLOT(changeUserAgent())); + addAction(action); + } + } + if (xml.hasError()) { + qDebug() << "Error reading custom user agents" << xml.errorString(); + // ... do error handling + } +} + +void UserAgentMenu::changeUserAgent() +{ + if (QAction *action = qobject_cast(sender())) { + WebPage::setUserAgent(action->data().toString()); + } +} + +void UserAgentMenu::switchToDefaultUserAgent() +{ + WebPage::setUserAgent(QString()); +} + +void UserAgentMenu::switchToOtherUserAgent() +{ + bool ok; + QString text = QInputDialog::getText(this, tr("Custom user agent"), + tr("User agent:"), QLineEdit::Normal, + WebPage::userAgent(), &ok, Qt::Sheet); + if (ok) { + WebPage::setUserAgent(text); + } +} + diff --git a/src/useragent/useragentmenu.h b/src/useragent/useragentmenu.h new file mode 100644 index 00000000..e7547b73 --- /dev/null +++ b/src/useragent/useragentmenu.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2010, William C. Witt + * Copyright (c) 2010, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Arora nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef USERAGENTMENU_H +#define USERAGENTMENU_H + +#include + +class UserAgentMenu : public QMenu +{ + Q_OBJECT + +public: + UserAgentMenu(QWidget *parent = 0); + +private slots: + void populateMenu(); + void changeUserAgent(); + void switchToDefaultUserAgent(); + void switchToOtherUserAgent(); + +private: + void addActionsFromFile(const QString &fileName); + +}; + +#endif // USERAGENTMENU_H diff --git a/src/useragent/useragents.qrc b/src/useragent/useragents.qrc new file mode 100644 index 00000000..29468193 --- /dev/null +++ b/src/useragent/useragents.qrc @@ -0,0 +1,5 @@ + + + useragents.xml + + diff --git a/src/useragent/useragents.xml b/src/useragent/useragents.xml new file mode 100644 index 00000000..ee043934 --- /dev/null +++ b/src/useragent/useragents.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/utils/README b/src/utils/README new file mode 100644 index 00000000..a81d0060 --- /dev/null +++ b/src/utils/README @@ -0,0 +1,7 @@ +The utils directory is a collection of classes: +- They are stand alone classes with no dependency on Arora or each other. +- Provide functionality that can not be found in Qt. +- Licensed under the BSD or public domain. +- Have auto tests and or manual tests were applicable. + +The purpose of the utils classes is to provide functionality that is missing from Qt, but not specific to Arora. For example the SqueezeLabel provides a QLabel that can take a string larger than the size of the widget and insert "..." in the middle to squeeze the text into the size of the widget. Such a class could be useful for many Qt application and might even be a feature added to Qt one day. diff --git a/src/utils/editlistview.cpp b/src/utils/editlistview.cpp new file mode 100644 index 00000000..778597d3 --- /dev/null +++ b/src/utils/editlistview.cpp @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2009, Jakub Wieczorek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "editlistview.h" + +#include + +EditListView::EditListView(QWidget *parent) + : QListView(parent) +{ +} + +void EditListView::keyPressEvent(QKeyEvent *event) +{ + if (model() && event->key() == Qt::Key_Delete) { + removeSelected(); + event->setAccepted(true); + } else { + QAbstractItemView::keyPressEvent(event); + } +} + +void EditListView::removeSelected() +{ + if (!model() || !selectionModel()) + return; + + QModelIndexList selectedRows = selectionModel()->selectedRows(); + for (int i = selectedRows.count() - 1; i >= 0; --i) { + QModelIndex idx = selectedRows.at(i); + model()->removeRow(idx.row(), rootIndex()); + } +} + +void EditListView::removeAll() +{ + if (!model()) + return; + + model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); +} + diff --git a/src/utils/editlistview.h b/src/utils/editlistview.h new file mode 100644 index 00000000..c7f4c2ff --- /dev/null +++ b/src/utils/editlistview.h @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2009, Jakub Wieczorek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef EDITLISTVIEW_H +#define EDITLISTVIEW_H + +#include + +class EditListView : public QListView +{ + Q_OBJECT + +public: + EditListView(QWidget *parent = 0); + void keyPressEvent(QKeyEvent *event); + +public slots: + void removeSelected(); + void removeAll(); +}; + +#endif // EDITLISTVIEW_H + diff --git a/src/utils/edittableview.cpp b/src/utils/edittableview.cpp new file mode 100644 index 00000000..cf7159f3 --- /dev/null +++ b/src/utils/edittableview.cpp @@ -0,0 +1,81 @@ +/** + * Copyright (c) 2008, Benjamin C. Meyer + * Copyright (c) 2009, Jakub Wieczorek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "edittableview.h" + +#include + +EditTableView::EditTableView(QWidget *parent) + : QTableView(parent) +{ +} + +void EditTableView::keyPressEvent(QKeyEvent *event) +{ + if (model() && event->key() == Qt::Key_Delete) { + removeSelected(); + event->setAccepted(true); + } else { + QAbstractItemView::keyPressEvent(event); + } +} + +void EditTableView::removeSelected() +{ + if (!model() || !selectionModel() || !selectionModel()->hasSelection()) + return; + + QModelIndexList selectedRows = selectionModel()->selectedRows(); + if (selectedRows.isEmpty()) + return; + + int newSelectedRow = selectedRows.at(0).row(); + for (int i = selectedRows.count() - 1; i >= 0; --i) { + QModelIndex idx = selectedRows.at(i); + model()->removeRow(idx.row(), rootIndex()); + } + + // select the item at the same position + QModelIndex newSelectedIndex = model()->index(newSelectedRow, 0, rootIndex()); + // if that was the last item + if (!newSelectedIndex.isValid()) + newSelectedIndex = model()->index(newSelectedRow - 1, 0, rootIndex()); + + selectionModel()->select(newSelectedIndex, QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows); + setCurrentIndex(newSelectedIndex); +} + +void EditTableView::removeAll() +{ + if (!model()) + return; + + model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); +} + diff --git a/src/utils/edittableview.h b/src/utils/edittableview.h new file mode 100644 index 00000000..ade02462 --- /dev/null +++ b/src/utils/edittableview.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2008, Benjamin C. Meyer + * Copyright (c) 2009, Jakub Wieczorek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef EDITTABLEVIEW_H +#define EDITTABLEVIEW_H + +#include + +class EditTableView : public QTableView +{ + Q_OBJECT + +public: + EditTableView(QWidget *parent = 0); + void keyPressEvent(QKeyEvent *event); + +public slots: + void removeSelected(); + void removeAll(); +}; + +#endif // EDITTABLEVIEW_H + diff --git a/src/utils/edittreeview.cpp b/src/utils/edittreeview.cpp new file mode 100644 index 00000000..9c1da5c1 --- /dev/null +++ b/src/utils/edittreeview.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (c) 2008, Benjamin C. Meyer + * Copyright (c) 2009, Jakub Wieczorek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "edittreeview.h" + +#include + +EditTreeView::EditTreeView(QWidget *parent) + : QTreeView(parent) +{ +} + +void EditTreeView::keyPressEvent(QKeyEvent *event) +{ + if (model() && event->key() == Qt::Key_Delete) { + removeSelected(); + event->setAccepted(true); + } else { + QAbstractItemView::keyPressEvent(event); + } +} + +void EditTreeView::removeSelected() +{ + if (!model() || !selectionModel() || !selectionModel()->hasSelection()) + return; + + QModelIndexList selectedRows = selectionModel()->selectedRows(); + for (int i = selectedRows.count() - 1; i >= 0; --i) { + QModelIndex idx = selectedRows.at(i); + model()->removeRow(idx.row(), idx.parent()); + } +} + +void EditTreeView::removeAll() +{ + if (!model()) + return; + + model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); +} + diff --git a/src/utils/edittreeview.h b/src/utils/edittreeview.h new file mode 100644 index 00000000..47663c79 --- /dev/null +++ b/src/utils/edittreeview.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2008, Benjamin C. Meyer + * Copyright (c) 2009, Jakub Wieczorek + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef EDITTREEVIEW_H +#define EDITTREEVIEW_H + +#include + +class EditTreeView : public QTreeView +{ + Q_OBJECT + +public: + EditTreeView(QWidget *parent = 0); + void keyPressEvent(QKeyEvent *event); + +public slots: + void removeSelected(); + void removeAll(); + +}; + +#endif // EDITTREEVIEW_H + diff --git a/src/utils/explorerstyle.cpp b/src/utils/explorerstyle.cpp new file mode 100644 index 00000000..4eafd5b5 --- /dev/null +++ b/src/utils/explorerstyle.cpp @@ -0,0 +1,351 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/**************************************************************************** +** +** Copyright (c) 2007 Trolltech ASA +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#include "explorerstyle.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifndef HTHEME +#define HTHEME void* +#endif + +typedef HANDLE (WINAPI *PtrOpenThemeData)(HWND hwnd, LPCWSTR pszClassList); +typedef HRESULT (WINAPI *PtrDrawThemeBackground)(HANDLE hTheme, HDC hdc, int iPartId, int iStateId, + const RECT *pRect, OPTIONAL const RECT *pClipRect); +typedef bool (WINAPI *PtrIsAppThemed)(); + +static PtrDrawThemeBackground pDrawThemeBackground = 0; +static PtrOpenThemeData pOpenThemeData = 0; +static PtrIsAppThemed pIsAppThemed = 0; +static bool vista = false; + +bool isAppThemed() +{ +#ifdef Q_OS_WIN + return pIsAppThemed && pIsAppThemed(); +#else + return false; +#endif +} + +ExplorerStyle::ExplorerStyle() + : QWindowsVistaStyle() +{ +#ifdef Q_OS_WIN + QLibrary themeLib(QLatin1String("uxtheme")); + themeLib.load(); + if (themeLib.isLoaded()) { //resolve uxtheme functions + pIsAppThemed = (PtrIsAppThemed)themeLib.resolve("IsAppThemed"); + pDrawThemeBackground = (PtrDrawThemeBackground)themeLib.resolve("DrawThemeBackground"); + pOpenThemeData = (PtrOpenThemeData)themeLib.resolve("OpenThemeData"); + } +#endif + vista = QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA && QSysInfo::WindowsVersion < QSysInfo::WV_NT_based; +} + +void drawRebarBackground(const QRect &rect, QPainter *painter) { + if (rect.isEmpty()) + return; + QString cacheKey = QLatin1String("q_rebar_") + QString::number(rect.size().width()) + + QLatin1Char('x') + QString::number(rect.size().height()); + QPixmap pixmap; + if (!QPixmapCache::find(cacheKey, pixmap)) { + pixmap = QPixmap(rect.size()); + const RECT wRect = {0, 0, pixmap.width(), pixmap.height()}; + HBITMAP bitmap = pixmap.toWinHBITMAP(); + HDC hdc = CreateCompatibleDC(qt_win_display_dc()); + HGDIOBJ oldhdc = (HBITMAP)SelectObject(hdc, bitmap); + HTHEME theme = pOpenThemeData(0, L"REBAR"); + pDrawThemeBackground(theme, hdc, 0, 0, &wRect, NULL); + pixmap = pixmap.fromWinHBITMAP(bitmap); + SelectObject(hdc, oldhdc); + DeleteObject(bitmap); + DeleteDC(hdc); + QPixmapCache::insert(cacheKey, pixmap); + } + painter->drawPixmap(rect.topLeft(), pixmap); +} + +void ExplorerStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const +{ + QRect rect = option->rect; + switch (element) { + case PE_Widget: + if (isAppThemed()) { + if (QMainWindow *window = qobject_cast(widget->window())) { + QRegion topreg; + QRegion bottomreg; + QMenuBar *menubar = qFindChild(window); + + //We draw the menubar as part of the top toolbar area + if (menubar) { + QRect rect(menubar->mapToParent(menubar->rect().topLeft()), menubar->rect().size()); + topreg += rect; + } + + //We need the bounding rect for all toolbars + QList toolbars = qFindChildren(window); + foreach (const QToolBar *tb, toolbars) { + if (!tb->isFloating()) { + QRect rect(tb->mapToParent(tb->rect().topLeft()), tb->rect().size()); + if (window->toolBarArea(const_cast(tb)) == Qt::TopToolBarArea) + topreg += rect; + else if (window->toolBarArea(const_cast(tb)) == Qt::BottomToolBarArea) + bottomreg += rect; + } + } + + //This is a hack to workaround missing toolbar updates since + //we now require updates that span across the whole toolbar area: + QRect topRect = topreg.boundingRect(); + topRect.setWidth(window->width()); + if (m_currentTopRect != topRect) { + m_currentTopRect = topRect; + window->update(topRect); + } + + QRect bottomRect = bottomreg.boundingRect(); + bottomRect.setWidth(window->width()); + if (m_currentBottomRect != bottomRect) { + m_currentBottomRect = bottomRect; + window->update(bottomRect); + } + + //Fill top toolbar area with gradient + drawRebarBackground(topRect, painter); + //Fill bottom toolbar area with gradient + drawRebarBackground(bottomRect, painter); + } + break; + + } //fall through + default: + if (vista) + QWindowsVistaStyle::drawPrimitive(element, option, painter, widget); + else + QWindowsXPStyle::drawPrimitive(element, option, painter, widget); + break; + } +} + +void ExplorerStyle::drawControl(ControlElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const +{ + QColor shadow = option->palette.dark().color(); + shadow.setAlpha(120); + + switch (element) { + case CE_DockWidgetTitle: + if (isAppThemed()) { + if (const QStyleOptionDockWidget *dwOpt = qstyleoption_cast(option)) { + painter->save(); + QStyleOptionDockWidget adjustedOpt = *dwOpt; + QRect rect = option->rect.adjusted(0, 1, -1, -2); + adjustedOpt.palette.setBrush(QPalette::All, QPalette::Dark, Qt::transparent); + painter->save(); + painter->setClipRect(rect); + drawRebarBackground(rect.adjusted(0, 0, 1, 1), painter); + painter->restore(); + painter->setPen(shadow); + painter->drawRect(rect); + QWindowsXPStyle::drawControl(element, &adjustedOpt, painter, widget); + painter->restore(); + } + break; + } //fall through + + case CE_MenuBarItem: + if (isAppThemed()) { + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast(option)) { + QStyleOptionMenuItem adjustedItem = *mbi; + adjustedItem.palette.setBrush(QPalette::All, QPalette::Dark, shadow); + adjustedItem.palette.setBrush(QPalette::All, QPalette::Button, Qt::NoBrush); + QWindowsXPStyle::drawControl(element, &adjustedItem, painter, widget); + } + break; + } //fall through + + case CE_MenuBarEmptyArea: + if (isAppThemed()) { + if (const QStyleOptionMenuItem *mbi = qstyleoption_cast(option)) { + QStyleOptionMenuItem adjustedItem = *mbi; + adjustedItem.palette.setBrush(QPalette::All, QPalette::Dark, shadow); + adjustedItem.palette.setBrush(QPalette::All, QPalette::Button, Qt::NoBrush); + QWindowsXPStyle::drawControl(element, &adjustedItem, painter, widget); + } + break; + } //fall through + + case CE_ToolBar: + if (isAppThemed()) { + if (const QStyleOptionToolBar *toolbar = qstyleoption_cast(option)) { + QStyleOptionToolBar adjustedToolBar = *toolbar; + adjustedToolBar.palette.setBrush(QPalette::All, QPalette::Dark, shadow); + QWindowsXPStyle::drawControl(element, &adjustedToolBar, painter, widget); + } + break; + } //fall through + + default: + if (vista) + QWindowsVistaStyle::drawControl(element, option, painter, widget); + else + QWindowsXPStyle::drawControl(element, option, painter, widget); + break; + } +} + +void ExplorerStyle::drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const +{ + if (vista) + QWindowsVistaStyle::drawComplexControl(control, option, painter, widget); + else + QWindowsXPStyle::drawComplexControl(control, option, painter, widget); +} + +QSize ExplorerStyle::sizeFromContents(ContentsType type, const QStyleOption *option, + const QSize &size, const QWidget *widget) const +{ + if (vista) + return QWindowsVistaStyle::sizeFromContents(type, option, size, widget); + else + return QWindowsXPStyle::sizeFromContents(type, option, size, widget); +} + +QRect ExplorerStyle::subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const +{ + if (vista) + return QWindowsVistaStyle::subElementRect(element, option, widget); + else + return QWindowsXPStyle::subElementRect(element, option, widget); +} + +QRect ExplorerStyle::subControlRect(ComplexControl control, const QStyleOptionComplex *option, + SubControl subControl, const QWidget *widget) const +{ + if (vista) + return QWindowsVistaStyle::subControlRect(control, option, subControl, widget); + else + return QWindowsXPStyle::subControlRect(control, option, subControl, widget); +} + +QStyle::SubControl ExplorerStyle::hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, + const QPoint &pos, const QWidget *widget) const +{ + if (vista) + return QWindowsVistaStyle::hitTestComplexControl(control, option, pos, widget); + else + return QWindowsXPStyle::hitTestComplexControl(control, option, pos, widget); +} + +int ExplorerStyle::pixelMetric(PixelMetric metric, const QStyleOption *option, const QWidget *widget) const +{ + if (vista) + return QWindowsVistaStyle::pixelMetric(metric, option, widget); + else + return QWindowsXPStyle::pixelMetric(metric, option, widget); +} + +QPalette ExplorerStyle::standardPalette() +{ + if (vista) + return QWindowsVistaStyle::standardPalette(); + else + return QWindowsXPStyle::standardPalette(); +} + +void ExplorerStyle::polish(QApplication *app) +{ + if (vista) + QWindowsVistaStyle::polish(app); + else + QWindowsXPStyle::polish(app); +} + +void ExplorerStyle::unpolish(QApplication *app) +{ + if (vista) + QWindowsVistaStyle::unpolish(app); + else + QWindowsXPStyle::unpolish(app); +} + +void ExplorerStyle::polish(QWidget *widget) +{ + if (QMainWindow *window = qobject_cast(widget)) + window->setAttribute(Qt::WA_StyledBackground, true); + if (vista) + QWindowsVistaStyle::polish(widget); + else + QWindowsXPStyle::polish(widget); +} + +void ExplorerStyle::unpolish(QWidget *widget) +{ + if (vista) + QWindowsVistaStyle::unpolish(widget); + else + QWindowsXPStyle::unpolish(widget); +} + +void ExplorerStyle::polish(QPalette pal) +{ + if (vista) + QWindowsVistaStyle::polish(pal); + else + QWindowsXPStyle::polish(pal); +} + +QPixmap ExplorerStyle::standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, + const QWidget *widget) const +{ + if (vista) + return QWindowsVistaStyle::standardPixmap(standardPixmap, opt, widget); + else + return QWindowsXPStyle::standardPixmap(standardPixmap, opt, widget); +} diff --git a/src/utils/explorerstyle.h b/src/utils/explorerstyle.h new file mode 100644 index 00000000..840bcd2d --- /dev/null +++ b/src/utils/explorerstyle.h @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/**************************************************************************** +** +** Copyright (c) 2007 Trolltech ASA +** +** Use, modification and distribution is allowed without limitation, +** warranty, liability or support of any kind. +** +****************************************************************************/ + +#ifndef EXPLORERSTYLE_H +#define EXPLORERSTYLE_H + +#include + +class ExplorerStyle : public QWindowsVistaStyle +{ +public: + ExplorerStyle(); + void drawPrimitive(PrimitiveElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget = 0) const; + void drawControl(ControlElement element, const QStyleOption *option, + QPainter *painter, const QWidget *widget) const; + void drawComplexControl(ComplexControl control, const QStyleOptionComplex *option, + QPainter *painter, const QWidget *widget) const; + QSize sizeFromContents(ContentsType type, const QStyleOption *option, + const QSize &size, const QWidget *widget) const; + QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const; + QRect subControlRect(ComplexControl cc, const QStyleOptionComplex *opt, + SubControl sc, const QWidget *widget) const; + SubControl hitTestComplexControl(ComplexControl control, const QStyleOptionComplex *option, + const QPoint &pos, const QWidget *widget = 0) const; + QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption *opt, + const QWidget *widget = 0) const; + int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const; + void polish(QWidget *widget); + void unpolish(QWidget *widget); + void polish(QPalette pal); + void polish(QApplication *app); + void unpolish(QApplication *app); + QPalette standardPalette(); + +private: + mutable QRect m_currentTopRect; //current toolbar top area size + mutable QRect m_currentBottomRect; //current toolbar top area size +}; + +#endif //EXPLORERSTYLE_H diff --git a/src/utils/languagemanager.cpp b/src/utils/languagemanager.cpp new file mode 100644 index 00000000..af33792c --- /dev/null +++ b/src/utils/languagemanager.cpp @@ -0,0 +1,303 @@ +/* + * Copyright 2008-2009 Diego Iastrubni, elcuco, at, kde.org + * Copyright 2008-2009 Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "languagemanager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +// #define LANGUAGEMANAGER_DEBUG + +LanguageManager::LanguageManager(QObject *parent) + : QObject(parent) + , m_sysTranslator(0) + , m_appTranslator(0) + , m_loaded(false) +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__; +#endif +} + +void LanguageManager::addLocaleDirectory(const QString &directory) +{ + m_localeDirectories.append(directory); +} + +QStringList LanguageManager::localeDirectories() const +{ + return m_localeDirectories; +} + +QString LanguageManager::currentLanguage() const +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__; +#endif + if (!m_currentLanguage.isEmpty()) + return m_currentLanguage; + + const QString sysLanguage = QLocale::system().name(); + if (isLanguageAvailable(sysLanguage)) + return sysLanguage; + return QString(); +} + +bool LanguageManager::isLanguageAvailable(const QString &language) const +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__ << language; +#endif + if (language.isEmpty()) + return true; + + // optimization so we don't have to load all the languages + if (!m_loaded) { + foreach (const QString &dir, m_localeDirectories) { + QString file = dir + QLatin1Char('/') + language + QLatin1String(".qm"); + if (QFile::exists(file)) + return true; + } + } + + return !(convertStringToLanguageFile(language).isEmpty()); +} + +// Return an empty string if we do not have the language file for string +// If we don't have an exact ma +// - Fall back to country +// - Fall back to the first country_ match if there is one +QString LanguageManager::convertStringToLanguageFile(const QString &string) const +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__ << string; +#endif + loadAvailableLanguages(); + if (m_languages.contains(string)) + return string; + QLocale locale(string); + QString fallback = locale.name().split(QLatin1Char('_')).value(0); + if (!string.contains(fallback)) + return QString(); +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__ << "fallback" << fallback; +#endif + if (m_languages.contains(fallback)) // fallback to the country + return fallback; + + // See if any language file matches the country + foreach (const QString &language, m_languages) { + QString country = QLocale(language).name().split(QLatin1Char('_')).value(0); + if (country == fallback) + return country; + } + + return QString(); +} + +bool LanguageManager::setCurrentLanguage(const QString &language) +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__ << language; +#endif + if (m_currentLanguage == language + || !isLanguageAvailable(language)) + return false; + + m_currentLanguage = language; + + QSettings settings; + settings.beginGroup(QLatin1String("LanguageManager")); + settings.setValue(QLatin1String("language"), m_currentLanguage); + + if (m_currentLanguage.isEmpty()) { + delete m_appTranslator; + delete m_sysTranslator; + m_appTranslator = 0; + m_sysTranslator = 0; + emit languageChanged(currentLanguage()); + return true; + } + + QTranslator *newAppTranslator = new QTranslator(this); + QString resourceDir = QLibraryInfo::location(QLibraryInfo::TranslationsPath); + QString languageFile = convertStringToLanguageFile(m_currentLanguage); + bool loaded = false; + foreach (const QString &dir, m_localeDirectories) { + loaded = newAppTranslator->load(languageFile, dir); + if (loaded) + break; + } + + QTranslator *newSysTranslator = new QTranslator(this); + QString translatorFileName = QLatin1String("qt_") + languageFile; + if (!newSysTranslator->load(translatorFileName, resourceDir)) { + delete newSysTranslator; + newSysTranslator = 0; + } + + if (!loaded) { + qWarning() << "Failed to load translation:" << currentLanguage(); + delete newAppTranslator; + delete newSysTranslator; + return false; + } + + QLocale::setDefault(QLocale(m_currentLanguage)); + + // A new language event is sent to all widgets in the application + // They need to catch it and re-translate + delete m_appTranslator; + delete m_sysTranslator; + qApp->installTranslator(newAppTranslator); + qApp->installTranslator(newSysTranslator); + m_appTranslator = newAppTranslator; + m_sysTranslator = newSysTranslator; + emit languageChanged(currentLanguage()); + return true; +} + +QStringList LanguageManager::languages() const +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__; +#endif + loadAvailableLanguages(); + return m_languages; +} + +void LanguageManager::loadLanguageFromSettings() +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__; +#endif + + QSettings settings; + settings.beginGroup(QLatin1String("LanguageManager")); + if (settings.contains(QLatin1String("language"))) { + QString selectedLanguage = settings.value(QLatin1String("language")).toString(); +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__ << "Loading language from settings" << selectedLanguage; +#endif + // When a translation fails to load remove it from the settings + // to prevent it from being loaded every time. + if (!setCurrentLanguage(selectedLanguage)) { +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__ << "Failed to load language"; +#endif + settings.remove(QLatin1String("language")); + } + } else if (!currentLanguage().isEmpty()) { + setCurrentLanguage(currentLanguage()); + } +} + +void LanguageManager::chooseNewLanguage() +{ +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__; +#endif + loadAvailableLanguages(); + if (m_languages.isEmpty()) { + QMessageBox messageBox; + QLatin1String separator = QLatin1String(", "); + messageBox.setText(tr("No translation files are installed at %1.") + .arg(m_localeDirectories.join(separator))); + messageBox.setStandardButtons(QMessageBox::Ok); + messageBox.exec(); + return; + } + + QStringList items; + int defaultItem = -1; + QString current = currentLanguage(); + foreach (const QString &name, m_languages) { + QLocale locale(name); + QString string = QString(QLatin1String("%1, %2 (%3) %4")) + .arg(QLocale::languageToString(locale.language())) + .arg(QLocale::countryToString(locale.country())) + .arg(name) + // this is for pretty RTL support + .arg(QChar(0x200E)); // LRM = 0x200E + if (name == current) + defaultItem = items.count(); + items << string; + } + items << QLatin1String("English (en_US)"); + if (defaultItem == -1) + defaultItem = items.count() - 1; + + bool ok; + QString item = QInputDialog::getItem(0, + tr("Choose language"), + tr("

    You can run with a different language than
    " + "the operating system default.

    " + "

    Please choose the language which should be used

    "), + items, defaultItem, false, &ok); + if (!ok) + return; + + int selection = items.indexOf(item); + setCurrentLanguage(m_languages.value(selection)); +} + +/*! + Find all *.qm files in the data directory that have a Qt translation. + */ +void LanguageManager::loadAvailableLanguages() const +{ + if (m_loaded) + return; + m_loaded = true; +#ifdef LANGUAGEMANAGER_DEBUG + qDebug() << "LanguageManager::" << __FUNCTION__; +#endif + + foreach (const QString &dir, m_localeDirectories) { + QDirIterator it(dir); + while (it.hasNext()) { + QString fileName = it.next(); + if (!fileName.endsWith(QLatin1String(".qm"))) + continue; + const QFileInfo info = it.fileInfo(); + QString language = info.completeBaseName(); + m_languages.append(language); + } + } +} diff --git a/src/utils/languagemanager.h b/src/utils/languagemanager.h new file mode 100644 index 00000000..58d12a3e --- /dev/null +++ b/src/utils/languagemanager.h @@ -0,0 +1,75 @@ +/* + * Copyright 2008-2009 Diego Iastrubni, elcuco, at, kde.org + * Copyright 2008-2009 Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef LANGUAGEMANAGER_H +#define LANGUAGEMANAGER_H + +#include + +#include + +class QTranslator; +class LanguageManager : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString currentLanguage READ currentLanguage WRITE setCurrentLanguage) + +signals: + void languageChanged(const QString &language); + +public: + LanguageManager(QObject *parent = 0); + + void addLocaleDirectory(const QString &directory); + QStringList localeDirectories() const; + + QString currentLanguage() const; + bool setCurrentLanguage(const QString &language); + + QStringList languages() const; + bool isLanguageAvailable(const QString &language) const; + +public slots: + void loadLanguageFromSettings(); + void chooseNewLanguage(); + +private: + QString convertStringToLanguageFile(const QString &string) const; + void loadAvailableLanguages() const; + + QString m_currentLanguage; + QTranslator *m_sysTranslator; + QTranslator *m_appTranslator; + mutable bool m_loaded; + mutable QStringList m_languages; + QStringList m_localeDirectories; +}; + +#endif //LANGUAGEMANAGER_H + diff --git a/src/utils/lineedit.cpp b/src/utils/lineedit.cpp new file mode 100644 index 00000000..9070986a --- /dev/null +++ b/src/utils/lineedit.cpp @@ -0,0 +1,232 @@ +/** + * Copyright (c) 2008 - 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "lineedit.h" +#include "lineedit_p.h" + +#include +#include +#include +#include + +#include + +SideWidget::SideWidget(QWidget *parent) + : QWidget(parent) +{ +} + +bool SideWidget::event(QEvent *event) +{ + if (event->type() == QEvent::LayoutRequest) + emit sizeHintChanged(); + return QWidget::event(event); +} + +LineEdit::LineEdit(QWidget *parent) + : QLineEdit(parent) + , m_leftLayout(0) + , m_rightLayout(0) +{ + init(); +} + +LineEdit::LineEdit(const QString &contents, QWidget *parent) + : QLineEdit(contents, parent) + , m_leftWidget(0) + , m_rightWidget(0) + , m_leftLayout(0) + , m_rightLayout(0) +{ + init(); +} + +void LineEdit::init() +{ + m_leftWidget = new SideWidget(this); + m_leftWidget->resize(0, 0); + m_leftLayout = new QHBoxLayout(m_leftWidget); + m_leftLayout->setContentsMargins(0, 0, 0, 0); + if (isRightToLeft()) + m_leftLayout->setDirection(QBoxLayout::RightToLeft); + else + m_leftLayout->setDirection(QBoxLayout::LeftToRight); + m_leftLayout->setSizeConstraint(QLayout::SetFixedSize); + + m_rightWidget = new SideWidget(this); + m_rightWidget->resize(0, 0); + m_rightLayout = new QHBoxLayout(m_rightWidget); + if (isRightToLeft()) + m_rightLayout->setDirection(QBoxLayout::RightToLeft); + else + m_rightLayout->setDirection(QBoxLayout::LeftToRight); + m_rightLayout->setContentsMargins(0, 0, 0, 0); + + QSpacerItem *horizontalSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum); + m_rightLayout->addItem(horizontalSpacer); + + setWidgetSpacing(3); + connect(m_leftWidget, SIGNAL(sizeHintChanged()), + this, SLOT(updateTextMargins())); + connect(m_rightWidget, SIGNAL(sizeHintChanged()), + this, SLOT(updateTextMargins())); +} + +bool LineEdit::event(QEvent *event) +{ + if (event->type() == QEvent::LayoutDirectionChange) { + if (isRightToLeft()) { + m_leftLayout->setDirection(QBoxLayout::RightToLeft); + m_rightLayout->setDirection(QBoxLayout::RightToLeft); + } else { + m_leftLayout->setDirection(QBoxLayout::LeftToRight); + m_rightLayout->setDirection(QBoxLayout::LeftToRight); + } + } + return QLineEdit::event(event); +} + +void LineEdit::addWidget(QWidget *widget, WidgetPosition position) +{ + if (!widget) + return; + + bool rtl = isRightToLeft(); + if (rtl) + position = (position == LeftSide) ? RightSide : LeftSide; + if (position == LeftSide) { + m_leftLayout->addWidget(widget); + } else { + m_rightLayout->insertWidget(1, widget); + } +} + +void LineEdit::removeWidget(QWidget *widget) +{ + if (!widget) + return; + + m_leftLayout->removeWidget(widget); + m_rightLayout->removeWidget(widget); + widget->hide(); +} + +void LineEdit::setWidgetSpacing(int spacing) +{ + m_leftLayout->setSpacing(spacing); + m_rightLayout->setSpacing(spacing); + updateTextMargins(); +} + +int LineEdit::widgetSpacing() const +{ + return m_leftLayout->spacing(); +} + +int LineEdit::textMargin(WidgetPosition position) const +{ + int spacing = m_rightLayout->spacing(); + int w = 0; + if (position == LeftSide) + w = m_leftWidget->sizeHint().width(); + else + w = m_rightWidget->sizeHint().width(); + if (w == 0) + return 0; + return w + spacing * 2; +} + +void LineEdit::updateTextMargins() +{ + int left = textMargin(LineEdit::LeftSide); + int right = textMargin(LineEdit::RightSide); + int top = 0; + int bottom = 0; + setTextMargins(left, top, right, bottom); + updateSideWidgetLocations(); +} + +void LineEdit::updateSideWidgetLocations() +{ + QStyleOptionFrameV2 opt; + initStyleOption(&opt); + QRect textRect = style()->subElementRect(QStyle::SE_LineEditContents, &opt, this); + int spacing = m_rightLayout->spacing(); + textRect.adjust(spacing, 0, -spacing, 0); + + int left = textMargin(LineEdit::LeftSide); + + int midHeight = textRect.center().y() + 1; + + if (m_leftLayout->count() > 0) { + int leftHeight = midHeight - m_leftWidget->height() / 2; + int leftWidth = m_leftWidget->width(); + if (leftWidth == 0) + leftHeight = midHeight - m_leftWidget->sizeHint().height() / 2; + m_leftWidget->move(textRect.x(), leftHeight); + } + textRect.setX(left); + textRect.setY(midHeight - m_rightWidget->sizeHint().height() / 2); + textRect.setHeight(m_rightWidget->sizeHint().height()); + m_rightWidget->setGeometry(textRect); +} + +void LineEdit::resizeEvent(QResizeEvent *event) +{ + updateSideWidgetLocations(); + QLineEdit::resizeEvent(event); +} + +QString LineEdit::inactiveText() const +{ + return m_inactiveText; +} + +void LineEdit::setInactiveText(const QString &text) +{ + m_inactiveText = text; +} + +void LineEdit::paintEvent(QPaintEvent *event) +{ + QLineEdit::paintEvent(event); + if (text().isEmpty() && !m_inactiveText.isEmpty() && !hasFocus()) { + QStyleOptionFrameV2 panel; + initStyleOption(&panel); + QRect textRect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this); + int horizontalMargin = 2; + textRect.adjust(horizontalMargin, 0, 0, 0); + int left = textMargin(LineEdit::LeftSide); + int right = textMargin(LineEdit::RightSide); + textRect.adjust(left, 0, -right, 0); + QPainter painter(this); + painter.setPen(palette().brush(QPalette::Disabled, QPalette::Text).color()); + painter.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, m_inactiveText); + } +} + diff --git a/src/utils/lineedit.h b/src/utils/lineedit.h new file mode 100644 index 00000000..1eeec3a7 --- /dev/null +++ b/src/utils/lineedit.h @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2008 - 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef LINEEDIT_H +#define LINEEDIT_H + +#include + +class QHBoxLayout; + +/* + LineEdit is a subclass of QLineEdit that provides an easy and simple + way to add widgets on the left or right hand side of the text. + + The layout of the widgets on either side are handled by a QHBoxLayout. + You can set the spacing around the widgets with setWidgetSpacing(). + + As widgets are added to the class they are inserted from the outside + into the center of the widget. +*/ +class SideWidget; +class LineEdit : public QLineEdit +{ + Q_OBJECT + Q_PROPERTY(QString inactiveText READ inactiveText WRITE setInactiveText) + +public: + enum WidgetPosition { + LeftSide, + RightSide + }; + + LineEdit(QWidget *parent = 0); + LineEdit(const QString &contents, QWidget *parent = 0); + + void addWidget(QWidget *widget, WidgetPosition position); + void removeWidget(QWidget *widget); + void setWidgetSpacing(int spacing); + int widgetSpacing() const; + int textMargin(WidgetPosition position) const; + QString inactiveText() const; + void setInactiveText(const QString &text); + + void paintEvent(QPaintEvent *event); + +protected: + void resizeEvent(QResizeEvent *event); + bool event(QEvent *event); + +protected slots: + void updateTextMargins(); + +private: + void init(); + void updateSideWidgetLocations(); + + SideWidget *m_leftWidget; + SideWidget *m_rightWidget; + QHBoxLayout *m_leftLayout; + QHBoxLayout *m_rightLayout; + QString m_inactiveText; +}; + +#endif // LINEEDIT_H + diff --git a/src/utils/lineedit_p.h b/src/utils/lineedit_p.h new file mode 100644 index 00000000..44181ad1 --- /dev/null +++ b/src/utils/lineedit_p.h @@ -0,0 +1,50 @@ +/** + * Copyright (c) 2008 - 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef LINEEDIT_P_H +#define LINEEDIT_P_H + +#include + +class SideWidget : public QWidget +{ + Q_OBJECT + +signals: + void sizeHintChanged(); + +public: + SideWidget(QWidget *parent = 0); + +protected: + bool event(QEvent *event); + +}; + +#endif // LINEEDIT_P_H + diff --git a/src/utils/networkaccessmanagerproxy.cpp b/src/utils/networkaccessmanagerproxy.cpp new file mode 100644 index 00000000..9ab28a1a --- /dev/null +++ b/src/utils/networkaccessmanagerproxy.cpp @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "networkaccessmanagerproxy.h" +#include "networkaccessmanagerproxy_p.h" + +#include "webpageproxy.h" + +#include +#include + +NetworkAccessManagerProxy *NetworkAccessManagerProxy::m_primaryManager = 0; + +/* + NetworkAccessManagerProxy inserts a pointer to the QWebPage in the + QNetworkRequest before passing it on. + */ +NetworkAccessManagerProxy::NetworkAccessManagerProxy(QObject *parent) + : QNetworkAccessManager(parent) + , m_webPage(0) +{ +} + +void NetworkAccessManagerProxy::setWebPage(WebPageProxy *page) +{ + Q_ASSERT(page); + m_webPage = page; +} + +void NetworkAccessManagerProxy::setPrimaryNetworkAccessManager(NetworkAccessManagerProxy *manager) +{ + Q_ASSERT(manager); + m_primaryManager = manager; + setCookieJar(new NetworkCookieJarProxy(this)); + + connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), + m_primaryManager, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*))); + connect(this, SIGNAL(finished(QNetworkReply *)), + m_primaryManager, SIGNAL(finished(QNetworkReply *))); + connect(this, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), + m_primaryManager, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); +#ifndef QT_NO_OPENSSL + connect(this, SIGNAL(sslErrors(QNetworkReply*, const QList&)), + m_primaryManager, SIGNAL(sslErrors(QNetworkReply*, const QList&))); +#endif +} + +QNetworkReply *NetworkAccessManagerProxy::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData) +{ + if (m_primaryManager && m_webPage) { + QNetworkRequest pageRequest = request; + m_webPage->populateNetworkRequest(pageRequest); + return m_primaryManager->createRequest(op, pageRequest, outgoingData); + } + return QNetworkAccessManager::createRequest(op, request, outgoingData); +} + diff --git a/src/utils/networkaccessmanagerproxy.h b/src/utils/networkaccessmanagerproxy.h new file mode 100644 index 00000000..53fa1eb8 --- /dev/null +++ b/src/utils/networkaccessmanagerproxy.h @@ -0,0 +1,59 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NETWORKACCESSMANAGERPROXY_H +#define NETWORKACCESSMANAGERPROXY_H + +#include + +class WebPageProxy; +class NetworkAccessManagerProxy : public QNetworkAccessManager +{ + Q_OBJECT + +public: + NetworkAccessManagerProxy(QObject *parent = 0); + + void setPrimaryNetworkAccessManager(NetworkAccessManagerProxy *primaryManager); + NetworkAccessManagerProxy *primaryNetworkAccessManager() const { return m_primaryManager; } + + void setWebPage(WebPageProxy *page); + WebPageProxy *webPage() const { return m_webPage; }; + +protected: + QNetworkReply *createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0); + +private: + friend class NetworkCookieJarProxy; + static NetworkAccessManagerProxy *m_primaryManager; + WebPageProxy *m_webPage; + +}; + +#endif // NETWORKACCESSMANAGERPROXY_H + diff --git a/src/utils/networkaccessmanagerproxy_p.h b/src/utils/networkaccessmanagerproxy_p.h new file mode 100644 index 00000000..37790191 --- /dev/null +++ b/src/utils/networkaccessmanagerproxy_p.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NETWORKACCESSMANAGERPROXY_P_H +#define NETWORKACCESSMANAGERPROXY_P_H + +#include + +#include "networkaccessmanagerproxy.h" + +class NetworkCookieJarProxy : public QNetworkCookieJar +{ + Q_OBJECT + +public: + NetworkCookieJarProxy(QObject *parent = 0) + : QNetworkCookieJar(parent) { } + + inline QList cookiesForUrl(const QUrl &url) const + { return NetworkAccessManagerProxy::m_primaryManager->cookieJar()->cookiesForUrl(url); } + + inline bool setCookiesFromUrl(const QList &cookieList, const QUrl &url) + { return NetworkAccessManagerProxy::m_primaryManager->cookieJar()->setCookiesFromUrl(cookieList, url); } + +}; + +#endif // NETWORKACCESSMANAGERPROXY_P_H + diff --git a/src/utils/singleapplication.cpp b/src/utils/singleapplication.cpp new file mode 100644 index 00000000..d6220b2e --- /dev/null +++ b/src/utils/singleapplication.cpp @@ -0,0 +1,166 @@ +/** + * Copyright (c) 2008-2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "singleapplication.h" + +#include +#include +#include +#include +#include + +#ifndef Q_OS_WIN +#include +#else +#include +#endif + +// #define SINGALAPPLICATION_DEBUG + +SingleApplication::SingleApplication(int &argc, char **argv) + : QApplication(argc, argv) + , m_localServer(0) +{ +} + +bool SingleApplication::sendMessage(const QByteArray &message, int waitMsecsForReply) +{ +#ifdef SINGALAPPLICATION_DEBUG + qDebug() << "SingleApplication::" << __FUNCTION__ << message << waitMsecsForReply; +#endif + QLocalSocket socket; + socket.connectToServer(serverName()); + if (!socket.waitForConnected(500)) + return false; + socket.write(message); + socket.flush(); + socket.waitForBytesWritten(); + bool success = true; + if (socket.error() != QLocalSocket::UnknownSocketError) { +#ifdef SINGALAPPLICATION_DEBUG + qDebug() << "SingleApplication::" << __FUNCTION__ << socket.errorString(); +#endif + success = false; + } + if (success) { + socket.waitForReadyRead(waitMsecsForReply); + if (socket.bytesAvailable() > 0) + emit messageReceived(&socket); + } + return success; +} + +bool SingleApplication::startSingleServer() +{ + if (m_localServer) + return false; + + m_localServer = new QLocalServer(this); + connect(m_localServer, SIGNAL(newConnection()), + this, SLOT(newConnection())); + bool success = false; + if (!m_localServer->listen(serverName())) { + if (QAbstractSocket::AddressInUseError == m_localServer->serverError()) { + // cleanup from a segfaulted server +#ifdef Q_OS_UNIX + QString fullServerName = QDir::tempPath() + QLatin1String("/") + serverName(); + if (QFile::exists(fullServerName)) + QFile::remove(fullServerName); +#endif + if (m_localServer->listen(serverName())) { + success = true; + } + } + if (!success) { + qWarning() << "SingleApplication: Unable to listen:" << m_localServer->errorString(); + } + } else { + success = true; + } + + if (success) { +#ifdef Q_OS_UNIX + QFile file(m_localServer->fullServerName()); + if (!file.setPermissions(QFile::ReadUser | QFile::WriteUser)) + qWarning() << "SingleApplication: Unable to set permissions on:" + << file.fileName() << file.errorString(); +#endif + } + + if (!success) { + delete m_localServer; + m_localServer = 0; + } + return success; +} + +bool SingleApplication::isRunning() const +{ + return (0 != m_localServer); +} + +void SingleApplication::newConnection() +{ + QLocalSocket *socket = m_localServer->nextPendingConnection(); + if (!socket) + return; + socket->waitForReadyRead(); + emit messageReceived(socket); + delete socket; +} + +QString SingleApplication::serverName() const +{ + QString serverName = QCoreApplication::applicationName(); + Q_ASSERT(!serverName.isEmpty()); +#ifdef Q_WS_QWS + serverName += QLatin1String("_qws"); +#endif +#ifndef Q_OS_WIN + serverName += QString(QLatin1String("_%1_%2")).arg(getuid()).arg(getgid()); +#else + static QString login; + if (login.isEmpty()) { + QT_WA({ + wchar_t buffer[256]; + DWORD bufferSize = sizeof(buffer) / sizeof(wchar_t) - 1; + GetUserNameW(buffer, &bufferSize); + login = QString::fromUtf16((ushort*)buffer); + }, + { + char buffer[256]; + DWORD bufferSize = sizeof(buffer) / sizeof(char) - 1; + GetUserNameA(buffer, &bufferSize); + login = QString::fromLocal8Bit(buffer); + }); + } + serverName += QString::fromAscii("_%1").arg(login); +#endif + return serverName; +} + diff --git a/src/utils/singleapplication.h b/src/utils/singleapplication.h new file mode 100644 index 00000000..12c8ddb7 --- /dev/null +++ b/src/utils/singleapplication.h @@ -0,0 +1,64 @@ +/** + * Copyright (c) 2008-2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef SINGLEAPPLICATION_H +#define SINGLEAPPLICATION_H + +#include + +/* + QApplication subclass that should be used when you only want one + instant of the application to exist at a time. +*/ +class QLocalServer; +class QLocalSocket; +class SingleApplication : public QApplication +{ + Q_OBJECT + +signals: + void messageReceived(QLocalSocket *socket); + +public: + SingleApplication(int &argc, char **argv); + + bool sendMessage(const QByteArray &message, int waitMsecsForReply = 0); + bool startSingleServer(); + bool isRunning() const; + +private slots: + void newConnection(); + +private: + QString serverName() const; + QLocalServer *m_localServer; + +}; + +#endif // SINGLEAPPLICATION_H + diff --git a/src/utils/squeezelabel.cpp b/src/utils/squeezelabel.cpp new file mode 100644 index 00000000..ca29a39d --- /dev/null +++ b/src/utils/squeezelabel.cpp @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "squeezelabel.h" + +SqueezeLabel::SqueezeLabel(QWidget *parent) + : QLabel(parent) +{ +} + +void SqueezeLabel::paintEvent(QPaintEvent *event) +{ + if (m_SqueezedTextCache != text()) { + m_SqueezedTextCache = text(); + QFontMetrics fm = fontMetrics(); + if (fm.width(m_SqueezedTextCache) > contentsRect().width()) { + QString elided = fm.elidedText(text(), Qt::ElideMiddle, width()); + setText(elided); + } + } + QLabel::paintEvent(event); +} + diff --git a/src/utils/squeezelabel.h b/src/utils/squeezelabel.h new file mode 100644 index 00000000..dd4836ca --- /dev/null +++ b/src/utils/squeezelabel.h @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef SQUEEZELABEL_H +#define SQUEEZELABEL_H + +#include + +/* + A label that will squeeze the set text to fit within the size of the + widget. The text will be elided in the middle. + */ +class SqueezeLabel : public QLabel +{ + Q_OBJECT + +public: + SqueezeLabel(QWidget *parent = 0); + +protected: + void paintEvent(QPaintEvent *event); + +private: + QString m_SqueezedTextCache; +}; + +#endif // SQUEEZELABEL_H + diff --git a/src/utils/treesortfilterproxymodel.cpp b/src/utils/treesortfilterproxymodel.cpp new file mode 100644 index 00000000..139edf20 --- /dev/null +++ b/src/utils/treesortfilterproxymodel.cpp @@ -0,0 +1,44 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "treesortfilterproxymodel.h" + +TreeSortFilterProxyModel::TreeSortFilterProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ + setFilterCaseSensitivity(Qt::CaseInsensitive); +} + +bool TreeSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const +{ + QModelIndex idx = sourceModel()->index(source_row, 0, source_parent); + if (sourceModel()->hasChildren(idx)) + return true; + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +} + diff --git a/src/utils/treesortfilterproxymodel.h b/src/utils/treesortfilterproxymodel.h new file mode 100644 index 00000000..3b0d461a --- /dev/null +++ b/src/utils/treesortfilterproxymodel.h @@ -0,0 +1,47 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef TREESORTFILTERPROXYMODEL_H +#define TREESORTFILTERPROXYMODEL_H + +#include + +class TreeSortFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + TreeSortFilterProxyModel(QObject *parent = 0); + +protected: + bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const; + +}; + +#endif // TREESORTFILTERPROXYMODEL_H + diff --git a/src/utils/utils.pri b/src/utils/utils.pri new file mode 100644 index 00000000..fb10c559 --- /dev/null +++ b/src/utils/utils.pri @@ -0,0 +1,35 @@ +INCLUDEPATH += $$PWD +DEPENDPATH += $$PWD + +HEADERS += \ + editlistview.h \ + edittableview.h \ + edittreeview.h \ + languagemanager.h \ + lineedit.h \ + lineedit_p.h \ + networkaccessmanagerproxy.h \ + networkaccessmanagerproxy_p.h \ + singleapplication.h \ + squeezelabel.h \ + treesortfilterproxymodel.h \ + webpageproxy.h + +SOURCES += \ + editlistview.cpp \ + edittableview.cpp \ + edittreeview.cpp \ + languagemanager.cpp \ + lineedit.cpp \ + networkaccessmanagerproxy.cpp \ + singleapplication.cpp \ + squeezelabel.cpp \ + treesortfilterproxymodel.cpp \ + webpageproxy.cpp + +win32 { + HEADERS += explorerstyle.h + SOURCES += explorerstyle.cpp + LIBS += -lgdi32 +} + diff --git a/src/utils/webpageproxy.cpp b/src/utils/webpageproxy.cpp new file mode 100644 index 00000000..9504a038 --- /dev/null +++ b/src/utils/webpageproxy.cpp @@ -0,0 +1,51 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "webpageproxy.h" + +#include +#include + +#define ATTRIBUTE_ID QNetworkRequest::User + 100 + +WebPageProxy::WebPageProxy(QObject *parent) + : QWebPage(parent) +{ +} + +int WebPageProxy::pageAttributeId() +{ + return ATTRIBUTE_ID; +} + +void WebPageProxy::populateNetworkRequest(QNetworkRequest &request) +{ + QVariant variant = qVariantFromValue((void *) this); + request.setAttribute((QNetworkRequest::Attribute)(pageAttributeId()), variant); +} + diff --git a/src/utils/webpageproxy.h b/src/utils/webpageproxy.h new file mode 100644 index 00000000..572b411c --- /dev/null +++ b/src/utils/webpageproxy.h @@ -0,0 +1,49 @@ +/** + * Copyright (c) 2009, Benjamin C. Meyer + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Benjamin Meyer nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef WEBPAGEPROXY_H +#define WEBPAGEPROXY_H + +#include +#include + +class WebPageProxy : public QWebPage +{ + Q_OBJECT + +public: + WebPageProxy(QObject *parent = 0); + static int pageAttributeId(); + +protected: + friend class NetworkAccessManagerProxy; + virtual void populateNetworkRequest(QNetworkRequest &request); +}; + +#endif // WEBPAGEPROXY_H + diff --git a/src/webactionmapper.cpp b/src/webactionmapper.cpp index a6d4ddfa..e8e20e42 100644 --- a/src/webactionmapper.cpp +++ b/src/webactionmapper.cpp @@ -134,6 +134,8 @@ void WebActionMapper::updateCurrent(QWebPage *currentParent) return; } QAction *source = m_currentParent->action(m_webAction); + if (!source) + return; m_root->setChecked(source->isChecked()); m_root->setEnabled(source->isEnabled()); connect(m_currentParent, SIGNAL(destroyed(QObject *)), diff --git a/src/webkittrunk.pri b/src/webkittrunk.pri deleted file mode 100644 index c44b7d06..00000000 --- a/src/webkittrunk.pri +++ /dev/null @@ -1,17 +0,0 @@ -# -# export QT_WEBKIT=webkit_trunk -# export WEBKITHOME=$HOME/dev/webkit/ -# -CONFIG += $$(QT_WEBKIT) -webkit_trunk { - message(Using WebKit Trunk) - WEBKITHOME = $$(WEBKITHOME) - QT -= webkit - debug: QMAKE_LIBDIR_FLAGS = -L$$WEBKITHOME/WebKitBuild/Debug/lib - release: QMAKE_LIBDIR_FLAGS = -L$$WEBKITHOME/WebKitBuild/Release/lib - LIBS = -lQtWebKit - INCLUDEPATH = $$WEBKITHOME/WebKit/qt/Api $$INCLUDEPATH - release: QMAKE_RPATHDIR = $$WEBKITHOME/WebKitBuild/Release/lib $$QMAKE_RPATHDIR - debug: QMAKE_RPATHDIR = $$WEBKITHOME/WebKitBuild/Debug/lib $$QMAKE_RPATHDIR -} - diff --git a/src/webpage.cpp b/src/webpage.cpp new file mode 100644 index 00000000..42daf7a2 --- /dev/null +++ b/src/webpage.cpp @@ -0,0 +1,448 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * Copyright 2009 Jakub Wieczorek + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include "webpage.h" + +#include "browserapplication.h" +#include "downloadmanager.h" +#include "historymanager.h" +#include "networkaccessmanager.h" +#include "opensearchengine.h" +#include "opensearchmanager.h" +#include "tabwidget.h" +#include "toolbarsearch.h" +#include "webpluginfactory.h" +#include "webview.h" + +#include +#include +#include +#include +#include +#include +#include + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +#include +#endif + +WebPluginFactory *WebPage::s_webPluginFactory = 0; +QString WebPage::s_userAgent; + +JavaScriptExternalObject::JavaScriptExternalObject(QObject *parent) + : QObject(parent) +{ +} + +void JavaScriptExternalObject::AddSearchProvider(const QString &url) +{ + ToolbarSearch::openSearchManager()->addEngine(QUrl(url)); +} + +Q_DECLARE_METATYPE(OpenSearchEngine*) +JavaScriptAroraObject::JavaScriptAroraObject(QObject *parent) + : QObject(parent) +{ + static const char *translations[] = { + QT_TR_NOOP("Welcome to Arora!"), + QT_TR_NOOP("Arora Start"), + QT_TR_NOOP("Search!"), + QT_TR_NOOP("Search results provided by"), + QT_TR_NOOP("About Arora") + }; + Q_UNUSED(translations); + + qRegisterMetaType("OpenSearchEngine*"); +} + +QString JavaScriptAroraObject::translate(const QString &string) +{ + QString translatedString = trUtf8(string.toUtf8().constData()); + + // If the translation is the same as the original string + // it could not be translated. In that case + // try to translate using the QApplication domain + if (translatedString != string) + return translatedString; + else + return qApp->trUtf8(string.toUtf8().constData()); +} + +QObject *JavaScriptAroraObject::currentEngine() const +{ + return ToolbarSearch::openSearchManager()->currentEngine(); +} + +QString JavaScriptAroraObject::searchUrl(const QString &string) const +{ + return QString::fromUtf8(ToolbarSearch::openSearchManager()->currentEngine()->searchUrl(string).toEncoded()); +} + +WebPage::WebPage(QObject *parent) + : WebPageProxy(parent) + , m_openTargetBlankLinksIn(TabWidget::NewWindow) + , m_javaScriptExternalObject(0) + , m_javaScriptAroraObject(0) +{ + setPluginFactory(webPluginFactory()); + NetworkAccessManagerProxy *networkManagerProxy = new NetworkAccessManagerProxy(this); + networkManagerProxy->setWebPage(this); + networkManagerProxy->setPrimaryNetworkAccessManager(BrowserApplication::networkAccessManager()); + setNetworkAccessManager(networkManagerProxy); + connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), + this, SLOT(handleUnsupportedContent(QNetworkReply *))); + connect(this, SIGNAL(frameCreated(QWebFrame *)), + this, SLOT(addExternalBinding(QWebFrame *))); + addExternalBinding(mainFrame()); + loadSettings(); +} + +WebPage::~WebPage() +{ + setNetworkAccessManager(0); +} + +WebPluginFactory *WebPage::webPluginFactory() +{ + if (!s_webPluginFactory) + s_webPluginFactory = new WebPluginFactory(BrowserApplication::instance()); + return s_webPluginFactory; +} + +QList WebPage::linkedResources(const QString &relation) +{ + QList resources; + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + QUrl baseUrl = mainFrame()->baseUrl(); + + QWebElementCollection linkElements = mainFrame()->findAllElements(QLatin1String("html > head > link")); + + foreach (const QWebElement &linkElement, linkElements) { + QString rel = linkElement.attribute(QLatin1String("rel")); + QString href = linkElement.attribute(QLatin1String("href")); + QString type = linkElement.attribute(QLatin1String("type")); + QString title = linkElement.attribute(QLatin1String("title")); + + if (href.isEmpty() || type.isEmpty()) + continue; + if (!relation.isEmpty() && rel != relation) + continue; + + WebPageLinkedResource resource; + resource.rel = rel; + resource.type = type; + resource.href = baseUrl.resolved(QUrl::fromEncoded(href.toUtf8())); + resource.title = title; + + resources.append(resource); + } +#else + QString baseUrlString = mainFrame()->evaluateJavaScript(QLatin1String("document.baseURI")).toString(); + QUrl baseUrl = QUrl::fromEncoded(baseUrlString.toUtf8()); + + QFile file(QLatin1String(":fetchLinks.js")); + if (!file.open(QFile::ReadOnly)) + return resources; + QString script = QString::fromUtf8(file.readAll()); + + QVariantList list = mainFrame()->evaluateJavaScript(script).toList(); + foreach (const QVariant &variant, list) { + QVariantMap map = variant.toMap(); + QString rel = map[QLatin1String("rel")].toString(); + QString type = map[QLatin1String("type")].toString(); + QString href = map[QLatin1String("href")].toString(); + QString title = map[QLatin1String("title")].toString(); + + if (href.isEmpty() || type.isEmpty()) + continue; + if (!relation.isEmpty() && rel != relation) + continue; + + WebPageLinkedResource resource; + resource.rel = rel; + resource.type = type; + resource.href = baseUrl.resolved(QUrl::fromEncoded(href.toUtf8())); + resource.title = title; + + resources.append(resource); + } +#endif + + return resources; +} + +void WebPage::populateNetworkRequest(QNetworkRequest &request) +{ + if (request == lastRequest) { + request.setAttribute((QNetworkRequest::Attribute)(pageAttributeId() + 1), lastRequestType); + } + WebPageProxy::populateNetworkRequest(request); +} + +void WebPage::addExternalBinding(QWebFrame *frame) +{ +#if QT_VERSION < 0x040600 + QWebSettings *defaultSettings = QWebSettings::globalSettings(); + if (!defaultSettings->testAttribute(QWebSettings::JavascriptEnabled)) + return; +#endif + if (!m_javaScriptExternalObject) + m_javaScriptExternalObject = new JavaScriptExternalObject(this); + + if (frame == 0) { // called from QWebFrame::javaScriptWindowObjectCleared + frame = qobject_cast(sender()); + + if (frame->url().scheme() == QLatin1String("qrc") + && frame->url().path() == QLatin1String("/startpage.html")) { + + if (!m_javaScriptAroraObject) + m_javaScriptAroraObject = new JavaScriptAroraObject(this); + + frame->addToJavaScriptWindowObject(QLatin1String("arora"), m_javaScriptAroraObject); + } + } else { // called from QWebPage::frameCreated + connect(frame, SIGNAL(javaScriptWindowObjectCleared()), + this, SLOT(addExternalBinding())); + } + frame->addToJavaScriptWindowObject(QLatin1String("external"), m_javaScriptExternalObject); +} + +QString WebPage::userAgent() +{ + return s_userAgent; +} + +void WebPage::setUserAgent(const QString &userAgent) +{ + if (userAgent == s_userAgent) + return; + + QSettings settings; + if (userAgent.isEmpty()) { + settings.remove(QLatin1String("userAgent")); + } else { + settings.setValue(QLatin1String("userAgent"), userAgent); + } + + s_userAgent = userAgent; +} + +QString WebPage::userAgentForUrl(const QUrl &url) const +{ + if (s_userAgent.isEmpty()) + s_userAgent = QWebPage::userAgentForUrl(url); + return s_userAgent; +} + +bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, + NavigationType type) +{ + lastRequest = request; + lastRequestType = type; + + QString scheme = request.url().scheme(); + if (scheme == QLatin1String("mailto") + || scheme == QLatin1String("ftp")) { + BrowserApplication::instance()->askDesktopToOpenUrl(request.url()); + return false; + } + + if (type == QWebPage::NavigationTypeFormResubmitted) { + QMessageBox::StandardButton button = QMessageBox::warning(view(), tr("Resending POST request"), + tr("In order to display the site, the request along with all the data must be sent once again, " + "which may lead to some unexpected behaviour of the site e.g. the same action might be " + "performed once again. Do you want to continue anyway?"), QMessageBox::Yes | QMessageBox::No); + if (button != QMessageBox::Yes) + return false; + } + + TabWidget::OpenUrlIn openIn = frame ? TabWidget::CurrentTab : TabWidget::NewWindow; + openIn = TabWidget::modifyWithUserBehavior(openIn); + + // handle the case where we want to do something different then + // what qwebpage would do + if (openIn == TabWidget::NewSelectedTab + || openIn == TabWidget::NewNotSelectedTab + || (frame && openIn == TabWidget::NewWindow)) { + if (WebView *webView = qobject_cast(view())) { + TabWidget *tabWidget = webView->tabWidget(); + if (tabWidget) { + WebView *newView = tabWidget->getView(openIn, webView); + QWebPage *page = 0; + if (newView) + page = newView->page(); + if (page && page->mainFrame()) + page->mainFrame()->load(request); + } + } + return false; + } + + bool accepted = QWebPage::acceptNavigationRequest(frame, request, type); + if (accepted && frame == mainFrame()) { + m_requestedUrl = request.url(); + emit aboutToLoadUrl(request.url()); + } + + return accepted; +} + +void WebPage::loadSettings() +{ + QSettings settings; + settings.beginGroup(QLatin1String("tabs")); + m_openTargetBlankLinksIn = (TabWidget::OpenUrlIn)settings.value(QLatin1String("openTargetBlankLinksIn"), + TabWidget::NewSelectedTab).toInt(); + settings.endGroup(); + s_userAgent = settings.value(QLatin1String("userAgent")).toString(); +} + +QWebPage *WebPage::createWindow(QWebPage::WebWindowType type) +{ + Q_UNUSED(type); + if (WebView *webView = qobject_cast(view())) { + TabWidget *tabWidget = webView->tabWidget(); + if (tabWidget) { + TabWidget::OpenUrlIn openIn = m_openTargetBlankLinksIn; + openIn = TabWidget::modifyWithUserBehavior(openIn); + return tabWidget->getView(openIn, webView)->page(); + } + } + return 0; +} + +QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, + const QStringList ¶mNames, const QStringList ¶mValues) +{ + Q_UNUSED(classId); + Q_UNUSED(url); + Q_UNUSED(paramNames); + Q_UNUSED(paramValues); +#if !defined(QT_NO_UITOOLS) + QUiLoader loader; + return loader.createWidget(classId, view()); +#else + return 0; +#endif +} + +// The chromium guys have documented many examples of incompatibilities that +// different browsers have when they mime sniff. +// http://src.chromium.org/viewvc/chrome/trunk/src/net/base/mime_sniffer.cc +// +// All WebKit ports should share a common set of rules to sniff content. +// By having this here we are yet another browser that has different behavior :( +// But sadly QtWebKit does no sniffing at all so we are forced to do something. +static bool contentSniff(const QByteArray &data) +{ + if (data.contains("url(); + + if (replyUrl.scheme() == QLatin1String("abp")) + return; + + switch (reply->error()) { + case QNetworkReply::NoError: + if (reply->header(QNetworkRequest::ContentTypeHeader).isValid()) { + BrowserApplication::downloadManager()->handleUnsupportedContent(reply); + return; + } + break; + case QNetworkReply::ProtocolUnknownError: { + QSettings settings; + settings.beginGroup(QLatin1String("WebView")); + QStringList externalSchemes = settings.value(QLatin1String("externalSchemes")).toStringList(); + if (externalSchemes.contains(replyUrl.scheme())) { + QDesktopServices::openUrl(replyUrl); + return; + } + break; + } + default: + break; + } + + // Find the frame that has the unsupported content + if (replyUrl.isEmpty() || replyUrl != m_requestedUrl) + return; + + QWebFrame *notFoundFrame = mainFrame(); + if (!notFoundFrame) + return; + + if (reply->header(QNetworkRequest::ContentTypeHeader).toString().isEmpty()) { + // do evil + QByteArray data = reply->readAll(); + if (contentSniff(data)) { + notFoundFrame->setHtml(QLatin1String(data), replyUrl); + return; + } + } + + // Generate translated not found error page with an image + QFile notFoundErrorFile(QLatin1String(":/notfound.html")); + if (!notFoundErrorFile.open(QIODevice::ReadOnly)) + return; + QString title = tr("Error loading page: %1").arg(QString::fromUtf8(replyUrl.toEncoded())); + QString html = QLatin1String(notFoundErrorFile.readAll()); + QPixmap pixmap = qApp->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, view()).pixmap(QSize(32, 32)); + QBuffer imageBuffer; + imageBuffer.open(QBuffer::ReadWrite); + if (pixmap.save(&imageBuffer, "PNG")) { + html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), + QLatin1String(imageBuffer.buffer().toBase64())); + } + html = html.arg(title, + reply->errorString(), + tr("When connecting to: %1.").arg(QString::fromUtf8(replyUrl.toEncoded())), + tr("Check the address for errors such as ww.arora-browser.org instead of www.arora-browser.org"), + tr("If the address is correct, try checking the network connection."), + tr("If your computer or network is protected by a firewall or proxy, make sure that the browser is permitted to access the network.")); + notFoundFrame->setHtml(html, replyUrl); + // Don't put error pages to the history. + BrowserApplication::instance()->historyManager()->removeHistoryEntry(replyUrl, notFoundFrame->title()); +} + diff --git a/src/webpage.h b/src/webpage.h new file mode 100644 index 00000000..c3dcba3d --- /dev/null +++ b/src/webpage.h @@ -0,0 +1,114 @@ +/* + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#ifndef WEBPAGE_H +#define WEBPAGE_H + +#include "webpageproxy.h" +#include "tabwidget.h" + +#include +#include + +class WebPageLinkedResource +{ +public: + QString rel; + QString type; + QUrl href; + QString title; +}; + +class OpenSearchEngine; +class QNetworkReply; +class WebPluginFactory; +// See https://developer.mozilla.org/en/adding_search_engines_from_web_pages +class JavaScriptExternalObject : public QObject +{ + Q_OBJECT + +public: + JavaScriptExternalObject(QObject *parent = 0); + +public slots: + void AddSearchProvider(const QString &url); +}; + +class JavaScriptAroraObject : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QObject *currentEngine READ currentEngine) + +public: + JavaScriptAroraObject(QObject *parent = 0); + +public slots: + QString translate(const QString &string); + QObject *currentEngine() const; + QString searchUrl(const QString &string) const; +}; + +class WebPage : public WebPageProxy +{ + Q_OBJECT + +signals: + void aboutToLoadUrl(const QUrl &url); + +public: + WebPage(QObject *parent = 0); + ~WebPage(); + + void loadSettings(); + + static WebPluginFactory *webPluginFactory(); + QList linkedResources(const QString &relation = QString()); + + static QString userAgent(); + static void setUserAgent(const QString &userAgent); + +protected: + QString userAgentForUrl(const QUrl &url) const; + bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, + NavigationType type); + QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); + QWebPage *createWindow(QWebPage::WebWindowType type); + +protected slots: + void handleUnsupportedContent(QNetworkReply *reply); + void addExternalBinding(QWebFrame *frame = 0); + +protected: + void populateNetworkRequest(QNetworkRequest &request); + static QString s_userAgent; + static WebPluginFactory *s_webPluginFactory; + TabWidget::OpenUrlIn m_openTargetBlankLinksIn; + QUrl m_requestedUrl; + JavaScriptExternalObject *m_javaScriptExternalObject; + JavaScriptAroraObject *m_javaScriptAroraObject; + +private: + QNetworkRequest lastRequest; + QWebPage::NavigationType lastRequestType; + +}; + +#endif // WEBPAGE_H + diff --git a/src/webview.cpp b/src/webview.cpp index e8e08f58..43eeeb91 100644 --- a/src/webview.cpp +++ b/src/webview.cpp @@ -1,6 +1,7 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * Copyright 2008 Jason A. Donenfeld + * Copyright 2008 Ariya Hidayat * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -61,211 +62,258 @@ ** ****************************************************************************/ +#include "webview.h" + +#include "adblockdialog.h" +#include "adblockmanager.h" +#include "adblockpage.h" +#include "autofillmanager.h" +#include "addbookmarkdialog.h" +#include "bookmarksmanager.h" #include "browserapplication.h" #include "browsermainwindow.h" -#include "cookiejar.h" #include "downloadmanager.h" -#include "networkaccessmanager.h" -#include "tabwidget.h" -#include "webview.h" -#include "bookmarks.h" +#include "opensearchengine.h" +#include "opensearchengineaction.h" +#include "opensearchmanager.h" +#include "toolbarsearch.h" +#include "webpage.h" -#include #include +#include #include -#include -#include - +#include +#include #include -#include - -WebPage::WebPage(QObject *parent) - : QWebPage(parent) - , m_keyboardModifiers(Qt::NoModifier) - , m_pressedButtons(Qt::NoButton) - , m_openInNewTab(false) -{ - setNetworkAccessManager(BrowserApplication::networkAccessManager()); - connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), - this, SLOT(handleUnsupportedContent(QNetworkReply *))); -} - -BrowserMainWindow *WebPage::mainWindow() -{ - QObject *w = this->parent(); - while (w) { - if (BrowserMainWindow *mw = qobject_cast(w)) - return mw; - w = w->parent(); - } - return BrowserApplication::instance()->mainWindow(); -} - -bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type) -{ - // ctrl open in new tab - // ctrl-shift open in new tab and select - // ctrl-alt open in new window - if (type == QWebPage::NavigationTypeLinkClicked - && (m_keyboardModifiers & Qt::ControlModifier - || m_pressedButtons == Qt::MidButton)) { - bool newWindow = (m_keyboardModifiers & Qt::AltModifier); - WebView *webView; - if (newWindow) { - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *newMainWindow = BrowserApplication::instance()->mainWindow(); - webView = newMainWindow->currentTab(); - newMainWindow->raise(); - newMainWindow->activateWindow(); - webView->setFocus(); - } else { - bool selectNewTab = (m_keyboardModifiers & Qt::ShiftModifier); - webView = mainWindow()->tabWidget()->makeNewTab(selectNewTab); - } - webView->load(request); - m_keyboardModifiers = Qt::NoModifier; - m_pressedButtons = Qt::NoButton; - return false; - } - if (frame == mainFrame()) { - m_loadingUrl = request.url(); - emit loadingUrl(m_loadingUrl); - } - return QWebPage::acceptNavigationRequest(frame, request, type); -} - -QWebPage *WebPage::createWindow(QWebPage::WebWindowType type) -{ - Q_UNUSED(type); - if (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton) - m_openInNewTab = true; - if (m_openInNewTab) { - m_openInNewTab = false; - return mainWindow()->tabWidget()->makeNewTab()->page(); - } - BrowserApplication::instance()->newMainWindow(); - BrowserMainWindow *mainWindow = BrowserApplication::instance()->mainWindow(); - return mainWindow->currentTab()->page(); -} - -#if !defined(QT_NO_UITOOLS) -QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) -{ - Q_UNUSED(url); - Q_UNUSED(paramNames); - Q_UNUSED(paramValues); - QUiLoader loader; - return loader.createWidget(classId, view()); -} -#endif // !defined(QT_NO_UITOOLS) - -void WebPage::handleUnsupportedContent(QNetworkReply *reply) -{ - if (reply->error() == QNetworkReply::NoError) { - BrowserApplication::downloadManager()->handleUnsupportedContent(reply); - return; - } - - QFile file(QLatin1String(":/notfound.html")); - bool isOpened = file.open(QIODevice::ReadOnly); - Q_ASSERT(isOpened); - QString title = tr("Error loading page: %1").arg(reply->url().toString()); - QString html = QString(QLatin1String(file.readAll())) - .arg(title) - .arg(reply->errorString()) - .arg(reply->url().toString()); - - QBuffer imageBuffer; - imageBuffer.open(QBuffer::ReadWrite); - QIcon icon = view()->style()->standardIcon(QStyle::SP_MessageBoxWarning, 0, view()); - QPixmap pixmap = icon.pixmap(QSize(32, 32)); - if (pixmap.save(&imageBuffer, "PNG")) { - html.replace(QLatin1String("IMAGE_BINARY_DATA_HERE"), - QString(QLatin1String(imageBuffer.buffer().toBase64()))); - } - - QList frames; - frames.append(mainFrame()); - while (!frames.isEmpty()) { - QWebFrame *frame = frames.takeFirst(); - if (frame->url() == reply->url()) { - frame->setHtml(html, reply->url()); - return; - } - QList children = frame->childFrames(); - foreach(QWebFrame *frame, children) - frames.append(frame); - } - if (m_loadingUrl == reply->url()) { - mainFrame()->setHtml(html, reply->url()); - } -} +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +#if !defined(QTWEBKIT_VERSION) || QTWEBKIT_VERSION < 0x020000 +Q_DECLARE_METATYPE(QWebElement) +#endif +#include +#include +#include +#include +#include +#include +#include +#endif +#include -WebView::WebView(QWidget* parent) +WebView::WebView(QWidget *parent) : QWebView(parent) , m_progress(0) + , m_currentZoom(100) , m_page(new WebPage(this)) +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + , m_enableAccessKeys(true) + , m_accessKeysPressed(false) +#endif { setPage(m_page); +#if QT_VERSION >= 0x040600 + QPalette p; + if (p.color(QPalette::Window) != Qt::white) { + QWindowsStyle s; + p = s.standardPalette(); + setPalette(p); + } +#endif connect(page(), SIGNAL(statusBarMessage(const QString&)), SLOT(setStatusBarText(const QString&))); connect(this, SIGNAL(loadProgress(int)), this, SLOT(setProgress(int))); connect(this, SIGNAL(loadFinished(bool)), this, SLOT(loadFinished())); - connect(page(), SIGNAL(loadingUrl(const QUrl&)), + connect(page(), SIGNAL(aboutToLoadUrl(const QUrl &)), this, SIGNAL(urlChanged(const QUrl &))); connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)), this, SLOT(downloadRequested(const QNetworkRequest &))); + connect(BrowserApplication::instance(), SIGNAL(zoomTextOnlyChanged(bool)), + this, SLOT(applyZoom())); page()->setForwardUnsupportedContent(true); + setAcceptDrops(true); + + // the zoom values (in percent) are chosen to be like in Mozilla Firefox 3 + m_zoomLevels << 30 << 50 << 67 << 80 << 90; + m_zoomLevels << 100; + m_zoomLevels << 110 << 120 << 133 << 150 << 170 << 200 << 240 << 300; +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + connect(m_page, SIGNAL(loadStarted()), + this, SLOT(hideAccessKeys())); + connect(m_page, SIGNAL(scrollRequested(int, int, const QRect &)), + this, SLOT(hideAccessKeys())); +#endif + loadSettings(); +} + +void WebView::loadSettings() +{ +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + QSettings settings; + settings.beginGroup(QLatin1String("WebView")); + m_enableAccessKeys = settings.value(QLatin1String("enableAccessKeys"), m_enableAccessKeys).toBool(); + + if (!m_enableAccessKeys) + hideAccessKeys(); +#endif + m_page->loadSettings(); +} + +#if !(QT_VERSION >= 0x040600) +#include +// DO NOT CHANGE ANYTHING IN THIS FUNCTION +// You want to change TabWidget::guessUrlFromString() +// This is a copy of QWebView::guessUrlFromStringis from +// QtWebKit and should never be out of sync with that code. +// This function is fragile, very easy to break, and tested in QtWebKit. +QUrl WebView::guessUrlFromString(const QString &string) +{ + QString trimmedString = string.trimmed(); + // Check the most common case of a valid url with scheme and host first + QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); + if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty()) + return url; + + // Absolute files that exists + if (QDir::isAbsolutePath(trimmedString) && QFile::exists(trimmedString)) + return QUrl::fromLocalFile(trimmedString); + + // If the string is missing the scheme or the scheme is not valid prepend a scheme + QString scheme = url.scheme(); + if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) { + // Do not do anything for strings such as "foo", only "foo.com" + int dotIndex = trimmedString.indexOf(QLatin1Char('.')); + if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) { + const QString hostscheme = trimmedString.left(dotIndex).toLower(); + QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http"; + trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString; + } + url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode); + } + + if (url.isValid()) + return url; + + return QUrl(); +} +#endif + +TabWidget *WebView::tabWidget() const +{ + QObject *widget = this->parent(); + while (widget) { + if (TabWidget *tw = qobject_cast(widget)) + return tw; + widget = widget->parent(); + } + return 0; } void WebView::contextMenuEvent(QContextMenuEvent *event) { - QMenu menu(this); + QMenu *menu = new QMenu(this); QWebHitTestResult r = page()->mainFrame()->hitTestContent(event->pos()); if (!r.linkUrl().isEmpty()) { - menu.addAction(tr("Open in New &Window"), this, SLOT(openLinkInNewWindow())); - menu.addAction(tr("Open in New &Tab"), this, SLOT(openLinkInNewTab())); - menu.addSeparator(); - menu.addAction(tr("Save Lin&k"), this, SLOT(downloadLinkToDisk())); - menu.addAction(tr("&Bookmark This Link"), this, SLOT(bookmarkLink()))->setData(r.linkUrl().toString()); - menu.addSeparator(); - menu.addAction(tr("&Copy Link Location"), this, SLOT(copyLinkToClipboard())); - if (page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled)) - menu.addAction(pageAction(QWebPage::InspectElement)); + QAction *newWindowAction = menu->addAction(tr("Open in New &Window"), this, SLOT(openActionUrlInNewWindow())); + newWindowAction->setData(r.linkUrl()); + QAction *newTabAction = menu->addAction(tr("Open in New &Tab"), this, SLOT(openActionUrlInNewTab())); + newTabAction->setData(r.linkUrl()); + menu->addSeparator(); + menu->addAction(tr("Save Lin&k"), this, SLOT(downloadLinkToDisk())); + menu->addAction(tr("&Bookmark This Link"), this, SLOT(bookmarkLink()))->setData(r.linkUrl()); + menu->addSeparator(); + if (!page()->selectedText().isEmpty()) + menu->addAction(pageAction(QWebPage::Copy)); + menu->addAction(tr("&Copy Link Location"), this, SLOT(copyLinkToClipboard())); } if (!r.imageUrl().isEmpty()) { - if (!menu.isEmpty()) - menu.addSeparator(); - menu.addAction(tr("Open Image in New &Window"), this, SLOT(openImageInNewWindow())); - menu.addAction(tr("Open Image in New &Tab"), this, SLOT(openImageInNewTab())); - menu.addSeparator(); - menu.addAction(tr("&Save Image"), this, SLOT(downloadImageToDisk())); - menu.addAction(tr("&Copy Image"), this, SLOT(copyImageToClipboard())); - menu.addAction(tr("C&opy Image Location"), this, SLOT(copyImageLocationToClipboard()))->setData(r.imageUrl().toString()); - } - - if (!menu.isEmpty()) { - menu.exec(mapToGlobal(event->pos())); + if (!menu->isEmpty()) + menu->addSeparator(); + QAction *newWindowAction = menu->addAction(tr("Open Image in New &Window"), this, SLOT(openActionUrlInNewWindow())); + newWindowAction->setData(r.imageUrl()); + QAction *newTabAction = menu->addAction(tr("Open Image in New &Tab"), this, SLOT(openActionUrlInNewTab())); + newTabAction->setData(r.imageUrl()); + menu->addSeparator(); + menu->addAction(tr("&Save Image"), this, SLOT(downloadImageToDisk())); + menu->addAction(tr("&Copy Image"), this, SLOT(copyImageToClipboard())); + menu->addAction(tr("C&opy Image Location"), this, SLOT(copyImageLocationToClipboard()))->setData(r.imageUrl().toString()); + menu->addSeparator(); + menu->addAction(tr("Block Image"), this, SLOT(blockImage()))->setData(r.imageUrl().toString()); + } + + if (!page()->selectedText().isEmpty()) { + if (menu->isEmpty()) { + menu->addAction(pageAction(QWebPage::Copy)); + } else { + menu->addSeparator(); + } + QMenu *searchMenu = menu->addMenu(tr("Search with...")); + + QList list = ToolbarSearch::openSearchManager()->allEnginesNames(); + for (int i = 0; i < list.count(); ++i) { + QString name = list.at(i); + OpenSearchEngine *engine = ToolbarSearch::openSearchManager()->engine(name); + QAction *action = new OpenSearchEngineAction(engine, searchMenu); + searchMenu->addAction(action); + action->setData(name); + } + + connect(searchMenu, SIGNAL(triggered(QAction *)), this, SLOT(searchRequested(QAction *))); + } + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + QWebElement element = r.element(); + if (!element.isNull() + && element.tagName().toLower() == QLatin1String("input") + && element.attribute(QLatin1String("type"), QLatin1String("text")) == QLatin1String("text")) { + if (menu->isEmpty()) { + menu->addAction(pageAction(QWebPage::Copy)); + } else { + menu->addSeparator(); + } + + QVariant variant; + variant.setValue(element); + menu->addAction(tr("Add to the toolbar search"), this, SLOT(addSearchEngine()))->setData(variant); + } +#endif + + if (menu->isEmpty()) { + delete menu; + menu = page()->createStandardContextMenu(); + } else { + if (page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled)) + menu->addAction(pageAction(QWebPage::InspectElement)); + } + + if (!menu->isEmpty()) { + if (BrowserMainWindow::parentWindow(tabWidget())->menuBar()->isHidden()) { + menu->addSeparator(); + menu->addAction(BrowserMainWindow::parentWindow(tabWidget())->showMenuBarAction()); + } + + menu->exec(mapToGlobal(event->pos())); + delete menu; return; } + delete menu; QWebView::contextMenuEvent(event); } void WebView::wheelEvent(QWheelEvent *event) { - if (QApplication::keyboardModifiers() & Qt::ControlModifier) { + if (event->modifiers() & Qt::ControlModifier) { int numDegrees = event->delta() / 8; int numSteps = numDegrees / 15; - setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1); + m_currentZoom = m_currentZoom + numSteps * 10; + applyZoom(); event->accept(); return; } @@ -282,18 +330,6 @@ void WebView::resizeEvent(QResizeEvent *event) QWebView::resizeEvent(event); } -void WebView::openLinkInNewTab() -{ - m_page->m_openInNewTab = true; - pageAction(QWebPage::OpenLinkInNewWindow)->trigger(); -} - -void WebView::openLinkInNewWindow() -{ - m_page->m_openInNewTab = false; - pageAction(QWebPage::OpenLinkInNewWindow)->trigger(); -} - void WebView::downloadLinkToDisk() { pageAction(QWebPage::DownloadLinkToDisk)->trigger(); @@ -304,10 +340,24 @@ void WebView::copyLinkToClipboard() pageAction(QWebPage::CopyLinkToClipboard)->trigger(); } -void WebView::openImageInNewTab() +void WebView::openActionUrlInNewTab() { - m_page->m_openInNewTab = true; - pageAction(QWebPage::OpenImageInNewWindow)->trigger(); + if (QAction *action = qobject_cast(sender())) { + QWebPage *page = tabWidget()->getView(TabWidget::NewNotSelectedTab, this)->page(); + QNetworkRequest request(action->data().toUrl()); + request.setRawHeader("Referer", url().toEncoded()); + page->mainFrame()->load(request); + } +} + +void WebView::openActionUrlInNewWindow() +{ + if (QAction *action = qobject_cast(sender())) { + QWebPage *page = tabWidget()->getView(TabWidget::NewWindow, this)->page(); + QNetworkRequest request(action->data().toUrl()); + request.setRawHeader("Referer", url().toEncoded()); + page->mainFrame()->load(request); + } } void WebView::openImageInNewWindow() @@ -332,31 +382,213 @@ void WebView::copyImageLocationToClipboard() } } +void WebView::blockImage() +{ + if (QAction *action = qobject_cast(sender())) { + QString imageUrl = action->data().toString(); + AdBlockDialog *dialog = AdBlockManager::instance()->showDialog(); + dialog->addCustomRule(imageUrl); + } +} + void WebView::bookmarkLink() { if (QAction *action = qobject_cast(sender())) { - AddBookmarkDialog dialog(action->data().toString(), ""); + AddBookmarkDialog dialog; + dialog.setUrl(QString::fromUtf8(action->data().toUrl().toEncoded())); dialog.exec(); } } +void WebView::searchRequested(QAction *action) +{ + QString searchText = page()->selectedText(); + + if (searchText.isEmpty()) + return; + + QVariant index = action->data(); + + if (index.canConvert()) { + OpenSearchEngine *engine = ToolbarSearch::openSearchManager()->engine(index.toString()); + emit search(engine->searchUrl(searchText), TabWidget::NewSelectedTab); + } +} + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +void WebView::addSearchEngine() +{ + QAction *action = qobject_cast(sender()); + if (!action) + return; + + QVariant variant = action->data(); + if (!variant.canConvert()) + return; + + QWebElement element = qvariant_cast(variant); + QString elementName = element.attribute(QLatin1String("name")); + QWebElement formElement = element; + while (formElement.tagName().toLower() != QLatin1String("form")) + formElement = formElement.parent(); + + if (formElement.isNull() || formElement.attribute(QLatin1String("action")).isEmpty()) + return; + + QString method = formElement.attribute(QLatin1String("method"), QLatin1String("get")).toLower(); + if (method != QLatin1String("get")) { + QMessageBox::warning(this, tr("Method not supported"), + tr("%1 method is not supported.").arg(method.toUpper())); + return; + } + + QUrl searchUrl(page()->mainFrame()->baseUrl().resolved(QUrl(formElement.attribute(QLatin1String("action"))))); + QMap searchEngines; + QWebElementCollection inputFields = formElement.findAll(QLatin1String("input")); + foreach (QWebElement inputField, inputFields) { + QString type = inputField.attribute(QLatin1String("type"), QLatin1String("text")); + QString name = inputField.attribute(QLatin1String("name")); + QString value = inputField.evaluateJavaScript(QLatin1String("this.value")).toString(); + + if (type == QLatin1String("submit")) { + searchEngines.insert(value, name); + } else if (type == QLatin1String("text")) { + if (inputField == element) + value = QLatin1String("{searchTerms}"); + + searchUrl.addQueryItem(name, value); + } else if (type == QLatin1String("checkbox") || type == QLatin1String("radio")) { + if (inputField.evaluateJavaScript(QLatin1String("this.checked")).toBool()) { + searchUrl.addQueryItem(name, value); + } + } else if (type == QLatin1String("hidden")) { + searchUrl.addQueryItem(name, value); + } + } + + QWebElementCollection selectFields = formElement.findAll(QLatin1String("select")); + foreach (QWebElement selectField, selectFields) { + QString name = selectField.attribute(QLatin1String("name")); + int selectedIndex = selectField.evaluateJavaScript(QLatin1String("this.selectedIndex")).toInt(); + if (selectedIndex == -1) + continue; + + QWebElementCollection options = selectField.findAll(QLatin1String("option")); + QString value = options.at(selectedIndex).toPlainText(); + searchUrl.addQueryItem(name, value); + } + + bool ok = true; + if (searchEngines.count() > 1) { + QString searchEngine = QInputDialog::getItem(this, tr("Search engine"), + tr("Choose the desired search engine"), searchEngines.keys(), + 0, false, &ok); + if (!ok) + return; + if (!searchEngines[searchEngine].isEmpty()) + searchUrl.addQueryItem(searchEngines[searchEngine], searchEngine); + } + + QString engineName; + QWebElementCollection labels = formElement.findAll(QString(QLatin1String("label[for=\"%1\"]")).arg(elementName)); + if (labels.count() > 0) + engineName = labels.at(0).toPlainText(); + + engineName = QInputDialog::getText(this, tr("Engine name"), tr("Type in a name for the engine"), + QLineEdit::Normal, engineName, &ok); + if (!ok) + return; + + OpenSearchEngine *engine = new OpenSearchEngine(); + engine->setName(engineName); + engine->setDescription(engineName); + engine->setSearchUrlTemplate(searchUrl.toString()); + engine->setImage(icon().pixmap(16, 16).toImage()); + + ToolbarSearch::openSearchManager()->addEngine(engine); +} +#endif + void WebView::setProgress(int progress) { m_progress = progress; } +int WebView::levelForZoom(int zoom) +{ + int i; + + i = m_zoomLevels.indexOf(zoom); + if (i >= 0) + return i; + + for (i = 0 ; i < m_zoomLevels.count(); ++i) + if (zoom <= m_zoomLevels[i]) + break; + + if (i == m_zoomLevels.count()) + return i - 1; + if (i == 0) + return i; + + if (zoom - m_zoomLevels[i-1] > m_zoomLevels[i] - zoom) + return i; + else + return i-1; +} + +void WebView::applyZoom() +{ + setZoomFactor(qreal(m_currentZoom) / 100.0); +} + +void WebView::zoomIn() +{ + int i = levelForZoom(m_currentZoom); + + if (i < m_zoomLevels.count() - 1) + m_currentZoom = m_zoomLevels[i + 1]; + applyZoom(); +} + +void WebView::zoomOut() +{ + int i = levelForZoom(m_currentZoom); + + if (i > 0) + m_currentZoom = m_zoomLevels[i - 1]; + applyZoom(); +} + +void WebView::resetZoom() +{ + m_currentZoom = 100; + applyZoom(); +} + void WebView::loadFinished() { if (100 != m_progress) { - qWarning() << "Recieved finished signal while progress is still:" << progress() + qWarning() << "Received finished signal while progress is still:" << progress() << "Url:" << url(); } m_progress = 0; + AdBlockManager::instance()->page()->applyRulesToPage(page()); + BrowserApplication::instance()->autoFillManager()->fill(page()); } -void WebView::loadUrl(const QUrl &url) +void WebView::loadUrl(const QUrl &url, const QString &title) { + if (url.scheme() == QLatin1String("javascript")) { + QString scriptSource = QUrl::fromPercentEncoding(url.toString(Q_FLAGS(QUrl::TolerantMode|QUrl::RemoveScheme)).toAscii()); + QVariant result = page()->mainFrame()->evaluateJavaScript(scriptSource); + return; + } m_initialUrl = url; + if (!title.isEmpty()) + emit titleChanged(tr("Loading...")); + else + emit titleChanged(title); load(url); } @@ -376,20 +608,76 @@ QUrl WebView::url() const void WebView::mousePressEvent(QMouseEvent *event) { - m_page->m_pressedButtons = event->buttons(); - m_page->m_keyboardModifiers = event->modifiers(); - QWebView::mousePressEvent(event); + BrowserApplication::instance()->setEventMouseButtons(event->buttons()); + BrowserApplication::instance()->setEventKeyboardModifiers(event->modifiers()); + + switch (event->button()) { + case Qt::XButton1: + pageAction(WebPage::Back)->trigger(); + break; + case Qt::XButton2: + pageAction(WebPage::Forward)->trigger(); + break; + default: + QWebView::mousePressEvent(event); + break; + } +} + +void WebView::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} + +void WebView::dragMoveEvent(QDragMoveEvent *event) +{ + event->ignore(); + if (event->source() != this) { + if (!event->mimeData()->urls().isEmpty()) { + event->acceptProposedAction(); + } else { + QUrl url(event->mimeData()->text()); + if (url.isValid()) + event->acceptProposedAction(); + } + } + if (!event->isAccepted()) { + QWebView::dragMoveEvent(event); + } +} + +void WebView::dropEvent(QDropEvent *event) +{ + QWebView::dropEvent(event); + if (!event->isAccepted() + && event->source() != this + && event->possibleActions() & Qt::CopyAction) { + + QUrl url; + if (!event->mimeData()->urls().isEmpty()) + url = event->mimeData()->urls().first(); + if (!url.isValid()) + url = event->mimeData()->text(); + if (url.isValid()) { + loadUrl(url); + event->acceptProposedAction(); + } + } } void WebView::mouseReleaseEvent(QMouseEvent *event) { - QWebView::mouseReleaseEvent(event); - if (!event->isAccepted() && (m_page->m_pressedButtons & Qt::MidButton)) { + const bool isAccepted = event->isAccepted(); + m_page->event(event); + if (!event->isAccepted() + && (BrowserApplication::instance()->eventMouseButtons() & Qt::MidButton)) { QUrl url(QApplication::clipboard()->text(QClipboard::Selection)); if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) { - setUrl(url); + BrowserApplication::instance()->setEventMouseButtons(Qt::NoButton); + loadUrl(url); } } + event->setAccepted(isAccepted); } void WebView::setStatusBarText(const QString &string) @@ -402,3 +690,221 @@ void WebView::downloadRequested(const QNetworkRequest &request) BrowserApplication::downloadManager()->download(request); } +void WebView::keyPressEvent(QKeyEvent *event) +{ +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + if (m_enableAccessKeys) { + m_accessKeysPressed = (event->modifiers() == Qt::ControlModifier + && event->key() == Qt::Key_Control); + if (!m_accessKeysPressed) { + if (checkForAccessKey(event)) { + hideAccessKeys(); + event->accept(); + return; + } + hideAccessKeys(); + } else { + QTimer::singleShot(300, this, SLOT(accessKeyShortcut())); + } + } +#endif + +#if QT_VERSION < 0x040600 + switch (event->key()) { + case Qt::Key_Back: + pageAction(WebPage::Back)->trigger(); + event->accept(); + break; + case Qt::Key_Forward: + pageAction(WebPage::Forward)->trigger(); + event->accept(); + break; + case Qt::Key_Stop: + pageAction(WebPage::Stop)->trigger(); + event->accept(); + break; + case Qt::Key_Refresh: + pageAction(WebPage::Reload)->trigger(); + event->accept(); + break; + default: + QWebView::keyPressEvent(event); + return; + } +#endif + QWebView::keyPressEvent(event); +} + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +void WebView::accessKeyShortcut() +{ + if (!hasFocus() + || !m_accessKeysPressed + || !m_enableAccessKeys) + return; + if (m_accessKeyLabels.isEmpty()) { + showAccessKeys(); + } else { + hideAccessKeys(); + } + m_accessKeysPressed = false; +} + +void WebView::keyReleaseEvent(QKeyEvent *event) +{ + if (m_enableAccessKeys) + m_accessKeysPressed = event->key() == Qt::Key_Control; + QWebView::keyReleaseEvent(event); +} + +void WebView::focusOutEvent(QFocusEvent *event) +{ + if (m_accessKeysPressed) { + hideAccessKeys(); + m_accessKeysPressed = false; + } + QWebView::focusOutEvent(event); +} + +bool WebView::checkForAccessKey(QKeyEvent *event) +{ + if (m_accessKeyLabels.isEmpty()) + return false; + + QString text = event->text(); + if (text.isEmpty()) + return false; + QChar key = text.at(0).toUpper(); + bool handled = false; + if (m_accessKeyNodes.contains(key)) { + QWebElement element = m_accessKeyNodes[key]; + QPoint p = element.geometry().center(); + QWebFrame *frame = element.webFrame(); + Q_ASSERT(frame); + do { + p -= frame->scrollPosition(); + frame = frame->parentFrame(); + } while (frame && frame != page()->mainFrame()); + QMouseEvent pevent(QEvent::MouseButtonPress, p, Qt::LeftButton, 0, 0); + qApp->sendEvent(this, &pevent); + QMouseEvent revent(QEvent::MouseButtonRelease, p, Qt::LeftButton, 0, 0); + qApp->sendEvent(this, &revent); + handled = true; + } + return handled; +} + +void WebView::hideAccessKeys() +{ + if (!m_accessKeyLabels.isEmpty()) { + for (int i = 0; i < m_accessKeyLabels.count(); ++i) { + QLabel *label = m_accessKeyLabels[i]; + label->hide(); + label->deleteLater(); + } + m_accessKeyLabels.clear(); + m_accessKeyNodes.clear(); + update(); + } +} + +void WebView::showAccessKeys() +{ + QStringList supportedElement; + supportedElement << QLatin1String("input") + << QLatin1String("a") + << QLatin1String("area") + << QLatin1String("button") + << QLatin1String("label") + << QLatin1String("legend") + << QLatin1String("textarea"); + + QList unusedKeys; + for (char c = 'A'; c <= 'Z'; ++c) + unusedKeys << QLatin1Char(c); + for (char c = '0'; c <= '9'; ++c) + unusedKeys << QLatin1Char(c); + + QRect viewport = QRect(m_page->mainFrame()->scrollPosition(), m_page->viewportSize()); + // Priority first goes to elements with accesskey attributes + QList alreadyLabeled; + foreach (const QString &elementType, supportedElement) { + QList result = page()->mainFrame()->findAllElements(elementType).toList(); + foreach (const QWebElement &element, result) { + const QRect geometry = element.geometry(); + if (geometry.size().isEmpty() + || !viewport.contains(geometry.topLeft())) { + continue; + } + QString accessKeyAttribute = element.attribute(QLatin1String("accesskey")).toUpper(); + if (accessKeyAttribute.isEmpty()) + continue; + QChar accessKey; + for (int i = 0; i < accessKeyAttribute.count(); i+=2) { + const QChar &possibleAccessKey = accessKeyAttribute[i]; + if (unusedKeys.contains(possibleAccessKey)) { + accessKey = possibleAccessKey; + break; + } + } + if (accessKey.isNull()) + continue; + unusedKeys.removeOne(accessKey); + makeAccessKeyLabel(accessKey, element); + alreadyLabeled.append(element); + } + } + + // Pick an access key first from the letters in the text and then from the + // list of unused access keys + foreach (const QString &elementType, supportedElement) { + QWebElementCollection result = page()->mainFrame()->findAllElements(elementType); + foreach (const QWebElement &element, result) { + const QRect geometry = element.geometry(); + if (unusedKeys.isEmpty() + || alreadyLabeled.contains(element) + || geometry.size().isEmpty() + || !viewport.contains(geometry.topLeft())) { + continue; + } + QChar accessKey; + QString text = element.toPlainText().toUpper(); + for (int i = 0; i < text.count(); ++i) { + const QChar &c = text.at(i); + if (unusedKeys.contains(c)) { + accessKey = c; + break; + } + } + if (accessKey.isNull()) + accessKey = unusedKeys.takeFirst(); + unusedKeys.removeOne(accessKey); + makeAccessKeyLabel(accessKey, element); + } + } +} + +void WebView::makeAccessKeyLabel(const QChar &accessKey, const QWebElement &element) +{ + QLabel *label = new QLabel(this); + label->setText(QString(QLatin1String("%1")).arg(accessKey)); + + QPalette p = QToolTip::palette(); + QColor color(Qt::yellow); + color = color.lighter(150); + color.setAlpha(175); + p.setColor(QPalette::Window, color); + label->setPalette(p); + label->setAutoFillBackground(true); + label->setFrameStyle(QFrame::Box | QFrame::Plain); + QPoint point = element.geometry().center(); + point -= m_page->mainFrame()->scrollPosition(); + label->move(point); + label->show(); + point.setX(point.x() - label->width() / 2); + label->move(point); + m_accessKeyLabels.append(label); + m_accessKeyNodes[accessKey] = element; +} + +#endif diff --git a/src/webview.h b/src/webview.h index f2be9ad1..6349a5cf 100644 --- a/src/webview.h +++ b/src/webview.h @@ -1,5 +1,5 @@ /* - * Copyright 2008 Benjamin C. Meyer + * Copyright 2008-2009 Benjamin C. Meyer * Copyright 2008 Ariya Hidayat * * This program is free software; you can redistribute it and/or modify @@ -66,46 +66,16 @@ #include -QT_BEGIN_NAMESPACE -class QAuthenticator; -class QMouseEvent; -class QNetworkProxy; -class QNetworkReply; -class QSslError; -QT_END_NAMESPACE +#include "tabwidget.h" -class BrowserMainWindow; -class WebPage : public QWebPage -{ - Q_OBJECT - -signals: - void loadingUrl(const QUrl &url); - -public: - WebPage(QObject *parent = 0); - BrowserMainWindow *mainWindow(); - -protected: - bool acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type); - QWebPage *createWindow(QWebPage::WebWindowType type); -#if !defined(QT_NO_UITOOLS) - QObject *createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +#include +class QLabel; #endif -private slots: - void handleUnsupportedContent(QNetworkReply *reply); - -private: - friend class WebView; - - // set the webview mousepressedevent - Qt::KeyboardModifiers m_keyboardModifiers; - Qt::MouseButtons m_pressedButtons; - bool m_openInNewTab; - QUrl m_loadingUrl; -}; - +class BrowserMainWindow; +class TabWidget; +class WebPage; class WebView : public QWebView { Q_OBJECT @@ -114,11 +84,31 @@ class WebView : public QWebView WebView(QWidget *parent = 0); WebPage *webPage() const { return m_page; } - void loadUrl(const QUrl &url); +#if !(QT_VERSION >= 0x040600) + static QUrl guessUrlFromString(const QString &url); +#endif + void loadSettings(); + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + void keyReleaseEvent(QKeyEvent *event); + void focusOutEvent(QFocusEvent *event); +#endif + + void loadUrl(const QUrl &url, const QString &title = QString()); QUrl url() const; QString lastStatusBarText() const; inline int progress() const { return m_progress; } + TabWidget *tabWidget() const; + +signals: + void search(const QUrl &searchUrl, TabWidget::OpenUrlIn openIn); + +public slots: + void zoomIn(); + void zoomOut(); + void resetZoom(); + void applyZoom(); protected: void mousePressEvent(QMouseEvent *event); @@ -126,28 +116,54 @@ class WebView : public QWebView void contextMenuEvent(QContextMenuEvent *event); void wheelEvent(QWheelEvent *event); void resizeEvent(QResizeEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dropEvent(QDropEvent *event); + void keyPressEvent(QKeyEvent *event); + +private: + int levelForZoom(int zoom); private slots: void setProgress(int progress); void loadFinished(); void setStatusBarText(const QString &string); void downloadRequested(const QNetworkRequest &request); - void openLinkInNewTab(); - void openLinkInNewWindow(); + void openActionUrlInNewTab(); + void openActionUrlInNewWindow(); void downloadLinkToDisk(); void copyLinkToClipboard(); - void openImageInNewTab(); void openImageInNewWindow(); void downloadImageToDisk(); void copyImageToClipboard(); void copyImageLocationToClipboard(); + void blockImage(); void bookmarkLink(); + void searchRequested(QAction *action); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + void addSearchEngine(); + void hideAccessKeys(); + void accessKeyShortcut(); +#endif private: QString m_statusBarText; QUrl m_initialUrl; int m_progress; + int m_currentZoom; + QList m_zoomLevels; WebPage *m_page; + +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + bool m_enableAccessKeys; + bool checkForAccessKey(QKeyEvent *event); + void showAccessKeys(); + void makeAccessKeyLabel(const QChar &accessKey, const QWebElement &element); + QList m_accessKeyLabels; + QHash m_accessKeyNodes; + bool m_accessKeysPressed; +#endif }; #endif + diff --git a/src/webviewsearch.cpp b/src/webviewsearch.cpp index 8f2b620b..273e9112 100644 --- a/src/webviewsearch.cpp +++ b/src/webviewsearch.cpp @@ -28,77 +28,17 @@ #include -WebViewSearch::WebViewSearch(QWidget *parent) - : QWidget(parent) - , m_widget(0) - , m_webView(0) - , m_timeLine(new QTimeLine(150, this)) -{ - initializeSearchWidget(); - - // we start off hidden - setMaximumHeight(0); - m_widget->setGeometry(0, -1 * m_widget->height(), - m_widget->width(), m_widget->height()); - hide(); - - connect(m_timeLine, SIGNAL(frameChanged(int)), - this, SLOT(frameChanged(int))); - - new QShortcut(QKeySequence(Qt::Key_Escape), this, SLOT(animateHide())); -} - -void WebViewSearch::initializeSearchWidget() +WebViewSearch::WebViewSearch(QWebView *webView, QWidget *parent) + : SearchBar(parent) { - m_widget = new QWidget(this); - m_widget->setContentsMargins(0, 0, 0, 0); - ui.setupUi(m_widget); - ui.previousButton->setText(QChar(9664)); - ui.nextButton->setText(QChar(9654)); - ui.searchInfo->setText(QString()); - connect(ui.nextButton, SIGNAL(clicked()), - this, SLOT(findNext())); - connect(ui.previousButton, SIGNAL(clicked()), - this, SLOT(findPrevious())); - connect(ui.searchLineEdit->lineEdit(), SIGNAL(returnPressed()), - this, SLOT(findNext())); - connect(ui.doneButton, SIGNAL(clicked()), - this, SLOT(animateHide())); - - setMinimumWidth(m_widget->minimumWidth()); - setMaximumWidth(m_widget->maximumWidth()); - setMinimumHeight(m_widget->minimumHeight()); -} - -void WebViewSearch::setWebView(QWebView *webView) -{ - m_webView = webView; -} - -QWebView *WebViewSearch::webView() const -{ - return m_webView; -} - -void WebViewSearch::clear() -{ - ui.searchLineEdit->lineEdit()->setText(QString()); -} - -void WebViewSearch::showFind() -{ - if (isVisible()) - return; - - show(); - ui.searchLineEdit->setFocus(); - ui.searchLineEdit->lineEdit()->selectAll(); - - m_timeLine->setFrameRange(-1 * m_widget->height(), 0); - m_timeLine->setDirection(QTimeLine::Forward); - disconnect(m_timeLine, SIGNAL(finished()), - this, SLOT(hide())); - m_timeLine->start(); + setSearchObject(webView); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + ui.highlightAllButton->setVisible(true); + connect(ui.highlightAllButton, SIGNAL(toggled(bool)), + this, SLOT(highlightAll())); + connect(ui.searchLineEdit, SIGNAL(textEdited(const QString &)), + this, SLOT(highlightAll())); +#endif } void WebViewSearch::findNext() @@ -111,39 +51,30 @@ void WebViewSearch::findPrevious() find(QWebPage::FindBackward | QWebPage::FindWrapsAroundDocument); } +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) +void WebViewSearch::highlightAll() +{ + webView()->findText(QString(), QWebPage::HighlightAllOccurrences); + + if (ui.highlightAllButton->isChecked()) + find(QWebPage::HighlightAllOccurrences); +} +#endif + void WebViewSearch::find(QWebPage::FindFlags flags) { - QString searchString = ui.searchLineEdit->lineEdit()->text(); - if (!m_webView || searchString.isEmpty()) + QString searchString = ui.searchLineEdit->text(); + if (!searchObject() || searchString.isEmpty()) return; QString infoString; - if (!m_webView->findText(searchString, flags)) + if (!webView()->findText(searchString, flags)) infoString = tr("Not Found"); ui.searchInfo->setText(infoString); } -void WebViewSearch::resizeEvent(QResizeEvent *event) -{ - if (event->size().width() != m_widget->width()) - m_widget->resize(event->size().width(), m_widget->height()); - QWidget::resizeEvent(event); -} - -void WebViewSearch::animateHide() -{ - m_timeLine->setDirection(QTimeLine::Backward); - m_timeLine->start(); - connect(m_timeLine, SIGNAL(finished()), this, SLOT(hide())); -} - -void WebViewSearch::frameChanged(int frame) +QWebView *WebViewSearch::webView() const { - if (!m_widget) - return; - m_widget->move(0, frame); - int height = qMax(0, m_widget->y() + m_widget->height()); - setMinimumHeight(height); - setMaximumHeight(height); + return qobject_cast(searchObject()); } WebViewWithSearch::WebViewWithSearch(WebView *webView, QWidget *parent) @@ -154,9 +85,9 @@ WebViewWithSearch::WebViewWithSearch(WebView *webView, QWidget *parent) QVBoxLayout *layout = new QVBoxLayout; layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); - m_webViewSearch = new WebViewSearch(this); + m_webViewSearch = new WebViewSearch(m_webView, this); layout->addWidget(m_webViewSearch); - m_webViewSearch->setWebView(m_webView); layout->addWidget(m_webView); setLayout(layout); } + diff --git a/src/webviewsearch.h b/src/webviewsearch.h index ae854000..d7158d56 100644 --- a/src/webviewsearch.h +++ b/src/webviewsearch.h @@ -20,49 +20,31 @@ #ifndef WEBVIEWSEARCH_H #define WEBVIEWSEARCH_H -#include +#include "searchbar.h" #include -#include "ui_searchbanner.h" - QT_BEGIN_NAMESPACE -class QTimeLine; class QWebView; QT_END_NAMESPACE -class WebViewSearch : public QWidget +class WebViewSearch : public SearchBar { Q_OBJECT public: - WebViewSearch(QWidget *parent = 0); - - void setWebView(QWebView *webView); - QWebView *webView() const; + WebViewSearch(QWebView *webView, QWidget *parent = 0); public slots: - void animateHide(); - void clear(); - void showFind(); void findNext(); void findPrevious(); - -protected: - void resizeEvent(QResizeEvent *event); - -private slots: - void frameChanged(int frame); - void find(QWebPage::FindFlags flags); +#if QT_VERSION >= 0x040600 || defined(WEBKIT_TRUNK) + void highlightAll(); +#endif private: - void initializeSearchWidget(); - - Ui_SearchBanner ui; - QWidget *m_widget; - - QWebView *m_webView; - QTimeLine *m_timeLine; + void find(QWebPage::FindFlags flags); + QWebView *webView() const; }; #include "webview.h" diff --git a/tools/cacheinfo/.gitignore b/tools/cacheinfo/.gitignore new file mode 100644 index 00000000..ff937645 --- /dev/null +++ b/tools/cacheinfo/.gitignore @@ -0,0 +1 @@ +arora-cacheinfo diff --git a/tools/cacheinfo/cacheinfo.pro b/tools/cacheinfo/cacheinfo.pro new file mode 100644 index 00000000..86d385c4 --- /dev/null +++ b/tools/cacheinfo/cacheinfo.pro @@ -0,0 +1,32 @@ +TEMPLATE = app +TARGET = arora-cacheinfo +DEPENDPATH += . +INCLUDEPATH += . + +win32|os2: CONFIG += console +mac:CONFIG -= app_bundle + +QT += network + +# Input +SOURCES += main.cpp + +RCC_DIR = $$PWD/.rcc +UI_DIR = $$PWD/.ui +MOC_DIR = $$PWD/.moc +OBJECTS_DIR = $$PWD/.obj + +include(../../install.pri) + +!mac { +unix { + INSTALLS += man man-compress + + man.path = $$DATADIR/man/man1 + man.files += data/arora-cacheinfo.1 + + man-compress.path = $$DATADIR/man/man1 + man-compress.extra = "" "gzip -9 -f \$(INSTALL_ROOT)/$$DATADIR/man/man1/arora-cacheinfo.1" "" + man-compress.depends = install_man +} +} diff --git a/tools/cacheinfo/data/arora-cacheinfo.1 b/tools/cacheinfo/data/arora-cacheinfo.1 new file mode 100644 index 00000000..ee567817 --- /dev/null +++ b/tools/cacheinfo/data/arora-cacheinfo.1 @@ -0,0 +1,39 @@ +.TH ARORA-CACHEINFO "1" "July 2009" + +.SH NAME +arora-cacheinfo - a tool for extracting files and metadata out of Arora cache files. + +.SH SYNOPSIS +.B arora-cacheinfo [-o cachefile] [file | url] + +.SH DESCRIPTION +.B Arora-cacheinfo +is a tool for extracting files and displaying metadata out of an Arora cache files that are stored on the disk. Every cache file contains both the cached file (sometimes compressed) and metadata associated with it such as expiration date. Cache files names always include the md5sum of the url and passing a url to arora-cacheinfo.1 will automatically determine the correct matching cache file name. + +.SH OPTIONS +.TP +.B -o cachefile +Write the cached file if it exists to \fBcachefile\fR +.TP +.B file +Specify the file to read from. +.TP +.B url +Specify the url from which to compute the file to read from. +.TP + +.SH BUGS +Please report bugs to \fIhttp://code.google.com/p/arora/issues/list\fR. + +.SH AUTHOR +The author of arora-cacheinfo is Benjamin C. Meyer . +.PP +This manual page was written by Benjamin C. Meyer +.PP +Permission is granted to copy, distribute and/or modify this document under the +terms of the +GNU General Public License, Version 2 or any later version published by the Free +Software Foundation. +.PP +On Debian systems, the complete text of the GNU General Public License can be +found in /usr/share/common-licenses/GPL. diff --git a/tools/cacheinfo/main.cpp b/tools/cacheinfo/main.cpp new file mode 100644 index 00000000..5e88ebc4 --- /dev/null +++ b/tools/cacheinfo/main.cpp @@ -0,0 +1,113 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include + +class NetworkDiskCache : public QNetworkDiskCache +{ +public: + QNetworkCacheMetaData _fileMetaData(const QString &fileName) + { return fileMetaData(fileName); } + +}; + +int main(int argc, char **argv) +{ + QCoreApplication application(argc, argv); + QCoreApplication::setOrganizationDomain(QLatin1String("arora-browser.org")); + QCoreApplication::setApplicationName(QLatin1String("Arora")); + + QStringList args = application.arguments(); + args.takeFirst(); + if (args.isEmpty()) { + QTextStream stream(stdout); + stream << "arora-cacheinfo is a tool for viewing and extracting information out of Arora cache files." << endl; + stream << "arora-cacheinfo [-o cachefile] [file | url]" << endl; + return 0; + } + + NetworkDiskCache diskCache; + QString location = QDesktopServices::storageLocation(QDesktopServices::CacheLocation) + + QLatin1String("/browser/"); + diskCache.setCacheDirectory(location); + + QNetworkCacheMetaData metaData; + QString last = args.takeLast(); + if (QFile::exists(last)) { + qDebug() << "Reading in from a file and not a URL."; + metaData = diskCache._fileMetaData(last); + } else { + qDebug() << "Reading in from a URL and not a file."; + metaData = diskCache.metaData(last); + } + + if (!args.isEmpty() + && args.count() >= 1 + && args.first() == QLatin1String("-o")) { + QUrl url = metaData.url(); + QIODevice *device = diskCache.data(url); + if (!device) { + qDebug() << "Error: data for URL is 0!"; + return 1; + } + QString fileName; + if (args.count() == 2) { + fileName = args.last(); + } else { + QFileInfo info(url.path()); + fileName = info.fileName(); + if (fileName.isEmpty()) { + qDebug() << "URL file name is empty, please specify an output file, I wont guess."; + return 1; + } + if (QFile::exists(fileName)) { + qDebug() << "File already exists, not overwriting, please specify an output file."; + return 1; + } + } + qDebug() << "Saved cache file to:" << fileName; + QFile file(fileName); + if (!file.open(QFile::ReadWrite)) + qDebug() << "Unable to open the output file for writing."; + else + file.write(device->readAll()); + delete device; + } + + QTextStream stream(stdout); + stream << "URL: " << metaData.url().toString() << endl; + stream << "Expiration Date: " << metaData.expirationDate().toString() << endl; + stream << "Last Modified Date: " << metaData.lastModified().toString() << endl; + stream << "Save to disk: " << metaData.saveToDisk() << endl; + stream << "Headers:" << endl; + foreach (const QNetworkCacheMetaData::RawHeader &header, metaData.rawHeaders()) + stream << "\t" << header.first << ": " << header.second << endl; + QIODevice *device = diskCache.data(metaData.url()); + if (device) { + stream << "Data Size: " << device->size() << endl; + stream << "First line: " << device->readLine(100); + } else { + stream << "No data? Either the file is corrupt or there is an error." << endl; + } + + delete device; + return 0; +} + diff --git a/tools/htmlToXBel/.gitignore b/tools/htmlToXBel/.gitignore new file mode 100644 index 00000000..b611ba2d --- /dev/null +++ b/tools/htmlToXBel/.gitignore @@ -0,0 +1 @@ +htmlToXBel diff --git a/tools/htmlToXBel/data/htmlToXBel.1 b/tools/htmlToXBel/data/htmlToXBel.1 new file mode 100644 index 00000000..59b8d32b --- /dev/null +++ b/tools/htmlToXBel/data/htmlToXBel.1 @@ -0,0 +1,33 @@ +.TH HTMLTOXBEL "1" "July 2009" + +.SH NAME +htmlToXBel - a tool to convert bookmarks stored in the html format into the xbel format. + +.SH SYNOPSIS +.B htmlToXBel [stdin|htmlfile] [stdout|-o outFile] + +.SH DESCRIPTION +.B htmlToXBel +is a tool to convert bookmarks stored in the html format into the xbel format. Many browser have the ability to export their bookmarks as a html file. htmlToXBel takes that file as an input and will output those bookmarks in the XML Bookmark Exchange Language (XBEL) format. + +.SH OPTIONS +.TP +.B -o outFile +Write the resulting XBEL to the file \fBoutFile\fR +.TP + +.SH BUGS +Please report bugs to \fIhttp://code.google.com/p/arora/issues/list\fR. + +.SH AUTHOR +The author of htmlToXBel is Benjamin C. Meyer . +.PP +This manual page was written by Benjamin C. Meyer +.PP +Permission is granted to copy, distribute and/or modify this document under the +terms of the +GNU General Public License, Version 2 or any later version published by the Free +Software Foundation. +.PP +On Debian systems, the complete text of the GNU General Public License can be +found in /usr/share/common-licenses/GPL. diff --git a/tools/htmlToXBel/extract.js b/tools/htmlToXBel/extract.js new file mode 100644 index 00000000..fc9eb752 --- /dev/null +++ b/tools/htmlToXBel/extract.js @@ -0,0 +1,49 @@ + +function walk() { + var parent = arguments[0]; + var indent = arguments[1]; + + var result = ""; + var children = parent.childNodes; + var folderName = ""; + var folded = ""; + for (var i = 0; i < children.length; i++) { + var object = children.item(i); + if (object.nodeName == "HR") { + result += indent + "\n"; + } + if (object.nodeName == "H3") { + folderName = object.innerHTML; + folded = object.folded; + if (object.folded == undefined) + folded = "false"; + else + folded = "true"; + } + if (object.nodeName == "A") { + result += indent + "\n"; + result += indent + indent + "" + object.innerHTML + "\n"; + result += indent + "\n"; + } + + var currentIndent = indent; + if (object.nodeName == "DL") { + result += indent + "\n"; + indent += " "; + result += indent + "" + folderName + "\n"; + } + result += walk(object, indent); + if (object.nodeName == "DL") { + result += currentIndent + "\n"; + } + } + return result; +} + +var xbel = walk(document, " "); + +if (xbel != "") { + xbel = "\n\n\n" + xbel + "\n"; +} + +xbel; diff --git a/tools/htmlToXBel/htmlToXBel.pro b/tools/htmlToXBel/htmlToXBel.pro new file mode 100644 index 00000000..a8cbef95 --- /dev/null +++ b/tools/htmlToXBel/htmlToXBel.pro @@ -0,0 +1,35 @@ +TEMPLATE = app +TARGET = htmlToXBel +DEPENDPATH += . +INCLUDEPATH += . + +win32|os2: CONFIG += console +mac:CONFIG -= app_bundle + +QT += network webkit + +# Input +SOURCES += main.cpp + +RCC_DIR = $$PWD/.rcc +UI_DIR = $$PWD/.ui +MOC_DIR = $$PWD/.moc +OBJECTS_DIR = $$PWD/.obj + +RESOURCES += source.qrc + +include(../../install.pri) +include(../../webkittrunk.pri) + +!mac { +unix { + INSTALLS += man man-compress + + man.path = $$DATADIR/man/man1 + man.files += data/htmlToXBel.1 + + man-compress.path = $$DATADIR/man/man1 + man-compress.extra = "" "gzip -9 -f \$(INSTALL_ROOT)/$$DATADIR/man/man1/htmlToXBel.1" "" + man-compress.depends = install_man +} +} diff --git a/tools/htmlToXBel/main.cpp b/tools/htmlToXBel/main.cpp new file mode 100644 index 00000000..15c2ea58 --- /dev/null +++ b/tools/htmlToXBel/main.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2008 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include + +/*! + A tool to convert html bookmark files into the xbel format. + + The html bookmark files should be DOCTYPE: NETSCAPE-Bookmark-file-1 + + More information about XBel can be found here: http://pyxml.sourceforge.net/topics/xbel/ +*/ +int main(int argc, char **argv) +{ + QApplication application(argc, argv); + + QFile inFile; + QFile outFile; + QTextStream in(&inFile); + QTextStream out(&outFile); + + // Either read in from stdin and output to stdout + // or read in from a file and output to a file + // Example: ./app foo.html -o bar.xbel + bool setInput = false; + bool setOutput = false; + QStringList args = application.arguments(); + args.pop_front(); + foreach (const QString &arg, args) { + if (arg == QLatin1String("-o")) { + setOutput = true; + } else if (setOutput) { + outFile.setFileName(arg); + outFile.open(QIODevice::WriteOnly); + } else if (QFile::exists(arg)) { + setInput = true; + inFile.setFileName(arg); + inFile.open(QIODevice::ReadOnly); + } else { + qWarning() << "Usage: htmlToXBel" + << "[stdin|htmlfile]" << "[stdout|-o outFile]"; + return 1; + } + } + + if (!setInput) + inFile.open(stdin, QIODevice::ReadOnly); + if (!setOutput) + outFile.open(stdout, QIODevice::WriteOnly); + if (inFile.openMode() == QIODevice::NotOpen + || outFile.openMode() == QIODevice::NotOpen) { + qWarning() << "Unable to open streams"; + return 1; + } + + QWebPage webPage; + webPage.mainFrame()->setHtml(inFile.readAll()); + QFile jsFile(":/extract.js"); + if (!jsFile.open(QFile::ReadOnly)) { + qWarning() << "Unable to load javascript to extract bookmarks."; + return 1; + } + QString result = webPage.mainFrame()->evaluateJavaScript(jsFile.readAll()).toString(); + if (result.isEmpty()) { + qWarning() << "Error while extracting bookmarks."; + return 1; + } + out << result; + return 0; +} diff --git a/tools/htmlToXBel/source.qrc b/tools/htmlToXBel/source.qrc new file mode 100644 index 00000000..5f5bd7df --- /dev/null +++ b/tools/htmlToXBel/source.qrc @@ -0,0 +1,6 @@ + + + extract.js + + + diff --git a/tools/htmlToXBel/tests/firefox3-bookmarks.html b/tools/htmlToXBel/tests/firefox3-bookmarks.html new file mode 100644 index 00000000..5352a48c --- /dev/null +++ b/tools/htmlToXBel/tests/firefox3-bookmarks.html @@ -0,0 +1,47 @@ + + + +Bookmarks +

    Bookmarks Menu

    + +

    +

    Recently Bookmarked +
    Recent Tags +
    +
    Get Bookmark Add-ons +
    +

    Mozilla Firefox

    +

    +

    Help and Tutorials +
    Customize Firefox +
    Get Involved +
    About Us +

    +

    Mozilla Firefox Start Page +
    Mozilla Firefox Start Page +

    Bookmarks Toolbar

    +
    Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar +

    +

    Most Visited +

    Smart Bookmarks

    +

    +

    Most Visited +
    Recently Bookmarked +
    +
    Recent Tags +

    +

    Getting Started +
    Latest Headlines +

    +

    Unfiled Bookmarks

    +

    +

    reddit.com: Apple pushes Windows Safari via iTunes updater +
    +
    reddit.com: what's new online! +
    +
    xkcd - A webcomic of romance, sarcasm, math, and language - By Randall Munroe +
    +

    +

    diff --git a/tools/htmlToXBel/tests/ie7-bookmarks.html b/tools/htmlToXBel/tests/ie7-bookmarks.html new file mode 100644 index 00000000..c4a55152 --- /dev/null +++ b/tools/htmlToXBel/tests/ie7-bookmarks.html @@ -0,0 +1,30 @@ + + +Bookmarks +

    Bookmarks

    +

    +

    Links

    +

    +

    Customize Links +
    Free Hotmail +
    Windows Marketplace +
    Windows Media +
    Windows +

    +

    Microsoft Websites

    +

    +

    IE Add-on site +
    IE site on Microsoft.com +
    Marketplace +
    Microsoft At Home +
    Microsoft At Work +
    Welcome to IE7 +

    +

    Yahoo!

    +

    +

    +

    MSN.com +
    Radio Station Guide +

    diff --git a/tools/htmlToXBel/tests/opera9-bookmarks.html b/tools/htmlToXBel/tests/opera9-bookmarks.html new file mode 100644 index 00000000..5cf7b85f --- /dev/null +++ b/tools/htmlToXBel/tests/opera9-bookmarks.html @@ -0,0 +1,20 @@ + + + +Bookmarks +

    Bookmarks

    +

    +

    Opera

    +

    +

    Download Opera +
    Opera Community +
    Opera Web Mail +
    Support Desk +

    +

    Download.com +
    Amazon.com +
    eBay +
    Yahoo! +

    diff --git a/tools/placesimport/.gitignore b/tools/placesimport/.gitignore new file mode 100644 index 00000000..a05641a2 --- /dev/null +++ b/tools/placesimport/.gitignore @@ -0,0 +1,2 @@ +arora-placesimport + diff --git a/tools/placesimport/data/arora-placesimport.1 b/tools/placesimport/data/arora-placesimport.1 new file mode 100644 index 00000000..4d50311b --- /dev/null +++ b/tools/placesimport/data/arora-placesimport.1 @@ -0,0 +1,27 @@ +.TH HTMLTOXBEL "1" "July 2009" + +.SH NAME +arora-placesimport - a tool for importing browser history from Firefox 3 and up + +.SH SYNOPSIS +.B arora-placesinfo ~/.mozilla/firefox/[profile-dir]/places.sqlite + +.SH DESCRIPTION +.B htmlToXBel +is a tool for importing browser history from Firefox 3 and up. + +.SH BUGS +Please report bugs to \fIhttp://code.google.com/p/arora/issues/list\fR. + +.SH AUTHOR +The author of htmlToXBel is Benjamin C. Meyer . +.PP +This manual page was written by Benjamin C. Meyer +.PP +Permission is granted to copy, distribute and/or modify this document under the +terms of the +GNU General Public License, Version 2 or any later version published by the Free +Software Foundation. +.PP +On Debian systems, the complete text of the GNU General Public License can be +found in /usr/share/common-licenses/GPL. diff --git a/tools/placesimport/main_placesimport.cpp b/tools/placesimport/main_placesimport.cpp new file mode 100644 index 00000000..ecca9adb --- /dev/null +++ b/tools/placesimport/main_placesimport.cpp @@ -0,0 +1,94 @@ +/* + * Copyright 2008-2009 Benjamin K. Stuhl + * Copyright 2009 Benjamin C. Meyer + * + * This program 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; either version 2 of the License, or + * (at your option) any later version. + * + * This program 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "singleapplication.h" +#include "historymanager.h" + +static HistoryEntry formatEntry(QByteArray url, QByteArray title, qlonglong prdate) +{ + QDateTime dateTime = QDateTime::fromTime_t(prdate / 1000000); + dateTime.addMSecs((prdate % 1000000) / 1000); + HistoryEntry entry(url, dateTime, title); + return entry; +} + +int main(int argc, char **argv) +{ + SingleApplication application(argc, argv); + QCoreApplication::setOrganizationDomain(QLatin1String("arora-browser.org")); + QCoreApplication::setApplicationName(QLatin1String("Arora")); + + if (application.sendMessage(QByteArray())) { + qWarning() << "To prevent the loss of any history please exit Arora while this is tool is being run"; + return 1; + } + + QStringList args = application.arguments(); + args.takeFirst(); + if (args.isEmpty()) { + QTextStream stream(stdout); + stream << "arora-placesimport is a tool for importing browser history from Firefox 3 and up" << endl; + stream << "arora-placesinfo ~/.mozilla/firefox/[profile-dir]/places.sqlite" << endl; + return 0; + } + + QSqlDatabase placesDatabase = QSqlDatabase::addDatabase("QSQLITE"); + placesDatabase.setDatabaseName(args.first()); + + if (!placesDatabase.open()) { + qWarning("Unable to open database: %s", qPrintable(placesDatabase.lastError().text())); + return 1; + } + + QSqlQuery historyQuery( + "SELECT moz_places.url, moz_places.title, moz_historyvisits.visit_date " + "FROM moz_places, moz_historyvisits " + "WHERE moz_places.id = moz_historyvisits.place_id;"); + historyQuery.setForwardOnly(true); + + if (!historyQuery.exec()) { + qWarning("Unable to extract history: %s. Is Firefox running?", qPrintable(historyQuery.lastError().text())); + return 1; + } + + HistoryManager manager; + QList history = manager.history(); + while (historyQuery.next()) { + QByteArray url = historyQuery.value(0).toByteArray(); + QByteArray title = historyQuery.value(1).toByteArray(); + qlonglong prdate = historyQuery.value(2).toLongLong(); + HistoryEntry entry = formatEntry(url, title, prdate); + history.append(entry); + } + manager.setHistory(history); + + return 0; +} + diff --git a/tools/placesimport/placesimport.pro b/tools/placesimport/placesimport.pro new file mode 100644 index 00000000..cc0810c9 --- /dev/null +++ b/tools/placesimport/placesimport.pro @@ -0,0 +1,30 @@ +TEMPLATE = app +TARGET = arora-placesimport +DEPENDPATH += . +INCLUDEPATH += . + +win32|os2: CONFIG += console +mac:CONFIG -= app_bundle + +QT += sql + +# Input +SOURCES += main_placesimport.cpp + +include(../../install.pri) +# This can be improved to just include the history manager and utility classes +# once the history classes are separated out into individual files. +include(../../src/src.pri) + +!mac { +unix { + INSTALLS += man man-compress + + man.path = $$DATADIR/man/man1 + man.files += data/arora-placesimport.1 + + man-compress.path = $$DATADIR/man/man1 + man-compress.extra = "" "gzip -9 -f \$(INSTALL_ROOT)/$$DATADIR/man/man1/arora-placesimport.1" "" + man-compress.depends = install_man +} +} diff --git a/tools/tools.pro b/tools/tools.pro new file mode 100644 index 00000000..428f211c --- /dev/null +++ b/tools/tools.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = cacheinfo htmlToXBel placesimport + +CONFIG += ordered diff --git a/webkittrunk.pri b/webkittrunk.pri new file mode 100644 index 00000000..e8c49540 --- /dev/null +++ b/webkittrunk.pri @@ -0,0 +1,47 @@ +# To build Arora against WebKit trunk: +# export QT_WEBKIT=webkit_trunk +# export WEBKITDIR=$HOME/dev/webkit +# +# Optional: +# export WEBKITOUTPUTDIR=$HOME/build/webkit +# export WEBKITBRANCH=some_cool_git_branch_of_webkit +# +CONFIG += $$(QT_WEBKIT) +webkit_trunk { + WEBKITDIR = $$(WEBKITDIR) + isEmpty(WEBKITDIR): error(Please point WEBKITDIR at the root of your WebKit source tree) + + OUTPUT_DIR = $$(WEBKITOUTPUTDIR) + isEmpty(OUTPUT_DIR): OUTPUT_DIR = $$WEBKITDIR/WebKitBuild + + WEBKITBRANCH = $$(WEBKITBRANCH) + !isEmpty(WEBKITBRANCH) { + OUTPUT_DIR = $$OUTPUT_DIR/$$WEBKITBRANCH + } + + # When building in debug try to link to the debug version of webkit + # and vice versa in release, but when they can not be paired up + # because webkit only has release or debug libs fall back to the other one + CONFIG(debug) { + exists($$OUTPUT_DIR/Debug) { + OUTPUT_DIR = $$OUTPUT_DIR/Debug + } else { + OUTPUT_DIR = $$OUTPUT_DIR/Release + } + } else:CONFIG(release) { + exists($$OUTPUT_DIR/Release) { + OUTPUT_DIR = $$OUTPUT_DIR/Release + } else { + OUTPUT_DIR = $$OUTPUT_DIR/Debug + } + } + + message(Using WebKit Trunk at $$WEBKITDIR) + message(Using WebKit Build at $$OUTPUT_DIR) + + QT -= webkit + DEFINES += WEBKIT_TRUNK + include($$WEBKITDIR/WebKit.pri) + QMAKE_RPATHDIR = $$OUTPUT_DIR/lib $$QMAKE_RPATHDIR +} + diff --git a/windowsinstaller.nsi b/windowsinstaller.nsi index 7c29c6bc..b6abed93 100644 --- a/windowsinstaller.nsi +++ b/windowsinstaller.nsi @@ -3,10 +3,12 @@ SetCompressor /SOLID /FINAL lzma !define PRODUCT_NAME "Arora" -!define /date PRODUCT_VERSION "Snapshot (%#m-%#d-%#Y)" +!define /date PRODUCT_VERSION "0.11.0" +;!define /date PRODUCT_VERSION "Snapshot (%#m-%#d-%#Y)" !define PRODUCT_DIR_REGKEY "Software\Microsoft\Windows\CurrentVersion\App Paths\arora.exe" !define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}" !define PRODUCT_UNINST_ROOT_KEY "HKLM" +!define QTDIR "C:\Qt\qt-all-opensource-src-4.5.3" !include "MUI.nsh" !define MUI_ABORTWARNING @@ -27,50 +29,62 @@ Name "${PRODUCT_NAME} ${PRODUCT_VERSION}" OutFile "${PRODUCT_NAME} ${PRODUCT_VERSION} Installer.exe" InstallDir "$PROGRAMFILES\${PRODUCT_NAME}" InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" "" -ShowInstDetails nevershow -ShowUnInstDetails nevershow +ShowInstDetails show +ShowUnInstDetails show -Section "Main Components" SEC01 +Section "Main Components" KillProcDLL::KillProc "arora.exe" Sleep 100 SetOverwrite on SetOutPath "$INSTDIR" File "arora.exe" - File "C:\qt\4.4.0\bin\QtCore4.dll" - File "C:\qt\4.4.0\bin\QtGui4.dll" - File "C:\qt\4.4.0\bin\QtNetwork4.dll" - File "C:\qt\4.4.0\bin\QtWebKit4.dll" - File "C:\windows\system32\ssleay32.dll" - File "C:\windows\system32\libeay32.dll" - File "C:\windows\system32\msvcr71.dll" + File "tools\htmlToXbel\release\htmlToXBel.exe" + File "tools\cacheinfo\release\arora-cacheinfo.exe" + File "tools\placesimport\release\arora-placesimport.exe" + File "${QTDIR}\lib\QtCore4.dll" + File "${QTDIR}\lib\QtGui4.dll" + File "${QTDIR}\lib\QtNetwork4.dll" + File "${QTDIR}\lib\QtWebKit4.dll" + File "${QTDIR}\lib\QtScript4.dll" + File "${QTDIR}\lib\QtSql4.dll" + ;File "${QTDIR}\lib\phonon4.dll" + File "C:\Qt\openssl-0.9.8j\out32dll\ssleay32.dll" + File "C:\Qt\openssl-0.9.8j\out32dll\libeay32.dll" SetOutPath "$INSTDIR\locale" File "src\.qm\locale\*.qm" + File "${QTDIR}\translations\qt*.qm" + + SetOutPath "$INSTDIR\plugins\sqldrivers" + File "${QTDIR}\plugins\sqldrivers\qsqlite4.dll" SetOutPath "$INSTDIR\imageformats" - File "C:\qt\4.4.0\plugins\imageformats\qtiff4.dll" - File "C:\qt\4.4.0\plugins\imageformats\qsvg4.dll" - File "C:\qt\4.4.0\plugins\imageformats\qmng4.dll" - File "C:\qt\4.4.0\plugins\imageformats\qjpeg4.dll" - File "C:\qt\4.4.0\plugins\imageformats\qico4.dll" - File "C:\qt\4.4.0\plugins\imageformats\qgif4.dll" + File "${QTDIR}\plugins\imageformats\qtiff4.dll" + File "${QTDIR}\plugins\imageformats\qsvg4.dll" + File "${QTDIR}\plugins\imageformats\qmng4.dll" + File "${QTDIR}\plugins\imageformats\qjpeg4.dll" + File "${QTDIR}\plugins\imageformats\qico4.dll" + File "${QTDIR}\plugins\imageformats\qgif4.dll" SetOutPath "$INSTDIR\iconengines" - File "C:\qt\4.4.0\plugins\iconengines\qsvgicon4.dll" + File "${QTDIR}\plugins\iconengines\qsvgicon4.dll" SetOutPath "$INSTDIR\codecs" - File "C:\qt\4.4.0\plugins\codecs\qtwcodecs4.dll" - File "C:\qt\4.4.0\plugins\codecs\qkrcodecs4.dll" - File "C:\qt\4.4.0\plugins\codecs\qjpcodecs4.dll" - File "C:\qt\4.4.0\plugins\codecs\qcncodecs4.dll" + File "${QTDIR}\plugins\codecs\qtwcodecs4.dll" + File "${QTDIR}\plugins\codecs\qkrcodecs4.dll" + File "${QTDIR}\plugins\codecs\qjpcodecs4.dll" + File "${QTDIR}\plugins\codecs\qcncodecs4.dll" + + SetOutPath "$INSTDIR\phonon_backend" +; File "${QTDIR}\plugins\phonon_backend\phonon_ds94.dll" SectionEnd -Section -Icons +Section Icons CreateShortCut "$SMPROGRAMS\Arora.lnk" "$INSTDIR\arora.exe" SectionEnd -Section -UninstallInfo +Section Uninstaller WriteUninstaller "$INSTDIR\uninst.exe" WriteRegStr HKLM "${PRODUCT_DIR_REGKEY}" "" "$INSTDIR\arora.exe" WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayName" "$(^Name)" @@ -79,6 +93,14 @@ Section -UninstallInfo WriteRegStr ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" "DisplayVersion" "${PRODUCT_VERSION}" SectionEnd +Section MSVC + InitPluginsDir + SetOutPath $PLUGINSDIR + File "C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\vcredist_x86\vcredist_x86.exe" + DetailPrint "Installing Visual C++ 2005 Libraries" + ExecWait '"$PLUGINSDIR\vcredist_x86.exe" /q:a /c:"msiexec /i vcredist.msi /quiet"' +SectionEnd + Section Uninstall KillProcDLL::KillProc "arora.exe" Sleep 100 @@ -87,4 +109,5 @@ Section Uninstall DeleteRegKey ${PRODUCT_UNINST_ROOT_KEY} "${PRODUCT_UNINST_KEY}" DeleteRegKey HKLM "${PRODUCT_DIR_REGKEY}" SectionEnd + BrandingText "arora-browser.org"