From c0190e41f7f2e5fe30fa8556fa35f43950afbfdb Mon Sep 17 00:00:00 2001 From: adjam Date: Sun, 3 May 2009 23:51:22 +0000 Subject: Importing recode (rekonq code). I'm sorry I coudn't perform this with gitsvn or tailor.. but I cannot lose all the evening just for this. And I need to sleep now.. git-svn-id: svn+ssh://svn.kde.org/home/kde/trunk/playground/network/rekonq@963146 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- AUTHORS | 4 + CMakeLists.txt | 98 +++ COPYING | 674 +++++++++++++++++++ ChangeLog | 26 + INSTALL | 27 + data/CMakeLists.txt | 24 + data/defaultbookmarks.xbel | 22 + data/loading.gif | Bin 0 -> 847 bytes data/notfound.html | 66 ++ data/rekonq.desktop | 12 + data/slack-desc | 12 + data/webkit-icon.png | Bin 0 -> 25694 bytes doc/CMakeLists.txt | 4 + doc/index.docbook | 327 ++++++++++ icons/CMakeLists.txt | 2 + icons/hi16-app-rekonq.png | Bin 0 -> 887 bytes icons/hi32-app-rekonq.png | Bin 0 -> 2269 bytes icons/hi64-app-rekonq.png | Bin 0 -> 6071 bytes po/CMakeLists.txt | 34 + po/rekonq.pot | 1007 +++++++++++++++++++++++++++++ po/rekonq_de.po | 1099 +++++++++++++++++++++++++++++++ po/rekonq_it.po | 1038 ++++++++++++++++++++++++++++++ po/rekonq_ru.po | 1134 ++++++++++++++++++++++++++++++++ rekonq.SlackBuild | 79 +++ scripts/codingstyle.sh | 48 ++ scripts/i18n.sh | 41 ++ src/CMakeLists.txt | 63 ++ src/application.cpp | 206 ++++++ src/application.h | 115 ++++ src/autosaver.cpp | 90 +++ src/autosaver.h | 55 ++ src/bookmarks.cpp | 278 ++++++++ src/bookmarks.h | 238 +++++++ src/cookiejar.cpp | 841 ++++++++++++++++++++++++ src/cookiejar.h | 200 ++++++ src/cookies.ui | 107 ++++ src/cookiesexceptions.ui | 179 ++++++ src/download.cpp | 224 +++++++ src/download.h | 141 ++++ src/edittableview.cpp | 61 ++ src/edittableview.h | 42 ++ src/edittreeview.cpp | 61 ++ src/edittreeview.h | 41 ++ src/findbar.cpp | 137 ++++ src/findbar.h | 61 ++ src/history.cpp | 1459 ++++++++++++++++++++++++++++++++++++++++++ src/history.h | 402 ++++++++++++ src/history.ui | 101 +++ src/lineedit.cpp | 85 +++ src/lineedit.h | 50 ++ src/main.cpp | 98 +++ src/mainview.cpp | 716 +++++++++++++++++++++ src/mainview.h | 198 ++++++ src/mainwindow.cpp | 930 +++++++++++++++++++++++++++ src/mainwindow.h | 153 +++++ src/modelmenu.cpp | 228 +++++++ src/modelmenu.h | 92 +++ src/networkaccessmanager.cpp | 165 +++++ src/networkaccessmanager.h | 47 ++ src/panelhistory.cpp | 95 +++ src/panelhistory.h | 55 ++ src/password.ui | 69 ++ src/proxy.ui | 62 ++ src/rekonq.kcfg | 119 ++++ src/rekonq.kcfgc | 5 + src/rekonqui.rc | 104 +++ src/searchbar.cpp | 129 ++++ src/searchbar.h | 67 ++ src/settings.cpp | 212 ++++++ src/settings.h | 55 ++ src/settings_fonts.ui | 97 +++ src/settings_general.ui | 142 ++++ src/settings_privacy.ui | 168 +++++ src/settings_proxy.ui | 152 +++++ src/settings_webkit.ui | 134 ++++ src/sidepanel.cpp | 53 ++ src/sidepanel.h | 50 ++ src/stackedurlbar.cpp | 152 +++++ src/stackedurlbar.h | 64 ++ src/tabbar.cpp | 145 +++++ src/tabbar.h | 78 +++ src/urlbar.cpp | 240 +++++++ src/urlbar.h | 99 +++ src/webview.cpp | 504 +++++++++++++++ src/webview.h | 155 +++++ 85 files changed, 16847 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 data/CMakeLists.txt create mode 100644 data/defaultbookmarks.xbel create mode 100644 data/loading.gif create mode 100644 data/notfound.html create mode 100644 data/rekonq.desktop create mode 100644 data/slack-desc create mode 100644 data/webkit-icon.png create mode 100644 doc/CMakeLists.txt create mode 100644 doc/index.docbook create mode 100644 icons/CMakeLists.txt create mode 100644 icons/hi16-app-rekonq.png create mode 100644 icons/hi32-app-rekonq.png create mode 100644 icons/hi64-app-rekonq.png create mode 100644 po/CMakeLists.txt create mode 100644 po/rekonq.pot create mode 100644 po/rekonq_de.po create mode 100644 po/rekonq_it.po create mode 100644 po/rekonq_ru.po create mode 100644 rekonq.SlackBuild create mode 100755 scripts/codingstyle.sh create mode 100755 scripts/i18n.sh create mode 100644 src/CMakeLists.txt create mode 100644 src/application.cpp create mode 100644 src/application.h create mode 100644 src/autosaver.cpp create mode 100644 src/autosaver.h create mode 100644 src/bookmarks.cpp create mode 100644 src/bookmarks.h create mode 100644 src/cookiejar.cpp create mode 100644 src/cookiejar.h create mode 100644 src/cookies.ui create mode 100644 src/cookiesexceptions.ui create mode 100644 src/download.cpp create mode 100644 src/download.h create mode 100644 src/edittableview.cpp create mode 100644 src/edittableview.h create mode 100644 src/edittreeview.cpp create mode 100644 src/edittreeview.h create mode 100644 src/findbar.cpp create mode 100644 src/findbar.h create mode 100644 src/history.cpp create mode 100644 src/history.h create mode 100644 src/history.ui create mode 100644 src/lineedit.cpp create mode 100644 src/lineedit.h create mode 100644 src/main.cpp create mode 100644 src/mainview.cpp create mode 100644 src/mainview.h create mode 100644 src/mainwindow.cpp create mode 100644 src/mainwindow.h create mode 100644 src/modelmenu.cpp create mode 100644 src/modelmenu.h create mode 100644 src/networkaccessmanager.cpp create mode 100644 src/networkaccessmanager.h create mode 100644 src/panelhistory.cpp create mode 100644 src/panelhistory.h create mode 100644 src/password.ui create mode 100644 src/proxy.ui create mode 100644 src/rekonq.kcfg create mode 100644 src/rekonq.kcfgc create mode 100644 src/rekonqui.rc create mode 100644 src/searchbar.cpp create mode 100644 src/searchbar.h create mode 100644 src/settings.cpp create mode 100644 src/settings.h create mode 100644 src/settings_fonts.ui create mode 100644 src/settings_general.ui create mode 100644 src/settings_privacy.ui create mode 100644 src/settings_proxy.ui create mode 100644 src/settings_webkit.ui create mode 100644 src/sidepanel.cpp create mode 100644 src/sidepanel.h create mode 100644 src/stackedurlbar.cpp create mode 100644 src/stackedurlbar.h create mode 100644 src/tabbar.cpp create mode 100644 src/tabbar.h create mode 100644 src/urlbar.cpp create mode 100644 src/urlbar.h create mode 100644 src/webview.cpp create mode 100644 src/webview.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..386a41d2 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +Andrea Diamantini adjam7_AT_gmail_DOT_com Project Lead, Developer, Italian translation +Alexander Domrachev alexander.domrachev_AT_gmail_DOT_com Developer, Russian translation +Pawel Prazak kojots350_AT_gmail_DOT_com Developer +snagiotis Papadopoulos pano_90@gmx.net German translation diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..4cbc3de2 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,98 @@ +# Andrea Diamantini - adjam7 at gmail dot com +# rekonq project + +PROJECT( rekonq ) + +# =============================================================================================== +# Informations to update before to release this package. + +# rekonq info +SET(REKONQ_MAJOR_VERSION "0") +SET(REKONQ_MINOR_VERSION "1") +SET(REKONQ_PATCH_VERSION "0alpha") + +SET(REKONQ_VERSION_STR + "${REKONQ_MAJOR_VERSION}.${REKONQ_MINOR_VERSION}.${REKONQ_PATCH_VERSION}" + ) + +SET(REKONQ_SITE "http://rekonq.sourceforge.net") + +# ================================================================================================= +# minimum cmake required + +CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2) + +# ================================================================================================= + + +SET(QT_MIN_VERSION 4.5.0) +FIND_PACKAGE(Qt4 REQUIRED) +SET(KDE_MIN_VERSION 4.2.0) +FIND_PACKAGE(KDE4 REQUIRED) + +INCLUDE(MacroOptionalFindPackage) +INCLUDE(FindPackageHandleStandardArgs) +INCLUDE(KDE4Defaults) +INCLUDE(MacroLibrary) + +# ================================================================================================== +# Log messages + +MESSAGE(STATUS "") +MESSAGE(STATUS "----------------------------------------------------------------------------------") +MESSAGE(STATUS " rekonq ${REKONQ_VERSION_STR} dependencies results <${REKONQ_SITE}>") + +# Require shared libraries results. + +SET(QT_VERS_STR + "${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}.${QT_VERSION_PATCH}" + ) + +IF(QT_FOUND) + MESSAGE(STATUS " Qt library found............... YES") + MESSAGE(STATUS " Qt version ${QT_VERS_STR} found! ") +ELSE(QT_FOUND) + MESSAGE(STATUS " Qt library found............... NO") + MESSAGE(STATUS "") + MESSAGE(SEND_ERROR " rekonq needs at least Qt ${QT_MIN_VERSION}. Please install it and try compiling again.") + MESSAGE(STATUS " Qt website is at http://www.qtsoftware.com") + MESSAGE(STATUS "") +ENDIF(QT_FOUND) + +MESSAGE(STATUS "----------------------------------------------------------------------------------") +MESSAGE(STATUS "") + +# Optional plugins results. + +IF(QT_FOUND) + MESSAGE(STATUS " rekonq will be compiled....... YES") + SET(REKONQ_CAN_BE_COMPILED true) +ELSE(QT_FOUND) + MESSAGE(FATAL_ERROR " rekonq will NOT be compiled!") + SET(REKONQ_CAN_BE_COMPILED false) +ENDIF(QT_FOUND) + +MESSAGE(STATUS "----------------------------------------------------------------------------------") +MESSAGE(STATUS "") + +# ================================================================================================== + +IF(REKONQ_CAN_BE_COMPILED) + + INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${KDE4_INCLUDES} + ${QT4_INCLUDES} + ${QT_QTNETWORK_INCLUDE_DIR} + ${QT_QTWEBKIT_INCLUDE_DIR} + ) + + ADD_SUBDIRECTORY( src ) + ADD_SUBDIRECTORY( icons ) + ADD_SUBDIRECTORY( data ) + ADD_SUBDIRECTORY( po ) +# ADD_SUBDIRECTORY( doc ) + +ENDIF(REKONQ_CAN_BE_COMPILED) + +# ===================================================================================================== diff --git a/COPYING b/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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 3 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, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 00000000..1c830037 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,26 @@ +0.0.4 +- Rekonq Singleton app +- With Qt 4.5, preliminary flash support +- Fixed tabbar actions +- Fixed System Font Loading +- improved bookmarks system + +0.0.3 +- ~80% ported to KDE4 +- use KConfigXT +- improved text search bar +- fixed all "web actions" +- KDE download system +- new bookmark toolbar (1st implementation) + +0.0.2 +- 70% ported to KDE4 +- new urlbar +- new searchbar (just Google, for now) +- new findbar (A-LA kate) +- Slackware Slackbuild available + + +0.0.1 +- initial porting to KDE4 +- share konqueror bookmarks diff --git a/INSTALL b/INSTALL new file mode 100644 index 00000000..3d8888a0 --- /dev/null +++ b/INSTALL @@ -0,0 +1,27 @@ +===== Building rekonq from sources ===== + +=== Prerequisites === + +Qt4.4.x: + + Qt should be prepackaged for all mayor linux distributions. Please see + http://www.trolltech.com/products/qt for more information and installation + instructions. + +KDE 4 + + KDE 4.1 (or better) should be prepackaged for all mayor linux distributions. Please see + http://techbase.kde.org/Getting_Started/Build/stable_Version + for instructions on how to build and setup a KDE4 environment to work in. + + +=== Building rekonq === + + To build it do the following after switching into the source directory: + + mkdir build && cd build + cmake .. + make && make install + +Enjoy. +adjam diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt new file mode 100644 index 00000000..e4535e07 --- /dev/null +++ b/data/CMakeLists.txt @@ -0,0 +1,24 @@ +INSTALL( + FILES loading.gif + DESTINATION ${DATA_INSTALL_DIR}/rekonq/pics +) + +INSTALL( + FILES defaultbookmarks.xbel + DESTINATION ${DATA_INSTALL_DIR}/rekonq +) + +INSTALL( + FILES rekonq.desktop + DESTINATION ${XDG_APPS_INSTALL_DIR} +) + +INSTALL( + FILES notfound.html + DESTINATION ${DATA_INSTALL_DIR}/rekonq/htmls +) + +INSTALL( + FILES webkit-icon.png + DESTINATION ${DATA_INSTALL_DIR}/rekonq/pics +) \ No newline at end of file diff --git a/data/defaultbookmarks.xbel b/data/defaultbookmarks.xbel new file mode 100644 index 00000000..b4919c5c --- /dev/null +++ b/data/defaultbookmarks.xbel @@ -0,0 +1,22 @@ + + + + + QtSoftware + + + WebKit.org + + + rekonq site + + + Trolltech Labs + + + KDE-Apps.org + + + KDE site + + diff --git a/data/loading.gif b/data/loading.gif new file mode 100644 index 00000000..c1545eb0 Binary files /dev/null and b/data/loading.gif differ diff --git a/data/notfound.html b/data/notfound.html new file mode 100644 index 00000000..09039eb1 --- /dev/null +++ b/data/notfound.html @@ -0,0 +1,66 @@ + + + +%1 + + + +
+ Not found +

%3

+

When connecting to: %4.

+
    +
  • Check the address for errors such as ww.kde.org + instead of www.kde.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 rekonq is permitted to access + the network.
  • +
  • Of course, if rekonq doesn't work properly, you can always + say it's a programmer error ;)
  • +
+

+
+ + diff --git a/data/rekonq.desktop b/data/rekonq.desktop new file mode 100644 index 00000000..599e81ee --- /dev/null +++ b/data/rekonq.desktop @@ -0,0 +1,12 @@ +[Desktop Entry] +Name=rekonq +GenericName=Webkit KDE Browser +Icon=rekonq +Type=Application +Exec=rekonq %u +X-DocPath=rekonq/index.html +Categories=Qt;KDE;Network; +Terminal=0 +MimeType=text/html;application/xhtml+xml;application/xml; +X-DBUS-StartupType=Unique +X-DBUS-ServiceName=net.sourceforge.rekonq diff --git a/data/slack-desc b/data/slack-desc new file mode 100644 index 00000000..3136b228 --- /dev/null +++ b/data/slack-desc @@ -0,0 +1,12 @@ + |-------------------------------------------------------------------| +rekonq: rekonq (Webkit KDE Browser) +rekonq: +rekonq: rekonq is a lightweight KDE browser based on webkit +rekonq: +rekonq: +rekonq: +rekonq: +rekonq: +rekonq: +rekonq: +rekonq: diff --git a/data/webkit-icon.png b/data/webkit-icon.png new file mode 100644 index 00000000..b3ec677a Binary files /dev/null and b/data/webkit-icon.png differ diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt new file mode 100644 index 00000000..3a54287f --- /dev/null +++ b/doc/CMakeLists.txt @@ -0,0 +1,4 @@ +########### install files ############### +# + +kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR rekonq) diff --git a/doc/index.docbook b/doc/index.docbook new file mode 100644 index 00000000..32fcb41e --- /dev/null +++ b/doc/index.docbook @@ -0,0 +1,327 @@ + + + + Andrea + Diamantini + + "> + adjam7@gmail.com"> + + +]> + + + + +The &rekonq; Handbook + + +&Andrea.Diamantini; &Andrea.Diamantini.mail; + + + +2008 +2009 +&Andrea.Diamantini; + + +&FDLNotice; + +2008-11-16 +0.0.4 + + + +&rekonq; is a lightweight KDE browser based on WebKit. + + + + +KDE +browser +rekonq +webkit + + + + + + + + +Introduction + + +&rekonq; is a lightweight KDE browser based on WebKit. + + + + +Launching &rekonq; + + +The Find Files tool is a useful method of searching for specific files on your +computer, or for searching for files that match a pattern. An example of +this could include searching for files of a particular type or with certain +letters in the filename. + +You can load this utility by clicking on Find Files. This will +launch &rekonq;. + + + + + + + + + +Finding Files + + +The Name/Location Tab + + +When starting &rekonq;, you will see a quite simple window. Type in the +name of the file you are searching in the text box labeled +Named:. Choose a folder where you want to search +by typing it in the field Look in: +or by clicking Browse... and press +Enter or click Find. If +Include subfolders is checked all +subfolders starting from your chosen folder will be searched +too. The results will be displayed in the box below. + + + +You can use the following wildcards: + + + + +The Asterisk * + + +The asterisk stands for any number of missing characters (even zero), +that means ⪚ searching for marc* may find the +files marc, marc.png and + marc_must_not_read_this.kwd. +mar*.kwd may find +marketplace.kwd and +marc_must_not_read_this.kwd. + + + + + +The Question Mark ? + + +In contrast to the asterisk, the question mark stands for exactly one +character, so mar? will find +marc, but marc? will not find +anything, as our files are called marc and +marc.png. You can put as many question marks in the +term as you want, it will find exactly that number of characters. + + + + + + + +Of course you can combine those two wildcard symbols in a search term. + + + + + +The Contents Tab + + + +File type + + +Here you can specify the type of file you are searching for. + + + + + +Containing text + + +Type in the word or phrase the files you are searching for must +contain. Note: If you do this in a large folder or checked +Include subfolders in the +Name/Location tab, this may take a long time. + + + +This option will not work for all files listed +under File type. Only the following file types +are supported: + + +Text files, ⪚ source code and README files +&kword; >= 1.2 +&kpresenter; >= 1.2 +&kspread; >= 1.2 +OpenOffice.org Writer +OpenOffice.org Impress +OpenOffice.org Calc + + + + + + + + + +Case sensitive + + +If you enable this option, &rekonq; will +only find files with the exact case matching, ⪚ +MARC will only match +MARC, not Marc. + + + + + +Regular expression +If you have installed the &kregexpeditor; tool from +the kdeutils package, you will have this additional option. Enabling +it will allow you to search for a regexp or +regular expression. A regexp is a way to specify conditions for your +search, and they can be very complex, and equally they can be very +powerful. If you are unfamiliar with regular expressions, you can +choose Edit Regular Expression to open +&kregexpeditor;. This tool allows you to construct your set of +conditions graphically, and then generates the expression for +you. + +&kregexpeditor; is a very useful tool, and can be used from within +many &kde; applications other than &rekonq;. You can find more +information from within its own help file. + + + + + + + + + + +The Properties Tab + + +Here you can refine your search. These are the special refinements +you can choose: + + + + + +Find all files created or modified + + +Here you can either enter two dates, between which the +files were created or modified, or specify a time period. + + + + + +File size is + +Here you can specify if the file has to be at least or as most as +big as the size you entered in the following box. + + + + + +Files owned by user, Files owned by group + +Here you can specify user and group names. + + + + + + + + + + + + + + +Credits and License + + +&rekonq; + + + +Program copyright: + + + +Developers + +&Andrea.Diamantini; &Andrea.Diamantini.mail; + + + + + +Documentation copyright 2008 &Andrea.Diamantini; &Andrea.Diamantini.mail; + + + + +&underFDL; +&underBSDLicense; + + + + +Installation + + +How to obtain &rekonq; + +&install.intro.documentation; + + + + +Requirements + + +In order to successfully use &rekonq;, you need at least Qt 4.4.x and &kde; 4.1.x. + + + + + +Compilation and Installation + +&install.compile.documentation; + + + + + +&documentation.index; + + diff --git a/icons/CMakeLists.txt b/icons/CMakeLists.txt new file mode 100644 index 00000000..9d7ead58 --- /dev/null +++ b/icons/CMakeLists.txt @@ -0,0 +1,2 @@ +# install standard icons +KDE4_INSTALL_ICONS( ${ICON_INSTALL_DIR} ) diff --git a/icons/hi16-app-rekonq.png b/icons/hi16-app-rekonq.png new file mode 100644 index 00000000..2427ffef Binary files /dev/null and b/icons/hi16-app-rekonq.png differ diff --git a/icons/hi32-app-rekonq.png b/icons/hi32-app-rekonq.png new file mode 100644 index 00000000..110c6017 Binary files /dev/null and b/icons/hi32-app-rekonq.png differ diff --git a/icons/hi64-app-rekonq.png b/icons/hi64-app-rekonq.png new file mode 100644 index 00000000..74d350a5 Binary files /dev/null and b/icons/hi64-app-rekonq.png differ diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 00000000..261e9e4c --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1,34 @@ +FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt) + +IF(NOT GETTEXT_MSGFMT_EXECUTABLE) + MESSAGE( +"------ + NOTE: msgfmt not found. Translations will *not* be installed +------") +ELSE(NOT GETTEXT_MSGFMT_EXECUTABLE) + + SET(catalogname rekonq) + + ADD_CUSTOM_TARGET(translations ALL) + + FILE(GLOB PO_FILES ${catalogname}*.po) + + FOREACH(_poFile ${PO_FILES}) + GET_FILENAME_COMPONENT(_poFileName ${_poFile} NAME) + STRING(REGEX REPLACE "^${catalogname}_?" "" _langCode ${_poFileName} ) + STRING(REGEX REPLACE "\\.po$" "" _langCode ${_langCode} ) + + IF( _langCode ) + GET_FILENAME_COMPONENT(_lang ${_poFile} NAME_WE) + SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.gmo) + + ADD_CUSTOM_COMMAND(TARGET translations + COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} --check -o ${_gmoFile} ${_poFile} + DEPENDS ${_poFile}) + INSTALL(FILES ${_gmoFile} DESTINATION ${LOCALE_INSTALL_DIR}/${_langCode}/LC_MESSAGES/ RENAME ${catalogname}.mo) + ENDIF( _langCode ) + + ENDFOREACH(_poFile ${PO_FILES}) + +ENDIF(NOT GETTEXT_MSGFMT_EXECUTABLE) + diff --git a/po/rekonq.pot b/po/rekonq.pot new file mode 100644 index 00000000..986af602 --- /dev/null +++ b/po/rekonq.pot @@ -0,0 +1,1007 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: http://sourceforge.net/tracker/?" +"group_id=252277&atid=1126949\n" +"POT-Creation-Date: 2009-05-02 02:35+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" + +#. i18n: file: rekonqui.rc:58 +#. i18n: ectx: Menu (go) +#: bookmarks.cpp:265 rc.cpp:90 +msgid "&Bookmarks" +msgstr "" + +#: bookmarks.cpp:274 +msgid "Bookmarks Bar" +msgstr "" + +#: cookiejar.cpp:457 cookiejar.cpp:636 +msgid "Website" +msgstr "" + +#: cookiejar.cpp:459 +msgid "Name" +msgstr "" + +#: cookiejar.cpp:461 +msgid "Path" +msgstr "" + +#: cookiejar.cpp:463 +msgid "Secure" +msgstr "" + +#: cookiejar.cpp:465 +msgid "Expires" +msgstr "" + +#: cookiejar.cpp:467 +msgid "Contents" +msgstr "" + +#: cookiejar.cpp:638 +msgid "Status" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:77 +#. i18n: ectx: property (text), widget (QPushButton, allowButton) +#: cookiejar.cpp:663 rc.cpp:27 +msgid "Allow" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:57 +#. i18n: ectx: property (text), widget (QPushButton, blockButton) +#: cookiejar.cpp:674 rc.cpp:21 +msgid "Block" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:67 +#. i18n: ectx: property (text), widget (QPushButton, allowForSessionButton) +#: cookiejar.cpp:685 rc.cpp:24 +msgid "Allow For Session" +msgstr "" + +#: download.cpp:73 +msgid "" +"Download '%1'?\n" +"Type: %2" +msgstr "" + +#: download.cpp:74 +msgid "Download '%1'..." +msgstr "" + +#: findbar.cpp:39 +msgid "&Match case" +msgstr "" + +#: findbar.cpp:55 +msgid "Find: " +msgstr "" + +#: findbar.cpp:65 +msgid "&Next" +msgstr "" + +#: findbar.cpp:66 +msgid "&Previous" +msgstr "" + +#: history.cpp:445 +msgid "Title" +msgstr "" + +#: history.cpp:446 +msgid "Address" +msgstr "" + +#: history.cpp:703 +msgid "Show All History" +msgstr "" + +#: history.cpp:707 +msgid "Clear History" +msgstr "" + +#: history.cpp:788 +msgid "Open" +msgstr "" + +#: history.cpp:790 +msgid "Copy" +msgstr "" + +#: history.cpp:792 +msgid "Delete" +msgstr "" + +#: history.cpp:1175 +msgid "Earlier Today" +msgstr "" + +#: history.cpp:1180 +msgid "1 item" +msgid_plural "%1 items" +msgstr[0] "" +msgstr[1] "" + +#: main.cpp:29 +msgid "KDE Browser Webkit Based" +msgstr "" + +#: main.cpp:39 +msgid "rekonq" +msgstr "" + +#: main.cpp:43 +msgid "(C) 2008-2009 Andrea Diamantini" +msgstr "" + +#: main.cpp:50 +msgid "Andrea Diamantini" +msgstr "" + +#: main.cpp:51 +msgid "Project Lead, Developer, Italian translations" +msgstr "" + +#: main.cpp:55 +msgid "Domrachev Alexandr" +msgstr "" + +#: main.cpp:56 +msgid "Developer, Russian translations" +msgstr "" + +#: main.cpp:60 +msgid "Pawel Prazak" +msgstr "" + +#: main.cpp:61 +msgid "Developer" +msgstr "" + +#: main.cpp:65 +msgid "Panagiotis Papadopoulos" +msgstr "" + +#: main.cpp:66 +msgid "German translations" +msgstr "" + +#: main.cpp:82 +msgid "Location to open" +msgstr "" + +#: mainview.cpp:98 +msgid "Recently Closed Tabs" +msgstr "" + +#: mainview.cpp:339 mainview.cpp:583 +msgid "(Untitled)" +msgstr "" + +#: mainview.cpp:455 +msgid "" +"You have modified this page and when closing it you would lose the " +"modification.\n" +"Do you really want to close this page?\n" +msgstr "" + +#: mainview.cpp:457 +msgid "Do you really want to close this page?" +msgstr "" + +#: mainview.cpp:514 +msgid "Loading..." +msgstr "" + +#: mainview.cpp:529 +msgid "Loading %1% (%2 %3)..." +msgstr "" + +#: mainview.cpp:556 +msgid "Done" +msgstr "" + +#: mainview.cpp:558 +msgid "Failed to load" +msgstr "" + +#: mainwindow.cpp:177 +msgid "Location Bar" +msgstr "" + +#: mainwindow.cpp:183 +msgid "Search Bar" +msgstr "" + +#: mainwindow.cpp:215 mainwindow.cpp:230 mainwindow.cpp:809 +msgid "Reload" +msgstr "" + +#: mainwindow.cpp:224 +msgid "&Stop" +msgstr "" + +#: mainwindow.cpp:235 +msgid "Open Location" +msgstr "" + +#: mainwindow.cpp:240 +msgid "&Enlarge Font" +msgstr "" + +#: mainwindow.cpp:245 +msgid "&Normal Font" +msgstr "" + +#: mainwindow.cpp:250 +msgid "&Shrink Font" +msgstr "" + +#: mainwindow.cpp:255 +msgid "Page S&ource" +msgstr "" + +#: mainwindow.cpp:260 +msgid "Web &Inspector" +msgstr "" + +#: mainwindow.cpp:265 +msgid "Private &Browsing" +msgstr "" + +#: mainwindow.cpp:271 +msgid "Back" +msgstr "" + +#: mainwindow.cpp:279 +msgid "Forward" +msgstr "" + +#: mainwindow.cpp:284 +msgid "New &Tab" +msgstr "" + +#: mainwindow.cpp:292 tabbar.cpp:110 +msgid "&Close Tab" +msgstr "" + +#: mainwindow.cpp:297 +msgid "Show Next Tab" +msgstr "" + +#: mainwindow.cpp:302 +msgid "Show Previous Tab" +msgstr "" + +#. i18n: file: history.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, HistoryDialog) +#. i18n: file: settings_privacy.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: mainwindow.cpp:312 mainwindow.cpp:320 rc.cpp:39 rc.cpp:156 +msgid "History" +msgstr "" + +#: mainwindow.cpp:336 +msgid "&History" +msgstr "" + +#: mainwindow.cpp:523 +msgid "Web Resources (*.html *.htm *.svg *.png *.gif *.svgz); All files (*.*)" +msgstr "" + +#: mainwindow.cpp:525 +msgid "Open Web Resource" +msgstr "" + +#: mainwindow.cpp:571 +msgid "Are you sure you want to turn on private browsing?" +msgstr "" + +#: mainwindow.cpp:572 +msgid "" +"

When private browsing in turned on, webpages are not added to " +"the history, new cookies are not stored, current cookies cannot be accessed, " +"site icons will not be stored, session will not 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." +msgstr "" + +#: mainwindow.cpp:632 mainwindow.cpp:654 +msgid " not found." +msgstr "" + +#: mainwindow.cpp:766 +msgid "" +"The web inspector will only work correctly for pages that were loaded after " +"enabling.\n" +"Do you want to reload all pages?" +msgstr "" + +#: mainwindow.cpp:768 +msgid "Web Inspector" +msgstr "" + +#: mainwindow.cpp:800 +msgid "Stop loading the current page" +msgstr "" + +#: mainwindow.cpp:801 +msgid "Stop" +msgstr "" + +#: mainwindow.cpp:808 +msgid "Reload the current page" +msgstr "" + +#: mainwindow.cpp:892 +msgid "" +"Are you sure you want to close the window?\n" +"You have 1 tap open" +msgid_plural "" +"Are you sure you want to close the window?\n" +"You have %1 tabs open" +msgstr[0] "" +msgstr[1] "" + +#: mainwindow.cpp:893 +msgid "Are you sure you want to close the window?" +msgstr "" + +#: mainwindow.cpp:895 +msgid "C&lose Current Tab" +msgstr "" + +#: networkaccessmanager.cpp:112 +msgid "Enter username and password for " +msgstr "" + +#: networkaccessmanager.cpp:113 +msgid " at " +msgstr "" + +#: networkaccessmanager.cpp:140 +msgid "Connect to proxy " +msgstr "" + +#: networkaccessmanager.cpp:140 +msgid " using:" +msgstr "" + +#: networkaccessmanager.cpp:160 +msgid "" +"SSL Errors:\n" +"\n" +msgstr "" + +#: panelhistory.cpp:50 +msgid "Search: " +msgstr "" + +#: searchbar.cpp:55 +msgid "Search.." +msgstr "" + +#. i18n: file: settings_general.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, general) +#: settings.cpp:81 rc.cpp:126 +msgid "General" +msgstr "" + +#. i18n: file: settings_fonts.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: settings.cpp:87 rc.cpp:111 +msgid "Fonts" +msgstr "" + +#. i18n: file: settings_privacy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, privacy) +#: settings.cpp:93 rc.cpp:153 +msgid "Privacy" +msgstr "" + +#. i18n: file: settings_proxy.ui:13 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxy) +#: settings.cpp:99 rc.cpp:213 +msgid "Proxy" +msgstr "" + +#: settings.cpp:105 +msgid "Webkit" +msgstr "" + +#: settings.cpp:121 +msgid "rekonfig.." +msgstr "" + +#: settings.cpp:143 +msgid "Specifies whether images are automatically loaded in web pages" +msgstr "" + +#: settings.cpp:144 +msgid "Enables the running of JavaScript programs." +msgstr "" + +#: settings.cpp:145 +msgid "Enables Java applets." +msgstr "" + +#: settings.cpp:146 +msgid "Enables plugins in web pages." +msgstr "" + +#: settings.cpp:147 +msgid "Allows JavaScript programs to opening new windows." +msgstr "" + +#: settings.cpp:148 +msgid "Allows JavaScript programs to reading/writing to the clipboard." +msgstr "" + +#: settings.cpp:149 +msgid "Includes hyperlinks in the keyboard focus chain." +msgstr "" + +#: settings.cpp:150 +msgid "Applies the zoom factor on a frame to only the text or all content." +msgstr "" + +#: settings.cpp:151 +msgid "Draws also background color and images when the page is printed." +msgstr "" + +#: settings.cpp:152 +msgid "Support for the HTML 5 offline storage feature." +msgstr "" + +#: settings.cpp:153 +msgid "Support for the HTML 5 web application cache feature." +msgstr "" + +#: settings.cpp:154 +msgid "Support for the HTML 5 local storage feature." +msgstr "" + +#: tabbar.cpp:108 +msgid "Clone Tab" +msgstr "" + +#: tabbar.cpp:111 +msgid "Close &Other Tabs" +msgstr "" + +#: tabbar.cpp:113 +msgid "Reload Tab" +msgstr "" + +#: tabbar.cpp:119 +msgid "Reload All Tabs" +msgstr "" + +#: webview.cpp:245 +msgid "Error loading page: " +msgstr "" + +#: webview.cpp:309 +msgid "Open Link in New &Tab" +msgstr "" + +#: webview.cpp:315 +msgid "Cu&t" +msgstr "" + +#: webview.cpp:320 +msgid "&Copy" +msgstr "" + +#: webview.cpp:325 +msgid "&Paste" +msgstr "" + +#: webview.cpp:330 +msgid "&Save Image As..." +msgstr "" + +#: webview.cpp:335 +msgid "&Copy This Image" +msgstr "" + +#: webview.cpp:340 +msgid "&Save Link As..." +msgstr "" + +#: webview.cpp:345 +msgid "&Copy Link Location" +msgstr "" + +#: webview.cpp:350 +msgid "&Inspect Element" +msgstr "" + +#: webview.cpp:364 +msgid "Bookmark This Page" +msgstr "" + +#: webview.cpp:417 +msgid "&Bookmark This Link" +msgstr "" + +#. i18n: file: cookies.ui:14 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesDialog) +#. i18n: file: settings_privacy.ui:73 +#. i18n: ectx: property (title), widget (QGroupBox, cookiesGroupBox) +#: rc.cpp:3 rc.cpp:180 +msgid "Cookies" +msgstr "" + +#. i18n: file: cookies.ui:41 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: cookiesexceptions.ui:114 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: history.ui:40 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#: rc.cpp:6 rc.cpp:33 rc.cpp:42 +msgid "&Remove" +msgstr "" + +#. i18n: file: cookies.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:9 +msgid "Remove &All Cookies" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesExceptionsDialog) +#: rc.cpp:12 +msgid "Cookie Exceptions" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:19 +#. i18n: ectx: property (title), widget (QGroupBox, newExceptionGroupBox) +#: rc.cpp:15 +msgid "New Exception" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:27 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:18 +msgid "Domain:" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:89 +#. i18n: ectx: property (title), widget (QGroupBox, ExceptionsGroupBox) +#: rc.cpp:30 +msgid "Exceptions" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:121 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#. i18n: file: history.ui:47 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:36 rc.cpp:45 +msgid "Remove &All" +msgstr "" + +#. i18n: file: password.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, passwordWidget) +#. i18n: file: proxy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxyWidget) +#. i18n: file: settings_webkit.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, webkit) +#: rc.cpp:48 rc.cpp:63 rc.cpp:243 +msgid "Form" +msgstr "" + +#. i18n: file: password.ui:22 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:51 +msgid "DUMMY ICON" +msgstr "" + +#. i18n: file: password.ui:35 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:54 +msgid "INTRO TEXT DUMMY" +msgstr "" + +#. i18n: file: password.ui:44 +#. i18n: ectx: property (text), widget (QLabel, label) +#. i18n: file: proxy.ui:37 +#. i18n: ectx: property (text), widget (QLabel, usernameLabel) +#. i18n: file: settings_proxy.ui:102 +#. i18n: ectx: property (text), widget (QLabel, label_12) +#: rc.cpp:57 rc.cpp:72 rc.cpp:237 +msgid "Username:" +msgstr "" + +#. i18n: file: password.ui:54 +#. i18n: ectx: property (text), widget (QLabel, lblPassword) +#. i18n: file: proxy.ui:47 +#. i18n: ectx: property (text), widget (QLabel, passwordLabel) +#. i18n: file: settings_proxy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label_13) +#: rc.cpp:60 rc.cpp:75 rc.cpp:240 +msgid "Password:" +msgstr "" + +#. i18n: file: proxy.ui:20 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:66 +msgid "ICON" +msgstr "" + +#. i18n: file: proxy.ui:27 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:69 +msgid "Connect to proxy" +msgstr "" + +#. i18n: file: rekonqui.rc:8 +#. i18n: ectx: Menu (file) +#: rc.cpp:78 +msgid "&File" +msgstr "" + +#. i18n: file: rekonqui.rc:24 +#. i18n: ectx: Menu (edit) +#: rc.cpp:81 +msgid "&Edit" +msgstr "" + +#. i18n: file: rekonqui.rc:38 +#. i18n: ectx: Menu (view) +#: rc.cpp:84 +msgid "&View" +msgstr "" + +#. i18n: file: rekonqui.rc:54 +#. i18n: ectx: Menu (go) +#: rc.cpp:87 +msgid "Hi&story" +msgstr "" + +#. i18n: file: rekonqui.rc:62 +#. i18n: ectx: Menu (tools) +#: rc.cpp:93 +msgid "&Tools" +msgstr "" + +#. i18n: file: rekonqui.rc:68 +#. i18n: ectx: Menu (settings) +#: rc.cpp:96 +msgid "&Settings" +msgstr "" + +#. i18n: file: rekonqui.rc:73 +#. i18n: ectx: Menu (side_panels) +#: rc.cpp:99 +msgid "Side &Panels" +msgstr "" + +#. i18n: file: rekonqui.rc:88 +#. i18n: ectx: ToolBar (mainToolBar) +#: rc.cpp:102 +msgid "Main Toolbar" +msgstr "" + +#. i18n: file: rekonqui.rc:100 +#. i18n: ectx: ToolBar (bookmarksToolBar) +#: rc.cpp:105 +msgid "Bookmark Toolbar" +msgstr "" + +#. i18n: file: settings_fonts.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, fonts) +#: rc.cpp:108 +msgid "Appearance" +msgstr "" + +#. i18n: file: settings_fonts.ui:28 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:114 +msgid "Standard Font" +msgstr "" + +#. i18n: file: settings_fonts.ui:35 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:117 +msgid "Fixed Font" +msgstr "" + +#. i18n: file: settings_fonts.ui:53 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: rc.cpp:120 +msgid "Dimension" +msgstr "" + +#. i18n: file: settings_fonts.ui:61 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:123 +msgid "Font Size" +msgstr "" + +#. i18n: file: settings_general.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:129 +msgid "Places" +msgstr "" + +#. i18n: file: settings_general.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:132 +msgid "Home Page:" +msgstr "" + +#. i18n: file: settings_general.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, setHomeToCurrentPageButton) +#: rc.cpp:135 +msgid "Set to current page" +msgstr "" + +#. i18n: file: settings_general.ui:73 +#. i18n: ectx: property (text), widget (QLabel, label_7) +#: rc.cpp:138 +msgid "Save downloads to:" +msgstr "" + +#. i18n: file: settings_general.ui:83 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_downloadToDefaultDir) +#: rc.cpp:141 +msgid "ask where saving downloads" +msgstr "" + +#. i18n: file: settings_general.ui:93 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: rc.cpp:144 +msgid "Tabbed Browsing" +msgstr "" + +#. i18n: file: settings_general.ui:99 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_alwaysShowTabBar) +#: rc.cpp:147 +msgid "Always show tab bar" +msgstr "" + +#. i18n: file: settings_general.ui:106 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_openTabsBack) +#: rc.cpp:150 +msgid "Open tabs in the background" +msgstr "" + +#. i18n: file: settings_privacy.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_4) +#: rc.cpp:159 +msgid "Remove history items:" +msgstr "" + +#. i18n: file: settings_privacy.ui:37 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:162 +msgid "After one day" +msgstr "" + +#. i18n: file: settings_privacy.ui:42 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:165 +msgid "After one week" +msgstr "" + +#. i18n: file: settings_privacy.ui:47 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:168 +msgid "After two weeks" +msgstr "" + +#. i18n: file: settings_privacy.ui:52 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:171 +msgid "After one month" +msgstr "" + +#. i18n: file: settings_privacy.ui:57 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:174 +msgid "After one year" +msgstr "" + +#. i18n: file: settings_privacy.ui:62 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:177 +msgid "Manually" +msgstr "" + +#. i18n: file: settings_privacy.ui:79 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:183 +msgid "Accept Cookies:" +msgstr "" + +#. i18n: file: settings_privacy.ui:90 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:186 +msgid "Always" +msgstr "" + +#. i18n: file: settings_privacy.ui:95 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:189 +msgid "Never" +msgstr "" + +#. i18n: file: settings_privacy.ui:100 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:192 +msgid "Only from sites you visit" +msgstr "" + +#. i18n: file: settings_privacy.ui:108 +#. i18n: ectx: property (text), widget (QPushButton, exceptionsButton) +#: rc.cpp:195 +msgid "Exceptions..." +msgstr "" + +#. i18n: file: settings_privacy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:198 +msgid "Keep until:" +msgstr "" + +#. i18n: file: settings_privacy.ui:126 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:201 +msgid "They expire" +msgstr "" + +#. i18n: file: settings_privacy.ui:131 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:204 +msgid "I exit the application" +msgstr "" + +#. i18n: file: settings_privacy.ui:136 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:207 +msgid "At most 90 days" +msgstr "" + +#. i18n: file: settings_privacy.ui:144 +#. i18n: ectx: property (text), widget (QPushButton, cookiesButton) +#: rc.cpp:210 +msgid "Cookies..." +msgstr "" + +#. i18n: file: settings_proxy.ui:19 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_isProxyEnabled) +#: rc.cpp:216 +msgid "Enable proxy" +msgstr "" + +#. i18n: file: settings_proxy.ui:26 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:219 +msgid "Proxy Settings" +msgstr "" + +#. i18n: file: settings_proxy.ui:32 +#. i18n: ectx: property (text), widget (QLabel, label_9) +#: rc.cpp:222 +msgid "Type:" +msgstr "" + +#. i18n: file: settings_proxy.ui:43 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:225 +msgid "SOCKS 5" +msgstr "" + +#. i18n: file: settings_proxy.ui:48 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:228 +msgid "HTTP" +msgstr "" + +#. i18n: file: settings_proxy.ui:56 +#. i18n: ectx: property (text), widget (QLabel, label_10) +#: rc.cpp:231 +msgid "Host:" +msgstr "" + +#. i18n: file: settings_proxy.ui:69 +#. i18n: ectx: property (text), widget (QLabel, label_11) +#: rc.cpp:234 +msgid "Port:" +msgstr "" + +#. i18n: file: settings_webkit.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:246 +msgid "WebKit Settings" +msgstr "" + +#. i18n: file: settings_webkit.ui:26 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_autoLoadImages) +#: rc.cpp:249 +msgid "Auto Load Images" +msgstr "" + +#. i18n: file: settings_webkit.ui:40 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_linksIncludedInFocusChain) +#: rc.cpp:252 +msgid "Links included in focus chain" +msgstr "" + +#. i18n: file: settings_webkit.ui:47 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptEnabled) +#: rc.cpp:255 +msgid "Javascript support" +msgstr "" + +#. i18n: file: settings_webkit.ui:54 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_zoomTextOnly) +#: rc.cpp:258 +msgid "Zoom Text Only" +msgstr "" + +#. i18n: file: settings_webkit.ui:61 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javaEnabled) +#: rc.cpp:261 +msgid "Java support" +msgstr "" + +#. i18n: file: settings_webkit.ui:68 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_printElementBackgrounds) +#: rc.cpp:264 +msgid "Print element Backgrounds" +msgstr "" + +#. i18n: file: settings_webkit.ui:75 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_pluginsEnabled) +#: rc.cpp:267 +msgid "Plugins" +msgstr "" + +#. i18n: file: settings_webkit.ui:82 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineStorageDatabaseEnabled) +#: rc.cpp:270 +msgid "Offline storage Database" +msgstr "" + +#. i18n: file: settings_webkit.ui:89 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanOpenWindows) +#: rc.cpp:273 +msgid "Javascript can open windows" +msgstr "" + +#. i18n: file: settings_webkit.ui:96 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineWebApplicationCacheEnabled) +#: rc.cpp:276 +msgid "Offline Web Application Cache " +msgstr "" + +#. i18n: file: settings_webkit.ui:103 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanAccessClipboard) +#: rc.cpp:279 +msgid "Javascript can access clipboard" +msgstr "" + +#. i18n: file: settings_webkit.ui:110 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_localStorageDatabaseEnabled) +#: rc.cpp:282 +msgid "Local storage database" +msgstr "" diff --git a/po/rekonq_de.po b/po/rekonq_de.po new file mode 100644 index 00000000..f5bb5bab --- /dev/null +++ b/po/rekonq_de.po @@ -0,0 +1,1099 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the rekonq package. +# FIRST AUTHOR Panagiotis Papadopoulos , 2009. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: http://sourceforge.net/tracker/?" +"group_id=252277&atid=1126949\n" +"POT-Creation-Date: 2009-05-02 02:35+0200\n" +"PO-Revision-Date: 2009-04-17 23:12+0200\n" +"Last-Translator: Panagiotis Papadopoulos \n" +"Language-Team: German \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: de_DE\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. i18n: file: rekonqui.rc:58 +#. i18n: ectx: Menu (go) +#: bookmarks.cpp:265 rc.cpp:90 +msgid "&Bookmarks" +msgstr "&Lesezeichen" + +#: bookmarks.cpp:274 +msgid "Bookmarks Bar" +msgstr "Lesezeichenleiste" + +#: cookiejar.cpp:457 cookiejar.cpp:636 +msgid "Website" +msgstr "Webseite" + +#: cookiejar.cpp:459 +msgid "Name" +msgstr "Name" + +#: cookiejar.cpp:461 +msgid "Path" +msgstr "Pfad" + +#: cookiejar.cpp:463 +msgid "Secure" +msgstr "Sicher" + +#: cookiejar.cpp:465 +msgid "Expires" +msgstr "Läuft ab am" + +#: cookiejar.cpp:467 +msgid "Contents" +msgstr "Inhalt" + +#: cookiejar.cpp:638 +msgid "Status" +msgstr "Status" + +#. i18n: file: cookiesexceptions.ui:77 +#. i18n: ectx: property (text), widget (QPushButton, allowButton) +#: cookiejar.cpp:663 rc.cpp:27 +msgid "Allow" +msgstr "Annehmen" + +#. i18n: file: cookiesexceptions.ui:57 +#. i18n: ectx: property (text), widget (QPushButton, blockButton) +#: cookiejar.cpp:674 rc.cpp:21 +msgid "Block" +msgstr "Zurückweisen" + +#. i18n: file: cookiesexceptions.ui:67 +#. i18n: ectx: property (text), widget (QPushButton, allowForSessionButton) +#: cookiejar.cpp:685 rc.cpp:24 +msgid "Allow For Session" +msgstr "Für Sitzung annehmen" + +#: download.cpp:73 +msgid "" +"Download '%1'?\n" +"Type: %2" +msgstr "" + +#: download.cpp:74 +#, fuzzy +msgid "Download '%1'..." +msgstr "Download '%1'..." + +#: findbar.cpp:39 +msgid "&Match case" +msgstr "Groß-/Kleinschreibung beachten" + +#: findbar.cpp:55 +msgid "Find: " +msgstr "Suchen:" + +#: findbar.cpp:65 +msgid "&Next" +msgstr "Weiter" + +#: findbar.cpp:66 +msgid "&Previous" +msgstr "Zurück" + +#: history.cpp:445 +msgid "Title" +msgstr "Name" + +#: history.cpp:446 +msgid "Address" +msgstr "Adresse" + +#: history.cpp:703 +msgid "Show All History" +msgstr "Gesamten Verlauf anzeigen" + +#: history.cpp:707 +msgid "Clear History" +msgstr "Verlauf löschen" + +#: history.cpp:788 +msgid "Open" +msgstr "Öffnen" + +#: history.cpp:790 +msgid "Copy" +msgstr "Kopieren" + +#: history.cpp:792 +msgid "Delete" +msgstr "Löschen" + +#: history.cpp:1175 +msgid "Earlier Today" +msgstr "" + +#: history.cpp:1180 +msgid "1 item" +msgid_plural "%1 items" +msgstr[0] "" +msgstr[1] "" + +#: main.cpp:29 +msgid "KDE Browser Webkit Based" +msgstr "" + +#: main.cpp:39 +msgid "rekonq" +msgstr "rekonq" + +#: main.cpp:43 +#, fuzzy +msgid "(C) 2008-2009 Andrea Diamantini" +msgstr "(C) 2008 Andrea Diamantini" + +#: main.cpp:50 +msgid "Andrea Diamantini" +msgstr "Andrea Diamantini" + +#: main.cpp:51 +msgid "Project Lead, Developer, Italian translations" +msgstr "" + +#: main.cpp:55 +msgid "Domrachev Alexandr" +msgstr "Domrachev Alexandr" + +#: main.cpp:56 +msgid "Developer, Russian translations" +msgstr "" + +#: main.cpp:60 +#, fuzzy +msgid "Pawel Prazak" +msgstr "Paweł Prażak" + +#: main.cpp:61 +msgid "Developer" +msgstr "" + +#: main.cpp:65 +msgid "Panagiotis Papadopoulos" +msgstr "" + +#: main.cpp:66 +msgid "German translations" +msgstr "" + +#: main.cpp:82 +msgid "Location to open" +msgstr "" + +#: mainview.cpp:98 +msgid "Recently Closed Tabs" +msgstr "Geschlossene Unterfenster" + +#: mainview.cpp:339 mainview.cpp:583 +msgid "(Untitled)" +msgstr "(Unbennant)" + +#: mainview.cpp:455 +msgid "" +"You have modified this page and when closing it you would lose the " +"modification.\n" +"Do you really want to close this page?\n" +msgstr "" + +#: mainview.cpp:457 +msgid "Do you really want to close this page?" +msgstr "" + +#: mainview.cpp:514 +msgid "Loading..." +msgstr "Lade ..." + +#: mainview.cpp:529 +msgid "Loading %1% (%2 %3)..." +msgstr "Lade %1% (%2 %3) ..." + +#: mainview.cpp:556 +msgid "Done" +msgstr "" + +#: mainview.cpp:558 +msgid "Failed to load" +msgstr "Laden fehlgeschlagen" + +#: mainwindow.cpp:177 +msgid "Location Bar" +msgstr "Adressleiste" + +#: mainwindow.cpp:183 +msgid "Search Bar" +msgstr "Suchleiste" + +#: mainwindow.cpp:215 mainwindow.cpp:230 mainwindow.cpp:809 +#, fuzzy +msgid "Reload" +msgstr "Unterfenster neu laden" + +#: mainwindow.cpp:224 +msgid "&Stop" +msgstr "&Stopp" + +#: mainwindow.cpp:235 +msgid "Open Location" +msgstr "Adresse aufrufen" + +#: mainwindow.cpp:240 +msgid "&Enlarge Font" +msgstr "Schrift vergrößern" + +#: mainwindow.cpp:245 +msgid "&Normal Font" +msgstr "" + +#: mainwindow.cpp:250 +msgid "&Shrink Font" +msgstr "Schrift verkleinern" + +#: mainwindow.cpp:255 +msgid "Page S&ource" +msgstr "Seitenquelltext" + +#: mainwindow.cpp:260 +msgid "Web &Inspector" +msgstr "" + +#: mainwindow.cpp:265 +msgid "Private &Browsing" +msgstr "" + +#: mainwindow.cpp:271 +msgid "Back" +msgstr "Zurück" + +#: mainwindow.cpp:279 +msgid "Forward" +msgstr "Nach Vorne" + +#: mainwindow.cpp:284 +msgid "New &Tab" +msgstr "Neues Unterfenster" + +#: mainwindow.cpp:292 tabbar.cpp:110 +msgid "&Close Tab" +msgstr "Unterfenster schließen" + +#: mainwindow.cpp:297 +msgid "Show Next Tab" +msgstr "Nächstes Unterfenster aktivieren" + +#: mainwindow.cpp:302 +msgid "Show Previous Tab" +msgstr "Vorheriges Unterfenster aktivieren" + +#. i18n: file: history.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, HistoryDialog) +#. i18n: file: settings_privacy.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: mainwindow.cpp:312 mainwindow.cpp:320 rc.cpp:39 rc.cpp:156 +msgid "History" +msgstr "Verlauf" + +#: mainwindow.cpp:336 +msgid "&History" +msgstr "&Verlauf" + +#: mainwindow.cpp:523 +#, fuzzy +msgid "Web Resources (*.html *.htm *.svg *.png *.gif *.svgz); All files (*.*)" +msgstr "Webinhalte (*.html *.htm *.svg *.png *.gif *.svgz); Alle Dateien(*.*)" + +#: mainwindow.cpp:525 +msgid "Open Web Resource" +msgstr "Webinhalt öffnen" + +#: mainwindow.cpp:571 +msgid "Are you sure you want to turn on private browsing?" +msgstr "" + +#: mainwindow.cpp:572 +msgid "" +"

When private browsing in turned on, webpages are not added to " +"the history, new cookies are not stored, current cookies cannot be accessed, " +"site icons will not be stored, session will not 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." +msgstr "" + +#: mainwindow.cpp:632 mainwindow.cpp:654 +msgid " not found." +msgstr "" + +#: mainwindow.cpp:766 +msgid "" +"The web inspector will only work correctly for pages that were loaded after " +"enabling.\n" +"Do you want to reload all pages?" +msgstr "" + +#: mainwindow.cpp:768 +msgid "Web Inspector" +msgstr "" + +#: mainwindow.cpp:800 +msgid "Stop loading the current page" +msgstr "" + +#: mainwindow.cpp:801 +msgid "Stop" +msgstr "Stopp" + +#: mainwindow.cpp:808 +msgid "Reload the current page" +msgstr "Aktuelle Webseite neu laden" + +#: mainwindow.cpp:892 +#, fuzzy +msgid "" +"Are you sure you want to close the window?\n" +"You have 1 tap open" +msgid_plural "" +"Are you sure you want to close the window?\n" +"You have %1 tabs open" +msgstr[0] "" +"Sind Sie sicher, dass Sie das Fenster schließen wollen?\n" +"Es sind %1 Unterfenster geöffnet" +msgstr[1] "" +"Sind Sie sicher, dass Sie das Fenster schließen wollen?\n" +"Es sind %1 Unterfenster geöffnet" + +#: mainwindow.cpp:893 +msgid "Are you sure you want to close the window?" +msgstr "Sind Sie sicher, dass Sie das Fenster schließen wollen?" + +#: mainwindow.cpp:895 +#, fuzzy +msgid "C&lose Current Tab" +msgstr "Unterfenster schließen" + +#: networkaccessmanager.cpp:112 +#, fuzzy +msgid "Enter username and password for " +msgstr "Geben Sie Ihren Benutzernamen und Ihr Passwort ein für " + +#: networkaccessmanager.cpp:113 +msgid " at " +msgstr "" + +#: networkaccessmanager.cpp:140 +#, fuzzy +msgid "Connect to proxy " +msgstr "Zu Proxy verbinden " + +#: networkaccessmanager.cpp:140 +msgid " using:" +msgstr "" + +#: networkaccessmanager.cpp:160 +msgid "" +"SSL Errors:\n" +"\n" +msgstr "" +"SSL-Fehler:\n" +"\n" + +#: panelhistory.cpp:50 +msgid "Search: " +msgstr "Suchen:" + +#: searchbar.cpp:55 +#, fuzzy +msgid "Search.." +msgstr "Suchen ..." + +#. i18n: file: settings_general.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, general) +#: settings.cpp:81 rc.cpp:126 +msgid "General" +msgstr "Allgemein" + +#. i18n: file: settings_fonts.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: settings.cpp:87 rc.cpp:111 +msgid "Fonts" +msgstr "Schriftarten" + +#. i18n: file: settings_privacy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, privacy) +#: settings.cpp:93 rc.cpp:153 +#, fuzzy +msgid "Privacy" +msgstr "Privatsphäre" + +#. i18n: file: settings_proxy.ui:13 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxy) +#: settings.cpp:99 rc.cpp:213 +msgid "Proxy" +msgstr "Proxy" + +#: settings.cpp:105 +#, fuzzy +msgid "Webkit" +msgstr "Webseite" + +#: settings.cpp:121 +#, fuzzy +msgid "rekonfig.." +msgstr "rekonq" + +#: settings.cpp:143 +msgid "Specifies whether images are automatically loaded in web pages" +msgstr "" + +#: settings.cpp:144 +msgid "Enables the running of JavaScript programs." +msgstr "" + +#: settings.cpp:145 +#, fuzzy +msgid "Enables Java applets." +msgstr "Javascript aktivieren" + +#: settings.cpp:146 +#, fuzzy +msgid "Enables plugins in web pages." +msgstr "Plugins aktivieren" + +#: settings.cpp:147 +msgid "Allows JavaScript programs to opening new windows." +msgstr "" + +#: settings.cpp:148 +msgid "Allows JavaScript programs to reading/writing to the clipboard." +msgstr "" + +#: settings.cpp:149 +msgid "Includes hyperlinks in the keyboard focus chain." +msgstr "" + +#: settings.cpp:150 +msgid "Applies the zoom factor on a frame to only the text or all content." +msgstr "" + +#: settings.cpp:151 +msgid "Draws also background color and images when the page is printed." +msgstr "" + +#: settings.cpp:152 +msgid "Support for the HTML 5 offline storage feature." +msgstr "" + +#: settings.cpp:153 +msgid "Support for the HTML 5 web application cache feature." +msgstr "" + +#: settings.cpp:154 +msgid "Support for the HTML 5 local storage feature." +msgstr "" + +#: tabbar.cpp:108 +msgid "Clone Tab" +msgstr "Unterfenster duplizieren" + +#: tabbar.cpp:111 +msgid "Close &Other Tabs" +msgstr "Andere Unterfenster schließen" + +#: tabbar.cpp:113 +msgid "Reload Tab" +msgstr "Unterfenster neu laden" + +#: tabbar.cpp:119 +msgid "Reload All Tabs" +msgstr "Alle Unterfenster neu laden" + +#: webview.cpp:245 +msgid "Error loading page: " +msgstr "" + +#: webview.cpp:309 +msgid "Open Link in New &Tab" +msgstr "In neuem Unterfenster öffnen" + +#: webview.cpp:315 +msgid "Cu&t" +msgstr "Ausschneiden" + +#: webview.cpp:320 +msgid "&Copy" +msgstr "&Kopieren" + +#: webview.cpp:325 +msgid "&Paste" +msgstr "&Einfügen" + +#: webview.cpp:330 +msgid "&Save Image As..." +msgstr "Bild speichern unter ..." + +#: webview.cpp:335 +msgid "&Copy This Image" +msgstr "Bild kopieren" + +#: webview.cpp:340 +msgid "&Save Link As..." +msgstr "Verknüpfung speichern unter ..." + +#: webview.cpp:345 +msgid "&Copy Link Location" +msgstr "Verknüpfungsaddresse kopieren" + +#: webview.cpp:350 +msgid "&Inspect Element" +msgstr "" + +#: webview.cpp:364 +msgid "Bookmark This Page" +msgstr "Lesezeichen für diese Seite" + +#: webview.cpp:417 +msgid "&Bookmark This Link" +msgstr "Lesezeichen für diese Verknüpfung" + +#. i18n: file: cookies.ui:14 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesDialog) +#. i18n: file: settings_privacy.ui:73 +#. i18n: ectx: property (title), widget (QGroupBox, cookiesGroupBox) +#: rc.cpp:3 rc.cpp:180 +msgid "Cookies" +msgstr "Cookies" + +#. i18n: file: cookies.ui:41 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: cookiesexceptions.ui:114 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: history.ui:40 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#: rc.cpp:6 rc.cpp:33 rc.cpp:42 +msgid "&Remove" +msgstr "Entfernen" + +#. i18n: file: cookies.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:9 +msgid "Remove &All Cookies" +msgstr "Alle Cookies entfernen" + +#. i18n: file: cookiesexceptions.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesExceptionsDialog) +#: rc.cpp:12 +msgid "Cookie Exceptions" +msgstr "Cookie-Ausnahmen" + +#. i18n: file: cookiesexceptions.ui:19 +#. i18n: ectx: property (title), widget (QGroupBox, newExceptionGroupBox) +#: rc.cpp:15 +msgid "New Exception" +msgstr "Neue Ausnahme" + +#. i18n: file: cookiesexceptions.ui:27 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:18 +#, fuzzy +msgid "Domain:" +msgstr "Domain:" + +#. i18n: file: cookiesexceptions.ui:89 +#. i18n: ectx: property (title), widget (QGroupBox, ExceptionsGroupBox) +#: rc.cpp:30 +msgid "Exceptions" +msgstr "Ausnahmen" + +#. i18n: file: cookiesexceptions.ui:121 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#. i18n: file: history.ui:47 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:36 rc.cpp:45 +msgid "Remove &All" +msgstr "&Alle Entfernen" + +#. i18n: file: password.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, passwordWidget) +#. i18n: file: proxy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxyWidget) +#. i18n: file: settings_webkit.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, webkit) +#: rc.cpp:48 rc.cpp:63 rc.cpp:243 +msgid "Form" +msgstr "" + +#. i18n: file: password.ui:22 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:51 +msgid "DUMMY ICON" +msgstr "" + +#. i18n: file: password.ui:35 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:54 +msgid "INTRO TEXT DUMMY" +msgstr "" + +#. i18n: file: password.ui:44 +#. i18n: ectx: property (text), widget (QLabel, label) +#. i18n: file: proxy.ui:37 +#. i18n: ectx: property (text), widget (QLabel, usernameLabel) +#. i18n: file: settings_proxy.ui:102 +#. i18n: ectx: property (text), widget (QLabel, label_12) +#: rc.cpp:57 rc.cpp:72 rc.cpp:237 +msgid "Username:" +msgstr "Benutzername:" + +#. i18n: file: password.ui:54 +#. i18n: ectx: property (text), widget (QLabel, lblPassword) +#. i18n: file: proxy.ui:47 +#. i18n: ectx: property (text), widget (QLabel, passwordLabel) +#. i18n: file: settings_proxy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label_13) +#: rc.cpp:60 rc.cpp:75 rc.cpp:240 +msgid "Password:" +msgstr "Passwort:" + +#. i18n: file: proxy.ui:20 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:66 +msgid "ICON" +msgstr "" + +#. i18n: file: proxy.ui:27 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:69 +#, fuzzy +msgid "Connect to proxy" +msgstr "Zu Proxy verbinden" + +#. i18n: file: rekonqui.rc:8 +#. i18n: ectx: Menu (file) +#: rc.cpp:78 +msgid "&File" +msgstr "&Datei" + +#. i18n: file: rekonqui.rc:24 +#. i18n: ectx: Menu (edit) +#: rc.cpp:81 +msgid "&Edit" +msgstr "&Bearbeiten" + +#. i18n: file: rekonqui.rc:38 +#. i18n: ectx: Menu (view) +#: rc.cpp:84 +msgid "&View" +msgstr "&Ansicht" + +#. i18n: file: rekonqui.rc:54 +#. i18n: ectx: Menu (go) +#: rc.cpp:87 +msgid "Hi&story" +msgstr "Verlauf" + +#. i18n: file: rekonqui.rc:62 +#. i18n: ectx: Menu (tools) +#: rc.cpp:93 +msgid "&Tools" +msgstr "" + +#. i18n: file: rekonqui.rc:68 +#. i18n: ectx: Menu (settings) +#: rc.cpp:96 +msgid "&Settings" +msgstr "&Einstellungen" + +#. i18n: file: rekonqui.rc:73 +#. i18n: ectx: Menu (side_panels) +#: rc.cpp:99 +#, fuzzy +msgid "Side &Panels" +msgstr "Lesezeichen-Seitenleiste anzeigen" + +#. i18n: file: rekonqui.rc:88 +#. i18n: ectx: ToolBar (mainToolBar) +#: rc.cpp:102 +msgid "Main Toolbar" +msgstr "Haupt-Werkzeugsleiste" + +#. i18n: file: rekonqui.rc:100 +#. i18n: ectx: ToolBar (bookmarksToolBar) +#: rc.cpp:105 +msgid "Bookmark Toolbar" +msgstr "Lesezeichen-Werkzeugsleiste" + +#. i18n: file: settings_fonts.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, fonts) +#: rc.cpp:108 +#, fuzzy +msgid "Appearance" +msgstr "Erscheinungsbild" + +#. i18n: file: settings_fonts.ui:28 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:114 +msgid "Standard Font" +msgstr "Allgemein" + +#. i18n: file: settings_fonts.ui:35 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:117 +msgid "Fixed Font" +msgstr "Feste Breite" + +#. i18n: file: settings_fonts.ui:53 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: rc.cpp:120 +msgid "Dimension" +msgstr "" + +#. i18n: file: settings_fonts.ui:61 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:123 +msgid "Font Size" +msgstr "Schriftgröße" + +#. i18n: file: settings_general.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:129 +msgid "Places" +msgstr "Orte" + +#. i18n: file: settings_general.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:132 +#, fuzzy +msgid "Home Page:" +msgstr "Startseite:" + +#. i18n: file: settings_general.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, setHomeToCurrentPageButton) +#: rc.cpp:135 +msgid "Set to current page" +msgstr "" + +#. i18n: file: settings_general.ui:73 +#. i18n: ectx: property (text), widget (QLabel, label_7) +#: rc.cpp:138 +#, fuzzy +msgid "Save downloads to:" +msgstr "&Downloads speichern unter:" + +#. i18n: file: settings_general.ui:83 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_downloadToDefaultDir) +#: rc.cpp:141 +msgid "ask where saving downloads" +msgstr "" + +#. i18n: file: settings_general.ui:93 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: rc.cpp:144 +msgid "Tabbed Browsing" +msgstr "" + +#. i18n: file: settings_general.ui:99 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_alwaysShowTabBar) +#: rc.cpp:147 +#, fuzzy +msgid "Always show tab bar" +msgstr "Unterfensterleiste immer anzeigen" + +#. i18n: file: settings_general.ui:106 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_openTabsBack) +#: rc.cpp:150 +msgid "Open tabs in the background" +msgstr "" + +#. i18n: file: settings_privacy.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_4) +#: rc.cpp:159 +#, fuzzy +msgid "Remove history items:" +msgstr "Verlaufseinträge entfernen nach:" + +#. i18n: file: settings_privacy.ui:37 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:162 +#, fuzzy +msgid "After one day" +msgstr "Einem Tag" + +#. i18n: file: settings_privacy.ui:42 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:165 +#, fuzzy +msgid "After one week" +msgstr "Einer Woche" + +#. i18n: file: settings_privacy.ui:47 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:168 +#, fuzzy +msgid "After two weeks" +msgstr "Zwei Wochen" + +#. i18n: file: settings_privacy.ui:52 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:171 +#, fuzzy +msgid "After one month" +msgstr "Einem Monat" + +#. i18n: file: settings_privacy.ui:57 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:174 +#, fuzzy +msgid "After one year" +msgstr "Einem Jahr" + +#. i18n: file: settings_privacy.ui:62 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:177 +msgid "Manually" +msgstr "Manuell" + +#. i18n: file: settings_privacy.ui:79 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:183 +#, fuzzy +msgid "Accept Cookies:" +msgstr "Cookies annehmen:" + +#. i18n: file: settings_privacy.ui:90 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:186 +msgid "Always" +msgstr "Immer" + +#. i18n: file: settings_privacy.ui:95 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:189 +msgid "Never" +msgstr "Nie" + +#. i18n: file: settings_privacy.ui:100 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:192 +#, fuzzy +msgid "Only from sites you visit" +msgstr "Von besuchten Seiten" + +#. i18n: file: settings_privacy.ui:108 +#. i18n: ectx: property (text), widget (QPushButton, exceptionsButton) +#: rc.cpp:195 +msgid "Exceptions..." +msgstr "Ausnahmen ..." + +#. i18n: file: settings_privacy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:198 +msgid "Keep until:" +msgstr "Behalten bis:" + +#. i18n: file: settings_privacy.ui:126 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:201 +msgid "They expire" +msgstr "Sie ablaufen" + +#. i18n: file: settings_privacy.ui:131 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:204 +#, fuzzy +msgid "I exit the application" +msgstr "Die Anwendung geschlossen wird" + +#. i18n: file: settings_privacy.ui:136 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:207 +#, fuzzy +msgid "At most 90 days" +msgstr "Spätestens 90 Tagen" + +#. i18n: file: settings_privacy.ui:144 +#. i18n: ectx: property (text), widget (QPushButton, cookiesButton) +#: rc.cpp:210 +msgid "Cookies..." +msgstr "Cookies ..." + +#. i18n: file: settings_proxy.ui:19 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_isProxyEnabled) +#: rc.cpp:216 +msgid "Enable proxy" +msgstr "Proxy aktivieren" + +#. i18n: file: settings_proxy.ui:26 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:219 +msgid "Proxy Settings" +msgstr "Proxy-Einstellungen" + +#. i18n: file: settings_proxy.ui:32 +#. i18n: ectx: property (text), widget (QLabel, label_9) +#: rc.cpp:222 +msgid "Type:" +msgstr "Typ:" + +#. i18n: file: settings_proxy.ui:43 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:225 +msgid "SOCKS 5" +msgstr "SOCKS 5" + +#. i18n: file: settings_proxy.ui:48 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:228 +msgid "HTTP" +msgstr "HTTP" + +#. i18n: file: settings_proxy.ui:56 +#. i18n: ectx: property (text), widget (QLabel, label_10) +#: rc.cpp:231 +msgid "Host:" +msgstr "Rechner:" + +#. i18n: file: settings_proxy.ui:69 +#. i18n: ectx: property (text), widget (QLabel, label_11) +#: rc.cpp:234 +msgid "Port:" +msgstr "Port:" + +#. i18n: file: settings_webkit.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:246 +#, fuzzy +msgid "WebKit Settings" +msgstr "&Einstellungen" + +#. i18n: file: settings_webkit.ui:26 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_autoLoadImages) +#: rc.cpp:249 +msgid "Auto Load Images" +msgstr "" + +#. i18n: file: settings_webkit.ui:40 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_linksIncludedInFocusChain) +#: rc.cpp:252 +msgid "Links included in focus chain" +msgstr "" + +#. i18n: file: settings_webkit.ui:47 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptEnabled) +#: rc.cpp:255 +msgid "Javascript support" +msgstr "" + +#. i18n: file: settings_webkit.ui:54 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_zoomTextOnly) +#: rc.cpp:258 +msgid "Zoom Text Only" +msgstr "" + +#. i18n: file: settings_webkit.ui:61 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javaEnabled) +#: rc.cpp:261 +msgid "Java support" +msgstr "" + +#. i18n: file: settings_webkit.ui:68 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_printElementBackgrounds) +#: rc.cpp:264 +msgid "Print element Backgrounds" +msgstr "" + +#. i18n: file: settings_webkit.ui:75 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_pluginsEnabled) +#: rc.cpp:267 +#, fuzzy +msgid "Plugins" +msgstr "Plugins aktivieren" + +#. i18n: file: settings_webkit.ui:82 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineStorageDatabaseEnabled) +#: rc.cpp:270 +msgid "Offline storage Database" +msgstr "" + +#. i18n: file: settings_webkit.ui:89 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanOpenWindows) +#: rc.cpp:273 +msgid "Javascript can open windows" +msgstr "" + +#. i18n: file: settings_webkit.ui:96 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineWebApplicationCacheEnabled) +#: rc.cpp:276 +msgid "Offline Web Application Cache " +msgstr "" + +#. i18n: file: settings_webkit.ui:103 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanAccessClipboard) +#: rc.cpp:279 +msgid "Javascript can access clipboard" +msgstr "" + +#. i18n: file: settings_webkit.ui:110 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_localStorageDatabaseEnabled) +#: rc.cpp:282 +msgid "Local storage database" +msgstr "" + +#~ msgid "Show side panel" +#~ msgstr "Lesezeichen-Seitenleiste anzeigen" + +#~ msgid "Print Document" +#~ msgstr "Dokument drucken" + +#~ msgid "Location Toolbar" +#~ msgstr "Adressleiste" + +#, fuzzy +#~ msgid "reload" +#~ msgstr "Unterfenster neu laden" + +#, fuzzy +#~ msgid "Clear Location Bar" +#~ msgstr "Adressleiste" + +#~ msgid "Finished loading" +#~ msgstr "Laden abgeschlossen" + +#~ msgid "Bookmarks" +#~ msgstr "Lesezeichen" + +#~ msgid "Interface" +#~ msgstr "Oberfläche" + +#~ msgid "Downloads" +#~ msgstr "Downloads" + +#~ msgid "Show close button on tabs" +#~ msgstr "„Schließen“-Knopf auf Unterfenstern anzeigen" + +#~ msgid "Confirm when closing window with multiple tabs" +#~ msgstr "" +#~ "&Beim Schließen von Fenster mit mehreren Unterfenster, um Bestätigung " +#~ "fragen" + +#~ msgid "Enable location bar progress indication" +#~ msgstr "Fortschrittsanzeige in Adressleiste aktivieren" + +#, fuzzy +#~ msgid "Secure connection indicator:" +#~ msgstr "Anzeige einer sicheren Verbindung:" + +#~ msgid "Progress indicator:" +#~ msgstr "Fortschrittsanzeige:" + +#~ msgid "Web Content" +#~ msgstr "Web-Inhalt" + +#~ msgid "Ask destination for each download" +#~ msgstr "Zielort für jeden Download nachfragen" diff --git a/po/rekonq_it.po b/po/rekonq_it.po new file mode 100644 index 00000000..d134f727 --- /dev/null +++ b/po/rekonq_it.po @@ -0,0 +1,1038 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the rekonq package. +# FIRST AUTHOR Andrea Diamantini , 2009. +msgid "" +msgstr "" +"Project-Id-Version: rekonq\n" +"Report-Msgid-Bugs-To: http://sourceforge." +"net/tracker/?group_id=252277&atid=1126949\n" +"POT-Creation-Date: 2009-05-02 02:35+0200\n" +"PO-Revision-Date: 2009-05-02 02:48+0200\n" +"Last-Translator: Andrea Diamantini \n" +"Language-Team: American English \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: it_IT\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. i18n: file: rekonqui.rc:58 +#. i18n: ectx: Menu (go) +#: bookmarks.cpp:265 rc.cpp:90 +msgid "&Bookmarks" +msgstr "B&ookmarks" + +#: bookmarks.cpp:274 +msgid "Bookmarks Bar" +msgstr "B&ookmarks" + +#: cookiejar.cpp:457 cookiejar.cpp:636 +msgid "Website" +msgstr "" + +#: cookiejar.cpp:459 +msgid "Name" +msgstr "Nome" + +#: cookiejar.cpp:461 +msgid "Path" +msgstr "path" + +#: cookiejar.cpp:463 +msgid "Secure" +msgstr "" + +#: cookiejar.cpp:465 +msgid "Expires" +msgstr "Scade" + +#: cookiejar.cpp:467 +msgid "Contents" +msgstr "" + +#: cookiejar.cpp:638 +msgid "Status" +msgstr "Stato" + +#. i18n: file: cookiesexceptions.ui:77 +#. i18n: ectx: property (text), widget (QPushButton, allowButton) +#: cookiejar.cpp:663 rc.cpp:27 +msgid "Allow" +msgstr "Permetti" + +#. i18n: file: cookiesexceptions.ui:57 +#. i18n: ectx: property (text), widget (QPushButton, blockButton) +#: cookiejar.cpp:674 rc.cpp:21 +msgid "Block" +msgstr "Blocca" + +#. i18n: file: cookiesexceptions.ui:67 +#. i18n: ectx: property (text), widget (QPushButton, allowForSessionButton) +#: cookiejar.cpp:685 rc.cpp:24 +msgid "Allow For Session" +msgstr "Permetti per una sessione" + +#: download.cpp:73 +msgid "" +"Download '%1'?\n" +"Type: %2" +msgstr "" +"Download '%1' \n" +" Tipo: %2" + +#: download.cpp:74 +msgid "Download '%1'..." +msgstr "" + +#: findbar.cpp:39 +msgid "&Match case" +msgstr "" + +#: findbar.cpp:55 +msgid "Find: " +msgstr "Trova:" + +#: findbar.cpp:65 +msgid "&Next" +msgstr "" + +#: findbar.cpp:66 +msgid "&Previous" +msgstr "" + +#: history.cpp:445 +msgid "Title" +msgstr "Titolo" + +#: history.cpp:446 +msgid "Address" +msgstr "Indirizzo" + +#: history.cpp:703 +msgid "Show All History" +msgstr "Mostra la cronologia" + +#: history.cpp:707 +msgid "Clear History" +msgstr "Cancella la cronologia" + +#: history.cpp:788 +msgid "Open" +msgstr "Apri" + +#: history.cpp:790 +msgid "Copy" +msgstr "Copia" + +#: history.cpp:792 +msgid "Delete" +msgstr "Cancella" + +#: history.cpp:1175 +msgid "Earlier Today" +msgstr "" + +#: history.cpp:1180 +msgid "1 item" +msgid_plural "%1 items" +msgstr[0] "" +msgstr[1] "" + +#: main.cpp:29 +msgid "KDE Browser Webkit Based" +msgstr "" + +#: main.cpp:39 +msgid "rekonq" +msgstr "" + +#: main.cpp:43 +msgid "(C) 2008-2009 Andrea Diamantini" +msgstr "" + +#: main.cpp:50 +msgid "Andrea Diamantini" +msgstr "" + +#: main.cpp:51 +msgid "Project Lead, Developer, Italian translations" +msgstr "" + +#: main.cpp:55 +msgid "Domrachev Alexandr" +msgstr "" + +#: main.cpp:56 +msgid "Developer, Russian translations" +msgstr "" + +#: main.cpp:60 +msgid "Pawel Prazak" +msgstr "" + +#: main.cpp:61 +msgid "Developer" +msgstr "" + +#: main.cpp:65 +msgid "Panagiotis Papadopoulos" +msgstr "" + +#: main.cpp:66 +msgid "German translations" +msgstr "" + +#: main.cpp:82 +msgid "Location to open" +msgstr "Indirizzo da aprire" + +#: mainview.cpp:98 +msgid "Recently Closed Tabs" +msgstr "tabs chiuse recentemente" + +#: mainview.cpp:339 mainview.cpp:583 +msgid "(Untitled)" +msgstr "(senza titolo)" + +#: mainview.cpp:455 +msgid "" +"You have modified this page and when closing it you would lose the " +"modification.\n" +"Do you really want to close this page?\n" +msgstr "" +"Hai modificato questa pagina e chiudendola, potresti perdere queste " +"modifiche.\n" +"Vuoi davvero chiudere questa pagina?\n" + +#: mainview.cpp:457 +msgid "Do you really want to close this page?" +msgstr "Vuoi davvero chiudere questa pagina?" + +#: mainview.cpp:514 +msgid "Loading..." +msgstr "Sto caricando.. " + +#: mainview.cpp:529 +msgid "Loading %1% (%2 %3)..." +msgstr "Sto caricando %1% (%2 %3)... " + +#: mainview.cpp:556 +msgid "Done" +msgstr "Fatto" + +#: mainview.cpp:558 +msgid "Failed to load" +msgstr "Caricamento fallito" + +#: mainwindow.cpp:177 +msgid "Location Bar" +msgstr "Barra degli Indirizzi" + +#: mainwindow.cpp:183 +msgid "Search Bar" +msgstr "Barra di ricerca" + +#: mainwindow.cpp:215 mainwindow.cpp:230 mainwindow.cpp:809 +msgid "Reload" +msgstr "Ricarica" + +#: mainwindow.cpp:224 +msgid "&Stop" +msgstr "&Stop" + +#: mainwindow.cpp:235 +msgid "Open Location" +msgstr "Carica Indirizzo" + +#: mainwindow.cpp:240 +msgid "&Enlarge Font" +msgstr "Allarga Caratt&ere" + +#: mainwindow.cpp:245 +msgid "&Normal Font" +msgstr "Carattere &Normale" + +#: mainwindow.cpp:250 +msgid "&Shrink Font" +msgstr "&Stringi Carattere" + +#: mainwindow.cpp:255 +msgid "Page S&ource" +msgstr "S&orgente della pagina" + +#: mainwindow.cpp:260 +msgid "Web &Inspector" +msgstr "" + +#: mainwindow.cpp:265 +msgid "Private &Browsing" +msgstr "Navigazione Privata" + +#: mainwindow.cpp:271 +msgid "Back" +msgstr "Indietro" + +#: mainwindow.cpp:279 +msgid "Forward" +msgstr "Avanti" + +#: mainwindow.cpp:284 +msgid "New &Tab" +msgstr "Nuova &Tab" + +#: mainwindow.cpp:292 tabbar.cpp:110 +msgid "&Close Tab" +msgstr "&Chiudi Tab" + +#: mainwindow.cpp:297 +msgid "Show Next Tab" +msgstr "Mostra la prossima Tab" + +#: mainwindow.cpp:302 +msgid "Show Previous Tab" +msgstr "Mostra la Tab precedente" + +#. i18n: file: history.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, HistoryDialog) +#. i18n: file: settings_privacy.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: mainwindow.cpp:312 mainwindow.cpp:320 rc.cpp:39 rc.cpp:156 +msgid "History" +msgstr "Cronologia" + +#: mainwindow.cpp:336 +msgid "&History" +msgstr "Cronologia" + +#: mainwindow.cpp:523 +msgid "Web Resources (*.html *.htm *.svg *.png *.gif *.svgz); All files (*.*)" +msgstr "" +"Risorse Web (*.html *.htm *.svg *.png *.gif *.svgz);;Tutti i files (*.*)" + +#: mainwindow.cpp:525 +msgid "Open Web Resource" +msgstr "Apri Risorsa Web" + +#: mainwindow.cpp:571 +msgid "Are you sure you want to turn on private browsing?" +msgstr "Sei sicuro di voler utilizzare la navigazione anonima?" + +#: mainwindow.cpp:572 +msgid "" +"

When private browsing in turned on, webpages are not added to " +"the history, new cookies are not stored, current cookies cannot be accessed, " +"site icons will not be stored, session will not 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." +msgstr "" + +#: mainwindow.cpp:632 mainwindow.cpp:654 +msgid " not found." +msgstr "non trovato" + +#: mainwindow.cpp:766 +msgid "" +"The web inspector will only work correctly for pages that were loaded after " +"enabling.\n" +"Do you want to reload all pages?" +msgstr "" +"Lo web inspector funziona correttamente solo per quelle pagine caricate dopo " +"averlo abilitato.\n" +"Vuoi ricaricare tutte le pagine?" + +#: mainwindow.cpp:768 +msgid "Web Inspector" +msgstr "" + +#: mainwindow.cpp:800 +msgid "Stop loading the current page" +msgstr "Ferma il caricamento della pagina corrente" + +#: mainwindow.cpp:801 +msgid "Stop" +msgstr "" + +#: mainwindow.cpp:808 +msgid "Reload the current page" +msgstr "Ricarica la pagina corrente" + +#: mainwindow.cpp:892 +msgid "" +"Are you sure you want to close the window?\n" +"You have 1 tap open" +msgid_plural "" +"Are you sure you want to close the window?\n" +"You have %1 tabs open" +msgstr[0] "Vuoi davvero chiudere questa pagina?\n C'è 1 tab aperta" +msgstr[1] "Vuoi davvero chiudere questa pagina?" + +#: mainwindow.cpp:893 +msgid "Are you sure you want to close the window?" +msgstr "Vuoi davvero chiudere questa pagina?" + +#: mainwindow.cpp:895 +msgid "C&lose Current Tab" +msgstr "&Chiudi la tab corrente" + +#: networkaccessmanager.cpp:112 +msgid "Enter username and password for " +msgstr " Inserisci username e password per" + +#: networkaccessmanager.cpp:113 +msgid " at " +msgstr "a" + +#: networkaccessmanager.cpp:140 +msgid "Connect to proxy " +msgstr " Connessione al proxy" + +#: networkaccessmanager.cpp:140 +msgid " using:" +msgstr "utilizzando: " + +#: networkaccessmanager.cpp:160 +msgid "" +"SSL Errors:\n" +"\n" +msgstr "" + +#: panelhistory.cpp:50 +msgid "Search: " +msgstr "Cerca:" + +#: searchbar.cpp:55 +msgid "Search.." +msgstr "Cerca.." + +#. i18n: file: settings_general.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, general) +#: settings.cpp:81 rc.cpp:126 +msgid "General" +msgstr "Generale" + +#. i18n: file: settings_fonts.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: settings.cpp:87 rc.cpp:111 +msgid "Fonts" +msgstr "Caratteri" + +#. i18n: file: settings_privacy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, privacy) +#: settings.cpp:93 rc.cpp:153 +msgid "Privacy" +msgstr "" + +#. i18n: file: settings_proxy.ui:13 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxy) +#: settings.cpp:99 rc.cpp:213 +msgid "Proxy" +msgstr "" + +#: settings.cpp:105 +msgid "Webkit" +msgstr "" + +#: settings.cpp:121 +msgid "rekonfig.." +msgstr "" + +#: settings.cpp:143 +msgid "Specifies whether images are automatically loaded in web pages" +msgstr "" +"Specifica se le immagini vengano caricate automaticamente nelle pagine web" + +#: settings.cpp:144 +msgid "Enables the running of JavaScript programs." +msgstr "Abilita l'esecuzione del javascript" + +#: settings.cpp:145 +msgid "Enables Java applets." +msgstr "Abilita la applet java" + +#: settings.cpp:146 +msgid "Enables plugins in web pages." +msgstr "Abilita i plugins nelle pagine web" + +#: settings.cpp:147 +msgid "Allows JavaScript programs to opening new windows." +msgstr "Permetti al javascript aprire nuove finestre" + +#: settings.cpp:148 +msgid "Allows JavaScript programs to reading/writing to the clipboard." +msgstr "Permetti a javascript to leggere/scrivere nella clipboard" + +#: settings.cpp:149 +msgid "Includes hyperlinks in the keyboard focus chain." +msgstr "Includi link nella sequenza di tab della tastiera" + +#: settings.cpp:150 +msgid "Applies the zoom factor on a frame to only the text or all content." +msgstr "" +"Applica il fattore di zoom in un frame solo al testo o a tutto il contenuto" + +#: settings.cpp:151 +msgid "Draws also background color and images when the page is printed." +msgstr "" +"Disegna anche i colori e le immagini di sfondo quando la pagina viene " +"stampata" + +#: settings.cpp:152 +msgid "Support for the HTML 5 offline storage feature." +msgstr "" + +#: settings.cpp:153 +msgid "Support for the HTML 5 web application cache feature." +msgstr " " + +#: settings.cpp:154 +msgid "Support for the HTML 5 local storage feature." +msgstr "Supporto per lo storage locale di HTML 5" + +#: tabbar.cpp:108 +msgid "Clone Tab" +msgstr "Clona tab" + +#: tabbar.cpp:111 +msgid "Close &Other Tabs" +msgstr "Chiudi le altre tab" + +#: tabbar.cpp:113 +msgid "Reload Tab" +msgstr "Ricarica tab" + +#: tabbar.cpp:119 +msgid "Reload All Tabs" +msgstr "Ricarica tutte le tabs" + +#: webview.cpp:245 +msgid "Error loading page: " +msgstr "Errore nel caricamento della pagina" + +#: webview.cpp:309 +msgid "Open Link in New &Tab" +msgstr "Apri link in una nuova tab" + +#: webview.cpp:315 +msgid "Cu&t" +msgstr "Taglia" + +#: webview.cpp:320 +msgid "&Copy" +msgstr "Copia" + +#: webview.cpp:325 +msgid "&Paste" +msgstr "Incolla" + +#: webview.cpp:330 +msgid "&Save Image As..." +msgstr "Salva Immagine come.." + +#: webview.cpp:335 +msgid "&Copy This Image" +msgstr "Copia immagine" + +#: webview.cpp:340 +msgid "&Save Link As..." +msgstr "Salva link.." + +#: webview.cpp:345 +msgid "&Copy Link Location" +msgstr "Copia link" + +#: webview.cpp:350 +msgid "&Inspect Element" +msgstr "&Ispeziona elemento" + +#: webview.cpp:364 +msgid "Bookmark This Page" +msgstr "Inserisci pagina nei bookmarks" + +#: webview.cpp:417 +msgid "&Bookmark This Link" +msgstr "Inserisci link nei Bookmarks" + +#. i18n: file: cookies.ui:14 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesDialog) +#. i18n: file: settings_privacy.ui:73 +#. i18n: ectx: property (title), widget (QGroupBox, cookiesGroupBox) +#: rc.cpp:3 rc.cpp:180 +msgid "Cookies" +msgstr "" + +#. i18n: file: cookies.ui:41 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: cookiesexceptions.ui:114 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: history.ui:40 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#: rc.cpp:6 rc.cpp:33 rc.cpp:42 +msgid "&Remove" +msgstr "Rimuovi" + +#. i18n: file: cookies.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:9 +msgid "Remove &All Cookies" +msgstr "Rimuovi tutti i cookies" + +#. i18n: file: cookiesexceptions.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesExceptionsDialog) +#: rc.cpp:12 +msgid "Cookie Exceptions" +msgstr "Eccezioni" + +#. i18n: file: cookiesexceptions.ui:19 +#. i18n: ectx: property (title), widget (QGroupBox, newExceptionGroupBox) +#: rc.cpp:15 +msgid "New Exception" +msgstr "Nuova eccezione" + +#. i18n: file: cookiesexceptions.ui:27 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:18 +msgid "Domain:" +msgstr "Dominio:" + +#. i18n: file: cookiesexceptions.ui:89 +#. i18n: ectx: property (title), widget (QGroupBox, ExceptionsGroupBox) +#: rc.cpp:30 +msgid "Exceptions" +msgstr "Eccezioni" + +#. i18n: file: cookiesexceptions.ui:121 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#. i18n: file: history.ui:47 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:36 rc.cpp:45 +msgid "Remove &All" +msgstr "Rimuovi tutti" + +#. i18n: file: password.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, passwordWidget) +#. i18n: file: proxy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxyWidget) +#. i18n: file: settings_webkit.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, webkit) +#: rc.cpp:48 rc.cpp:63 rc.cpp:243 +msgid "Form" +msgstr "" + +#. i18n: file: password.ui:22 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:51 +msgid "DUMMY ICON" +msgstr "" + +#. i18n: file: password.ui:35 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:54 +msgid "INTRO TEXT DUMMY" +msgstr "" + +#. i18n: file: password.ui:44 +#. i18n: ectx: property (text), widget (QLabel, label) +#. i18n: file: proxy.ui:37 +#. i18n: ectx: property (text), widget (QLabel, usernameLabel) +#. i18n: file: settings_proxy.ui:102 +#. i18n: ectx: property (text), widget (QLabel, label_12) +#: rc.cpp:57 rc.cpp:72 rc.cpp:237 +msgid "Username:" +msgstr "" + +#. i18n: file: password.ui:54 +#. i18n: ectx: property (text), widget (QLabel, lblPassword) +#. i18n: file: proxy.ui:47 +#. i18n: ectx: property (text), widget (QLabel, passwordLabel) +#. i18n: file: settings_proxy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label_13) +#: rc.cpp:60 rc.cpp:75 rc.cpp:240 +msgid "Password:" +msgstr "" + +#. i18n: file: proxy.ui:20 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:66 +msgid "ICON" +msgstr "" + +#. i18n: file: proxy.ui:27 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:69 +msgid "Connect to proxy" +msgstr "Connetti al proxy" + +#. i18n: file: rekonqui.rc:8 +#. i18n: ectx: Menu (file) +#: rc.cpp:78 +msgid "&File" +msgstr "&File" + +#. i18n: file: rekonqui.rc:24 +#. i18n: ectx: Menu (edit) +#: rc.cpp:81 +msgid "&Edit" +msgstr "&Modifica" + +#. i18n: file: rekonqui.rc:38 +#. i18n: ectx: Menu (view) +#: rc.cpp:84 +msgid "&View" +msgstr "&Vedi" + +#. i18n: file: rekonqui.rc:54 +#. i18n: ectx: Menu (go) +#: rc.cpp:87 +msgid "Hi&story" +msgstr "&Cronologia" + +#. i18n: file: rekonqui.rc:62 +#. i18n: ectx: Menu (tools) +#: rc.cpp:93 +msgid "&Tools" +msgstr "&Strumenti" + +#. i18n: file: rekonqui.rc:68 +#. i18n: ectx: Menu (settings) +#: rc.cpp:96 +msgid "&Settings" +msgstr "&Impostazioni" + +#. i18n: file: rekonqui.rc:73 +#. i18n: ectx: Menu (side_panels) +#: rc.cpp:99 +msgid "Side &Panels" +msgstr "&Pannelli laterali" + +#. i18n: file: rekonqui.rc:88 +#. i18n: ectx: ToolBar (mainToolBar) +#: rc.cpp:102 +msgid "Main Toolbar" +msgstr "" + +#. i18n: file: rekonqui.rc:100 +#. i18n: ectx: ToolBar (bookmarksToolBar) +#: rc.cpp:105 +msgid "Bookmark Toolbar" +msgstr "" + +#. i18n: file: settings_fonts.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, fonts) +#: rc.cpp:108 +msgid "Appearance" +msgstr "Aspetto" + +#. i18n: file: settings_fonts.ui:28 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:114 +msgid "Standard Font" +msgstr "Carattere standard" + +#. i18n: file: settings_fonts.ui:35 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:117 +msgid "Fixed Font" +msgstr "Carattere fisso" + +#. i18n: file: settings_fonts.ui:53 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: rc.cpp:120 +msgid "Dimension" +msgstr "Dimensione" + +#. i18n: file: settings_fonts.ui:61 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:123 +msgid "Font Size" +msgstr "Dimensione carattere" + +#. i18n: file: settings_general.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:129 +msgid "Places" +msgstr "Come si traduce \"places\"?" + +#. i18n: file: settings_general.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:132 +msgid "Home Page:" +msgstr "" + +#. i18n: file: settings_general.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, setHomeToCurrentPageButton) +#: rc.cpp:135 +msgid "Set to current page" +msgstr "Imposta alla pagina corrente" + +#. i18n: file: settings_general.ui:73 +#. i18n: ectx: property (text), widget (QLabel, label_7) +#: rc.cpp:138 +msgid "Save downloads to:" +msgstr "Salva download:" + +#. i18n: file: settings_general.ui:83 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_downloadToDefaultDir) +#: rc.cpp:141 +msgid "ask where saving downloads" +msgstr "Chiedi dove salvare i downloads" + +#. i18n: file: settings_general.ui:93 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: rc.cpp:144 +msgid "Tabbed Browsing" +msgstr "Navigazione Anonima" + +#. i18n: file: settings_general.ui:99 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_alwaysShowTabBar) +#: rc.cpp:147 +msgid "Always show tab bar" +msgstr "Mostra sempre la tab bar" + +#. i18n: file: settings_general.ui:106 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_openTabsBack) +#: rc.cpp:150 +msgid "Open tabs in the background" +msgstr "Apri le nuove tab in background" + +#. i18n: file: settings_privacy.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_4) +#: rc.cpp:159 +msgid "Remove history items:" +msgstr "Rimuovi la cronologia:" + +#. i18n: file: settings_privacy.ui:37 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:162 +msgid "After one day" +msgstr "Dopo 1 giorno" + +#. i18n: file: settings_privacy.ui:42 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:165 +msgid "After one week" +msgstr "Dopo 1 settimana" + +#. i18n: file: settings_privacy.ui:47 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:168 +msgid "After two weeks" +msgstr "Dopo 2 settimane" + +#. i18n: file: settings_privacy.ui:52 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:171 +msgid "After one month" +msgstr "Dopo 1 mese" + +#. i18n: file: settings_privacy.ui:57 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:174 +msgid "After one year" +msgstr "Dopo 1 anno" + +#. i18n: file: settings_privacy.ui:62 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:177 +msgid "Manually" +msgstr "Manualmente" + +#. i18n: file: settings_privacy.ui:79 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:183 +msgid "Accept Cookies:" +msgstr "Accetta Cookies:" + +#. i18n: file: settings_privacy.ui:90 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:186 +msgid "Always" +msgstr "Sempre" + +#. i18n: file: settings_privacy.ui:95 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:189 +msgid "Never" +msgstr "Mai" + +#. i18n: file: settings_privacy.ui:100 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:192 +msgid "Only from sites you visit" +msgstr "Solo dai siti che visiti" + +#. i18n: file: settings_privacy.ui:108 +#. i18n: ectx: property (text), widget (QPushButton, exceptionsButton) +#: rc.cpp:195 +msgid "Exceptions..." +msgstr "Eccezioni.." + +#. i18n: file: settings_privacy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:198 +msgid "Keep until:" +msgstr "Mantieni finché" + +#. i18n: file: settings_privacy.ui:126 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:201 +msgid "They expire" +msgstr "non scadono" + +#. i18n: file: settings_privacy.ui:131 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:204 +msgid "I exit the application" +msgstr "esci dall'applicazione" + +#. i18n: file: settings_privacy.ui:136 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:207 +msgid "At most 90 days" +msgstr "Al massimo 90 giorni" + +#. i18n: file: settings_privacy.ui:144 +#. i18n: ectx: property (text), widget (QPushButton, cookiesButton) +#: rc.cpp:210 +msgid "Cookies..." +msgstr "" + +#. i18n: file: settings_proxy.ui:19 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_isProxyEnabled) +#: rc.cpp:216 +msgid "Enable proxy" +msgstr "Abilita proxy" + +#. i18n: file: settings_proxy.ui:26 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:219 +msgid "Proxy Settings" +msgstr "Impostazioni Proxy:" + +#. i18n: file: settings_proxy.ui:32 +#. i18n: ectx: property (text), widget (QLabel, label_9) +#: rc.cpp:222 +msgid "Type:" +msgstr "Tipo:" + +#. i18n: file: settings_proxy.ui:43 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:225 +msgid "SOCKS 5" +msgstr "" + +#. i18n: file: settings_proxy.ui:48 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:228 +msgid "HTTP" +msgstr "" + +#. i18n: file: settings_proxy.ui:56 +#. i18n: ectx: property (text), widget (QLabel, label_10) +#: rc.cpp:231 +msgid "Host:" +msgstr "Host:" + +#. i18n: file: settings_proxy.ui:69 +#. i18n: ectx: property (text), widget (QLabel, label_11) +#: rc.cpp:234 +msgid "Port:" +msgstr "Porta:" + +#. i18n: file: settings_webkit.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:246 +msgid "WebKit Settings" +msgstr "Impostazioni WebKit" + +#. i18n: file: settings_webkit.ui:26 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_autoLoadImages) +#: rc.cpp:249 +msgid "Auto Load Images" +msgstr "Carica automaticamente immagini" + +#. i18n: file: settings_webkit.ui:40 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_linksIncludedInFocusChain) +#: rc.cpp:252 +msgid "Links included in focus chain" +msgstr "link inclusi nella sequenza di focus" + +#. i18n: file: settings_webkit.ui:47 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptEnabled) +#: rc.cpp:255 +msgid "Javascript support" +msgstr "Supporto a Javascript" + +#. i18n: file: settings_webkit.ui:54 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_zoomTextOnly) +#: rc.cpp:258 +msgid "Zoom Text Only" +msgstr "Zoom solo testo" + +#. i18n: file: settings_webkit.ui:61 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javaEnabled) +#: rc.cpp:261 +msgid "Java support" +msgstr "supporto a Java" + +#. i18n: file: settings_webkit.ui:68 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_printElementBackgrounds) +#: rc.cpp:264 +msgid "Print element Backgrounds" +msgstr "Stampa gli elementi di sfondo" + +#. i18n: file: settings_webkit.ui:75 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_pluginsEnabled) +#: rc.cpp:267 +msgid "Plugins" +msgstr "" + +#. i18n: file: settings_webkit.ui:82 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineStorageDatabaseEnabled) +#: rc.cpp:270 +msgid "Offline storage Database" +msgstr "" + +#. i18n: file: settings_webkit.ui:89 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanOpenWindows) +#: rc.cpp:273 +msgid "Javascript can open windows" +msgstr "javascript può aprire finestre" + +#. i18n: file: settings_webkit.ui:96 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineWebApplicationCacheEnabled) +#: rc.cpp:276 +msgid "Offline Web Application Cache " +msgstr "" + +#. i18n: file: settings_webkit.ui:103 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanAccessClipboard) +#: rc.cpp:279 +msgid "Javascript can access clipboard" +msgstr "javascript può accedere alla clipboard" + +#. i18n: file: settings_webkit.ui:110 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_localStorageDatabaseEnabled) +#: rc.cpp:282 +msgid "Local storage database" +msgstr "" + +#~ msgid "Show side panel" +#~ msgstr "Mostra il pannello laterale" + +#~ msgid "Print Document" +#~ msgstr "Stampa Documento" + +#~ msgid "reload" +#~ msgstr "ricarica" + +#~ msgid "Clear Location Bar" +#~ msgstr "Cancella la Barra degli Indirizzi" + +#~ msgid "" +#~ "Clear Location bar

Clears the contents of the location " +#~ "bar." +#~ msgstr "" +#~ "Cancella la barra degli indirizzi

Cancella il contenuto " +#~ "della barra degli indirizzi" diff --git a/po/rekonq_ru.po b/po/rekonq_ru.po new file mode 100644 index 00000000..91dfb2ec --- /dev/null +++ b/po/rekonq_ru.po @@ -0,0 +1,1134 @@ +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the rekonq package. +# FIRST AUTHOR Domrachev Alexandr , 2009. +# Domrachev Alexandr , 2009. +msgid "" +msgstr "" +"Project-Id-Version: \n" +"Report-Msgid-Bugs-To: http://sourceforge.net/tracker/?" +"group_id=252277&atid=1126949\n" +"POT-Creation-Date: 2009-05-02 02:35+0200\n" +"PO-Revision-Date: 2009-04-18 22:21+0400\n" +"Last-Translator: Domrachev Alexandr \n" +"Language-Team: Russian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Language: ru_RU\n" +"X-Generator: Lokalize 0.3\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" +"10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" + +#. i18n: file: rekonqui.rc:58 +#. i18n: ectx: Menu (go) +#: bookmarks.cpp:265 rc.cpp:90 +msgid "&Bookmarks" +msgstr "&Закладки" + +#: bookmarks.cpp:274 +msgid "Bookmarks Bar" +msgstr "Панель закладок" + +#: cookiejar.cpp:457 cookiejar.cpp:636 +msgid "Website" +msgstr "Сайт" + +#: cookiejar.cpp:459 +msgid "Name" +msgstr "Имя" + +#: cookiejar.cpp:461 +msgid "Path" +msgstr "Путь" + +#: cookiejar.cpp:463 +msgid "Secure" +msgstr "" + +#: cookiejar.cpp:465 +msgid "Expires" +msgstr "Истекает" + +#: cookiejar.cpp:467 +msgid "Contents" +msgstr "Содержимое" + +#: cookiejar.cpp:638 +msgid "Status" +msgstr "Статус" + +#. i18n: file: cookiesexceptions.ui:77 +#. i18n: ectx: property (text), widget (QPushButton, allowButton) +#: cookiejar.cpp:663 rc.cpp:27 +msgid "Allow" +msgstr "Разрешить" + +#. i18n: file: cookiesexceptions.ui:57 +#. i18n: ectx: property (text), widget (QPushButton, blockButton) +#: cookiejar.cpp:674 rc.cpp:21 +msgid "Block" +msgstr "Блокировать" + +#. i18n: file: cookiesexceptions.ui:67 +#. i18n: ectx: property (text), widget (QPushButton, allowForSessionButton) +#: cookiejar.cpp:685 rc.cpp:24 +msgid "Allow For Session" +msgstr "Разрешить до конца сессии" + +#: download.cpp:73 +msgid "" +"Download '%1'?\n" +"Type: %2" +msgstr "" +"Загрузить '%1'?\n" +"Тип: %2" + +#: download.cpp:74 +msgid "Download '%1'..." +msgstr "Загрузка '%1'..." + +#: findbar.cpp:39 +msgid "&Match case" +msgstr "С учётом &регистра" + +#: findbar.cpp:55 +msgid "Find: " +msgstr "Поиск:" + +#: findbar.cpp:65 +msgid "&Next" +msgstr "&Вперед" + +#: findbar.cpp:66 +msgid "&Previous" +msgstr "&Назад" + +#: history.cpp:445 +msgid "Title" +msgstr "" + +#: history.cpp:446 +msgid "Address" +msgstr "" + +#: history.cpp:703 +msgid "Show All History" +msgstr "Открыть журнал" + +#: history.cpp:707 +msgid "Clear History" +msgstr "Очистить журнал" + +#: history.cpp:788 +msgid "Open" +msgstr "Открыть" + +#: history.cpp:790 +msgid "Copy" +msgstr "Копировать" + +#: history.cpp:792 +msgid "Delete" +msgstr "Удалить" + +#: history.cpp:1175 +msgid "Earlier Today" +msgstr "Сегодня ранее" + +#: history.cpp:1180 +msgid "1 item" +msgid_plural "%1 items" +msgstr[0] "" +msgstr[1] "" +msgstr[2] "" + +#: main.cpp:29 +msgid "KDE Browser Webkit Based" +msgstr "" + +#: main.cpp:39 +msgid "rekonq" +msgstr "" + +#: main.cpp:43 +msgid "(C) 2008-2009 Andrea Diamantini" +msgstr "" + +#: main.cpp:50 +msgid "Andrea Diamantini" +msgstr "" + +#: main.cpp:51 +msgid "Project Lead, Developer, Italian translations" +msgstr "" + +#: main.cpp:55 +msgid "Domrachev Alexandr" +msgstr "Домрачев Александр" + +#: main.cpp:56 +msgid "Developer, Russian translations" +msgstr "" + +#: main.cpp:60 +msgid "Pawel Prazak" +msgstr "" + +#: main.cpp:61 +msgid "Developer" +msgstr "" + +#: main.cpp:65 +msgid "Panagiotis Papadopoulos" +msgstr "" + +#: main.cpp:66 +msgid "German translations" +msgstr "" + +#: main.cpp:82 +msgid "Location to open" +msgstr "" + +#: mainview.cpp:98 +msgid "Recently Closed Tabs" +msgstr "Недавно закрытые вкладки" + +#: mainview.cpp:339 mainview.cpp:583 +msgid "(Untitled)" +msgstr "(Без заголовка)" + +#: mainview.cpp:455 +msgid "" +"You have modified this page and when closing it you would lose the " +"modification.\n" +"Do you really want to close this page?\n" +msgstr "" +"Вы изменили данную страницу, при закрытии Вы потеряете все изменения.\n" +"Вы действительно хотите закрыть эту страницу?\n" + +#: mainview.cpp:457 +msgid "Do you really want to close this page?" +msgstr "Вы действительно хотите закрыть эту страницу?" + +#: mainview.cpp:514 +msgid "Loading..." +msgstr "Загрузка..." + +#: mainview.cpp:529 +msgid "Loading %1% (%2 %3)..." +msgstr "Загрузка %1% (%2 %3)..." + +#: mainview.cpp:556 +msgid "Done" +msgstr "" + +#: mainview.cpp:558 +msgid "Failed to load" +msgstr "Ошибка загрузки" + +#: mainwindow.cpp:177 +msgid "Location Bar" +msgstr "Отрыть местоположение" + +#: mainwindow.cpp:183 +msgid "Search Bar" +msgstr "Поиск..." + +#: mainwindow.cpp:215 mainwindow.cpp:230 mainwindow.cpp:809 +msgid "Reload" +msgstr "Обновить" + +#: mainwindow.cpp:224 +#, fuzzy +msgid "&Stop" +msgstr "&Стоп" + +#: mainwindow.cpp:235 +msgid "Open Location" +msgstr "Отрыть местоположение" + +#: mainwindow.cpp:240 +msgid "&Enlarge Font" +msgstr "У&величить шрифт" + +#: mainwindow.cpp:245 +msgid "&Normal Font" +msgstr "&Нормальный шрифт" + +#: mainwindow.cpp:250 +msgid "&Shrink Font" +msgstr "У&меньшить шрифт" + +#: mainwindow.cpp:255 +msgid "Page S&ource" +msgstr "Исходный &код" + +#: mainwindow.cpp:260 +#, fuzzy +msgid "Web &Inspector" +msgstr "Включить Web &Inspector" + +#: mainwindow.cpp:265 +#, fuzzy +msgid "Private &Browsing" +msgstr "Режим &конфиденциальности..." + +#: mainwindow.cpp:271 +msgid "Back" +msgstr "Назад" + +#: mainwindow.cpp:279 +msgid "Forward" +msgstr "Вперед" + +#: mainwindow.cpp:284 +msgid "New &Tab" +msgstr "Новая &вкладка" + +#: mainwindow.cpp:292 tabbar.cpp:110 +msgid "&Close Tab" +msgstr "&Закрыть вкладку" + +#: mainwindow.cpp:297 +msgid "Show Next Tab" +msgstr "Открыть следующую вкладку" + +#: mainwindow.cpp:302 +msgid "Show Previous Tab" +msgstr "Открыть предыдущую вкладку" + +#. i18n: file: history.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, HistoryDialog) +#. i18n: file: settings_privacy.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: mainwindow.cpp:312 mainwindow.cpp:320 rc.cpp:39 rc.cpp:156 +msgid "History" +msgstr "Журнал" + +#: mainwindow.cpp:336 +msgid "&History" +msgstr "&Журнал" + +#: mainwindow.cpp:523 +#, fuzzy +msgid "Web Resources (*.html *.htm *.svg *.png *.gif *.svgz); All files (*.*)" +msgstr "Веб ресурсы (*.html *.htm *.svg *.png *.gif *.svgz);;All files (*.*)" + +#: mainwindow.cpp:525 +msgid "Open Web Resource" +msgstr "Открыть..." + +#: mainwindow.cpp:571 +msgid "Are you sure you want to turn on private browsing?" +msgstr "Вы действительно хотите включить режим конфиденциальности?" + +#: mainwindow.cpp:572 +#, fuzzy +msgid "" +"

When private browsing in turned on, webpages are not added to " +"the history, new cookies are not stored, current cookies cannot be accessed, " +"site icons will not be stored, session will not 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." +msgstr "" +"

При включенном режиме конфиденциальности, страницы не " +"добавляются в журнал, по завершении загрузки они удаляются из списка " +"загрузок, новые cookie не сохраняются, к уже имеющимся доступ закрыт, " +"история поиска не сохраняется. Пока Вы не закроете окно, Вы можете " +"использовать кнопки \"Вперед\" и \"Назад\" для перемещения по уже посещенным " +"сайтам." + +#: mainwindow.cpp:632 mainwindow.cpp:654 +msgid " not found." +msgstr "не найдено." + +#: mainwindow.cpp:766 +msgid "" +"The web inspector will only work correctly for pages that were loaded after " +"enabling.\n" +"Do you want to reload all pages?" +msgstr "" +"Web Inspector будет работать нормально только для страниц загруженных после " +"его включения.\n" +"Вы хотите обновить все вкладки?" + +#: mainwindow.cpp:768 +msgid "Web Inspector" +msgstr "" + +#: mainwindow.cpp:800 +msgid "Stop loading the current page" +msgstr "Остановить загрузку страницы" + +#: mainwindow.cpp:801 +msgid "Stop" +msgstr "" + +#: mainwindow.cpp:808 +msgid "Reload the current page" +msgstr "Обновить страницу" + +#: mainwindow.cpp:892 +#, fuzzy +msgid "" +"Are you sure you want to close the window?\n" +"You have 1 tap open" +msgid_plural "" +"Are you sure you want to close the window?\n" +"You have %1 tabs open" +msgstr[0] "" +"Вы действительно хотите закрыть окно?\n" +"У Вас окрыто %1 вкладк(а,и,ок)" +msgstr[1] "" +"Вы действительно хотите закрыть окно?\n" +"У Вас окрыто %1 вкладк(а,и,ок)" +msgstr[2] "" +"Вы действительно хотите закрыть окно?\n" +"У Вас окрыто %1 вкладк(а,и,ок)" + +#: mainwindow.cpp:893 +msgid "Are you sure you want to close the window?" +msgstr " Вы уверены, что хотите закрыть окно?" + +#: mainwindow.cpp:895 +#, fuzzy +msgid "C&lose Current Tab" +msgstr "&Закрыть вкладку" + +#: networkaccessmanager.cpp:112 +msgid "Enter username and password for " +msgstr "Введите имя пользователя и пароль для " + +#: networkaccessmanager.cpp:113 +msgid " at " +msgstr "" + +#: networkaccessmanager.cpp:140 +msgid "Connect to proxy " +msgstr "" + +#: networkaccessmanager.cpp:140 +msgid " using:" +msgstr "" + +#: networkaccessmanager.cpp:160 +msgid "" +"SSL Errors:\n" +"\n" +msgstr "" + +#: panelhistory.cpp:50 +msgid "Search: " +msgstr "Поиск: " + +#: searchbar.cpp:55 +#, fuzzy +msgid "Search.." +msgstr "Поиск..." + +#. i18n: file: settings_general.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, general) +#: settings.cpp:81 rc.cpp:126 +msgid "General" +msgstr "Основное" + +#. i18n: file: settings_fonts.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: settings.cpp:87 rc.cpp:111 +msgid "Fonts" +msgstr "Шрифты" + +#. i18n: file: settings_privacy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, privacy) +#: settings.cpp:93 rc.cpp:153 +msgid "Privacy" +msgstr "Приватность" + +#. i18n: file: settings_proxy.ui:13 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxy) +#: settings.cpp:99 rc.cpp:213 +msgid "Proxy" +msgstr "Прокси" + +#: settings.cpp:105 +msgid "Webkit" +msgstr "" + +#: settings.cpp:121 +#, fuzzy +msgid "rekonfig.." +msgstr "Параметры..." + +#: settings.cpp:143 +msgid "Specifies whether images are automatically loaded in web pages" +msgstr "" + +#: settings.cpp:144 +msgid "Enables the running of JavaScript programs." +msgstr "" + +#: settings.cpp:145 +msgid "Enables Java applets." +msgstr "" + +#: settings.cpp:146 +msgid "Enables plugins in web pages." +msgstr "Включает использование плагинов на странице" + +#: settings.cpp:147 +msgid "Allows JavaScript programs to opening new windows." +msgstr "" + +#: settings.cpp:148 +msgid "Allows JavaScript programs to reading/writing to the clipboard." +msgstr "" + +#: settings.cpp:149 +msgid "Includes hyperlinks in the keyboard focus chain." +msgstr "" + +#: settings.cpp:150 +msgid "Applies the zoom factor on a frame to only the text or all content." +msgstr "" + +#: settings.cpp:151 +msgid "Draws also background color and images when the page is printed." +msgstr "" + +#: settings.cpp:152 +msgid "Support for the HTML 5 offline storage feature." +msgstr "" + +#: settings.cpp:153 +msgid "Support for the HTML 5 web application cache feature." +msgstr "" + +#: settings.cpp:154 +msgid "Support for the HTML 5 local storage feature." +msgstr "" + +#: tabbar.cpp:108 +msgid "Clone Tab" +msgstr "Закрыть вкладку" + +#: tabbar.cpp:111 +msgid "Close &Other Tabs" +msgstr "Закрыть все, &кроме активной" + +#: tabbar.cpp:113 +msgid "Reload Tab" +msgstr "Обновить вкладку" + +#: tabbar.cpp:119 +msgid "Reload All Tabs" +msgstr "Обновить все вкладки" + +#: webview.cpp:245 +msgid "Error loading page: " +msgstr "Ошибка загрузки страницы: " + +#: webview.cpp:309 +msgid "Open Link in New &Tab" +msgstr "Открыть ссылку в &новой вкладке" + +#: webview.cpp:315 +msgid "Cu&t" +msgstr "" + +#: webview.cpp:320 +msgid "&Copy" +msgstr "" + +#: webview.cpp:325 +msgid "&Paste" +msgstr "" + +#: webview.cpp:330 +msgid "&Save Image As..." +msgstr "&Сохранить изображение..." + +#: webview.cpp:335 +msgid "&Copy This Image" +msgstr "&Копировать изображение в буфер обмена" + +#: webview.cpp:340 +msgid "&Save Link As..." +msgstr "Сохранить по ссылке как..." + +#: webview.cpp:345 +msgid "&Copy Link Location" +msgstr "&Отрыть местоположение" + +#: webview.cpp:350 +msgid "&Inspect Element" +msgstr "" + +#: webview.cpp:364 +msgid "Bookmark This Page" +msgstr "Создать закладку" + +#: webview.cpp:417 +msgid "&Bookmark This Link" +msgstr "Создать &закладку ссылки" + +#. i18n: file: cookies.ui:14 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesDialog) +#. i18n: file: settings_privacy.ui:73 +#. i18n: ectx: property (title), widget (QGroupBox, cookiesGroupBox) +#: rc.cpp:3 rc.cpp:180 +msgid "Cookies" +msgstr "" + +#. i18n: file: cookies.ui:41 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: cookiesexceptions.ui:114 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#. i18n: file: history.ui:40 +#. i18n: ectx: property (text), widget (QPushButton, removeButton) +#: rc.cpp:6 rc.cpp:33 rc.cpp:42 +msgid "&Remove" +msgstr "&Удалить" + +#. i18n: file: cookies.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:9 +msgid "Remove &All Cookies" +msgstr "Удалить &все cookie" + +#. i18n: file: cookiesexceptions.ui:13 +#. i18n: ectx: property (windowTitle), widget (QDialog, CookiesExceptionsDialog) +#: rc.cpp:12 +msgid "Cookie Exceptions" +msgstr "Исключения для cookies" + +#. i18n: file: cookiesexceptions.ui:19 +#. i18n: ectx: property (title), widget (QGroupBox, newExceptionGroupBox) +#: rc.cpp:15 +msgid "New Exception" +msgstr "Новое исключение" + +#. i18n: file: cookiesexceptions.ui:27 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:18 +msgid "Domain:" +msgstr "" + +#. i18n: file: cookiesexceptions.ui:89 +#. i18n: ectx: property (title), widget (QGroupBox, ExceptionsGroupBox) +#: rc.cpp:30 +msgid "Exceptions" +msgstr "Исключения" + +#. i18n: file: cookiesexceptions.ui:121 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#. i18n: file: history.ui:47 +#. i18n: ectx: property (text), widget (QPushButton, removeAllButton) +#: rc.cpp:36 rc.cpp:45 +msgid "Remove &All" +msgstr "Удалить &всё" + +#. i18n: file: password.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, passwordWidget) +#. i18n: file: proxy.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, proxyWidget) +#. i18n: file: settings_webkit.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, webkit) +#: rc.cpp:48 rc.cpp:63 rc.cpp:243 +msgid "Form" +msgstr "" + +#. i18n: file: password.ui:22 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:51 +msgid "DUMMY ICON" +msgstr "" + +#. i18n: file: password.ui:35 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:54 +msgid "INTRO TEXT DUMMY" +msgstr "" + +#. i18n: file: password.ui:44 +#. i18n: ectx: property (text), widget (QLabel, label) +#. i18n: file: proxy.ui:37 +#. i18n: ectx: property (text), widget (QLabel, usernameLabel) +#. i18n: file: settings_proxy.ui:102 +#. i18n: ectx: property (text), widget (QLabel, label_12) +#: rc.cpp:57 rc.cpp:72 rc.cpp:237 +msgid "Username:" +msgstr "Имя пользователя:" + +#. i18n: file: password.ui:54 +#. i18n: ectx: property (text), widget (QLabel, lblPassword) +#. i18n: file: proxy.ui:47 +#. i18n: ectx: property (text), widget (QLabel, passwordLabel) +#. i18n: file: settings_proxy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label_13) +#: rc.cpp:60 rc.cpp:75 rc.cpp:240 +msgid "Password:" +msgstr "Пароль:" + +#. i18n: file: proxy.ui:20 +#. i18n: ectx: property (text), widget (QLabel, iconLabel) +#: rc.cpp:66 +msgid "ICON" +msgstr "" + +#. i18n: file: proxy.ui:27 +#. i18n: ectx: property (text), widget (QLabel, introLabel) +#: rc.cpp:69 +msgid "Connect to proxy" +msgstr "" + +#. i18n: file: rekonqui.rc:8 +#. i18n: ectx: Menu (file) +#: rc.cpp:78 +msgid "&File" +msgstr "&Файл" + +#. i18n: file: rekonqui.rc:24 +#. i18n: ectx: Menu (edit) +#: rc.cpp:81 +msgid "&Edit" +msgstr "&Правка" + +#. i18n: file: rekonqui.rc:38 +#. i18n: ectx: Menu (view) +#: rc.cpp:84 +msgid "&View" +msgstr "&Вид" + +#. i18n: file: rekonqui.rc:54 +#. i18n: ectx: Menu (go) +#: rc.cpp:87 +msgid "Hi&story" +msgstr "&Журнал" + +#. i18n: file: rekonqui.rc:62 +#. i18n: ectx: Menu (tools) +#: rc.cpp:93 +msgid "&Tools" +msgstr "" + +#. i18n: file: rekonqui.rc:68 +#. i18n: ectx: Menu (settings) +#: rc.cpp:96 +msgid "&Settings" +msgstr "&Настройки" + +#. i18n: file: rekonqui.rc:73 +#. i18n: ectx: Menu (side_panels) +#: rc.cpp:99 +msgid "Side &Panels" +msgstr "Боковые &панели" + +#. i18n: file: rekonqui.rc:88 +#. i18n: ectx: ToolBar (mainToolBar) +#: rc.cpp:102 +msgid "Main Toolbar" +msgstr "Панель инструментов" + +#. i18n: file: rekonqui.rc:100 +#. i18n: ectx: ToolBar (bookmarksToolBar) +#: rc.cpp:105 +msgid "Bookmark Toolbar" +msgstr "Панель закладок" + +#. i18n: file: settings_fonts.ui:14 +#. i18n: ectx: property (windowTitle), widget (QWidget, fonts) +#: rc.cpp:108 +msgid "Appearance" +msgstr "Внешний вид" + +#. i18n: file: settings_fonts.ui:28 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:114 +msgid "Standard Font" +msgstr "Стандартный шрифт" + +#. i18n: file: settings_fonts.ui:35 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:117 +msgid "Fixed Font" +msgstr "Моноширинный шрифт" + +#. i18n: file: settings_fonts.ui:53 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_2) +#: rc.cpp:120 +msgid "Dimension" +msgstr "Размеры" + +#. i18n: file: settings_fonts.ui:61 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:123 +msgid "Font Size" +msgstr "Размер шрифта:" + +#. i18n: file: settings_general.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:129 +msgid "Places" +msgstr "" + +#. i18n: file: settings_general.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_3) +#: rc.cpp:132 +#, fuzzy +msgid "Home Page:" +msgstr "Адрес:" + +#. i18n: file: settings_general.ui:48 +#. i18n: ectx: property (text), widget (QPushButton, setHomeToCurrentPageButton) +#: rc.cpp:135 +msgid "Set to current page" +msgstr "Использовать текущую страницу" + +#. i18n: file: settings_general.ui:73 +#. i18n: ectx: property (text), widget (QLabel, label_7) +#: rc.cpp:138 +#, fuzzy +msgid "Save downloads to:" +msgstr "&Загружать файлы в:" + +#. i18n: file: settings_general.ui:83 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_downloadToDefaultDir) +#: rc.cpp:141 +msgid "ask where saving downloads" +msgstr "" + +#. i18n: file: settings_general.ui:93 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox_3) +#: rc.cpp:144 +msgid "Tabbed Browsing" +msgstr "Вкладки" + +#. i18n: file: settings_general.ui:99 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_alwaysShowTabBar) +#: rc.cpp:147 +msgid "Always show tab bar" +msgstr "Всегда показывать панель вкладок" + +#. i18n: file: settings_general.ui:106 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_openTabsBack) +#: rc.cpp:150 +msgid "Open tabs in the background" +msgstr "" + +#. i18n: file: settings_privacy.ui:26 +#. i18n: ectx: property (text), widget (QLabel, label_4) +#: rc.cpp:159 +#, fuzzy +msgid "Remove history items:" +msgstr "Удалять записи истории:" + +#. i18n: file: settings_privacy.ui:37 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:162 +#, fuzzy +msgid "After one day" +msgstr "Каждый день" + +#. i18n: file: settings_privacy.ui:42 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:165 +#, fuzzy +msgid "After one week" +msgstr "Каждую неделю" + +#. i18n: file: settings_privacy.ui:47 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:168 +#, fuzzy +msgid "After two weeks" +msgstr "Каждые две недели" + +#. i18n: file: settings_privacy.ui:52 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:171 +#, fuzzy +msgid "After one month" +msgstr "Каждый месяц" + +#. i18n: file: settings_privacy.ui:57 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:174 +#, fuzzy +msgid "After one year" +msgstr "Каждый год" + +#. i18n: file: settings_privacy.ui:62 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_expireHistory) +#: rc.cpp:177 +msgid "Manually" +msgstr "Вручную" + +#. i18n: file: settings_privacy.ui:79 +#. i18n: ectx: property (text), widget (QLabel, label_2) +#: rc.cpp:183 +msgid "Accept Cookies:" +msgstr "Принимать cookie:" + +#. i18n: file: settings_privacy.ui:90 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:186 +msgid "Always" +msgstr "Всегда" + +#. i18n: file: settings_privacy.ui:95 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:189 +msgid "Never" +msgstr "Никогда" + +#. i18n: file: settings_privacy.ui:100 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_acceptCookies) +#: rc.cpp:192 +msgid "Only from sites you visit" +msgstr "Только от посещённых сайтов" + +#. i18n: file: settings_privacy.ui:108 +#. i18n: ectx: property (text), widget (QPushButton, exceptionsButton) +#: rc.cpp:195 +msgid "Exceptions..." +msgstr "Исключения..." + +#. i18n: file: settings_privacy.ui:115 +#. i18n: ectx: property (text), widget (QLabel, label) +#: rc.cpp:198 +msgid "Keep until:" +msgstr "Хранить до:" + +#. i18n: file: settings_privacy.ui:126 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:201 +msgid "They expire" +msgstr "Их истечения" + +#. i18n: file: settings_privacy.ui:131 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:204 +#, fuzzy +msgid "I exit the application" +msgstr "Выхода из программы" + +#. i18n: file: settings_privacy.ui:136 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_keepCookiesUntil) +#: rc.cpp:207 +msgid "At most 90 days" +msgstr "До 90 дней" + +#. i18n: file: settings_privacy.ui:144 +#. i18n: ectx: property (text), widget (QPushButton, cookiesButton) +#: rc.cpp:210 +msgid "Cookies..." +msgstr "" + +#. i18n: file: settings_proxy.ui:19 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_isProxyEnabled) +#: rc.cpp:216 +msgid "Enable proxy" +msgstr "Использовать proxy" + +#. i18n: file: settings_proxy.ui:26 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:219 +msgid "Proxy Settings" +msgstr "Настройки proxy" + +#. i18n: file: settings_proxy.ui:32 +#. i18n: ectx: property (text), widget (QLabel, label_9) +#: rc.cpp:222 +msgid "Type:" +msgstr "Тип:" + +#. i18n: file: settings_proxy.ui:43 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:225 +msgid "SOCKS 5" +msgstr "" + +#. i18n: file: settings_proxy.ui:48 +#. i18n: ectx: property (text), item, widget (QComboBox, kcfg_proxyType) +#: rc.cpp:228 +msgid "HTTP" +msgstr "" + +#. i18n: file: settings_proxy.ui:56 +#. i18n: ectx: property (text), widget (QLabel, label_10) +#: rc.cpp:231 +msgid "Host:" +msgstr "" + +#. i18n: file: settings_proxy.ui:69 +#. i18n: ectx: property (text), widget (QLabel, label_11) +#: rc.cpp:234 +msgid "Port:" +msgstr "Порт:" + +#. i18n: file: settings_webkit.ui:20 +#. i18n: ectx: property (title), widget (QGroupBox, groupBox) +#: rc.cpp:246 +msgid "WebKit Settings" +msgstr "Настройки WebKit" + +#. i18n: file: settings_webkit.ui:26 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_autoLoadImages) +#: rc.cpp:249 +msgid "Auto Load Images" +msgstr "Автоматически загружать картинки" + +#. i18n: file: settings_webkit.ui:40 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_linksIncludedInFocusChain) +#: rc.cpp:252 +msgid "Links included in focus chain" +msgstr "" + +#. i18n: file: settings_webkit.ui:47 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptEnabled) +#: rc.cpp:255 +msgid "Javascript support" +msgstr "Включить Javascript" + +#. i18n: file: settings_webkit.ui:54 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_zoomTextOnly) +#: rc.cpp:258 +msgid "Zoom Text Only" +msgstr "Увеличивать только текст" + +#. i18n: file: settings_webkit.ui:61 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javaEnabled) +#: rc.cpp:261 +msgid "Java support" +msgstr "Включить Java" + +#. i18n: file: settings_webkit.ui:68 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_printElementBackgrounds) +#: rc.cpp:264 +msgid "Print element Backgrounds" +msgstr "" + +#. i18n: file: settings_webkit.ui:75 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_pluginsEnabled) +#: rc.cpp:267 +msgid "Plugins" +msgstr "Плагины" + +#. i18n: file: settings_webkit.ui:82 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineStorageDatabaseEnabled) +#: rc.cpp:270 +msgid "Offline storage Database" +msgstr "" + +#. i18n: file: settings_webkit.ui:89 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanOpenWindows) +#: rc.cpp:273 +msgid "Javascript can open windows" +msgstr "" + +#. i18n: file: settings_webkit.ui:96 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_offlineWebApplicationCacheEnabled) +#: rc.cpp:276 +msgid "Offline Web Application Cache " +msgstr "" + +#. i18n: file: settings_webkit.ui:103 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_javascriptCanAccessClipboard) +#: rc.cpp:279 +msgid "Javascript can access clipboard" +msgstr "" + +#. i18n: file: settings_webkit.ui:110 +#. i18n: ectx: property (text), widget (QCheckBox, kcfg_localStorageDatabaseEnabled) +#: rc.cpp:282 +msgid "Local storage database" +msgstr "" + +#~ msgid "Show side panel" +#~ msgstr "Боковая панель" + +#~ msgid "Print Document" +#~ msgstr "Печать" + +#~ msgid "Location Toolbar" +#~ msgstr "Адресная строка" + +#, fuzzy +#~ msgid "reload" +#~ msgstr "Обновить" + +#, fuzzy +#~ msgid "Clear Location Bar" +#~ msgstr "Отрыть местоположение" + +#~ msgid "Finished loading" +#~ msgstr "Загрузка завершена" + +#~ msgid "Bookmarks" +#~ msgstr "Закладки" + +#~ msgid "Interface" +#~ msgstr "Интерфейс" + +#~ msgid "Startup" +#~ msgstr "Запуск" + +#~ msgid "Downloads" +#~ msgstr "Загрузки" + +#~ msgid "&Always show open/save dialog" +#~ msgstr "&Всегда спрашивать сохранять файл или открывать" + +#~ msgid "This option will work only with Qt 4.5 and higher" +#~ msgstr "Эта опция будет работать с QT4.5 или новее." + +#~ msgid "Show close button on tabs" +#~ msgstr "Показывать кнопку закрытия на вкладках" + +#~ msgid "Show corner buttons on tab bar" +#~ msgstr "Показывать боковые кнопки" + +#~ msgid "Confirm when closing window with multiple tabs" +#~ msgstr "Подтверждать закрытие окна с несколькими вкладками" + +#~ msgid "Enable location bar progress indication" +#~ msgstr "Показывать индикатор загрузки страницы в адресной строке" + +#~ msgid "Secure connection indicator:" +#~ msgstr "Индикатор защищённых соединений:" + +#~ msgid "Progress indicator:" +#~ msgstr "Индикатор прогресса загрузки:" + +#~ msgid "Web Content" +#~ msgstr "Веб-содержимое" + +#~ msgid "Ask destination for each download" +#~ msgstr "Каждый раз спрашивать папку назначения" + +#~ msgid "Use one close tab button" +#~ msgstr "Использовать единую кнопку закрытия вкладок" + +#~ msgid "Location bar" +#~ msgstr "Адресная строка" + +#~ msgid "Tab bar" +#~ msgstr "Вкладки" + +#, fuzzy +#~ msgid "History Dock" +#~ msgstr "Журнал" + +#~ msgid "Copy This Link" +#~ msgstr "Копировать адрес ссылки" + +#~ msgid "Exit rekonq if last tab closed" +#~ msgstr "Выходить из rekonq при закрытии последней вкладки" + +#~ msgid "User Name:" +#~ msgstr "Логин:" + +#~ msgid "private_browsing" +#~ msgstr "режим конфиденциальности" diff --git a/rekonq.SlackBuild b/rekonq.SlackBuild new file mode 100644 index 00000000..2de6ceae --- /dev/null +++ b/rekonq.SlackBuild @@ -0,0 +1,79 @@ +#!/bin/sh +# Slackware build script for $NAME +# Heavily based on the Slackware 12.2 SlackBuild +# Written by Andrea Diamantini - adjam7_AT_gmail_DOT_com + +NAME=rekonq +VERSION=0.0.4 +ARCH=${ARCH:-i486} +BUILD=1ad + +# working dirs +CWD=$(pwd) +TMP=$CWD/tmp +BUILDIR=$TMP/build +PKG=$TMP/package-$NAME + +KDEPREFIX=$(kde4-config --prefix) + +JOBS=${JOBS:-2} # Might not be wanted or needed in some cases + +if [ "$ARCH" = "i486" ]; then + SLKCFLAGS="-O2 -march=i486 -mtune=i686" +elif [ "$ARCH" = "i686" ]; then + SLKCFLAGS="-O3 -march=i686 -pipe -fomit-frame-pointer" +elif [ "$ARCH" = "athlon64" ]; then + SLKCFLAGS="-O2 -march=athlon64 -pipe" +elif [ "$ARCH" = "athlonxp" ]; then + SLKCFLAGS="-O3 -march=athlon-xp -pipe -fomit-frame-pointer" +elif [ "$ARCH" = "x86_64" ]; then + SLKCFLAGS="-O2" +fi + +rm -rf $TMP +mkdir -p $TMP $PKG $BUILDIR + +cd $BUILDIR + +# configure option for $NAME +cmake \ +-DCMAKE_CXX_FLAGS:STRING="$SLKCFLAGS" \ +-DCMAKE_INSTALL_PREFIX=$KDEPREFIX \ +-DCMAKE_BUILD_TYPE=release \ +$CWD + +# Compile the application and install it into the $PKG directory +nice make -j $JOBS || exit 1 +make install DESTDIR=$PKG || exit 1 + +# Strip binaries and libraries +( cd $PKG + find . | xargs file | grep "executable" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true + find . | xargs file | grep "shared object" | grep ELF | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null +) + + +# Copy program documentation into the package +# Also, include the SlackBuild script in the documentation directory +mkdir -p $PKG/usr/doc/$NAME-$VERSION +cp -a AUTHORS COPYING ChangeLog INSTALL NEWS README \ +$PKG/usr/doc/$NAME-$VERSION +cat $CWD/$NAME.SlackBuild > $PKG/usr/doc/$NAME-$VERSION/$NAME.SlackBuild + +# Copy the slack-desc (and a custom doinst.sh if necessary) into ./install +mkdir -p $PKG/install +cat $CWD/data/slack-desc > $PKG/install/slack-desc + +# Make the package; +# If package symlinks need to be created during install *before* +# your custom contents of doinst.sh runs, then add the -p switch to +# the makepkg command below -- see makepkg(8) for details +cd $PKG +/sbin/makepkg -l y -c n $CWD/$NAME-$VERSION-$ARCH-$BUILD.tgz + +# remove unnecessary tmp dir.. +rm -rf $TMP + +# echo "done" +echo "done! Yuppy!!" + diff --git a/scripts/codingstyle.sh b/scripts/codingstyle.sh new file mode 100755 index 00000000..bb3add49 --- /dev/null +++ b/scripts/codingstyle.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# apply rekonq coding style to all cpp and header files in src directory +# +# requirements: installed astyle +# +# rekonq use kdelibs coding style, except for brackets, so while kdelibs coding style +# is +# +# void foo() { +# ... +# } +# +# rekonq uses +# +# void foo() +# { +# ... +# } +# +# I like this way, for me more readable. +# +# Kdelibs coding style is defined in http://techbase.kde.org/Policies/Kdelibs_Coding_Style + + +PWD=$(pwd) + +cd $PWD +cd .. +cd src + +echo "Applying astyle rules..." +astyle \ +--indent=spaces=4 \ +--brackets=break \ +--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 "Removing .orig files..." +rm *.orig + +echo "Done!" + diff --git a/scripts/i18n.sh b/scripts/i18n.sh new file mode 100755 index 00000000..e9b5444d --- /dev/null +++ b/scripts/i18n.sh @@ -0,0 +1,41 @@ +#! /usr/bin/env bash + +BASEDIR="../src/" +PROJECT="rekonq" +BUGADDR="http://sourceforge.net/tracker/?group_id=252277&atid=1126949" +WDIR="../po/" + +cd ${BASEDIR} +echo "Preparing rc files" +find . -name '*.rc' -o -name '*.ui' -o -name '*.kcfg' | sort > ${WDIR}/rcfiles.list +xargs --arg-file=${WDIR}/rcfiles.list extractrc > ${WDIR}/rc.cpp +cd ${WDIR} +echo "Done preparing rc files" + +echo "Extracting messages" +cd ${BASEDIR} +find . -name '*.cpp' -o -name '*.h' -o -name '*.c' | sort > ${WDIR}/infiles.list +echo "rc.cpp" >> ${WDIR}/infiles.list +cd ${WDIR} +xgettext --from-code=UTF-8 -C -kde -ci18n -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -ktr2i18n:1 \ + -kI18N_NOOP:1 -kI18N_NOOP2:1c,2 -kaliasLocale -kki18n:1 -kki18nc:1c,2 -kki18np:1,2 -kki18ncp:1c,2,3 \ + --msgid-bugs-address="${BUGADDR}" \ + --files-from=infiles.list -D ${BASEDIR} -D ${WDIR} -o ${PROJECT}.pot || { echo "error while calling xgettext. aborting."; exit 1; } +echo "Done extracting messages" + +echo "Merging translations" +catalogs=`find . -name '*.po'` +for cat in $catalogs; do + echo $cat + msgmerge -o $cat.new $cat ${PROJECT}.pot + mv $cat.new $cat +done +echo "Done merging translations" + +echo "Cleaning up" +cd ${WDIR} +rm rcfiles.list +rm infiles.list +rm rc.cpp +echo "Done" + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 00000000..a64cc747 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,63 @@ +SET( rekonq_SRCS + autosaver.cpp + application.cpp + mainwindow.cpp + mainview.cpp + tabbar.cpp + cookiejar.cpp + edittableview.cpp + edittreeview.cpp + history.cpp + download.cpp + bookmarks.cpp + modelmenu.cpp + networkaccessmanager.cpp + urlbar.cpp + findbar.cpp + searchbar.cpp + settings.cpp + webview.cpp + main.cpp + sidepanel.cpp + panelhistory.cpp + lineedit.cpp + stackedurlbar.cpp +) + +KDE4_ADD_UI_FILES( rekonq_SRCS + cookies.ui + cookiesexceptions.ui + history.ui + password.ui + proxy.ui + settings_general.ui + settings_fonts.ui + settings_privacy.ui + settings_proxy.ui + settings_webkit.ui + ) + +KDE4_ADD_KCFG_FILES( rekonq_SRCS rekonq.kcfgc ) + +### ------------------------------------------ + +ADD_DEFINITIONS( ${KDE4_DEFINITIONS} ) + +KDE4_ADD_EXECUTABLE( rekonq ${rekonq_SRCS} ) + +TARGET_LINK_LIBRARIES( rekonq + ${QT_LIBRARIES} + ${QT_QTNETWORK_LIBRARY} + ${QT_QTWEBKIT_LIBRARY} + ${QT_QTUITOOLS_LIBRARY} + ${KDE4_KUTILS_LIBS} + ${KDE4_KDEUI_LIBS} + ${KDE4_KIO_LIBS} +) + +INSTALL( TARGETS rekonq ${INSTALL_TARGETS_DEFAULT_ARGS} ) + +########### install files ############### + +INSTALL( FILES rekonq.kcfg DESTINATION ${KCFG_INSTALL_DIR} ) +INSTALL( FILES rekonqui.rc DESTINATION ${DATA_INSTALL_DIR}/rekonq ) diff --git a/src/application.cpp b/src/application.cpp new file mode 100644 index 00000000..ec24691e --- /dev/null +++ b/src/application.cpp @@ -0,0 +1,206 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + +// Self Includes +#include "application.h" +#include "application.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "mainwindow.h" +#include "cookiejar.h" +#include "history.h" +#include "networkaccessmanager.h" +#include "mainview.h" +#include "webview.h" +#include "download.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include + + +QPointer Application::s_historyManager; +QPointer Application::s_networkAccessManager; +QPointer Application::s_downloadManager; +QPointer Application::s_bookmarkProvider; + + + +Application::Application() + : KUniqueApplication() +{ +} + + +Application::~Application() +{ + delete m_mainWindow; + delete s_bookmarkProvider; + delete s_networkAccessManager; + delete s_historyManager; +} + + +int Application::newInstance() +{ + KCmdLineArgs::setCwd(QDir::currentPath().toUtf8()); + KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); + + if (!m_mainWindow) + { + m_mainWindow = new MainWindow(); + + m_mainWindow->setObjectName("MainWindow"); + setWindowIcon(KIcon("rekonq")); + + m_mainWindow->show(); + + QTimer::singleShot(0, this, SLOT(postLaunch())); + } + + if (args->count() > 0) + { + for (int i = 0; i < args->count(); ++i) + { + KUrl url = MainWindow::guessUrlFromString(args->arg(i)); + newWebView(); + mainWindow()->loadUrl(url); + } + args->clear(); + } + else + { + newWebView(); + mainWindow()->slotHome(); + } + + return 0; +} + + +Application *Application::instance() +{ + return (static_cast(QCoreApplication::instance())); +} + + +void Application::postLaunch() +{ + // set Icon Database Path to store "favicons" associated with web sites + QString directory = KStandardDirs::locateLocal("cache" , "" , true); + if (directory.isEmpty()) + { + directory = QDir::homePath() + QLatin1String("/.") + QCoreApplication::applicationName(); + } + QWebSettings::setIconDatabasePath(directory); + + Application::historyManager(); +} + + + +void Application::slotSaveConfiguration() const +{ + ReKonfig::self()->writeConfig(); +} + + +MainWindow *Application::mainWindow() +{ + return m_mainWindow; +} + + +WebView *Application::newWebView(Rekonq::OpenType type) +{ + return m_mainWindow->mainView()->newWebView(type); +} + + +CookieJar *Application::cookieJar() +{ + return (CookieJar*)networkAccessManager()->cookieJar(); +} + + +NetworkAccessManager *Application::networkAccessManager() +{ + if (!s_networkAccessManager) + { + s_networkAccessManager = new NetworkAccessManager(); + s_networkAccessManager->setCookieJar(new CookieJar); + } + return s_networkAccessManager; +} + + +HistoryManager *Application::historyManager() +{ + if (!s_historyManager) + { + s_historyManager = new HistoryManager(); + QWebHistoryInterface::setDefaultInterface(s_historyManager); + } + return s_historyManager; +} + + +DownloadManager *Application::downloadManager() +{ + if (!s_downloadManager) + { + s_downloadManager = new DownloadManager(); + } + return s_downloadManager; +} + + +BookmarkProvider *Application::bookmarkProvider() +{ + if (!s_bookmarkProvider) + { + s_bookmarkProvider = new BookmarkProvider(); + } + return s_bookmarkProvider; +} + + +KIcon Application::icon(const KUrl &url) const +{ + KIcon icon = KIcon(QWebSettings::iconForUrl(url)); + if (icon.isNull()) + { + icon = KIcon("kde"); + } + return icon; +} diff --git a/src/application.h b/src/application.h new file mode 100644 index 00000000..61f4af81 --- /dev/null +++ b/src/application.h @@ -0,0 +1,115 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef APPLICATION_H +#define APPLICATION_H + +// Qt Includes +#include + +// KDE Includes +#include +#include +#include +#include +#include +#include +#include + + +// Forward Declarations +class KIcon; +class KUrl; +class BookmarkProvider; +class CookieJar; +class DownloadManager; +class HistoryManager; +class MainWindow; +class NetworkAccessManager; +class WebView; + + +namespace Rekonq +{ + /** + * @short Open link options + * Different modes of opening new tab + */ + enum OpenType + { + Default, ///< open url according to users settings + New, ///< open url in new tab and make it current + Background ///< open url in new tab in background + }; +} + + +/** + * + */ +class Application : public KUniqueApplication +{ + Q_OBJECT + +public: + Application(); + ~Application(); + int newInstance(); + static Application *instance(); + + MainWindow *mainWindow(); + WebView* newWebView(Rekonq::OpenType type = Rekonq::Default); + + KIcon icon(const KUrl &url) const; + + static HistoryManager *historyManager(); + static CookieJar *cookieJar(); + static NetworkAccessManager *networkAccessManager(); + static DownloadManager *downloadManager(); + static BookmarkProvider *bookmarkProvider(); + +public slots: + /** + * Save application's configuration + * @see ReKonfig::self()->writeConfig(); + */ + void slotSaveConfiguration() const; + + +private slots: + + /** + * Any actions that can be delayed until the window is visible + */ + void postLaunch(); + + +private: + static QPointer s_historyManager; + static QPointer s_networkAccessManager; + static QPointer s_downloadManager; + static QPointer s_bookmarkProvider; + + QPointer m_mainWindow; +}; + +#endif // APPLICATION_H diff --git a/src/autosaver.cpp b/src/autosaver.cpp new file mode 100644 index 00000000..25bf9016 --- /dev/null +++ b/src/autosaver.cpp @@ -0,0 +1,90 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +// Local Includes +#include "autosaver.h" + +// KDE Includes +#include + +// Qt Includes +#include + + +#define AUTOSAVE_IN 1000 * 3 // seconds +#define MAXWAIT 1000 * 15 // seconds + + +AutoSaver::AutoSaver(QObject *parent) : QObject(parent) +{ + Q_ASSERT(parent); +} + + +AutoSaver::~AutoSaver() +{ + if (m_timer.isActive()) + kWarning() << "AutoSaver: still active when destroyed, changes not saved."; +} + + +void AutoSaver::changeOccurred() +{ + if (m_firstChange.isNull()) + m_firstChange.start(); + + if (m_firstChange.elapsed() > MAXWAIT) + { + saveIfNeccessary(); + } + else + { + m_timer.start(AUTOSAVE_IN, this); + } +} + + +void AutoSaver::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == m_timer.timerId()) + { + saveIfNeccessary(); + } + else + { + QObject::timerEvent(event); + } +} + + +void AutoSaver::saveIfNeccessary() +{ + if (!m_timer.isActive()) + return; + m_timer.stop(); + m_firstChange = QTime(); + if (!QMetaObject::invokeMethod(parent(), "save", Qt::DirectConnection)) + { + kWarning() << "AutoSaver: error invoking slot save() on parent"; + } +} + diff --git a/src/autosaver.h b/src/autosaver.h new file mode 100644 index 00000000..8931da13 --- /dev/null +++ b/src/autosaver.h @@ -0,0 +1,55 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef AUTOSAVER_H +#define AUTOSAVER_H + +#include + +/* + This class will call the save() slot on the parent object when the parent changes. + It will wait several seconds after changed() to combining multiple changes and + prevent continuous writing to disk. + */ +class AutoSaver : public QObject +{ + Q_OBJECT + +public: + AutoSaver(QObject *parent); + ~AutoSaver(); + void saveIfNeccessary(); + +public slots: + void changeOccurred(); + +protected: + void timerEvent(QTimerEvent *event); + +private: + QBasicTimer m_timer; + QTime m_firstChange; + +}; + +#endif // AUTOSAVER_H + diff --git a/src/bookmarks.cpp b/src/bookmarks.cpp new file mode 100644 index 00000000..c7f4da98 --- /dev/null +++ b/src/bookmarks.cpp @@ -0,0 +1,278 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + +// Self Includes +#include "bookmarks.h" +#include "bookmarks.moc" + +// Local Includes +#include "mainwindow.h" +#include "webview.h" +#include "application.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include + + +BookmarkOwner::BookmarkOwner(QObject *parent) + : QObject(parent) + , KBookmarkOwner() +{ +} + + +void BookmarkOwner::openBookmark(const KBookmark & bookmark, + Qt::MouseButtons mouseButtons, + Qt::KeyboardModifiers keyboardModifiers) +{ + Q_UNUSED(mouseButtons) + Q_UNUSED(keyboardModifiers) + + emit openUrl(bookmark.url()); +} + + +QString BookmarkOwner::currentUrl() const +{ + return Application::instance()->mainWindow()->currentTab()->url().url(); +} + + +QString BookmarkOwner::currentTitle() const +{ + return Application::instance()->mainWindow()->currentTab()->title(); +} + + +void BookmarkOwner::openFolderinTabs(const KBookmarkGroup &bm) +{ + QList urlList = bm.groupUrlList(); + QList::iterator url; + Application* app = Application::instance(); + for (url = urlList.begin(); url != urlList.end(); ++url) + { + app->newWebView(); + app->mainWindow()->loadUrl(*url); + } +} + + +// ------------------------------------------------------------------------------------------------------ + + +BookmarkMenu::BookmarkMenu(KBookmarkManager *manager, + KBookmarkOwner *owner, + KMenu *menu, + KActionCollection* actionCollection) + : KBookmarkMenu(manager, owner, menu, actionCollection) + +{ + actionCollection->addAction(KStandardAction::AddBookmark, + QLatin1String("add_bookmark_payload"), + this, SLOT(slotAddBookmark())); + +} + +BookmarkMenu::~BookmarkMenu() +{ +} + + +KMenu *BookmarkMenu::viewContextMenu(QAction *action) +{ + return contextMenu(action); +} + + +void BookmarkMenu::slotAddBookmark() +{ + KAction *action = qobject_cast(sender()); + if (action && !action->data().isNull()) + { + KBookmarkGroup parentBookmark = manager()->findByAddress(parentAddress()).toGroup(); + /// TODO Add bookmark Icon + parentBookmark.addBookmark(owner()->currentTitle(), action->data().toUrl()); + manager()->emitChanged(); + return; + } + + KBookmarkMenu::slotAddBookmark(); +} + + +// ------------------------------------------------------------------------------------------------------ + + +BookmarkProvider::BookmarkProvider(QWidget *parent) + : QWidget(parent) + , m_manager(0) + , m_owner(0) + , m_menu(new KMenu(this)) + , m_actionCollection(new KActionCollection(this)) + , m_bookmarkMenu(0) + , m_bookmarkToolBar(0) +{ + KUrl bookfile = KUrl("~/.kde/share/apps/konqueror/bookmarks.xml"); // share konqueror bookmarks + + if (!QFile::exists(bookfile.path())) + { + bookfile = KUrl("~/.kde4/share/apps/konqueror/bookmarks.xml"); + if (!QFile::exists(bookfile.path())) + { + QString bookmarksDefaultPath = KStandardDirs::locate("appdata" , "defaultbookmarks.xbel"); + kWarning() << bookmarksDefaultPath; + QFile bkms(bookmarksDefaultPath); + QString bookmarksPath = KStandardDirs::locateLocal("appdata", "bookmarks.xml", true); + bookmarksPath.replace("rekonq", "konqueror"); + bkms.copy(bookmarksPath); + + bookfile = KUrl(bookmarksPath); + } + } + m_manager = KBookmarkManager::managerForExternalFile(bookfile.path()); + connect(m_manager, SIGNAL(changed(const QString &, const QString &)), + this, SLOT(slotBookmarksChanged(const QString &, const QString &))); + + // setup menu + m_owner = new BookmarkOwner(this); + connect(m_owner, SIGNAL(openUrl(const KUrl&)), this, SIGNAL(openUrl(const KUrl&))); + m_bookmarkMenu = new BookmarkMenu(m_manager, m_owner, m_menu, m_actionCollection); + + // setup toolbar + setupToolBar(); +} + + +BookmarkProvider::~BookmarkProvider() +{ + delete m_bookmarkToolBar; + delete m_bookmarkMenu; + delete m_actionCollection; + delete m_menu; + delete m_owner; + delete m_manager; +} + + +void BookmarkProvider::setupToolBar() +{ + m_bookmarkToolBar = new KToolBar(this); + m_bookmarkToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + m_bookmarkToolBar->setIconDimensions(16); + m_bookmarkToolBar->setAcceptDrops(true); + m_bookmarkToolBar->setContentsMargins(0, 0, 0, 0); + m_bookmarkToolBar->setMinimumHeight(16); + m_bookmarkToolBar->setContextMenuPolicy(Qt::CustomContextMenu); + connect(m_bookmarkToolBar, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(contextMenu(const QPoint &))); + + slotBookmarksChanged("", ""); +} + + +void BookmarkProvider::slotBookmarksChanged(const QString &group, const QString &caller) +{ + Q_UNUSED(group) + Q_UNUSED(caller) + + if (!m_bookmarkToolBar) + { + kWarning() << "There is no bookmark toolbar"; + return; + } + + KActionCollection bookmarkCollection(this); + + KBookmarkGroup toolBarGroup = m_manager->toolbar(); + if (toolBarGroup.isNull()) + return; + + KBookmark bookmark = toolBarGroup.first(); + while (!bookmark.isNull()) + { + if (!bookmark.isGroup()) + { + KAction *action = new KBookmarkAction(bookmark, m_owner, this); + QString text = bookmark.address(); + bookmarkCollection.addAction(text, action); + } + bookmark = toolBarGroup.next(bookmark); + } + m_bookmarkToolBar->clear(); + m_bookmarkToolBar->addActions(bookmarkCollection.actions()); +} + + +QAction *BookmarkProvider::actionByName(const QString &name) +{ + QAction *action = m_actionCollection->action(name); + if (action) + return action; + /* else */ + kWarning() << "Action named: " << name << " not found, returning empty action."; + return new QAction(this); // return empty object instead of NULL pointer +} + + +void BookmarkProvider::contextMenu(const QPoint &point) +{ + KAction* action = dynamic_cast(m_bookmarkToolBar->actionAt(point)); + if (!action) + return; + KMenu *menu = m_bookmarkMenu->viewContextMenu(action); + menu->popup(m_bookmarkToolBar->mapToGlobal(point)); +} + + +KActionMenu* BookmarkProvider::bookmarkActionMenu() +{ + KActionMenu *bookmarkActionMenu = new KActionMenu(this); + bookmarkActionMenu->setMenu(m_menu); + bookmarkActionMenu->setText(i18n("&Bookmarks")); + return bookmarkActionMenu; +} + + +KAction* BookmarkProvider::bookmarkToolBarAction() +{ + KAction *bookmarkToolBarAction = new KAction(this); + bookmarkToolBarAction->setDefaultWidget(m_bookmarkToolBar); // The ownership is transferred to action + bookmarkToolBarAction->setText(i18n("Bookmarks Bar")); + bookmarkToolBarAction->setShortcutConfigurable(false); + return bookmarkToolBarAction; +} + diff --git a/src/bookmarks.h b/src/bookmarks.h new file mode 100644 index 00000000..d7213cb7 --- /dev/null +++ b/src/bookmarks.h @@ -0,0 +1,238 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef BOOKMARKS_H +#define BOOKMARKS_H + +// Qt Includes +#include + +// KDE Includes +#include + +// Forward Declarations +class BookmarkProvider; + +class KAction; +class KActionCollection; +class KActionMenu; +class KUrl; +class KToolBar; +class KBookmarkManager; + + +/** + * Reimplementation of KBookmarkOwner, this class allows to manage + * bookmarks as actions + * + */ +class BookmarkOwner : public QObject , public KBookmarkOwner +{ + Q_OBJECT + +public: + + /** + * @short The class constructor. + * + * @param parent the pointer parent Bookmark provider. We need it + * to get pointer to MainWindow + */ + BookmarkOwner(QObject *parent = 0); + virtual ~BookmarkOwner() {} + + /** + * This function is called when a bookmark is selected and belongs to + * the ancestor class. + * This method actually emits signal to load bookmark's url. + * + * @param bookmark the bookmark to open + * @param mouseButtons the mouse buttons clicked to select the bookmark + * @param keyboardModifiers the keyboard modifiers pushed when the bookmark was selected + */ + virtual void openBookmark(const KBookmark &bookmark, + Qt::MouseButtons mouseButtons, + Qt::KeyboardModifiers keyboardModifiers); + + + /** + * this method, from KBookmarkOwner interface, allows to add the current page + * to the bookmark list, returning the URL page as QString. + * + * @return the current page's URL + */ + virtual QString currentUrl() const; + + /** + * this method, from KBookmarkOwner interface, allows to add the current page + * to the bookmark list, returning the title's page as QString. + * + * @return the current page's title + */ + virtual QString currentTitle() const; + + /** + * This function returns whether the owner supports tabs. + */ + virtual bool supportsTabs() const + { + return true; + } + + /** + * Called if the user wants to open every bookmark in this folder in a new tab. + * The default implementation does nothing. + * This is only called if supportsTabs() returns true + */ + virtual void openFolderinTabs(const KBookmarkGroup &bm); + +signals: + /** + * This signal is emitted when an url has to be loaded + * + * @param url the URL to load + * + */ + void openUrl(const KUrl &); + +private: + +}; + +// ------------------------------------------------------------------------------ + + +#include + + +/** + * This class represent the rekonq bookmarks menu. + * It's just a simple class inherited from KBookmarkMenu + * + */ +class BookmarkMenu : public KBookmarkMenu +{ + Q_OBJECT + +public: + BookmarkMenu(KBookmarkManager* manager, + KBookmarkOwner* owner, + KMenu* menu, + KActionCollection* actionCollection); + ~BookmarkMenu(); + + virtual KMenu *viewContextMenu(QAction* action); + +protected slots: + void slotAddBookmark(); + +}; + + +// ------------------------------------------------------------------------------ + + +/** + * This class represent the interface to rekonq bookmarks system. + * All rekonq needs (Bookmarks Menu, Bookmarks Toolbar) is provided + * from this class. + * So it implements code to have each one + * + * + */ +class BookmarkProvider : public QWidget +{ + Q_OBJECT + +public: + /** + * @short Class constructor. + * Connect BookmarksProvider with bookmarks source + * (actually konqueror's bookmarks) + * @param parent The MainWindow to provide bookmarks objects + * + */ + BookmarkProvider(QWidget* parent = 0); + ~BookmarkProvider(); + + /** + * @short Get the Bookmarks Menu Action + * @return the Bookmarks Menu + */ + KActionMenu *bookmarkActionMenu(); + + + /** + * @short Get the Bookmarks Toolbar Action + * @return the Bookmarks Toolbar Action + */ + KAction *bookmarkToolBarAction(); + + + /** + * @short Get action by name + * This method returns poiner bookmark action of given name. + * @pre m_actionCollection != NULL + * @param name Name of action you want to get + * @return It returns actions if one exists or empty object + */ + QAction *actionByName(const QString &name); + +signals: + /** + * @short This signal is emitted when an url has to be loaded + * + * @param url the URL to load + */ + void openUrl(const KUrl &url); + + +public slots: + /** + * @short Opens the context menu on given position + * @param point Point on whitch you want to open this menu + */ + void contextMenu(const QPoint &point); + + /** + * @short Waits for signal that the group with the address has been modified by the caller. + * Waits for signal that the group (or any of its children) with the address + * @p groupAddress (e.g. "/4/5") has been modified by the caller @p caller. + * + * @param group bookmark group adress + * @param caller caller that modified the bookmarks + * @see KBookmarkManager::changed + */ + void slotBookmarksChanged(const QString &group, const QString &caller); + +private: + void setupToolBar(); + + KBookmarkManager *m_manager; + BookmarkOwner *m_owner; + KMenu *m_menu; + KActionCollection *m_actionCollection; + BookmarkMenu *m_bookmarkMenu; + KToolBar *m_bookmarkToolBar; +}; + +#endif diff --git a/src/cookiejar.cpp b/src/cookiejar.cpp new file mode 100644 index 00000000..de7d7d7e --- /dev/null +++ b/src/cookiejar.cpp @@ -0,0 +1,841 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Domrachev Alexandr +* +* +* 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, 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. +* +* ============================================================ */ + + + +// Self Includes +#include "cookiejar.h" +#include "cookiejar.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "autosaver.h" + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include +#include +#include + + +static const unsigned int JAR_VERSION = 23; + + +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) + { + kWarning() << "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; +} + + +CookieJar::CookieJar(QObject *parent) + : QNetworkCookieJar(parent) + , m_loaded(false) + , m_saveTimer(new AutoSaver(this)) + , m_acceptCookies(AcceptOnlyFromSitesNavigatedTo) +{ + load(); +} + + +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 + QString filepath = KStandardDirs::locateLocal("appdata", "cookies.ini"); + qRegisterMetaTypeStreamOperators >("QList"); + QSettings cookieSettings(filepath, 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(); + + save(); +} + + +void CookieJar::loadSettings() +{ + int canAcceptCookies = ReKonfig::acceptCookies(); + + switch (canAcceptCookies) + { + case 0: + m_acceptCookies = AcceptAlways; + break; + case 1: + m_acceptCookies = AcceptNever; + break; + case 2: + default: + m_acceptCookies = AcceptOnlyFromSitesNavigatedTo; + break; + } + + int canKeepCookiesUntil = ReKonfig::keepCookiesUntil(); + + switch (canKeepCookiesUntil) + { + default: + case 0: + m_keepCookies = KeepUntilExpire; + break; + case 1: + m_keepCookies = KeepUntilExit; + setAllCookies(QList()); + break; + case 2: + m_keepCookies = KeepUntilTimeLimit; + break; + } + + m_loaded = true; + emit cookiesChanged(); +} + + +void CookieJar::save() +{ + if (!m_loaded) + return; + purgeOldCookies(); + + QString filepath = KStandardDirs::locateLocal("appdata", "cookies.ini"); + QSettings cookieSettings(filepath, 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 + int n; + switch (m_acceptCookies) + { + case AcceptAlways: + n = 0; + break; + case AcceptNever: + n = 1; + break; + case AcceptOnlyFromSitesNavigatedTo: + default: + n = 2; + break; + } + ReKonfig::setAcceptCookies(n); + + + switch (m_keepCookies) + { + default: + case KeepUntilExpire: + n = 0; + break; + case KeepUntilExit: + n = 1; + break; + case KeepUntilTimeLimit: + n = 2; + break; + } + ReKonfig::setKeepCookiesUntil(n); +} + + +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; + } + + return QNetworkCookieJar::cookiesForUrl(url); +} + + +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(); + cookies += cookie; + setAllCookies(cookies); + addedCookies = true; + } +#if 0 + else + kWarning() << "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 i18n("Website"); + case 1: + return i18n("Name"); + case 2: + return i18n("Path"); + case 3: + return i18n("Secure"); + case 4: + return i18n("Expires"); + case 5: + return i18n("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(removeOne())); + 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 i18n("Website"); + case 1: + return i18n("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 i18n("Allow"); + } + } + row = row - m_allowedCookies.count(); + if (row < m_blockedCookies.count()) + { + switch (index.column()) + { + case 0: + return m_blockedCookies.at(row); + case 1: + return i18n("Block"); + } + } + row = row - m_blockedCookies.count(); + if (row < m_sessionCookies.count()) + { + switch (index.column()) + { + case 0: + return m_sessionCookies.at(row); + case 1: + return i18n("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(removeOne())); + 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/cookiejar.h b/src/cookiejar.h new file mode 100644 index 00000000..27071b6d --- /dev/null +++ b/src/cookiejar.h @@ -0,0 +1,200 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Domrachev Alexandr +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef COOKIEJAR_H +#define COOKIEJAR_H + + +// KDE Includes +#include + +// Qt Includes +#include +#include +#include +#include + +// Forward Declarations +class QSortFilterProxyModel; +class QKeyEvent; +class AutoSaver; + + +class CookieJar : public QNetworkCookieJar +{ + friend class CookieModel; + Q_OBJECT + Q_PROPERTY(AcceptPolicy acceptPolicy READ acceptPolicy WRITE setAcceptPolicy) + Q_PROPERTY(KeepPolicy keepPolicy READ keepPolicy WRITE setKeepPolicy) + Q_PROPERTY(QStringList blockedCookies READ blockedCookies WRITE setBlockedCookies) + Q_PROPERTY(QStringList allowedCookies READ allowedCookies WRITE setAllowedCookies) + Q_PROPERTY(QStringList allowForSessionCookies READ allowForSessionCookies WRITE setAllowForSessionCookies) + Q_ENUMS(KeepPolicy) + Q_ENUMS(AcceptPolicy) + +signals: + void cookiesChanged(); + +public: + enum AcceptPolicy + { + AcceptAlways, + AcceptNever, + AcceptOnlyFromSitesNavigatedTo + }; + + enum KeepPolicy + { + KeepUntilExpire, + KeepUntilExit, + KeepUntilTimeLimit + }; + + CookieJar(QObject *parent = 0); + ~CookieJar(); + + QList cookiesForUrl(const QUrl &url) const; + bool setCookiesFromUrl(const QList &cookieList, const QUrl &url); + + AcceptPolicy acceptPolicy() const; + void setAcceptPolicy(AcceptPolicy policy); + + KeepPolicy keepPolicy() const; + void setKeepPolicy(KeepPolicy policy); + + QStringList blockedCookies() const; + QStringList allowedCookies() const; + QStringList allowForSessionCookies() const; + + void setBlockedCookies(const QStringList &list); + void setAllowedCookies(const QStringList &list); + void setAllowForSessionCookies(const QStringList &list); + +public slots: + void clear(); + void loadSettings(); + +private slots: + void save(); + +private: + void purgeOldCookies(); + void load(); + bool m_loaded; + AutoSaver *m_saveTimer; + + AcceptPolicy m_acceptCookies; + KeepPolicy m_keepCookies; + + 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" + +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; +}; + + +// ----------------------------------------------------------------------------------------------------------------- + + +#include "ui_cookiesexceptions.h" + +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; +}; + +#endif // COOKIEJAR_H diff --git a/src/cookies.ui b/src/cookies.ui new file mode 100644 index 00000000..49ad3a96 --- /dev/null +++ b/src/cookies.ui @@ -0,0 +1,107 @@ + + + CookiesDialog + + + + 0 + 0 + 550 + 370 + + + + Cookies + + + + + + Qt::Horizontal + + + + 252 + 20 + + + + + + + + + + + + + + + + &Remove + + + + + + + Remove &All Cookies + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QDialogButtonBox::Ok + + + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+ + EditTableView + QTableView +
edittableview.h
+
+
+ + + + buttonBox + accepted() + CookiesDialog + accept() + + + 472 + 329 + + + 461 + 356 + + + + +
diff --git a/src/cookiesexceptions.ui b/src/cookiesexceptions.ui new file mode 100644 index 00000000..de59eee0 --- /dev/null +++ b/src/cookiesexceptions.ui @@ -0,0 +1,179 @@ + + CookiesExceptionsDialog + + + + 0 + 0 + 466 + 446 + + + + Cookie Exceptions + + + + + + New Exception + + + + + + + + Domain: + + + + + + + + + + + + + + Qt::Horizontal + + + + 81 + 25 + + + + + + + + false + + + Block + + + + + + + false + + + Allow For Session + + + + + + + false + + + Allow + + + + + + + + + + + + Exceptions + + + + + + Qt::Horizontal + + + + 252 + 20 + + + + + + + + + + + + + + &Remove + + + + + + + Remove &All + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + + + + + + EditTableView + QTableView +
edittableview.h
+
+
+ + + + buttonBox + accepted() + CookiesExceptionsDialog + accept() + + + 381 + 428 + + + 336 + 443 + + + + +
diff --git a/src/download.cpp b/src/download.cpp new file mode 100644 index 00000000..9489b270 --- /dev/null +++ b/src/download.cpp @@ -0,0 +1,224 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007 Lukas Appelhans +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* Copyright (C) 2009 by Domrachev Alexandr +* +* +* 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, 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. +* +* ============================================================ */ + + +// local Includes +#include "download.h" +#include "download.moc" + +// KDE Includes +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include + +// Local Includes +#include "application.h" +#include "mainwindow.h" + + +DownloadManager::DownloadManager() + : QObject() +{ +} + + +DownloadManager::~DownloadManager() +{ + foreach(Download *download, m_downloads) + { + // cancel all unfinished downloads + download->cancel(); + delete download; + } +} + + +void DownloadManager::newDownload(const KUrl &srcUrl, const KUrl &destUrl) +{ + KUrl destination = destUrl; + Download::DownloadType type; + + KSharedPtr mimeType = KMimeType::findByPath(srcUrl.prettyUrl()); + + QString typeText = KMimeType::extractKnownExtension(srcUrl.fileName()); + typeText += " (" + mimeType->name() + ")"; + + int answer = KMessageBox::questionYesNoCancel(NULL, + i18n("Download '%1'?\n""Type: %2", srcUrl.prettyUrl(), typeText), + i18n("Download '%1'...", srcUrl.fileName()), + KStandardGuiItem::save(), + KStandardGuiItem::open(), + KStandardGuiItem::cancel(), + "showOpenSaveDownloadDialog" + ); + + switch (answer) + { + case KMessageBox::Cancel: + return; + break; + + case KMessageBox::Yes: // ----- SAVE + // if destination is empty than ask for download path (if showOpenSaveDownloadDialog setting enabled) + if (destination.isEmpty()) + { + destination = downloadDestination(srcUrl.fileName()); + } + type = Download::Save; + break; + + case KMessageBox::No: // ----- OPEN + // Download file to tmp dir + destination.setDirectory(KStandardDirs::locateLocal("tmp", "", true)); + destination.addPath(srcUrl.fileName()); + type = Download::Open; + break; + + default: + // impossible + break; + }; + + // if user canceled download than abort + if (destination.isEmpty()) + return; + + Download *download = new Download(srcUrl, destination, type); + connect(download, SIGNAL(downloadFinished(int)), this, SLOT(slotDownloadFinished(int))); + m_downloads.append(download); +} + + +const QList &DownloadManager::downloads() const +{ + return m_downloads; +}; + + +KUrl DownloadManager::downloadDestination(const QString &filename) +{ + KUrl destination = ReKonfig::downloadDir(); + if (destination.isEmpty()) + destination = KGlobalSettings::downloadPath(); + destination.addPath(filename); + + if (!ReKonfig::downloadToDefaultDir()) + { + destination = KFileDialog::getSaveUrl(destination); + // if user canceled the download return empty url + if (destination.isEmpty()) + return KUrl(); + } + return destination; +} + + +void DownloadManager::slotDownloadFinished(int errorCode) +{ + Q_UNUSED(errorCode) + + // if sender exists and list contains it - (open and) delete it + Download *download = qobject_cast(sender()); + if (download && m_downloads.contains(download)) + { + if (download->type() == Download::Open) + { + KSharedPtr mimeType = KMimeType::findByPath(download->destUrl().prettyUrl()); + KRun::runUrl(download->destUrl(), mimeType->name(), NULL, true); + } + disconnect(download, SIGNAL(downloadFinished(int)), this, SLOT(slotDownloadFinished(int))); + int index = m_downloads.indexOf(download); + delete m_downloads.takeAt(index); + return; + } + kWarning() << "Could not find download or invalid sender. Sender:" << sender(); +} + + +//---- + +#include +#include +#include + + +Download::Download(const KUrl &srcUrl, const KUrl &destUrl, DownloadType type) + : QObject() + , m_srcUrl(srcUrl) + , m_destUrl(destUrl) + , m_type(type) +{ + Q_ASSERT(!m_srcUrl.isEmpty()); + Q_ASSERT(!m_destUrl.isEmpty()); + kDebug() << "DownloadFile: " << m_srcUrl.url() << " to dest: " << m_destUrl.url(); + + m_copyJob = KIO::file_copy(m_srcUrl, m_destUrl); + connect(m_copyJob, SIGNAL(result(KJob *)), SLOT(slotResult(KJob *))); +} + + +Download::~Download() +{ +} + + +void Download::cancel() +{ + bool result = m_copyJob->kill(KJob::EmitResult); + Q_ASSERT(result); +} + + +void Download::slotResult(KJob *job) +{ + switch (job->error()) + { + case 0: //The download has finished + { + kDebug() << "Downloading successfully finished: " << m_destUrl.url(); + break; + } + case KIO::ERR_FILE_ALREADY_EXIST: + { + kWarning() << "ERROR - File already exists"; + break; + } + case KIO::ERR_USER_CANCELED: + { + kWarning() << "ERROR - User canceled the downlaod"; + break; + } + default: + kWarning() << "We are sorry to say you, that there were errors while downloading :("; + break; + } + + // inform the world + emit downloadFinished(job->error()); +} diff --git a/src/download.h b/src/download.h new file mode 100644 index 00000000..0ad01e69 --- /dev/null +++ b/src/download.h @@ -0,0 +1,141 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007 Lukas Appelhans +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* Copyright (C) 2009 by Domrachev Alexandr +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef DOWNLOAD_H +#define DOWNLOAD_H + +// Auto Includes +#include "rekonq.h" + +// KDE Includes +#include + +// Qt Includes +#include + +// Forward Declarations +class KJob; + +namespace KIO +{ +class Job; +} + + +/** + * This class lets rekonq to download an object from the network. + * Creating a new object, you can continue downloading a file also + * when rekonq is closed. + * + */ +class Download : public QObject +{ + Q_OBJECT + +public: + enum DownloadType { Save, Open }; + + /** + * Class constructor. This is the unique method we need to + * use this class. In fact Download class needs to know just + * "where" catch the file to download and where it has to put it + * + * @param srcUrl the source url + * @param destUrl the destination url + * + */ + Download(const KUrl &srcUrl, const KUrl &destUrl, DownloadType type); + + /** + * class destructor + */ + ~Download(); + + KUrl srcUrl() const + { + return m_srcUrl; + } + KUrl destUrl() const + { + return m_destUrl; + } + DownloadType type() const + { + return m_type; + } + void cancel(); + +signals: + void downloadFinished(int errorCode); + +private slots: + void slotResult(KJob *job); + +private: + KIO::FileCopyJob *m_copyJob; + KUrl m_srcUrl; + KUrl m_destUrl; + KUrl m_destFile; + QByteArray m_data; + DownloadType m_type; +}; + + +// ---------------------- + + +class DownloadManager : public QObject +{ + Q_OBJECT + +public: + DownloadManager(); + ~DownloadManager(); + + /** + * @short Creates new download job. + * This method lets you to download a file from a remote source url + * to a local destination url. + * + * @param srcUrl the source url + * @param destUrl the destination url (default value is your default download destination setting) + * + */ + void newDownload(const KUrl &srcUrl, const KUrl &destUrl = KUrl()); + + const QList &downloads() const; + +public slots: + void slotDownloadFinished(int errorCode); + +private: + KUrl downloadDestination(const QString &filename); + + QList m_downloads; +}; + + +//-- + + +#endif diff --git a/src/edittableview.cpp b/src/edittableview.cpp new file mode 100644 index 00000000..bf1ef370 --- /dev/null +++ b/src/edittableview.cpp @@ -0,0 +1,61 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +#include "edittableview.h" +#include + +EditTableView::EditTableView(QWidget *parent) + : QTableView(parent) +{ +} + +void EditTableView::keyPressEvent(QKeyEvent *event) +{ + if ((event->key() == Qt::Key_Delete + || event->key() == Qt::Key_Backspace) + && model()) + { + removeOne(); + } + else + { + QAbstractItemView::keyPressEvent(event); + } +} + +void EditTableView::removeOne() +{ + if (!model() || !selectionModel()) + return; + int row = currentIndex().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); +} + +void EditTableView::removeAll() +{ + if (model()) + model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); +} diff --git a/src/edittableview.h b/src/edittableview.h new file mode 100644 index 00000000..dbc9a145 --- /dev/null +++ b/src/edittableview.h @@ -0,0 +1,42 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +#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 removeOne(); + void removeAll(); +}; + +#endif // EDITTABLEVIEW_H + diff --git a/src/edittreeview.cpp b/src/edittreeview.cpp new file mode 100644 index 00000000..49730d67 --- /dev/null +++ b/src/edittreeview.cpp @@ -0,0 +1,61 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +#include "edittreeview.h" + +#include + +EditTreeView::EditTreeView(QWidget *parent) + : QTreeView(parent) +{ +} + +void EditTreeView::keyPressEvent(QKeyEvent *event) +{ + if ((event->key() == Qt::Key_Delete + || event->key() == Qt::Key_Backspace) + && model()) + { + removeOne(); + } + else + { + QAbstractItemView::keyPressEvent(event); + } +} + +void EditTreeView::removeOne() +{ + if (!model()) + return; + QModelIndex ci = currentIndex(); + int row = ci.row(); + model()->removeRow(row, ci.parent()); +} + +void EditTreeView::removeAll() +{ + if (!model()) + return; + model()->removeRows(0, model()->rowCount(rootIndex()), rootIndex()); +} + diff --git a/src/edittreeview.h b/src/edittreeview.h new file mode 100644 index 00000000..5be0dc45 --- /dev/null +++ b/src/edittreeview.h @@ -0,0 +1,41 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +#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 removeOne(); + void removeAll(); +}; + +#endif // EDITTREEVIEW_H + diff --git a/src/findbar.cpp b/src/findbar.cpp new file mode 100644 index 00000000..11d890c1 --- /dev/null +++ b/src/findbar.cpp @@ -0,0 +1,137 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "findbar.h" +#include "findbar.moc" + +// KDE Includes +#include +#include +#include +#include +#include + +// Qt Includes +#include + + +FindBar::FindBar(KXmlGuiWindow *mainwindow) + : QWidget(mainwindow) + , m_lineEdit(new KLineEdit(this)) + , m_matchCase(new QCheckBox(i18n("&Match case"), this)) +{ + QHBoxLayout *layout = new QHBoxLayout; + + // cosmetic + layout->setContentsMargins(2, 0, 2, 0); + + // hide button + QToolButton *hideButton = new QToolButton(this); + hideButton->setAutoRaise(true); + hideButton->setIcon(KIcon("dialog-close")); + connect(hideButton, SIGNAL(clicked()), this, SLOT(hide())); + layout->addWidget(hideButton); + layout->setAlignment(hideButton, Qt::AlignLeft | Qt::AlignTop); + + // label + QLabel *label = new QLabel(i18n("Find: ")); + layout->addWidget(label); + + // lineEdit, focusProxy + setFocusProxy(m_lineEdit); + m_lineEdit->setMaximumWidth(250); + connect(m_lineEdit, SIGNAL(textChanged(const QString &)), mainwindow, SLOT(slotFind(const QString &))); + layout->addWidget(m_lineEdit); + + // buttons + KPushButton *findNext = new KPushButton(KIcon("go-down"), i18n("&Next"), this); + KPushButton *findPrev = new KPushButton(KIcon("go-up"), i18n("&Previous"), this); + connect(findNext, SIGNAL(clicked()), mainwindow, SLOT(slotFindNext())); + connect(findPrev, SIGNAL(clicked()), mainwindow, SLOT(slotFindPrevious())); + layout->addWidget(findNext); + layout->addWidget(findPrev); + + // Case sensitivity. Deliberately set so this is off by default. + m_matchCase->setCheckState(Qt::Unchecked); + m_matchCase->setTristate(false); + layout->addWidget(m_matchCase); + + // stretching widget on the left + layout->addStretch(); + + setLayout(layout); + + // we start off hidden + hide(); +} + + +FindBar::~FindBar() +{ +} + + +KLineEdit *FindBar::lineEdit() const +{ + return m_lineEdit; +} + + +bool FindBar::matchCase() const +{ + return m_matchCase->isChecked(); +} + + +void FindBar::clear() +{ + m_lineEdit->setText(QString()); +} + + +void FindBar::showFindBar() +{ + // show findbar if not visible + if (!isVisible()) + { + show(); + } + // set focus to findbar if user select showFindBar shortcut + m_lineEdit->setFocus(); + m_lineEdit->selectAll(); +} + + +void FindBar::keyPressEvent(QKeyEvent* event) +{ + if (event->key() == Qt::Key_Escape) + { + hide(); + return; + } + if (event->key() == Qt::Key_Return && !m_lineEdit->text().isEmpty()) + { + emit searchString(m_lineEdit->text()); + return; + } + QWidget::keyPressEvent(event); +} + diff --git a/src/findbar.h b/src/findbar.h new file mode 100644 index 00000000..15a82e1e --- /dev/null +++ b/src/findbar.h @@ -0,0 +1,61 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef FINDBAR_H +#define FINDBAR_H + +// KDE Includes +#include +#include +#include + +// Qt Includes +#include +#include + + +class FindBar : public QWidget +{ + Q_OBJECT + +public: + FindBar(KXmlGuiWindow *mainwindow); + ~FindBar(); + KLineEdit *lineEdit() const; + bool matchCase() const; + +public slots: + void clear(); + void showFindBar(); + +protected Q_SLOTS: + void keyPressEvent(QKeyEvent* event); + +signals: + void searchString(const QString &); + +private: + KLineEdit *m_lineEdit; + QCheckBox *m_matchCase; +}; + + +#endif diff --git a/src/history.cpp b/src/history.cpp new file mode 100644 index 00000000..afcb477a --- /dev/null +++ b/src/history.cpp @@ -0,0 +1,1459 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008 Benjamin C. Meyer +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "history.h" +#include "history.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "autosaver.h" +#include "application.h" + +// KDE Includes +#include +#include + +// Qt Includes +#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() +{ + 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()); + addHistoryEntry(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::addHistoryEntry(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::updateHistoryEntry(const KUrl &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; + } + } +} + + +void HistoryManager::removeHistoryEntry(const HistoryItem &item) +{ + m_lastSavedUrl.clear(); + m_history.removeOne(item); + emit entryRemoved(item); +} + + +void HistoryManager::removeHistoryEntry(const KUrl &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::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() +{ + int historyExpire = ReKonfig::expireHistory(); + int days; + switch (historyExpire) + { + case 0: days = 1; break; + case 1: days = 7; break; + case 2: days = 14; break; + case 3: days = 30; break; + case 4: days = 365; break; + case 5: days = -1; break; + default: days = -1; + } + m_historyLimit = days; +} + + +void HistoryManager::load() +{ + loadSettings(); + + QString historyFilePath = KStandardDirs::locateLocal("appdata" , "history"); + QFile historyFile(historyFilePath); + if (!historyFile.exists()) + return; + if (!historyFile.open(QFile::ReadOnly)) + { + kWarning() << "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() +{ + 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 historyFilePath = KStandardDirs::locateLocal("appdata" , "history"); + QFile historyFile(historyFilePath); + + // 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) + { + kWarning() << "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()) + kWarning() << "History: error removing old history." << historyFile.errorString(); + if (!tempFile.rename(historyFile.fileName())) + kWarning() << "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) +{ + Q_ASSERT(m_history); + connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); + connect(m_history, SIGNAL(entryRemoved(const HistoryItem &)), this, SLOT(historyReset())); + connect(m_history, SIGNAL(entryAdded(const HistoryItem &)), this, SLOT(entryAdded())); + connect(m_history, SIGNAL(entryUpdated(int)), this, SLOT(entryUpdated(int))); +} + + +void HistoryModel::historyReset() +{ + reset(); +} + + +void HistoryModel::entryAdded() +{ + beginInsertRows(QModelIndex(), 0, 0); + endInsertRows(); +} + + +void HistoryModel::entryUpdated(int offset) +{ + QModelIndex idx = index(offset, 0); + emit dataChanged(idx, idx); +} + + +QVariant HistoryModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal + && role == Qt::DisplayRole) + { + switch (section) + { + case 0: return i18n("Title"); + case 1: return i18n("Address"); + } + } + return QAbstractTableModel::headerData(section, orientation, role); +} + + +QVariant HistoryModel::data(const QModelIndex &index, int role) const +{ + QList lst = m_history->history(); + if (index.row() < 0 || index.row() >= lst.size()) + return QVariant(); + + const HistoryItem &item = lst.at(index.row()); + switch (role) + { + case DateTimeRole: + return item.dateTime; + case DateRole: + return item.dateTime.date(); + case UrlRole: + return QUrl(item.url); + case UrlStringRole: + return item.url; + 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; + case 1: + return item.url; + } + } + case Qt::DecorationRole: + if (index.column() == 0) + { + return Application::instance()->icon(item.url); + } + } + return QVariant(); +} + + +int HistoryModel::columnCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : 2; +} + + +int HistoryModel::rowCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : m_history->history().count(); +} + + +bool HistoryModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (parent.isValid()) + return false; + int lastRow = row + count - 1; + beginRemoveRows(parent, row, lastRow); + QList lst = m_history->history(); + for (int i = lastRow; i >= row; --i) + lst.removeAt(i); + disconnect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); + m_history->setHistory(lst); + connect(m_history, SIGNAL(historyReset()), this, SLOT(historyReset())); + endRemoveRows(); + return true; +} + + + +// ----------------------------------------------------------------------------------------------- + + +#define MOVEDROWS 10 + + +/* + Maps the first bunch of items of the source model to the root +*/ +HistoryMenuModel::HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent) + : QAbstractProxyModel(parent) + , m_treeModel(sourceModel) +{ + setSourceModel(sourceModel); +} + + +int HistoryMenuModel::bumpedRows() const +{ + QModelIndex first = m_treeModel->index(0, 0); + if (!first.isValid()) + return 0; + return qMin(m_treeModel->rowCount(first), MOVEDROWS); +} + + +int HistoryMenuModel::columnCount(const QModelIndex &parent) const +{ + return m_treeModel->columnCount(mapToSource(parent)); +} + + +int HistoryMenuModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) + return 0; + + if (!parent.isValid()) + { + int folders = sourceModel()->rowCount(); + int bumpedItems = bumpedRows(); + if (bumpedItems <= MOVEDROWS + && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) + --folders; + return bumpedItems + folders; + } + + if (parent.internalId() == -1) + { + if (parent.row() < bumpedRows()) + return 0; + } + + QModelIndex idx = mapToSource(parent); + int defaultCount = sourceModel()->rowCount(idx); + if (idx == sourceModel()->index(0, 0)) + return defaultCount - bumpedRows(); + return defaultCount; +} + + +QModelIndex HistoryMenuModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + // currently not used or autotested + Q_ASSERT(false); + int sr = m_treeModel->mapToSource(sourceIndex).row(); + return createIndex(sourceIndex.row(), sourceIndex.column(), sr); +} + + +QModelIndex HistoryMenuModel::mapToSource(const QModelIndex &proxyIndex) const +{ + if (!proxyIndex.isValid()) + return QModelIndex(); + + if (proxyIndex.internalId() == -1) + { + int bumpedItems = bumpedRows(); + if (proxyIndex.row() < bumpedItems) + return m_treeModel->index(proxyIndex.row(), proxyIndex.column(), m_treeModel->index(0, 0)); + if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(m_treeModel->index(0, 0))) + --bumpedItems; + return m_treeModel->index(proxyIndex.row() - bumpedItems, proxyIndex.column()); + } + + QModelIndex historyIndex = m_treeModel->sourceModel()->index(proxyIndex.internalId(), proxyIndex.column()); + QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); + return treeIndex; +} + + +QModelIndex HistoryMenuModel::index(int row, int column, const QModelIndex &parent) const +{ + if (row < 0 + || column < 0 || column >= columnCount(parent) + || parent.column() > 0) + return QModelIndex(); + if (!parent.isValid()) + return createIndex(row, column, -1); + + QModelIndex treeIndexParent = mapToSource(parent); + + int bumpedItems = 0; + if (treeIndexParent == m_treeModel->index(0, 0)) + bumpedItems = bumpedRows(); + QModelIndex treeIndex = m_treeModel->index(row + bumpedItems, column, treeIndexParent); + QModelIndex historyIndex = m_treeModel->mapToSource(treeIndex); + int historyRow = historyIndex.row(); + if (historyRow == -1) + historyRow = treeIndex.row(); + return createIndex(row, column, historyRow); +} + + +QModelIndex HistoryMenuModel::parent(const QModelIndex &index) const +{ + int offset = index.internalId(); + if (offset == -1 || !index.isValid()) + return QModelIndex(); + + QModelIndex historyIndex = m_treeModel->sourceModel()->index(index.internalId(), 0); + QModelIndex treeIndex = m_treeModel->mapFromSource(historyIndex); + QModelIndex treeIndexParent = treeIndex.parent(); + + int sr = m_treeModel->mapToSource(treeIndexParent).row(); + int bumpedItems = bumpedRows(); + if (bumpedItems <= MOVEDROWS && bumpedItems == sourceModel()->rowCount(sourceModel()->index(0, 0))) + --bumpedItems; + return createIndex(bumpedItems + treeIndexParent.row(), treeIndexParent.column(), sr); +} + + +// ------------------------------------------------------------------------------------------------------------- + + +HistoryMenu::HistoryMenu(QWidget *parent) + : ModelMenu(parent) + , m_history(0) +{ + connect(this, SIGNAL(activated(const QModelIndex &)), this, SLOT(activated(const QModelIndex &))); + setHoverRole(HistoryModel::UrlStringRole); +} + + +void HistoryMenu::activated(const QModelIndex &index) +{ + emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); +} + + +bool HistoryMenu::prePopulated() +{ + if (!m_history) + { + m_history = Application::historyManager(); + m_historyMenuModel = new HistoryMenuModel(m_history->historyTreeModel(), this); + setModel(m_historyMenuModel); + } + // initial actions + for (int i = 0; i < m_initialActions.count(); ++i) + addAction(m_initialActions.at(i)); + if (!m_initialActions.isEmpty()) + addSeparator(); + setFirstSeparator(m_historyMenuModel->bumpedRows()); + + return false; +} + + +void HistoryMenu::postPopulated() +{ + if (m_history->history().count() > 0) + addSeparator(); + + KAction *showAllAction = new KAction(i18n("Show All History"), this); + connect(showAllAction, SIGNAL(triggered()), this, SLOT(showHistoryDialog())); + addAction(showAllAction); + + KAction *clearAction = new KAction(i18n("Clear History"), this); + connect(clearAction, SIGNAL(triggered()), m_history, SLOT(clear())); + addAction(clearAction); +} + + +void HistoryMenu::showHistoryDialog() +{ + HistoryDialog *dialog = new HistoryDialog(this); + connect(dialog, SIGNAL(openUrl(const KUrl&)), this, SIGNAL(openUrl(const KUrl&))); + dialog->show(); +} + + +void HistoryMenu::setInitialActions(QList actions) +{ + m_initialActions = actions; + for (int i = 0; i < m_initialActions.count(); ++i) + 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 +{ + if (!source_parent.isValid()) + return true; + return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent); +} + + +// ----------------------------------------------------------------------------------------------------- + + +HistoryDialog::HistoryDialog(QWidget *parent, HistoryManager *setHistory) : QDialog(parent) +{ + HistoryManager *history = setHistory; + if (!history) + history = Application::historyManager(); + setupUi(this); + tree->setUniformRowHeights(true); + tree->setSelectionBehavior(QAbstractItemView::SelectRows); + tree->setTextElideMode(Qt::ElideMiddle); + QAbstractItemModel *model = history->historyTreeModel(); + TreeProxyModel *proxyModel = new TreeProxyModel(this); + connect(search, SIGNAL(textChanged(QString)), + proxyModel, SLOT(setFilterFixedString(QString))); + connect(removeButton, SIGNAL(clicked()), tree, SLOT(removeOne())); + connect(removeAllButton, SIGNAL(clicked()), history, SLOT(clear())); + proxyModel->setSourceModel(model); + tree->setModel(proxyModel); + tree->setExpanded(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(open())); + tree->setContextMenuPolicy(Qt::CustomContextMenu); + connect(tree, SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(customContextMenuRequested(const QPoint &))); +} + + +void HistoryDialog::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(i18n("Open"), this, SLOT(open())); + menu.addSeparator(); + menu.addAction(i18n("Copy"), this, SLOT(copy())); + } + menu.addAction(i18n("Delete"), tree, SLOT(removeOne())); + menu.exec(QCursor::pos()); +} + + +void HistoryDialog::open() +{ + QModelIndex index = tree->currentIndex(); + if (!index.parent().isValid()) + return; + emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); +} + + +void HistoryDialog::copy() +{ + QModelIndex index = tree->currentIndex(); + if (!index.parent().isValid()) + return; + QString url = index.data(HistoryModel::UrlStringRole).toString(); + + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(url); +} + + +// --------------------------------------------------------------------------------------------------------------- + +HistoryFilterModel::HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent) + : QAbstractProxyModel(parent), + m_loaded(false) +{ + setSourceModel(sourceModel); +} + + +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 +{ + return QAbstractProxyModel::data(index, role); +} + + +void HistoryFilterModel::setSourceModel(QAbstractItemModel *newSourceModel) +{ + if (sourceModel()) + { + disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); + disconnect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(dataChanged(const QModelIndex &, const QModelIndex &))); + disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); + disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); + } + + QAbstractProxyModel::setSourceModel(newSourceModel); + + if (sourceModel()) + { + m_loaded = false; + connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); + connect(sourceModel(), SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(sourceDataChanged(const QModelIndex &, const QModelIndex &))); + connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); + connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); + } +} + + +void HistoryFilterModel::sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + emit dataChanged(mapFromSource(topLeft), mapFromSource(bottomRight)); +} + + +QVariant HistoryFilterModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + return sourceModel()->headerData(section, orientation, role); +} + + +void HistoryFilterModel::sourceReset() +{ + m_loaded = false; + reset(); +} + + +int HistoryFilterModel::rowCount(const QModelIndex &parent) const +{ + load(); + if (parent.isValid()) + return 0; + return m_historyHash.count(); +} + + +int HistoryFilterModel::columnCount(const QModelIndex &parent) const +{ + return (parent.isValid()) ? 0 : 2; +} + + +QModelIndex HistoryFilterModel::mapToSource(const QModelIndex &proxyIndex) const +{ + load(); + int sourceRow = sourceModel()->rowCount() - proxyIndex.internalId(); + return sourceModel()->index(sourceRow, proxyIndex.column()); +} + + +QModelIndex HistoryFilterModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + load(); + QString url = sourceIndex.data(HistoryModel::UrlStringRole).toString(); + 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) + return QModelIndex(); + + return createIndex(realRow, sourceIndex.column(), sourceModel()->rowCount() - sourceIndex.row()); +} + + +QModelIndex HistoryFilterModel::index(int row, int column, const QModelIndex &parent) const +{ + load(); + if (row < 0 || row >= rowCount(parent) + || column < 0 || column >= columnCount(parent)) + return QModelIndex(); + + return createIndex(row, column, m_sourceRow[row]); +} + + +QModelIndex HistoryFilterModel::parent(const QModelIndex &) const +{ + return QModelIndex(); +} + + +void HistoryFilterModel::load() const +{ + if (m_loaded) + return; + m_sourceRow.clear(); + m_historyHash.clear(); + m_historyHash.reserve(sourceModel()->rowCount()); + 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; + } + } + m_loaded = true; +} + + +void HistoryFilterModel::sourceRowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(start == end && start == 0); + Q_UNUSED(end); + if (!m_loaded) + return; + QModelIndex idx = sourceModel()->index(start, 0, parent); + QString url = idx.data(HistoryModel::UrlStringRole).toString(); + if (m_historyHash.contains(url)) + { + int sourceRow = sourceModel()->rowCount() - m_historyHash[url]; + int realRow = mapFromSource(sourceModel()->index(sourceRow, 0)).row(); + beginRemoveRows(QModelIndex(), realRow, realRow); + m_sourceRow.removeAt(realRow); + m_historyHash.remove(url); + endRemoveRows(); + } + beginInsertRows(QModelIndex(), 0, 0); + m_historyHash.insert(url, sourceModel()->rowCount() - start); + m_sourceRow.insert(0, sourceModel()->rowCount()); + endInsertRows(); +} + + +void HistoryFilterModel::sourceRowsRemoved(const QModelIndex &, int start, int end) +{ + Q_UNUSED(start); + Q_UNUSED(end); + sourceReset(); +} + + +/* + Removing a continuous block of rows will remove filtered rows too as this is + the users intention. +*/ +bool HistoryFilterModel::removeRows(int row, int count, const QModelIndex &parent) +{ + if (row < 0 || count <= 0 || row + count > rowCount(parent) || parent.isValid()) + return false; + int lastRow = row + count - 1; + disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + 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); + sourceModel()->removeRows(start, end - start + 1); + endRemoveRows(); + connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); + m_loaded = false; + if (oldCount - count != rowCount()) + reset(); + return true; +} + + +// ------------------------------------------------------------------------------------------------------ + + +HistoryCompletionModel::HistoryCompletionModel(QObject *parent) + : QAbstractProxyModel(parent) +{ +} + + +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; + } + 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(); +} + + +// ------------------------------------------------------------------------------------------------------ + + +HistoryTreeModel::HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent) + : QAbstractProxyModel(parent) +{ + setSourceModel(sourceModel); +} + + +QVariant HistoryTreeModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + return sourceModel()->headerData(section, orientation, role); +} + + +QVariant HistoryTreeModel::data(const QModelIndex &index, int role) const +{ + if ((role == Qt::EditRole || role == Qt::DisplayRole)) + { + int start = index.internalId(); + if (start == 0) + { + int offset = sourceDateRow(index.row()); + if (index.column() == 0) + { + QModelIndex idx = sourceModel()->index(offset, 0); + QDate date = idx.data(HistoryModel::DateRole).toDate(); + if (date == QDate::currentDate()) + return i18n("Earlier Today"); + return date.toString(QLatin1String("dddd, MMMM d, yyyy")); + } + if (index.column() == 1) + { + return i18np("1 item", "%1 items", rowCount(index.sibling(index.row(), 0))); + } + } + } + if (role == Qt::DecorationRole && index.column() == 0 && !index.parent().isValid()) + return KIcon("view-history"); + 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); + } + + return QAbstractProxyModel::data(index, role); +} + + +int HistoryTreeModel::columnCount(const QModelIndex &parent) const +{ + return sourceModel()->columnCount(mapToSource(parent)); +} + + +int HistoryTreeModel::rowCount(const QModelIndex &parent) const +{ + if (parent.internalId() != 0 + || parent.column() > 0 + || !sourceModel()) + return 0; + + // row count OF dates + if (!parent.isValid()) + { + if (!m_sourceRowCache.isEmpty()) + return m_sourceRowCache.count(); + QDate currentDate; + int rows = 0; + int totalRows = sourceModel()->rowCount(); + + for (int i = 0; i < totalRows; ++i) + { + QDate rowDate = sourceModel()->index(i, 0).data(HistoryModel::DateRole).toDate(); + if (rowDate != currentDate) + { + m_sourceRowCache.append(i); + currentDate = rowDate; + ++rows; + } + } + Q_ASSERT(m_sourceRowCache.count() == rows); + return rows; + } + + // row count FOR a date + int start = sourceDateRow(parent.row()); + int end = sourceDateRow(parent.row() + 1); + return (end - start); +} + + +// Translate the top level date row into the offset where that date starts +int HistoryTreeModel::sourceDateRow(int row) const +{ + if (row <= 0) + return 0; + + if (m_sourceRowCache.isEmpty()) + rowCount(QModelIndex()); + + if (row >= m_sourceRowCache.count()) + { + if (!sourceModel()) + return 0; + return sourceModel()->rowCount(); + } + return m_sourceRowCache.at(row); +} + + +QModelIndex HistoryTreeModel::mapToSource(const QModelIndex &proxyIndex) const +{ + int offset = proxyIndex.internalId(); + if (offset == 0) + return QModelIndex(); + int startDateRow = sourceDateRow(offset - 1); + return sourceModel()->index(startDateRow + proxyIndex.row(), proxyIndex.column()); +} + + +QModelIndex HistoryTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if (row < 0 + || column < 0 || column >= columnCount(parent) + || parent.column() > 0) + return QModelIndex(); + + if (!parent.isValid()) + return createIndex(row, column, 0); + return createIndex(row, column, parent.row() + 1); +} + + +QModelIndex HistoryTreeModel::parent(const QModelIndex &index) const +{ + int offset = index.internalId(); + if (offset == 0 || !index.isValid()) + return QModelIndex(); + return createIndex(offset - 1, 0, 0); +} + + +bool HistoryTreeModel::hasChildren(const QModelIndex &parent) const +{ + QModelIndex grandparent = parent.parent(); + if (!grandparent.isValid()) + return true; + return false; +} + + +Qt::ItemFlags HistoryTreeModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return Qt::NoItemFlags; + 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()) + { + disconnect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); + disconnect(sourceModel(), SIGNAL(layoutChanged()), this, SLOT(sourceReset())); + disconnect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); + disconnect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); + } + + QAbstractProxyModel::setSourceModel(newSourceModel); + + if (newSourceModel) + { + connect(sourceModel(), SIGNAL(modelReset()), this, SLOT(sourceReset())); + connect(sourceModel(), SIGNAL(layoutChanged()), this, SLOT(sourceReset())); + connect(sourceModel(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(sourceRowsInserted(const QModelIndex &, int, int))); + connect(sourceModel(), SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(sourceRowsRemoved(const QModelIndex &, int, int))); + } + + reset(); +} + + +void HistoryTreeModel::sourceReset() +{ + m_sourceRowCache.clear(); + reset(); +} + + +void HistoryTreeModel::sourceRowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent); // Avoid warnings when compiling release + Q_ASSERT(!parent.isValid()); + if (start != 0 || start != end) + { + m_sourceRowCache.clear(); + reset(); + return; + } + + m_sourceRowCache.clear(); + QModelIndex treeIndex = mapFromSource(sourceModel()->index(start, 0)); + QModelIndex treeParent = treeIndex.parent(); + if (rowCount(treeParent) == 1) + { + beginInsertRows(QModelIndex(), 0, 0); + endInsertRows(); + } + else + { + beginInsertRows(treeParent, treeIndex.row(), treeIndex.row()); + endInsertRows(); + } +} + + +QModelIndex HistoryTreeModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + if (!sourceIndex.isValid()) + return QModelIndex(); + + if (m_sourceRowCache.isEmpty()) + rowCount(QModelIndex()); + + QList::iterator it; + it = qLowerBound(m_sourceRowCache.begin(), m_sourceRowCache.end(), sourceIndex.row()); + if (*it != sourceIndex.row()) + --it; + + int dateRow = qMax(0, it - m_sourceRowCache.begin()); + // FIXME fix crach on history submenu open. BUG:'ASSERT failure in QList::at: "index out of range"' + // it crashes when dateRow == 1 + // kDebug() << m_sourceRowCache << dateRow; + int row = sourceIndex.row() - m_sourceRowCache.at(dateRow); + return createIndex(row, sourceIndex.column(), dateRow + 1); +} + + +void HistoryTreeModel::sourceRowsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_UNUSED(parent); // Avoid warnings when compiling release + Q_ASSERT(!parent.isValid()); + if (m_sourceRowCache.isEmpty()) + return; + 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()); + int offset = m_sourceRowCache[row]; + QModelIndex dateParent = index(row, 0); + // 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]; + endRemoveRows(); + } +} diff --git a/src/history.h b/src/history.h new file mode 100644 index 00000000..ecae00c3 --- /dev/null +++ b/src/history.h @@ -0,0 +1,402 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008 Benjamin C. Meyer +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef HISTORY_H +#define HISTORY_H + +// Local Includes +#include "modelmenu.h" + +// KDE Includes +#include +#include + +// Qt Includes +#include +#include +#include +#include +#include +#include + + +/** + * Elements in this class represent an history item + * + */ + +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 updateHistoryEntry(const KUrl &url, const QString &title); + void removeHistoryEntry(const KUrl &url, const QString &title = QString()); + + 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 addHistoryEntry(const HistoryItem &item); + void removeHistoryEntry(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 HistoryModel : public QAbstractTableModel +{ + Q_OBJECT + +public slots: + void historyReset(); + void entryAdded(); + void entryUpdated(int offset); + +public: + enum Roles + { + DateRole = Qt::UserRole + 1, + DateTimeRole = Qt::UserRole + 2, + UrlRole = Qt::UserRole + 3, + UrlStringRole = Qt::UserRole + 4 + }; + + HistoryModel(HistoryManager *history, 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: + HistoryManager *m_history; +}; + + +// ---------------------------------------------------------------------------------------------------- + +/** + * Proxy model that will remove any duplicate entries. + * Both m_sourceRow and m_historyHash store their offsets not from + * the front of the list, but as offsets from the back. + * + */ + +class HistoryFilterModel : public QAbstractProxyModel +{ + Q_OBJECT + +public: + HistoryFilterModel(QAbstractItemModel *sourceModel, QObject *parent = 0); + + inline bool historyContains(const QString &url) const + { + load(); return m_historyHash.contains(url); + } + int historyLocation(const QString &url) const; + + 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; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + +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); + +private: + void load() const; + + mutable QList m_sourceRow; + mutable QHash m_historyHash; + mutable bool m_loaded; +}; + + +// ---------------------------------------------------------------------------------------------------------------------- + +/** + * The history menu + * - Removes the first twenty entries and puts them as children of the top level. + * - If there are less then twenty entries then the first folder is also removed. + * + * The mapping is done by knowing that HistoryTreeModel is over a table + * We store that row offset in our index's private data. + * + */ + +class HistoryMenuModel : public QAbstractProxyModel +{ + Q_OBJECT + +public: + HistoryMenuModel(HistoryTreeModel *sourceModel, QObject *parent = 0); + int columnCount(const QModelIndex &parent) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QModelIndex mapFromSource(const QModelIndex & sourceIndex) const; + QModelIndex mapToSource(const QModelIndex & proxyIndex) const; + QModelIndex index(int, int, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index = QModelIndex()) const; + + int bumpedRows() const; + +private: + HistoryTreeModel *m_treeModel; +}; + + +// --------------------------------------------------------------------------------------------- + +/** + * Menu that is dynamically populated from the history + * + */ + +class HistoryMenu : public ModelMenu +{ + Q_OBJECT + +signals: + void openUrl(const KUrl &url); + +public: + HistoryMenu(QWidget *parent = 0); + void setInitialActions(QList actions); + +protected: + bool prePopulated(); + void postPopulated(); + +private slots: + void activated(const QModelIndex &index); + void showHistoryDialog(); + +private: + HistoryManager *m_history; + HistoryMenuModel *m_historyMenuModel; + 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. + * + */ + +class HistoryTreeModel : public QAbstractProxyModel +{ + Q_OBJECT + +public: + HistoryTreeModel(QAbstractItemModel *sourceModel, QObject *parent = 0); + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + int columnCount(const QModelIndex &parent) const; + int rowCount(const QModelIndex &parent = QModelIndex()) const; + QModelIndex mapFromSource(const QModelIndex &sourceIndex) const; + QModelIndex mapToSource(const QModelIndex &proxyIndex) const; + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; + QModelIndex parent(const QModelIndex &index = QModelIndex()) const; + bool hasChildren(const QModelIndex &parent = QModelIndex()) const; + Qt::ItemFlags flags(const QModelIndex &index) const; + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; + + void setSourceModel(QAbstractItemModel *sourceModel); + +private slots: + void sourceReset(); + void sourceRowsInserted(const QModelIndex &parent, int start, int end); + void sourceRowsRemoved(const QModelIndex &parent, int start, int end); + +private: + int sourceDateRow(int row) const; + mutable QList m_sourceRowCache; + +}; + + +// ----------------------------------------------------------------------------------------------------------------- + +/** + * 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 +{ + Q_OBJECT + +signals: + void openUrl(const KUrl &url); + +public: + HistoryDialog(QWidget *parent = 0, HistoryManager *history = 0); + +private slots: + void customContextMenuRequested(const QPoint &pos); + void open(); + void copy(); + +}; + +#endif // HISTORY_H + diff --git a/src/history.ui b/src/history.ui new file mode 100644 index 00000000..806bc9ad --- /dev/null +++ b/src/history.ui @@ -0,0 +1,101 @@ + + HistoryDialog + + + + 0 + 0 + 758 + 450 + + + + History + + + + + + Qt::Horizontal + + + + 252 + 20 + + + + + + + + + + + + + + + + &Remove + + + + + + + Remove &All + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + QDialogButtonBox::Ok + + + + + + + + + + EditTreeView + QTreeView +
edittreeview.h
+
+
+ + + + buttonBox + accepted() + HistoryDialog + accept() + + + 472 + 329 + + + 461 + 356 + + + + +
diff --git a/src/lineedit.cpp b/src/lineedit.cpp new file mode 100644 index 00000000..c9df7bfa --- /dev/null +++ b/src/lineedit.cpp @@ -0,0 +1,85 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + +// Self Includes +#include "lineedit.h" +#include "lineedit.moc" + +// Qt Includes +#include +#include +#include + +// KDE Includes +#include + +// Local Includes + +LineEdit::LineEdit(QWidget* parent) + : KLineEdit(parent) +{ + setMinimumWidth(180); + setFocusPolicy(Qt::WheelFocus); + + setHandleSignals(true); +} + + +LineEdit::~LineEdit() +{ +} + + +void LineEdit::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape) + { + clearFocus(); + event->accept(); + } + + KLineEdit::keyPressEvent(event); +} + + +void LineEdit::contextMenuEvent(QContextMenuEvent *event) +{ + KLineEdit::contextMenuEvent(event); +} + + +void LineEdit::focusInEvent(QFocusEvent *event) +{ + selectAll(); + + KLineEdit::focusInEvent(event); +} + + +void LineEdit::focusOutEvent(QFocusEvent *event) +{ + KLineEdit::focusOutEvent(event); + + // reset cursor state and deselect + setCursorPosition(0); + deselect(); +} + + + diff --git a/src/lineedit.h b/src/lineedit.h new file mode 100644 index 00000000..f1bd8f88 --- /dev/null +++ b/src/lineedit.h @@ -0,0 +1,50 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef LINEEDIT_H +#define LINEEDIT_H + +// Qt Includes + +// KDE Includes +#include + +// Local Includes + +class QContextMenuEvent; +class QFocusEvent; +class QKeyEvent; + +class LineEdit : public KLineEdit +{ + Q_OBJECT + +public: + explicit LineEdit(QWidget *parent = 0); + virtual ~LineEdit(); + +protected: + virtual void keyPressEvent(QKeyEvent*); + virtual void contextMenuEvent(QContextMenuEvent*); + virtual void focusInEvent(QFocusEvent*); + virtual void focusOutEvent(QFocusEvent*); +}; + +#endif // LINEEDIT_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 00000000..5ada94b4 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,98 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +#include "application.h" + +#include +#include +#include + + +static const char description[] = + I18N_NOOP("KDE Browser Webkit Based"); + + +static const char version[] = "0.1alpha"; + + +int main(int argc, char **argv) +{ + KAboutData about("rekonq", + 0, + ki18n("rekonq"), + version, + ki18n(description), + KAboutData::License_GPL_V3, + ki18n("(C) 2008-2009 Andrea Diamantini"), + KLocalizedString(), + "http://rekonq.sourceforge.net", + "rekonq@kde.org" + ); + + // about authors + about.addAuthor(ki18n("Andrea Diamantini"), + ki18n("Project Lead, Developer, Italian translation"), + "adjam7@gmail.com", + "http://www.adjam.org"); + + about.addAuthor(ki18n("Domrachev Alexandr"), + ki18n("Developer, Russian translation"), + "alexandr.domrachev@gmail.com", + ""); + + about.addAuthor(ki18n("Pawel Prazak"), + ki18n("Developer"), + "kojots350@gmail.com", + ""); + + about.addAuthor(ki18n("Panagiotis Papadopoulos"), + ki18n("German translation"), + "pano_90@gmx.net", + ""); + +// about.addAuthor(ki18n("your name"), +// ki18n("your role"), +// "your mail", +// "your site"); + + // Initialize command line args + KCmdLineArgs::init(argc, argv, &about); + + // Define the command line options using KCmdLineOptions + KCmdLineOptions options; + + // adding URL option + options.add("+[URL]" , ki18n("Location to open")); + + // Register the supported options + KCmdLineArgs::addCmdLineOptions(options); + + // Add options from Application class + Application::addCmdLineOptions(); + + if (!Application::start()) + { + kWarning() << "rekonq is already running!"; + return 0; + } + + Application app; + return app.exec(); +} diff --git a/src/mainview.cpp b/src/mainview.cpp new file mode 100644 index 00000000..d4edeb19 --- /dev/null +++ b/src/mainview.cpp @@ -0,0 +1,716 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + +// Self Includes +#include "mainview.h" +#include "mainview.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "tabbar.h" +#include "application.h" +#include "mainwindow.h" +#include "history.h" +#include "stackedurlbar.h" +#include "urlbar.h" +#include "webview.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include +#include + + + +MainView::MainView(QWidget *parent) + : KTabWidget(parent) + , m_recentlyClosedTabsAction(0) + , m_recentlyClosedTabsMenu(new KMenu(this)) + , m_urlBars(new StackedUrlBar(this)) + , m_tabBar(new TabBar(this)) +{ + // setting tabbar + setTabBar(m_tabBar); + + // loading pixmap path + m_loadingGitPath = KStandardDirs::locate("appdata" , "pics/loading.gif"); + + // connecting tabbar signals + connect(m_tabBar, SIGNAL(closeTab(int)), this, SLOT(slotCloseTab(int))); + connect(m_tabBar, SIGNAL(cloneTab(int)), this, SLOT(slotCloneTab(int))); + connect(m_tabBar, SIGNAL(closeOtherTabs(int)), this, SLOT(slotCloseOtherTabs(int))); + connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(slotReloadTab(int))); + connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(slotReloadAllTabs())); + connect(m_tabBar, SIGNAL(tabMoved(int, int)), this, SLOT(moveTab(int, int))); + + // current page index changing + connect(this, SIGNAL(currentChanged(int)), this, SLOT(slotCurrentChanged(int))); + + setTabsClosable(true); + connect(m_tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(slotCloseTab(int))); + + QTimer::singleShot(0, this, SLOT(postLaunch())); +} + + +MainView::~MainView() +{ +} + + +void MainView::postLaunch() +{ + // Recently Closed Tab Action + connect(m_recentlyClosedTabsMenu, SIGNAL(aboutToShow()), this, SLOT(aboutToShowRecentTabsMenu())); + connect(m_recentlyClosedTabsMenu, SIGNAL(triggered(QAction *)), this, SLOT(aboutToShowRecentTriggeredAction(QAction *))); + m_recentlyClosedTabsAction = new KAction(i18n("Recently Closed Tabs"), this); + m_recentlyClosedTabsAction->setMenu(m_recentlyClosedTabsMenu); + m_recentlyClosedTabsAction->setEnabled(false); +} + +void MainView::showTabBar() +{ + if (ReKonfig::alwaysShowTabBar()) + { + if (m_tabBar->isHidden()) + { + m_tabBar->show(); + } + return; + } + + if (m_tabBar->count() == 1) + { + m_tabBar->hide(); + } + else + { + if (m_tabBar->isHidden()) + { + m_tabBar->show(); + } + } +} + + +void MainView::slotWebReload() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Reload); + action->trigger(); +} + + +void MainView::slotWebStop() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Stop); + action->trigger(); +} + + +void MainView::slotWebBack() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Back); + action->trigger(); +} + + +void MainView::slotWebForward() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Forward); + action->trigger(); +} + + +void MainView::slotWebUndo() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Undo); + action->trigger(); +} + + +void MainView::slotWebRedo() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Redo); + action->trigger(); +} + + +void MainView::slotWebCut() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Cut); + action->trigger(); +} + + +void MainView::slotWebCopy() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Copy); + action->trigger(); +} + + +void MainView::slotWebPaste() +{ + WebView *webView = currentWebView(); + QWebPage *currentParent = webView->webPage(); + QAction *action = currentParent->action(QWebPage::Paste); + action->trigger(); +} + + +void MainView::clear() +{ + // clear the recently closed tabs + m_recentlyClosedTabs.clear(); + // clear the line edit history + for (int i = 0; i < m_urlBars->count(); ++i) + { + /// TODO What exacly do we need to clear here? + urlBar(i)->clearHistory(); + urlBar(i)->clear(); + } +} + + +// When index is -1 index chooses the current tab +void MainView::slotReloadTab(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + QWidget *widget = this->widget(index); + if (WebView *tab = qobject_cast(widget)) + tab->reload(); +} + + +void MainView::slotCurrentChanged(int index) +{ + WebView *webView = this->webView(index); + if (!webView) + return; + + Q_ASSERT(m_urlBars->count() == count()); + + WebView *oldWebView = this->webView(m_urlBars->currentIndex()); + if (oldWebView) + { + disconnect(oldWebView, SIGNAL(statusBarMessage(const QString&)), + this, SIGNAL(showStatusBarMessage(const QString&))); + disconnect(oldWebView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), + this, SIGNAL(linkHovered(const QString&))); + disconnect(oldWebView, SIGNAL(loadProgress(int)), + this, SIGNAL(loadProgress(int))); + } + + connect(webView, SIGNAL(statusBarMessage(const QString&)), this, SIGNAL(showStatusBarMessage(const QString&))); + connect(webView->page(), SIGNAL(linkHovered(const QString&, const QString&, const QString&)), this, SIGNAL(linkHovered(const QString&))); + connect(webView, SIGNAL(loadProgress(int)), this, SIGNAL(loadProgress(int))); + + emit setCurrentTitle(webView->title()); + m_urlBars->setCurrentIndex(index); + emit loadProgress(webView->progress()); + emit showStatusBarMessage(webView->lastStatusBarText()); + + // set focus to the current webview + webView->setFocus(); +} + + +UrlBar *MainView::urlBar(int index) const +{ + if (index == -1) + { + index = m_urlBars->currentIndex(); + } + UrlBar *urlBar = m_urlBars->urlBar(index); + if (urlBar) + { + return urlBar; + } + kWarning() << "URL bar with index" << index << "not found. Returning NULL. (line:" << __LINE__ << ")"; + return NULL; +} + + +WebView *MainView::webView(int index) const +{ + QWidget *widget = this->widget(index); + if (WebView *webView = qobject_cast(widget)) + { + return webView; + } + + kWarning() << "WebView with index " << index << "not found. Returning NULL." ; + return 0; +} + + +WebView *MainView::newWebView(Rekonq::OpenType type) +{ + // line edit + UrlBar *urlBar = new UrlBar; // Ownership of widget is passed on to the QStackedWidget (addWidget method). + connect(urlBar, SIGNAL(activated(const KUrl&)), this, SLOT(loadUrl(const KUrl&))); + m_urlBars->addUrlBar(urlBar); + + WebView *webView = new WebView; // should be deleted on tab close + + // connecting webview with urlbar + connect(webView, SIGNAL(loadProgress(int)), urlBar, SLOT(slotUpdateProgress(int))); + connect(webView, SIGNAL(loadFinished(bool)), urlBar, SLOT(slotLoadFinished(bool))); + connect(webView, SIGNAL(urlChanged(const QUrl &)), urlBar, SLOT(setUrl(const QUrl &))); + connect(webView, SIGNAL(iconChanged()), urlBar, SLOT(slotUpdateUrl())); + + // connecting webview with mainview + connect(webView, SIGNAL(loadStarted()), this, SLOT(webViewLoadStarted())); + connect(webView, SIGNAL(loadProgress(int)), this, SLOT(webViewLoadProgress(int))); + connect(webView, SIGNAL(loadFinished(bool)), 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(ctrlTabPressed()), this, SLOT(nextTab())); + connect(webView, SIGNAL(shiftCtrlTabPressed()), this, SLOT(previousTab())); + + // connecting webPage signals with mainview + 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(menuBarVisibilityChangeRequested(bool)), + this, SIGNAL(menuBarVisibilityChangeRequested(bool))); + connect(webView->page(), SIGNAL(statusBarVisibilityChangeRequested(bool)), + this, SIGNAL(statusBarVisibilityChangeRequested(bool))); + connect(webView->page(), SIGNAL(toolBarVisibilityChangeRequested(bool)), + this, SIGNAL(toolBarVisibilityChangeRequested(bool))); + + addTab(webView, i18n("(Untitled)")); + + switch(type) + { + case Rekonq::Default: + if (!m_makeBackTab) + { + setCurrentWidget(webView); // this method does NOT take ownership of webView + urlBar->setFocus(); + } + break; + case Rekonq::New: + setCurrentWidget(webView); // this method does NOT take ownership of webView + urlBar->setFocus(); + break; + case Rekonq::Background: + break; + }; + + emit tabsChanged(); + + showTabBar(); + + return webView; +} + + +void MainView::slotReloadAllTabs() +{ + for (int i = 0; i < count(); ++i) + { + QWidget *tabWidget = widget(i); + if (WebView *tab = qobject_cast(tabWidget)) + { + tab->reload(); + } + } +} + + +void MainView::windowCloseRequested() +{ + + WebPage *webPage = qobject_cast(sender()); + WebView *webView = qobject_cast(webPage->view()); + int index = webViewIndex(webView); + + if (index >= 0) + { + if (count() == 1) + { + Application::instance()->mainWindow()->close(); + } + else + { + slotCloseTab(index); + } + } + else + { + kWarning() << "Invalid tab index" << "line:" << __LINE__; + } +} + + +void MainView::slotCloseOtherTabs(int index) +{ + if (-1 == index) + return; + + for (int i = count() - 1; i > index; --i) + { + slotCloseTab(i); + } + + for (int i = index - 1; i >= 0; --i) + { + slotCloseTab(i); + } + + showTabBar(); +} + + +// When index is -1 index chooses the current tab +void MainView::slotCloneTab(int index) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + WebView *tab = newWebView(); + tab->setUrl(webView(index)->url()); + + showTabBar(); +} + + +// When index is -1 index chooses the current tab +void MainView::slotCloseTab(int index) +{ + // do nothing if just one tab is opened + if (count() == 1) + return; + + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + bool hasFocus = false; + if (WebView *tab = webView(index)) + { + if (tab->isModified()) + { + int risp = KMessageBox::questionYesNo(this , + i18n("You have modified this page and when closing it you would lose the modification.\n" + "Do you really want to close this page?\n"), + i18n("Do you really want to close this page?") + ); + if (risp == KMessageBox::No) + return; + } + hasFocus = tab->hasFocus(); + + m_recentlyClosedTabsAction->setEnabled(true); + m_recentlyClosedTabs.prepend(tab->url()); + + // don't add empty urls + if (tab->url().isValid()) + { + m_recentlyClosedTabs.prepend(tab->url()); + } + + if (m_recentlyClosedTabs.size() >= MainView::m_recentlyClosedTabsSize) + { + m_recentlyClosedTabs.removeLast(); + } + } + + QWidget *urlBar = m_urlBars->urlBar(index); + m_urlBars->removeWidget(urlBar); + urlBar->deleteLater(); // urlBar is scheduled for deletion. + + QWidget *webView = widget(index); + removeTab(index); + webView->deleteLater(); // webView is scheduled for deletion. + + emit tabsChanged(); + + if (hasFocus && count() > 0) + { + currentWebView()->setFocus(); + } + + showTabBar(); +} + + +void MainView::webViewLoadStarted() +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) + { + QLabel *label = animatedLoading(index, true); + if (label->movie()) + { + label->movie()->start(); + } + } + + if (index != currentIndex()) + return; + + emit showStatusBarMessage(i18n("Loading...")); +} + + +void MainView::webViewLoadProgress(int progress) +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (index != currentIndex() || index < 0) + { + return; + } + + double totalBytes = static_cast(webView->webPage()->totalBytes() / 1024); + + QString message = i18n("Loading %1% (%2 %3)...", progress, totalBytes, QLatin1String("kB")); + emit showStatusBarMessage(message); +} + + +void MainView::webViewLoadFinished(bool ok) +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + + if (-1 != index) + { + QLabel *label = animatedLoading(index, true); + QMovie *movie = label->movie(); + if (movie) + movie->stop(); + } + + webViewIconChanged(); + + // don't display messages for background tabs + if (index != currentIndex()) + { + return; + } + + if (ok) + emit showStatusBarMessage(i18n("Done")); + else + emit showStatusBarMessage(i18n("Failed to load")); +} + + +void MainView::webViewIconChanged() +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) + { + QIcon icon = Application::instance()->icon(webView->url()); + QLabel *label = animatedLoading(index, false); + QMovie *movie = label->movie(); + delete movie; + label->setMovie(0); + label->setPixmap(icon.pixmap(16, 16)); + } +} + + +void MainView::webViewTitleChanged(const QString &title) +{ + QString tabTitle = title; + if (title.isEmpty()) + { + tabTitle = i18n("(Untitled)"); + } + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) + { + setTabText(index, tabTitle); + } + if (currentIndex() == index) + { + emit setCurrentTitle(tabTitle); + } + Application::historyManager()->updateHistoryEntry(webView->url(), tabTitle); +} + + +void MainView::webViewUrlChanged(const QUrl &url) +{ + WebView *webView = qobject_cast(sender()); + int index = webViewIndex(webView); + if (-1 != index) + { + m_tabBar->setTabData(index, url); + } + emit tabsChanged(); +} + + +void MainView::aboutToShowRecentTabsMenu() +{ + m_recentlyClosedTabsMenu->clear(); + for (int i = 0; i < m_recentlyClosedTabs.count(); ++i) + { + KAction *action = new KAction(m_recentlyClosedTabsMenu); + action->setData(m_recentlyClosedTabs.at(i)); + QIcon icon = Application::instance()->icon(m_recentlyClosedTabs.at(i)); + action->setIcon(icon); + action->setText(m_recentlyClosedTabs.at(i).prettyUrl()); + m_recentlyClosedTabsMenu->addAction(action); + } +} + + +void MainView::aboutToShowRecentTriggeredAction(QAction *action) +{ + KUrl url = action->data().toUrl(); + loadUrl(url); +} + + +void MainView::loadUrl(const KUrl &url) +{ + if (url.isEmpty()) + return; + + currentUrlBar()->setUrl(url.prettyUrl()); + + WebView *webView = currentWebView(); + + KUrl loadingUrl(url); + + if (loadingUrl.isRelative()) + { + QString fn = loadingUrl.url(KUrl::RemoveTrailingSlash); + loadingUrl.setUrl("//" + fn); + loadingUrl.setScheme("http"); + } + + if (webView) + { + webView->load(loadingUrl); + webView->setFocus(); + } +} + + +void MainView::nextTab() +{ + int next = currentIndex() + 1; + if (next == count()) + next = 0; + setCurrentIndex(next); +} + + +void MainView::previousTab() +{ + int next = currentIndex() - 1; + if (next < 0) + next = count() - 1; + setCurrentIndex(next); +} + + +void MainView::moveTab(int fromIndex, int toIndex) +{ + QWidget *lineEdit = m_urlBars->widget(fromIndex); + m_urlBars->removeWidget(lineEdit); + m_urlBars->insertWidget(toIndex, lineEdit); +} + + +QLabel *MainView::animatedLoading(int index, bool addMovie) +{ + if (index == -1) + return 0; + + QLabel *label = qobject_cast(m_tabBar->tabButton(index, QTabBar::LeftSide)); + if (!label) + { + label = new QLabel(this); + } + if (addMovie && !label->movie()) + { + QMovie *movie = new QMovie(m_loadingGitPath, QByteArray(), label); + movie->setSpeed(50); + label->setMovie(movie); + movie->start(); + } + m_tabBar->setTabButton(index, QTabBar::LeftSide, 0); + m_tabBar->setTabButton(index, QTabBar::LeftSide, label); + return label; +} + + +void MainView::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (!childAt(event->pos())) + { + newWebView(Rekonq::New); + return; + } + KTabWidget::mouseDoubleClickEvent(event); +} \ No newline at end of file diff --git a/src/mainview.h b/src/mainview.h new file mode 100644 index 00000000..372902dd --- /dev/null +++ b/src/mainview.h @@ -0,0 +1,198 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + + +#ifndef TABWIDGET_H +#define TABWIDGET_H + +// Local Includes +#include "webview.h" +#include "application.h" + +// KDE Includes +#include + +// Forward Declarations +class QLineEdit; +class QUrl; +class QWebFrame; +class QLabel; + +class KAction; +class KCompletion; +class KMenu; +class KUrl; + +class HistoryCompletionModel; +class StackedUrlBar; +class TabBar; +class UrlBar; + + +/** + * This class represent rekonq Main View. It contains all WebViews and a stack widget + * of associated line edits. + * + */ + +class MainView : public KTabWidget +{ + Q_OBJECT + +public: + MainView(QWidget *parent = 0); + ~MainView(); + +public: + + UrlBar *urlBar(int index) const; + UrlBar *currentUrlBar() const { return urlBar(-1); } + WebView *webView(int index) const; + QList tabs(); // ? + + // inlines + TabBar *tabBar() const { return m_tabBar; } + StackedUrlBar *urlBarStack() const { return m_urlBars; } + WebView *currentWebView() const { return webView(currentIndex()); } + int webViewIndex(WebView *webView) const { return indexOf(webView); } + KAction *recentlyClosedTabsAction() const { return m_recentlyClosedTabsAction; } + void setMakeBackTab(bool b) { m_makeBackTab = b; } + + /** + * show and hide TabBar if user doesn't choose + * "Always Show TabBar" option + * + */ + void showTabBar(); + void clear(); + + +signals: + // tab widget signals + void tabsChanged(); + void lastTabClosed(); + + // current tab signals + void setCurrentTitle(const QString &url); + void showStatusBarMessage(const QString &message); + void linkHovered(const QString &link); + void loadProgress(int progress); + + void geometryChangeRequested(const QRect &geometry); + void menuBarVisibilityChangeRequested(bool visible); + void statusBarVisibilityChangeRequested(bool visible); + void toolBarVisibilityChangeRequested(bool visible); + void printRequested(QWebFrame *frame); + +public slots: + /** + * Core browser slot. This create a new tab with a WebView inside + * for browsing. + * + * @return a pointer to the new WebView + */ + WebView *newWebView(Rekonq::OpenType type = Rekonq::Default); + + /** + * Core browser slot. Load an url in a webview + * + * @param url The url to load + */ + void loadUrl(const KUrl &url); + void slotCloneTab(int index = -1); + void slotCloseTab(int index = -1); + void slotCloseOtherTabs(int index); + void slotReloadTab(int index = -1); + void slotReloadAllTabs(); + void nextTab(); + void previousTab(); + + // WEB slot actions + void slotWebReload(); + void slotWebStop(); + void slotWebBack(); + void slotWebForward(); + void slotWebUndo(); + void slotWebRedo(); + void slotWebCut(); + void slotWebCopy(); + void slotWebPaste(); + +private slots: + void slotCurrentChanged(int index); + void aboutToShowRecentTabsMenu(); + void aboutToShowRecentTriggeredAction(QAction *action); // need QAction! + + void webViewLoadStarted(); + void webViewLoadProgress(int progress); + void webViewLoadFinished(bool ok); + void webViewIconChanged(); + void webViewTitleChanged(const QString &title); + void webViewUrlChanged(const QUrl &url); + + void windowCloseRequested(); + + /** + * This functions move tab informations "from index to index" + * + * @param fromIndex the index from which we move + * + * @param toIndex the index to which we move + */ + void moveTab(int fromIndex, int toIndex); + + void postLaunch(); + +protected: + + virtual void mouseDoubleClickEvent(QMouseEvent *event); + + +private: + + /** + * This function creates (if not exists) and returns a QLabel + * with a loading QMovie. + * Imported from Arora's code. + * + * @param index the tab index where inserting the animated label + * @param addMovie creates or not a loading movie + * + * @return animated label's pointer + */ + QLabel *animatedLoading(int index, bool addMovie); + + static const int m_recentlyClosedTabsSize = 10; + KAction *m_recentlyClosedTabsAction; + + KMenu *m_recentlyClosedTabsMenu; + QList m_recentlyClosedTabs; + + StackedUrlBar *m_urlBars; + TabBar *m_tabBar; + + QString m_loadingGitPath; + + bool m_makeBackTab; +}; + +#endif diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 00000000..d1ab721f --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,930 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "mainwindow.h" +#include "mainwindow.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "application.h" +#include "settings.h" +#include "history.h" +#include "cookiejar.h" +#include "networkaccessmanager.h" +#include "bookmarks.h" +#include "webview.h" +#include "mainview.h" +#include "bookmarks.h" +#include "download.h" +#include "findbar.h" +#include "sidepanel.h" +#include "urlbar.h" +#include "stackedurlbar.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +// Qt Includes +#include +#include +#include + + +MainWindow::MainWindow() + : KXmlGuiWindow() + , m_view(new MainView(this)) + , m_findBar(new FindBar(this)) + , m_searchBar(new SearchBar(this)) + , m_sidePanel(0) +{ + // updating rekonq configuration + slotUpdateConfiguration(); + + // creating a centralWidget containing panel, m_view and the hidden findbar + QWidget *centralWidget = new QWidget; + centralWidget->setContentsMargins(0, 0, 0, 0); + + // setting layout + QVBoxLayout *layout = new QVBoxLayout; + layout->setContentsMargins(0, 0, 0, 0); + layout->addWidget(m_view); + layout->addWidget(m_findBar); + centralWidget->setLayout(layout); + + // central widget + setCentralWidget(centralWidget); + + // setting size policies + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + // then, setup our actions + setupActions(); + + // setting up toolbars: this has to be done BEFORE setupGUI!! + setupToolBars(); + + // Bookmark Menu + KActionMenu *bmMenu = Application::bookmarkProvider()->bookmarkActionMenu(); + actionCollection()->addAction(QLatin1String("bookmarks"), bmMenu); + + // Side Panel: this has to be done BEFORE setupGUI!! + setupSidePanel(); + + // a call to KXmlGuiWindow::setupGUI() populates the GUI + // with actions, using KXMLGUI. + // It also applies the saved mainwindow settings, if any, and ask the + // mainwindow to automatically save settings if changed: window size, + // toolbar position, icon size, etc. + setupGUI(); + + QTimer::singleShot(0, this, SLOT(postLaunch())); +} + + +MainWindow::~MainWindow() +{ + delete m_view; +} + + +void MainWindow::postLaunch() +{ + // setup history menu: this has to be done AFTER setupGUI!! + setupHistoryMenu(); + + // --------- connect signals and slots + connect(m_view, SIGNAL(setCurrentTitle(const QString &)), this, SLOT(slotUpdateWindowTitle(const QString &))); + connect(m_view, SIGNAL(loadProgress(int)), this, SLOT(slotLoadProgress(int))); + connect(m_view, SIGNAL(geometryChangeRequested(const QRect &)), this, SLOT(geometryChangeRequested(const QRect &))); + connect(m_view, SIGNAL(printRequested(QWebFrame *)), this, SLOT(printRequested(QWebFrame *))); + connect(m_view, SIGNAL(menuBarVisibilityChangeRequested(bool)), menuBar(), SLOT(setVisible(bool))); + connect(m_view, SIGNAL(statusBarVisibilityChangeRequested(bool)), statusBar(), SLOT(setVisible(bool))); + + // status bar messages + connect(m_view, SIGNAL(showStatusBarMessage(const QString&)), statusBar(), SLOT(showMessage(const QString&))); + connect(m_view, SIGNAL(linkHovered(const QString&)), statusBar(), SLOT(showMessage(const QString&))); + + // update toolbar actions signals + connect(m_view, SIGNAL(tabsChanged()), this, SLOT(slotUpdateActions())); + connect(m_view, SIGNAL(currentChanged(int)), this, SLOT(slotUpdateActions())); + + // Find Bar signal + connect(m_findBar, SIGNAL(searchString(const QString &)), this, SLOT(slotFind(const QString &))); + + // bookmarks loading + connect(Application::bookmarkProvider(), SIGNAL(openUrl(const KUrl&)), this, SLOT(loadUrl(const KUrl&))); + + // setting up toolbars to NOT have context menu enabled + setContextMenuPolicy(Qt::DefaultContextMenu); + + // accept d'n'd + setAcceptDrops(true); +} + + +QSize MainWindow::sizeHint() const +{ + QRect desktopRect = QApplication::desktop()->screenGeometry(); + QSize size = desktopRect.size() * 0.8; + return size; +} + + +void MainWindow::setupToolBars() +{ + KAction *a; + + // location bar + a = new KAction(i18n("Location Bar"), this); + a->setShortcut(KShortcut(Qt::Key_F6)); + a->setDefaultWidget(m_view->urlBarStack()); + actionCollection()->addAction(QLatin1String("url_bar"), a); + + // search bar + a = new KAction(i18n("Search Bar"), this); + a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_K)); + a->setDefaultWidget(m_searchBar); + connect(m_searchBar, SIGNAL(search(const KUrl&)), this, SLOT(loadUrl(const KUrl&))); + actionCollection()->addAction(QLatin1String("search_bar"), a); + + // bookmarks bar + KAction *bookmarkBarAction = Application::bookmarkProvider()->bookmarkToolBarAction(); + a = actionCollection()->addAction(QLatin1String("bookmarks_bar"), bookmarkBarAction); +} + + +void MainWindow::setupActions() +{ + KAction *a; + + // Standard Actions + KStandardAction::open(this, SLOT(slotFileOpen()), actionCollection()); + KStandardAction::saveAs(this, SLOT(slotFileSaveAs()), actionCollection()); + KStandardAction::printPreview(this, SLOT(slotFilePrintPreview()), actionCollection()); + KStandardAction::print(this, SLOT(slotFilePrint()), actionCollection()); + KStandardAction::quit(this , SLOT(close()), actionCollection()); + KStandardAction::find(this, SLOT(slotViewFindBar()) , actionCollection()); + KStandardAction::findNext(this, SLOT(slotFindNext()) , actionCollection()); + KStandardAction::findPrev(this, SLOT(slotFindPrevious()) , actionCollection()); + KStandardAction::fullScreen(this, SLOT(slotViewFullScreen(bool)), this, actionCollection()); + KStandardAction::home(this, SLOT(slotHome()), actionCollection()); + KStandardAction::preferences(this, SLOT(slotPreferences()), actionCollection()); + KStandardAction::showMenubar(this, SLOT(slotShowMenubar(bool)), actionCollection()); + + // WEB Actions (NO KStandardActions..) + a = KStandardAction::redisplay(m_view, SLOT(slotWebReload()), actionCollection()); + a->setText(i18n("Reload")); + KStandardAction::back(m_view, SLOT(slotWebBack()), actionCollection()); + KStandardAction::forward(m_view, SLOT(slotWebForward()), actionCollection()); + KStandardAction::undo(m_view, SLOT(slotWebUndo()), actionCollection()); + KStandardAction::redo(m_view, SLOT(slotWebRedo()), actionCollection()); + KStandardAction::cut(m_view, SLOT(slotWebCut()), actionCollection()); + KStandardAction::copy(m_view, SLOT(slotWebCopy()), actionCollection()); + KStandardAction::paste(m_view, SLOT(slotWebPaste()), actionCollection()); + + a = new KAction(KIcon("process-stop"), i18n("&Stop"), this); + a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Period)); + actionCollection()->addAction(QLatin1String("stop"), a); + connect(a, SIGNAL(triggered(bool)), m_view, SLOT(slotWebStop())); + + // stop reload Action + m_stopReloadAction = new KAction(KIcon("view-refresh"), i18n("Reload"), this); + actionCollection()->addAction(QLatin1String("stop_reload") , m_stopReloadAction); + m_stopReloadAction->setShortcutConfigurable(false); + + // ============== Custom Actions + a = new KAction(KIcon("document-open-remote"), i18n("Open Location"), this); + a->setShortcut(Qt::CTRL + Qt::Key_L); + actionCollection()->addAction(QLatin1String("open_location"), a); + connect(a, SIGNAL(triggered(bool)) , this, SLOT(slotOpenLocation())); + + a = new KAction(KIcon("zoom-in"), i18n("&Enlarge Font"), this); + a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Plus)); + actionCollection()->addAction(QLatin1String("bigger_font"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(slotViewTextBigger())); + + a = new KAction(KIcon("zoom-original"), i18n("&Normal Font"), this); + a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_0)); + actionCollection()->addAction(QLatin1String("normal_font"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(slotViewTextNormal())); + + a = new KAction(KIcon("zoom-out"), i18n("&Shrink Font"), this); + a->setShortcut(KShortcut(Qt::CTRL | Qt::Key_Minus)); + actionCollection()->addAction(QLatin1String("smaller_font"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(slotViewTextSmaller())); + + a = new KAction(i18n("Page S&ource"), this); + actionCollection()->addAction(QLatin1String("page_source"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(slotViewPageSource())); + + // ================ Tools (WebKit) Actions + a = new KAction(KIcon("tools-report-bug"), i18n("Web &Inspector"), this); + a->setCheckable(true); + actionCollection()->addAction(QLatin1String("web_inspector"), a); + connect(a, SIGNAL(triggered(bool)), this, SLOT(slotToggleInspector(bool))); + + a = new KAction(KIcon("view-media-artist"), i18n("Private &Browsing"), this); + a->setCheckable(true); + actionCollection()->addAction(QLatin1String("private_browsing"), a); + connect(a, SIGNAL(triggered(bool)) , this, SLOT(slotPrivateBrowsing(bool))); + + // ================ history related actions + m_historyBackAction = new KAction(KIcon("go-previous"), i18n("Back"), this); + m_historyBackMenu = new KMenu(this); + m_historyBackAction->setMenu(m_historyBackMenu); + connect(m_historyBackAction, SIGNAL(triggered(bool)), this, SLOT(slotOpenPrevious())); + connect(m_historyBackMenu, SIGNAL(aboutToShow()), this, SLOT(slotAboutToShowBackMenu())); + connect(m_historyBackMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotOpenActionUrl(QAction *))); + actionCollection()->addAction(QLatin1String("history_back"), m_historyBackAction); + + m_historyForwardAction = new KAction(KIcon("go-next"), i18n("Forward"), this); + connect(m_historyForwardAction, SIGNAL(triggered(bool)), this, SLOT(slotOpenNext())); + actionCollection()->addAction(QLatin1String("history_forward"), m_historyForwardAction); + + // =================== Tab Actions + a = new KAction(KIcon("tab-new"), i18n("New &Tab"), this); + QList newTabShortcutList; + newTabShortcutList << QKeySequence(QKeySequence::New); + newTabShortcutList << QKeySequence(QKeySequence::AddTab); + a->setShortcut(KShortcut(newTabShortcutList)); + actionCollection()->addAction(QLatin1String("new_tab"), a); + connect(a, SIGNAL(triggered(bool)), m_view, SLOT(newWebView())); + + a = new KAction(KIcon("tab-close"), i18n("&Close Tab"), this); + a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_W)); + actionCollection()->addAction(QLatin1String("close_tab"), a); + connect(a, SIGNAL(triggered(bool)), m_view, SLOT(slotCloseTab())); + + a = new KAction(i18n("Show Next Tab"), this); + a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabPrev() : KStandardShortcut::tabNext()); + actionCollection()->addAction(QLatin1String("show_next_tab"), a); + connect(a, SIGNAL(triggered(bool)), m_view, SLOT(nextTab())); + + a = new KAction(i18n("Show Previous Tab"), this); + a->setShortcuts(QApplication::isRightToLeft() ? KStandardShortcut::tabNext() : KStandardShortcut::tabPrev()); + actionCollection()->addAction(QLatin1String("show_prev_tab"), a); + connect(a, SIGNAL(triggered(bool)), m_view, SLOT(previousTab())); +} + + +void MainWindow::setupSidePanel() +{ + // Setup history side panel + m_sidePanel = new SidePanel(i18n("History"), this); + connect(m_sidePanel, SIGNAL(openUrl(const KUrl&)), this, SLOT(loadUrl(const KUrl&))); + connect(m_sidePanel, SIGNAL(destroyed()), Application::instance(), SLOT(slotSaveConfiguration())); + + addDockWidget(Qt::LeftDockWidgetArea, m_sidePanel); + + // setup side panel actions + KAction* a = new KAction(this); + a->setText(i18n("History")); + a->setCheckable(true); + a->setChecked(ReKonfig::showSideBar()); + a->setShortcut(KShortcut(Qt::CTRL + Qt::Key_H)); + actionCollection()->addAction(QLatin1String("show_history_panel"), a); + + // connect to toogle action + connect(a, SIGNAL(triggered(bool)), m_sidePanel->toggleViewAction(), SLOT(trigger())); +} + + +void MainWindow::setupHistoryMenu() +{ + HistoryMenu *historyMenu = new HistoryMenu(this); + connect(historyMenu, SIGNAL(openUrl(const KUrl&)), this, SLOT(loadUrl(const KUrl&))); + connect(historyMenu, SIGNAL(hovered(const QString&)), this, SLOT(slotUpdateStatusbar(const QString&))); + historyMenu->setTitle(i18n("&History")); + + // setting history menu position + menuBar()->insertMenu(actionCollection()->action("bookmarks"), historyMenu); + + // setting initial actions + QList historyActions; + historyActions.append(actionCollection()->action("history_back")); + historyActions.append(actionCollection()->action("history_forward")); + historyActions.append(m_view->recentlyClosedTabsAction()); + historyMenu->setInitialActions(historyActions); +} + + +void MainWindow::slotUpdateConfiguration() +{ + // ============== General ================== + m_homePage = ReKonfig::homePage(); + mainView()->showTabBar(); + mainView()->setMakeBackTab( ReKonfig::openTabsBack() ); + + // =========== Fonts ============== + QWebSettings *defaultSettings = QWebSettings::globalSettings(); + + int fnSize = ReKonfig::fontSize(); + + QFont standardFont = ReKonfig::standardFont(); + defaultSettings->setFontFamily(QWebSettings::StandardFont, standardFont.family()); + defaultSettings->setFontSize(QWebSettings::DefaultFontSize, fnSize); + + QFont fixedFont = ReKonfig::fixedFont(); + defaultSettings->setFontFamily(QWebSettings::FixedFont, fixedFont.family()); + defaultSettings->setFontSize(QWebSettings::DefaultFixedFontSize, fnSize); + + // ================ WebKit ============================ + defaultSettings->setAttribute(QWebSettings::AutoLoadImages, ReKonfig::autoLoadImages()); + defaultSettings->setAttribute(QWebSettings::JavascriptEnabled, ReKonfig::javascriptEnabled()); + defaultSettings->setAttribute(QWebSettings::JavaEnabled, ReKonfig::javaEnabled()); + defaultSettings->setAttribute(QWebSettings::PluginsEnabled, ReKonfig::pluginsEnabled()); + defaultSettings->setAttribute(QWebSettings::JavascriptCanOpenWindows, ReKonfig::javascriptCanOpenWindows()); + defaultSettings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, ReKonfig::javascriptCanAccessClipboard()); + defaultSettings->setAttribute(QWebSettings::LinksIncludedInFocusChain, ReKonfig::linksIncludedInFocusChain()); + defaultSettings->setAttribute(QWebSettings::ZoomTextOnly, ReKonfig::zoomTextOnly()); + defaultSettings->setAttribute(QWebSettings::PrintElementBackgrounds, ReKonfig::printElementBackgrounds()); + defaultSettings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, ReKonfig::offlineStorageDatabaseEnabled()); + defaultSettings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, ReKonfig::offlineWebApplicationCacheEnabled()); + defaultSettings->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, ReKonfig::localStorageDatabaseEnabled()); + + // ====== load Settings on main classes + Application::networkAccessManager()->loadSettings(); + Application::cookieJar()->loadSettings(); + Application::historyManager()->loadSettings(); +} + + +void MainWindow::slotUpdateBrowser() +{ + slotUpdateConfiguration(); + mainView()->slotReloadAllTabs(); +} + + +KUrl MainWindow::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 qurl(urlStr, QUrl::TolerantMode); + KUrl url(qurl); + + if (url.isValid()) + { + return url; + } + } + + // Might be a file. + if (QFile::exists(urlStr)) + { + QFileInfo info(urlStr); + return KUrl::fromPath(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 qurl(schema + QLatin1String("://") + urlStr, QUrl::TolerantMode); + KUrl url(qurl); + + if (url.isValid()) + { + return url; + } + } + } + + // Fall back to QUrl's own tolerant parser. + QUrl qurl = QUrl(string, QUrl::TolerantMode); + KUrl url(qurl); + + // finally for cases where the user just types in a hostname add http + if (qurl.scheme().isEmpty()) + { + qurl = QUrl(QLatin1String("http://") + string, QUrl::TolerantMode); + url = KUrl(qurl); + } + return url; +} + + +void MainWindow::loadUrl(const KUrl &url) +{ + m_view->loadUrl(url); +} + + +void MainWindow::slotOpenLocation() +{ + m_view->currentUrlBar()->selectAll(); + m_view->currentUrlBar()->setFocus(); +} + + +void MainWindow::slotFileSaveAs() +{ + KUrl srcUrl = currentTab()->url(); + Application::downloadManager()->newDownload(srcUrl); +} + + +void MainWindow::slotPreferences() +{ + // an instance the dialog could be already created and could be cached, + // in which case you want to display the cached dialog + if (SettingsDialog::showDialog("rekonfig")) + return; + + // we didn't find an instance of this dialog, so lets create it + SettingsDialog *s = new SettingsDialog(this); + + // keep us informed when the user changes settings + connect(s, SIGNAL(settingsChanged(const QString&)), this, SLOT(slotUpdateBrowser())); + + s->exec(); +} + + +void MainWindow::slotUpdateStatusbar(const QString &string) +{ + statusBar()->showMessage(string, 2000); +} + + +void MainWindow::slotUpdateActions() +{ + m_historyBackAction->setEnabled(currentTab()->history()->canGoBack()); + m_historyForwardAction->setEnabled(currentTab()->history()->canGoForward()); +} + + +void MainWindow::slotUpdateWindowTitle(const QString &title) +{ + if (title.isEmpty()) + { + setWindowTitle("rekonq"); + } + else + { + setWindowTitle(title + " - rekonq"); + } +} + + +void MainWindow::slotFileOpen() +{ + QString filePath = KFileDialog::getOpenFileName(KUrl(), + i18n("Web Resources (*.html *.htm *.svg *.png *.gif *.svgz); All files (*.*)"), + this, + i18n("Open Web Resource") + ); + + if (filePath.isEmpty()) + return; + + loadUrl(guessUrlFromString(filePath)); +} + + +void MainWindow::slotFilePrintPreview() +{ + if (!currentTab()) + return; + + QPrinter printer; + KPrintPreview previewdlg(&printer, this); + currentTab()->print(&printer); + previewdlg.exec(); +} + + +void MainWindow::slotFilePrint() +{ + if (!currentTab()) + return; + printRequested(currentTab()->page()->mainFrame()); +} + + +void MainWindow::printRequested(QWebFrame *frame) +{ + QPrinter printer; + + QPrintDialog *dialog = KdePrint::createPrintDialog(&printer, this); + if (dialog->exec() != QDialog::Accepted) + return; + frame->print(&printer); +} + + +void MainWindow::slotPrivateBrowsing(bool enable) +{ + QWebSettings *settings = QWebSettings::globalSettings(); + if (enable) + { + QString title = i18n("Are you sure you want to turn on private browsing?"); + QString text = "" + title + i18n("

When private browsing in turned on," + " webpages are not added to the history," + " new cookies are not stored, current cookies cannot be accessed," \ + " site icons will not be stored, session will not 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."); + + int button = KMessageBox::questionYesNo(this, text, title); + if (button == KMessageBox::Ok) + { + settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); + } + else + { + actionCollection()->action("private_browsing")->setChecked(false); + } + } + else + { + settings->setAttribute(QWebSettings::PrivateBrowsingEnabled, false); + + MainWindow* win = Application::instance()->mainWindow(); + win->m_lastSearch = QString::null; + win->mainView()->clear(); + } +} + +void MainWindow::slotFind(const QString & search) +{ + if (!currentTab()) + return; + m_lastSearch = search; + slotFindNext(); +} + + +void MainWindow::slotViewFindBar() +{ + m_findBar->showFindBar(); +} + + +void MainWindow::slotFindNext() +{ + if (!currentTab() && m_lastSearch.isEmpty()) + return; + + QWebPage::FindFlags options; + if (m_findBar->matchCase()) + { + options = QWebPage::FindCaseSensitively | QWebPage::FindWrapsAroundDocument; + } + else + { + options = QWebPage::FindWrapsAroundDocument; + } + + if (!currentTab()->findText(m_lastSearch, options)) + { + slotUpdateStatusbar(QString(m_lastSearch) + i18n(" not found.")); + } +} + + +void MainWindow::slotFindPrevious() +{ + if (!currentTab() && m_lastSearch.isEmpty()) + return; + + QWebPage::FindFlags options; + if (m_findBar->matchCase()) + { + options = QWebPage::FindCaseSensitively | QWebPage::FindBackward | QWebPage::FindWrapsAroundDocument; + } + else + { + options = QWebPage::FindBackward | QWebPage::FindWrapsAroundDocument; + } + + if (!currentTab()->findText(m_lastSearch, options)) + { + slotUpdateStatusbar(QString(m_lastSearch) + i18n(" not found.")); + } +} + + +void MainWindow::slotViewTextBigger() +{ + if (!currentTab()) + return; + currentTab()->setTextSizeMultiplier(currentTab()->textSizeMultiplier() + 0.1); +} + + +void MainWindow::slotViewTextNormal() +{ + if (!currentTab()) + return; + currentTab()->setTextSizeMultiplier(1.0); +} + + +void MainWindow::slotViewTextSmaller() +{ + if (!currentTab()) + return; + currentTab()->setTextSizeMultiplier(currentTab()->textSizeMultiplier() - 0.1); +} + + +void MainWindow::slotViewFullScreen(bool makeFullScreen) +{ + // state flags + static bool menubarFlag; + static bool mainToolBarFlag; + static bool bookmarksToolBarFlag; + static bool statusBarFlag; + static bool sidePanelFlag; + + if (makeFullScreen == true) + { + // save current state + menubarFlag = menuBar()->isHidden(); + mainToolBarFlag = toolBar("mainToolBar")->isHidden(); + bookmarksToolBarFlag = toolBar("bookmarksToolBar")->isHidden(); + statusBarFlag = statusBar()->isHidden(); + sidePanelFlag = sidePanel()->isHidden(); + + menuBar()->hide(); + toolBar("mainToolBar")->hide(); + toolBar("bookmarksToolBar")->hide(); + statusBar()->hide(); + sidePanel()->hide(); + } + else + { + if (!menubarFlag) + menuBar()->show(); + if (!mainToolBarFlag) + toolBar("mainToolBar")->show(); + if (!bookmarksToolBarFlag) + toolBar("bookmarksToolBar")->show(); + if (!statusBarFlag) + statusBar()->show(); + if (!sidePanelFlag) + sidePanel()->show(); + } + + KToggleFullScreenAction::setFullScreen(this, makeFullScreen); +} + + +void MainWindow::slotViewPageSource() +{ + if (!currentTab()) + return; + + KUrl url(currentTab()->url()); + bool isTempFile = false; + if (!url.isLocalFile()) + { + KTemporaryFile sourceFile; + + /// TODO: autochoose tempfile suffix + sourceFile.setSuffix(QString(".html")); + sourceFile.setAutoRemove(false); + + if (sourceFile.open()) + { + QDataStream stream(&sourceFile); + stream << currentTab()->page()->mainFrame()->toHtml().toUtf8(); + + url = KUrl(); + url.setPath(sourceFile.fileName()); + isTempFile = true; + } + } + KRun::runUrl(url, QLatin1String("text/plain"), this, isTempFile); +} + + +void MainWindow::slotHome() +{ + loadUrl(KUrl(m_homePage)); +} + + +void MainWindow::slotToggleInspector(bool enable) +{ + QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, enable); + if (enable) + { + int result = KMessageBox::questionYesNo(this, + i18n("The web inspector will only work correctly for pages that were loaded after enabling.\n" + "Do you want to reload all pages?"), + i18n("Web Inspector") + ); + + if (result == KMessageBox::Yes) + { + m_view->slotReloadAllTabs(); + } + } +} + + +MainView *MainWindow::mainView() const +{ + return m_view; +} + + + +WebView *MainWindow::currentTab() const +{ + return m_view->currentWebView(); +} + + +void MainWindow::slotLoadProgress(int progress) +{ + QAction *stop = actionCollection()->action("stop"); + QAction *reload = actionCollection()->action("view_redisplay"); + if (progress < 100 && progress > 0) + { + disconnect(m_stopReloadAction, SIGNAL(triggered(bool)), reload , SIGNAL(triggered(bool))); + m_stopReloadAction->setIcon(KIcon("process-stop")); + m_stopReloadAction->setToolTip(i18n("Stop loading the current page")); + m_stopReloadAction->setText(i18n("Stop")); + connect(m_stopReloadAction, SIGNAL(triggered(bool)), stop, SIGNAL(triggered(bool))); + } + else + { + disconnect(m_stopReloadAction, SIGNAL(triggered(bool)), stop , SIGNAL(triggered(bool))); + m_stopReloadAction->setIcon(KIcon("view-refresh")); + m_stopReloadAction->setToolTip(i18n("Reload the current page")); + m_stopReloadAction->setText(i18n("Reload")); + connect(m_stopReloadAction, SIGNAL(triggered(bool)), reload, SIGNAL(triggered(bool))); + + } +} + + +void MainWindow::slotAboutToShowBackMenu() +{ + m_historyBackMenu->clear(); + if (!currentTab()) + return; + QWebHistory *history = currentTab()->history(); + int historyCount = history->count(); + for (int i = history->backItems(historyCount).count() - 1; i >= 0; --i) + { + QWebHistoryItem item = history->backItems(history->count()).at(i); + KAction *action = new KAction(this); + action->setData(-1*(historyCount - i - 1)); + QIcon icon = Application::instance()->icon(item.url()); + action->setIcon(icon); + action->setText(item.title()); + m_historyBackMenu->addAction(action); + } +} + + +void MainWindow::slotOpenActionUrl(QAction *action) +{ + int offset = action->data().toInt(); + QWebHistory *history = currentTab()->history(); + if (offset < 0) + { + history->goToItem(history->backItems(-1*offset).first()); // back + } + else + { + if (offset > 0) + { + history->goToItem(history->forwardItems(history->count() - offset + 1).back()); // forward + } + } +} + + +void MainWindow::slotOpenPrevious() +{ + QWebHistory *history = currentTab()->history(); + if (history->canGoBack()) + history->goToItem(history->backItem()); +} + + +void MainWindow::slotOpenNext() +{ + QWebHistory *history = currentTab()->history(); + if (history->canGoForward()) + history->goToItem(history->forwardItem()); +} + + +void MainWindow::geometryChangeRequested(const QRect &geometry) +{ + setGeometry(geometry); +} + + +void MainWindow::slotShowMenubar(bool enable) +{ + if (enable) + menuBar()->show(); + else + menuBar()->hide(); +} + + +bool MainWindow::queryClose() +{ + if (m_view->count() > 1) + { + + int answer = KMessageBox::questionYesNoCancel( + this, + i18np("Are you sure you want to close the window?\n" "You have 1 tab open","Are you sure you want to close the window?\n" "You have %1 tabs open" , m_view->count()), + i18n("Are you sure you want to close the window?"), + KStandardGuiItem::quit(), + KGuiItem(i18n("C&lose Current Tab"), KIcon("tab-close")), + KStandardGuiItem::cancel(), + "confirmClosingMultipleTabs" + ); + + switch (answer) + { + case KMessageBox::Yes: + // Quit + return true; + break; + case KMessageBox::No: + // Close only the current tab + m_view->slotCloseTab(); + default: + return false; + } + } + + return true; +} + + +QAction *MainWindow::actionByName(const QString name) +{ + QAction *ret = actionCollection()->action(name); + + if (ret) + return ret; + + /* else */ + kWarning() << "Action named: " << name << " not found, returning empty action."; + + return new QAction(this); // return empty object instead of NULL pointer +} + diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100644 index 00000000..cdb7151d --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,153 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +// Local Includes +#include "searchbar.h" +#include "bookmarks.h" +#include "mainview.h" +#include "webview.h" + +// KDE Includes +#include +#include + +// Forward Declarations +class QWebFrame; + +class KUrl; +class KAction; +class KActionMenu; +class KIcon; +class KMenu; + +class FindBar; +class HistoryMenu; +class SidePanel; +class WebView; + + +/** + * This class serves as the main window for rekonq. + * It handles the menus, toolbars, and status bars. + * + */ +class MainWindow : public KXmlGuiWindow +{ + Q_OBJECT + +public: + MainWindow(); + ~MainWindow(); + + static KUrl guessUrlFromString(const QString &url); + MainView *mainView() const; + WebView *currentTab() const; + QAction *actionByName(const QString name); + virtual QSize sizeHint() const; + +private: + void setupActions(); + void setupHistoryMenu(); + void setupToolBars(); + void setupSidePanel(); + SidePanel *sidePanel() + { + return m_sidePanel; + } + +public slots: + void slotHome(); + void loadUrl(const KUrl &url); + void slotUpdateBrowser(); + +protected: + bool queryClose(); + +private slots: + void postLaunch(); + void slotUpdateConfiguration(); + void slotLoadProgress(int); + void slotUpdateStatusbar(const QString &string); + void slotUpdateActions(); + void slotUpdateWindowTitle(const QString &title = QString()); + void slotOpenLocation(); + void slotAboutToShowBackMenu(); + void geometryChangeRequested(const QRect &geometry); + + // history related + void slotOpenActionUrl(QAction *action); + void slotOpenPrevious(); + void slotOpenNext(); + + // File Menu slots + void slotFileOpen(); + void slotFilePrintPreview(); + void slotFilePrint(); + void slotPrivateBrowsing(bool); + void slotFileSaveAs(); + void printRequested(QWebFrame *frame); + + // Edit Menu slots + void slotFind(const QString &); + void slotFindNext(); + void slotFindPrevious(); + + // View Menu slots + void slotViewTextBigger(); + void slotViewTextNormal(); + void slotViewTextSmaller(); + void slotViewPageSource(); + void slotViewFullScreen(bool enable); + void slotViewFindBar(); + + // Tools Menu slots + void slotToggleInspector(bool enable); + + // Settings Menu slots + void slotShowMenubar(bool enable); + void slotPreferences(); + +private: + MainView *m_view; + FindBar *m_findBar; + SearchBar *m_searchBar; + SidePanel *m_sidePanel; + + KMenu *m_historyBackMenu; + KMenu *m_windowMenu; + KActionMenu *m_historyActionMenu; + + KAction *m_stopReloadAction; + KAction *m_stopAction; + KAction *m_reloadAction; + KAction *m_historyBackAction; + KAction *m_historyForwardAction; + + QString m_lastSearch; + QString m_homePage; +}; + +#endif // MAINWINDOW_H diff --git a/src/modelmenu.cpp b/src/modelmenu.cpp new file mode 100644 index 00000000..cc43a3f3 --- /dev/null +++ b/src/modelmenu.cpp @@ -0,0 +1,228 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +#include "modelmenu.h" + + +ModelMenu::ModelMenu(QWidget * parent) + : KMenu(parent) + , m_maxRows(7) + , m_firstSeparator(-1) + , m_maxWidth(-1) + , m_hoverRole(0) + , m_separatorRole(0) + , m_model(0) +{ + connect(this, SIGNAL(aboutToShow()), this, SLOT(aboutToShow())); +} + + +bool ModelMenu::prePopulated() +{ + return false; +} + + +void ModelMenu::postPopulated() +{ +} + + +void ModelMenu::setModel(QAbstractItemModel *model) +{ + m_model = model; +} + + +QAbstractItemModel *ModelMenu::model() const +{ + return m_model; +} + + +void ModelMenu::setMaxRows(int max) +{ + m_maxRows = max; +} + + +int ModelMenu::maxRows() const +{ + return m_maxRows; +} + + +void ModelMenu::setFirstSeparator(int offset) +{ + m_firstSeparator = offset; +} + + +int ModelMenu::firstSeparator() const +{ + return m_firstSeparator; +} + + +void ModelMenu::setRootIndex(const QModelIndex &index) +{ + m_root = index; +} + + +QModelIndex ModelMenu::rootIndex() const +{ + return m_root; +} + + +void ModelMenu::setHoverRole(int role) +{ + m_hoverRole = role; +} + + +int ModelMenu::hoverRole() const +{ + return m_hoverRole; +} + + +void ModelMenu::setSeparatorRole(int role) +{ + m_separatorRole = role; +} + + +int ModelMenu::separatorRole() const +{ + return m_separatorRole; +} + + +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; + if (max != -1) + max += m_firstSeparator; + createMenu(m_root, max, this, this); + postPopulated(); +} + +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())); + return; + } + + int end = m_model->rowCount(parent); + if (max != -1) + end = qMin(max, end); + + connect(menu, SIGNAL(triggered(QAction*)), this, SLOT(triggered(QAction*))); + connect(menu, SIGNAL(hovered(QAction*)), this, SLOT(hovered(QAction*))); + + for (int i = 0; i < end; ++i) + { + QModelIndex idx = m_model->index(i, 0, parent); + if (m_model->hasChildren(idx)) + { + createMenu(idx, -1, menu); + } + else + { + if (m_separatorRole != 0 + && idx.data(m_separatorRole).toBool()) + addSeparator(); + else + menu->addAction(makeAction(idx)); + } + if (menu == this && i == m_firstSeparator - 1) + addSeparator(); + } +} + +KAction *ModelMenu::makeAction(const QModelIndex &index) +{ + QIcon icon = qvariant_cast(index.data(Qt::DecorationRole)); + KAction *action = (KAction *) makeAction(KIcon(icon), index.data().toString(), this); + QVariant v; + v.setValue(index); + action->setData(v); + return action; +} + +KAction *ModelMenu::makeAction(const KIcon &icon, const QString &text, QObject *parent) +{ + QFontMetrics fm(font()); + if (-1 == m_maxWidth) + m_maxWidth = fm.width(QLatin1Char('m')) * 30; + QString smallText = fm.elidedText(text, Qt::ElideMiddle, m_maxWidth); + return new KAction(icon, smallText, parent); +} + +void ModelMenu::triggered(QAction *action) +{ + QVariant v = action->data(); + if (v.canConvert()) + { + QModelIndex idx = qvariant_cast(v); + emit activated(idx); + } +} + +void ModelMenu::hovered(QAction *action) +{ + QVariant v = action->data(); + if (v.canConvert()) + { + QModelIndex idx = qvariant_cast(v); + QString hoveredString = idx.data(m_hoverRole).toString(); + if (!hoveredString.isEmpty()) + emit hovered(hoveredString); + } +} diff --git a/src/modelmenu.h b/src/modelmenu.h new file mode 100644 index 00000000..3cc657b3 --- /dev/null +++ b/src/modelmenu.h @@ -0,0 +1,92 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef MODELMENU_H +#define MODELMENU_H + +// Qt Includes +#include +#include + +// KDE Includes +#include +#include +#include + +// A QMenu that is dynamically populated from a QAbstractItemModel +class ModelMenu : public KMenu +{ + Q_OBJECT + +signals: + void activated(const QModelIndex &index); + void hovered(const QString &text); + +public: + ModelMenu(QWidget *parent = 0); + + void setModel(QAbstractItemModel *model); + QAbstractItemModel *model() const; + + void setMaxRows(int max); + int maxRows() const; + + void setFirstSeparator(int offset); + int firstSeparator() const; + + void setRootIndex(const QModelIndex &index); + QModelIndex rootIndex() const; + + void setHoverRole(int role); + int hoverRole() const; + + void setSeparatorRole(int role); + int separatorRole() const; + + KAction *makeAction(const KIcon &icon, const QString &text, QObject *parent); + +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(); + // 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); + +private slots: + void aboutToShow(); + void triggered(QAction *action); + void hovered(QAction *action); + +private: + KAction *makeAction(const QModelIndex &index); + int m_maxRows; + int m_firstSeparator; + int m_maxWidth; + int m_hoverRole; + int m_separatorRole; + QAbstractItemModel *m_model; + QPersistentModelIndex m_root; +}; + +#endif // MODELMENU_H + diff --git a/src/networkaccessmanager.cpp b/src/networkaccessmanager.cpp new file mode 100644 index 00000000..d92edbd6 --- /dev/null +++ b/src/networkaccessmanager.cpp @@ -0,0 +1,165 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "networkaccessmanager.h" +#include "networkaccessmanager.moc" + +// Local Includes +#include "application.h" +#include "mainwindow.h" + +// Auto Includes +#include "rekonq.h" + +// Ui Includes +#include "ui_password.h" +#include "ui_proxy.h" + +// KDE Includes +#include +#include + +// Qt Includes +#include +#include +#include +#include +#include +#include +#include + + +NetworkAccessManager::NetworkAccessManager(QObject *parent) + : QNetworkAccessManager(parent) +{ + connect(this, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), + SLOT(authenticationRequired(QNetworkReply*, QAuthenticator*))); + connect(this, SIGNAL(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*)), + SLOT(proxyAuthenticationRequired(const QNetworkProxy&, QAuthenticator*))); + +#ifndef QT_NO_OPENSSL + connect(this, SIGNAL(sslErrors(QNetworkReply*, const QList&)), + SLOT(sslErrors(QNetworkReply*, const QList&))); +#endif + + loadSettings(); + + QNetworkDiskCache *diskCache = new QNetworkDiskCache(this); + QString location = KStandardDirs::locateLocal("cache", "", true); + diskCache->setCacheDirectory(location); + setCache(diskCache); +} + + +void NetworkAccessManager::loadSettings() +{ + QNetworkProxy proxy; + if (ReKonfig::isProxyEnabled()) + { + if (ReKonfig::proxyType() == 0) + { + proxy.setType(QNetworkProxy::Socks5Proxy); + } + else + { + proxy.setType(QNetworkProxy::HttpProxy); + } + proxy.setHostName(ReKonfig::proxyHostName()); + proxy.setPort(ReKonfig::proxyPort()); + proxy.setUser(ReKonfig::proxyUserName()); + proxy.setPassword(ReKonfig::proxyPassword()); + } + setProxy(proxy); +} + + + +void NetworkAccessManager::authenticationRequired(QNetworkReply *reply, QAuthenticator *auth) +{ + MainWindow *mainWindow = Application::instance()->mainWindow(); + + KDialog dialog(mainWindow, Qt::Sheet); + dialog.setButtons(KDialog::Ok | KDialog::Cancel); + + Ui::passwordWidget passwordWidget; + QWidget widget; + passwordWidget.setupUi(&widget); + + dialog.setMainWidget(&widget); + + passwordWidget.iconLabel->setText(QString()); + passwordWidget.iconLabel->setPixmap(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow).pixmap(32, 32)); + + QString introMessage = i18n("Enter username and password for ") + + Qt::escape(reply->url().toString()) + i18n(" at ") + Qt::escape(reply->url().toString()) + ""; + passwordWidget.introLabel->setText(introMessage); + passwordWidget.introLabel->setWordWrap(true); + + if (dialog.exec() == QDialog::Accepted) + { + auth->setUser(passwordWidget.userNameLineEdit->text()); + auth->setPassword(passwordWidget.passwordLineEdit->text()); + } +} + +void NetworkAccessManager::proxyAuthenticationRequired(const QNetworkProxy &proxy, QAuthenticator *auth) +{ + MainWindow *mainWindow = Application::instance()->mainWindow(); + + KDialog dialog(mainWindow, Qt::Sheet); + dialog.setButtons(KDialog::Ok | KDialog::Cancel); + + Ui::proxyWidget proxyWdg; + QWidget widget; + proxyWdg.setupUi(&widget); + + dialog.setMainWidget(&widget); + + proxyWdg.iconLabel->setText(QString()); + proxyWdg.iconLabel->setPixmap(mainWindow->style()->standardIcon(QStyle::SP_MessageBoxQuestion, 0, mainWindow).pixmap(32, 32)); + + QString introMessage = i18n("Connect to proxy ") + Qt::escape(proxy.hostName()) + i18n(" using:"); + proxyWdg.introLabel->setText(introMessage); + proxyWdg.introLabel->setWordWrap(true); + + if (dialog.exec() == QDialog::Accepted) + { + auth->setUser(proxyWdg.userNameLineEdit->text()); + auth->setPassword(proxyWdg.passwordLineEdit->text()); + } +} + +#ifndef QT_NO_OPENSSL +void NetworkAccessManager::sslErrors(QNetworkReply *reply, const QList &error) +{ + MainWindow *mainWindow = Application::instance()->mainWindow(); + + QStringList errorStrings; + for (int i = 0; i < error.count(); ++i) + errorStrings += error.at(i).errorString(); + QString errors = errorStrings.join(QLatin1String("\n")); + int ret = KMessageBox::warningYesNo(mainWindow, i18n("SSL Errors:\n\n") + reply->url().toString() + "\n\n" + QString(errors) + "\n\n"); + if (ret == KMessageBox::Yes) + reply->ignoreSslErrors(); +} +#endif + diff --git a/src/networkaccessmanager.h b/src/networkaccessmanager.h new file mode 100644 index 00000000..ebcd952d --- /dev/null +++ b/src/networkaccessmanager.h @@ -0,0 +1,47 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef NETWORKACCESSMANAGER_H +#define NETWORKACCESSMANAGER_H + + +#include + + +class NetworkAccessManager : public QNetworkAccessManager +{ + Q_OBJECT + +public: + NetworkAccessManager(QObject *parent = 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 +}; + +#endif // NETWORKACCESSMANAGER_H diff --git a/src/panelhistory.cpp b/src/panelhistory.cpp new file mode 100644 index 00000000..72507663 --- /dev/null +++ b/src/panelhistory.cpp @@ -0,0 +1,95 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Domrachev Alexandr +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "panelhistory.h" +#include "panelhistory.moc" + +// QT Includes +#include + +// KDE Includes +#include +#include +#include + +// Local Includes +#include "history.h" + + +PanelHistory::PanelHistory(QWidget *parent) + : QWidget(parent) + , m_historyTreeView(new QTreeView) + , m_treeProxyModel(new TreeProxyModel(this)) +{ + m_historyTreeView->setUniformRowHeights(true); + m_historyTreeView->setSelectionBehavior(QAbstractItemView::SelectRows); + m_historyTreeView->setTextElideMode(Qt::ElideMiddle); + m_historyTreeView->setAlternatingRowColors(true); + + // add search bar + QHBoxLayout *hBoxLayout = new QHBoxLayout; + hBoxLayout->setContentsMargins(5, 0, 0, 0); + QLabel *searchLabel = new QLabel(i18n("Search: ")); + hBoxLayout->addWidget(searchLabel); + KLineEdit *search = new KLineEdit; + hBoxLayout->addWidget(search); + QWidget *searchBar = new QWidget; + searchBar->setLayout(hBoxLayout); + + // setup view + QVBoxLayout *vBoxLayout = new QVBoxLayout; + vBoxLayout->setContentsMargins(0, 0, 0, 0); + vBoxLayout->addWidget(searchBar); + vBoxLayout->addWidget(m_historyTreeView); + setLayout(vBoxLayout); + + //- + HistoryManager *historyManager = Application::historyManager(); + QAbstractItemModel *model = historyManager->historyTreeModel(); + + m_treeProxyModel->setSourceModel(model); + m_historyTreeView->setModel(m_treeProxyModel); + m_historyTreeView->setExpanded(m_treeProxyModel->index(0, 0), true); + m_historyTreeView->header()->hideSection(1); + QFontMetrics fm(font()); + int header = fm.width(QLatin1Char('m')) * 40; + m_historyTreeView->header()->resizeSection(0, header); + + connect(search, SIGNAL(textChanged(QString)), m_treeProxyModel, SLOT(setFilterFixedString(QString))); + connect(m_historyTreeView, SIGNAL(activated(const QModelIndex&)), this, SLOT(open())); +} + + +PanelHistory::~PanelHistory() +{ + delete m_treeProxyModel; + delete m_historyTreeView; +} + + +void PanelHistory::open() +{ + QModelIndex index = m_historyTreeView->currentIndex(); + if (!index.parent().isValid()) + return; + emit openUrl(index.data(HistoryModel::UrlRole).toUrl()); +} + diff --git a/src/panelhistory.h b/src/panelhistory.h new file mode 100644 index 00000000..89759a84 --- /dev/null +++ b/src/panelhistory.h @@ -0,0 +1,55 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Domrachev Alexandr +* +* +* 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, 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. +* +* ============================================================ */ + +#ifndef PANELHISTORY_H +#define PANELHISTORY_H + +// Qt Includes +#include + +// Local Includes +#include "application.h" + +class QTreeView; +class KUrl; +class TreeProxyModel; + + +class PanelHistory : public QWidget +{ + Q_OBJECT + Q_DISABLE_COPY(PanelHistory) + +public: + explicit PanelHistory(QWidget *parent = 0); + virtual ~PanelHistory(); + +signals: + void openUrl(const KUrl &); + +private slots: + void open(); + +private: + QTreeView *m_historyTreeView; + TreeProxyModel *m_treeProxyModel; + +}; + +#endif // PANELHISTORY_H diff --git a/src/password.ui b/src/password.ui new file mode 100644 index 00000000..028e1683 --- /dev/null +++ b/src/password.ui @@ -0,0 +1,69 @@ + + + passwordWidget + + + + 0 + 0 + 343 + 193 + + + + Form + + + + + + + + DUMMY ICON + + + + + + + + 0 + 0 + + + + INTRO TEXT DUMMY + + + + + + + + + Username: + + + + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + + diff --git a/src/proxy.ui b/src/proxy.ui new file mode 100644 index 00000000..e7440862 --- /dev/null +++ b/src/proxy.ui @@ -0,0 +1,62 @@ + + + proxyWidget + + + + 0 + 0 + 264 + 153 + + + + Form + + + + + + ICON + + + + + + + Connect to proxy + + + true + + + + + + + Username: + + + + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + + diff --git a/src/rekonq.kcfg b/src/rekonq.kcfg new file mode 100644 index 00000000..499258d2 --- /dev/null +++ b/src/rekonq.kcfg @@ -0,0 +1,119 @@ + + + + + +QtWebKit +KUrl + + + + + http://www.kde.org/ + + + $HOME + + + false + + + true + + + false + + + false + + + + + + + QFont(QWebSettings::globalSettings()->fontFamily(QWebSettings::StandardFont)) + + + QFont(QWebSettings::globalSettings()->fontFamily(QWebSettings::FixedFont)) + + + 12 + + + + + + + 1 + + + 2 + + + 0 + + + + + + + false + + + 0 + + + + + 8080 + + + + + + + + + + + true + + + true + + + true + + + true + + + true + + + false + + + true + + + false + + + true + + + true + + + true + + + true + + + + diff --git a/src/rekonq.kcfgc b/src/rekonq.kcfgc new file mode 100644 index 00000000..50a9817d --- /dev/null +++ b/src/rekonq.kcfgc @@ -0,0 +1,5 @@ +File=rekonq.kcfg +ClassName=ReKonfig +Singleton=true +Mutators=true +UseEnumTypes=true diff --git a/src/rekonqui.rc b/src/rekonqui.rc new file mode 100644 index 00000000..aa372538 --- /dev/null +++ b/src/rekonqui.rc @@ -0,0 +1,104 @@ + + + + + + + +&File + + + + + + + + + + + + + + + +&Edit + + + + + + + + + + + + + +&View + + + + + + + + + + + + + + + +Hi&story + + + +&Bookmarks + + + +&Tools + + + + + +&Settings + + + + + Side &Panels + + + + + + + + + + + + + + +Main Toolbar + + + + + + + + + + + + + diff --git a/src/searchbar.cpp b/src/searchbar.cpp new file mode 100644 index 00000000..fad35748 --- /dev/null +++ b/src/searchbar.cpp @@ -0,0 +1,129 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "searchbar.h" +#include "searchbar.moc" + +// Local Includes +#include "application.h" +#include "mainwindow.h" + +// KDE Includes +#include + +// Qt Includes +#include +#include +#include + + +SearchBar::SearchBar(QWidget *parent) : + KLineEdit(parent) + , m_networkAccessManager(new QNetworkAccessManager(this)) + , m_timer(new QTimer(this)) +{ + setMinimumWidth(180); + + setFocusPolicy(Qt::WheelFocus); + setMouseTracking(true); + setAcceptDrops(true); + + QSizePolicy policy = sizePolicy(); + setSizePolicy(QSizePolicy::Preferred, policy.verticalPolicy()); + + setClearButtonShown(true); + + // better solution than using QPalette(s).. + setClickMessage(i18n("Search..")); + + // setting QNetworkAccessManager.. + connect(m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleNetworkData(QNetworkReply*))); + + // setting QTimer.. + m_timer->setSingleShot(true); + m_timer->setInterval(200); + connect(m_timer, SIGNAL(timeout()), SLOT(autoSuggest())); + connect(this, SIGNAL(textEdited(QString)), m_timer, SLOT(start())); + + // connect searchNow slot.. + connect(this, SIGNAL(returnPressed()) , this , SLOT(searchNow())); +} + + +SearchBar::~SearchBar() +{ +} + + +void SearchBar::searchNow() +{ + m_timer->stop(); + QString searchText = text(); + + KUrl 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"), QLatin1String("rekonq")); + emit search(url); +} + + +void SearchBar::focusInEvent(QFocusEvent *event) +{ + KLineEdit::focusInEvent(event); + clear(); +} + + +void SearchBar::autoSuggest() +{ + QString str = text(); + QString url = QString("http://google.com/complete/search?output=toolbar&q=%1").arg(str); + m_networkAccessManager->get(QNetworkRequest(QString(url))); +} + + +void SearchBar::handleNetworkData(QNetworkReply *networkReply) +{ + QUrl url = networkReply->url(); + if (!networkReply->error()) + { + QStringList choices; + + QString response(networkReply->readAll()); + QXmlStreamReader xml(response); + while (!xml.atEnd()) + { + xml.readNext(); + if (xml.tokenType() == QXmlStreamReader::StartElement) + if (xml.name() == "suggestion") + { + QStringRef str = xml.attributes().value("data"); + choices << str.toString(); + } + } + + setCompletedItems(choices, true); + } + + networkReply->deleteLater(); +} diff --git a/src/searchbar.h b/src/searchbar.h new file mode 100644 index 00000000..3fdf55b4 --- /dev/null +++ b/src/searchbar.h @@ -0,0 +1,67 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef SEARCHBAR_H +#define SEARCHBAR_H + +// KDE Includes +#include + +// Forward Declarations +class KUrl; +class QFocusEvent; +class QTimer; +class QNetworkAccessManager; +class QNetworkReply; + +/** + * This class defines an internet search bar. + */ +class SearchBar : public KLineEdit +{ + Q_OBJECT + +public: + SearchBar(QWidget *parent = 0); + ~SearchBar(); + +public slots: + void autoSuggest(); + void handleNetworkData(QNetworkReply *networkReply); + + /** + * Use this slot to perform one search in one search engine + * + */ + void searchNow(); + +protected: + void focusInEvent(QFocusEvent *); + +signals: + void search(const KUrl &); + +private: + QNetworkAccessManager *m_networkAccessManager; + QTimer *m_timer; +}; + +#endif diff --git a/src/settings.cpp b/src/settings.cpp new file mode 100644 index 00000000..1e42413f --- /dev/null +++ b/src/settings.cpp @@ -0,0 +1,212 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + + +// Self Includes +#include "settings.h" +#include "settings.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "application.h" +#include "mainwindow.h" +#include "cookiejar.h" +#include "history.h" +#include "networkaccessmanager.h" +#include "webview.h" + +//Ui Includes +#include "ui_settings_general.h" +#include "ui_settings_fonts.h" +#include "ui_settings_privacy.h" +#include "ui_settings_proxy.h" +#include "ui_settings_webkit.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include + + +class Private +{ +private: + Ui::general generalUi; + Ui::fonts fontsUi; + Ui::privacy privacyUi; + Ui::proxy proxyUi; + Ui::webkit webkitUi; + + Private(SettingsDialog *parent); + + friend class SettingsDialog; +}; + + +Private::Private(SettingsDialog *parent) +{ + QWidget *widget; + KPageWidgetItem *pageItem; + + widget = new QWidget; + generalUi.setupUi(widget); + widget->layout()->setMargin(0); + pageItem = parent->addPage(widget , i18n("General")); + pageItem->setIcon(KIcon("rekonq")); + + widget = new QWidget; + fontsUi.setupUi(widget); + widget->layout()->setMargin(0); + pageItem = parent->addPage(widget , i18n("Fonts")); + pageItem->setIcon(KIcon("preferences-desktop-font")); + + widget = new QWidget; + privacyUi.setupUi(widget); + widget->layout()->setMargin(0); + pageItem = parent->addPage(widget , i18n("Privacy")); + pageItem->setIcon(KIcon("preferences-desktop-personal")); + + widget = new QWidget; + proxyUi.setupUi(widget); + widget->layout()->setMargin(0); + pageItem = parent->addPage(widget , i18n("Proxy")); + pageItem->setIcon(KIcon("preferences-system-network")); + + widget = new QWidget; + webkitUi.setupUi(widget); + widget->layout()->setMargin(0); + pageItem = parent->addPage(widget , i18n("Webkit")); + QString webkitIconPath = KStandardDirs::locate("appdata", "pics/webkit-icon.png"); + kWarning() << webkitIconPath; + KIcon webkitIcon = KIcon(QIcon(webkitIconPath)); + pageItem->setIcon(webkitIcon); +} + +// ----------------------------------------------------------------------------------------------------- + +SettingsDialog::SettingsDialog(QWidget *parent) + : KConfigDialog(parent, "rekonfig", ReKonfig::self()) + , d(new Private(this)) +{ + setFaceType(KPageDialog::List); + showButtonSeparator(true); + + setWindowTitle(i18n("rekonfig..")); + setModal(true); + + readConfig(); + + connect(d->generalUi.setHomeToCurrentPageButton, SIGNAL(clicked()), this, SLOT(setHomeToCurrentPage())); + connect(d->privacyUi.exceptionsButton, SIGNAL(clicked()), this, SLOT(showExceptions())); + connect(d->privacyUi.cookiesButton, SIGNAL(clicked()), this, SLOT(showCookies())); + + setWebSettingsToolTips(); +} + + + +SettingsDialog::~SettingsDialog() +{ + delete d; +} + + +void SettingsDialog::setWebSettingsToolTips() +{ + d->webkitUi.kcfg_autoLoadImages->setToolTip(i18n("Specifies whether images are automatically loaded in web pages")); + d->webkitUi.kcfg_javascriptEnabled->setToolTip(i18n("Enables the running of JavaScript programs.")); + d->webkitUi.kcfg_javaEnabled->setToolTip(i18n("Enables Java applets.")); + d->webkitUi.kcfg_pluginsEnabled->setToolTip(i18n("Enables plugins in web pages.")); + d->webkitUi.kcfg_javascriptCanOpenWindows->setToolTip(i18n("Allows JavaScript programs to opening new windows.")); + d->webkitUi.kcfg_javascriptCanAccessClipboard->setToolTip(i18n("Allows JavaScript programs to reading/writing to the clipboard.")); + d->webkitUi.kcfg_linksIncludedInFocusChain->setToolTip(i18n("Includes hyperlinks in the keyboard focus chain.")); + d->webkitUi.kcfg_zoomTextOnly->setToolTip(i18n("Applies the zoom factor on a frame to only the text or all content.")); + d->webkitUi.kcfg_printElementBackgrounds->setToolTip(i18n("Draws also background color and images when the page is printed.")); + d->webkitUi.kcfg_offlineStorageDatabaseEnabled->setToolTip(i18n("Support for the HTML 5 offline storage feature.")); + d->webkitUi.kcfg_offlineWebApplicationCacheEnabled->setToolTip(i18n("Support for the HTML 5 web application cache feature.")); + d->webkitUi.kcfg_localStorageDatabaseEnabled->setToolTip(i18n("Support for the HTML 5 local storage feature.")); +} + + +// we need this function to UPDATE the config widget data.. +void SettingsDialog::readConfig() +{ + // ======= General + d->generalUi.downloadDirUrlRequester->setMode(KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly); + d->generalUi.downloadDirUrlRequester->setUrl(ReKonfig::downloadDir()); + connect(d->generalUi.downloadDirUrlRequester, SIGNAL(textChanged(QString)), this, SLOT(saveSettings())); + + // ======= Fonts + d->fontsUi.kcfg_fixedFont->setOnlyFixed(true); + + // ======= Proxy + bool proxyEnabled = ReKonfig::isProxyEnabled(); + d->proxyUi.groupBox->setEnabled(proxyEnabled); + connect(d->proxyUi.kcfg_isProxyEnabled, SIGNAL(clicked(bool)), d->proxyUi.groupBox, SLOT(setEnabled(bool))); +} + + +// we need this function to SAVE settings in rc file.. +void SettingsDialog::saveSettings() +{ + // General + ReKonfig::setDownloadDir(d->generalUi.downloadDirUrlRequester->url().prettyUrl()); + + // Save + ReKonfig::self()->writeConfig(); +} + + +// ---------------------------------------------------------------------------------------------- + + +void SettingsDialog::showCookies() +{ + CookiesDialog *dialog = new CookiesDialog(Application::cookieJar(), this); + dialog->exec(); +} + + +void SettingsDialog::showExceptions() +{ + CookiesExceptionsDialog *dialog = new CookiesExceptionsDialog(Application::cookieJar(), this); + dialog->exec(); +} + + +void SettingsDialog::setHomeToCurrentPage() +{ + MainWindow *mw = static_cast(parent()); + WebView *webView = mw->currentTab(); + if (webView) + { + d->generalUi.kcfg_homePage->setText(webView->url().prettyUrl()); + } +} diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 00000000..26fd2d16 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,55 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef SETTINGS_H +#define SETTINGS_H + +// KDE Includes +#include + +// Forward Declarations +class QWidget; +class Private; + + +class SettingsDialog : public KConfigDialog +{ + Q_OBJECT + +public: + SettingsDialog(QWidget *parent = 0); + ~SettingsDialog(); + +private: + Private* const d; + + void setWebSettingsToolTips(); + +private slots: + void readConfig(); + void saveSettings(); + + void setHomeToCurrentPage(); + void showCookies(); + void showExceptions(); +}; + +#endif // SETTINGS_H diff --git a/src/settings_fonts.ui b/src/settings_fonts.ui new file mode 100644 index 00000000..de258cad --- /dev/null +++ b/src/settings_fonts.ui @@ -0,0 +1,97 @@ + + + fonts + + + + 0 + 0 + 414 + 298 + + + + Appearance + + + + + + Fonts + + + + + + + + Standard Font + + + + + + + Fixed Font + + + + + + + + + + + + + + + + + + Dimension + + + + + + + + Font Size + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + KFontComboBox + KComboBox +
kfontcombobox.h
+
+
+ + +
diff --git a/src/settings_general.ui b/src/settings_general.ui new file mode 100644 index 00000000..44561b02 --- /dev/null +++ b/src/settings_general.ui @@ -0,0 +1,142 @@ + + + general + + + + 0 + 0 + 515 + 415 + + + + General + + + + + + Places + + + + + + Home Page: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + + + + + + Set to current page + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Save downloads to: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + ask where saving downloads + + + + + + + + + + Tabbed Browsing + + + + + + Always show tab bar + + + + + + + Open tabs in the background + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+ + KUrlRequester + QFrame +
kurlrequester.h
+
+
+ + +
diff --git a/src/settings_privacy.ui b/src/settings_privacy.ui new file mode 100644 index 00000000..78202688 --- /dev/null +++ b/src/settings_privacy.ui @@ -0,0 +1,168 @@ + + + privacy + + + + 0 + 0 + 461 + 313 + + + + Privacy + + + + + + History + + + + + + 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 + + + + + + + + + + + Cookies + + + + + + Accept Cookies: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + Always + + + + + Never + + + + + Only from sites you visit + + + + + + + + Exceptions... + + + + + + + Keep until: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + They expire + + + + + I exit the application + + + + + At most 90 days + + + + + + + + Cookies... + + + + + + + + + + Qt::Vertical + + + + 20 + 136 + + + + + + + + + diff --git a/src/settings_proxy.ui b/src/settings_proxy.ui new file mode 100644 index 00000000..90e308a2 --- /dev/null +++ b/src/settings_proxy.ui @@ -0,0 +1,152 @@ + + proxy + + + + 0 + 0 + 440 + 223 + + + + Proxy + + + + + + Enable proxy + + + + + + + Proxy Settings + + + + + + Type: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + SOCKS 5 + + + + + HTTP + + + + + + + + Host: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Port: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 10000 + + + 1080 + + + + + + + Qt::Horizontal + + + + 293 + 20 + + + + + + + + Username: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Password: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + + + + Qt::Vertical + + + + 20 + 8 + + + + + + + + + + + + KLineEdit + QLineEdit +
klineedit.h
+
+
+ + +
diff --git a/src/settings_webkit.ui b/src/settings_webkit.ui new file mode 100644 index 00000000..362e392a --- /dev/null +++ b/src/settings_webkit.ui @@ -0,0 +1,134 @@ + + + webkit + + + + 0 + 0 + 564 + 360 + + + + Form + + + + + + WebKit Settings + + + + + + Auto Load Images + + + + + + + Qt::Vertical + + + + + + + Links included in focus chain + + + + + + + Javascript support + + + + + + + Zoom Text Only + + + + + + + Java support + + + + + + + Print element Backgrounds + + + + + + + Plugins + + + + + + + Offline storage Database + + + + + + + Javascript can open windows + + + + + + + Offline Web Application Cache + + + + + + + Javascript can access clipboard + + + + + + + Local storage database + + + + + + + + + + Qt::Vertical + + + + 20 + 146 + + + + + + + + + diff --git a/src/sidepanel.cpp b/src/sidepanel.cpp new file mode 100644 index 00000000..0fab81c0 --- /dev/null +++ b/src/sidepanel.cpp @@ -0,0 +1,53 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + +// Self Includes +#include "sidepanel.h" +#include "sidepanel.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "panelhistory.h" + + +SidePanel::SidePanel(const QString &title, QWidget *parent, Qt::WindowFlags flags) + : QDockWidget(title, parent, flags) + , m_panelHistory(new PanelHistory(this)) +{ + setObjectName("sidePanel"); + setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); + + setShown(ReKonfig::showSideBar()); + + connect(m_panelHistory, SIGNAL(openUrl(const KUrl&)), this, SIGNAL(openUrl(const KUrl&))); + + setWidget(m_panelHistory); +} + + +SidePanel::~SidePanel() +{ + // Save side panel's state + ReKonfig::setShowSideBar(!isHidden()); + + delete m_panelHistory; +} + diff --git a/src/sidepanel.h b/src/sidepanel.h new file mode 100644 index 00000000..c0af7827 --- /dev/null +++ b/src/sidepanel.h @@ -0,0 +1,50 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Paweł Prażak +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef SIDEPANEL_H +#define SIDEPANEL_H + +// Qt Includes +#include + +// Local Includes +#include "application.h" + +class KUrl; +class PanelHistory; + + +class SidePanel : public QDockWidget +{ + Q_OBJECT + Q_DISABLE_COPY(SidePanel) + +public: + explicit SidePanel(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~SidePanel(); + +signals: + void openUrl(const KUrl &); + +private: + PanelHistory *m_panelHistory; + +}; + +#endif // SIDEPANEL_H diff --git a/src/stackedurlbar.cpp b/src/stackedurlbar.cpp new file mode 100644 index 00000000..113c8769 --- /dev/null +++ b/src/stackedurlbar.cpp @@ -0,0 +1,152 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "stackedurlbar.h" +#include "stackedurlbar.moc" + +// KDE Includes +#include "kdebug.h" + +// Local Includes +#include "application.h" +#include "history.h" +#include "urlbar.h" + + +StackedUrlBar::StackedUrlBar(QWidget *parent) + : QStackedWidget(parent) + , m_completion(0) + , m_completionModel(0) +{ +} + + +StackedUrlBar::~StackedUrlBar() +{ + delete m_completion; + delete m_completionModel; +} + + +UrlBar *StackedUrlBar::currentUrlBar() +{ + return urlBar(currentIndex()); +} + + +UrlBar *StackedUrlBar::urlBar(int index) +{ + UrlBar *urlBar = qobject_cast(QStackedWidget::widget(index)); + if (!urlBar) + { + kWarning() << "URL bar with index" << index << "not found. Returning NULL. line:" << __LINE__; + } + + return urlBar; +} + + +void StackedUrlBar::addUrlBar(UrlBar* urlBar) +{ + QStackedWidget::addWidget(urlBar); + + // setup completion objects + urlBar->setCompletionObject(completion()); +} + + +void StackedUrlBar::setCurrentUrlBar(UrlBar* urlBar) +{ + QStackedWidget::setCurrentWidget(urlBar); +} + + +void StackedUrlBar::removeUrlBar(UrlBar* urlBar) +{ + QStackedWidget::removeWidget(urlBar); +} + + +void StackedUrlBar::clear() +{ + currentUrlBar()->clearHistory(); + + for (int i = 0; i < count(); ++i) + { + urlBar(i)->clear(); + } +} + + +QList StackedUrlBar::urlBars() +{ + QList list; + for (int i = 0; i < count(); ++i) + { + const UrlBar* u = urlBar(i); + list.append(u); + } + return list; +} + + +KCompletion *StackedUrlBar::completion() +{ + // make sure completion was created + if (!m_completion) + { + m_completion = new KCompletion(); + m_completion->setCompletionMode(KGlobalSettings::CompletionPopupAuto); + m_completion->setOrder(KCompletion::Weighted); + m_completion->setIgnoreCase(true); + + kDebug() << "Initialize completion list..."; + + HistoryCompletionModel *model = completionModel(); + int count = model->rowCount(); + + kDebug() << "...initialize history items" << count; + + // change order to insertion to avoid confusion of the addItem method + // in weighted it expects format string:number and it thinks http it the whole string + m_completion->setOrder(KCompletion::Insertion); + for (int i = 0; i < count; ++i) + { + QString item = model->data(model->index(i, 0)).toString(); + item.remove(QRegExp("^http://|/$")); + m_completion->addItem(item); + } + m_completion->setOrder(KCompletion::Weighted); + } + + return m_completion; +} + + +HistoryCompletionModel *StackedUrlBar::completionModel() +{ + if (!m_completionModel) + { + m_completionModel = new HistoryCompletionModel(this); + m_completionModel->setSourceModel(Application::historyManager()->historyFilterModel()); + } + return m_completionModel; +} diff --git a/src/stackedurlbar.h b/src/stackedurlbar.h new file mode 100644 index 00000000..d3aea16f --- /dev/null +++ b/src/stackedurlbar.h @@ -0,0 +1,64 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + + +#ifndef STACKEDURLBAR_H +#define STACKEDURLBAR_H + +// Qt Includes +#include + +class KCompletion; +class HistoryCompletionModel; +class UrlBar; + +class StackedUrlBar : public QStackedWidget +{ + Q_OBJECT + +public: + StackedUrlBar(QWidget *parent = 0); + ~StackedUrlBar(); + +public: + UrlBar *currentUrlBar(); + UrlBar *urlBar(int index); + void addUrlBar(UrlBar *urlBar); + void setCurrentUrlBar(UrlBar *urlBar); + void removeUrlBar(UrlBar *urlBar); + + QList urlBars(); + + KCompletion *completion(); + HistoryCompletionModel *completionModel(); + +public slots: + void clear(); + +private: + Q_DISABLE_COPY(StackedUrlBar) + + KCompletion *m_completion; + HistoryCompletionModel *m_completionModel; +}; + +#endif // STACKEDURLBAR_H + diff --git a/src/tabbar.cpp b/src/tabbar.cpp new file mode 100644 index 00000000..be1b05fd --- /dev/null +++ b/src/tabbar.cpp @@ -0,0 +1,145 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + +//Self Includes +#include "tabbar.h" +#include "tabbar.moc" + +// Local Includes +#include "application.h" +#include "mainwindow.h" +#include "history.h" +#include "urlbar.h" +#include "webview.h" + +// KDE Includes +#include +#include +#include +#include +#include +#include + +// Qt Includes +#include + + +TabBar::TabBar(QWidget *parent) + : KTabBar(parent) + , m_parent(parent) +{ + setElideMode(Qt::ElideRight); + setContextMenuPolicy(Qt::CustomContextMenu); + setMovable(true); + connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), this, + SLOT(contextMenuRequested(const QPoint &))); + + // tabbar font + QFont standardFont = KGlobalSettings::generalFont(); + QString fontFamily = standardFont.family(); + int dim = standardFont.pointSize(); + setFont(QFont(fontFamily, dim - 1)); +} + + +TabBar::~TabBar() +{ +} + + +QSize TabBar::tabSizeHint(int index) const +{ + QSize s = m_parent->sizeHint(); + int w; + + int n = count(); + + if (n > 6) + { + w = s.width() / 5; + } + else + { + if (n > 3) + { + w = s.width() / 4; + } + else + { + w = s.width() / 3; + } + } + int h = KTabBar::tabSizeHint(index).height(); + + QSize ts = QSize(w, h); + return ts; +} + + +void TabBar::contextMenuRequested(const QPoint &position) +{ + KMenu menu; + MainWindow *mainWindow = Application::instance()->mainWindow(); + + menu.addAction(mainWindow->actionByName(QLatin1String("new_tab"))); + int index = tabAt(position); + if (-1 != index) + { + m_actualIndex = index; + + menu.addAction(KIcon("tab-duplicate"), i18n("Clone Tab"), this, SLOT(cloneTab())); + menu.addSeparator(); + menu.addAction(KIcon("tab-close"), i18n("&Close Tab"), this, SLOT(closeTab())); + menu.addAction(KIcon("tab-close-other"), i18n("Close &Other Tabs"), this, SLOT(closeOtherTabs())); + menu.addSeparator(); + menu.addAction(KIcon("view-refresh"), i18n("Reload Tab"), this, SLOT(reloadTab())); + } + else + { + menu.addSeparator(); + } + menu.addAction(i18n("Reload All Tabs"), this, SIGNAL(reloadAllTabs())); + menu.exec(QCursor::pos()); +} + + +void TabBar::cloneTab() +{ + emit cloneTab(m_actualIndex); +} + + +void TabBar::closeTab() +{ + emit closeTab(m_actualIndex); +} + + +void TabBar::closeOtherTabs() +{ + emit closeOtherTabs(m_actualIndex); +} + + +void TabBar::reloadTab() +{ + emit reloadTab(m_actualIndex); +} diff --git a/src/tabbar.h b/src/tabbar.h new file mode 100644 index 00000000..8563793f --- /dev/null +++ b/src/tabbar.h @@ -0,0 +1,78 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef TABBAR_H +#define TABBAR_H + +// KDE Includes +#include + +// Qt Includes +#include + +/** + * Tab bar with a few more features such as + * a context menu and shortcuts + * + */ + +class TabBar : public KTabBar +{ + Q_OBJECT + + +public: + TabBar(QWidget *parent = 0); + ~TabBar(); + +signals: + void cloneTab(int index); + void closeTab(int index); + void closeOtherTabs(int index); + void reloadTab(int index); + void reloadAllTabs(); + +protected: + /** + * Added to fix tab dimension + */ + virtual QSize tabSizeHint(int index) const; + +private slots: + void cloneTab(); + void closeTab(); + void closeOtherTabs(); + void reloadTab(); + void contextMenuRequested(const QPoint &position); + +private: + friend class MainView; + + QWidget *m_parent; + + /** + * the index in which we are seeing a Context menu + */ + int m_actualIndex; +}; + +#endif diff --git a/src/urlbar.cpp b/src/urlbar.cpp new file mode 100644 index 00000000..29eaed70 --- /dev/null +++ b/src/urlbar.cpp @@ -0,0 +1,240 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Domrachev Alexandr +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "urlbar.h" +#include "urlbar.moc" + +// Qt Includes +#include +#include + +// KDE Includes +#include +#include +#include + +// Local Includes +#include "application.h" +#include "history.h" +#include "lineedit.h" +#include "mainwindow.h" +#include "webview.h" + + +QColor UrlBar::s_defaultBaseColor; + +UrlBar::UrlBar(QWidget *parent) + : KHistoryComboBox(true, parent) + , m_lineEdit(new LineEdit) + , m_progress(0) +{ + setUrlDropsEnabled(true); + setAutoDeleteCompletionObject(true); + setMinimumWidth(180); + + setTrapReturnKey(true); + + setupLineEdit(); + + // add every item to history + connect(this, SIGNAL(returnPressed(const QString&)), SLOT(slotActivated(const QString&))); + connect(completionBox(), SIGNAL(activated(const QString&)), SLOT(slotActivated(const QString&))); + + connect(this, SIGNAL(cleared()), SLOT(slotCleared())); + + // setup completion box + completionBox()->setTabHandling(true); // Konqueror bug #167135 + + // set dropdown list background + QPalette p = view()->palette(); + p.setColor(QPalette::Base, palette().color(QPalette::Base)); + view()->setPalette(p); + + // set empty item with default icon + slotUpdateUrl(); +} + + +UrlBar::~UrlBar() +{ +} + + +void UrlBar::setupLineEdit() +{ + // Make m_lineEdit background transparent + QPalette p = m_lineEdit->palette(); + p.setColor(QPalette::Base, Qt::transparent); + m_lineEdit->setPalette(p); + + if (!s_defaultBaseColor.isValid()) + { + s_defaultBaseColor = palette().color(QPalette::Base); + } + + setLineEdit(m_lineEdit); + + // Make the lineedit consume the Qt::Key_Enter event... + lineEdit()->setTrapReturnKey(true); + + lineEdit()->setHandleSignals(true); + + // clear the URL bar + lineEdit()->clear(); +} + + +void UrlBar::setUrl(const QUrl& url) +{ + if (url.isEmpty()) + return; + + m_currentUrl = url; + slotUpdateUrl(); +} + + +void UrlBar::slotUpdateUrl() +{ + if (count()) + { + changeUrl(0, Application::instance()->icon(m_currentUrl), m_currentUrl); + } + else + { + insertUrl(0, Application::instance()->icon(m_currentUrl), m_currentUrl); + } + + setCurrentIndex(0); + + // important security consideration: always display the beginning + // of the url rather than its end to prevent spoofing attempts. + // Must be AFTER setCurrentIndex + if (!hasFocus()) + { + lineEdit()->setCursorPosition(0); + } +} + + +inline void UrlBar::slotActivated(const QString& url) +{ + if (url.isEmpty()) + return; + + setUrl(url); + + Application::historyManager()->addHistoryEntry(url); + + emit activated(m_currentUrl); +} + + +inline void UrlBar::slotCleared() +{ + // clear the history on user's request from context menu + clear(); + Application::historyManager()->clear(); +} + + +inline void UrlBar::slotLoadFinished(bool) +{ + // reset progress bar after small delay + m_progress = 0; + QTimer::singleShot(200, this, SLOT(repaint())); +} + + +inline void UrlBar::slotUpdateProgress(int progress) +{ + m_progress = progress; + repaint(); +} + + +void UrlBar::paintEvent(QPaintEvent *event) +{ + // set background color of UrlBar + QPalette p = palette(); + p.setColor(QPalette::Base, s_defaultBaseColor); + setPalette(p); + + KHistoryComboBox::paintEvent(event); + + if (!hasFocus()) + { + QPainter painter(this); + + QColor loadingColor; + if (m_currentUrl.scheme() == QLatin1String("https")) + { + loadingColor = QColor(248, 248, 100); + } + else + { + loadingColor = QColor(116, 192, 250); + } + painter.setBrush(generateGradient(loadingColor, height())); + painter.setPen(Qt::transparent); + + QRect backgroundRect = lineEdit()->frameGeometry(); + int mid = backgroundRect.width() / 100 * m_progress; + QRect progressRect(backgroundRect.x(), backgroundRect.y(), mid, backgroundRect.height()); + painter.drawRect(progressRect); + painter.end(); + } +} + + +void UrlBar::focusOutEvent(QFocusEvent *event) +{ + // set back last loaded url in case user cleared it + setUrl(m_currentUrl); + + KHistoryComboBox::focusOutEvent(event); +} + + +QSize UrlBar::sizeHint() const +{ + QSize size(lineEdit()->sizeHint()); + // make it (more or less) the same height with search bar (at least on oxygen) +// size.setHeight(size.height() + 2); + return size; +} + +QLinearGradient UrlBar::generateGradient(const QColor &color, int height) +{ + QColor base = s_defaultBaseColor; + base.setAlpha(0); + QColor barColor = color; + barColor.setAlpha(200); + QLinearGradient gradient(0, 0, 0, height); + gradient.setColorAt(0, base); + gradient.setColorAt(0.25, barColor.lighter(120)); + gradient.setColorAt(0.5, barColor); + gradient.setColorAt(0.75, barColor.lighter(120)); + gradient.setColorAt(1, base); + return gradient; +} diff --git a/src/urlbar.h b/src/urlbar.h new file mode 100644 index 00000000..236792bd --- /dev/null +++ b/src/urlbar.h @@ -0,0 +1,99 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Domrachev Alexandr +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef URLBAR_H +#define URLBAR_H + +// Qt Includes +#include +#include +#include + +// KDE Includes +#include +#include + +// Local Includes +#include "lineedit.h" + + +// Forward Declarations +class QLinearGradient; +class QWidget; + + +class UrlBar : public KHistoryComboBox +{ + Q_OBJECT + +public: + UrlBar(QWidget *parent = 0); + ~UrlBar(); + + void selectAll() const + { + lineEdit()->selectAll(); + } + KUrl url() const + { + return m_currentUrl; + } + + QSize sizeHint() const; + +signals: + void activated(const KUrl&); + +public slots: + void setUrl(const QUrl &url); + void slotUpdateProgress(int progress); + +private slots: + void slotActivated(const QString&); + void slotLoadFinished(bool); + void slotCleared(); + void slotUpdateUrl(); + +protected: + virtual void paintEvent(QPaintEvent *event); + virtual void focusOutEvent(QFocusEvent *event); + +private: + void setupLineEdit(); + + KLineEdit *lineEdit() const + { + return m_lineEdit; + } + + static QLinearGradient generateGradient(const QColor &color, int height); + + static QColor s_defaultBaseColor; + + LineEdit *m_lineEdit; + + QIcon m_currentIcon; + KUrl m_currentUrl; + int m_progress; +}; + +#endif diff --git a/src/webview.cpp b/src/webview.cpp new file mode 100644 index 00000000..5f42112b --- /dev/null +++ b/src/webview.cpp @@ -0,0 +1,504 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008 Benjamin C. Meyer +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +// Self Includes +#include "webview.h" +#include "webview.moc" + +// Auto Includes +#include "rekonq.h" + +// Local Includes +#include "application.h" +#include "mainwindow.h" +#include "mainview.h" +#include "cookiejar.h" +#include "networkaccessmanager.h" +#include "download.h" +#include "history.h" + + +// KDE Includes +#include +#include +#include +#include +#include + +// Qt Includes +#include +#include +#include +#include + + +WebPage::WebPage(QObject *parent) + : QWebPage(parent) + , m_keyboardModifiers(Qt::NoModifier) + , m_pressedButtons(Qt::NoButton) + , m_openInNewTab(false) +{ + setNetworkAccessManager(Application::networkAccessManager()); + + setForwardUnsupportedContent(true); + connect(this, SIGNAL(unsupportedContent(QNetworkReply *)), this, SLOT(handleUnsupportedContent(QNetworkReply *))); +} + + +WebPage::~WebPage() +{ +} + + +bool WebPage::acceptNavigationRequest(QWebFrame *frame, const QNetworkRequest &request, NavigationType type) +{ + QString scheme = request.url().scheme(); + if (scheme == QLatin1String("mailto")) + { + KToolInvocation::invokeMailer(request.url()); + return false; + } + + WebView *webView; + + switch (type) + { + + // user clicked on a link or pressed return on a focused link. + case QWebPage::NavigationTypeLinkClicked: + + if (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton) + { + webView = Application::instance()->newWebView(); + webView->setFocus(); + webView->load(request); + m_keyboardModifiers = Qt::NoModifier; + m_pressedButtons = Qt::NoButton; + return false; + } + + if (frame == mainFrame()) + { + m_loadingUrl = request.url(); + emit loadingUrl(m_loadingUrl); + } + else + { + // if frame doesn't exists (perhaps) we are pointing to a blank target.. + if (!frame) + { + webView = Application::instance()->newWebView(); + webView->setFocus(); + webView->load(request); + return false; + } + } + break; + + // user activated a submit button for an HTML form. + case QWebPage::NavigationTypeFormSubmitted: + break; + + // Navigation to a previously shown document in the back or forward history is requested. + case QWebPage::NavigationTypeBackOrForward: + break; + + // user activated the reload action. + case QWebPage::NavigationTypeReload: + +#if QT_VERSION <= 040500 + // HACK Ported from Arora + // A short term hack until QtWebKit can get a reload without cache QAction + // *FYI* currently type is never NavigationTypeReload + // See: https://bugs.webkit.org/show_bug.cgi?id=24283 + if (qApp->keyboardModifiers() & Qt::ShiftModifier) + { + QNetworkRequest newRequest(request); + newRequest.setAttribute(QNetworkRequest::CacheLoadControlAttribute, + QNetworkRequest::AlwaysNetwork); + mainFrame()->load(request); + return false; + } +#endif + + break; + + // An HTML form was submitted a second time. + case QWebPage::NavigationTypeFormResubmitted: + break; + + // A navigation to another document using a method not listed above. + case QWebPage::NavigationTypeOther: + break; + + // should be nothing.. + default: + break; + } + + return QWebPage::acceptNavigationRequest(frame, request, type); +} + + +QWebPage *WebPage::createWindow(QWebPage::WebWindowType type) +{ + // added to manage web modal dialogs + if (type == QWebPage::WebModalDialog) + { + // FIXME : need a "real" implementation.. + kWarning() << "Modal Dialog ---------------------------------------"; + QWebView *w = new QWebView(); + w->show(); + return w->page(); + } + + if (m_keyboardModifiers & Qt::ControlModifier || m_pressedButtons == Qt::MidButton) + { + m_openInNewTab = true; + } + + if (m_openInNewTab) + { + m_openInNewTab = false; + return Application::instance()->newWebView()->page(); + } + + MainWindow *mainWindow = Application::instance()->mainWindow(); + return mainWindow->currentTab()->page(); +} + + +QObject *WebPage::createPlugin(const QString &classId, const QUrl &url, const QStringList ¶mNames, const QStringList ¶mValues) +{ + kWarning() << "creating PLUGIN for rekonq "; + kWarning() << "classId = " << classId; + kWarning() << "url = " << url; + kWarning() << "Param Names = " << paramNames; + kWarning() << "Param Values = " << paramValues; + + QUiLoader loader; + return loader.createWidget(classId, view()); +} + + +void WebPage::handleUnsupportedContent(QNetworkReply *reply) +{ + // create convenience fake api:// protocol for KDE apidox search and Qt docs + if (reply->url().scheme() == "api") + { + QString path; + QString className = reply->url().host().toLower(); + if (className[0] == 'k') + { + path = QString("http://api.kde.org/new.classmapper.php?class=%1").arg(className); + } + else if (className[0] == 'q') + { + path = QString("http://doc.trolltech.com/4.5/%1.html").arg(className); + } + QUrl url(path); + + Application::instance()->mainWindow()->loadUrl(url); + return; + } + + if (reply->error() == QNetworkReply::NoError) + { + // st iframe unwanted download fix + if (reply->header(QNetworkRequest::ContentTypeHeader).isValid()) + { + KUrl srcUrl = reply->url(); + Application::downloadManager()->newDownload(srcUrl); + } + return; + } + + // display "not found" page + QString notfoundFilePath = KStandardDirs::locate("data", "rekonq/htmls/notfound.html"); + QFile file(notfoundFilePath); + bool isOpened = file.open(QIODevice::ReadOnly); + if (!isOpened) + { + kWarning() << "Couldn't open the notfound.html file"; + return; + } + QString title = i18n("Error loading page: ") + reply->url().toString(); + + QString imagePath = KIconLoader::global()->iconPath("rekonq", KIconLoader::NoGroup, false); + + QString html = QString(QLatin1String(file.readAll())) + .arg(title) + .arg("file://" + imagePath) + .arg(reply->errorString()) + .arg(reply->url().toString()); + + QList frames; + frames.append(mainFrame()); + while (!frames.isEmpty()) + { + QWebFrame *firstFrame = frames.takeFirst(); + if (firstFrame->url() == reply->url()) + { + firstFrame->setHtml(html, reply->url()); + return; + } + QList children = firstFrame->childFrames(); + foreach(QWebFrame *frame, children) + { + frames.append(frame); + } + } + if (m_loadingUrl == reply->url()) + { + mainFrame()->setHtml(html, reply->url()); + // Don't put error pages to the history. + Application::historyManager()->removeHistoryEntry(reply->url(), mainFrame()->title()); + } +} + + +// ----------------------------------------------------------------------------------------------------------------- + + +KActionCollection* WebView::s_webActionCollection; + + +WebView::WebView(QWidget* parent) + : QWebView(parent) + , m_page(new WebPage(this)) + , m_progress(0) +{ + setPage(m_page); + connect(page(), SIGNAL(statusBarMessage(const QString&)), this, 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&)), this, SIGNAL(urlChanged(const QUrl &))); + connect(page(), SIGNAL(downloadRequested(const QNetworkRequest &)), this, SLOT(downloadRequested(const QNetworkRequest &))); + page()->setForwardUnsupportedContent(true); +} + + +KActionCollection* WebView::webActions() +{ + if (!s_webActionCollection) + { + s_webActionCollection = new KActionCollection(this); + + QAction *a; + + a = new KAction(KIcon("tab-new"), i18n("Open Link in New &Tab"), this); + connect(a, SIGNAL(triggered()), this, SLOT(openLinkInNewTab())); + s_webActionCollection->addAction(QLatin1String("open_link_in_new_tab"), a); + + a = pageAction(QWebPage::Cut); + a->setIcon(KIcon("edit-cut")); + a->setText(i18n("Cu&t")); + s_webActionCollection->addAction(QLatin1String("edit_cut"), a); + + a = pageAction(QWebPage::Copy); + a->setIcon(KIcon("edit-copy")); + a->setText(i18n("&Copy")); + s_webActionCollection->addAction(QLatin1String("edit_copy"), a); + + a = pageAction(QWebPage::Paste); + a->setIcon(KIcon("edit-paste")); + a->setText(i18n("&Paste")); + s_webActionCollection->addAction(QLatin1String("edit_paste"), a); + + a = pageAction(QWebPage::DownloadImageToDisk); + a->setIcon(KIcon("folder-image")); + a->setText(i18n("&Save Image As...")); + s_webActionCollection->addAction(QLatin1String("save_image_as"), a); + + a = pageAction(QWebPage::CopyImageToClipboard); + a->setIcon(KIcon("insert-image")); + a->setText(i18n("&Copy This Image")); + s_webActionCollection->addAction(QLatin1String("copy_this_image"), a); + + a = pageAction(QWebPage::DownloadLinkToDisk); + a->setIcon(KIcon("folder-downloads")); + a->setText(i18n("&Save Link As...")); + s_webActionCollection->addAction(QLatin1String("save_link_as"), a); + + a = pageAction(QWebPage::CopyLinkToClipboard); + a->setIcon(KIcon("insert-link")); + a->setText(i18n("&Copy Link Location")); + s_webActionCollection->addAction(QLatin1String("copy_link_location"), a); + + a = pageAction(QWebPage::InspectElement); + a->setIcon(KIcon("tools-report-bug")); + a->setText(i18n("&Inspect Element")); + s_webActionCollection->addAction(QLatin1String("inspect_element"), a); + } + + return s_webActionCollection; +} + + +void WebView::contextMenuEvent(QContextMenuEvent *event) +{ + QWebHitTestResult result = page()->mainFrame()->hitTestContent(event->pos()); + MainWindow *mainwindow = Application::instance()->mainWindow(); + + QAction *addBookmarkAction = Application::bookmarkProvider()->actionByName("add_bookmark_payload"); + addBookmarkAction->setText(i18n("Bookmark This Page")); + addBookmarkAction->setData(QVariant()); + KMenu menu(this); + + bool linkIsEmpty = result.linkUrl().isEmpty(); + if (!linkIsEmpty) + { + menu.addAction(webActions()->action("open_link_in_new_tab")); + } + else + { + menu.addAction(mainwindow->actionByName("new_tab")); + } + menu.addAction(mainwindow->actionByName("view_redisplay")); + menu.addSeparator(); + + if (page()->settings()->testAttribute(QWebSettings::DeveloperExtrasEnabled)) + { + menu.addAction(webActions()->action("inspect_element")); + menu.addSeparator(); + } + + menu.addAction(mainwindow->actionByName("history_back")); + menu.addAction(mainwindow->actionByName("history_forward")); + menu.addSeparator(); + + if (result.isContentSelected() && result.isContentEditable()) + { + menu.addAction(webActions()->action("edit_cut")); + } + + if (result.isContentSelected()) + { + menu.addAction(webActions()->action("edit_copy")); + } + + if (result.isContentEditable()) + { + menu.addAction(webActions()->action("edit_paste")); + } + + if (!linkIsEmpty) + { + menu.addSeparator(); + if (!result.pixmap().isNull()) + { + // TODO Add "View Image" + menu.addAction(webActions()->action("save_image_as")); + menu.addAction(webActions()->action("copy_this_image")); + } + menu.addAction(webActions()->action("save_link_as")); + menu.addAction(webActions()->action("copy_link_location")); + addBookmarkAction->setData(result.linkUrl()); + addBookmarkAction->setText(i18n("&Bookmark This Link")); + } + menu.addSeparator(); + + menu.addAction(addBookmarkAction); + menu.exec(mapToGlobal(event->pos())); +} + + +void WebView::wheelEvent(QWheelEvent *event) +{ + if (QApplication::keyboardModifiers() & Qt::ControlModifier) + { + int numDegrees = event->delta() / 8; + int numSteps = numDegrees / 15; + setTextSizeMultiplier(textSizeMultiplier() + numSteps * 0.1); + event->accept(); + return; + } + QWebView::wheelEvent(event); +} + + +void WebView::openLinkInNewTab() +{ + m_page->m_openInNewTab = true; + pageAction(QWebPage::OpenLinkInNewWindow)->trigger(); +} + + +void WebView::loadFinished() +{ + if (m_progress != 100) + { + kWarning() << "Recieved finished signal while progress is still:" << progress() + << "Url:" << url(); + } + m_progress = 0; +} + + +void WebView::mousePressEvent(QMouseEvent *event) +{ + m_page->m_pressedButtons = event->buttons(); + m_page->m_keyboardModifiers = event->modifiers(); + QWebView::mousePressEvent(event); +} + + +void WebView::mouseReleaseEvent(QMouseEvent *event) +{ + QWebView::mouseReleaseEvent(event); + if (!event->isAccepted() && (m_page->m_pressedButtons & Qt::MidButton)) + { + KUrl url(QApplication::clipboard()->text(QClipboard::Selection)); + if (!url.isEmpty() && url.isValid() && !url.scheme().isEmpty()) + { + setUrl(url); + } + } +} + + +void WebView::downloadRequested(const QNetworkRequest &request) +{ + KUrl srcUrl = request.url(); + QString path = ReKonfig::downloadDir() + QString("/") + srcUrl.fileName(); + KUrl destUrl = KUrl(path); + Application::downloadManager()->newDownload(srcUrl); +} + + +void WebView::keyPressEvent(QKeyEvent *event) +{ + if ((event->modifiers() == Qt::ControlModifier) && (event->key() == Qt::Key_Tab)) + { + emit ctrlTabPressed(); + return; + } + + if ((event->modifiers() == Qt::ControlModifier + Qt::ShiftModifier) && (event->key() == Qt::Key_Backtab)) + { + emit shiftCtrlTabPressed(); + return; + } + + QWebView::keyPressEvent(event); +} diff --git a/src/webview.h b/src/webview.h new file mode 100644 index 00000000..11f04571 --- /dev/null +++ b/src/webview.h @@ -0,0 +1,155 @@ +/* ============================================================ +* +* This file is a part of the rekonq project +* +* Copyright (C) 2007-2008 Trolltech ASA. All rights reserved +* Copyright (C) 2008 Benjamin C. Meyer +* Copyright (C) 2008-2009 by Andrea Diamantini +* Copyright (C) 2009 by Paweł Prażak +* +* +* 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, 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. +* +* ============================================================ */ + + +#ifndef WEBVIEW_H +#define WEBVIEW_H + +// KDE Includes +#include + +// Qt Includes +#include + +// Forward Declarations +class MainWindow; +class Application; + +class KActionCollection; + +class QWebFrame; +class QAuthenticator; +class QMouseEvent; +class QNetworkProxy; +class QNetworkReply; +class QSslError; + + +class WebPage : public QWebPage +{ + Q_OBJECT + +signals: + void loadingUrl(const QUrl &url); // WARNING has to be QUrl!! + +public: + WebPage(QObject *parent = 0); + ~WebPage(); + +protected: + bool acceptNavigationRequest(QWebFrame *frame, + const QNetworkRequest &request, + NavigationType type); + + QWebPage *createWindow(QWebPage::WebWindowType type); + QObject *createPlugin(const QString &classId, + const QUrl &url, + const QStringList ¶mNames, + const QStringList ¶mValues); + +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; + KUrl m_loadingUrl; +}; + + +// ---------------------------------------------------------------------------------------------------- + +// Qt Includes +#include + + +class WebView : public QWebView +{ + Q_OBJECT + +public: + WebView(QWidget *parent = 0); + + KActionCollection* webActions(); + + // inline + WebPage *webPage() const + { + return m_page; + } + KUrl url() const + { + return KUrl(QWebView::url()); + } + QString lastStatusBarText() const + { + return m_statusBarText; + } + int progress() const + { + return m_progress; + } + +signals: + // switching tabs + void ctrlTabPressed(); + void shiftCtrlTabPressed(); + +protected: + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void contextMenuEvent(QContextMenuEvent *event); + void wheelEvent(QWheelEvent *event); + + /** + * Filters (SHIFT + ) CTRL + TAB events and emit (shift)ctrlTabPressed() + * to make switch tab + */ + void keyPressEvent(QKeyEvent *event); + +private slots: + void setProgress(int progress) + { + m_progress = progress; + } + void loadFinished(); + void setStatusBarText(const QString &string) + { + m_statusBarText = string; + } + void downloadRequested(const QNetworkRequest &request); + void openLinkInNewTab(); + +private: + static KActionCollection* s_webActionCollection; + + WebPage *m_page; + + int m_progress; + QString m_statusBarText; +}; + +#endif -- cgit v1.2.1