--- /dev/null
+build/
+Makefile*
+minitube.pro.user
+.settings/
+.DS_Store
+.cproject
+.project
--- /dev/null
+Flavio Tordini flavio.tordini@gmail.com
--- /dev/null
+1.0 - April ?, 2010
+- Ability to play Full HD (1080p) videos
+- Ability to copy the YouTube link and the video stream URL to the clipboard
+- Fixed videos failing to play
+- Fixed missing caret in the search box
+- Better toolbar and icon theme integration on Linux with Qt >= 4.6
+- Completely removed tooltips
+- Romanian translation by Ovidiu Niţan
+- Greek translation by Giorgos Skettos
+- Dutch translation by Brian Keetman
+- Arabic translation by Sderawi
+- Portuguese translation by Daniel Rodrigues
+- Finnish translation by Jesse Jaara
+- Bulgarian translation by Tsvyatko Makazchiev
+
+0.9 - January 22, 2010
+- Ability to clear recent keywords (by popular demand!)
+- Show the toolbar when mouse hits the top of the screen in Fullscreen mode (Linux only)
+- Show the playlist when mouse hits the left side of the screen in Fullscreen mode (Linux only)
+- Fixed toolbar search suggestions working just once (Thanks to Salvatore Benedetto)
+- Fixed toobar search incorrect handling of keys that also represent a shortcut (like Escape or Space)
+- Fixed time formatting bug with videos longer than an hour (Thanks to Rene Bogusch)
+- Fixed long queries in the recent keywords list (Thanks to Vadim P.)
+- Norwegian translation by Jan W. Skjoldal
+
+0.8.1 - November 20, 2009
+- Fix showstopper bug: Normal quality videos won't play when HD mode is enabled
+- Turkish translation by Ali E. İmrek
+
+0.8 - November 16, 2009
+- HD video support
+- Volume level and mute is restored accross sessions
+- No icons in menus on Linux (GNOME 2.28 style)
+- Select search box text on Ctrl+F
+- Handle HTTP_PROXY variable with trailing slash (Fix by Eduardo Suarez-Santana)
+- Croatian translation by Srecko Belaic
+- Latvian translation by Inga Muste
+- Galician and Neutral Spanish translations by Miguel Anxo Bouzada
+- Hungarian translation by Krisztián Horváth
+- French translation by Guillaume Betous
+
+0.7 - October 12, 2009
+- Fixed "embedding disabled by request" message. All videos now play.
+- Slightly faster playlist painting
+- Fixed overflowing text in the playlist
+- Fixed view crossfades on the Mac
+- Fixed FreeDesktop icons on Linux
+
+0.6.1 - September 15, 2009
+- Fixed showstopper bug caused by a change in the YouTube web service
+ Thanks to Guillaume Girard for reporting it
+
+0.6 - September 7, 2009
+- New search view look
+- Hide idle mouse cursor when above the video (Linux only)
+- Volume keyboard shortcuts
+- Keyboard shortcuts appear in the status bar
+- Better error reporting
+- Playlist width is saved accross restarts
+- HTTP proxy support contributed by Kiwamu Okabe
+- Fixed Space key not pausing videos in fullscreen mode (Mac only)
+- Fixed window losing focus after exiting fullscreen (Mac only)
+- Spanish translation by Rafa
+- Japanese translation by Kiwamu Okabe
+- Czech translation by Dan Vrátil
+- Hebrew translation by Yaron Shahrabani
+
+0.5 - July 31, 2009
+- Search autocomplete
+- Skip to the next when a video cannot be loaded
+- Playlist items can now be dropped onto the video area
+- Fixed messages in the playlist not updating
+- Disabled view crossfade on Linux
+- Save keywords only when there are results
+- Fixed fullscreen keyboard shortcurt not working
+- Polish translation by Grzegorz Gibas
+
+0.4 - July 2, 2009
+- Finally fixed playback start problem on Mac OSX
+- Display title and description while video is loading
+- Compact mode, contributed by Stefan Brück
+- Current video position and total time in the status bar
+- Keyboard shortcuts now work when in full screen mode
+- Fixed crash occurring when pressing stop during a search
+- Argentin spanish translation by Sergio Tocalini Joerg
+- German translation by Stefan Brück
+
+0.3 - June 15, 2009
+- Can sort videos by relevance, date and popularity
+- Doubleclick on video goes full screen
+- Video context menu
+- Can remove videos using the Backspace key, Mac laptops lack a Delete key
+- Keyboard shortcut to give focus to the search box
+- Load thumbnails asynchronously
+- Fixed wrong (absurdly high) number views on some videos
+- Now Minitube is ready to be translated. Italian, Russian and Portuguese translations available
+- Cosmetics
+
+0.2.1 - June 1, 2009
+- Fixed showstopper bug on Linux: Minitube fails to automatically play the next video
+
+0.2 - May 29, 2009
+- Faster playlist results
+- Ability to (re)move selected playlist items
+- Drag'n'drop playlist items
+- Uses less memory
+- Basic fullscreen mode now works
+- Show the total number of views of a video
+- Video duration is now overlayed on the thumb
+- Update notifier
+
+0.1 - May 15, 2009
+First release
--- /dev/null
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 <http://www.gnu.org/licenses/>.
+
+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:
+
+ <program> Copyright (C) <year> <name of author>
+ 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
+<http://www.gnu.org/licenses/>.
+
+ 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
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- /dev/null
+# Build instructions
+
+## Prerequisites
+
+To compile Minitube you need Qt >= 4.5 installed.
+
+On a Debian or Ubuntu system just type:
+ sudo apt-get install build-essential qt4-dev-tools libphonon-dev
+
+Windows and Mac users can get the Qt libraries from:
+http://qt.nokia.com/downloads
+
+## Compiling
+
+Compiling on Linux is fairly easy. Just run:
+ qmake
+and then
+ make
+
+Beware of the Qt3 version of qmake! If things go wrong try running qmake-qt4 instead.
+
+## Running
+
+Just type:
+ ./build/target/minitube
+
+## The visual way
+
+There is also a visual way to build and run Qt apps.
+Download the Qt SDK from: http://qt.nokia.com/downloads
+Open `minitube.pro` with Qt Creator and use the Run (big green "play" icon) command.
+
+## Legal Stuff
+
+Copyright (C) 2009 Flavio Tordini
+
+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 <http://www.gnu.org/licenses/>.
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleName</key>
+ <string>Minitube</string>
+ <key>CFBundleIconFile</key>
+ <string>minitube.icns</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Copyright 2009 Flavio Tordini</string>
+ <key>CFBundleExecutable</key>
+ <string>minitube</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.tordini.flavio.minitube</string>
+</dict>
+</plist>
--- /dev/null
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL. It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it. You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+ When we speak of free software, we are referring to freedom of use,
+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 this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+ To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights. These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ To protect each distributor, we want to make it very clear that
+there is no warranty for the free library. Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+ Finally, software patents pose a constant threat to the existence of
+any free program. We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder. Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+ Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License. This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License. We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+ When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library. The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom. The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+ We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License. It also provides other free software developers Less
+of an advantage over competing non-free programs. These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries. However, the Lesser license provides advantages in certain
+special circumstances.
+
+ For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard. To achieve this, non-free programs must be
+allowed to use the library. A more frequent case is that a free
+library does the same job as widely used non-free libraries. In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+ In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software. For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+ Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+ GNU LESSER GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+\f
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+ 6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (1) uses at run time a
+ copy of the library already present on the user's computer system,
+ rather than copying library functions into the executable, and (2)
+ will operate properly with a modified version of the library, if
+ the user installs one, as long as the modified version is
+ interface-compatible with the version that the work was made with.
+
+ c) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ d) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ e) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser 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 Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null
+# Minitube TODO list
+
+## Known Bugs
+- Wrong item positions when moving more than one item down or up
+
+## Killer features
+
+- Video download
+ Playlist items should have a download icon that appears on mouse hover.
+ Once the icon is clicked a mini-progressbar appears and the download icon remains visible
+ even on "mouseout", maybe with a different color.
+ Videos should be downloaded in HD format, if available.
+ Videos should be downloaded directly on the Desktop without asking for a location.
+
+- YouTube related videos
+ List of related videos identical to the playlist.
+ When a related video is clicked Minitube will keep playing the next related videos.
+ Don't know where the list should appear, maybe on the right, but when activated it should replace the playlist.
+ Maybe the playlist should disappear, leaving only the panel on the right.
+
+- Accept YouTube URLs in the search box and as CLI args
+ ./minitube [url]
+ When Minitube has a single video to play, it will continue playing related videos.
+ This feature depends on the related videos above.
+ We could also accept any URL and scrape web pages searching for YouTube videos.
+
+- Windows build
+ Stefan Brueck has compiled on Windows but there are problems with Phonon's directX backend
+ Marco di Antonio tried with the Mplayer backend, but it is very unstable
+
+- Subtitles, see http://google2srt.sourceforge.net/
+
+## Minor Features
+- Safe search levels (in the status bar beside HD)
+- Show buffering progress (when Phonon backends will work)
+- Show more thumbs on hover with animated crossfade
+
+## Unsure features
+- Restore status when a recent keyword is clicked: skipped videos, sortBar and play time
+- Add menu entries for Most relevant, Most recent, Most viewed (Playlist => ...)
+- Saved playlists
+- Starred videos
+
+## Phonon bugs (Come on Qt and KDE devs, do your job!)
+- Mac: playback sometimes does not start (got a workaround!)
+- Mac: Phonon freezes the GUI when loading a video
+- Phonon::MediaSource does not work with QIODevices
+- Mac: Cannot seek beyond the buffered part of the video
+- Xine: Seek does not work at all. https://bugs.kde.org/show_bug.cgi?id=197927
+- Phonon does not report the buffering percent correctly. https://bugs.kde.org/show_bug.cgi?id=210336
+- Linux: The Phonon volume slider mute button does not change: https://bugs.kde.org/show_bug.cgi?id=214543
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="32"
+ height="32"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.46"
+ sodipodi:docbase="/home/needcoffee/Templates"
+ sodipodi:docname="tv.svg"
+ version="1.0"
+ inkscape:output_extension="org.inkscape.output.svg.inkscape"
+ inkscape:export-filename="/home/flavio/projects/minitube/images/app.png"
+ inkscape:export-xdpi="360"
+ inkscape:export-ydpi="360">
+ <defs
+ id="defs4">
+ <inkscape:perspective
+ sodipodi:type="inkscape:persp3d"
+ inkscape:vp_x="0 : 16 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_z="32 : 16 : 1"
+ inkscape:persp3d-origin="16 : 10.666667 : 1"
+ id="perspective65" />
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient8228">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop8230" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop8232" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient7815">
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="0"
+ id="stop7817" />
+ <stop
+ id="stop7823"
+ offset="0.5"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop7819" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient7422">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop7424" />
+ <stop
+ style="stop-color:#000000;stop-opacity:0;"
+ offset="1"
+ id="stop7426" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient6646">
+ <stop
+ style="stop-color:#eeeeec;stop-opacity:1"
+ offset="0"
+ id="stop6648" />
+ <stop
+ style="stop-color:#555753;stop-opacity:1"
+ offset="1"
+ id="stop6650" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient6257">
+ <stop
+ style="stop-color:#555753;stop-opacity:1;"
+ offset="0"
+ id="stop6259" />
+ <stop
+ style="stop-color:#2e3436;stop-opacity:1"
+ offset="1"
+ id="stop6261" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5863">
+ <stop
+ style="stop-color:#000000;stop-opacity:1;"
+ offset="0"
+ id="stop5865" />
+ <stop
+ style="stop-color:#2e3436;stop-opacity:1"
+ offset="1"
+ id="stop5867" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient5088">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0.54347825;"
+ offset="0"
+ id="stop5090" />
+ <stop
+ style="stop-color:#729fcf;stop-opacity:1;"
+ offset="1"
+ id="stop5092" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient4701"
+ inkscape:collect="always">
+ <stop
+ id="stop4703"
+ offset="0"
+ style="stop-color:#729fcf;stop-opacity:1" />
+ <stop
+ id="stop4705"
+ offset="1"
+ style="stop-color:#3465a4;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient4301">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop4303" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop4305" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ id="linearGradient3145">
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="0"
+ id="stop3147" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:0;"
+ offset="1"
+ id="stop3149" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3145"
+ id="linearGradient3151"
+ x1="7"
+ y1="-1"
+ x2="12"
+ y2="16"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6666666,0,0,1.0000001,-2.7699557e-8,-3)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4301"
+ id="linearGradient4307"
+ x1="-5"
+ y1="-7"
+ x2="39"
+ y2="30"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5555555,0,0,0.5692092,2.6666665,1.1694899)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient4701"
+ id="radialGradient4699"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0025642,3.1703514e-8,-1.117005e-8,0.4159999,-8.0615381,4.9319989)"
+ cx="24"
+ cy="39.923077"
+ fx="24"
+ fy="39.923077"
+ r="20" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5088"
+ id="linearGradient5097"
+ gradientUnits="userSpaceOnUse"
+ x1="2"
+ y1="-4"
+ x2="19"
+ y2="30"
+ gradientTransform="matrix(0.5675677,0,0,0.6086956,2.3783783,0.5000008)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient5863"
+ id="linearGradient5872"
+ gradientUnits="userSpaceOnUse"
+ x1="8"
+ y1="37"
+ x2="8"
+ y2="41"
+ gradientTransform="matrix(3.1249998,0,0,0.9999976,-10.562498,-13.999915)" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6257"
+ id="linearGradient6263"
+ x1="12.283331"
+ y1="41.250008"
+ x2="12.283331"
+ y2="36.750004"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5405406,0,0,-0.3333337,1.5270266,38.000017)" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient6646"
+ id="radialGradient6652"
+ cx="12"
+ cy="8.4459467"
+ fx="12"
+ fy="8.4459467"
+ r="22"
+ gradientTransform="matrix(0.3514481,0.895542,-1.0274841,0.4545455,12.925816,-8.0855683)"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="radialGradient7831"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2500003,0,-10.875016)"
+ cx="2"
+ cy="43.5"
+ fx="2"
+ fy="43.5"
+ r="2" />
+ <radialGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7422"
+ id="radialGradient7833"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,1.2500003,44,-10.875014)"
+ cx="2"
+ cy="43.5"
+ fx="2"
+ fy="43.5"
+ r="2" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient7815"
+ id="linearGradient7835"
+ gradientUnits="userSpaceOnUse"
+ x1="6"
+ y1="41"
+ x2="6"
+ y2="46" />
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient8228"
+ id="linearGradient8234"
+ x1="10"
+ y1="40.999996"
+ x2="10"
+ y2="35.999996"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.6756757,0,0,0.7499986,-0.2162159,-3.8749457)" />
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="13.62465"
+ inkscape:cx="28.332311"
+ inkscape:cy="12.08918"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="1280"
+ inkscape:window-height="772"
+ inkscape:window-x="0"
+ inkscape:window-y="28"
+ inkscape:showpageshadow="false"
+ width="32px"
+ height="32px"
+ borderlayer="true"
+ gridtolerance="10000"
+ showgrid="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid2173" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Ebene 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g7826"
+ style="opacity:0.46000001"
+ transform="matrix(0.6666666,0,0,1.1999995,0,-24.199975)">
+ <path
+ sodipodi:nodetypes="cscc"
+ id="path6654"
+ d="M 2,45.999998 C 0.896,45.999998 0,44.879998 0,43.499998 C 0,42.119997 0.896,40.999997 2,40.999997 C 2,40.999997 2,45.999998 2,45.999998 z"
+ style="color:#000000;fill:url(#radialGradient7831);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ sodipodi:nodetypes="cccc"
+ id="path7037"
+ d="M 48,43.5 C 48,44.88 47.104,46 46,46 C 46,46 46,40.999999 46,40.999999 C 47.104,40.999999 48,42.119999 48,43.5 z"
+ style="color:#000000;fill:url(#radialGradient7833);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
+ <path
+ id="rect7432"
+ d="M 2,41 L 46,41 L 46,46 L 2,46 L 2,41 z"
+ style="fill:url(#linearGradient7835);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+ <path
+ style="fill:#2e3436;fill-opacity:1;stroke:#000000;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 4.2388889,2.5000001 L 1.5,3.8684212 L 1.5,28.500002 L 30.499999,28.500002 L 30.499999,3.8684212 L 27.76111,2.5000001 L 4.2388889,2.5000001 z"
+ id="rect2174"
+ sodipodi:nodetypes="ccccccc" />
+ <path
+ style="fill:url(#linearGradient3151);fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 4.6666667,3 L 27.333332,3 L 30,5 L 2,5 L 4.6666667,3 z"
+ id="rect2761"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ sodipodi:nodetypes="ccccccc"
+ id="path2757"
+ d="M 4.7696847,3.5000001 L 2.5000002,4.5250628 L 2.5000002,27.500001 L 29.500001,27.500001 L 29.500001,4.5250628 L 27.230316,3.5000001 L 4.7696847,3.5000001 z"
+ style="fill:none;fill-opacity:1;stroke:url(#radialGradient6652);stroke-width:1.00000024;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:url(#radialGradient4699);fill-opacity:1;stroke:#204a87;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 4.5,6.5000002 L 27.5,6.5000002 L 27.5,22.500001 L 4.5,22.500001 L 4.5,6.5000002 z"
+ id="rect2759" />
+ <path
+ style="opacity:0.4;fill:url(#linearGradient4307);fill-opacity:1;stroke:none;stroke-width:0.99999994;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 6,8 L 26,8 L 26,11.415255 C 26,11.415255 24.888889,9.7076275 18.777778,13.692092 C 12.666667,17.676555 6,14.898987 6,14.898987 L 6,8 z"
+ id="rect3536"
+ sodipodi:nodetypes="ccczcc" />
+ <path
+ style="fill:none;fill-opacity:1;stroke:url(#linearGradient5097);stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 5.5000001,7.4999998 L 26.500001,7.4999998 L 26.500001,21.499999 L 5.5000001,21.499999 L 5.5000001,7.4999998 z"
+ id="rect3534" />
+ <path
+ style="fill:url(#linearGradient5872);fill-opacity:1;stroke:url(#linearGradient8234);stroke-width:1.00000036;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 3.5000001,23.500001 L 28.5,23.500001 L 28.5,26.499995 L 3.5000001,26.499995 L 3.5000001,23.500001 z"
+ id="rect5099" />
+ <path
+ id="path5874"
+ d="M 4.4999997,25.500001 L 24.500001,25.500001 L 24.500001,24.5 L 4.4999997,24.5 L 4.4999997,25.500001 z"
+ style="fill:none;fill-opacity:1;stroke:url(#linearGradient6263);stroke-width:0.99999988;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1" />
+ <path
+ style="fill:#2e3436;fill-opacity:1;stroke:#555753;stroke-width:0.99999952;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 25.5,24.499999 L 27.499999,24.499999 L 27.499999,25.5 L 25.5,25.5 L 25.5,24.499999 z"
+ id="path7839" />
+ <rect
+ style="opacity:1;fill:#4e9a06;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect7843"
+ width="1"
+ height="1"
+ x="27"
+ y="25" />
+ <rect
+ y="25"
+ x="26"
+ height="1"
+ width="1"
+ id="rect7845"
+ style="opacity:1;fill:#8ae234;fill-opacity:1;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </g>
+</svg>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ar_SA">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>هناك حياة خارج المتصفح!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>النسخة %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 هو برنامج مجاني و لكن برمجته تستهلك وقتا ثمينا.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>الرجاء <a href='%1'>التبرع</a> لمتابعة تطوير %2.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>ارسل الاخطاء و الاراء الى %1</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>صمم الايقونة %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>صمم الواجهة الخفيفة %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>صمم بروكسي HTTP %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>تمت الترجمة بواسطة %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>نشر هذا البرنامج تحت رخصة <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&اقفل</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>عن البرنامج</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>ما اردت معرفته عن %1 و لم تستطع ان تسأل</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>مسح</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>جاري البحث...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>اظهر %1 المزيد</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>لا توجد فيديوات</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation> لا توجد فيديوات اخرى</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>خطأ</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Stop</source>
+ <translation>&قف</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>وقف التشغيل و العودة لوضع البحث</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&القفز</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>القفز للفيديو التالي</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&ايقاف مؤقت</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>ايقاف التشغيل</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&شاشة كاملة</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>تشغيل شاشة كاملة</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&الواجهة الخفيفة</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>اخفاء القائمة و شريط المهام</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>فتح &صفحة YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>اذهب الى صفحة فيديو YouTube و وقف التشغيل</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>نسخ &رابط YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>نسخ رابط YouTube الى clipboard</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>نسخ الفيديو و &الرابط</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>نسخ رابط الفيديو الى clipboard</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&إزالة</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>إزالة الفيديو من القائمة</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>الرفع الى &اعلى</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>رفع المقاطع المختارة الى فوق في القائمة</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>الانزال الى &تحت</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>انزال المقاطع المختارة الى تحت في القائمة</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&مسح كلمات البحث السابقة</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>مسح تاريخ البحث. لا يمكن استعادته.</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&الانتهاء</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>مع السلامة</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&الموقع</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 على الشبكة</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>&التبرع</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>الرجاء التبرع لمتابعة تطوير %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&عن البرنامج</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>معلومات عن %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>البحث</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>كتم الصوت</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&البرنامج</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&القائمة</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&الفيديو</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&المساعدة</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>اضغط %1 لرفع الصوت و %2 لخفضه</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>جاري فتح %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>خطأ قاتل: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>خطأ: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&التشغيل</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>اكمال التشغيل</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>الخروج من &الشاشة الكاملة</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>الوقت المتبقي: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>%1%الصوت عند </translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>الصوت مكتوم</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>الصوت غير مكتوم</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>الوضوح الاقصى %1</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>خصوصيتك امنة</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>اقرب النتائج</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>الاقرب زمنا</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>الاكثر عرضا</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>يمكنك لصق رابط YouTube في برنامج اخر</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>يمكنك لصق رابط الفيديو في برنامج اخر</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>الرابط سيكون صالحا لمدة محدودة.</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>انت تشاهد "%1"</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>خطأ شبكة:%1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 مشاهدات</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>البحث</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>مرحبا بك في <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>اختر كلمة بحث للبدء في مشاهدة المقاطع.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>شاهد</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>كلمات بحث سابقة</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>تم ايجاد نسخة جديدة من %1 الرجاء <a href='%2'>الترقية الى نسخة %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>اجعل نفسك مرتاحا</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>خطأ شبكة:%1 الى %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<!DOCTYPE TS><TS>
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Има живот и извън браузера!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Версия %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 е безплатен софтуер, но разработването му отнема безценно време.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Моля <a href='%1'>дарете</a> за да подкрепите бъдещите разработки, на %2.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Докладвайте за бъгове и изпращайте вашите идей на %1</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Иконите са изработени от %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Компактният режим е допринесен от %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP proxy поддръжката е допринесена от %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Преведено е от %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Издадено е под <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Затваряне</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Относно</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Какво винаги сте искали да знаете за %1 , но никога не сте посмявали да попитате</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Изчисти</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Търся...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Покажи %1 повече</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Няма видеа</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Няма повече видеа</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Грешка</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Stop</source>
+ <translation>&Спри</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Спри изпълнението и се върни в търсачката</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>П&ропусни</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Следващо видео</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Пауза</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Пауза на възпроизвеждането</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Цял екран</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Отвори в цял екран</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Компактен режим</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Скрии прейлистата и туулбара</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Отвори в &YouTube страницата</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Отиди в YouTube видео страницата и сложи на пауза</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Копирай YouTube &връзката</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Постави връзка към видеото в YouTube в клипборда</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Копирай &URL на видео излъчването</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Копирай URL на гледаното видео в клипборда</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Премахни</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Премахни избраните виде от плейлистата</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Премести &нагоре</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Премести избраните видеа в плейлиста</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Премести &надолу</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Премести надолу в плейлиста избраните видеа</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Изчисти скорошните ключови думи</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Изчисти историята на търсене. Не е обратимо.</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Изход</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Чао</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Уебсайт</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 в мрежата</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Направи &дарение</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Моля подкрепете, бъдещите разработки на %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Относно</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Информация за %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Търси</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Заглуши звука</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Апликация</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Плейлиста</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Видео</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Помощ</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Натисни %1 за да увеличите звука, %2 да го намалите</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Отваряне %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Фатална грешка: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Грешка: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Възпроизвеждане</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Възстанови възпроизвеждането</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Изход от &Цял екран</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Оставащо време: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Звук на %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Звука е заглушен</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Звука е отглушен</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Максимално качество на видеото зададено на %1</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Вашата интимност вече е обезопасена</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Най-уместни</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Най-скорошни</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Най-гледани</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Вече можете да вмъкнете YouTube линка в друго приложение</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Вече можете да вмъкнете URL адреса на излъчването в друго приложение</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Линка ще е валиден само за определено време.</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Вие гледате "%1"</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Мрежова грешка: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 гледания</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Търси</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Добре дошли в <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Въведете ключова дума за да почнете да гледате видео клипчета.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Гледай</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Скорошни ключови думи</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Нова версия на %1 е достъпна. Моля <a href='%2'>ъпдейтнете до версия %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Отпуснете се</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Мрежова грешка: %1 за %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+#!/bin/bash
+#
+# This script was written to get some data on how far the various translations are
+# compared to each other
+#
+# This script is donated to the public domain
+#
+# Klaas van Gend, 2008
+
+printf "\n translation file %%ready (unfinished/(total-obsolete))\n"
+printf '=============================================================\n'
+for I in `ls -1 *.ts`;
+do
+ UNFINISHED=`grep 'type="unfinished"' $I | wc -l`;
+ OBSOLETE=`grep 'obsolete' $I | wc -l`;
+ MSGLINES=`grep '</message>' $I | wc -l`;
+ let "REALLINES=$MSGLINES-$OBSOLETE";
+ let "PERCENT=(100*$UNFINISHED)/$REALLINES";
+ let "FINISHED=100-$PERCENT";
+ printf "% 18s : % 4d%% %d/(%d-%d)\n" $I $FINISHED $UNFINISHED $MSGLINES $OBSOLETE ;
+done
+printf "\n"
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="cs_CZ" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <location filename="../src/AboutView.cpp" line="20"/>
+ <source>There's life outside the browser!</source>
+ <translation>Život existuje i mimo prohlížeč!</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="21"/>
+ <source>Version %1</source>
+ <translation>Verze %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Toto je vývojová verze, neočekávejte plnou funkčnost.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="28"/>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Hlaste chyby a posílejte své nápady na %1</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="24"/>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 je svobodný software, ale jeho vývoj stojí drahocenný čas.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Prosím <a href='%1'>přispějte přes PayPal</a> a podpořte další vývoj aplikace %2.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="25"/>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Prosím <a href='%1'>přispějte</a> na další vývoj %2.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="32"/>
+ <source>Icon designed by %1.</source>
+ <translation>Autor ikony: %1.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="33"/>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Autor kompaktního módu: %1.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="34"/>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Autor podpory HTTP proxy: %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Verzi pro Windows sestavil: %1</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="37"/>
+ <source>Translated by %1</source>
+ <translation>Přeložili: %1</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="58"/>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Vydáno pod <a href='%1'>licencí GNU General Public License</a></translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="69"/>
+ <source>&Close</source>
+ <translation>&Zavřít</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.h" line="18"/>
+ <source>About</source>
+ <translation>O aplikaci</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.h" line="20"/>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Co jste vždy chtěli vědět o aplikaci %1 ale nikdy jste se neodvážili zeptat</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <location filename="../src/searchlineedit.cpp" line="56"/>
+ <source>Clear</source>
+ <translation>Odstranit vše</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <location filename="../src/ListModel.cpp" line="46"/>
+ <source>Searching...</source>
+ <translation>Hledám...</translation>
+ </message>
+ <message>
+ <location filename="../src/ListModel.cpp" line="47"/>
+ <source>Show %1 More</source>
+ <translation>Zobrazit dalších %1</translation>
+ </message>
+ <message>
+ <location filename="../src/ListModel.cpp" line="48"/>
+ <source>No videos</source>
+ <translation>Žádná videa</translation>
+ </message>
+ <message>
+ <location filename="../src/ListModel.cpp" line="49"/>
+ <source>No more videos</source>
+ <translation>Žádná další videa</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <location filename="../src/loadingwidget.cpp" line="66"/>
+ <source>Error</source>
+ <translation>Chyba</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Zpět</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Vrátit se k předchozí obrazovce</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="80"/>
+ <source>&Stop</source>
+ <translation>&Stop</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="81"/>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Zastaví přehrávání a vrátí se zpět na vyhledávání</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="86"/>
+ <source>S&kip</source>
+ <translation>Př&eskočit</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="87"/>
+ <source>Skip to the next video</source>
+ <translation>Přeskočí na další video</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="93"/>
+ <location filename="../src/MainWindow.cpp" line="526"/>
+ <source>&Pause</source>
+ <translation>&Pauza</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="94"/>
+ <location filename="../src/MainWindow.cpp" line="527"/>
+ <source>Pause playback</source>
+ <translation>Pozastaví přehrávání</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="100"/>
+ <location filename="../src/MainWindow.cpp" line="605"/>
+ <source>&Full Screen</source>
+ <translation>&Celá obrazovka</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="101"/>
+ <source>Go full screen</source>
+ <translation>Přepne na celou obrazovku</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="107"/>
+ <source>&Compact mode</source>
+ <translation>&Kompaktní mód</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="108"/>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Skryje playlist a toolbar</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Otevřít video na YouTube</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="116"/>
+ <source>Open the &YouTube page</source>
+ <translation>Otevřít stránku &YouTube</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="117"/>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Otevře video na webu YouTube a pozastaví přehrávání</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="123"/>
+ <source>Copy the YouTube &link</source>
+ <translation>Zkopírovat &odkaz na YouTube</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="124"/>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Zkopíruje adresu videa na YouTube do schránky</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="130"/>
+ <source>Copy the video stream &URL</source>
+ <translation>Zkopírovat adresu &video streamu</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="131"/>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Zkopíruje do schránky adresu video streamu</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="137"/>
+ <source>&Remove</source>
+ <translation>&Odstranit</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="138"/>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Odstraní vybraná videa z playlistu</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="144"/>
+ <source>Move &Up</source>
+ <translation>&Nahoru</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="145"/>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Posune vybraná videa výš v playlistu</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="151"/>
+ <source>Move &Down</source>
+ <translation>&Dolů</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="152"/>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Posune vybraná videa níž v playlistu</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="158"/>
+ <source>&Clear recent keywords</source>
+ <translation>&Vymazat hledané výrazy</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="163"/>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Vyprázdní historii vyhledávání. Akci nelze vrátit.</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="168"/>
+ <source>&Quit</source>
+ <translation>&Zavřít</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="170"/>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="171"/>
+ <source>Bye</source>
+ <translation>Sbohem</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="175"/>
+ <source>&Website</source>
+ <translation>&Homepage</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="177"/>
+ <source>%1 on the Web</source>
+ <translation>%1 na Webu</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="181"/>
+ <source>Make a &donation</source>
+ <translation>&Podpořit</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="760"/>
+ <source>Maximum video definition set to %1</source>
+ <translation>Maximální rozlišení videa je %1</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Podpořte přes PayPal</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="182"/>
+ <source>Please support the continued development of %1</source>
+ <translation>Prosím přispějte na další vývoj aplikace %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="186"/>
+ <source>&About</source>
+ <translation>&O aplikaci</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="188"/>
+ <source>Info about %1</source>
+ <translation>Info o aplikaci %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="196"/>
+ <source>Search</source>
+ <translation>Hledat</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="214"/>
+ <source>Mute volume</source>
+ <translation>Ztlumit</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="215"/>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">HD video je povolené</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">HD video není povolené</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Aktuální video je v HD</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Aktuální video není v HD</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="800"/>
+ <source>Your privacy is now safe</source>
+ <translation>Vaše soukromí je nyní v bezpečí</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="264"/>
+ <source>&Application</source>
+ <translation>&Aplikace</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="272"/>
+ <source>&Playlist</source>
+ <translation>&Playlist</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="279"/>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="292"/>
+ <source>&Help</source>
+ <translation>&Nápověda</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="337"/>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Stiskněte %1 pro zvýšení hlasitosti; %2 pro snížení</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="467"/>
+ <location filename="../src/MainWindow.cpp" line="473"/>
+ <source>Opening %1</source>
+ <translation>Otevírám %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="517"/>
+ <source>Fatal error: %1</source>
+ <translation>Chyba: %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="519"/>
+ <source>Error: %1</source>
+ <translation>Chyba: %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="540"/>
+ <source>&Play</source>
+ <translation>&Play</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="541"/>
+ <source>Resume playback</source>
+ <translation>Pokračovat v přehrávání</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="618"/>
+ <source>Exit &Full Screen</source>
+ <translation>Vypnout &fullscreen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="701"/>
+ <source>Remaining time: %1</source>
+ <translation>Zbývající čas: %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="747"/>
+ <source>Volume at %1%</source>
+ <translation>Hlasitost na %1%</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="752"/>
+ <source>Volume is muted</source>
+ <translation>Zvuk je ztlumen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="754"/>
+ <source>Volume is unmuted</source>
+ <translation>Zvuk je zapnut</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <location filename="../src/MediaView.cpp" line="25"/>
+ <source>Most relevant</source>
+ <translation>Nalezená videa</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="32"/>
+ <source>Most recent</source>
+ <translation>Nejnovější</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="39"/>
+ <source>Most viewed</source>
+ <translation>Nejsledovanější</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="339"/>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Nyní můžete vložit odkaz na video na YouTube do jiného programu</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="347"/>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Nyní můžete vložit odkaz na video stream do jiné aplikace</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="348"/>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Tento odkaz platí jen po omezenou dobu.</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.h" line="31"/>
+ <source>You're watching "%1"</source>
+ <translation>Sledujete "%1"</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <location filename="../src/networkaccess.cpp" line="188"/>
+ <source>Network error: %1</source>
+ <translation>Chyba připojení: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <location filename="../src/playlist/PrettyItemDelegate.cpp" line="145"/>
+ <source>%1 views</source>
+ <translation>Shlédnuto %1x</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <location filename="../src/searchlineedit.cpp" line="177"/>
+ <source>Search</source>
+ <translation>Hledat</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <location filename="../src/SearchView.cpp" line="46"/>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Vítejte v <a href='%1'>%2</a></translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="55"/>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Zadejte klíčové slovo pro vyhledávání videí.</translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="75"/>
+ <source>Watch</source>
+ <translation>Sledovat</translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="91"/>
+ <source>Recent keywords</source>
+ <translation>Poslední klíčová slova</translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="186"/>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Nová verze aplikace %1 je dostupná. Prosím <a href='%2'>aktualizujte na verzi %3</a></translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.h" line="29"/>
+ <source>Make yourself comfortable</source>
+ <translation>Udělejte si pohodlí</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Nastavení</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">&Nastavení videa</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Zobrazit video ve vysoké kvalitě pokud je dostupná</translation>
+ </message>
+ <message>
+ <source>&Saved recent keywords</source>
+ <translation type="obsolete">&Uložit hledané výrazy</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="obsolete">&Vymazat hledané výrazy</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Zavřít</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <location filename="../src/video.cpp" line="121"/>
+ <source>Network error: %1 for %2</source>
+ <translation>Chyba přípojení: %1 pro %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="de_DE" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <location filename="../src/AboutView.cpp" line="20"/>
+ <source>There's life outside the browser!</source>
+ <translation>Es existiert Leben neben dem Browser !</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="21"/>
+ <source>Version %1</source>
+ <translation>Version %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Dies ist eine "Technology Vorschau", erwarte nicht, dass sie perfekt ist.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="28"/>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Bitte berichte Fehler und sende Deine Ideen an %1</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="24"/>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 ist freie Software, aber die Entwicklung kostet wertvolle Zeit.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Bitte <a href='%1'>spende via PayPal</a> um die dauerhafte Entwicklung von %2 zu unterstützen.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="25"/>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Bitte <a href='%1'>Spenden</a> um die ständige Entwicklung von %2 zu unterstützen.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="32"/>
+ <source>Icon designed by %1.</source>
+ <translation>Icon Entwurf durch %1.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="33"/>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Kompakt Modus beigetragen von %1.</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="34"/>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP Proxy unterstützung beigetragen von %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Windows Version erstellt durch %1</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="37"/>
+ <source>Translated by %1</source>
+ <translation>Übersetzung durch %1</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="58"/>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Veröffentlicht unter der <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.cpp" line="69"/>
+ <source>&Close</source>
+ <translation>S&chließen</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.h" line="18"/>
+ <source>About</source>
+ <translation>Über</translation>
+ </message>
+ <message>
+ <location filename="../src/AboutView.h" line="20"/>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Was Du schon immer über %1 wissen wolltest, aber nie zu fragen wagtest</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <location filename="../src/searchlineedit.cpp" line="56"/>
+ <source>Clear</source>
+ <translation>Säubern</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <location filename="../src/ListModel.cpp" line="46"/>
+ <source>Searching...</source>
+ <translation>Suche...</translation>
+ </message>
+ <message>
+ <location filename="../src/ListModel.cpp" line="47"/>
+ <source>Show %1 More</source>
+ <translation>Zeige %1 weitere</translation>
+ </message>
+ <message>
+ <location filename="../src/ListModel.cpp" line="48"/>
+ <source>No videos</source>
+ <translation>Keine Videos</translation>
+ </message>
+ <message>
+ <location filename="../src/ListModel.cpp" line="49"/>
+ <source>No more videos</source>
+ <translation>Keine weiteren Videos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <location filename="../src/loadingwidget.cpp" line="66"/>
+ <source>Error</source>
+ <translation>Fehler</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Zurück</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Gehe zur vorherigen Ansicht</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="80"/>
+ <source>&Stop</source>
+ <translation>&Halt</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="81"/>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Wiedergabe anhalten und zurück zur Suchansicht</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="86"/>
+ <source>S&kip</source>
+ <translation>Ü&berspringen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="87"/>
+ <source>Skip to the next video</source>
+ <translation>Überspringe zum nächsten Video</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="93"/>
+ <location filename="../src/MainWindow.cpp" line="526"/>
+ <source>&Pause</source>
+ <translation>&Pause</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="94"/>
+ <location filename="../src/MainWindow.cpp" line="527"/>
+ <source>Pause playback</source>
+ <translation>Wiedergabe pausieren</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="100"/>
+ <location filename="../src/MainWindow.cpp" line="605"/>
+ <source>&Full Screen</source>
+ <translation>&Vollbildmodus</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="101"/>
+ <source>Go full screen</source>
+ <translation>Vollbildmodus aktivieren</translation>
+ </message>
+ <message>
+ <source>&Compact View</source>
+ <translation type="obsolete">&Kompakt Ansicht</translation>
+ </message>
+ <message>
+ <source>Go compact view</source>
+ <translation type="obsolete">Kompakt Ansicht aktivieren</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Öffne die YouTube Video Seite</translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="obsolete">Ctrl+Y</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="107"/>
+ <source>&Compact mode</source>
+ <translation>&Kompakt-Ansicht</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="108"/>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Verstecke Abspielliste und Werkzeugleiste</translation>
+ </message>
+ <message>
+ <source>&Download</source>
+ <translation type="obsolete">&Herunterladen</translation>
+ </message>
+ <message>
+ <source>Download this video</source>
+ <translation type="obsolete">Dieses Video herunterladen</translation>
+ </message>
+ <message>
+ <source>Ctrl+S</source>
+ <translation type="obsolete">Strg+S</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="116"/>
+ <source>Open the &YouTube page</source>
+ <translation>Öffne die &YouTube Seite</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="117"/>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Gehe zur YouTube Video Seite und pausiere die Wiedergabe</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="123"/>
+ <source>Copy the YouTube &link</source>
+ <translation>YouTube &Link kopieren</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="124"/>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>YouTube Link in die Zwischenablage kopieren</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="130"/>
+ <source>Copy the video stream &URL</source>
+ <translation>Video &URL kopieren</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="131"/>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Video URL in die Zwischenablage kopieren</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="137"/>
+ <source>&Remove</source>
+ <translation>Entfe&rnen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="138"/>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Entferne das ausgewählte Video aus der Abspielliste</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="144"/>
+ <source>Move &Up</source>
+ <translation>Bewege &hinauf</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="145"/>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Bewerge das ausgewählte Video in der Abspielliste hinauf</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="151"/>
+ <source>Move &Down</source>
+ <translation>Bewege hin&ab</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="152"/>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Bewege das ausgewählte Video in der Abspielliste hinunter</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="158"/>
+ <source>&Clear recent keywords</source>
+ <translation>Kürzlich genutzte S&chlüsselwörter entfernen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="163"/>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Such Historie leeren. Kann nicht rückgängig gemacht werden.</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="168"/>
+ <source>&Quit</source>
+ <translation>&Verlassen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="170"/>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="171"/>
+ <source>Bye</source>
+ <translation>Tschüss</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="175"/>
+ <source>&Website</source>
+ <translation>&Webseite</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="177"/>
+ <source>%1 on the Web</source>
+ <translation>%1 im Internet</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="181"/>
+ <source>Make a &donation</source>
+ <translation>Eine Spen&den machen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="760"/>
+ <source>Maximum video definition set to %1</source>
+ <translation>Maximale video Definition wurde auf %1 gesetzt</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">Spen&den via PayPal</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="182"/>
+ <source>Please support the continued development of %1</source>
+ <translation>Bitte unterstüte die fortwährende Entwicklung von %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="186"/>
+ <source>&About</source>
+ <translation>&Über</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="188"/>
+ <source>Info about %1</source>
+ <translation>Informationen über %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="196"/>
+ <source>Search</source>
+ <translation>Suche</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="214"/>
+ <source>Mute volume</source>
+ <translation>Audio ausschalten</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="215"/>
+ <source>Ctrl+M</source>
+ <translation>Strg+M</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="337"/>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>%1 drücken um die Lautstärke zu erhöhen, %2 um sie zu verringern</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="701"/>
+ <source>Remaining time: %1</source>
+ <translation>Verbleibende Zeit: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">High Definition Video ist eingeschaltet</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">High Definition Video ist nicht eingeschaltet</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Das derzeitige Video ist in High Definition</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Das derzeitige Video ist nicht in High Definition</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="800"/>
+ <source>Your privacy is now safe</source>
+ <translation>Deine Privatsphäre ist nun geschützt</translation>
+ </message>
+ <message>
+ <source>No Video playing</source>
+ <translation type="obsolete">Es wird kein Video abgespielt</translation>
+ </message>
+ <message>
+ <source>You must first play the video you intent to download !</source>
+ <translation type="obsolete">Du musst das Video erst abspielen !</translation>
+ </message>
+ <message>
+ <source>Save video as...</source>
+ <translation type="obsolete">Video speichern unter...</translation>
+ </message>
+ <message>
+ <source>minitube video.mp4</source>
+ <translation type="obsolete">minitube video.mp4</translation>
+ </message>
+ <message>
+ <source>Downloading: </source>
+ <translation type="obsolete">Herunterladen:</translation>
+ </message>
+ <message>
+ <source>Abort Download</source>
+ <translation type="obsolete">Herunterladen abbrechen</translation>
+ </message>
+ <message>
+ <source>File creation failed</source>
+ <translation type="obsolete">Das anlegen der Datei ist fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>Download failed</source>
+ <translation type="obsolete">Herunterladen fehlgeschlagen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="747"/>
+ <source>Volume at %1%</source>
+ <translation>Lautstärke %1%</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="752"/>
+ <source>Volume is muted</source>
+ <translation>Audio ist ausgeschaltet</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="754"/>
+ <source>Volume is unmuted</source>
+ <translation>Audio eingeschaltet</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Suche</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="264"/>
+ <source>&Application</source>
+ <translation>&Anwendung</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="272"/>
+ <source>&Playlist</source>
+ <translation>&Abspielliste</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="279"/>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="292"/>
+ <source>&Help</source>
+ <translation>&Hilfe</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="467"/>
+ <location filename="../src/MainWindow.cpp" line="473"/>
+ <source>Opening %1</source>
+ <translation>Öffne %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="517"/>
+ <source>Fatal error: %1</source>
+ <translation>Schwerer Fehler: %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="519"/>
+ <source>Error: %1</source>
+ <translation>Fehler: %1</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="540"/>
+ <source>&Play</source>
+ <translation>&Abspielen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="541"/>
+ <source>Resume playback</source>
+ <translation>Wiedergabe fortsetzen</translation>
+ </message>
+ <message>
+ <location filename="../src/MainWindow.cpp" line="618"/>
+ <source>Exit &Full Screen</source>
+ <translation>Vollbildmodus &verlassen</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <location filename="../src/MediaView.cpp" line="25"/>
+ <source>Most relevant</source>
+ <translation>Die bedeutsamsten</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="32"/>
+ <source>Most recent</source>
+ <translation>Die neusten</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="39"/>
+ <source>Most viewed</source>
+ <translation>Meist gesehen</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="339"/>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Du kann den YouTube Link nun in einer anderen Anwendung einfügen</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="347"/>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Die kannst die Video URL nun in einer anderen Anwendung einfügen</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.cpp" line="348"/>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Der Link wird nur eine beschränkte Zeit gültig sein.</translation>
+ </message>
+ <message>
+ <location filename="../src/MediaView.h" line="31"/>
+ <source>You're watching "%1"</source>
+ <translation>Du betrachtest "%1"</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <location filename="../src/networkaccess.cpp" line="188"/>
+ <source>Network error: %1</source>
+ <translation>Netzwerk Fehler: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <location filename="../src/playlist/PrettyItemDelegate.cpp" line="145"/>
+ <source>%1 views</source>
+ <translation>%1 mal betrachtet</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <location filename="../src/searchlineedit.cpp" line="177"/>
+ <source>Search</source>
+ <translation>Suche</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <location filename="../src/SearchView.cpp" line="46"/>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Willkommen bei <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="55"/>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Schlüsselwort eingeben um die Wiedergabe zu starten.</translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="75"/>
+ <source>Watch</source>
+ <translation>Anschauen</translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="91"/>
+ <source>Recent keywords</source>
+ <translation>Aktuelle Schlüsselwörter</translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.cpp" line="186"/>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Eine neue Version von %1 ist verfügbar. Bitte <a href='%2'>auf Version %3 aktuallisieren</a></translation>
+ </message>
+ <message>
+ <location filename="../src/SearchView.h" line="29"/>
+ <source>Make yourself comfortable</source>
+ <translation>Mach es Dir gemütlich</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Einstellungen</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">S&chließen</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <location filename="../src/video.cpp" line="121"/>
+ <source>Network error: %1 for %2</source>
+ <translation>Netzwerk Fehler: %1 für %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="el_GR">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translatorcomment>Πλοηγός = browser, though many people call it just "browser"</translatorcomment>
+ <translation>Υπάρχει ζωή έξω απο τον πλοηγό!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Έκδοση %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Αυτή είναι μια έκδοση «Επίδειξης Τεχνολογίας », μην περιμένετε να είναι τέλεια.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Αναφέρετε προβλήματα και στείλτε τις ιδέες σας στην διεύθυνση %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>Το %1 είναι Ελεύθερο Λογισμικό αλλά η ανάπτυξη του παίρνει πολύτιμο χρόνο.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Παρακαλούμε <a href='%1'>δωρίστε μέσω PayPal</a> για να υποστηρίξετε την συνεχόμενη ανάπτυξη του %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Σχεδιασμός εικονιδίου από %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Μετάφραση από %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Έκδοση κάτω απο τους όρους της <a href='%1'>Γενικής Άδειας Χρήσης GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Κλείσιμο</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Σχετικά</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Ότι θέλατε να μάθετε σχετικά με το %1 και δεν τολμούσατε να ρωτήσετε</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Συνεισφορά της συμπαγούς εμφάνισης (Compact Mode) από %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Συνεισφορά υποστήριξης μεσολαβητή HTTP (proxy) από %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Версія для Windows %1</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Παρακαλούμε <a href='%1%'>δωρίστε</a> για να υποστηρίξετε την συνεχόμενη ανάπτυξη του %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Καθαρισμός</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Αναζήτηση...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Εμφάνιση %1 ακόμα</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Κανένα βίντεο</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Δεν υπάρχουν άλλα βίντεο</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Σφάλμα</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Πίσω</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Alt+Вліво</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Προς την προηγούμενη όψη (view)</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Στοπ</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Στοπ αναπαραγωγής και επιστροφή στην όψη αναζήτησης</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Esc</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Παράλειψη</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Παράλειψη προς το επόμενο βίντεο</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Ctrl+Вправо</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Διακοπή</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Διακοπή αναπαραγωγής</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Клавіша пробілу</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Πλήρης Οθόνη</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Προβολή σε Πλήρη Οθόνη</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Alt+Enter</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Άνοιγμα σελίδας YouTube</translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="obsolete">Ctrl+Y</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Αφαίρεση</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Αφαίρεση επιλεγμένων βίντεο απο την λίστα αναπαραγωγής</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Μετακίνηση προς τα &πάνω</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Μετακίνηση επιλεγμένων βίντεο προς τα πάνω</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Ctrl+Вгору</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Μετακίνηση προς τα &κάτω</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Μετακίνηση επιλεγμένων βίντεο προς τα κάτω</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Ctrl+Вниз</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>Έ&ξοδος</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Γεια</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Ιστοχώρος</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube в мережі</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>Το %1 στο διαδίκτυο</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">Δωρεά μέσω Pa&yPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Παρακαλούμε υποστηρίξτε την συνεχόμενη ανάπτυξη του %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Σχετικά</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Πληροφορίες για %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">Пош&ук</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Εφαρμογή</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>Λ&ίστα αναπαραγωγής</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>Βίν&τεο</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Βοήθεια</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Άνοιγμα %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>Α&ναπαραγωγή</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Συνέχεια αναπαραγωγής</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Έξο&δος απο Πλήρη Οθόνη</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Συμπαγής εμφάνιση</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Απόκρυψη λίστας αναπαραγωγής και εργαλειοθήκης</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Θανάσιμο σφάλμα : %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Σφάλμα: %1</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Ένταση στο %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Σίγαση</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Η ένταση αποκαταστάθηκε</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Αναζήτηση</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Σίγαση</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Πατήστε %1 για να αυξήσετε την ένταση, %2 για να την χαμηλώσετε</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Υπολειπόμενος χρόνος: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Βίντεο Υψηλής Ανάλυσης ενεργό</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Βίντεο Υψηλής Ανάλυσης ανενεργό</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Το τρέχων βίντεο είναι σε Υψηλή Ανάλυση</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Το τρέχων βίντεο δεν είναι σε Υψηλή Ανάλυση</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Καθαρισμός πρόσφατων αναζητήσεων</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Καθαρισμός του ιστορικού αναζήτησης. Δεν μπορεί να γίνει επαναφορά.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Η ιδιωτικότητα σας είναι τώρα ασφαλής</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Ανοίξτε την ιστοσελίδα του &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Πλοήγηση στην σελίδα βίντεο του YouTube και παύση αναπαραγωγής</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translatorcomment>link=σύνδεσμος, however link is more commonly used</translatorcomment>
+ <translation>Αντιγραφή του YouTube &link</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Αντιγραφή του link του τρέχοντος YouTube βίντεο στην μνήμη</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Αντιγραφή του &URL της ροής βίντεο</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Αντιγραφή του URL της τρέχουσας ροής βίντεο στην μνήμη</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Κάντε μια &δωρεά</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>H μέγιστη ανάλυση βίντεο τέθηκε σε %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Πιο σχετικά</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Πιο πρόσφατα</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Πιο προβεβλημένα</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Βλέπετε «%1»</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Τώρα μπορείτε να επικολλήσετε το YouTube link σε κάποια άλλη εφαρμογή</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Τώρα μπορείτε να επικολλήσετε το URL της ροής βίντεο σε κάποια άλλη εφαρμογή</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Ο σύνδεμος θα είναι έγκυρος μόνο για περιορισμένο χρονικό διάστημα.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Σφάλμα δικτύου: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>Προβολές %1</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Αναζήτηση</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Καλωσορίσατε στο <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Εισάγετε μια λέξη-κλειδί για να αρχίσετε να βλέπετε βίντεο.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Δείτε</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Πρόσφατες λέξεις-κλειδιά</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Μια νέα έκδοση του %1 είναι διαθέσιμη. Παρακαλούμε<a href='%2'> αναβαθμίστε στην έκδοση %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Βολευτείτε</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Επιλογές</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">Відео &можливості</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Відтворювати відео високої якості при наявності</translation>
+ </message>
+ <message>
+ <source>&Saved recent keywords</source>
+ <translation type="obsolete">&Збережені недавні терміни пошуку</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="obsolete">Очистити недавн&і терміни пошуку</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">За&крити</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Σφάλμα δικτύου: %1 για %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<!DOCTYPE TS><TS>
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>¡Hay vida más allá del navegador!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versión %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Esta es una edición «Prueba conceptual», no espere que sea perfecta.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Envie sus informes de errores o sus ideas a %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 es Software Libre pero su desarrollo supone un tiempo muy valioso.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Por favor <a href='%1'>haga una donación a través de PayPal</a> para colaborar con el desarrollo de %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Icono diseñado por %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Modo compacto aportado por %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Compatibilidad con proxy HTTP aportado por %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Traducido por %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Publicado bajo la <a href='%1'>Licencia Publica General GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Cerrar</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Acerca de</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Que es lo que siempre quiso saber acerca de %1 y nunca se atrevió a preguntar</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Versión Windows construida por %1</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Haga una <a href='%1'>donación</a> para ayudar en la continuación del desarrollo de %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Limpiar</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Buscando...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mostrar %1 más</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>No hay videos</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>No hay más videos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Error</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Atrás</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Retroceder</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Ir a la vista anterior</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Detener</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Detener la reproducción y volver a la vista de busqueda</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Escape</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Saltar</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Saltar al siguiente video</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Avanzar</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pausar</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pausar la reproducción</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Espacio</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Pantalla completa</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Ir a pantalla completa</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Pantalla completa</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Abrir la pagina del video en YouTube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Eliminar</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Eliminarlos videos seleccionados de la lista de reproducción</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Mover A&rriba</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Mover hacia arriba, en la lista de reproducción, los videos seleccionados</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Arriba</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Mover Aba&jo</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Mover hacia abajo, en la lista de reproducción, los videos seleccionados</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Arriba</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Salir</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Hasta luego</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Sitio &web</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube en internet</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Modo &compacto</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Ocultar la lista de reproducción y la barra de herramientas</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 en la web</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">D&onar a través de PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Por favor apoye el desarrollo continuo de %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Acerca de</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Información acerca de %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Buscar</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Buscar</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Silenciar el volumen</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Aplicación</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Lista de reproducción</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>Ay&uda</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Presione %1 para aumentar el volumen, %2 para reducirlo</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Abriendo %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Error fatal:%1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Error: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Reproducir</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Continuar la reproducción</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Salir de &pantalla completa</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Tiempo restante: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volumen al %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>El volumen está silenciado</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>El volumen no está silenciado</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">El video en alta definición está activado</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">El video en alta definición está desactivado</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">El vídeo actual es de alta definición</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">El vídeo actual no es de alta definición</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>Limpiar palabras &clave recientes</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Limpiar el historial de búsquedas. No se puede deshacer.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Su intimidad ahora está segura
+</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Abrir la página de &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Ir a la página de videos YouTube y pausar la reproducción</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Copiar el en&lace de YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Copiar el enlace actual de video de YouTube en el portapapeles</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Copiar el &URL de flujo de video</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Copiar el URL actual del flujo de video en el portapapeles</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Hacer una &donación</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Resolución máxima de video fijada en %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Más destacados</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Más recientes</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Más vistos</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Está viendo %1</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Ahora puede pegar el enlace de YouTube en otra aplicación</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Ahora puede pegar el URl del flujo de video en otra aplicación</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>El enlace es válido sólo por un tiempo limitado.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Error de red: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 visualizaciones</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Buscar</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Bienvenido a <a href='%1'>%2</a></translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Introduzca una palabra clave para empezar a ver videos.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Ver</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Palabra clave reciente</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Está disponible una nueva versión de %1. Por favor <a href='%2'>actualice a la version %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Sientase cómodo</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Preferencias</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Cerrar</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Error de red: %1 por %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="es_AR" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Hay vida fuera del navegador!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versión-%1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Esta es a edicion "Technology Preview". no espere que sea perfecta.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Reportar errores y envia tus idea a %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 es Software Libre pero su desarrollo lleva tiempo.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Por favor <a href='%1'>donar a través de PayPal para colaborar con el desarrollo de %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Iconos diseñados por %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Traducido por %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Desarrollado bajo <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Acerca</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Que es lo que siempre quisiste saber acerca de %1 y nunca lo preguntaste</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Limpiar</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Buscando...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mostrar %1 más</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>No videos</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>No más videos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Atrás</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Retroceder</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Atrás</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Parar</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Parar</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Escape</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Saltar</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Siguiente</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Avanzar</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pausar</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pausar</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Espacio</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Pantalla completa</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Pantalla completa</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Pantalla completa</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Abrir YouTube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Borrar</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Borrar</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>&Arriba</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Arriba</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Arriba</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>&Abajo</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Abajo</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Arriba</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Salir</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Adiós</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Sitio web</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube en internet</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Donar-a-través de PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Por favor apoyo el desarrollo continuo de-%1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Acerca</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Acercá de-%1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Buscar</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation type="unfinished">Buscar</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation type="unfinished">&Aplicación</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Lista de reproducción</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Ayuda</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Abriendo-%1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Reproducir</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Reproducir</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>&Salir de pantalla completa</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Más relevantes</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Más recientes</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Más visitadas</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Estás viendo %1</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1-visitas</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Buscar</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Bienvenidos a <a href='%1'>%2</a></translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Ingrese palabra a buscar.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Viendo</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Búsquedas recientes</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Una nueva versión de %1 esta disponible. Por favor <a href='%2'>actualice a la version %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Personalizar</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Preferencias</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="es_AR" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>¡Hay vida más allá del navegador!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versión %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Esta es una edición "Technology Preview", no espere que sea perfecta.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Notifique errores y envie sus ideas a %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 es Software Libre pero su desarrollo supone valioso tiempo.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Por favor <a href='%1'>done a través de PayPal</a> para colaborar con el desarrollo de %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Icono diseñado por %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Modo compacto contribuido por %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Soporte de proxy HTTP contribuido por %1</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Versión Windows compilada por %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Traducido por %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Desarrollado bajo la <a href='%1'>Licencia publica general GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Cerrar</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Acerca de</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Que es lo que siempre quiso saber acerca de %1 y nunca osó preguntar</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Limpiar</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Buscando...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mostrar %1 más</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>No videos</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>No más videos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Atrás</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Retroceder</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Ir a vista previa</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Detener</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Detener reproducción y volver a la busqueda</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Escape</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Saltar</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Saltar al siguiente video</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Avanzar</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pausar</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pausar reproducción</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Espacio</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>Pantalla &completa</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Ir a pantalla completa</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Pantalla completa</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Abrir pagina del video en YouTube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Borrar</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Borrar los videos seleccionados de la lista de reproducción</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Mover A&rriba</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Mover arriba los videos seleccionados en la lista de reproducción</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Arriba</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Mover Aba&jo</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Mover Abajo los videos seleccionados en la lista de reproducción</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Arriba</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Salir</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Adiós</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Sitio &web</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube en internet</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Modo &Compacto</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Ocultar la lista de reproducción y la barra de herramientas</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 en la Web</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">D&onar a través de PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Por favor sustente el desarrollo continuo de %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Acerca de</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Información de %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Buscar</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Buscar</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Silenciar</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation type="unfinished">&Aplicación</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Lista de reproducción</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Ayuda</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Presione %1 para aumentar el volumen, %2 para reducirlo</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Abriendo-%1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Error fatal:%1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Reproducir</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Continuar Reproducción</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>&Salir de pantalla completa</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Tiempo restante: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volumen al %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Volumen silenciado</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Volumen activado</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Video de alta definición activado</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Video de alta definición no activado</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">El video actual es de alta definición</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">El video actual no es de alta definición</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Más relevantes</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Más recientes</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Más vistos</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Está viendo %1</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Error de red: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1-visualizaciones</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Buscar</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Bienvenido a <a href='%1'>%2</a></translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Introduzca una palabra para empezar a ver videos.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Ver</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Búsquedas recientes</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Una nueva versión de %1 esta disponible. Por favor <a href='%2'>actualice a la version %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Personalizar</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Preferencias</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Cerrar</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Error de red: %1 por %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="fi_FI">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Elämää on muuallakin kuin selaimessa!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versio numero: %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 on ilmainen ohjelma,mutta sen kehittäminen vie kallista aika.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Olisi mukaavaa jos tukisit %2 kehitystä tekemällä <a href='%1'>lahjoituksen</a>.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Kerro virheistä/ongelmista ja jaa ideoitasi osoitteeseen %1</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Kuvakkeen suunnitteli %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Kompaktin tilan teki %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP välityspalvelin tuen teki %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Käännöksen teki %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Julkaistu <a href='%1'>GNU General Public License</a> lisenssin alla</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Sulje</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Tietoja</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Mitä olet aina halunnut tietää %1sta muttet ole koskaan kehdannut kysyä</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Tyhjennä</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Etsitään...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Näytä %1 lisää</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Ei videoita</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Ei enempää videoita</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Virhe</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Stop</source>
+ <translation>&Pysäytä</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Pysäytä taista ja palaa hakuruuttun</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Hyppää yli</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Siirry seuraavaan videoon</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Stoppaa</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pysäytä toistaminen</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Kokoruutu</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Vaihda kokoruutu tilaan</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Kompakti tila</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Piilota toistolista sekä työkalupalkki</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Avaa &Youtube sivusto</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Pysäytä toisto ja mene YouTube sivulle</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Kopio YouTube &linkki</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Kopio nykyisen videon YouTube linkki</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Kopio videovirran osoite (&URL)</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Kopio nykyisen videvirran osoite (URL)</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Poista</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Poista valittu video listalta</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Siirrä &Ylös päin</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Siirrä valittu video ylemmäksi listalla</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Sirrä &Alas päin</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Siirrä valittu video alemmaksi listalla</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Poista viimeisimmät haut</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Tyhjennä haku historia. Tätä toimintoa ei voi kumota.</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Poistu</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Heippa</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Nettisivu</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 netissä</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Tee &lahjoitus</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Tue %1n jatkuvaa kehitystä</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Tietoja</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Tiotoja %1sta</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Etsi</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Mykistä ääni</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Ohjelma</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Soittolista</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Apua</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Paina %1ta nostaaksesi tai %2ta laskeaksesi äänen voimakkuutta</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Avataan %1ta/tä</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Kauhia Virhe: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Virhe: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Toista</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Jatka toistoa</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Poistu &kokoruudun tilasta</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Aikaa jäljellä: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Äänen tasa %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Ääni on mykistetty</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Ääni ei ole mykistetty</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Suurin videon laatu on rajoiteetu %1aan/ään</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Yksityisyytesi on nyt turvattu</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Olennaisin</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Uusin</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Katsotuin</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Voit nyt liittää YouTube linkin johonkin toiseen ohjelmaan</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Voit nyt liittää videovirran osoitteen(URL) johonkin toiseen ohjelmaan</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Osoite on käytössä vain rajoitetun ajan.</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Nyt pyörii "%1"</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Verkko virhe: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>Katsottu %1 kertaa</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Etsi</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation><a href='%1'>%2en</a></translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Anna hakusana alkaaksesi katsella videoita.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Katso</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Viimeisimmät hakusanat</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Uusi versio %1sta on saatavilla. <a href='%2'>Päivitäthän versioon %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Tee olosi kotoisaksi</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Verkko virhe: "%1" "%2"lle</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<!DOCTYPE TS><TS>
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Il y a une vie après le browser !</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Version %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Ceci est une "Preview Technologique", ne vous attendez pas à ce que ce soit parfait.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Rapportez les bugs et envoyez vos idées à %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 est un Logiciel Libre, mais son développement prend un temps précieux.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Merci <a href='%1'>d'envoyer vos dons via PayPal</a> pour aider à poursuivre le développement de %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Icône déssinée par %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Mode compact développé par %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Support du proxy HTTP apporté par %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Version Windows faite par %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Traduction par %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Proposé sous licence <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Fermer</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>A propos</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Ce que vous avez toujours voulu savoir à propos de %1 et que vous n'avez jamais osé le demander</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Merci <a href='%1'>d'envoyer vos dons</a> pour aider à poursuivre le développement de %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Effacer</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Recherche...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Afficher %1 de plus</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Pas de vidéos</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Plus de vidéos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Erreur</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Retour</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Aller à la vue précédente</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Stop</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Arrêter et aller à la page de recherche</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Sauter</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Passer à la vidéo suivante</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pause</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Mettre en pause</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Plein écran</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Mettre en plein écran</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Mode &compact</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Cacher la playlist</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&Youtube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Ouvrir la page Youtube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Supprimer</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Supprimer la vidéo sélectionnée de la liste de lecture</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Déplacer vers les &haut</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Déplacer la vidéo sélectionnée vers le haut dans la liste de lecture</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Déplacer vers les &bas</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Déplacer la vidéo sélectionnée vers le bas dans la liste de lecture</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Quitter</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Au revoir</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Site &Web</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 sur le Web</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">Faire un &don via PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Merci d'aider à poursuivre le développement de %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&A propos</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>A propos de %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Chercher</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Couper le son</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Liste de lecture</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Aide</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Appuyer sur %1 pour augmenter le volume, sur %2 pour le baisser</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Ouverture de %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Erreur fatale : %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Erreur : %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Jouer</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Relancer la lecture</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Quitter le &plein écran</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Temps restant : %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volume à %1</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Volume OFF</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Volume ON</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Haute définition activée</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Haute définition désactivée</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">La vidéo actuelle est en Haute Définition</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">La vidéo actuelle n'est pas en Haute Définition</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Effacer les derniers mots-clés</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Application</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Effacer l'historique de recherche. Opération irréversible.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Votre confidentialité est maintenant respectée</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Ouvrir la page &Youtube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Aller à la page de la vidéo Youtube et mettre en pause</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Copier le &lien Youtube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Copier l'adresse de la vidéo YouTube courante dans le presse-papier</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Copier l'adresse du flux &vidéo</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Copier l'adresse du flux vidéo courant dans le presse-papier</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Faire un &don</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Résolution vidéo maximale fixée à %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Plus pertinent</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Plus récent</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Plus vus</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Vous regardez %1</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Vous pouvez maintenant copier l'adresse Youtube dans une autre application</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Vous pouvez maintenant coller l'adresse du flux vidéo dans une autre application</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Le lien ne sera valide que pour un temps limité.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Erreur réseau : %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 vues</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Chercher</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Bienvenue sur <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Entre un mot-clé pour commencer à regarder des vidéos.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Regarder</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Derniers mots-clés</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Une nouvelle version de %1 est disponible. Merci <a href='%2'>de mettre à jour pour la version %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Installez-vous confortablement</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Préférences</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Erreur réseau : %1 pour %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<!DOCTYPE TS><TS>
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Existe vida máis aló do navegador!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versión %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Esta é unha edición «Proba conceptual», non agarde que sexa perfecta.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Envie os seus informes de erros ou as súas ideas a %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 é Software libre, mais o seu desenvolvemento leva un tempo precioso.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Por favor, <a href='%1'>faga unha donación a través de PayPal</a> para apoiar o desenvolvemento continuo de %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Icona deseñada por %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Traducido por %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Publicado baixo a <a href='%1'>Licenza pública Xeral GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Pechar</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Acerca de</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>O que vostede sempre quixo saber acerca de %1 e nunca se atreveu a preguntar</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Modo compacto aportado por %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Compatibilidade con proxy HTTP aportado por %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">A versión Windows foi construida por %1</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Faga unha <a href='%1'>donación</a> para axudar na continuación do desenvolvemento de %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Limpar</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Buscando...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mostrar %1 máis</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Non hai vídeos</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Non hai máis vídeos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Atrás</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Alt+Left</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Ir para a vista anterior</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Deter</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Deter a reprodución e volver á vista de busca</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Esc</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Saltar</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Saltar ao seguinte vídeo</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Ctrl+Right</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pausar</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pausar a reprodución</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Barra de espaço</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Pantalla completa</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Ir á pantalla completa</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Alt+Enter</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Abrir a páxina do vídeo en YouTube</translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="obsolete">Ctrl+Y</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Eliminar</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Eliminar os videos seleccionados da lista de reprodución</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Mover cara &arriba</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Mover cara arriba os vídeos selecionados na lista de reprodución</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Ctrl+Up</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Mover cara a&baixo</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Mover cara abaixo os vídeos selecionados na lista de reprodución</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Ctrl+Down</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Saír</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Deica logo</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Sitio &web</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube na Web</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 na web</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Doar ao través de PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Por favor apoie o desenvolvemento continuo de %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Acerca de</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Información acerca de %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Pesquisar</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Aplicativo</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Lista de reprodución</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Vídeo</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>A&xuda</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Abrindo %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Reproducir</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Continuar a reprodución</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Saír de &pantalla completa</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Modo &compacto</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Agochar a lista de reprodución e a barra de tarefas</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Erro fatal: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Erro: %1</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volume ao %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>O volume está silenciado</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>O volume non está silenciado</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Buscar</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Silenciar o volume</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Prema %1 para aumentar o volume, %2 para diminuilo</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Tempo restante: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">O vídeo en alta definición está activado</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">O vídeo en alta definición non está activado</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">O vídeo actual é de alta definición</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">O vídeo actual non é de alta definición</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>Limpar palabras &clave recentes</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Limpar o historial de buscas. Non se pode desfacer.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>A súa intimidade agora está segura</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Abrir a páxina de &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Ir á páxina de vídeos YouTube e pausar a reprodución</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Copiar a &ligazón de YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Copiar a ligazón actual de vídeo de YouTube no portaretallos</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Copiar o &URL de fluxo de vídeo</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Copiar o URL actual do fluxo de vídeo no portaretallos</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Facer unha &donación</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Resolución máxima de vídeo fixada en %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Máis destacados</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Máis recentes</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Máis vistos</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Está a ver "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Agora pode pegar a ligazón de YouTube noutro aplicativo</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Agora pode pegar o URL do fluxo de vídeo noutro aplicativo</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>A ligazón ten validez só por un tempo limitado.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Erro na rede: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 visualizacións</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Buscar</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Benvindo ao <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Escriba unha palabra clave para comezar a ver os vídeos.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Ver</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Palabra clave recente</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Está dispoñible unha nova versión de %1. Por favor, <a href='%2'>actualice cara a versión %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Síntase cómodo</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Preferencias</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">Opções de &vídeo</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Utilizar vídeo de alta qualidade quando estiver disponível</translation>
+ </message>
+ <message>
+ <source>&Saved recent keywords</source>
+ <translation type="obsolete">Palavras-chave &salvas recentemente</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="obsolete">Palavras-chave &limpas recentemente</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Fechar</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Erro na rede: %1 por %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="he_IL">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>יש חיים מחוץ לדפדפן!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>גרסה %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation>הפצה זו הנה "הצגה טכנולוגית מקדימה", אל תצפו ממנה להיות מושלמת.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>יש לדווח על באגים ורעיונות אל %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 הינה תוכנה חופשית אך פיתוחה לוקח המון זמן יקר.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation>אנא <a href='%1'>תרמו באמצעות PayPal</a> כדי לתמוך בהמשך הפיתוח של %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>הסמל עוצב על ידי %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>המצב החסכוני נתרם על ידי %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>תורגם על ידי %1.</translation>
+ </message>
+ <message>
+ <source>Released under the </source>
+ <translation>שוחרר תחת תנאי</translation>
+ </message>
+ <message>
+ <source></source>
+ <translation>&סגירה</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>על אודות</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>מה שתמיד רצית לדעת אודות %1 ולא העזת לשאול</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>התוכנה שוחררה תחת תנאי <a href='%1'>הרישיון הציבורי הכללי של GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&סגירה</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>התמיכה במתווך HTTP נתרמה על ידי %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation>הגרסה ל־Windows נבנתה על ידי %1</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>אנא <a href='%1'>תרמו</a> כדי לתמוך בהמשך הפיתוח של %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>מחיקה</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>מחפש...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>הצגת %1 נוספים</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>אין סרטונים</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>אין עוד סרטונים</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>שגיאה</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source></source>
+ <translation>&חזרה</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation>מעבר אל התצוגה הקודמת</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&עצירה</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>עצירת הנגינה וחזרה אל תצוגת החיפוש</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&דילוג</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>דילוג אל הסרטון הבא</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>ה&שהיה</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>השהיית הנגינה</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&מסך מלא</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>מעבר למסך מלא</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>מצב &חסכוני</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>הסתרת רשימת ההשמעה וסרגל הכלים</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation>&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation>פתיחת עמוד הווידאו ב־YouTube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>ה&סרה</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>הסרת הסרטונים הנבחרים מרשימת ההשמעה</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>הזזה מ&מעלה</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>הזזת הסרטונים הנבחרים במעלה רשימת ההשמעה</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>הזזה מ&טה</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>הזזת הסרטונים הנבחרים במורד רשימת ההשמעה</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>י&ציאה</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>להתראות</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&אתר האינטרנט</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 באינטרנט</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation>&תרומה באמצעות PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>אנא תמכו בהמשך הפיתוח של %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&על אודות</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>מידע אודות %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation>&חיפוש</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&יישום</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&רשימת השמעה</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&וידאו</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&עזרה</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>%1 נפתח</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>שגיאה מכרעת: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>שגיאה: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&נגינה</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>המשך הנגינה</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>יציאה ממ&סך מלא</translation>
+ </message>
+ <message>
+ <source>&Back</source>
+ <translation>&חזרה</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>חיפוש</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>השתקת השמע</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>ניתן ללחוץ על %1 כדי להגביר את עצמת השמע, %2 כדי להנמיך אותה</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>הזמן הנותר: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>עצמת השמע היא %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>השמע מושתק</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>השמע אינו מושתק</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation>האפשרות לצפיה באיכות גבוהה פעילה</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation>האפשרות לצפיה באיכות גבוהה אינה פעילה</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation>סרטון הווידאו הנוכחי הנו באיכות גבוהה (HD)</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation>סרטון הווידאו הנוכחי אינו באיכות גבוהה (HD)</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>מחיקת &מילות המפתח האחרונות</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>מחיקת היסטוריית החיפוש. לא ניתן לבטל</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>פרטיותך מוגנת כעת.</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>פthe &תיחת העמוד ב־YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>מעבר לעמוד הווידאו ב־YouTube והשהיית הנגינה.</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>העתקת ה&קישור ל־YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>העתקת הקישור אל הווידאו הנוכחי אל לוח הגזירים</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>העתקת כתובת &תזרים הווידאו</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>העתקת כתובת תזרים הווידאו אל לוח הגזירים</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>&מתן תרומה</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>איכות הנגינה המירבית מוגדרת ל־%1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>הרלוונטיים ביותר</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>העדכניים ביותר</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>הנצפים ביותר</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>הנכם צופים ב־"%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>כעת ניתן להדביק את קישור ה־YouTube שלכם ליישום אחר</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>כעת ניתן להדביק את כתובת תזרים הווידאו ליישום אחר</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>הקישור יהיה תקף לזמן מוגבל בלבד.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>שגיאת רשת: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 צפיות</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>חיפוש</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>ברוכים הבאים אל <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>הזינו מילת מפתח כדי להתחיל לצפות בסרטונים.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>צפיה</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>מילות מפתח אחרונות</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>גרסה חדשה של %1 זמינה להורדה. אנא <a href='%2'>עדכנו לגרסה %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>שבו בניחותא</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation>העדפות</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>שגיאת רשת: %1 עבור %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="hr_HR">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Postoji život izvan preglednika!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Verzija %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Ovo je "Technology Preview"izdanje, te ne očekujte da bude savršeno.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Prijavite sve bugove i posaljite svoje ideje na %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 je besplatan program ali njegov razvoj uzima dragocjeno vrijeme.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Molimo <a href='%1 '>donirajte preko PayPal-a</a> za podršku i kontinuiran razvoj %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Ikonu je dizajnirao %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Kompaktni način pridonio je %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP proxy podršku je pridonio %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Windows verziju uradio je %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Preveo je %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Objavljeno je pod <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Zatvori</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>O</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Što ste oduvijek željeli znati o %1 a nikad se niste usudili pitati</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Očisti</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Pretraživanje...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Pokaži još jedan %1</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Nema videa</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Nema više videa</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Greška</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Natrag</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Idi na prethodni prikaz</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Stani</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Zaustavi playback i vrati se na pretraživanje</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>Preskoči</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Preskoči na sljedeći video</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pauza</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pauziraj playback</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Cijeli ekran</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Gledaj preko cijelog ekrana</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Kompaktan način</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Sakrij naslove i alatnu traku</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Otvori YouTube video stranicu</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Ukloni</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Ukloni odabrane snimke sa playliste</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Premjesti gore</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Premjesti gore selektirane snimke u playlistu</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Premjesti &Dolje</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Premjesti dolje selektirane snimke u playlistu</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Odustani</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Pozdrav</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Web stranica</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 na internetu</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Donirajte preko PayPal-a</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Molimo potporu u daljnjem razvoju %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&O</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Info o %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Pretraga</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Isključi zvuk</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Playlista</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Pomoć</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Pritisnite %1 za povećati zvuk, %2 za smanjiti zvuk</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Otvaranje %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Fatalna greška: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Greška: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Pusti</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Nastavi playback</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Izlaz&Cijeli ekran</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Preostalo vrijeme: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Jačina zvuka je na %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Zvuk je isključen</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Zvuk je uključen</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Visoka rezolucija videa je uključena</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Visoka rezolucija videa je isključena</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Odabrani video je u visokoj rezoluciji</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Odabrani video nije u visokoj rezoluciji</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Najznačajniji</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Najnoviji</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Najgledaniji</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Gledate "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Greška u mreži:%1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 gledano</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Pretraga</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Dobro došli <a href='%1'>%2</a></translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Unesite ključnu riječ za početak gledanja videa.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Gledaj</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Nedavno gledano</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Nova verzija %1 je dostupna. Molimo <a href='%2'>nadogradite verziju %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Osjećajte se udobno</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Postavke</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Greška u mreži:%1 za %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="hu_HU">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Van élet a böngészőn kívül!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>%1 verzió</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Ez egy bemutató verzió, nem biztos, hogy tökéletesen működik.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Hibabejelentés, ötletek: %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>A %1 szabad szoftver, de a fejlesztés időbe telik és az idő pénz.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Kérlek <a href='%1'>adakozz Paypalon keresztül</a>, hogy segítsd a %2 fejlesztését.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Az ikonokat tervezte: %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Kompakt mód: %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP proxy támogatás: %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Windows verzió: %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Fordította: %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Kiadva <a href='%1'>GNU General Public License</a> alatt</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Bezárás</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Névjegy</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Amit mindig is tudni akartál a %1-ról, de sosem merted megkérdezni</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Kérlek <a href='%1'>adakozz</a>, hogy folytathassam a %2 fejlesztését</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Törlés</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Keresés...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mutass még %1-et</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Nincsenek videók</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Nincs több videó</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Hiba</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Vissza</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Vissza az előző nézethez</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Állj</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Megáll és visszamegy a keresőbe</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Kihagyás</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Kihagyja a következő videót</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Szünet</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Szünetelteti a lejátszást</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Teljes képernyő</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Teljes képernyőre teszi a videót</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>K&ompakt mód</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Elrejti a lejátszó listát és az eszköztárat</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Megnyitja a YouTube videómegosztó oldalt</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Törlés</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Eltávolítja a kijelölt videókat a listából</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>&Fel</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Előrehozza a kijelölt videókat a listán</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>&Le</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Lejjebb viszi a kijelölt videókat a listán</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Kilépés</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Viszlát</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Weboldal</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 a weben</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Adakozás PayPalon keresztül</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Kérlek támogasd a %1 fejlesztését</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Névjegy</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Információk a %1-ról</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Keresés</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Némítás</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Lejátszó lista</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Segítség</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Nyomd meg a %1 gombot a hangosításhoz, a %2 gombot a halkításhoz</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Megnyitás %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Végzetes hiba: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Hiba: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Lejátszás</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Lejátszás folytatása</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Kilépés a &Teljes képernyőből</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Hátralévő idő: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Hangerő: %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Némítás bekapcsolva</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Némítás kikapcsolva</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">HD videó bekapcsolva</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">HD videó kikapcsolva</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Ez a videó HD minőségű</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Ez a videó nem HD minőségű</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Legújabb kulcsszavak törlése</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Alkalmazás</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Keresési előzmények törlése. Nem visszavonható.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Biztonságban vagy</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>A YouTube megnyitása</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>A YouTube oldalra irányítás és a lejátszás szüneteltetése</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>YouTube link másolása</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Az aktuális YouTube video link másolása vágólapra</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>A video stream &URL másolása</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Az aktuális video stream URL másolása vágólapra</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>A&dakozz</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Maximum videó minőség beállítása %1-ra</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Kapcsolódó videók</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Legújabbak</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Legnézettebbek</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>A "%1"-t nézed</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Most már beillesztheted a YouTube linket más alkalmazásba</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Most már beillesztheted a video stream URL-t más alkalmazásba</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>A link korlátozott ideig érvényes</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Hálózati hiba: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1x megtekintve</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Keresés</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Üdvözöl a <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Írd be a keresendő kifejezést.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Keresés</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Gyakori kulcsszavak</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>A %1 új verziója elérhető. Kérlek <a href='%2'>frissíts erre a verzióra: %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Helyezd magad kényelembe</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Beállítások</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Hálózati hiba: %1 for %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="it_IT" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>C'è vita fuori del browser!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versione %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Questa è una versione Beta, non aspettarti che sia perfetta.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Segnala problemi e manda le tue idee a %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 è Software Libero ma il suo sviluppo richiede tempo prezioso.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Per favore <a href='%1'>fai una donazione con PayPal</a> per aiutare lo sviluppo di %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Icona disegnata da %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Modalità compatta sviluppata da %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Tradotto da %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Rilasciato sotto licenza <a href="%1">GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Chiudi</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Informazioni</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Quello che hai sempre voluto sapere su %1 e non hai mai osato chiedere</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Supporto per i proxy HTTP svilupparo da %1</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Versione per Windows compilata da %</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation><a href="%1">Fai una donazione</a> per aiutare lo sviluppo di %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Cancella</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Ricerca...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mostra altri %1</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Nessun video</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Nessun altro video</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Errore</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Indietro</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Vai alla vista precedente</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Ferma</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Ferma il video e torna alla ricerca</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Salta</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Salta al prossimo video</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pausa</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Metti in pausa</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Schermo intero</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Vai in modalità schermo intero</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Modalità compatta</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Nascondi la playlist e la barra degli strumenti</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Apri la pagina del video su YouTube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Elimina</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Elimina i video selezionati dalla playlist</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Sposta &sopra</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Sposta video selezionati verso l'alto</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Sposta so&tto</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Sposta i video selezionati verso il basso</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Esci</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Ciao</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Sito &web</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volume al %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Audio disattivato</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Audio attivato</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube sul Web</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 sul Web</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">Fai una &donazione con PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Supporta lo sviluppo di %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Informazioni</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Informazioni su %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Ricerca</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Applicazione</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Aiuto</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Apertura di %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Errore fatale: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Errore: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Continua</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>&Esci dallo schermo intero</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Cerca</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Disattiva l'audio</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Premi %1 per alzare il volume, %2 per abbassarlo</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Tempo rimanente: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Il video ad alta definizione è abilitato</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Il video ad alta definizione è disabilitato</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Il video corrente è in alta definizione</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Il video corrente non è in alta definizione</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Cancella le ultime ricerche</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>&Cancella le ultime ricerche. L'azione non potrà essere annullata.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>La tua privacy è al sicuro</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Apri su &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Vai su YouTube e metti in pausa</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Copia il &link a YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Copia negli appunti il link a YouTube per il video corrente</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Copia la &URL dello stream video</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Copia negli appunti la URL dello stream per il video corrente</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Fai una donazione</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>La definizione video massima è impostata a %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Più rilevanti</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Più recenti</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Più visti</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Stai guardando "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Ora puoi incollare il link a YouTube in un'altra applicazione</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Ora puoi incollare la URL dello stream in un'altra applicazione</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Il link rimarrà valido per un periodo di tempo limitato.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Errore di rete: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 visualizzazioni</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Cerca</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Benvenuto su <a href="%1">%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Scrivi una parola chiave per iniziare a guardare i video.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Guarda</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Ultime ricerche</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>È disponibile una nuova versione di %1. <a href='%2'>Aggiorna alla versione %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Mettiti comodo</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Opzioni</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">Opzioni &video</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Usa video ad alta definizione se disponibile</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Chiudi</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Errore di rete: %1 per %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ja_JP">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Webブラウザなしでも大丈夫!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>バージョン %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">このプログラムは"テクノロジープレビュー"です。完璧な動作は期待しないでください。</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>バグレポートやアイデアは%1までお願いします</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1はフリーソフトウェアですが、開発には貴重な時間が費やされています。</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">%2の開発/サポートのため、<a href='%1'>寄付</a>をお願いします。</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>アイコンは%1さんのデザインです。</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>コンパクトモードは%1さんの貢献です。</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>翻訳は%1さん達の協力です</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation><a href='%1'>GNU General Public License</a>で配布されます</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>閉じる(&C)</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>プログラムについて</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>%1について知りたいことがあったら、思いきって連絡をください</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>クリア</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>検索中...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>さらに%1エントリ観る</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>見つかりませんでした</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>見つかりませんでした</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>エラー</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">戻る(&B)</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">前のビューに戻る</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>ストップ(&S)</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>再生を停止させて、検索ビューに戻ります</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>スキップ(&k)</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>次の動画へ</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>一時停止(&P)</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>再生を一時停止します</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>フルスクリーン(&F)</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>フルスクリーン</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>コンパクトモード(&C)</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>プレイリストとツールバーを隠す</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">YouTube(&Y)</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">YouTubeの動画Webページを開く</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>削除(&R)</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>プレイリストから選択した動画を削除</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>上へ(&U)</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>選択した動画をプレイリスト内で上へ移動させます</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>下へ(&D)</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>選択した動画をプレイリスト内で下へ移動させます</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>終了(&Q)</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>プログラムを終了</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Webページへ(&W)</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1のWebページを開きます</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">寄付(&D)</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>%1の開発をサポートしてください!</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>プログラムについて(&A)</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>%1について</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl-M</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation type="unfinished">アプリケーション(&A)</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>プレイリスト(&P)</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>動画(&V)</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>ヘルプ(&H)</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>%1を開いています</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>致命的なエラー: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>エラー: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>再生(&P)</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>再生再開します</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>フルスクリーンから戻る(&F)</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>ボリューム%1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>音量OFFにしました</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>音量ONにしました</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation type="unfinished">検索</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>関連度</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>新着</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>閲覧回数</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>"%1"を閲覧中</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation type="unfinished"></translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>ネットワークエラー: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1回 閲覧</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>検索</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>ようこそ<a href='%1'>%2</a>へ!</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>探している動画のキーワードを入力。</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>検索</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>最近検索したキーワード</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>新しい%1があります。<a href='%2'>バージョン%3へバージョンアップ</a>しましょう</translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>さあリラックスしましょう</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">設定</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">閉じる(&C)</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>ネットワークエラー: %1 (%2へのアクセスにて)</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="lv_LV" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Arī ārpus web pārlūka ir dzīve!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versija %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation>Šis ir priekšapskates izlaidums, negaidiet no tā brīnumus.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Ziņojiet par kļūdām un iesūtiet idejas: %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 ir Bezmaksas Programma, taču tās izstrāde prasa dārgu laiku.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation>Lūdzu, <a href='%1'>ziedojiet ar PayPal</a>, lai atbalstītu %2 turpmāku izstrādi.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Ikonu izveidoja %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Kompakto režīmu iespējoja %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP proxy atbalstu iespējoja by %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation>Windows versiju izveidoja %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Pārtulkoja %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Licencēts pēc <a href='%1'>GNU Vispārējās Publiskās Licences</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Aizvērt</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Par</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Ko jūs vienmēr vēlējāties zināt par %1, taču neuzdrošinājāties pajautāt</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Lūdzu, <a href='%1'>ziedojiet</a>, lai atbalstītu %2 turpmāku izstrādi.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Dzēst</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Meklē...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Parādīt vairāk no %1</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Nav klipu</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Vairs nav klipu</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Kļūda</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation>Atpakaļ</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation>Atgriezties iepriekšējā skatā</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>Apturēt</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Apturēt atskaņošanu un atgriezties meklēšanas logā</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>Izlaist</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Pārlēkt uz nākamo klipu</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>Pauze</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Apturēt</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>Pilnekrāna režīms</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Ieslēgt pilnekrāna režīmu</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Kompaktais režīms</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Paslēpt klipu sarakstu un rīkjoslu</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation>&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation>Atvērt YouTube vietni</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>Izņemt</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Izņemt atzīmētos klipus</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Pārcelt augšup</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Pārcelt atzīmētos klipus augšup</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Pārcelt lejup</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Pārcelt atzīmētos klipus lejup</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>Beigt darbu</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Visu labu</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Tīmekļa vietne</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 tīmeklī</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation>Ziedojiet ar PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Lūdzu, atbalstiet %1 turpmāku izstrādi</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>Par</translation>
+ </message>
+ <message>
+ <source>Info par %1</source>
+ <translation>Ziņas par %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Meklēt</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Izslēgt skaņu</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>Klipu saraksts</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>Klips</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>Palīdzība</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Nospiediet %1 lai palielinātu skaļumu, %2 lai to samazinātu</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Atvēru %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Nenovēršama kļūda: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Kļūda: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>Atskaņot</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Turpināt atskaņošanu</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Pārslēgties pilnekrāna režīmā</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Atlikušais laiks: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Skaļuma līmenis: %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Skaņa ir atslēgta</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Skaņa ir ieslēgta</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Ziņas par %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation>Augstā izšķirtspēja ir ieslēgta</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation>Augstā izšķirtspēja nav ieslēgta</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation>Šis ir augstās izšķirtspējas video</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation>Šis nav augstās izšķirtspējas video</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>Dzēst atslēgvārdu vēsturi</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>Programma</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Dzēst meklēšanas vēsturi. Šī rīcība būs neatgriezeniska.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Jūsu privātums tagad ir drošībā</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Atvērt &YouTube vietni</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Doties uz YouTube video vietni un apturēt atskaņošanu</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Nokopēt YouTube norādi</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Nokopēt esošā klipa YouTube norādi starpliktuvē</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Nokopēt video plūsmas &URL</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Nokopēt esošās video plūsmas URL starpliktuvē</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Ziedot</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Klipa maksimālā izšķirtspēja ir %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Atbilstošākie</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Jaunākie</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Apmeklētākie</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Jūs skatāties "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Tagad varat ielīmēt YouTube norādi citā programmā</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Tagad varat ielīmēt video plūsmas URL citā programmā</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Norāde būs derīga tikai ierobežotu laiku</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Tīkla kļūda: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 skatījumi</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Meklēt</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Laipni lūdzam <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Ierakstiet atslēgvārdu lai sāktu skatīties klipus</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Skatīties</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Iepriekšējie atslēgvārdi</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>%1 jaunā versija ir pieejama. Lūdzu, <a href='%2'>atjauniniet pret %3 versiju</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Jūsu ērtībai</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation>Uzstādījumi</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Tīkla kļūda: %1 ar %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+# This voodoo comes from the Arora project
+
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+
+TRANSLATIONS += \
+ it_IT.ts \
+ pt_BR.ts \
+ ru_RU.ts \
+ pl_PL.ts \
+ de_DE.ts \
+ ja_JP.ts \
+ cs_CZ.ts \
+ uk.ts \
+ he_IL.ts \
+ lat.ts \
+ hr_HR.ts \
+ es.ts \
+ gl.ts \
+ fr_FR.ts \
+ hu_HU.ts \
+ tr_TR.ts \
+ nb_NO.ts \
+ ro_RO.ts \
+ el_GR.ts \
+ nl_NL.ts \
+ ar.ts \
+ pt_PT.ts \
+ fi_FI.ts \
+ bg_BG.ts
+
+isEmpty(QMAKE_LRELEASE) {
+ win32:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]\lrelease.exe
+ else:QMAKE_LRELEASE = $$[QT_INSTALL_BINS]/lrelease
+}
+
+updateqm.input = TRANSLATIONS
+updateqm.output = build/target/locale/${QMAKE_FILE_BASE}.qm
+updateqm.commands = $$QMAKE_LRELEASE ${QMAKE_FILE_IN} -qm build/target/locale/${QMAKE_FILE_BASE}.qm
+updateqm.CONFIG += no_link target_predeps
+QMAKE_EXTRA_COMPILERS += updateqm
+
+#qmfiles.files = TRANSLATIONS
+#qmfiles.path = Content/Resources
+#QMAKE_BUNDLE_DATA += qmfiles
--- /dev/null
+#!/bin/bash
+#
+# This script was written to update all the .ts files in one go
+#
+# This script is donated to the public domain
+#
+# Flavio Tordini, 2009
+
+for I in `ls -1 *.ts`;
+do
+ echo Updating $I
+ lupdate-qt4 ../minitube.pro -ts $I
+done
+
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="nb_NO" sourcelanguage="en">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Det finnes et liv utenfor nettleseren!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versjon %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Dette er en betarelease, ikke forvent at den er perfekt.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Rapporter bugs og send inn dine ideer til %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 er Fri Programvare men utviklingen tar verdifull tid.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete"><a href='%1'>doner via PayPal</a> for å gjøre fortsatt utvikling av %2 mulig.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Ikon er designet av %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Kompakt-Visning er utviklet av %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP proxy support utviklet av %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Windows versjon bygget av %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Oversatt av %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Sluppet under <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Steng</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Om</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Hva du alltid har villet visst om %1 men aldri torde å spørre om</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Vennligst <a href='%1'>doner</a> for og støtte vidre utvikling av %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Nullstill</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Søker...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Vis %1 flere</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Ingen videoer</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Ingen flere videoer</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Feil</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Tilbake</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Gå tilbake til forrige visning</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Stopp</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Stopp avspilling og gå tilbake til dine søk</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Hopp over</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Hopp over neste video</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pause</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Sett avspilling på pause</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Fullskjerm</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Fullskjermsvisning</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Kompakt-Visning</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Gjem spillelista og verktøylinja</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Åpne filmen på youtube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Fjern</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Fjern valgte videoer fra spillelista</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Flytt &opp</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Flytt opp valgte videoer i spillelista</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Flytt &Ned</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Flytt ned valgte videoer i spillelista</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Avslutt</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Ha en fin dag</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Nettsted</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 på internett</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Doner via PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Bidra til fortsatt utvikling av %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Om</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Informasjon om %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Søk</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Mute</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Spilleliste</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Hjelp</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Trykk på %1 for å stille opp volum, %2 for å skru ned</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Åpner %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Kritisk feil: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Feil: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Spill av</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Gjenoppta avspilling</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Avslutt &Fullskjerm</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Gjenstående tid: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volum %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Mute er på</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Mute er av</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">High Definition video er aktivert</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">High Definition video er ikke aktivert</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Denne videoen er i High Definition</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Denne videoen er ikke i High Definition</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Nullstill siste søkeord</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>Applikasjon</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Klarer søkehistorie. Kan ikke bli angert.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Ditt privatliv er nå sikkert</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Åpne &YouTube side</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Gå til YouTube video siden og pause avspillingen</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Kopier YouTube &link</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Kopier denne YouTube video linken til utklippstavle</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Kopier video stream &URL</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Kopier denne video stream URL til utklippstavle</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Gjør en &donasjon</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Maksimum video definisjon innstilling til %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Mest relevant</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Nyeste</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Mest sett</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Du ser på "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Du kan nå lime inn YouTube linken i et annet program</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Du kan nå lime inn video stream URL i et annet applikasjon</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Denne linken vil kun være gyldig i en begrenset tid.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Feil på nettverk: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 visninger</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Søk</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Velommen til <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Skriv inn et søkeord for å se på videoer.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Se Film</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Aktuelle søkeord</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>En ny versjon av %1 er tilgjengelig. Vennligst <a href='%2'>oppdater til versjon %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Finn deg til rette</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Innstillinger</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Feil på nettverk: %1 for %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="nl_NL">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Er is leven buiten de browser!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versie %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 is Gratis Software maar de ontwikkeling is kostbare tijd.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation><a href='%1'>Doneer</a> om bij te dragen aan de ontwikkeling van %2.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Raporteer fouten en stuur je ideën naar %1</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Icon ontworpen door %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Compact mode aangedragen door %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP proxy ondersteuning aangedragen door %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Vertaald door %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Uitgebracht onder de <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Sluiten</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Over</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Wat u altijd al had willen weten over %1 maar nooit heeft durven vragen</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Wis</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Bezig met Zoeken...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Laat %1 meer zien</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Geen video's</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Geen video's meer</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Fout</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Stop</source>
+ <translation>&Stop</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Stop het afspelen en ga terug naar het zoek overzicht</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Overslaan</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Overslaan en naar de volgende video</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pauzeer</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pauzeer afspelen</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Volledig scherm</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Ga naar volledig scherm</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Compacte modus</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Verberg de overzichtslijst en de werkbalk</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Open de &YouTube pagina</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Ga naar de YouTube video pagina en pauzeer het afspelen</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Kopieer de YouTube &link</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Kopieer de huidige YouTube link naar het klembord</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Kopieer de video stream &URL</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Kopieer de huidige video stream URL naar het klembord</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Verwijder</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Verwijder de geselecteerde video's van de afspeellijst</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Verplaats &Omhoog</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Verplaats de geselecteerde video's in de afspeellijst naar boven</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Verplaats &Omlaag</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Verplaats de geselecteerde video's in de afspeelijst naar beneden</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Wis de recente zoekopdrachten</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Wis de zoek geschiedenis. Dit kan niet ongedaan worden gemaakt.</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Afsluiten</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Tot ziens</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Website</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 op het internet</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Maak een &donatie</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Ondersteun de ontwikkeling van %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Over</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Informatie over %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Zoek</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Geen volume</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Applicatie</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Afspeellijst</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Help</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Druk op %1 voor meer volume en op %2 voor minder</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Openen van %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Fatale fout: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Fout: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Afspelen</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Afspelen hervatten</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Sluit &Volledig Scherm</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Overige tijd: %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volume op %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Volume is uit</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Volume is aan</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Maximale video defititie staat op %1</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Uw privacy is nu veilig</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Meest relevant</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Meest recent</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Meest bekeken</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>U kunt nu uw YouTube link kopieeren naar een andere applicatie</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>U kunt nu uw video stream URL kopieeren naar een andere applicatie</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>De link zal maar een beperkte tijd geldig zijn.</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>U kijkt naar "%1"</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Netwerk fout %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 bekeken</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Zoek</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Welkom bij <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Vul een zoekterm in om te beginnen met het bekijken van video's.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Bekijk</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Recente zoekopdrachten</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Een nieuwere versie van %1 is beschikbaar.<a href='%2'>Update naar versie %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Ga er lekker voor zitten</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Netwerk fout %1 voor %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="pl_PL">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Istnieje życie poza przeglądarką internetową!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Wersja %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">To jest wydanie "Technology Preview" więc nie spodziewaj się, że będzie idealne.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Raporty o błędach oraz pomysłach ślij na adres %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 to darmowe oprogramowanie ale jego tworzenie zabiera cenny czas.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Proszę <a href='%1'>wspomóż finansowo przez PayPal</a> prace nad programem %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Ikony stworzone przez %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Tryb kompaktowy dzięĸi %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Udział w tłumaczeniu mają: %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Program wydany na licencji <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Zamknij</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>O programie</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>To co zawsze chciałeś wiedzieć o %1 ale bałeś się zapytać</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Wsparcie dla HTTP proxy dzięki wkładowi %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">%1 - kompilacja dla Windows</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Proszę <a href='%1'>wspomóż</a> prace nad programem %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Wyczyść</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Szukanie...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Pokaż następne %1</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Brak plików wideo</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Nie ma więcej filmów</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Błąd</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">Powrót</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Wróć do poprzedniego filmu</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Zatrzymaj odtwarzanie i wróć do wyszukiwania</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>Następny</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Pomiń i włącz następny film</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pauza</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Wstrzymaj odtwarzanie</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>Pełny &Ekran</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Włącz widok pełnoekranowy</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Tryb kompaktowy</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Ukryj listę odtwarzania i pasek narzędziowy</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Otwórz film YouTube w przeglądarce</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>Usuń</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Usuń zaznaczone filmy z listy odtwarzania</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Przes&uń w górę</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Przesuń do góry zaznaczone filmy na liście odtwarzania</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Przesuń w &dół</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Przesuń na dół zaznaczone filmy na liście odtwarzania</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>Wyjdź</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Na razie</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Strona domo&wa</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>Strona domowa %1</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Dotacja dla twórcy przez PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Proszę, wspomóż finansowo prace nad %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>O progr&amie</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Info o %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">Szukaj</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>Progr&am</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>Lista odtwarzania</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>Film</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>Pomoc</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Otwieranie %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Fatalny błąd: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Błąd: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Odtwarzaj</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Wznów odtwarzanie</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Wyłącz &pełny ekran</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Głośność %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Dźwięk jest wyłączony</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Dźwięk jest włączony</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Szukaj</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Wyłącz dźwięk</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Wciśnij %1 aby zwiększyć głośność, %2 żeby ściszyć</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Pozostały czas: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">High Definition jest włączone</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">High Definition jest wyłączone</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Bieżący film jest dostępny w High Definition</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Bieżący film nie jest dostępny w High Definition</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Usuń ostatnie szukane słowa</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Usuń historię wyszukiwania. Operacja nie może zostać cofnięta.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Twoja prywatność jest teraz zapewniona</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Otwórz stronę &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Idź do strony YouTube i wstrzymaj odtwarzanie</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Kopiuj &link YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Kopiuj bieżący link YouTube do schowka</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Kopiuj &URL strumienia wideo</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Kopiuj URL bieżącego strumienia wideo do schowka</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Wspomóż finansowo</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Aktualne ustawienie jakości wideo to %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Najbardziej trafne</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Najnowsze</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Najpopularniejsze</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Oglądasz "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Teraz możesz wkleić link YouTube do innego programu</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Teraz możesz wkleić URL strumienia wideo do innego programu</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Link będzie ważny tylko przez określony czas.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Błąd sieci: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 wyświetleń</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Szukaj</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Witaj w <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Wpisz szukane słowo i zacznij oglądać filmy.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Wyświetl</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Ostatnio szukane</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Nowa wersja %1 jest dostępna. Proszę <a href='%2'> zaktualizuj do wersji %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Usiądź wygodnie</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Opcje</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">Opcje &obrazu</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Użyj wysokiej jakości wideo jeśli jest to możliwe</translation>
+ </message>
+ <message>
+ <source>&Saved recent keywords</source>
+ <translation type="obsolete">&Zapisz ostatnie słowa szukane</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="obsolete">&Usuń ostatnie słowa szukane</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Zamknij</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Błąd sieci: %1 dla %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="pt_BR">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Não há vida fora do navegador!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versão %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Este é um lançamento "Prévio da Tecnologia", não esperamos que ela seja perfeita.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Relate as falhas e envie suas ideias para %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 é um Software livre, mas o seu desenvolvimento tem um tempo precioso.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Por favor, <a href='%1'>doções via PayPal</a> para apoiar o desenvolvimento contínuo de %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Ícone desenhado por %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Traduzido por %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Lançado sob a <a href='%1'>Licença Pública Geral GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Fechar</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Sobre</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>O que você sempre quis saber sobre %1 e nunca se atreveu a perguntar</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Modo compacto contribuído por %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Suporte a HTTP proxy contribuído por %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Vesão da janela construída por %1</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Por favor <a href='%1'>doe</a> para apoiar o desenvolvimento contínuo de %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Limpar</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Pesquisando...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mostrar %1 a mais</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Não há vídeos</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Não há mais vídeos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Voltar</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Alt+Left</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Ir para a visualização anterior</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Parar</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Parar a reprodução e voltar à visualização da pesquisa</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Esc</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>Pu&lar</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Pular para o próximo vídeo</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Ctrl+Right</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pausar</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pausar a reprodução</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Barra de espaço</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Tela Cheia</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Ir para a tela cheia</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Alt+Enter</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Abrir a página de vídeo do YouTube</translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="obsolete">Ctrl+Y</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Remover</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Remover os vídeos selecionados da playlist</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Mover para &cima</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Mover para cima os vídeos selecionados na playlist</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Ctrl+Up</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Mover para &baixo</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Mover para baixo os vídeos selecionados na playlist</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Ctrl+Down</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Sair</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Tchau</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Si&te</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube na Web</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 na Web</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Doações via PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Por favor, apoie o desenvolvimento contínuo de %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Sobre</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Informações sobre %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Pesquisar</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Aplicação</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Playlist</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Vídeo</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Ajuda</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Abrindo %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Reproduzir</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Continuar reprodução</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Sair de &Tela Cheia</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Modo &compacto</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Ocultar a playlist e a barra de ferramentas</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Erro fatal: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Erro: %1</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volume a %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Volume está mudo</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Volume não está mudo</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Pesquisar</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Volume mudo</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Pressione %1 para aumentar o volume, %2 para diminui-lo</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Tempo restante: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Vídeo de Alta Definição está habilitado</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Vídeo de Alta Definição não está habilitado</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">O vídeo atual está em Alta Definição</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">O vídeo atual nõ está em Alta Definição</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Apagar palavras-chave recentes</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Apagar o histórico de pesquisa. Não pode ser desfeito.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Sua privacidade está agora segura</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Abrir a página do &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Ir à página de vídeo do YouTube e pausar a reprodução</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Copiar o &link do YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Copiar o link do vídeo atual do YouTube para a área de transferência</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Copiar a &URL do stream do vídeo</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Copiar a URL do stream do vídeo atual para a área de transferência</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Faça uma &doação</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Máxima definição de vídeo definida para %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Mais relevantes</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Mais recentes</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Mais vistos</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Você está assistindo "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Agora você pode colar o link do YouTube em outro programa</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Agora você pode colar a URL do stream de vídeo em outro programa</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>O link só será válido por um tempo limitado.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Erro na rede: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 exibições</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Pesquisar</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Bem-vindo ao <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Digite uma palavra-chave para começar a assistir os vídeos.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Assistir</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Palavra-chave recente</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Um nova versão de %1 está disponível. Por favor, <a href='%2'>atualize para a versão %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Sinta-se confortável</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Preferências</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">Opções de &vídeo</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Utilizar vídeo de alta qualidade quando estiver disponível</translation>
+ </message>
+ <message>
+ <source>&Saved recent keywords</source>
+ <translation type="obsolete">Palavras-chave &salvas recentemente</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="obsolete">Palavras-chave &limpas recentemente</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Fechar</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Erro na rede: %1 para %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="pt_PT">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Existe vida para além do navegador!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versão %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 é Software Livre mas o seu desenvolvimento leva tempo precioso.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Por favor <a href='%1'>Faça um donativo</a> para suportar o desenvolvimento continuado do%2.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Reporte erros e envie as suas ideias para%1</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Icon criado por %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Modo compacto contribuído por%1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Suporte a proxy HTTP contribuído por%1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Traduzido por %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Lançado nos termos da <a href='"%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Fechar</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Sobre</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Tudo o que sempre quis saber sobre o %1 e nunca se atreveu a perguntar</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Limpar</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>A pesquisar...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Mostrar mais %1</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Sem vídeos</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Sem mais vídeos</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Erro</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Stop</source>
+ <translation>&Parar</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Para a reprodução e voltar à vista de pesquisa</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>S&altar</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Saltar para o próximo vídeo</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pausar</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pausar reprodução</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>Ecrã &Completo</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Ir para ecrã completo</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Modo &Compacto</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Esconder a lista de reprodução e a barra de ferramentas</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Abrir a página do &Youtube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Ir para a página do Youtube do vídeo e parar a reprodução</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Copiar o &link do Youtube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Copiar o link do Youtube do vídeo actual para a área de transferência</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Copiar o &URL da emissão de vídeo</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Copiar o URL da emissão de vídeo actual para a área de transferência</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Remover</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Remover os vídeos seleccionados da lista de reprodução</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Mover para &Cima</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Mover para cima os vídeos seleccionados na lista de reprodução</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Mover para &Baixo</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Mover para baixo os vídeos seleccionados na lista de reprodução</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Limpar pesquisas recentes</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Limpar o histório de pesquisa. Não pode ser desfeito.</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Sair</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Adeus</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Sítio &Web</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 na Internet</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Fazer uma &doação</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Por favor suporte o desenvolvimento continuado do %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Sobre</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Informação sobre %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Pesquisar</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Silenciar o volume</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Aplicação</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Lista de reprodução</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Vídeo</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Ajuda</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Prima %1 para aumentar o volume, %2 para reduzi-lo</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>A abrir %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Erro fatal:%1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Erro:%1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Reproduzir</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Retomar a reprodução</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Sair do Ecrã &Completo</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Tempo restante:%1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volume a :%1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>O volume está silenciado</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>O volume não está silenciado</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Definição de vídeo máxima estabelecida em %1</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>A sua privacidade está agora assegurada</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Mais relevantes</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Mais recentes</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Mais vistos</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Pode agora colar o link do Youtube noutra aplicação</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Pode agora colar o URL da emissão de vídeo noutra aplicação</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>O link será válido apenas por algum tempo.</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Está a assistir a "%1"</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Erro de rede: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 visualizações</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Pesquisar</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Bem-vindo ao <a href='%1'>%2</a></translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Insira uma pesquisa para começar a assitir a vídeos.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Assistir</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Pesquisas recentes</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Uma nova versão do %1 está disponível. Por favor <a href='%2'>actualize para a versão %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Acomode-se confortavelmente</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Erro de rede: %1 para %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ro_RO">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Există viaţă dincolo de browser!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Versiunea %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Această versiune este doar pentru o "impresie tehnlogică", nu te aştepta să funcţioneze perfect.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Raportează erori şi trimite ideile tale la %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 este un program gratuit, dar dezvoltarea acestuia necesită timp preţios.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Te gog <a href='%1'>donează o sumă modestă</a> pentru a ajuta dezvoltarea %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Iconul a fost conceput de %1.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Modul compact a fost dezvoltat de %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Suportul pentru proxy-uri HTTP a fost dezvoltat de %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Version Windows faite par %1</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Tradus de %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Oferit sub <a href='%1'>Licenţa Publică Generală GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>În&chide</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Despre</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Tot ce ai vrut să ştii despre %1 dar n-ai vrut să îndrăzneşti a întreba</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Vă rugăm să <a href='%1'>donaţi</a> pentru a ajuta la continuarea dezvoltării %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Şterge</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Căutare...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Afişează încă %1</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Nu sunt videoclipuri</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Nu mai sunt videoclipuri</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Eroare</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">Îna&poi</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Întoarcere</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Stop</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Opreşte redarea şi întoarce-te la căsuţa de căutare</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>O&mite</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Treci la videoclipul următor</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Pauză</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Pune redarea pe pauză</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>Ec&ran complet</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Schimbă modul de vizualizare pe tot ecranul</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>Mod &compact</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Ascunde lista de redare şi bara de unelte</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&Youtube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Deschide pagina YouTube</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>Ş&terge</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Şterge clipul selectat din lista de redare</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Mută în &sus</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Mută în sus videoclipul selectat</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Mută în &jos</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Mută în jos videoclipul selectat</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Ieşire</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>La revedere</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Site &Web</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 pe Web</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Donează prin PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Te rog să susţii dezvoltarea aplicaţiei %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Despre</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Informaţii despre %1</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Căutare</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Oprire sunet</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Listă de redare</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Ajutor</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Apasă pe %1 pentru a da volumul mai tare sau pe %2 pentru a-l da mai încet</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Deschidere %1</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Eroare fatală : %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Eroare: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Redare</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Rezumă redarea videoclipului</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Părăseşte modul "Ec&ran complet"</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Timp rămas : %1</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Volum %1</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Sunetul este oprit</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Sunetul este pornit</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Modul Înaltă Definiţie este activ</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Modul Înaltă Definiţie nu este activ</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Videoclipul curent este în format Înaltă Definiţie</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Videoclipul curent nu este în format Înaltă Definiţie</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>Şterge &căutările recente</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Aplicaţie</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Curăţă istoricul de căutări. Această acţiune nu poate fi anulată.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Intimitatea dumneavoastră este acum în siguranţă</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Deschide pagina &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Deschide pagina de pe YouTube si pune pauză</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Copiază &link-ul de YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Copiază link-ul videoclipului curent în clipboard</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Copiază adresa streamul&ui</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Copiază adresa stream-ului în clipboard</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>&Donează</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Rezoluţia maxima a videoclipului este setată la %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Cele mai relevante</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Cele mai recente</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Cele mai vizualizate</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Te uiţi la %1</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Acum poţi lipi link-ul într-o altă aplicaţie</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Acum poţi lipi link-ul stream-ului într-o altă aplicaţie</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Link-ul va fi valid doar pentru o perioadă limitată de timp.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Eroare de reţea : %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 vizualizări</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Căutare</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Bine aţi venit la <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Efectuaţi o căutare pentru a începe să vizionaţi videoclipuri.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Urmăreşte</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Căutări recente</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Este disponibilă o nouă versiune a %1. Te rog <a href='%2'>să actualizezi</a> aplicaţia la versiunea %3</translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Faceţi-vă confortabil</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Preferinţe</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Eroare reţea: %1 pentru %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="ru_RU">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Жизнь за пределами браузера!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Версия %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Эта предварительная версия, не стоит ожидать совершенства.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Отзывы и сообщения об ошибках следует отправлять на %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 - свободное ПО, но его разработка отнимает драгоценное время.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete"><a href='%1'>Поддержите через PayPal</a> дальнейшую разработку %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Автор значка %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Перевод выполнили: %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Выпущено на условиях <a href='%1'>GNU General Public License</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Закрыть</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>О программе</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Все что Вы всегда хотели узнать о %1 и никогда бы не спросили</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Облегчённый режим предоставлен %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Поддержка HTTP-прокси предоставлена %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Сборку под Windows выполнил %1</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation><a href='%1'>Поддержите</a> дальнейшую разработку %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Очистить</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Поиск...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Показать больше %1</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Клипы не найдены</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Больше нет клипов</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Ошибка</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Назад</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Alt+стрелка назад</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Перейти к предыдущему</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Остановить</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Остановить воспроизведение и вернуться к поиску</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Esc</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>П&ропустить</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Перейти к следующему клипу</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Ctrl+стрелка вправо</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Приостановить</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Приостановить воспроизведение</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Пробел</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&На весь экран</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Полноэкранное воспроизведение</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Alt+Enter</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Открыть страницу видео в YouTube</translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="obsolete">Ctrl+Y</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Удалить</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Удалить выбранные клипы из списка воспроизведения</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>В&верх</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Переместить выбранные видеоклипы вверх в списке воспроизведения</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Ctrl+стрелка вверх</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>В&низ</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Переместить выбранные видеоклипы вниз в списке воспроизведения</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Ctrl+стрелка вниз</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Выход</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Пока</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Домашняя страница</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube в интернете</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 в интернете</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">&Поддержать через PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Поддержите дальнейшую разработку %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&О программе</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Сведения о %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Поиск</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>Пр&иложение</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>&Список воспроизведения</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Клипы</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>Спр&авка</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Открытие %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>Пр&оиграть</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Продолжить воспроизведение</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>В&ыйти из полноэкранного воспроизведения</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Облегчённый режим</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Скрыть список воспроизведения и панель инструментов</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Фатальная ошибка: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Ошибка: %1</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Громкость %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Звук выключен</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Звук включен</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Поиск</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Выключить звук</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>Нажмите %1 для увеличения громкости и %2 для снижения</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Времени осталось: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Показ видео в высоком разрешении включен</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Показ видео в высоком разрешении выключен</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Видео воспроизводится в высоком разрешении</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Видео воспроизводится не в высоком разрешении</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>&Очистить последние запросы</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Очистить журнал запросов. Изменения необратимы.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Конфиденциальность обеспечена</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>Открыть страницу &YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Приостановить воспроизведение и перейти на страницу видео в YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Копировать &ссылку YouTube</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Скопировать ссылку текущего клипа YouTube в буфер обмена</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Копировать &адрес видео потока</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Скопировать адрес текущего видео потока в буфер обмена</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Сделать &пожертвование</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Максимальное разрешение видео: %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Похожие видео</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Недавно просмотренные</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Самые популярные</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Сейчас просматривается "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Теперь можно вставить адрес YouTube в другое приложение</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Теперь можно вставить адрес видео потока в другое приложение</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Адрес будет существовать ограниченное время.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Ошибка сети: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 просмотров</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Поиск</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Добро пожаловать в <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Введите ключевые слова для начала просмотра видео.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Смотреть</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Последние запросы</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Доступна новая версия %1. <a href='%2'>Обновите до %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Чувствуйте себя как дома</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Настройки</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">&Параметры видео</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Использовать по возможности видео высокого качества</translation>
+ </message>
+ <message>
+ <source>&Saved recent keywords</source>
+ <translation type="obsolete">&Сохранённые последние запросы</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="obsolete">&Очистить последние запросы</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">&Закрыть</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Ошибка сети: %1 на %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="tr_TR" sourcelanguage="en_US">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>Tarayıcının dışındaki yaşam!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Version %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Bu "Teknoloji gösterimi" sürümüdür, mükemmel olmasını beklemeyin.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Hataları ve yeni fikirlerinizi %1 adresine gönderin</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 özgür yazılımdır ama geliştirmek değerli zaman alır.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Lütfen %2 gelişiminin sürekliliği için <a href='%1'>PayPal ile bağış</a> yaparak destek olun.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Simge %1 tarafından tasarlandı.</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Pencereye sığdırmada %1'ün katkısı var.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>HTTP Vekil desteğinde %1'nin katkısı var.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Windows sürümü %1 tarafından yapıldı.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Çevirenler %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation><a href='%1'>GNU Genel Kamu Lisansı</a> ile yayınlanmıştır</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>&Kapat</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Hakkında</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Lütfen %2 geliştirilmesinin devam etmesi için <a href='%1'>bağış</a> yapın.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Temizle</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Aranıyor...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>%1 Tane daha</translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Video yok</translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Daha fazla yok</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Hata</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Geri</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Öncekine git</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Dur</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Oynatmayı durdur ve aramaya geri dön</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>&Atla</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Sonraki videoya atla</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Bekle</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Oynatmayı beklet</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>&Tam ekran</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Tam ekran görünümü</translation>
+ </message>
+ <message>
+ <source>&Compact View</source>
+ <translation type="obsolete">&Kompakt Ansicht</translation>
+ </message>
+ <message>
+ <source>Go compact view</source>
+ <translation type="obsolete">Kompakt Ansicht aktivieren</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">YouTube video sayfasını aç</translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="obsolete">Ctrl+Y</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Pencereye sığdır</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Listeyi ve araç çubuğunu gizle</translation>
+ </message>
+ <message>
+ <source>&Download</source>
+ <translation type="obsolete">&Herunterladen</translation>
+ </message>
+ <message>
+ <source>Download this video</source>
+ <translation type="obsolete">Dieses Video herunterladen</translation>
+ </message>
+ <message>
+ <source>Ctrl+S</source>
+ <translation type="obsolete">Strg+S</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Kaldır</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Seçilen videoları listeden kaldır</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Y&ukarı taşı</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Seçilen videoları listede yukarı taşı</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>A&şağı taşı</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Seçilen videoları listede aşağı taşı</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>&Çık</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Ç</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Gülegüle</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>&Website</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 İnternette</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">PayPal ile ba&ğış yap</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Lütfen %1 gelişiminin sürekliliği için destekleyin</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Hakkında</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>%1 Hakkında</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Ara</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Sesi kes</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>%1 Sesi arttır, %2 sesi azalt</translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Kalan zaman: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Yüksek çözünürlüklü video aktif</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Yüksek çözünürlüklü video aktif değil</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Geçerli video yüksek çözünürlüklü</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">Geçerli video yüksek çözünürlüklü değil</translation>
+ </message>
+ <message>
+ <source>No Video playing</source>
+ <translation type="obsolete">Es wird kein Video abgespielt</translation>
+ </message>
+ <message>
+ <source>You must first play the video you intent to download !</source>
+ <translation type="obsolete">Du musst das Video erst abspielen !</translation>
+ </message>
+ <message>
+ <source>Save video as...</source>
+ <translation type="obsolete">Video speichern unter...</translation>
+ </message>
+ <message>
+ <source>minitube video.mp4</source>
+ <translation type="obsolete">minitube video.mp4</translation>
+ </message>
+ <message>
+ <source>Downloading: </source>
+ <translation type="obsolete">Herunterladen:</translation>
+ </message>
+ <message>
+ <source>Abort Download</source>
+ <translation type="obsolete">Herunterladen abbrechen</translation>
+ </message>
+ <message>
+ <source>File creation failed</source>
+ <translation type="obsolete">Das anlegen der Datei ist fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>Download failed</source>
+ <translation type="obsolete">Herunterladen fehlgeschlagen</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Ses %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Ses kapandı</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Ses açık</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">&Suche</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Uygulama</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>Oynatma &listesi</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>&Video</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>Yardı&m</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>%1 Açılıyor</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>İç hata: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Hata: %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>&Oynat</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Oynatmaya devam et</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>&Tam ekrandan çık</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>Geçmiş aramaları &sil</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Arama geçmişini sil. Bu geri alınamaz.</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Şimdi gizliliğiniz güvende</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>&YouTube sayfasını aç</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Oynatmayı beklet ve YouTube sayfasına git</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>YouTube bağlantısını &kopyala</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Geçerli videonun YouTube bağlantısını panoya kopyala</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Video akışı &URL adresini kopyala</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Geçerli video akışının URL adresini panoya kopyala</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>&Bağış yap</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>En yüksek video tanımı %1 olarak ayarlı</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>En ilgili</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>En yeni</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Çok izlenen</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>"%1" İzliyorsunuz</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Şimdi YouTube bağlantısını başka bir uygulamaya yapıştırabilirsiniz</translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Şimdi video akışı URL adresini başka bir uygulamaya yapıştırabilirsiniz</translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Bağlantı kısıtlı bir süre için geçerli olacak.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Ağ hatası: %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>%1 görüntüleme</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Ara</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation><a href='%1'>%2</a>'a Hoşgeldiniz</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Bir anahtar kelime girerek izlemeye başlayın.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>İzle</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Son arananlar</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>%1'un yeni sürümü mevcut. Lütfen buradan <a href='%2'> %3 sürümüne yükseltin</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Kendinize konfor sunun</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Seçenekler</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">S&chließen</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Ağ hatası: %2 için %1</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.0" language="uk_UA">
+<defaultcodec>UTF-8</defaultcodec>
+<context>
+ <name>AboutView</name>
+ <message>
+ <source>There's life outside the browser!</source>
+ <translation>За межами браузера також є життя!</translation>
+ </message>
+ <message>
+ <source>Version %1</source>
+ <translation>Версія %1</translation>
+ </message>
+ <message>
+ <source>This is a "Technology Preview" release, do not expect it to be perfect.</source>
+ <translation type="obsolete">Це технологічний попередній випуск програми, не очікуйте від нього досконалості.</translation>
+ </message>
+ <message>
+ <source>Report bugs and send in your ideas to %1</source>
+ <translation>Повідомляйте про несправності та висилайте ваші ідеї на %1</translation>
+ </message>
+ <message>
+ <source>%1 is Free Software but its development takes precious time.</source>
+ <translation>%1 є Вільним Програмним Забезпеченням але на його розробку було затрачено коштовний час.</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate via PayPal</a> to support the continued development of %2.</source>
+ <translation type="obsolete">Будь ласка <a href='%1'>скористайтесь PayPal</a> щоб підтримати подальший розвиток %2.</translation>
+ </message>
+ <message>
+ <source>Icon designed by %1.</source>
+ <translation>Розробник піктограм %1.</translation>
+ </message>
+ <message>
+ <source>Translated by %1</source>
+ <translation>Переклад %1</translation>
+ </message>
+ <message>
+ <source>Released under the <a href='%1'>GNU General Public License</a></source>
+ <translation>Випущено під <a href='%1'>Загальною громадською ліцензією GNU</a></translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation>Пове&рнутися</translation>
+ </message>
+ <message>
+ <source>About</source>
+ <translation>Про програму</translation>
+ </message>
+ <message>
+ <source>What you always wanted to know about %1 and never dared to ask</source>
+ <translation>Все що ви завжди хотіли знати про %1 але не наважувались запитати</translation>
+ </message>
+ <message>
+ <source>Compact mode contributed by %1.</source>
+ <translation>Розробка компактного режиму %1.</translation>
+ </message>
+ <message>
+ <source>HTTP proxy support contributed by %1.</source>
+ <translation>Реалізація підтримки HTTP проксі %1.</translation>
+ </message>
+ <message>
+ <source>Windows version built by %1</source>
+ <translation type="obsolete">Версія для Windows %1</translation>
+ </message>
+ <message>
+ <source>Please <a href='%1'>donate</a> to support the continued development of %2.</source>
+ <translation>Будь ласка <a href='%1'>внесіть пожертву</a> щоб підтримати подальший розвиток %2.</translation>
+ </message>
+</context>
+<context>
+ <name>ClearButton</name>
+ <message>
+ <source>Clear</source>
+ <translation>Очистити</translation>
+ </message>
+</context>
+<context>
+ <name>ListModel</name>
+ <message>
+ <source>Searching...</source>
+ <translation>Шукаю...</translation>
+ </message>
+ <message>
+ <source>Show %1 More</source>
+ <translation>Наступні %1 </translation>
+ </message>
+ <message>
+ <source>No videos</source>
+ <translation>Нічого не знайдено </translation>
+ </message>
+ <message>
+ <source>No more videos</source>
+ <translation>Більше немає</translation>
+ </message>
+</context>
+<context>
+ <name>LoadingWidget</name>
+ <message>
+ <source>Error</source>
+ <translation>Помилка</translation>
+ </message>
+</context>
+<context>
+ <name>MainWindow</name>
+ <message>
+ <source>&Back</source>
+ <translation type="obsolete">&Назад</translation>
+ </message>
+ <message>
+ <source>Alt+Left</source>
+ <translation type="obsolete">Alt+Вліво</translation>
+ </message>
+ <message>
+ <source>Go to the previous view</source>
+ <translation type="obsolete">Повернутися до попереднього режиму</translation>
+ </message>
+ <message>
+ <source>&Stop</source>
+ <translation>&Зупинити</translation>
+ </message>
+ <message>
+ <source>Stop playback and go back to the search view</source>
+ <translation>Зупинити відтворення і перейти до вікна пошуку</translation>
+ </message>
+ <message>
+ <source>Esc</source>
+ <translation type="obsolete">Esc</translation>
+ </message>
+ <message>
+ <source>S&kip</source>
+ <translation>П&ропустити</translation>
+ </message>
+ <message>
+ <source>Skip to the next video</source>
+ <translation>Перейти до наступного відео</translation>
+ </message>
+ <message>
+ <source>Ctrl+Right</source>
+ <translation type="obsolete">Ctrl+Вправо</translation>
+ </message>
+ <message>
+ <source>&Pause</source>
+ <translation>&Призупинити</translation>
+ </message>
+ <message>
+ <source>Pause playback</source>
+ <translation>Призупинити відтворення</translation>
+ </message>
+ <message>
+ <source>Space</source>
+ <translation type="obsolete">Клавіша пробілу</translation>
+ </message>
+ <message>
+ <source>&Full Screen</source>
+ <translation>Н&а весь экран</translation>
+ </message>
+ <message>
+ <source>Go full screen</source>
+ <translation>Перехід в повноекранний режим</translation>
+ </message>
+ <message>
+ <source>Alt+Return</source>
+ <translation type="obsolete">Alt+Enter</translation>
+ </message>
+ <message>
+ <source>&YouTube</source>
+ <translation type="obsolete">&YouTube</translation>
+ </message>
+ <message>
+ <source>Open the YouTube video page</source>
+ <translation type="obsolete">Відкрити сторінку YouTube</translation>
+ </message>
+ <message>
+ <source>Ctrl+Y</source>
+ <translation type="obsolete">Ctrl+Y</translation>
+ </message>
+ <message>
+ <source>&Remove</source>
+ <translation>&Видалити</translation>
+ </message>
+ <message>
+ <source>Remove the selected videos from the playlist</source>
+ <translation>Видалити обрані відео з переліку композицій</translation>
+ </message>
+ <message>
+ <source>Move &Up</source>
+ <translation>Зсув в&гору</translation>
+ </message>
+ <message>
+ <source>Move up the selected videos in the playlist</source>
+ <translation>Зсунути обране відео на позицію вгору в переліку композицій</translation>
+ </message>
+ <message>
+ <source>Ctrl+Up</source>
+ <translation type="obsolete">Ctrl+Вгору</translation>
+ </message>
+ <message>
+ <source>Move &Down</source>
+ <translation>Зсув вни&з</translation>
+ </message>
+ <message>
+ <source>Move down the selected videos in the playlist</source>
+ <translation>Зсунути обране відео на позицію вниз в переліку композицій</translation>
+ </message>
+ <message>
+ <source>Ctrl+Down</source>
+ <translation type="obsolete">Ctrl+Вниз</translation>
+ </message>
+ <message>
+ <source>&Quit</source>
+ <translation>Ви&хід</translation>
+ </message>
+ <message>
+ <source>Ctrl+Q</source>
+ <translation>Ctrl+Q</translation>
+ </message>
+ <message>
+ <source>Bye</source>
+ <translation>Хай щастить</translation>
+ </message>
+ <message>
+ <source>&Website</source>
+ <translation>Домашн&я сторінка програми</translation>
+ </message>
+ <message>
+ <source>Minitube on the Web</source>
+ <translation type="obsolete">Minitube в мережі</translation>
+ </message>
+ <message>
+ <source>%1 on the Web</source>
+ <translation>%1 в мережі</translation>
+ </message>
+ <message>
+ <source>&Donate via PayPal</source>
+ <translation type="obsolete">Підтрима&йте проект через PayPal</translation>
+ </message>
+ <message>
+ <source>Please support the continued development of %1</source>
+ <translation>Будь ласка підтримайте подальший розвиток %1</translation>
+ </message>
+ <message>
+ <source>&About</source>
+ <translation>&Про програму</translation>
+ </message>
+ <message>
+ <source>Info about %1</source>
+ <translation>Інформація про %1</translation>
+ </message>
+ <message>
+ <source>&Search</source>
+ <translation type="obsolete">Пош&ук</translation>
+ </message>
+ <message>
+ <source>&Application</source>
+ <translation>&Програма</translation>
+ </message>
+ <message>
+ <source>&Playlist</source>
+ <translation>Перелік &композицій</translation>
+ </message>
+ <message>
+ <source>&Video</source>
+ <translation>В&ідео</translation>
+ </message>
+ <message>
+ <source>&Help</source>
+ <translation>&Допомога</translation>
+ </message>
+ <message>
+ <source>Opening %1</source>
+ <translation>Відкриваю %1</translation>
+ </message>
+ <message>
+ <source>&Play</source>
+ <translation>Відтворюв&ати</translation>
+ </message>
+ <message>
+ <source>Resume playback</source>
+ <translation>Продовжити відтворення</translation>
+ </message>
+ <message>
+ <source>Exit &Full Screen</source>
+ <translation>Вийти з повноекр&анного режиму</translation>
+ </message>
+ <message>
+ <source>&Compact mode</source>
+ <translation>&Компактний режим</translation>
+ </message>
+ <message>
+ <source>Hide the playlist and the toolbar</source>
+ <translation>Приховати перелік композицій та панель інструментів</translation>
+ </message>
+ <message>
+ <source>Fatal error: %1</source>
+ <translation>Невиправна помилка: %1</translation>
+ </message>
+ <message>
+ <source>Error: %1</source>
+ <translation>Помилка: %1</translation>
+ </message>
+ <message>
+ <source>Ctrl+M</source>
+ <translation>Ctrl+M</translation>
+ </message>
+ <message>
+ <source>Volume at %1%</source>
+ <translation>Гучність %1%</translation>
+ </message>
+ <message>
+ <source>Volume is muted</source>
+ <translation>Гучність приглушено</translation>
+ </message>
+ <message>
+ <source>Volume is unmuted</source>
+ <translation>Гучність відновлено</translation>
+ </message>
+ <message>
+ <source>Search</source>
+ <translation>Пошук</translation>
+ </message>
+ <message>
+ <source>Mute volume</source>
+ <translation>Приглушити гучність </translation>
+ </message>
+ <message>
+ <source>Press %1 to raise the volume, %2 to lower it</source>
+ <translation>%1 щоб приглушити гучність, %2 щоб відновити </translation>
+ </message>
+ <message>
+ <source>Remaining time: %1</source>
+ <translation>Час до завершення: %1</translation>
+ </message>
+ <message>
+ <source>High Definition video is enabled</source>
+ <translation type="obsolete">Відео високої чіткості активоване</translation>
+ </message>
+ <message>
+ <source>High Definition video is not enabled</source>
+ <translation type="obsolete">Відео високої чіткості не активоване</translation>
+ </message>
+ <message>
+ <source>The current video is in High Definition</source>
+ <translation type="obsolete">Відео в режимі високої чіткості</translation>
+ </message>
+ <message>
+ <source>The current video is not in High Definition</source>
+ <translation type="obsolete">ВІдео не в режимі високої чіткості</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation>Очистити недавн&і терміни пошуку</translation>
+ </message>
+ <message>
+ <source>Clear the search history. Cannot be undone.</source>
+ <translation>Очистити історію пошуку (зміни незвороні).</translation>
+ </message>
+ <message>
+ <source>Your privacy is now safe</source>
+ <translation>Ваша приватність застережена</translation>
+ </message>
+ <message>
+ <source>Open the &YouTube page</source>
+ <translation>&Відкрити сторінку YouTube</translation>
+ </message>
+ <message>
+ <source>Go to the YouTube video page and pause playback</source>
+ <translation>Відкрити сторінку YouTube і призупини відтворення відео</translation>
+ </message>
+ <message>
+ <source>Copy the YouTube &link</source>
+ <translation>Скопіювати YouTube &посилання в буфер</translation>
+ </message>
+ <message>
+ <source>Copy the current video YouTube link to the clipboard</source>
+ <translation>Скопіювати YouTube посилання поточного відео в буфер</translation>
+ </message>
+ <message>
+ <source>Copy the video stream &URL</source>
+ <translation>Скопіювати &посилання в буфер</translation>
+ </message>
+ <message>
+ <source>Copy the current video stream URL to the clipboard</source>
+ <translation>Скопіювати посилання поточного відео в буфер</translation>
+ </message>
+ <message>
+ <source>Make a &donation</source>
+ <translation>Підтрима&йте проект</translation>
+ </message>
+ <message>
+ <source>Maximum video definition set to %1</source>
+ <translation>Режим чіткості відео %1</translation>
+ </message>
+</context>
+<context>
+ <name>MediaView</name>
+ <message>
+ <source>Most relevant</source>
+ <translation>Подібні</translation>
+ </message>
+ <message>
+ <source>Most recent</source>
+ <translation>Недавні</translation>
+ </message>
+ <message>
+ <source>Most viewed</source>
+ <translation>Популярні</translation>
+ </message>
+ <message>
+ <source>You're watching "%1"</source>
+ <translation>Ви дивитесь "%1"</translation>
+ </message>
+ <message>
+ <source>You can now paste the YouTube link into another application</source>
+ <translation>Ви можете використовувати YouTube посилання на відео в завнішній програмі </translation>
+ </message>
+ <message>
+ <source>You can now paste the video stream URL into another application</source>
+ <translation>Ви можете використовувати посилання на відео в завнішній програмі </translation>
+ </message>
+ <message>
+ <source>The link will be valid only for a limited time.</source>
+ <translation>Посилання буде дійсне тільки протягом обмеженого часу.</translation>
+ </message>
+</context>
+<context>
+ <name>NetworkAccess</name>
+ <message>
+ <source>Network error: %1</source>
+ <translation>Помилка мережі %1</translation>
+ </message>
+</context>
+<context>
+ <name>PrettyItemDelegate</name>
+ <message>
+ <source>%1 views</source>
+ <translation>переглядів %1</translation>
+ </message>
+</context>
+<context>
+ <name>SearchLineEdit</name>
+ <message>
+ <source>Search</source>
+ <translation>Пошук</translation>
+ </message>
+</context>
+<context>
+ <name>SearchView</name>
+ <message>
+ <source>Welcome to <a href='%1'>%2</a>,</source>
+ <translation>Вітаємо в <a href='%1'>%2</a>,</translation>
+ </message>
+ <message>
+ <source>Enter a keyword to start watching videos.</source>
+ <translation>Введіть терміни для пошуку відео.</translation>
+ </message>
+ <message>
+ <source>Watch</source>
+ <translation>Перегляд</translation>
+ </message>
+ <message>
+ <source>Recent keywords</source>
+ <translation>Недавній пошук</translation>
+ </message>
+ <message>
+ <source>A new version of %1 is available. Please <a href='%2'>update to version %3</a></source>
+ <translation>Наявна нова версія %1. Будь ласка <a href='%2'> обновіть програму до версії %3</a></translation>
+ </message>
+ <message>
+ <source>Make yourself comfortable</source>
+ <translation>Влаштовуйтеся зручніше</translation>
+ </message>
+</context>
+<context>
+ <name>SettingsView</name>
+ <message>
+ <source>Preferences</source>
+ <translation type="obsolete">Налаштування</translation>
+ </message>
+ <message>
+ <source>&Video options</source>
+ <translation type="obsolete">Відео &можливості</translation>
+ </message>
+ <message>
+ <source>Use high quality video when available</source>
+ <translation type="obsolete">Відтворювати відео високої якості при наявності</translation>
+ </message>
+ <message>
+ <source>&Saved recent keywords</source>
+ <translation type="obsolete">&Збережені недавні терміни пошуку</translation>
+ </message>
+ <message>
+ <source>&Clear recent keywords</source>
+ <translation type="obsolete">Очистити недавн&і терміни пошуку</translation>
+ </message>
+ <message>
+ <source>&Close</source>
+ <translation type="obsolete">За&крити</translation>
+ </message>
+</context>
+<context>
+ <name>Video</name>
+ <message>
+ <source>Network error: %1 for %2</source>
+ <translation>Помилка мережі: %1 для %2</translation>
+ </message>
+</context>
+</TS>
--- /dev/null
+[Desktop Entry]
+Name=Minitube
+Name[en_US]=Minitube
+Comment=Watch YouTube videos
+Comment[es]=Vea los videos de YouTube
+Comment[gl]=Vexa os vídeos de YouTube
+Comment[it]=Guarda i video di YouTube
+GenericName=YouTube client
+GenericName[en_US]=YouTube client
+GenericName[es]=Cliente de YouTube
+GenericName[gl]=Cliente de YouTube
+GenericName[it]=Client per YouTube
+Exec=minitube
+Terminal=false
+Type=Application
+Icon=minitube
+Categories=Application;Qt;AudioVideo;Video;
+StartupNotify=true
--- /dev/null
+INCLUDEPATH += /usr/include/phonon
+CONFIG += release
+TEMPLATE = app
+
+# TODO Saner string behaviour
+# DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII QT_STRICT_ITERATORS
+TARGET = minitube
+mac {
+ TARGET = Minitube
+ QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.4
+}
+QT += network \
+ xml \
+ phonon
+include(src/qtsingleapplication/qtsingleapplication.pri)
+include(src/thlibrary/thlibrary.pri)
+HEADERS += src/MainWindow.h \
+ src/SearchView.h \
+ src/MediaView.h \
+ src/AboutView.h \
+ src/youtubesearch.h \
+ src/video.h \
+ src/youtubestreamreader.h \
+ src/View.h \
+ src/searchlineedit.h \
+ src/urllineedit.h \
+ src/spacer.h \
+ src/Constants.h \
+ src/iconloader/qticonloader.h \
+ src/faderwidget/FaderWidget.h \
+ src/ListModel.h \
+ src/playlist/PrettyItemDelegate.h \
+ src/networkaccess.h \
+ src/videomimedata.h \
+ src/global.h \
+ src/updatechecker.h \
+ src/playlistwidget.h \
+ src/searchparams.h \
+ src/minisplitter.h \
+ src/loadingwidget.h \
+ src/videoareawidget.h \
+ src/googlesuggest.h \
+ src/videowidget.h \
+ src/flickcharm.h \
+ src/videodefinition.h
+SOURCES += src/main.cpp \
+ src/MainWindow.cpp \
+ src/SearchView.cpp \
+ src/MediaView.cpp \
+ src/AboutView.cpp \
+ src/youtubesearch.cpp \
+ src/youtubestreamreader.cpp \
+ src/searchlineedit.cpp \
+ src/urllineedit.cpp \
+ src/spacer.cpp \
+ src/video.cpp \
+ src/iconloader/qticonloader.cpp \
+ src/faderwidget/FaderWidget.cpp \
+ src/ListModel.cpp \
+ src/playlist/PrettyItemDelegate.cpp \
+ src/videomimedata.cpp \
+ src/updatechecker.cpp \
+ src/networkaccess.cpp \
+ src/playlistwidget.cpp \
+ src/searchparams.cpp \
+ src/minisplitter.cpp \
+ src/loadingwidget.cpp \
+ src/videoareawidget.cpp \
+ src/googlesuggest.cpp \
+ src/videowidget.cpp \
+ src/flickcharm.cpp \
+ src/videodefinition.cpp
+RESOURCES += resources.qrc
+DESTDIR = build/target/
+OBJECTS_DIR = build/obj/
+MOC_DIR = build/moc/
+RCC_DIR = build/rcc/
+
+# Tell Qt Linguist that we use UTF-8 strings in our sources
+CODECFORTR = UTF-8
+CODECFORSRC = UTF-8
+include(locale/locale.pri)
+
+# deploy
+DISTFILES += CHANGES \
+ COPYING
+mac {
+ CONFIG += x86 \
+ ppc
+ QMAKE_INFO_PLIST = Info.plist
+ ICON = minitube.icns
+}
+unix {
+ isEmpty(PREFIX):PREFIX = /usr
+ BINDIR = $$PREFIX/bin
+ INSTALLS += target
+ target.path = $$BINDIR
+ DATADIR = $$PREFIX/share
+ PKGDATADIR = $$DATADIR/minitube
+ DEFINES += DATADIR=\\\"$$DATADIR\\\" \
+ PKGDATADIR=\\\"$$PKGDATADIR\\\"
+ INSTALLS += translations \
+ desktop \
+ iconsvg \
+ icon16 \
+ icon32 \
+ icon48 \
+ icon64 \
+ icon128 \
+ icon256
+ translations.path = $$PKGDATADIR
+ translations.files += $$DESTDIR/locale
+ desktop.path = $$DATADIR/applications
+ desktop.files += minitube.desktop
+ iconsvg.path = $$DATADIR/icons/hicolor/scalable/apps
+ iconsvg.files += data/minitube.svg
+ icon16.path = $$DATADIR/icons/hicolor/16x16/apps
+ icon16.files += data/16x16/minitube.png
+ icon32.path = $$DATADIR/icons/hicolor/32x32/apps
+ icon32.files += data/32x32/minitube.png
+ icon48.path = $$DATADIR/icons/hicolor/48x48/apps
+ icon48.files += data/48x48/minitube.png
+ icon64.path = $$DATADIR/icons/hicolor/64x64/apps
+ icon64.files += data/64x64/minitube.png
+ icon128.path = $$DATADIR/icons/hicolor/128x128/apps
+ icon128.files += data/128x128/minitube.png
+ icon256.path = $$DATADIR/icons/hicolor/256x256/apps
+ icon256.files += data/256x256/minitube.png
+}
+win32:RC_FILE = minitube.rc
--- /dev/null
+IDI_ICON1 ICON DISCARDABLE "minitube.ico"
+
--- /dev/null
+<RCC>
+ <qresource prefix="/">
+ <file>images/app.png</file>
+ <file>images/view-fullscreen.png</file>
+ <file>images/media-playback-pause.png</file>
+ <file>images/media-playback-start.png</file>
+ <file>images/media-playback-stop.png</file>
+ <file>images/media-skip-forward.png</file>
+ </qresource>
+</RCC>
--- /dev/null
+#include "AboutView.h"
+#include "Constants.h"
+
+AboutView::AboutView(QWidget *parent) : QWidget(parent) {
+
+ QBoxLayout *aboutlayout = new QHBoxLayout(this);
+ aboutlayout->setAlignment(Qt::AlignCenter);
+ aboutlayout->setSpacing(30);
+
+ QLabel *logo = new QLabel(this);
+ logo->setPixmap(QPixmap(":/images/app.png"));
+ aboutlayout->addWidget(logo, 0, Qt::AlignTop);
+
+ QBoxLayout *layout = new QVBoxLayout();
+ layout->setAlignment(Qt::AlignCenter);
+ layout->setSpacing(30);
+ aboutlayout->addLayout(layout);
+
+ QString info = "<h1>" + QString(Constants::APP_NAME) + "</h1>"
+ "<p>" + tr("There's life outside the browser!") + "</p>"
+ "<p>" + tr("Version %1").arg(Constants::VERSION) + "</p>"
+ + QString("<p><a href=\"%1/\">%1</a></p>").arg(Constants::WEBSITE) +
+
+ "<p>" + tr("%1 is Free Software but its development takes precious time.").arg(Constants::APP_NAME) + "<br/>"
+ + tr("Please <a href='%1'>donate</a> to support the continued development of %2.")
+ .arg(QString(Constants::WEBSITE).append("#donate"), Constants::APP_NAME) + "</p>"
+
+ "<p>" + tr("Report bugs and send in your ideas to %1")
+ .arg(QString("<a href=\"mailto:%1\">%1</a>").arg(Constants::EMAIL)) + "</p>"
+
+ "<p>"
+ + tr("Icon designed by %1.").arg("Sebastian Kraft")
+ + "<br>" + tr("Compact mode contributed by %1.").arg("Stefan Brück")
+ + "<br>" + tr("HTTP proxy support contributed by %1.").arg("Kiwamu Okabe")
+ + "</p>"
+
+ "<p>" + tr("Translated by %1").arg("Nikita Lyalin (ru_RU), "
+ "Márcio Moraes (pt_BR), "
+ // "Sergio Tocalini Joerg (es_AR), "
+ "Stefan Brück (de_DE), "
+ "Grzegorz Gibas (pl_PL), "
+ "Kiwamu Okabe (ja_JP), "
+ "Dan Vrátil (cs_CZ), "
+ // "Rafa (es_ES), "
+ "Yaron Shahrabani (he_IL), "
+ "Oleksandr Korneta (uk), "
+ "Inga Muste (lat), "
+ "Srecko Belaic (hr_HR), "
+ "Miguel Anxo Bouzada (es, gl), "
+ "Guillaume Betous & Mathieu Dimanche (fr_FR), "
+ "Krisztián Horváth (hu_HU), "
+ "Ali E. İmrek (tr_TR), "
+ "Jan W. Skjoldal & Halvor Lyche Strandvoll (nb_NO), "
+ "Ovidiu Niţan (ro_RO), "
+ "Giorgos Skettos (el_GR), "
+ "Brian Keetman (nl_NL), "
+ "Sderawi (ar), "
+ "Daniel Rodrigues (pt_PT), "
+ "Jesse Jaara (fi_FI), "
+ "Tsvyatko Makazchiev (bg_BG)"
+ ) + "</p>"
+
+ "<p>" + tr("Released under the <a href='%1'>GNU General Public License</a>")
+ .arg("http://www.gnu.org/licenses/gpl.html") + "</p>"
+
+ "<p>© 2009-2010 " + Constants::ORG_NAME + "</p>";
+ QLabel *infoLabel = new QLabel(info, this);
+ infoLabel->setOpenExternalLinks(true);
+ infoLabel->setWordWrap(true);
+ layout->addWidget(infoLabel);
+
+ QLayout *buttonLayout = new QHBoxLayout();
+ buttonLayout->setAlignment(Qt::AlignLeft);
+ QPushButton *closeButton = new QPushButton(tr("&Close"), this);
+ closeButton->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
+
+ closeButton->setDefault(true);
+ closeButton->setFocus(Qt::OtherFocusReason);
+ connect(closeButton, SIGNAL(clicked()), parent, SLOT(goBack()));
+ buttonLayout->addWidget(closeButton);
+
+ layout->addLayout(buttonLayout);
+
+}
--- /dev/null
+#ifndef ABOUTVIEW_H
+#define ABOUTVIEW_H
+
+#include <QtGui>
+#include "View.h"
+#include "Constants.h"
+
+class AboutView : public QWidget, public View {
+
+ Q_OBJECT
+
+public:
+ AboutView(QWidget *parent);
+ void appear() {}
+ void disappear() {}
+ QMap<QString, QVariant> metadata() {
+ QMap<QString, QVariant> metadata;
+ metadata.insert("title", tr("About"));
+ metadata.insert("description",
+ tr("What you always wanted to know about %1 and never dared to ask")
+ .arg(Constants::APP_NAME));
+ return metadata;
+ }
+
+};
+#endif
--- /dev/null
+#ifndef CONSTANTS_H
+#define CONSTANTS_H
+
+#include <QString>
+
+namespace Constants {
+ static const char *VERSION = "1.0";
+ static const char *APP_NAME = "Minitube";
+ static const char *ORG_NAME = "Flavio Tordini";
+ static const char *ORG_DOMAIN = "flavio.tordini.org";
+ static const char *WEBSITE = "http://flavio.tordini.org/minitube";
+ static const char *EMAIL = "flavio.tordini@gmail.com";
+ static const QString USER_AGENT = QString(APP_NAME) + " " + VERSION + " (" + WEBSITE + ")";
+}
+
+#endif
--- /dev/null
+#include "ListModel.h"
+#include "videomimedata.h"
+
+#define MAX_ITEMS 10
+static const QString recentKeywordsKey = "recentKeywords";
+
+ListModel::ListModel(QWidget *parent) : QAbstractListModel(parent) {
+ youtubeSearch = 0;
+ searching = false;
+ canSearchMore = true;
+ m_activeVideo = 0;
+ m_activeRow = -1;
+ skip = 1;
+}
+
+ListModel::~ListModel() {
+ delete youtubeSearch;
+}
+
+int ListModel::rowCount(const QModelIndex &/*parent*/) const {
+ int count = videos.size();
+
+ // add the message item
+ if (videos.isEmpty() || !searching)
+ count++;
+
+ return count;
+}
+
+QVariant ListModel::data(const QModelIndex &index, int role) const {
+
+ int row = index.row();
+
+ if (row == videos.size()) {
+
+ QPalette palette;
+ QFont boldFont;
+ boldFont.setBold(true);
+
+ switch (role) {
+ case ItemTypeRole:
+ return ItemTypeShowMore;
+ case Qt::DisplayRole:
+ case Qt::StatusTipRole:
+ if (!errorMessage.isEmpty()) return errorMessage;
+ if (searching) return tr("Searching...");
+ if (canSearchMore) return tr("Show %1 More").arg(MAX_ITEMS);
+ if (videos.isEmpty()) return tr("No videos");
+ else return tr("No more videos");
+ case Qt::TextAlignmentRole:
+ return QVariant(int(Qt::AlignHCenter | Qt::AlignVCenter));
+ case Qt::ForegroundRole:
+ if (!errorMessage.isEmpty())
+ return palette.color(QPalette::ToolTipText);
+ else
+ return palette.color(QPalette::Dark);
+ case Qt::BackgroundColorRole:
+ if (!errorMessage.isEmpty())
+ return palette.color(QPalette::ToolTipBase);
+ else
+ return QVariant();
+ case Qt::FontRole:
+ return boldFont;
+ default:
+ return QVariant();
+ }
+
+ } else if (row < 0 || row >= videos.size())
+ return QVariant();
+
+ Video *video = videos.at(row);
+
+ switch (role) {
+ case ItemTypeRole:
+ return ItemTypeVideo;
+ case VideoRole:
+ return QVariant::fromValue(QPointer<Video>(video));
+ case ActiveTrackRole:
+ return video == m_activeVideo;
+ case Qt::DisplayRole:
+ case Qt::StatusTipRole:
+ return video->title();
+ /*
+ case Qt::ToolTipRole:
+
+ QString tooltip;
+ if (!element.firstChildElement().text().isEmpty()) {
+ tooltip.append(QString("<b>").append(element.firstChildElement().text()).append("</b><br/>"));
+ }
+ if (!fromDate.isEmpty()) {
+ tooltip.append("<i>Pubblicato il</i> ").append(fromDate);
+ }
+ if (!toDate.isEmpty()) {
+ tooltip.append("<br/><i>Scadenza</i>: ").append(toDate);
+ }
+ tooltip.append("<br/><i>Tipo</i>: ").append(typeName)
+ .append("<br/><i>Id</i>: ").appen QFont boldFont;
+ boldFont.setBold(true);d(id);
+ return tooltip;
+ */
+
+ // case StreamUrlRole:
+ // return video->streamUrl();
+ }
+
+ return QVariant();
+}
+
+void ListModel::setActiveRow( int row) {
+ if ( rowExists( row ) ) {
+
+ m_activeRow = row;
+ m_activeVideo = videoAt(row);
+
+ // setStateOfRow( row, Item::Played );
+
+ int oldactiverow = m_activeRow;
+
+ if ( rowExists( oldactiverow ) )
+ emit dataChanged( createIndex( oldactiverow, 0 ), createIndex( oldactiverow, columnCount() - 1 ) );
+
+ emit dataChanged( createIndex( m_activeRow, 0 ), createIndex( m_activeRow, columnCount() - 1 ) );
+ emit activeRowChanged(row);
+
+ } else {
+ m_activeRow = -1;
+ m_activeVideo = 0;
+ }
+
+}
+
+int ListModel::nextRow() const {
+ int nextRow = m_activeRow + 1;
+ if (rowExists(nextRow))
+ return nextRow;
+ return -1;
+}
+
+Video* ListModel::videoAt( int row ) const {
+ if ( rowExists( row ) )
+ return videos.at( row );
+ return 0;
+}
+
+Video* ListModel::activeVideo() const {
+ return m_activeVideo;
+}
+
+void ListModel::search(SearchParams *searchParams) {
+
+ // delete current videos
+ while (!videos.isEmpty())
+ delete videos.takeFirst();
+ m_activeVideo = 0;
+ m_activeRow = -1;
+ skip = 1;
+ errorMessage.clear();
+ reset();
+
+ // (re)initialize the YouTubeSearch
+ if (youtubeSearch) delete youtubeSearch;
+ youtubeSearch = new YouTubeSearch();
+ connect(youtubeSearch, SIGNAL(gotVideo(Video*)), this, SLOT(addVideo(Video*)));
+ connect(youtubeSearch, SIGNAL(finished(int)), this, SLOT(searchFinished(int)));
+ connect(youtubeSearch, SIGNAL(error(QString)), this, SLOT(searchError(QString)));
+
+ this->searchParams = searchParams;
+ searching = true;
+ youtubeSearch->search(searchParams, MAX_ITEMS, skip);
+ skip += MAX_ITEMS;
+}
+
+void ListModel::searchMore(int max) {
+ if (searching) return;
+ searching = true;
+ errorMessage.clear();
+ youtubeSearch->search(searchParams, max, skip);
+ skip += max;
+}
+
+void ListModel::searchMore() {
+ searchMore(MAX_ITEMS);
+}
+
+void ListModel::searchNeeded() {
+ int remainingRows = videos.size() - m_activeRow;
+ int rowsNeeded = MAX_ITEMS - remainingRows;
+ if (rowsNeeded > 0)
+ searchMore(rowsNeeded);
+}
+
+void ListModel::abortSearch() {
+ while (!videos.isEmpty())
+ delete videos.takeFirst();
+ reset();
+ youtubeSearch->abort();
+ searching = false;
+}
+
+void ListModel::searchFinished(int total) {
+ searching = false;
+ canSearchMore = total > 0;
+
+ // update the message item
+ emit dataChanged( createIndex( MAX_ITEMS, 0 ), createIndex( MAX_ITEMS, columnCount() - 1 ) );
+}
+
+void ListModel::searchError(QString message) {
+ errorMessage = message;
+ // update the message item
+ emit dataChanged( createIndex( MAX_ITEMS, 0 ), createIndex( MAX_ITEMS, columnCount() - 1 ) );
+}
+
+void ListModel::addVideo(Video* video) {
+
+ connect(video, SIGNAL(gotThumbnail()), this, SLOT(updateThumbnail()));
+
+ beginInsertRows(QModelIndex(), videos.size(), videos.size());
+ videos << video;
+ endInsertRows();
+
+ // first result!
+ if (videos.size() == 1) {
+ // autoplay
+ setActiveRow(0);
+
+ // save keyword
+ QString query = searchParams->keywords();
+ QSettings settings;
+ QStringList keywords = settings.value(recentKeywordsKey).toStringList();
+ keywords.removeAll(query);
+ keywords.prepend(query);
+ while (keywords.size() > 10)
+ keywords.removeLast();
+ settings.setValue(recentKeywordsKey, keywords);
+ }
+
+}
+
+void ListModel::updateThumbnail() {
+
+ Video *video = static_cast<Video *>(sender());
+ if (!video) {
+ qDebug() << "Cannot get sender";
+ return;
+ }
+
+ int row = rowForVideo(video);
+ emit dataChanged( createIndex( row, 0 ), createIndex( row, columnCount() - 1 ) );
+
+}
+
+// --- item removal
+
+/**
+ * This function does not free memory
+ */
+bool ListModel::removeRows(int position, int rows, const QModelIndex & /*parent*/) {
+ beginRemoveRows(QModelIndex(), position, position+rows-1);
+ for (int row = 0; row < rows; ++row) {
+ videos.removeAt(position);
+ }
+ endRemoveRows();
+ return true;
+}
+
+void ListModel::removeIndexes(QModelIndexList &indexes) {
+ QList<Video*> originalList(videos);
+ QList<Video*> delitems;
+ foreach (QModelIndex index, indexes) {
+ Video* video = originalList.at(index.row());
+ int idx = videos.indexOf(video);
+ if (idx != -1) {
+ beginRemoveRows(QModelIndex(), idx, idx);
+ delitems.append(video);
+ videos.removeAll(video);
+ endRemoveRows();
+ }
+ }
+
+ qDeleteAll(delitems);
+
+}
+
+// --- Sturm und drang ---
+
+
+
+Qt::DropActions ListModel::supportedDropActions() const {
+ return Qt::MoveAction;
+}
+
+Qt::ItemFlags ListModel::flags(const QModelIndex &index) const {
+ Qt::ItemFlags defaultFlags = QAbstractListModel::flags(index);
+
+ if (index.isValid()) {
+ if (index.row() == videos.size()) {
+ // don't drag the "show 10 more" item
+ return defaultFlags;
+ } else
+ return ( defaultFlags | Qt::ItemIsDropEnabled | Qt::ItemIsDragEnabled );
+ } else
+ return Qt::ItemIsDropEnabled | defaultFlags;
+}
+
+QStringList ListModel::mimeTypes() const {
+ QStringList types;
+ types << "application/x-minitube-video";
+ return types;
+}
+
+QMimeData* ListModel::mimeData( const QModelIndexList &indexes ) const {
+ VideoMimeData* mime = new VideoMimeData();
+
+ foreach( const QModelIndex &it, indexes ) {
+ int row = it.row();
+ if (row >= 0 && row < videos.size())
+ mime->addVideo( videos.at( it.row() ) );
+ }
+
+ return mime;
+}
+
+bool ListModel::dropMimeData(const QMimeData *data,
+ Qt::DropAction action, int row, int column,
+ const QModelIndex &parent) {
+ if (action == Qt::IgnoreAction)
+ return true;
+
+ if (!data->hasFormat("application/x-minitube-video"))
+ return false;
+
+ if (column > 0)
+ return false;
+
+ int beginRow;
+ if (row != -1)
+ beginRow = row;
+ else if (parent.isValid())
+ beginRow = parent.row();
+ else
+ beginRow = rowCount(QModelIndex());
+
+ const VideoMimeData* videoMimeData = dynamic_cast<const VideoMimeData*>( data );
+ if(!videoMimeData ) return false;
+
+ QList<Video*> droppedVideos = videoMimeData->videos();
+ foreach( Video *video, droppedVideos) {
+
+ // remove videos
+ int videoRow = videos.indexOf(video);
+ removeRows(videoRow, 1, QModelIndex());
+
+ // and then add them again at the new position
+ beginInsertRows(QModelIndex(), beginRow, beginRow);
+ videos.insert(beginRow, video);
+ endInsertRows();
+
+ }
+
+ // fix m_activeRow after all this
+ m_activeRow = videos.indexOf(m_activeVideo);
+
+ // let the MediaView restore the selection
+ emit needSelectionFor(droppedVideos);
+
+ return true;
+
+}
+
+int ListModel::rowForVideo(Video* video) {
+ return videos.indexOf(video);
+}
+
+QModelIndex ListModel::indexForVideo(Video* video) {
+ return createIndex(videos.indexOf(video), 0);
+}
+
+void ListModel::move(QModelIndexList &indexes, bool up) {
+
+ QList<Video*> movedVideos;
+
+ foreach (QModelIndex index, indexes) {
+ int row = index.row();
+ // qDebug() << "index row" << row;
+ Video *video = videoAt(row);
+ movedVideos << video;
+ }
+
+ int counter = 1;
+ foreach (Video *video, movedVideos) {
+
+ int row = rowForVideo(video);
+ // qDebug() << "video row" << row;
+ removeRows(row, 1, QModelIndex());
+
+ if (up) row--;
+ else row++;
+
+ beginInsertRows(QModelIndex(), row, row);
+ videos.insert(row, video);
+ endInsertRows();
+
+ counter++;
+ }
+
+ emit needSelectionFor(movedVideos);
+
+}
--- /dev/null
+#ifndef LISTMODEL_H
+#define LISTMODEL_H
+
+#include "video.h"
+#include "youtubesearch.h"
+#include "searchparams.h"
+
+enum DataRoles {
+ ItemTypeRole = Qt::UserRole,
+ VideoRole,
+ ActiveTrackRole
+};
+
+enum ItemTypes {
+ ItemTypeVideo = 1,
+ ItemTypeShowMore
+};
+
+class ListModel : public QAbstractListModel {
+
+ Q_OBJECT
+
+public:
+
+ ListModel(QWidget *parent);
+ ~ListModel();
+
+ // inherited from QAbstractListModel
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ // int rowCount( const QModelIndex& parent = QModelIndex() ) const { Q_UNUSED( parent ); return videos.size(); }
+ int columnCount( const QModelIndex& parent = QModelIndex() ) const { Q_UNUSED( parent ); return 4; }
+ QVariant data(const QModelIndex &index, int role) const;
+ bool removeRows(int position, int rows, const QModelIndex &parent);
+
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QStringList mimeTypes() const;
+ Qt::DropActions supportedDropActions() const;
+ QMimeData* mimeData( const QModelIndexList &indexes ) const;
+ bool dropMimeData(const QMimeData *data,
+ Qt::DropAction action, int row, int column,
+ const QModelIndex &parent);
+
+ // custom methods
+ void setActiveRow( int row );
+ bool rowExists( int row ) const { return (( row >= 0 ) && ( row < videos.size() ) ); }
+ int activeRow() const { return m_activeRow; } // returns -1 if there is no active row
+ int nextRow() const;
+ void removeIndexes(QModelIndexList &indexes);
+ int rowForVideo(Video* video);
+ QModelIndex indexForVideo(Video* video);
+ void move(QModelIndexList &indexes, bool up);
+
+ Video* videoAt( int row ) const;
+ Video* activeVideo() const;
+
+ // video search methods
+ void search(SearchParams *searchParams);
+ void abortSearch();
+
+
+public slots:
+ void searchMore();
+ void searchNeeded();
+ void addVideo(Video* video);
+ void searchFinished(int total);
+ void searchError(QString message);
+ void updateThumbnail();
+
+signals:
+ void activeRowChanged(int);
+ void needSelectionFor(QList<Video*>);
+
+private:
+ void searchMore(int max);
+
+ YouTubeSearch *youtubeSearch;
+ SearchParams *searchParams;
+ bool searching;
+ bool canSearchMore;
+
+ QList<Video*> videos;
+ int skip;
+
+ // the row being played
+ int m_activeRow;
+ Video *m_activeVideo;
+
+ QString errorMessage;
+};
+
+#endif
--- /dev/null
+#include "MainWindow.h"
+#include "spacer.h"
+#include "Constants.h"
+#include "iconloader/qticonloader.h"
+#include "global.h"
+#include "videodefinition.h"
+
+MainWindow::MainWindow() :
+ mediaObject(0),
+ audioOutput(0),
+ aboutView(0),
+ m_fullscreen(false) {
+
+ // views mechanism
+ history = new QStack<QWidget*>();
+ views = new QStackedWidget(this);
+
+ // views
+ searchView = new SearchView(this);
+ connect(searchView, SIGNAL(search(QString)), this, SLOT(showMedia(QString)));
+ views->addWidget(searchView);
+
+ mediaView = new MediaView(this);
+ views->addWidget(mediaView);
+
+ toolbarSearch = new SearchLineEdit(this);
+ toolbarSearch->setFont(qApp->font());
+ toolbarSearch->setMinimumWidth(toolbarSearch->fontInfo().pixelSize()*15);
+ connect(toolbarSearch, SIGNAL(search(const QString&)), searchView, SLOT(watch(const QString&)));
+
+ // build ui
+ createActions();
+ createMenus();
+ createToolBars();
+ createStatusBar();
+
+ initPhonon();
+ mediaView->setMediaObject(mediaObject);
+
+ // remove that useless menu/toolbar context menu
+ this->setContextMenuPolicy(Qt::NoContextMenu);
+
+ // mediaView init stuff thats needs actions
+ mediaView->initialize();
+
+ // restore window position
+ readSettings();
+
+ // cool toolbar on the Mac
+ // this is too buggy to be enabled
+ // setUnifiedTitleAndToolBarOnMac(true);
+
+ // event filter to block ugly toolbar tooltips
+ qApp->installEventFilter(this);
+
+ // show the initial view
+ showWidget(searchView);
+
+ setCentralWidget(views);
+}
+
+MainWindow::~MainWindow() {
+ delete history;
+}
+
+bool MainWindow::eventFilter(QObject *obj, QEvent *event) {
+ if (event->type() == QEvent::ToolTip) {
+ // kill tooltips
+ return true;
+ } else {
+ // standard event processing
+ return QObject::eventFilter(obj, event);
+ }
+}
+
+void MainWindow::createActions() {
+
+ QMap<QString, QAction*> *actions = The::globalActions();
+
+ stopAct = new QAction(QtIconLoader::icon("media-playback-stop", QIcon(":/images/media-playback-stop.png")), tr("&Stop"), this);
+ stopAct->setStatusTip(tr("Stop playback and go back to the search view"));
+ stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
+ actions->insert("stop", stopAct);
+ connect(stopAct, SIGNAL(triggered()), this, SLOT(stop()));
+
+ skipAct = new QAction(QtIconLoader::icon("media-skip-forward", QIcon(":/images/media-skip-forward.png")), tr("S&kip"), this);
+ skipAct->setStatusTip(tr("Skip to the next video"));
+ skipAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Right) << QKeySequence(Qt::Key_MediaNext));
+ skipAct->setEnabled(false);
+ actions->insert("skip", skipAct);
+ connect(skipAct, SIGNAL(triggered()), mediaView, SLOT(skip()));
+
+ pauseAct = new QAction(QtIconLoader::icon("media-playback-pause", QIcon(":/images/media-playback-pause.png")), tr("&Pause"), this);
+ pauseAct->setStatusTip(tr("Pause playback"));
+ pauseAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Space) << QKeySequence(Qt::Key_MediaPlay));
+ pauseAct->setEnabled(false);
+ actions->insert("pause", pauseAct);
+ connect(pauseAct, SIGNAL(triggered()), mediaView, SLOT(pause()));
+
+ fullscreenAct = new QAction(QtIconLoader::icon("view-fullscreen", QIcon(":/images/view-fullscreen.png")), tr("&Full Screen"), this);
+ fullscreenAct->setStatusTip(tr("Go full screen"));
+ fullscreenAct->setShortcut(QKeySequence(Qt::ALT + Qt::Key_Return));
+ fullscreenAct->setShortcutContext(Qt::ApplicationShortcut);
+ actions->insert("fullscreen", fullscreenAct);
+ connect(fullscreenAct, SIGNAL(triggered()), this, SLOT(fullscreen()));
+
+ compactViewAct = new QAction(tr("&Compact mode"), this);
+ compactViewAct->setStatusTip(tr("Hide the playlist and the toolbar"));
+ compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
+ compactViewAct->setCheckable(true);
+ compactViewAct->setChecked(false);
+ compactViewAct->setEnabled(false);
+ actions->insert("compactView", compactViewAct);
+ connect(compactViewAct, SIGNAL(toggled(bool)), this, SLOT(compactView(bool)));
+
+ webPageAct = new QAction(tr("Open the &YouTube page"), this);
+ webPageAct->setStatusTip(tr("Go to the YouTube video page and pause playback"));
+ webPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
+ webPageAct->setEnabled(false);
+ actions->insert("webpage", webPageAct);
+ connect(webPageAct, SIGNAL(triggered()), mediaView, SLOT(openWebPage()));
+
+ copyPageAct = new QAction(tr("Copy the YouTube &link"), this);
+ copyPageAct->setStatusTip(tr("Copy the current video YouTube link to the clipboard"));
+ copyPageAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_L));
+ copyPageAct->setEnabled(false);
+ actions->insert("pagelink", copyPageAct);
+ connect(copyPageAct, SIGNAL(triggered()), mediaView, SLOT(copyWebPage()));
+
+ copyLinkAct = new QAction(tr("Copy the video stream &URL"), this);
+ copyLinkAct->setStatusTip(tr("Copy the current video stream URL to the clipboard"));
+ copyLinkAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
+ copyLinkAct->setEnabled(false);
+ actions->insert("videolink", copyLinkAct);
+ connect(copyLinkAct, SIGNAL(triggered()), mediaView, SLOT(copyVideoLink()));
+
+ removeAct = new QAction(tr("&Remove"), this);
+ removeAct->setStatusTip(tr("Remove the selected videos from the playlist"));
+ removeAct->setShortcuts(QList<QKeySequence>() << QKeySequence("Del") << QKeySequence("Backspace"));
+ removeAct->setEnabled(false);
+ actions->insert("remove", removeAct);
+ connect(removeAct, SIGNAL(triggered()), mediaView, SLOT(removeSelected()));
+
+ moveUpAct = new QAction(tr("Move &Up"), this);
+ moveUpAct->setStatusTip(tr("Move up the selected videos in the playlist"));
+ moveUpAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Up));
+ moveUpAct->setEnabled(false);
+ actions->insert("moveUp", moveUpAct);
+ connect(moveUpAct, SIGNAL(triggered()), mediaView, SLOT(moveUpSelected()));
+
+ moveDownAct = new QAction(tr("Move &Down"), this);
+ moveDownAct->setStatusTip(tr("Move down the selected videos in the playlist"));
+ moveDownAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Down));
+ moveDownAct->setEnabled(false);
+ actions->insert("moveDown", moveDownAct);
+ connect(moveDownAct, SIGNAL(triggered()), mediaView, SLOT(moveDownSelected()));
+
+ clearAct = new QAction(tr("&Clear recent keywords"), this);
+ clearAct->setMenuRole(QAction::ApplicationSpecificRole);
+ clearAct->setShortcuts(QList<QKeySequence>()
+ << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Delete)
+ << QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Backspace));
+ clearAct->setStatusTip(tr("Clear the search history. Cannot be undone."));
+ clearAct->setEnabled(true);
+ actions->insert("clearRecentKeywords", clearAct);
+ connect(clearAct, SIGNAL(triggered()), SLOT(clearRecentKeywords()));
+
+ quitAct = new QAction(tr("&Quit"), this);
+ quitAct->setMenuRole(QAction::QuitRole);
+ quitAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+Q")) << QKeySequence(Qt::CTRL + Qt::Key_W));
+ quitAct->setStatusTip(tr("Bye"));
+ actions->insert("quit", quitAct);
+ connect(quitAct, SIGNAL(triggered()), this, SLOT(quit()));
+
+ siteAct = new QAction(tr("&Website"), this);
+ siteAct->setShortcut(QKeySequence::HelpContents);
+ siteAct->setStatusTip(tr("%1 on the Web").arg(Constants::APP_NAME));
+ actions->insert("site", siteAct);
+ connect(siteAct, SIGNAL(triggered()), this, SLOT(visitSite()));
+
+ donateAct = new QAction(tr("Make a &donation"), this);
+ donateAct->setStatusTip(tr("Please support the continued development of %1").arg(Constants::APP_NAME));
+ actions->insert("donate", donateAct);
+ connect(donateAct, SIGNAL(triggered()), this, SLOT(donate()));
+
+ aboutAct = new QAction(tr("&About"), this);
+ aboutAct->setMenuRole(QAction::AboutRole);
+ aboutAct->setStatusTip(tr("Info about %1").arg(Constants::APP_NAME));
+ actions->insert("about", aboutAct);
+ connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
+
+ // Invisible actions
+
+ searchFocusAct = new QAction(this);
+ searchFocusAct->setShortcut(QKeySequence::Find);
+ searchFocusAct->setStatusTip(tr("Search"));
+ actions->insert("search", searchFocusAct);
+ connect(searchFocusAct, SIGNAL(triggered()), this, SLOT(searchFocus()));
+ addAction(searchFocusAct);
+
+ volumeUpAct = new QAction(this);
+ volumeUpAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Plus) << QKeySequence(Qt::Key_VolumeUp));
+ actions->insert("volume-up", volumeUpAct);
+ connect(volumeUpAct, SIGNAL(triggered()), this, SLOT(volumeUp()));
+ addAction(volumeUpAct);
+
+ volumeDownAct = new QAction(this);
+ volumeDownAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_Minus) << QKeySequence(Qt::Key_VolumeDown));
+ actions->insert("volume-down", volumeDownAct);
+ connect(volumeDownAct, SIGNAL(triggered()), this, SLOT(volumeDown()));
+ addAction(volumeDownAct);
+
+ volumeMuteAct = new QAction(this);
+ volumeMuteAct->setStatusTip(tr("Mute volume"));
+ volumeMuteAct->setShortcuts(QList<QKeySequence>() << QKeySequence(tr("Ctrl+M")) << QKeySequence(Qt::Key_VolumeMute));
+ actions->insert("volume-mute", volumeMuteAct);
+ connect(volumeMuteAct, SIGNAL(triggered()), this, SLOT(volumeMute()));
+ addAction(volumeMuteAct);
+
+ QAction *definitionAct = new QAction(this);
+ definitionAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::CTRL + Qt::Key_D));
+ /*
+ QMenu *definitionMenu = new QMenu(this);
+ foreach (QString definition, VideoDefinition::getDefinitionNames()) {
+ definitionMenu->addAction(definition);
+ }
+ definitionAct->setMenu(definitionMenu);
+ */
+ actions->insert("definition", definitionAct);
+ connect(definitionAct, SIGNAL(triggered()), SLOT(toggleDefinitionMode()));
+ addAction(definitionAct);
+
+ // common action properties
+ foreach (QAction *action, actions->values()) {
+
+ // add actions to the MainWindow so that they work
+ // when the menu is hidden
+ addAction(action);
+
+ // never autorepeat.
+ // unexperienced users tend to keep keys pressed for a "long" time
+ action->setAutoRepeat(false);
+
+ // set to something more meaningful then the toolbar text
+ // HELP! how to remove tooltips altogether?!
+ if (!action->statusTip().isEmpty())
+ action->setToolTip(action->statusTip());
+
+ // show keyboard shortcuts in the status bar
+ if (!action->shortcut().isEmpty())
+ action->setStatusTip(action->statusTip() + " (" + action->shortcut().toString(QKeySequence::NativeText) + ")");
+
+ // no icons in menus
+ action->setIconVisibleInMenu(false);
+
+ }
+
+}
+
+void MainWindow::createMenus() {
+
+ QMap<QString, QMenu*> *menus = The::globalMenus();
+
+ fileMenu = menuBar()->addMenu(tr("&Application"));
+ // menus->insert("file", fileMenu);
+ fileMenu->addAction(clearAct);
+#ifndef Q_WS_MAC
+ fileMenu->addSeparator();
+#endif
+ fileMenu->addAction(quitAct);
+
+ playlistMenu = menuBar()->addMenu(tr("&Playlist"));
+ menus->insert("playlist", playlistMenu);
+ playlistMenu->addAction(removeAct);
+ playlistMenu->addSeparator();
+ playlistMenu->addAction(moveUpAct);
+ playlistMenu->addAction(moveDownAct);
+
+ viewMenu = menuBar()->addMenu(tr("&Video"));
+ menus->insert("video", viewMenu);
+ viewMenu->addAction(stopAct);
+ viewMenu->addAction(pauseAct);
+ viewMenu->addAction(skipAct);
+ viewMenu->addSeparator();
+ viewMenu->addAction(webPageAct);
+ viewMenu->addAction(copyPageAct);
+ viewMenu->addAction(copyLinkAct);
+ viewMenu->addSeparator();
+ viewMenu->addAction(compactViewAct);
+ viewMenu->addAction(fullscreenAct);
+
+ helpMenu = menuBar()->addMenu(tr("&Help"));
+ helpMenu->addAction(siteAct);
+ helpMenu->addAction(donateAct);
+ helpMenu->addAction(aboutAct);
+}
+
+void MainWindow::createToolBars() {
+
+ mainToolBar = new QToolBar(this);
+#if QT_VERSION < 0x040600 || defined(Q_WS_MAC)
+ mainToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
+#else
+ mainToolBar->setToolButtonStyle(Qt::ToolButtonFollowStyle);
+#endif
+ mainToolBar->setFloatable(false);
+ mainToolBar->setMovable(false);
+
+ QFont smallerFont;
+ smallerFont.setPointSize(smallerFont.pointSize()*.85);
+ QFontInfo fontInfo(smallerFont);
+ if (fontInfo.pixelSize() < 10) {
+ smallerFont.setPixelSize(10);
+ }
+ mainToolBar->setFont(smallerFont);
+
+#ifdef Q_WS_MAC
+ mainToolBar->setIconSize(QSize(32, 32));
+#endif
+
+ mainToolBar->addAction(stopAct);
+ mainToolBar->addAction(pauseAct);
+ mainToolBar->addAction(skipAct);
+ mainToolBar->addAction(fullscreenAct);
+
+ seekSlider = new Phonon::SeekSlider(this);
+ seekSlider->setIconVisible(false);
+ Spacer *seekSliderSpacer = new Spacer(mainToolBar, seekSlider);
+ seekSliderSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ mainToolBar->addWidget(seekSliderSpacer);
+
+ volumeSlider = new Phonon::VolumeSlider(this);
+ // qDebug() << volumeSlider->children();
+ // status tip for the volume slider
+ QSlider* volumeQSlider = volumeSlider->findChild<QSlider*>();
+ if (volumeQSlider)
+ volumeQSlider->setStatusTip(tr("Press %1 to raise the volume, %2 to lower it").arg(
+ volumeUpAct->shortcut().toString(QKeySequence::NativeText), volumeDownAct->shortcut().toString(QKeySequence::NativeText)));
+ // status tip for the mute button
+ QToolButton* muteToolButton = volumeSlider->findChild<QToolButton*>();
+ if (muteToolButton)
+ muteToolButton->setStatusTip(volumeMuteAct->statusTip());
+ // this makes the volume slider smaller
+ volumeSlider->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ mainToolBar->addWidget(new Spacer(mainToolBar, volumeSlider));
+
+ toolbarSearch->setStatusTip(searchFocusAct->statusTip());
+ mainToolBar->addWidget(new Spacer(mainToolBar, toolbarSearch));
+
+ addToolBar(mainToolBar);
+}
+
+void MainWindow::createStatusBar() {
+
+ // remove ugly borders on OSX
+ // also remove excessive spacing
+ statusBar()->setStyleSheet("::item{border:0 solid} QToolBar {padding:0;spacing:0;margin:0}");
+
+ currentTime = new QLabel(this);
+ statusBar()->addPermanentWidget(currentTime);
+
+ totalTime = new QLabel(this);
+ statusBar()->addPermanentWidget(totalTime);
+
+ QToolBar *toolBar = new QToolBar(this);
+ toolBar->setToolButtonStyle(Qt::ToolButtonTextOnly);
+ toolBar->addAction(The::globalActions()->value("definition"));
+ statusBar()->addPermanentWidget(toolBar);
+
+ statusBar()->show();
+}
+
+void MainWindow::readSettings() {
+ QSettings settings;
+ restoreGeometry(settings.value("geometry").toByteArray());
+ setDefinitionMode(settings.value("definition", VideoDefinition::getDefinitionNames().first()).toString());
+ audioOutput->setVolume(settings.value("volume", 1).toDouble());
+ audioOutput->setMuted(settings.value("volumeMute").toBool());
+}
+
+void MainWindow::writeSettings() {
+ // do not save geometry when in full screen
+ if (m_fullscreen)
+ return;
+ QSettings settings;
+ settings.setValue("geometry", saveGeometry());
+ settings.setValue("volume", audioOutput->volume());
+ settings.setValue("volumeMute", audioOutput->isMuted());
+ mediaView->saveSplitterState();
+}
+
+void MainWindow::goBack() {
+ if ( history->size() > 1 ) {
+ history->pop();
+ QWidget *widget = history->pop();
+ showWidget(widget);
+ }
+}
+
+void MainWindow::showWidget ( QWidget* widget ) {
+
+ setUpdatesEnabled(false);
+
+ // call hide method on the current view
+ View* oldView = dynamic_cast<View *> (views->currentWidget());
+ if (oldView) {
+ oldView->disappear();
+ }
+
+ // call show method on the new view
+ View* newView = dynamic_cast<View *> (widget);
+ if (newView) {
+ newView->appear();
+ QMap<QString,QVariant> metadata = newView->metadata();
+ QString windowTitle = metadata.value("title").toString();
+ if (windowTitle.length())
+ windowTitle += " - ";
+ setWindowTitle(windowTitle + Constants::APP_NAME);
+ statusBar()->showMessage((metadata.value("description").toString()));
+ }
+
+ stopAct->setEnabled(widget == mediaView);
+ fullscreenAct->setEnabled(widget == mediaView);
+ compactViewAct->setEnabled(widget == mediaView);
+ webPageAct->setEnabled(widget == mediaView);
+ copyPageAct->setEnabled(widget == mediaView);
+ copyLinkAct->setEnabled(widget == mediaView);
+ aboutAct->setEnabled(widget != aboutView);
+
+ // toolbar only for the mediaView
+ mainToolBar->setVisible(widget == mediaView && !compactViewAct->isChecked());
+
+ setUpdatesEnabled(true);
+
+ QWidget *oldWidget = views->currentWidget();
+ views->setCurrentWidget(widget);
+
+#ifdef Q_WS_MAC
+ // crossfade only on OSX
+ // where we can be sure of video performance
+ fadeInWidget(oldWidget, widget);
+#endif
+
+ history->push(widget);
+}
+
+void MainWindow::fadeInWidget(QWidget *oldWidget, QWidget *newWidget) {
+ if (faderWidget) faderWidget->close();
+ if (!oldWidget || !newWidget) {
+ // qDebug() << "no widgets";
+ return;
+ }
+ faderWidget = new FaderWidget(newWidget);
+ faderWidget->start(QPixmap::grabWidget(oldWidget));
+}
+
+void MainWindow::about() {
+ if (!aboutView) {
+ aboutView = new AboutView(this);
+ views->addWidget(aboutView);
+ }
+ showWidget(aboutView);
+}
+
+void MainWindow::visitSite() {
+ QUrl url(Constants::WEBSITE);
+ statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
+ QDesktopServices::openUrl(url);
+}
+
+void MainWindow::donate() {
+ QUrl url(QString(Constants::WEBSITE) + "#donate");
+ statusBar()->showMessage(QString(tr("Opening %1").arg(url.toString())));
+ QDesktopServices::openUrl(url);
+}
+
+void MainWindow::quit() {
+ writeSettings();
+ qApp->quit();
+}
+
+void MainWindow::closeEvent(QCloseEvent *event) {
+ quit();
+ QWidget::closeEvent(event);
+}
+
+/*
+void MainWindow::showSettings() {
+ if (!settingsView) {
+ settingsView = new SettingsView(this);
+ views->addWidget(settingsView);
+ }
+ showWidget(settingsView);
+}*/
+
+void MainWindow::showSearch() {
+ showWidget(searchView);
+ currentTime->clear();
+ totalTime->clear();
+}
+
+void MainWindow::showMedia(QString query) {
+ SearchParams *searchParams = new SearchParams();
+ searchParams->setKeywords(query);
+ mediaView->search(searchParams);
+ showWidget(mediaView);
+}
+
+void MainWindow::stateChanged(Phonon::State newState, Phonon::State /* oldState */) {
+
+ // qDebug() << "Phonon state: " << newState;
+
+ switch (newState) {
+
+ case Phonon::ErrorState:
+ if (mediaObject->errorType() == Phonon::FatalError) {
+ statusBar()->showMessage(tr("Fatal error: %1").arg(mediaObject->errorString()));
+ } else {
+ statusBar()->showMessage(tr("Error: %1").arg(mediaObject->errorString()));
+ }
+ break;
+
+ case Phonon::PlayingState:
+ pauseAct->setEnabled(true);
+ pauseAct->setIcon(QtIconLoader::icon("media-playback-pause", QIcon(":/images/media-playback-pause.png")));
+ pauseAct->setText(tr("&Pause"));
+ pauseAct->setStatusTip(tr("Pause playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
+ skipAct->setEnabled(true);
+ break;
+
+ case Phonon::StoppedState:
+ pauseAct->setEnabled(false);
+ skipAct->setEnabled(false);
+ break;
+
+ case Phonon::PausedState:
+ skipAct->setEnabled(true);
+ pauseAct->setEnabled(true);
+ pauseAct->setIcon(QtIconLoader::icon("media-playback-start", QIcon(":/images/media-playback-start.png")));
+ pauseAct->setText(tr("&Play"));
+ pauseAct->setStatusTip(tr("Resume playback") + " (" + pauseAct->shortcut().toString(QKeySequence::NativeText) + ")");
+ break;
+
+ case Phonon::BufferingState:
+ case Phonon::LoadingState:
+ skipAct->setEnabled(true);
+ pauseAct->setEnabled(false);
+ currentTime->clear();
+ totalTime->clear();
+ break;
+
+ default:
+ ;
+ }
+}
+
+void MainWindow::stop() {
+ mediaView->stop();
+ showSearch();
+}
+
+void MainWindow::fullscreen() {
+
+ setUpdatesEnabled(false);
+
+ // No compact view action when in full screen
+ compactViewAct->setVisible(m_fullscreen);
+ compactViewAct->setChecked(false);
+
+ // Also no Youtube action since it opens a new window
+ webPageAct->setVisible(m_fullscreen);
+ copyPageAct->setVisible(m_fullscreen);
+ copyLinkAct->setVisible(m_fullscreen);
+
+ stopAct->setVisible(m_fullscreen);
+
+ // workaround: prevent focus on the search bar
+ // it steals the Space key needed for Play/Pause
+ mainToolBar->setEnabled(m_fullscreen);
+
+ // Hide anything but the video
+ mediaView->setPlaylistVisible(m_fullscreen);
+ statusBar()->setVisible(m_fullscreen);
+
+#ifndef Q_WS_MAC
+ menuBar()->setVisible(m_fullscreen);
+#endif
+
+#ifdef Q_WS_MAC
+ // make the actions work when video is fullscreen (on the Mac)
+ QMap<QString, QAction*> *actions = The::globalActions();
+ foreach (QAction *action, actions->values()) {
+ if (m_fullscreen) {
+ action->setShortcutContext(Qt::WindowShortcut);
+ } else {
+ action->setShortcutContext(Qt::ApplicationShortcut);
+ }
+ }
+#endif
+
+ if (m_fullscreen) {
+ // use setShortucs instead of setShortcut
+ // the latter seems not to work
+ fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::ALT + Qt::Key_Return));
+ fullscreenAct->setText(tr("&Full Screen"));
+ stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::Key_MediaStop));
+
+ mainToolBar->show();
+ if (m_maximized) showMaximized();
+ else showNormal();
+
+ // Make sure the window has focus (Mac)
+ activateWindow();
+
+ } else {
+ stopAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_MediaStop));
+ fullscreenAct->setShortcuts(QList<QKeySequence>() << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::ALT + Qt::Key_Return));
+ fullscreenAct->setText(tr("Exit &Full Screen"));
+ m_maximized = isMaximized();
+
+ // save geometry now, if the user quits when in full screen
+ // geometry won't be saved
+ writeSettings();
+
+ mainToolBar->hide();
+ showFullScreen();
+ }
+
+ m_fullscreen = !m_fullscreen;
+
+ setUpdatesEnabled(true);
+}
+
+void MainWindow::compactView(bool enable) {
+
+ setUpdatesEnabled(false);
+
+ mainToolBar->setVisible(!enable);
+ mainToolBar->setEnabled(!enable);
+ mediaView->setPlaylistVisible(!enable);
+ statusBar()->setVisible(!enable);
+
+#ifndef Q_WS_MAC
+ menuBar()->setVisible(!enable);
+#endif
+
+ // ensure focus does not end up to the search box
+ // as it would steal the Space shortcut
+ // toolbarSearch->setEnabled(!enable);
+
+ if (enable) {
+ stopAct->setShortcut(QString(""));
+ QList<QKeySequence> shortcuts;
+ // for some reason it is important that ESC comes first
+ shortcuts << QKeySequence(Qt::CTRL + Qt::Key_Return) << QKeySequence(Qt::Key_Escape);
+ compactViewAct->setShortcuts(shortcuts);
+ } else {
+ compactViewAct->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
+ stopAct->setShortcut(QKeySequence(Qt::Key_Escape));
+ }
+
+ setUpdatesEnabled(true);
+}
+
+void MainWindow::searchFocus() {
+ QWidget *view = views->currentWidget();
+ if (view == mediaView) {
+ toolbarSearch->selectAll();
+ toolbarSearch->setFocus();
+ }
+}
+
+void MainWindow::initPhonon() {
+ // Phonon initialization
+ if (mediaObject) delete mediaObject;
+ if (audioOutput) delete audioOutput;
+ mediaObject = new Phonon::MediaObject(this);
+ mediaObject->setTickInterval(100);
+ connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
+ this, SLOT(stateChanged(Phonon::State, Phonon::State)));
+ connect(mediaObject, SIGNAL(tick(qint64)), this, SLOT(tick(qint64)));
+ connect(mediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(totalTimeChanged(qint64)));
+ seekSlider->setMediaObject(mediaObject);
+ audioOutput = new Phonon::AudioOutput(Phonon::VideoCategory, this);
+ connect(audioOutput, SIGNAL(volumeChanged(qreal)), this, SLOT(volumeChanged(qreal)));
+ connect(audioOutput, SIGNAL(mutedChanged(bool)), this, SLOT(volumeMutedChanged(bool)));
+ volumeSlider->setAudioOutput(audioOutput);
+ Phonon::createPath(mediaObject, audioOutput);
+}
+
+void MainWindow::tick(qint64 time) {
+ if (time <= 0) {
+ currentTime->clear();
+ return;
+ }
+
+ currentTime->setText(formatTime(time));
+
+ // remaining time
+ const qint64 remainingTime = mediaObject->remainingTime();
+ currentTime->setStatusTip(tr("Remaining time: %1").arg(formatTime(remainingTime)));
+
+}
+
+void MainWindow::totalTimeChanged(qint64 time) {
+ if (time <= 0) {
+ totalTime->clear();
+ return;
+ }
+ totalTime->setText("/ " + formatTime(time));
+}
+
+QString MainWindow::formatTime(qint64 time) {
+ QTime displayTime;
+ displayTime = displayTime.addMSecs(time);
+ QString timeString;
+ // 60 * 60 * 1000 = 3600000
+ if (time > 3600000)
+ timeString = displayTime.toString("h:mm:ss");
+ else
+ timeString = displayTime.toString("m:ss");
+ return timeString;
+}
+
+void MainWindow::volumeUp() {
+ qreal newVolume = volumeSlider->audioOutput()->volume() + .1;
+ if (newVolume > volumeSlider->maximumVolume())
+ newVolume = volumeSlider->maximumVolume();
+ volumeSlider->audioOutput()->setVolume(newVolume);
+}
+
+void MainWindow::volumeDown() {
+ qreal newVolume = volumeSlider->audioOutput()->volume() - .1;
+ if (newVolume < 0)
+ newVolume = 0;
+ volumeSlider->audioOutput()->setVolume(newVolume);
+}
+
+void MainWindow::volumeMute() {
+ volumeSlider->audioOutput()->setMuted(!volumeSlider->audioOutput()->isMuted());
+}
+
+void MainWindow::volumeChanged(qreal newVolume) {
+ // automatically unmute when volume changes
+ if (volumeSlider->audioOutput()->isMuted())
+ volumeSlider->audioOutput()->setMuted(false);
+ statusBar()->showMessage(tr("Volume at %1%").arg(newVolume*100));
+}
+
+void MainWindow::volumeMutedChanged(bool muted) {
+ if (muted)
+ statusBar()->showMessage(tr("Volume is muted"));
+ else
+ statusBar()->showMessage(tr("Volume is unmuted"));
+}
+
+void MainWindow::setDefinitionMode(QString definitionName) {
+ QAction *definitionAct = The::globalActions()->value("definition");
+ definitionAct->setText(definitionName);
+ definitionAct->setStatusTip(tr("Maximum video definition set to %1").arg(definitionAct->text())
+ + " (" + definitionAct->shortcut().toString(QKeySequence::NativeText) + ")");
+ statusBar()->showMessage(definitionAct->statusTip());
+ QSettings settings;
+ settings.setValue("definition", definitionName);
+}
+
+void MainWindow::toggleDefinitionMode() {
+ QSettings settings;
+ QString currentDefinition = settings.value("definition").toString();
+ QStringList definitionNames = VideoDefinition::getDefinitionNames();
+ int currentIndex = definitionNames.indexOf(currentDefinition);
+ int nextIndex = 0;
+ if (currentIndex != definitionNames.size() - 1) {
+ nextIndex = currentIndex + 1;
+ }
+ QString nextDefinition = definitionNames.at(nextIndex);
+ setDefinitionMode(nextDefinition);
+}
+
+void MainWindow::showFullscreenToolbar(bool show) {
+ if (!m_fullscreen) return;
+
+ if (show) {
+ mainToolBar->show();
+ } else {
+ mainToolBar->hide();
+ }
+ mainToolBar->setEnabled(show);
+}
+
+void MainWindow::showFullscreenPlaylist(bool show) {
+ if (!m_fullscreen) return;
+ mediaView->setPlaylistVisible(show);
+}
+
+void MainWindow::clearRecentKeywords() {
+ QSettings settings;
+ settings.remove("recentKeywords");
+ searchView->updateRecentKeywords();
+ statusBar()->showMessage(tr("Your privacy is now safe"));
+}
--- /dev/null
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include <QtGui>
+#include "faderwidget/FaderWidget.h"
+#include "searchlineedit.h"
+#include <phonon/audiooutput.h>
+#include <phonon/volumeslider.h>
+#include <phonon/mediaobject.h>
+#include <phonon/seekslider.h>
+#include "View.h"
+#include "SearchView.h"
+#include "MediaView.h"
+#include "AboutView.h"
+
+class MainWindow : public QMainWindow {
+
+ Q_OBJECT
+
+public:
+ MainWindow();
+ ~MainWindow();
+
+protected:
+ void closeEvent(QCloseEvent *);
+ bool eventFilter(QObject *obj, QEvent *event);
+
+private slots:
+ void fadeInWidget(QWidget *oldWidget, QWidget *newWidget);
+ void goBack();
+ void showSearch();
+ void showMedia(QString query);
+ void visitSite();
+ void donate();
+ void about();
+ void quit();
+ void fullscreen();
+ void compactView(bool enable);
+ void stop();
+ void stateChanged(Phonon::State newState, Phonon::State oldState);
+ void searchFocus();
+ void tick(qint64 time);
+ void totalTimeChanged(qint64 time);
+ void setDefinitionMode(QString definitionName);
+ void toggleDefinitionMode();
+ void clearRecentKeywords();
+
+ // volume shortcuts
+ void volumeUp();
+ void volumeDown();
+ void volumeMute();
+ void volumeChanged(qreal newVolume);
+ void volumeMutedChanged(bool muted);
+
+ // fullscreen toolbar
+ void showFullscreenToolbar(bool show);
+ void showFullscreenPlaylist(bool show);
+
+private:
+ void initPhonon();
+ void createActions();
+ void createMenus();
+ void createToolBars();
+ void createStatusBar();
+ void readSettings();
+ void writeSettings();
+ void showWidget(QWidget*);
+ static QString formatTime(qint64 time);
+
+ // view mechanism
+ QPointer<FaderWidget> faderWidget;
+ QStackedWidget *views;
+ QStack<QWidget*> *history;
+
+ // view widgets
+ SearchView *searchView;
+ MediaView *mediaView;
+ QWidget *aboutView;
+
+ // actions
+ QAction *addGadgetAct;
+ QAction *backAct;
+ QAction *quitAct;
+ QAction *siteAct;
+ QAction *donateAct;
+ QAction *aboutAct;
+ QAction *searchFocusAct;
+
+ // media actions
+ QAction *skipAct;
+ QAction *pauseAct;
+ QAction *stopAct;
+ QAction *fullscreenAct;
+ QAction *compactViewAct;
+ QAction *webPageAct;
+ QAction *copyPageAct;
+ QAction *copyLinkAct;
+ QAction *downloadAct;
+ QAction *volumeUpAct;
+ QAction *volumeDownAct;
+ QAction *volumeMuteAct;
+
+ // playlist actions
+ QAction *removeAct;
+ QAction *moveDownAct;
+ QAction *moveUpAct;
+ QAction *fetchMoreAct;
+ QAction *clearAct;
+
+ // menus
+ QMenu *fileMenu;
+ QMenu *viewMenu;
+ QMenu *playlistMenu;
+ QMenu *helpMenu;
+
+ // toolbar
+ QToolBar *mainToolBar;
+ SearchLineEdit *toolbarSearch;
+
+ // phonon
+ Phonon::SeekSlider *seekSlider;
+ Phonon::VolumeSlider *volumeSlider;
+ Phonon::MediaObject *mediaObject;
+ Phonon::AudioOutput *audioOutput;
+ QLabel *currentTime;
+ QLabel *totalTime;
+
+ bool m_fullscreen;
+ bool m_maximized;
+
+};
+
+#endif
--- /dev/null
+#include "MediaView.h"
+#include "playlist/PrettyItemDelegate.h"
+#include "networkaccess.h"
+#include "videowidget.h"
+#include "minisplitter.h"
+#include "flickcharm.h"
+
+namespace The {
+ QMap<QString, QAction*>* globalActions();
+ QMap<QString, QMenu*>* globalMenus();
+ QNetworkAccessManager* networkAccessManager();
+}
+
+MediaView::MediaView(QWidget *parent) : QWidget(parent) {
+
+ reallyStopped = false;
+
+ QBoxLayout *layout = new QHBoxLayout();
+ layout->setMargin(0);
+
+ splitter = new MiniSplitter(this);
+ splitter->setChildrenCollapsible(false);
+
+ sortBar = new THBlackBar(this);
+ mostRelevantAction = new QAction(tr("Most relevant"), this);
+ QKeySequence keySequence(Qt::CTRL + Qt::Key_1);
+ mostRelevantAction->setShortcut(keySequence);
+ mostRelevantAction->setStatusTip(mostRelevantAction->text() + " (" + keySequence.toString(QKeySequence::NativeText) + ")");
+ addAction(mostRelevantAction);
+ connect(mostRelevantAction, SIGNAL(triggered()), this, SLOT(searchMostRelevant()), Qt::QueuedConnection);
+ sortBar->addAction(mostRelevantAction);
+ mostRecentAction = new QAction(tr("Most recent"), this);
+ keySequence = QKeySequence(Qt::CTRL + Qt::Key_2);
+ mostRecentAction->setShortcut(keySequence);
+ mostRecentAction->setStatusTip(mostRecentAction->text() + " (" + keySequence.toString(QKeySequence::NativeText) + ")");
+ addAction(mostRecentAction);
+ connect(mostRecentAction, SIGNAL(triggered()), this, SLOT(searchMostRecent()), Qt::QueuedConnection);
+ sortBar->addAction(mostRecentAction);
+ mostViewedAction = new QAction(tr("Most viewed"), this);
+ keySequence = QKeySequence(Qt::CTRL + Qt::Key_3);
+ mostViewedAction->setShortcut(keySequence);
+ mostViewedAction->setStatusTip(mostViewedAction->text() + " (" + keySequence.toString(QKeySequence::NativeText) + ")");
+ addAction(mostViewedAction);
+ connect(mostViewedAction, SIGNAL(triggered()), this, SLOT(searchMostViewed()), Qt::QueuedConnection);
+ sortBar->addAction(mostViewedAction);
+
+ listView = new QListView(this);
+ listView->setItemDelegate(new PrettyItemDelegate(this));
+ listView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+
+ // dragndrop
+ listView->setDragEnabled(true);
+ listView->setAcceptDrops(true);
+ listView->setDropIndicatorShown(true);
+ listView->setDragDropMode(QAbstractItemView::DragDrop);
+
+ // cosmetics
+ listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+ listView->setFrameShape( QFrame::NoFrame );
+ listView->setAttribute(Qt::WA_MacShowFocusRect, false);
+ listView->setMinimumSize(320,240);
+ listView->setUniformItemSizes(true);
+
+ // respond to the user doubleclicking a playlist item
+ connect(listView, SIGNAL(activated(const QModelIndex &)), this, SLOT(itemActivated(const QModelIndex &)));
+
+ listModel = new ListModel(this);
+ connect(listModel, SIGNAL(activeRowChanged(int)), this, SLOT(activeRowChanged(int)));
+ // needed to restore the selection after dragndrop
+ connect(listModel, SIGNAL(needSelectionFor(QList<Video*>)), this, SLOT(selectVideos(QList<Video*>)));
+ listView->setModel(listModel);
+
+ connect(listView->selectionModel(),
+ SIGNAL(selectionChanged ( const QItemSelection & , const QItemSelection & )),
+ this, SLOT(selectionChanged ( const QItemSelection & , const QItemSelection & )));
+
+ playlistWidget = new PlaylistWidget(this, sortBar, listView);
+
+ splitter->addWidget(playlistWidget);
+
+ videoAreaWidget = new VideoAreaWidget(this);
+ videoAreaWidget->setMinimumSize(320,240);
+
+#ifdef Q_WS_MAC
+ // mouse autohide does not work on the Mac (no mouseMoveEvent)
+ videoWidget = new Phonon::VideoWidget(this);
+#else
+ videoWidget = new VideoWidget(this);
+#endif
+
+ videoAreaWidget->setVideoWidget(videoWidget);
+ videoAreaWidget->setListModel(listModel);
+
+ loadingWidget = new LoadingWidget(this);
+ videoAreaWidget->setLoadingWidget(loadingWidget);
+
+ splitter->addWidget(videoAreaWidget);
+
+ layout->addWidget(splitter);
+ setLayout(layout);
+
+ // restore splitter state
+ QSettings settings;
+ splitter->restoreState(settings.value("splitter").toByteArray());
+
+ errorTimer = new QTimer(this);
+ errorTimer->setSingleShot(true);
+ errorTimer->setInterval(3000);
+ connect(errorTimer, SIGNAL(timeout()), SLOT(skipVideo()));
+
+ workaroundTimer = new QTimer(this);
+ workaroundTimer->setSingleShot(true);
+ workaroundTimer->setInterval(3000);
+ connect(workaroundTimer, SIGNAL(timeout()), SLOT(timerPlay()));
+
+ // TODO Enable this on touch devices
+ // FlickCharm *flickCharm = new FlickCharm(this);
+ // flickCharm->activateOn(listView);
+
+}
+
+MediaView::~MediaView() {
+
+}
+
+void MediaView::initialize() {
+ connect(videoAreaWidget, SIGNAL(doubleClicked()), The::globalActions()->value("fullscreen"), SLOT(trigger()));
+ videoAreaWidget->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(videoAreaWidget, SIGNAL(customContextMenuRequested(QPoint)),
+ this, SLOT(showVideoContextMenu(QPoint)));
+}
+
+void MediaView::setMediaObject(Phonon::MediaObject *mediaObject) {
+ this->mediaObject = mediaObject;
+ Phonon::createPath(this->mediaObject, videoWidget);
+ connect(mediaObject, SIGNAL(finished()), this, SLOT(skip()));
+ connect(mediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)),
+ this, SLOT(stateChanged(Phonon::State, Phonon::State)));
+ connect(mediaObject, SIGNAL(currentSourceChanged(Phonon::MediaSource)),
+ this, SLOT(currentSourceChanged(Phonon::MediaSource)));
+ connect(mediaObject, SIGNAL(bufferStatus(int)), loadingWidget, SLOT(bufferStatus(int)));
+}
+
+void MediaView::search(SearchParams *searchParams) {
+ reallyStopped = false;
+
+ videoAreaWidget->clear();
+ workaroundTimer->stop();
+ errorTimer->stop();
+
+ this->searchParams = searchParams;
+
+ // start serching for videos
+ listModel->search(searchParams);
+
+ // this implies that the enum and the bar action order is the same
+ sortBar->setCheckedAction(searchParams->sortBy()-1);
+
+ listView->setFocus();
+
+}
+
+void MediaView::disappear() {
+ timerPlayFlag = true;
+}
+
+void MediaView::handleError(QString message) {
+ videoAreaWidget->showError(message);
+ skippedVideo = listModel->activeVideo();
+ // recover from errors by skipping to the next video
+ errorTimer->start(2000);
+}
+
+void MediaView::stateChanged(Phonon::State newState, Phonon::State /*oldState*/)
+{
+
+ // qDebug() << "Phonon state: " << newState << oldState;
+
+ switch (newState) {
+
+ case Phonon::ErrorState:
+ qDebug() << "Phonon error:" << mediaObject->errorString() << mediaObject->errorType();
+ handleError(mediaObject->errorString());
+ break;
+
+ case Phonon::PlayingState:
+ //qDebug("playing");
+ videoAreaWidget->showVideo();
+ break;
+
+ case Phonon::StoppedState:
+ //qDebug("stopped");
+ // play() has already been called when setting the source
+ // but Phonon on Linux needs a little more help to start playback
+ if (!reallyStopped) mediaObject->play();
+
+#ifdef Q_WS_MAC
+ // Workaround for Mac playback start problem
+ if (!timerPlayFlag) {
+ workaroundTimer->start();
+ }
+#endif
+
+ break;
+
+ case Phonon::PausedState:
+ //qDebug("paused");
+ break;
+
+ case Phonon::BufferingState:
+ //qDebug("buffering");
+ break;
+
+ case Phonon::LoadingState:
+ //qDebug("loading");
+ break;
+
+ default:
+ ;
+ }
+}
+
+void MediaView::pause() {
+ // qDebug() << "pause() called" << mediaObject->state();
+ switch( mediaObject->state() ) {
+ case Phonon::PlayingState:
+ mediaObject->pause();
+ break;
+ default:
+ mediaObject->play();
+ break;
+ }
+}
+
+void MediaView::stop() {
+ listModel->abortSearch();
+ reallyStopped = true;
+ mediaObject->stop();
+ videoAreaWidget->clear();
+ workaroundTimer->stop();
+ errorTimer->stop();
+ listView->selectionModel()->clearSelection();
+}
+
+void MediaView::activeRowChanged(int row) {
+ if (reallyStopped) return;
+
+ Video *video = listModel->videoAt(row);
+ if (!video) return;
+
+ // now that we have a new video to play
+ // stop all the timers
+ workaroundTimer->stop();
+ errorTimer->stop();
+
+ // immediately show the loading widget
+ videoAreaWidget->showLoading(video);
+
+ connect(video, SIGNAL(gotStreamUrl(QUrl)), SLOT(gotStreamUrl(QUrl)));
+ // TODO handle signal in a proper slot and impl item error status
+ connect(video, SIGNAL(errorStreamUrl(QString)), SLOT(handleError(QString)));
+
+ video->loadStreamUrl();
+
+ // reset the timer flag
+ timerPlayFlag = false;
+
+ // video title in the statusbar
+ QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(window());
+ if (mainWindow) mainWindow->statusBar()->showMessage(video->title());
+
+ // see you in gotStreamUrl...
+
+}
+
+void MediaView::gotStreamUrl(QUrl streamUrl) {
+ if (reallyStopped) return;
+
+ // go!
+ mediaObject->setCurrentSource(streamUrl);
+ mediaObject->play();
+
+ // ensure we always have 10 videos ahead
+ listModel->searchNeeded();
+
+ // ensure active item is visible
+ int row = listModel->activeRow();
+ if (row != -1) {
+ QModelIndex index = listModel->index(row, 0, QModelIndex());
+ listView->scrollTo(index, QAbstractItemView::EnsureVisible);
+ }
+}
+
+void MediaView::itemActivated(const QModelIndex &index) {
+ if (listModel->rowExists(index.row()))
+ listModel->setActiveRow(index.row());
+ // the user doubleclicked on the "Search More" item
+ else listModel->searchMore();
+}
+
+void MediaView::currentSourceChanged(const Phonon::MediaSource source) {
+ qDebug() << "Playing" << source.url().toString();
+}
+
+void MediaView::skipVideo() {
+ // skippedVideo is useful for DELAYED skip operations
+ // in order to be sure that we're skipping the video we wanted
+ // and not another one
+ if (skippedVideo) {
+ if (listModel->activeVideo() != skippedVideo) {
+ qDebug() << "Skip of video canceled";
+ return;
+ }
+ int nextRow = listModel->rowForVideo(skippedVideo);
+ nextRow++;
+ if (nextRow == -1) return;
+ listModel->setActiveRow(nextRow);
+ }
+}
+
+void MediaView::skip() {
+ int nextRow = listModel->nextRow();
+ if (nextRow == -1) return;
+ listModel->setActiveRow(nextRow);
+}
+
+void MediaView::openWebPage() {
+ Video* video = listModel->activeVideo();
+ if (!video) return;
+ mediaObject->pause();
+ QDesktopServices::openUrl(video->webpage());
+}
+
+void MediaView::copyWebPage() {
+ Video* video = listModel->activeVideo();
+ if (!video) return;
+ QString address = video->webpage().toString();
+ address.remove("&feature=youtube_gdata");
+ QApplication::clipboard()->setText(address);
+ QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(window());
+ QString message = tr("You can now paste the YouTube link into another application");
+ if (mainWindow) mainWindow->statusBar()->showMessage(message);
+}
+
+void MediaView::copyVideoLink() {
+ Video* video = listModel->activeVideo();
+ if (!video) return;
+ QApplication::clipboard()->setText(video->getStreamUrl().toString());
+ QString message = tr("You can now paste the video stream URL into another application")
+ + ". " + tr("The link will be valid only for a limited time.");
+ QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(window());
+ if (mainWindow) mainWindow->statusBar()->showMessage(message);
+}
+
+void MediaView::removeSelected() {
+ if (!listView->selectionModel()->hasSelection()) return;
+ QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
+ listModel->removeIndexes(indexes);
+}
+
+void MediaView::selectVideos(QList<Video*> videos) {
+ foreach (Video *video, videos) {
+ QModelIndex index = listModel->indexForVideo(video);
+ listView->selectionModel()->select(index, QItemSelectionModel::Select);
+ listView->scrollTo(index, QAbstractItemView::EnsureVisible);
+ }
+}
+
+void MediaView::selectionChanged(const QItemSelection & /*selected*/, const QItemSelection & /*deselected*/) {
+ const bool gotSelection = listView->selectionModel()->hasSelection();
+ The::globalActions()->value("remove")->setEnabled(gotSelection);
+ The::globalActions()->value("moveUp")->setEnabled(gotSelection);
+ The::globalActions()->value("moveDown")->setEnabled(gotSelection);
+}
+
+void MediaView::moveUpSelected() {
+ if (!listView->selectionModel()->hasSelection()) return;
+ QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
+ listModel->move(indexes, true);
+}
+
+void MediaView::moveDownSelected() {
+ if (!listView->selectionModel()->hasSelection()) return;
+ QModelIndexList indexes = listView->selectionModel()->selectedIndexes();
+ listModel->move(indexes, false);
+}
+
+void MediaView::showVideoContextMenu(QPoint point) {
+ The::globalMenus()->value("video")->popup(videoWidget->mapToGlobal(point));
+}
+
+void MediaView::searchMostRelevant() {
+ searchParams->setSortBy(SearchParams::SortByRelevance);
+ search(searchParams);
+}
+
+void MediaView::searchMostRecent() {
+ searchParams->setSortBy(SearchParams::SortByNewest);
+ search(searchParams);
+}
+
+void MediaView::searchMostViewed() {
+ searchParams->setSortBy(SearchParams::SortByViewCount);
+ search(searchParams);
+}
+
+void MediaView::setPlaylistVisible(bool visible) {
+ playlistWidget->setVisible(visible);
+}
+
+void MediaView::timerPlay() {
+ // Workaround Phonon bug on Mac OSX
+ // qDebug() << mediaObject->currentTime();
+ if (mediaObject->currentTime() <= 0 && mediaObject->state() == Phonon::PlayingState) {
+ // qDebug() << "Mac playback workaround";
+ mediaObject->pause();
+ // QTimer::singleShot(1000, mediaObject, SLOT(play()));
+ mediaObject->play();
+ }
+}
+
+void MediaView::saveSplitterState() {
+ QSettings settings;
+ settings.setValue("splitter", splitter->saveState());
+}
--- /dev/null
+#ifndef __MEDIAVIEW_H__
+#define __MEDIAVIEW_H__
+
+#include <QtGui>
+#include <QtNetwork>
+#include <phonon/mediaobject.h>
+#include <phonon/videowidget.h>
+#include "View.h"
+#include "ListModel.h"
+#include "thblackbar.h"
+#include "searchparams.h"
+#include "playlistwidget.h"
+#include "loadingwidget.h"
+#include "videoareawidget.h"
+
+class MediaView : public QWidget, public View {
+ Q_OBJECT
+
+public:
+ MediaView(QWidget *parent);
+ ~MediaView();
+ void initialize();
+
+ // View
+ void appear() {}
+ void disappear();
+ QMap<QString, QVariant> metadata() {
+ QMap<QString, QVariant> metadata;
+ if (searchParams) {
+ metadata.insert("title", searchParams->keywords());
+ metadata.insert("description", tr("You're watching \"%1\"").arg(searchParams->keywords()));
+ }
+ return metadata;
+ }
+
+ void setMediaObject(Phonon::MediaObject *mediaObject);
+
+public slots:
+ void search(SearchParams *searchParams);
+ void pause();
+ void stop();
+ void skip();
+ void skipVideo();
+ void openWebPage();
+ void copyWebPage();
+ void copyVideoLink();
+ void removeSelected();
+ void moveUpSelected();
+ void moveDownSelected();
+ void setPlaylistVisible(bool visible=true);
+ void saveSplitterState();
+
+private slots:
+ // list/model
+ void itemActivated(const QModelIndex &index);
+ void selectionChanged (const QItemSelection & selected, const QItemSelection & deselected);
+ void activeRowChanged(int);
+ void selectVideos(QList<Video*> videos);
+ void gotStreamUrl(QUrl streamUrl);
+ void handleError(QString message);
+ // phonon
+ void stateChanged(Phonon::State newState, Phonon::State oldState);
+ void currentSourceChanged(const Phonon::MediaSource source);
+ void showVideoContextMenu(QPoint point);
+ // bar
+ void searchMostRelevant();
+ void searchMostRecent();
+ void searchMostViewed();
+ // timer
+ void timerPlay();
+
+private:
+
+ SearchParams *searchParams;
+
+ QSplitter *splitter;
+
+ PlaylistWidget *playlistWidget;
+ QListView *listView;
+ ListModel *listModel;
+
+ // sortBar
+ THBlackBar *sortBar;
+ QAction *mostRelevantAction;
+ QAction *mostRecentAction;
+ QAction *mostViewedAction;
+
+ // phonon
+ Phonon::MediaObject *mediaObject;
+ Phonon::VideoWidget *videoWidget;
+
+ // loadingWidget
+ VideoAreaWidget *videoAreaWidget;
+ LoadingWidget *loadingWidget;
+
+ bool timerPlayFlag;
+ bool reallyStopped;
+
+ QTimer *errorTimer;
+ QTimer *workaroundTimer;
+ Video *skippedVideo;
+
+};
+
+#endif // __MEDIAVIEW_H__
--- /dev/null
+#include "SearchView.h"
+#include "Constants.h"
+
+namespace The {
+ QMap<QString, QAction*>* globalActions();
+}
+
+static const QString recentKeywordsKey = "recentKeywords";
+static const int PADDING = 30;
+
+SearchView::SearchView(QWidget *parent) : QWidget(parent) {
+
+ QFont biggerFont;
+ biggerFont.setPointSize(biggerFont.pointSize()*1.5);
+
+ QFont smallerFont;
+ smallerFont.setPointSize(smallerFont.pointSize()*.85);
+ smallerFont.setBold(true);
+
+ QBoxLayout *mainLayout = new QVBoxLayout();
+ mainLayout->setMargin(0);
+ mainLayout->setSpacing(0);
+
+ // hidden message widget
+ message = new QLabel(this);
+ message->hide();
+ mainLayout->addWidget(message);
+
+ mainLayout->addStretch();
+
+ QBoxLayout *hLayout = new QHBoxLayout();
+ hLayout->setAlignment(Qt::AlignCenter);
+ mainLayout->addLayout(hLayout);
+
+ QLabel *logo = new QLabel(this);
+ logo->setPixmap(QPixmap(":/images/app.png"));
+ hLayout->addWidget(logo, 0, Qt::AlignTop);
+ hLayout->addSpacing(PADDING);
+
+ QVBoxLayout *layout = new QVBoxLayout();
+ layout->setAlignment(Qt::AlignCenter);
+ hLayout->addLayout(layout);
+
+ QLabel *welcomeLabel =
+ new QLabel("<h1>" +
+ tr("Welcome to <a href='%1'>%2</a>,")
+ .replace("<a ", "<a style='color:palette(text)'")
+ .arg(Constants::WEBSITE, Constants::APP_NAME)
+ + "</h1>", this);
+ welcomeLabel->setOpenExternalLinks(true);
+ layout->addWidget(welcomeLabel);
+
+ layout->addSpacing(PADDING);
+
+ QLabel *tipLabel = new QLabel(tr("Enter a keyword to start watching videos."), this);
+ tipLabel->setFont(biggerFont);
+ layout->addWidget(tipLabel);
+
+ layout->addSpacing(10);
+
+ QHBoxLayout *searchLayout = new QHBoxLayout();
+ searchLayout->setAlignment(Qt::AlignVCenter);
+
+ queryEdit = new SearchLineEdit(this);
+ queryEdit->setFont(biggerFont);
+ queryEdit->setMinimumWidth(queryEdit->fontInfo().pixelSize()*15);
+ queryEdit->sizeHint();
+ queryEdit->setFocus(Qt::OtherFocusReason);
+ connect(queryEdit, SIGNAL(search(const QString&)), this, SLOT(watch(const QString&)));
+ connect(queryEdit, SIGNAL(textChanged(const QString &)), this, SLOT(textChanged(const QString &)));
+ searchLayout->addWidget(queryEdit);
+
+ searchLayout->addSpacing(10);
+
+ watchButton = new QPushButton(tr("Watch"), this);
+ watchButton->setDefault(true);
+ watchButton->setEnabled(false);
+ watchButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ connect(watchButton, SIGNAL(clicked()), this, SLOT(watch()));
+ searchLayout->addWidget(watchButton);
+
+ layout->addItem(searchLayout);
+
+ layout->addSpacing(PADDING);
+
+ QHBoxLayout *otherLayout = new QHBoxLayout();
+
+ recentKeywordsLayout = new QVBoxLayout();
+ recentKeywordsLayout->setSpacing(5);
+ recentKeywordsLayout->setAlignment(Qt::AlignVCenter | Qt::AlignLeft);
+ recentKeywordsLabel = new QLabel(tr("Recent keywords").toUpper(), this);
+ recentKeywordsLabel->hide();
+ recentKeywordsLabel->setForegroundRole(QPalette::Dark);
+ recentKeywordsLabel->setFont(smallerFont);
+ recentKeywordsLayout->addWidget(recentKeywordsLabel);
+
+ otherLayout->addLayout(recentKeywordsLayout);
+
+ layout->addLayout(otherLayout);
+
+ mainLayout->addStretch();
+
+ setLayout(mainLayout);
+
+ updateChecker = 0;
+ checkForUpdate();
+}
+
+void SearchView::updateRecentKeywords() {
+
+ // cleanup
+ QLayoutItem *item;
+ while ((item = recentKeywordsLayout->takeAt(1)) != 0) {
+ item->widget()->close();
+ delete item;
+ }
+
+ // load
+ QSettings settings;
+ QStringList keywords = settings.value(recentKeywordsKey).toStringList();
+ recentKeywordsLabel->setVisible(!keywords.isEmpty());
+ The::globalActions()->value("clearRecentKeywords")->setEnabled(!keywords.isEmpty());
+
+ foreach (QString keyword, keywords) {
+ QLabel *itemLabel = new QLabel("<a href=\"" + keyword
+ + "\" style=\"color:palette(text); text-decoration:none\">"
+ + keyword + "</a>", this);
+
+ itemLabel->setMaximumWidth(queryEdit->width() + watchButton->width());
+ // itemLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ // Make links navigable with the keyboard too
+ itemLabel->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
+
+ connect(itemLabel, SIGNAL(linkActivated(QString)), this, SLOT(watch(QString)));
+ recentKeywordsLayout->addWidget(itemLabel);
+ }
+
+}
+
+
+
+void SearchView::watch() {
+ QString query = queryEdit->text().simplified();
+ watch(query);
+}
+
+void SearchView::textChanged(const QString &text) {
+ watchButton->setEnabled(!text.simplified().isEmpty());
+}
+
+void SearchView::watch(QString query) {
+
+ // check for empty query
+ if (query.length() == 0) {
+ queryEdit->setFocus(Qt::OtherFocusReason);
+ return;
+ }
+
+ // go!
+ emit search(query);
+}
+
+void SearchView::checkForUpdate() {
+ static const QString updateCheckKey = "updateCheck";
+
+ // check every 24h
+ QSettings settings;
+ uint unixTime = QDateTime::currentDateTime().toTime_t();
+ int lastCheck = settings.value(updateCheckKey).toInt();
+ int secondsSinceLastCheck = unixTime - lastCheck;
+ // qDebug() << "secondsSinceLastCheck" << unixTime << lastCheck << secondsSinceLastCheck;
+ if (secondsSinceLastCheck < 86400) return;
+
+ // check it out
+ if (updateChecker) delete updateChecker;
+ updateChecker = new UpdateChecker();
+ connect(updateChecker, SIGNAL(newVersion(QString)),
+ this, SLOT(gotNewVersion(QString)));
+ updateChecker->checkForUpdate();
+ settings.setValue(updateCheckKey, unixTime);
+
+}
+
+void SearchView::gotNewVersion(QString version) {
+ message->setText(
+ tr("A new version of %1 is available. Please <a href='%2'>update to version %3</a>")
+ .arg(
+ Constants::APP_NAME,
+ QString(Constants::WEBSITE).append("#download"),
+ version)
+ );
+ message->setOpenExternalLinks(true);
+ message->setMargin(10);
+ message->setBackgroundRole(QPalette::ToolTipBase);
+ message->setForegroundRole(QPalette::ToolTipText);
+ message->setAutoFillBackground(true);
+ message->show();
+ if (updateChecker) delete updateChecker;
+}
--- /dev/null
+#ifndef __SEARCHVIEW_H__
+#define __SEARCHVIEW_H__
+
+#include <QtGui>
+#include "View.h"
+#include "searchlineedit.h"
+#include "updatechecker.h"
+
+class SearchView : public QWidget, public View {
+
+ Q_OBJECT
+
+public:
+ SearchView(QWidget *parent);
+ void updateRecentKeywords();
+
+ void appear() {
+ updateRecentKeywords();
+ queryEdit->clear();
+ queryEdit->setFocus(Qt::OtherFocusReason);
+ queryEdit->enableSuggest();
+ }
+
+ void disappear() {}
+
+ QMap<QString, QVariant> metadata() {
+ QMap<QString, QVariant> metadata;
+ metadata.insert("title", "");
+ metadata.insert("description", tr("Make yourself comfortable"));
+ return metadata;
+ }
+
+public slots:
+ void watch(QString query);
+ void gotNewVersion(QString version);
+
+signals:
+ void search(QString query);
+
+private slots:
+ void watch();
+ void textChanged(const QString &text);
+
+private:
+ void checkForUpdate();
+
+ SearchLineEdit *queryEdit;
+ QLabel *recentKeywordsLabel;
+ QVBoxLayout *recentKeywordsLayout;
+ QLabel *message;
+ QPushButton *watchButton;
+
+ UpdateChecker *updateChecker;
+
+};
+
+#endif // __SEARCHVIEW_H__
--- /dev/null
+#ifndef VIEW_H
+#define VIEW_H
+
+class View {
+
+ public:
+ virtual QMap<QString, QVariant> metadata() = 0;
+ virtual void appear() = 0;
+ virtual void disappear() = 0;
+
+};
+
+#endif // VIEW_H
--- /dev/null
+#include "FaderWidget.h"
+
+// http://labs.trolltech.com/blogs/2007/08/21/fade-effects-a-blast-from-the-past/
+
+FaderWidget::FaderWidget(QWidget *parent) : QWidget(parent) {
+ timeLine = new QTimeLine(250, this);
+ timeLine->setFrameRange(1000, 0);
+ connect(timeLine, SIGNAL(frameChanged(int)), this, SLOT(update()));
+ setAttribute(Qt::WA_DeleteOnClose);
+ resize(parent->size());
+}
+
+void FaderWidget::start(QPixmap frozenView) {
+ this->frozenView = frozenView;
+ timeLine->start();
+ show();
+}
+
+void FaderWidget::paintEvent(QPaintEvent *) {
+ const qreal opacity = timeLine->currentFrame() / 1000.;
+ QPainter painter(this);
+ painter.setOpacity(opacity);
+ painter.drawPixmap(0, 0, frozenView);
+ // qDebug() << opacity;
+
+ if (opacity <= 0.)
+ close();
+
+}
--- /dev/null
+#ifndef FADERWIDGET_H
+#define FADERWIDGET_H
+
+#include <QtGui>
+
+class FaderWidget : public QWidget {
+
+ Q_OBJECT
+ Q_PROPERTY(int fadeDuration READ fadeDuration WRITE setFadeDuration)
+
+public:
+
+ FaderWidget(QWidget *parent);
+
+ int fadeDuration() const {
+ return timeLine->duration();
+ }
+ void setFadeDuration(int milliseconds) {
+ timeLine->setDuration(milliseconds);
+ }
+ void start(QPixmap frozenView);
+
+protected:
+ void paintEvent(QPaintEvent *event);
+
+private:
+ QTimeLine *timeLine;
+ QPixmap frozenView;
+
+};
+
+#endif
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Graphics Dojo project on Qt Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 or 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#include "flickcharm.h"
+
+#include <QAbstractScrollArea>
+#include <QApplication>
+#include <QBasicTimer>
+#include <QEvent>
+#include <QHash>
+#include <QList>
+#include <QMouseEvent>
+#include <QScrollBar>
+
+#include <QDebug>
+
+struct FlickData {
+ typedef enum { Steady, Pressed, ManualScroll, AutoScroll, Stop } State;
+ State state;
+ QWidget *widget;
+ QPoint pressPos;
+ QPoint offset;
+ QPoint dragPos;
+ QPoint speed;
+ QList<QEvent*> ignored;
+};
+
+class FlickCharmPrivate
+{
+public:
+ QHash<QWidget*, FlickData*> flickData;
+ QBasicTimer ticker;
+};
+
+FlickCharm::FlickCharm(QObject *parent): QObject(parent)
+{
+ d = new FlickCharmPrivate;
+}
+
+FlickCharm::~FlickCharm()
+{
+ delete d;
+}
+
+void FlickCharm::activateOn(QWidget *widget)
+{
+ QAbstractScrollArea *scrollArea = dynamic_cast<QAbstractScrollArea*>(widget);
+ if (scrollArea) {
+ scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+
+ QWidget *viewport = scrollArea->viewport();
+
+ viewport->installEventFilter(this);
+ scrollArea->installEventFilter(this);
+
+ d->flickData.remove(viewport);
+ d->flickData[viewport] = new FlickData;
+ d->flickData[viewport]->widget = widget;
+ d->flickData[viewport]->state = FlickData::Steady;
+
+ return;
+ }
+
+ qWarning() << "FlickCharm only works on QAbstractScrollArea (and derived classes)";
+}
+
+void FlickCharm::deactivateFrom(QWidget *widget)
+{
+ QAbstractScrollArea *scrollArea = dynamic_cast<QAbstractScrollArea*>(widget);
+ if (scrollArea) {
+ QWidget *viewport = scrollArea->viewport();
+
+ viewport->removeEventFilter(this);
+ scrollArea->removeEventFilter(this);
+
+ delete d->flickData[viewport];
+ d->flickData.remove(viewport);
+
+ return;
+ }
+}
+
+static QPoint scrollOffset(QWidget *widget)
+{
+ int x = 0, y = 0;
+
+ QAbstractScrollArea *scrollArea = dynamic_cast<QAbstractScrollArea*>(widget);
+ if (scrollArea) {
+ x = scrollArea->horizontalScrollBar()->value();
+ y = scrollArea->verticalScrollBar()->value();
+ }
+
+ return QPoint(x, y);
+}
+
+static void setScrollOffset(QWidget *widget, const QPoint &p)
+{
+ QAbstractScrollArea *scrollArea = dynamic_cast<QAbstractScrollArea*>(widget);
+ if (scrollArea) {
+ scrollArea->horizontalScrollBar()->setValue(p.x());
+ scrollArea->verticalScrollBar()->setValue(p.y());
+ }
+}
+
+static QPoint deaccelerate(const QPoint &speed, int a = 1, int max = 64)
+{
+ int x = qBound(-max, speed.x(), max);
+ int y = qBound(-max, speed.y(), max);
+ x = (x == 0) ? x : (x > 0) ? qMax(0, x - a) : qMin(0, x + a);
+ y = (y == 0) ? y : (y > 0) ? qMax(0, y - a) : qMin(0, y + a);
+ return QPoint(x, y);
+}
+
+bool FlickCharm::eventFilter(QObject *object, QEvent *event)
+{
+
+ if (!object->isWidgetType())
+ return false;
+
+ QEvent::Type type = event->type();
+ if (type != QEvent::MouseButtonPress &&
+ type != QEvent::MouseButtonRelease &&
+ type != QEvent::MouseMove)
+ return false;
+
+ QMouseEvent *mouseEvent = dynamic_cast<QMouseEvent*>(event);
+ if (!mouseEvent || mouseEvent->modifiers() != Qt::NoModifier)
+ return false;
+
+ QWidget *viewport = dynamic_cast<QWidget*>(object);
+ FlickData *data = d->flickData.value(viewport);
+ if (!viewport || !data || data->ignored.removeAll(event))
+ return false;
+
+ QWidget *scrollArea = dynamic_cast<QWidget*>(object);
+
+ bool consumed = false;
+ switch (data->state) {
+
+ case FlickData::Steady:
+ if (mouseEvent->type() == QEvent::MouseButtonPress)
+ if (mouseEvent->buttons() == Qt::LeftButton) {
+ consumed = true;
+ data->state = FlickData::Pressed;
+ data->pressPos = mouseEvent->pos();
+ data->offset = scrollOffset(data->widget);
+ }
+ break;
+
+ case FlickData::Pressed:
+ if (mouseEvent->type() == QEvent::MouseButtonRelease) {
+ consumed = true;
+ data->state = FlickData::Steady;
+
+ QMouseEvent *event1 = new QMouseEvent(QEvent::MouseButtonPress,
+ data->pressPos, Qt::LeftButton,
+ Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent *event2 = new QMouseEvent(*mouseEvent);
+
+ data->ignored << event1;
+ data->ignored << event2;
+ QApplication::postEvent(object, event1);
+ QApplication::postEvent(object, event2);
+ }
+ if (mouseEvent->type() == QEvent::MouseMove) {
+
+ consumed = true;
+ data->state = FlickData::ManualScroll;
+ data->dragPos = QCursor::pos();
+ if (!d->ticker.isActive())
+ d->ticker.start(20, this);
+
+ }
+ break;
+
+ case FlickData::ManualScroll:
+ if (mouseEvent->type() == QEvent::MouseMove) {
+ QPoint pos = scrollArea->mapFromGlobal(QCursor::pos());
+ if (pos.x() > scrollArea->width() || pos.x() < 0) {
+ pos.setX(1);
+ QMouseEvent *event1 = new QMouseEvent(QEvent::MouseButtonPress,
+ pos, Qt::LeftButton,
+ Qt::LeftButton, Qt::NoModifier);
+ QMouseEvent *event2 = new QMouseEvent(QEvent::MouseMove,
+ pos, Qt::LeftButton,
+ Qt::LeftButton, Qt::NoModifier);
+
+ data->ignored << event1;
+ data->ignored << event2;
+ QApplication::postEvent(object, event1);
+ QApplication::postEvent(object, event2);
+ data->state = FlickData::Steady;
+ consumed = true;
+ } else {
+ consumed = true;
+ QPoint delta = mouseEvent->pos() - data->pressPos;
+ setScrollOffset(data->widget, data->offset - delta);
+ }
+ }
+ if (mouseEvent->type() == QEvent::MouseButtonRelease) {
+ consumed = true;
+ data->state = FlickData::AutoScroll;
+ }
+ break;
+
+ case FlickData::AutoScroll:
+ if (mouseEvent->type() == QEvent::MouseButtonPress) {
+ consumed = true;
+ data->state = FlickData::Stop;
+ data->speed = QPoint(0, 0);
+ data->pressPos = mouseEvent->pos();
+ data->offset = scrollOffset(data->widget);
+ }
+ if (mouseEvent->type() == QEvent::MouseButtonRelease) {
+ consumed = true;
+ data->state = FlickData::Steady;
+ data->speed = QPoint(0, 0);
+ }
+ break;
+
+ case FlickData::Stop:
+ if (mouseEvent->type() == QEvent::MouseButtonRelease) {
+ consumed = true;
+ data->state = FlickData::Steady;
+ }
+ if (mouseEvent->type() == QEvent::MouseMove) {
+ consumed = true;
+ data->state = FlickData::ManualScroll;
+ data->dragPos = QCursor::pos();
+ if (!d->ticker.isActive())
+ d->ticker.start(20, this);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return consumed;
+}
+
+void FlickCharm::timerEvent(QTimerEvent *event)
+{
+ int count = 0;
+ QHashIterator<QWidget*, FlickData*> item(d->flickData);
+ while (item.hasNext()) {
+ item.next();
+ FlickData *data = item.value();
+
+ const bool scrolling = data->state == FlickData::ManualScroll || data->state == FlickData::AutoScroll;
+ scrollBarShow(data->widget, scrolling);
+ // data->widget->setUpdatesEnabled(!scrolling);
+
+ if (data->state == FlickData::ManualScroll) {
+ count++;
+ data->speed = QCursor::pos() - data->dragPos;
+ data->dragPos = QCursor::pos();
+ }
+
+ if (data->state == FlickData::AutoScroll) {
+ count++;
+ data->speed = deaccelerate(data->speed);
+ QPoint p = scrollOffset(data->widget);
+ setScrollOffset(data->widget, p - data->speed);
+ if (data->speed == QPoint(0, 0))
+ data->state = FlickData::Steady;
+ }
+ }
+
+ if (!count)
+ d->ticker.stop();
+
+ QObject::timerEvent(event);
+}
+
+void FlickCharm::showScrollBars(QWidget *widget) {
+ QAbstractScrollArea *scrollArea = dynamic_cast<QAbstractScrollArea*>(widget);
+ if (scrollArea) {
+ // scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ }
+}
+
+void FlickCharm::hideScrollBars(QWidget *widget) {
+ QAbstractScrollArea *scrollArea = dynamic_cast<QAbstractScrollArea*>(widget);
+ if (scrollArea) {
+ scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ }
+}
+
+void FlickCharm::scrollBarShow(QWidget *widget, bool show) {
+ static bool shown = false;
+
+ if (show) {
+ if (!shown) {
+ showScrollBars(widget);
+ shown = true;
+ }
+ } else {
+ if (shown) {
+ hideScrollBars(widget);
+ shown = false;
+ }
+ }
+}
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the Graphics Dojo project on Qt Labs.
+**
+** This file may be used under the terms of the GNU General Public
+** License version 2.0 or 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of
+** this file. Please review the following information to ensure GNU
+** General Public Licensing requirements will be met:
+** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+**
+****************************************************************************/
+
+#ifndef FLICKCHARM_H
+#define FLICKCHARM_H
+
+#include <QObject>
+
+class FlickCharmPrivate;
+class QWidget;
+
+class FlickCharm: public QObject
+{
+ Q_OBJECT
+public:
+ FlickCharm(QObject *parent = 0);
+ ~FlickCharm();
+ void activateOn(QWidget *widget);
+ void deactivateFrom(QWidget *widget);
+ bool eventFilter(QObject *object, QEvent *event);
+
+protected:
+ void timerEvent(QTimerEvent *event);
+
+private:
+ void scrollBarShow(QWidget *widget, bool show);
+ void hideScrollBars(QWidget *widget);
+ void showScrollBars(QWidget *widget);
+ FlickCharmPrivate *d;
+};
+
+#endif // FLICKCHARM_H
--- /dev/null
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#include <QtGui>
+#include <QStringList>
+#include <QNetworkProxy>
+#include <QNetworkAccessManager>
+#include <QNetworkProxyFactory>
+#include <cstdlib>
+#include "networkaccess.h"
+
+namespace The {
+
+ static QMap<QString, QAction*> *g_actions = 0;
+
+ QMap<QString, QAction*>* globalActions() {
+ if (!g_actions)
+ g_actions = new QMap<QString, QAction*>;
+ return g_actions;
+ }
+
+ static QMap<QString, QMenu*> *g_menus = 0;
+
+ QMap<QString, QMenu*>* globalMenus() {
+ if (!g_menus)
+ g_menus = new QMap<QString, QMenu*>;
+ return g_menus;
+ }
+
+ void maybeSetSystemProxy() {
+
+ QNetworkProxyQuery proxyQuery(QUrl("http://www"));
+ proxyQuery.setProtocolTag("http");
+ QList<QNetworkProxy> proxylist = QNetworkProxyFactory::systemProxyForQuery(proxyQuery);
+
+ for (int i = 0; i < proxylist.count(); i++) {
+ QNetworkProxy proxy = proxylist.at(i);
+
+ /*
+ qDebug() << i << " type:"<< proxy.type();
+ qDebug() << i << " host:" << proxy.hostName();
+ qDebug() << i << " port:" << proxy.port();
+ qDebug() << i << " user:" << proxy.user();
+ qDebug() << i << " pass:" << proxy.password();
+ */
+
+ if (!proxy.hostName().isEmpty()) {
+ qDebug() << "Using proxy:" << proxy.hostName() << proxy.port();
+ QNetworkProxy::setApplicationProxy(proxy);
+ return;
+ }
+ }
+ }
+
+ void networkHttpProxySetting() {
+ char *http_proxy_env;
+ http_proxy_env = std::getenv("http_proxy");
+ if (!http_proxy_env) {
+ http_proxy_env = std::getenv("HTTP_PROXY");
+ }
+
+ if (http_proxy_env) {
+ QString proxy_host = "";
+ QString proxy_port = "";
+ QString proxy_user = "";
+ QString proxy_pass = "";
+ QString http_proxy = QString(http_proxy_env);
+ http_proxy.remove(QRegExp("^http://"));
+
+ // Remove trailing slash, if any
+ // Fix by Eduardo Suarez-Santana
+ http_proxy.remove(QRegExp("/$"));
+
+ // parse username and password
+ if (http_proxy.contains(QChar('@'))) {
+ QStringList http_proxy_list = http_proxy.split(QChar('@'));
+ QStringList http_proxy_user_pass = http_proxy_list[0].split(QChar(':'));
+ if (http_proxy_user_pass.size() > 0) {
+ proxy_user = http_proxy_user_pass[0];
+ }
+ if (http_proxy_user_pass.size() == 2) {
+ proxy_pass = http_proxy_user_pass[1];
+ }
+ if (http_proxy_list.size() > 1) {
+ http_proxy = http_proxy_list[1];
+ }
+ }
+
+ // parse hostname and port
+ QStringList http_proxy_list = http_proxy.split(QChar(':'));
+ if (http_proxy_list.size() > 0) {
+ proxy_host = http_proxy_list[0];
+ }
+ if (http_proxy_list.size() > 1) {
+ proxy_port = http_proxy_list[1];
+ }
+
+ /*
+ qDebug() << "proxy_host: " << proxy_host;
+ qDebug() << "proxy_port: " << proxy_port;
+ qDebug() << "proxy_user: " << proxy_user;
+ qDebug() << "proxy_pass: " << proxy_pass;
+ */
+
+ // set proxy setting
+ if (!proxy_host.isEmpty()) {
+ QNetworkProxy proxy;
+ proxy.setType(QNetworkProxy::HttpProxy);
+ proxy.setHostName(proxy_host);
+ if (!proxy_port.isEmpty()) {
+ proxy.setPort(proxy_port.toUShort());
+ }
+ if (!proxy_user.isEmpty()) {
+ proxy.setUser(proxy_user);
+ }
+ if (!proxy_pass.isEmpty()) {
+ proxy.setPassword(proxy_pass);
+ }
+
+ qDebug() << "Using HTTP proxy:" << http_proxy_env;
+ QNetworkProxy::setApplicationProxy(proxy);
+ }
+ }
+ }
+
+ static QNetworkAccessManager *nam = 0;
+
+ QNetworkAccessManager* networkAccessManager() {
+ if (!nam) {
+ networkHttpProxySetting();
+ maybeSetSystemProxy();
+ nam = new QNetworkAccessManager();
+
+ // A simple disk based cache
+ /*
+ QNetworkDiskCache *cache = new QNetworkDiskCache();
+ QString cacheLocation = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
+ qDebug() << cacheLocation;
+ cache->setCacheDirectory(cacheLocation);
+ nam->setCache(cache);
+ */
+ }
+ return nam;
+ }
+
+ static NetworkAccess *g_http = 0;
+ NetworkAccess* http() {
+ if (!g_http) {
+ // qDebug() << "Creating NetworkAccess";
+ g_http = new NetworkAccess();
+ }
+ return g_http;
+ }
+
+}
+
+#endif // GLOBAL_H
--- /dev/null
+#include "googlesuggest.h"
+#include "networkaccess.h"
+
+#define GSUGGEST_URL "http://suggestqueries.google.com/complete/search?ds=yt&output=toolbar&hl=%1&q=%2"
+
+namespace The {
+ NetworkAccess* http();
+}
+
+GSuggestCompletion::GSuggestCompletion(QWidget *parent, QLineEdit *editor):
+ QObject(parent), buddy(parent), editor(editor) {
+
+ enabled = true;
+
+ popup = new QListWidget;
+ popup->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ popup->installEventFilter(this);
+ popup->setMouseTracking(true);
+
+ connect(popup, SIGNAL(itemClicked(QListWidgetItem*)),
+ SLOT(doneCompletion()));
+
+ // connect(popup, SIGNAL(currentItemChanged(QListWidgetItem *, QListWidgetItem *)),
+ // SLOT(currentItemChanged(QListWidgetItem *)));
+
+ // mouse hover
+ // connect(popup, SIGNAL(itemEntered(QListWidgetItem*)),
+ // SLOT(currentItemChanged(QListWidgetItem *)));
+
+ popup->setWindowFlags(Qt::Popup);
+ popup->setFocusPolicy(Qt::NoFocus);
+ popup->setFocusProxy(parent);
+
+ timer = new QTimer(this);
+ timer->setSingleShot(true);
+ timer->setInterval(300);
+ connect(timer, SIGNAL(timeout()), SLOT(autoSuggest()));
+ connect(editor, SIGNAL(textEdited(QString)), timer, SLOT(start()));
+
+}
+
+GSuggestCompletion::~GSuggestCompletion() {
+ delete popup;
+}
+
+bool GSuggestCompletion::eventFilter(QObject *obj, QEvent *ev) {
+ if (obj != popup)
+ return false;
+
+ if (ev->type() == QEvent::MouseButtonPress) {
+ popup->hide();
+ editor->setFocus();
+ editor->setText(originalText);
+ return true;
+ }
+
+ if (ev->type() == QEvent::KeyPress) {
+
+ bool consumed = false;
+
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>(ev);
+ int key = keyEvent->key();
+ // qDebug() << keyEvent->text();
+ switch (key) {
+ case Qt::Key_Enter:
+ case Qt::Key_Return:
+ if (popup->currentItem()) {
+ doneCompletion();
+ consumed = true;
+ } else {
+ editor->setFocus();
+ editor->event(ev);
+ popup->hide();
+ }
+ break;
+
+ case Qt::Key_Escape:
+ editor->setFocus();
+ editor->setText(originalText);
+ popup->hide();
+ consumed = true;
+ break;
+
+ case Qt::Key_Up:
+ case Qt::Key_Down:
+ case Qt::Key_Home:
+ case Qt::Key_End:
+ case Qt::Key_PageUp:
+ case Qt::Key_PageDown:
+ break;
+
+ default:
+ // qDebug() << keyEvent->text();
+ editor->setFocus();
+ editor->event(ev);
+ popup->hide();
+ break;
+ }
+
+ return consumed;
+ }
+
+ return false;
+}
+
+void GSuggestCompletion::showCompletion(const QStringList &choices) {
+
+ if (choices.isEmpty())
+ return;
+
+ popup->setUpdatesEnabled(false);
+ popup->clear();
+ for (int i = 0; i < choices.count(); ++i) {
+ QListWidgetItem * item;
+ item = new QListWidgetItem(popup);
+ item->setText(choices[i]);
+ }
+ popup->setCurrentItem(0);
+ popup->adjustSize();
+ popup->setUpdatesEnabled(true);
+
+ int h = popup->sizeHintForRow(0) * choices.count() + 4;
+ popup->resize(buddy->width(), h);
+
+ popup->move(buddy->mapToGlobal(QPoint(0, buddy->height())));
+
+ popup->setFocus();
+ popup->show();
+}
+
+void GSuggestCompletion::doneCompletion() {
+ timer->stop();
+ popup->hide();
+ editor->setFocus();
+ QListWidgetItem *item = popup->currentItem();
+ if (item) {
+ editor->setText(item->text());
+ QKeyEvent *e;
+ e = new QKeyEvent(QEvent::KeyPress, Qt::Key_Enter, Qt::NoModifier);
+ QApplication::postEvent(editor, e);
+ e = new QKeyEvent(QEvent::KeyRelease, Qt::Key_Enter, Qt::NoModifier);
+ QApplication::postEvent(editor, e);
+ }
+}
+
+void GSuggestCompletion::preventSuggest() {
+ // qDebug() << "preventSuggest";
+ timer->stop();
+ enabled = false;
+ popup->hide();
+}
+
+void GSuggestCompletion::enableSuggest() {
+ // qDebug() << "enableSuggest";
+ enabled = true;
+}
+
+void GSuggestCompletion::autoSuggest() {
+ if (!enabled) return;
+
+ QString query = editor->text();
+ originalText = query;
+ // qDebug() << "originalText" << originalText;
+ if (query.isEmpty()) return;
+
+ QString locale = QLocale::system().name().replace("_", "-");
+ // case for system locales such as "C"
+ if (locale.length() < 2) {
+ locale = "en-US";
+ }
+
+ QString url = QString(GSUGGEST_URL).arg(locale, query);
+
+ QObject *reply = The::http()->get(url);
+ connect(reply, SIGNAL(data(QByteArray)), SLOT(handleNetworkData(QByteArray)));
+}
+
+void GSuggestCompletion::handleNetworkData(QByteArray response) {
+ if (!enabled) return;
+
+ QStringList choices;
+
+ 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();
+ }
+ }
+
+ showCompletion(choices);
+
+}
+
+void GSuggestCompletion::currentItemChanged(QListWidgetItem *current) {
+ if (current) {
+ // qDebug() << "current" << current->text();
+ current->setSelected(true);
+ editor->setText(current->text());
+ editor->setSelection(originalText.length(), editor->text().length());
+ }
+}
--- /dev/null
+#ifndef GOOGLESUGGEST_H
+#define GOOGLESUGGEST_H
+
+#include <QtGui>
+
+class GSuggestCompletion : public QObject {
+ Q_OBJECT
+
+public:
+ GSuggestCompletion(QWidget *parent, QLineEdit *editor);
+ ~GSuggestCompletion();
+ bool eventFilter(QObject *obj, QEvent *ev);
+ void showCompletion(const QStringList &choices);
+
+public slots:
+ void doneCompletion();
+ void preventSuggest();
+ void enableSuggest();
+ void autoSuggest();
+ void handleNetworkData(QByteArray response);
+ void currentItemChanged(QListWidgetItem *current);
+
+private:
+ QWidget *buddy;
+ QLineEdit *editor;
+ QString originalText;
+ QListWidget *popup;
+ QTimer *timer;
+ bool enabled;
+
+};
+
+#endif // GOOGLESUGGEST_H
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#include "qticonloader.h"
+#include <QtGui/QPixmapCache>
+
+#include <QtCore/QList>
+#include <QtCore/QHash>
+#include <QtCore/QDir>
+#include <QtCore/QString>
+#include <QtCore/QLibrary>
+#include <QtCore/QSettings>
+#include <QtCore/QTextStream>
+
+#ifdef Q_WS_X11
+
+class QIconTheme
+{
+public:
+ QIconTheme(QHash <int, QString> dirList, QStringList parents) :
+ _dirList(dirList), _parents(parents), _valid(true){ }
+ QIconTheme() : _valid(false){ }
+ QHash <int, QString> dirList() {return _dirList;}
+ QStringList parents() {return _parents;}
+ bool isValid() {return _valid;}
+
+private:
+ QHash <int, QString> _dirList;
+ QStringList _parents;
+ bool _valid;
+};
+
+class QtIconLoaderImplementation
+{
+public:
+ QtIconLoaderImplementation();
+ QPixmap findIcon(int size, const QString &name) const;
+
+private:
+ QIconTheme parseIndexFile(const QString &themeName) const;
+ void lookupIconTheme() const;
+ QPixmap findIconHelper(int size,
+ const QString &themeName,
+ const QString &iconName,
+ QStringList &visited) const;
+ mutable QString themeName;
+ mutable QStringList iconDirs;
+ mutable QHash <QString, QIconTheme> themeList;
+};
+
+Q_GLOBAL_STATIC(QtIconLoaderImplementation, iconLoaderInstance)
+#endif
+
+/*!
+
+ Returns the standard icon for the given icon /a name
+ as specified in the freedesktop icon spec
+ http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
+
+ /a fallback is an optional argument to specify the icon to be used if
+ no icon is found on the platform. This is particularily useful for
+ crossplatform code.
+
+*/
+QIcon QtIconLoader::icon(const QString &name, const QIcon &fallback)
+{
+ QIcon icon;
+
+#if QT_VERSION < 0x040600
+
+#ifdef Q_WS_X11
+ QString pngExtension(QLatin1String(".png"));
+ QList<int> iconSizes;
+ iconSizes << 16 << 24 << 32 << 48 << 64;
+ Q_FOREACH (int size, iconSizes) {
+ icon.addPixmap(iconLoaderInstance()->findIcon(size, name + pngExtension));
+ }
+#endif
+
+#else
+ icon = QIcon::fromTheme(name, fallback);
+#endif
+
+ if (icon.isNull())
+ icon = fallback;
+ Q_UNUSED(name);
+ return icon;
+}
+
+#ifdef Q_WS_X11
+
+QtIconLoaderImplementation::QtIconLoaderImplementation()
+{
+ lookupIconTheme();
+}
+
+extern "C" {
+ struct GConfClient;
+ struct GError;
+ typedef void (*Ptr_g_type_init)();
+ typedef GConfClient* (*Ptr_gconf_client_get_default)();
+ typedef char* (*Ptr_gconf_client_get_string)(GConfClient*, const char*, GError **);
+ typedef void (*Ptr_g_object_unref)(void *);
+ typedef void (*Ptr_g_error_free)(GError *);
+ typedef void (*Ptr_g_free)(void*);
+ static Ptr_g_type_init p_g_type_init = 0;
+ static Ptr_gconf_client_get_default p_gconf_client_get_default = 0;
+ static Ptr_gconf_client_get_string p_gconf_client_get_string = 0;
+ static Ptr_g_object_unref p_g_object_unref = 0;
+ static Ptr_g_error_free p_g_error_free = 0;
+ static Ptr_g_free p_g_free = 0;
+}
+
+
+static int kdeVersion()
+{
+ static int version = qgetenv("KDE_SESSION_VERSION").toInt();
+ return version;
+}
+
+static QString kdeHome()
+{
+ static QString kdeHomePath;
+ if (kdeHomePath.isEmpty()) {
+ kdeHomePath = QFile::decodeName(qgetenv("KDEHOME"));
+ if (kdeHomePath.isEmpty()) {
+ int kdeSessionVersion = kdeVersion();
+ QDir homeDir(QDir::homePath());
+ QString kdeConfDir(QLatin1String("/.kde"));
+ if (4 == kdeSessionVersion && homeDir.exists(QLatin1String(".kde4")))
+ kdeConfDir = QLatin1String("/.kde4");
+ kdeHomePath = QDir::homePath() + kdeConfDir;
+ }
+ }
+ return kdeHomePath;
+}
+
+void QtIconLoaderImplementation::lookupIconTheme() const
+{
+
+#ifdef Q_WS_X11
+ QString dataDirs = QFile::decodeName(getenv("XDG_DATA_DIRS"));
+ if (dataDirs.isEmpty())
+ dataDirs = QLatin1String("/usr/local/share/:/usr/share/");
+
+ dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
+ iconDirs = dataDirs.split(QLatin1Char(':'));
+
+ // If we are running GNOME we resolve and use GConf. In all other
+ // cases we currently use the KDE icon theme
+
+ if (qgetenv("DESKTOP_SESSION") == "gnome" ||
+ !qgetenv("GNOME_DESKTOP_SESSION_ID").isEmpty()) {
+
+ if (themeName.isEmpty()) {
+ // Resolve glib and gconf
+
+ p_g_type_init = (Ptr_g_type_init)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_type_init");
+ p_gconf_client_get_default = (Ptr_gconf_client_get_default)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_default");
+ p_gconf_client_get_string = (Ptr_gconf_client_get_string)QLibrary::resolve(QLatin1String("gconf-2"), 4, "gconf_client_get_string");
+ p_g_object_unref = (Ptr_g_object_unref)QLibrary::resolve(QLatin1String("gobject-2.0"), 0, "g_object_unref");
+ p_g_error_free = (Ptr_g_error_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_error_free");
+ p_g_free = (Ptr_g_free)QLibrary::resolve(QLatin1String("glib-2.0"), 0, "g_free");
+
+ if (p_g_type_init && p_gconf_client_get_default &&
+ p_gconf_client_get_string && p_g_object_unref &&
+ p_g_error_free && p_g_free) {
+
+ p_g_type_init();
+ GConfClient* client = p_gconf_client_get_default();
+ GError *err = 0;
+
+ char *str = p_gconf_client_get_string(client, "/desktop/gnome/interface/icon_theme", &err);
+ if (!err) {
+ themeName = QString::fromUtf8(str);
+ p_g_free(str);
+ }
+
+ p_g_object_unref(client);
+ if (err)
+ p_g_error_free (err);
+ }
+ if (themeName.isEmpty())
+ themeName = QLatin1String("gnome");
+ }
+
+ if (!themeName.isEmpty())
+ return;
+ }
+
+ // KDE (and others)
+ if (dataDirs.isEmpty())
+ dataDirs = QLatin1String("/usr/local/share/:/usr/share/");
+
+ dataDirs += QLatin1Char(':') + kdeHome() + QLatin1String("/share");
+ dataDirs.prepend(QDir::homePath() + QLatin1String("/:"));
+ QStringList kdeDirs = QFile::decodeName(getenv("KDEDIRS")).split(QLatin1Char(':'));
+ Q_FOREACH (const QString dirName, kdeDirs)
+ dataDirs.append(QLatin1Char(':') + dirName + QLatin1String("/share"));
+ iconDirs = dataDirs.split(QLatin1Char(':'));
+
+ QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
+ QDir dir(fileInfo.canonicalFilePath());
+ QString kdeDefault = kdeVersion() >= 4 ? QString::fromLatin1("oxygen") : QString::fromLatin1("crystalsvg");
+ QString defaultTheme = fileInfo.exists() ? dir.dirName() : kdeDefault;
+ QSettings settings(kdeHome() + QLatin1String("/share/config/kdeglobals"), QSettings::IniFormat);
+ settings.beginGroup(QLatin1String("Icons"));
+ themeName = settings.value(QLatin1String("Theme"), defaultTheme).toString();
+#endif
+}
+
+QIconTheme QtIconLoaderImplementation::parseIndexFile(const QString &themeName) const
+{
+ QIconTheme theme;
+ QFile themeIndex;
+ QStringList parents;
+ QHash <int, QString> dirList;
+
+ for ( int i = 0 ; i < iconDirs.size() && !themeIndex.exists() ; ++i) {
+ const QString &contentDir = QLatin1String(iconDirs[i].startsWith(QDir::homePath()) ? "/.icons/" : "/icons/");
+ themeIndex.setFileName(iconDirs[i] + contentDir + themeName + QLatin1String("/index.theme"));
+ }
+
+ if (themeIndex.exists()) {
+ QSettings indexReader(themeIndex.fileName(), QSettings::IniFormat);
+ Q_FOREACH (const QString &key, indexReader.allKeys()) {
+ if (key.endsWith("/Size")) {
+ if (int size = indexReader.value(key).toInt())
+ dirList.insertMulti(size, key.left(key.size() - 5));
+ }
+ }
+
+ // Parent themes provide fallbacks for missing icons
+ // parents = indexReader.value(QLatin1String("Icon Theme/Inherits")).toString().split(QLatin1Char(','));
+ parents = indexReader.value(QLatin1String("Icon Theme/Inherits")).toStringList();
+
+
+ }
+
+ if (kdeVersion() >= 3) {
+ QFileInfo fileInfo(QLatin1String("/usr/share/icons/default.kde"));
+ QDir dir(fileInfo.canonicalFilePath());
+ QString defaultKDETheme = dir.exists() ? dir.dirName() : kdeVersion() == 3 ?
+ QString::fromLatin1("crystalsvg") : QString::fromLatin1("oxygen");
+ if (!parents.contains(defaultKDETheme) && themeName != defaultKDETheme)
+ parents.append(defaultKDETheme);
+ } else if (parents.isEmpty() && themeName != QLatin1String("hicolor")) {
+ parents.append(QLatin1String("hicolor"));
+ }
+
+ theme = QIconTheme(dirList, parents);
+ return theme;
+}
+
+QPixmap QtIconLoaderImplementation::findIconHelper(int size, const QString &themeName,
+ const QString &iconName, QStringList &visited) const
+{
+ QPixmap pixmap;
+
+ if (!themeName.isEmpty()) {
+ visited << themeName;
+ QIconTheme theme = themeList.value(themeName);
+
+ if (!theme.isValid()) {
+ theme = parseIndexFile(themeName);
+ themeList.insert(themeName, theme);
+ }
+
+ if (!theme.isValid())
+ return QPixmap();
+
+ QList <QString> subDirs = theme.dirList().values(size);
+
+ for ( int i = 0 ; i < iconDirs.size() ; ++i) {
+ for ( int j = 0 ; j < subDirs.size() ; ++j) {
+ QString contentDir = (iconDirs[i].startsWith(QDir::homePath())) ?
+ QLatin1String("/.icons/") : QLatin1String("/icons/");
+ QString fileName = iconDirs[i] + contentDir + themeName + QLatin1Char('/') + subDirs[j] + QLatin1Char('/') + iconName;
+ QFile file(fileName);
+ if (file.exists())
+ pixmap.load(fileName);
+ if (!pixmap.isNull())
+ break;
+ }
+ }
+
+ if (pixmap.isNull()) {
+ QStringList parents = theme.parents();
+ //search recursively through inherited themes
+ for (int i = 0 ; pixmap.isNull() && i < parents.size() ; ++i) {
+ QString parentTheme = parents[i].trimmed();
+ if (!visited.contains(parentTheme)) //guard against endless recursion
+ pixmap = findIconHelper(size, parentTheme, iconName, visited);
+ }
+ }
+ }
+ return pixmap;
+}
+
+QPixmap QtIconLoaderImplementation::findIcon(int size, const QString &name) const
+{
+ QPixmap pixmap;
+ QString pixmapName = QLatin1String("$qt") + name + QString::number(size);
+ if (QPixmapCache::find(pixmapName, pixmap))
+ return pixmap;
+
+ if (!themeName.isEmpty()) {
+ QStringList visited;
+ pixmap = findIconHelper(size, themeName, name, visited);
+ }
+ QPixmapCache::insert(pixmapName, pixmap);
+ return pixmap;
+}
+#endif //Q_WS_X11
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#ifndef QTICONLOADER_H
+#define QTICONLOADER_H
+
+#include <QtGui/QIcon>
+
+// This is the QtIconLoader
+// Version 0.1
+//
+
+class QtIconLoader
+{
+public:
+ static QIcon icon(const QString &name, const QIcon &fallback = QIcon());
+};
+
+#endif // QTICONLOADER_H
--- /dev/null
+#include "loadingwidget.h"
+
+LoadingWidget::LoadingWidget(QWidget *parent) : QWidget(parent) {
+
+ QPalette p = palette();
+ p.setBrush(QPalette::Window, Qt::black);
+ p.setBrush(QPalette::Text, Qt::white);
+ setPalette(p);
+
+ setAutoFillBackground(true);
+
+ QFont bigFont;
+ bigFont.setPointSize(bigFont.pointSize()*4);
+ QFontMetrics fm(bigFont);
+ int textHeightInPixels = fm.height();
+ int spacing = textHeightInPixels / 2;
+
+ QBoxLayout *layout = new QVBoxLayout();
+ layout->setSpacing(spacing);
+ layout->setMargin(spacing);
+
+ titleLabel = new QLabel(this);
+ titleLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
+ titleLabel->setPalette(p);
+ titleLabel->setForegroundRole(QPalette::Text);
+ titleLabel->setWordWrap(true);
+ titleLabel->setFont(bigFont);
+ titleLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ layout->addWidget(titleLabel);
+
+ QFont biggerFont;
+ biggerFont.setPointSize(biggerFont.pointSize()*2);
+
+ descriptionLabel = new QLabel(this);
+ descriptionLabel->setAlignment(Qt::AlignHCenter | Qt::AlignTop);
+ descriptionLabel->setPalette(p);
+ descriptionLabel->setForegroundRole(QPalette::Text);
+ descriptionLabel->setWordWrap(true);
+ descriptionLabel->setFont(biggerFont);
+ descriptionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ layout->addWidget(descriptionLabel);
+
+ /*
+ progressBar = new QProgressBar(this);
+ progressBar->hide();
+ layout->addWidget(progressBar);
+ */
+
+ setMouseTracking(true);
+
+ setLayout(layout);
+}
+
+void LoadingWidget::setVideo(Video *video) {
+ QString title = video->title();
+ // enhance legibility by splitting the title
+ title = title.replace(" - ", "<p>");
+ title = title.replace("] ", "]<p>");
+ title = title.replace(" [", "<p>[");
+ titleLabel->setText(title);
+ descriptionLabel->setText(video->description());
+ // progressBar->hide();
+}
+
+void LoadingWidget::setError(QString message) {
+ titleLabel->setText(tr("Error"));
+ descriptionLabel->setText(message);
+ // progressBar->hide();
+}
+
+void LoadingWidget::bufferStatus(int /* percent */) {
+ /*
+ qDebug() << percent;
+ progressBar->setShown(percent > 0);
+ progressBar->setValue(percent);
+ */
+}
+
+void LoadingWidget::clear() {
+ titleLabel->clear();
+ descriptionLabel->clear();
+ // progressBar->hide();
+}
--- /dev/null
+#ifndef LOADINGWIDGET_H
+#define LOADINGWIDGET_H
+
+#include <QtGui>
+#include "video.h"
+
+class LoadingWidget : public QWidget {
+
+ Q_OBJECT
+
+public:
+ LoadingWidget(QWidget *parent);
+ void setVideo(Video *video);
+ void setError(QString message);
+ void clear();
+
+public slots:
+ void bufferStatus(int);
+
+private:
+ QLabel *titleLabel;
+ QLabel *descriptionLabel;
+ // TODO uncomment the whole progress bar feature
+ // when the Phonon backends will correctly emit bufferStatus(int)
+ // QProgressBar *progressBar;
+
+};
+
+#endif // LOADINGWIDGET_H
--- /dev/null
+#include <QtGui>
+#include <qtsingleapplication.h>
+#include "Constants.h"
+#include "MainWindow.h"
+
+int main(int argc, char **argv) {
+
+ QtSingleApplication app(argc, argv);
+ if (app.sendMessage("Wake up!"))
+ return 0;
+
+ app.setApplicationName(Constants::APP_NAME);
+ app.setOrganizationName(Constants::ORG_NAME);
+ app.setOrganizationDomain(Constants::ORG_DOMAIN);
+#ifndef Q_WS_MAC
+ app.setWheelScrollLines(1);
+#endif
+
+ const QString locale = QLocale::system().name();
+
+ // qt translations
+ QTranslator qtTranslator;
+ qtTranslator.load("qt_" + locale,
+ QLibraryInfo::location(QLibraryInfo::TranslationsPath));
+ app.installTranslator(&qtTranslator);
+
+ // app translations
+#ifdef PKGDATADIR
+ QString dataDir = QLatin1String(PKGDATADIR);
+#else
+ QString dataDir = "";
+#endif
+ QString localeDir = dataDir + QDir::separator() + "locale";
+ // if app was not "installed" use the app directory
+ if (!QFile::exists(localeDir)) {
+ localeDir = qApp->applicationDirPath() + QDir::separator() + "locale";
+ // qDebug() << "Using locale dir" << localeDir << locale;
+ }
+ QTranslator translator;
+ translator.load(locale, localeDir);
+ app.installTranslator(&translator);
+ QTextCodec::setCodecForTr(QTextCodec::codecForName("utf8"));
+
+ MainWindow mainWin;
+ mainWin.setWindowTitle(Constants::APP_NAME);
+
+// no window icon on Mac
+#ifndef Q_WS_MAC
+ if (!QFile::exists(dataDir)) {
+ dataDir = qApp->applicationDirPath() + "/data";
+ }
+ const int iconSizes [] = { 16, 22, 24, 32, 48, 64, 128, 256 };
+ QIcon appIcon;
+ for (int i = 0; i < 8; i++) {
+ QString size = QString::number(iconSizes[i]);
+ QString png = dataDir + "/" + size + "x" + size + "/minitube.png";
+ // qDebug() << png;
+ appIcon.addFile(png, QSize(iconSizes[i], iconSizes[i]));
+ }
+ mainWin.setWindowIcon(appIcon);
+#endif
+
+ mainWin.show();
+
+ app.setActivationWindow(&mainWin, true);
+
+ // all string literals are UTF-8
+ QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+
+ return app.exec();
+}
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#include "minisplitter.h"
+
+#include <QtGui/QPaintEvent>
+#include <QtGui/QPainter>
+#include <QtGui/QSplitterHandle>
+
+class MiniSplitterHandle : public QSplitterHandle
+{
+public:
+ MiniSplitterHandle(Qt::Orientation orientation, QSplitter *parent)
+ : QSplitterHandle(orientation, parent)
+ {
+ setMask(QRegion(contentsRect()));
+ setAttribute(Qt::WA_MouseNoMask, true);
+ }
+protected:
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+};
+
+void MiniSplitterHandle::resizeEvent(QResizeEvent *event)
+{
+ if (orientation() == Qt::Horizontal)
+ setContentsMargins(2, 0, 2, 0);
+ else
+ setContentsMargins(0, 2, 0, 2);
+ setMask(QRegion(contentsRect()));
+ QSplitterHandle::resizeEvent(event);
+}
+
+void MiniSplitterHandle::paintEvent(QPaintEvent *event)
+{
+ QPainter painter(this);
+ painter.fillRect(event->rect(), Qt::black);
+}
+
+QSplitterHandle *MiniSplitter::createHandle()
+{
+ return new MiniSplitterHandle(orientation(), this);
+}
+
+MiniSplitter::MiniSplitter(QWidget *parent)
+ : QSplitter(parent)
+{
+ setHandleWidth(1);
+ setChildrenCollapsible(false);
+ setProperty("minisplitter", true);
+}
+
+MiniSplitter::MiniSplitter(Qt::Orientation orientation)
+ : QSplitter(orientation)
+{
+ setHandleWidth(1);
+ setChildrenCollapsible(false);
+ setProperty("minisplitter", true);
+}
--- /dev/null
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+**************************************************************************/
+
+#ifndef MINISPLITTER_H
+#define MINISPLITTER_H
+
+#include <QtGui/QSplitter>
+
+QT_BEGIN_NAMESPACE
+class QSplitterHandle;
+QT_END_NAMESPACE
+
+/*! This is a simple helper-class to obtain mac-style 1-pixel wide splitters */
+class MiniSplitter : public QSplitter
+{
+public:
+ MiniSplitter(QWidget *parent = 0);
+ MiniSplitter(Qt::Orientation orientation);
+
+protected:
+ QSplitterHandle *createHandle();
+};
+
+#endif // MINISPLITTER_H
--- /dev/null
+#include "networkaccess.h"
+#include "Constants.h"
+#include <QtGui>
+
+namespace The {
+ NetworkAccess* http();
+}
+
+NetworkReply::NetworkReply(QNetworkReply *networkReply) : QObject(networkReply) {
+ this->networkReply = networkReply;
+}
+
+void NetworkReply::finished() {
+
+ QUrl redirection = networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
+ if (redirection.isValid()) {
+
+ // qDebug() << "Redirect!"; // << redirection;
+
+ QNetworkReply *redirectReply = The::http()->simpleGet(redirection, networkReply->operation());
+
+ setParent(redirectReply);
+ networkReply->deleteLater();
+ networkReply = redirectReply;
+
+ // when the request is finished we'll invoke the target method
+ connect(networkReply, SIGNAL(finished()), this, SLOT(finished()), Qt::AutoConnection);
+
+ return;
+ }
+
+
+ emit finished(networkReply);
+
+ // get the HTTP response body
+ QByteArray bytes = networkReply->readAll();
+
+ emit data(bytes);
+
+ // bye bye my reply
+ // this will also delete this NetworkReply as the QNetworkReply is its parent
+ networkReply->deleteLater();
+}
+
+void NetworkReply::requestError(QNetworkReply::NetworkError code) {
+ emit error(networkReply);
+}
+
+/* --- NetworkAccess --- */
+
+NetworkAccess::NetworkAccess( QObject* parent) : QObject( parent ) {}
+
+QNetworkReply* NetworkAccess::simpleGet(QUrl url, int operation) {
+
+ QNetworkAccessManager *manager = The::networkAccessManager();
+
+ QNetworkRequest request(url);
+ request.setRawHeader("User-Agent", Constants::USER_AGENT.toUtf8());
+ request.setRawHeader("Connection", "Keep-Alive");
+
+ QNetworkReply *networkReply;
+ switch (operation) {
+
+ case QNetworkAccessManager::GetOperation:
+ qDebug() << "GET" << url.toString();
+ networkReply = manager->get(request);
+ break;
+
+ case QNetworkAccessManager::HeadOperation:
+ qDebug() << "HEAD" << url.toString();
+ networkReply = manager->head(request);
+ break;
+
+ default:
+ qDebug() << "Unknown operation:" << operation;
+ return 0;
+
+ }
+
+ // error handling
+ connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(error(QNetworkReply::NetworkError)));
+
+ return networkReply;
+
+}
+
+NetworkReply* NetworkAccess::get(const QUrl url) {
+
+ QNetworkReply *networkReply = simpleGet(url);
+ NetworkReply *reply = new NetworkReply(networkReply);
+
+ // error signal
+ connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
+ reply, SLOT(requestError(QNetworkReply::NetworkError)));
+
+ // when the request is finished we'll invoke the target method
+ connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::AutoConnection);
+
+ return reply;
+
+}
+
+NetworkReply* NetworkAccess::head(const QUrl url) {
+
+ QNetworkReply *networkReply = simpleGet(url, QNetworkAccessManager::HeadOperation);
+ NetworkReply *reply = new NetworkReply(networkReply);
+
+ // error signal
+ connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
+ reply, SLOT(requestError(QNetworkReply::NetworkError)));
+
+ // when the request is finished we'll invoke the target method
+ connect(networkReply, SIGNAL(finished()), reply, SLOT(finished()), Qt::AutoConnection);
+
+ return reply;
+
+}
+
+/*** sync ***/
+
+
+QNetworkReply* NetworkAccess::syncGet(QUrl url) {
+
+ working = true;
+
+ networkReply = simpleGet(url);
+ connect(networkReply, SIGNAL(metaDataChanged()),
+ this, SLOT(syncMetaDataChanged()), Qt::AutoConnection);
+ connect(networkReply, SIGNAL(finished()),
+ this, SLOT(syncFinished()), Qt::AutoConnection);
+ connect(networkReply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(error(QNetworkReply::NetworkError)));
+
+ // A little trick to make this function blocking
+ while (working) {
+ // Do something else, maybe even network processing events
+ qApp->processEvents();
+ }
+
+ networkReply->deleteLater();
+ return networkReply;
+
+}
+
+void NetworkAccess::syncMetaDataChanged() {
+
+ QUrl redirection = networkReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
+ if (redirection.isValid()) {
+
+ qDebug() << "Redirect" << redirection;
+ networkReply->deleteLater();
+ syncGet(redirection);
+
+ /*
+ QNetworkAccessManager *manager = The::networkAccessManager();
+ networkReply->deleteLater();
+ networkReply = manager->get(QNetworkRequest(redirection));
+ connect(networkReply, SIGNAL(metaDataChanged()),
+ this, SLOT(metaDataChanged()), Qt::AutoConnection);
+ connect(networkReply, SIGNAL(finished()),
+ this, SLOT(finished()), Qt::AutoConnection);
+ */
+ }
+
+}
+
+void NetworkAccess::syncFinished() {
+ // got it!
+ working = false;
+}
+
+void NetworkAccess::error(QNetworkReply::NetworkError code) {
+ // get the QNetworkReply that sent the signal
+ QNetworkReply *networkReply = static_cast<QNetworkReply *>(sender());
+ if (!networkReply) {
+ qDebug() << "Cannot get sender";
+ return;
+ }
+
+ // Ignore HEADs
+ if (networkReply->operation() == QNetworkAccessManager::HeadOperation)
+ return;
+
+ // report the error in the status bar
+ QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(qApp->topLevelWidgets().first());
+ if (mainWindow) mainWindow->statusBar()->showMessage(
+ tr("Network error: %1").arg(networkReply->errorString()));
+
+ qDebug() << "Network error:" << networkReply->errorString() << code;
+
+ networkReply->deleteLater();
+}
+
+QByteArray NetworkAccess::syncGetBytes(QUrl url) {
+ return syncGet(url)->readAll();
+}
+
+QString NetworkAccess::syncGetString(QUrl url) {
+ return QString::fromUtf8(syncGetBytes(url));
+}
--- /dev/null
+#ifndef NETWORKACCESS_H
+#define NETWORKACCESS_H
+
+#include <QtNetwork>
+
+namespace The {
+ QNetworkAccessManager* networkAccessManager();
+}
+
+class NetworkReply : public QObject {
+
+ Q_OBJECT
+
+public:
+ NetworkReply(QNetworkReply* networkReply);
+
+public slots:
+ void finished();
+ void requestError(QNetworkReply::NetworkError);
+
+signals:
+ void data(QByteArray);
+ void error(QNetworkReply*);
+ void finished(QNetworkReply*);
+
+private:
+ QNetworkReply *networkReply;
+
+};
+
+
+class NetworkAccess : public QObject {
+
+ Q_OBJECT
+
+public:
+ NetworkAccess( QObject* parent=0);
+ QNetworkReply* simpleGet(QUrl url, int operation = QNetworkAccessManager::GetOperation);
+ NetworkReply* get(QUrl url);
+ NetworkReply* head(QUrl url);
+ QNetworkReply* syncGet(QUrl url);
+ QByteArray syncGetBytes(QUrl url);
+ QString syncGetString(QUrl url);
+
+private slots:
+ void error(QNetworkReply::NetworkError);
+ void syncMetaDataChanged();
+ void syncFinished();
+
+private:
+ QNetworkReply *networkReply;
+ bool working;
+
+};
+
+typedef QPointer<QObject> ObjectPointer;
+Q_DECLARE_METATYPE(ObjectPointer)
+
+#endif // NETWORKACCESS_H
--- /dev/null
+#include "PrettyItemDelegate.h"
+#include "../ListModel.h"
+
+#include <QFontMetricsF>
+#include <QPainter>
+
+const qreal PrettyItemDelegate::THUMB_HEIGHT = 90.0;
+const qreal PrettyItemDelegate::THUMB_WIDTH = 120.0;
+const qreal PrettyItemDelegate::PADDING = 10.0;
+
+PrettyItemDelegate::PrettyItemDelegate( QObject* parent ) : QStyledItemDelegate( parent ) {
+
+ boldFont.setBold(true);
+ smallerFont.setPointSize(smallerFont.pointSize()*.85);
+ smallerBoldFont.setBold(true);
+ smallerBoldFont.setPointSize(smallerBoldFont.pointSize()*.85);
+ QFontInfo fontInfo(smallerFont);
+ if (fontInfo.pixelSize() < 10) {
+ smallerFont.setPixelSize(10);
+ smallerBoldFont.setPixelSize(10);
+ }
+ createPlayIcon();
+}
+
+void PrettyItemDelegate::createPlayIcon() {
+ playIcon = QPixmap(THUMB_WIDTH, THUMB_HEIGHT);
+ playIcon.fill(Qt::transparent);
+ QPainter painter(&playIcon);
+ QPolygon polygon;
+ polygon << QPoint(PADDING*4, PADDING*2)
+ << QPoint(THUMB_WIDTH-PADDING*4, THUMB_HEIGHT/2)
+ << QPoint(PADDING*4, THUMB_HEIGHT-PADDING*2);
+ painter.setRenderHints(QPainter::Antialiasing, true);
+ painter.setBrush(Qt::white);
+ QPen pen;
+ pen.setColor(Qt::white);
+ pen.setWidth(PADDING);
+ pen.setJoinStyle(Qt::RoundJoin);
+ pen.setCapStyle(Qt::RoundCap);
+ painter.setPen(pen);
+ painter.drawPolygon(polygon);
+}
+
+PrettyItemDelegate::~PrettyItemDelegate() { }
+
+QSize PrettyItemDelegate::sizeHint( const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const {
+ return QSize( 256, THUMB_HEIGHT+1.0);
+}
+
+void PrettyItemDelegate::paint( QPainter* painter,
+ const QStyleOptionViewItem& option, const QModelIndex& index ) const {
+
+ int itemType = index.data(ItemTypeRole).toInt();
+ if (itemType == ItemTypeVideo) {
+ QApplication::style()->drawPrimitive( QStyle::PE_PanelItemViewItem, &option, painter );
+ paintBody( painter, option, index );
+ } else
+ QStyledItemDelegate::paint( painter, option, index );
+
+}
+
+void PrettyItemDelegate::paintBody( QPainter* painter,
+ const QStyleOptionViewItem& option,
+ const QModelIndex& index ) const {
+
+ painter->save();
+ painter->translate( option.rect.topLeft() );
+
+
+ const QRectF line(0, 0, option.rect.width(), option.rect.height());
+ painter->setClipRect(line);
+
+ const bool isActive = index.data( ActiveTrackRole ).toBool();
+ const bool isSelected = option.state & QStyle::State_Selected;
+
+ // draw the "current track" highlight underneath the text
+ if (isActive && !isSelected) {
+ paintActiveOverlay(painter, line.x(), line.y(), line.width(), line.height());
+ }
+
+ // get the video metadata
+ const VideoPointer videoPointer = index.data( VideoRole ).value<VideoPointer>();
+ const Video *video = videoPointer.data();
+
+ // thumb
+ if (!video->thumbnail().isNull()) {
+ painter->drawImage(QRect(0, 0, THUMB_WIDTH, THUMB_HEIGHT), video->thumbnail());
+
+ // play icon overlayed on the thumb
+ if (isActive)
+ paintPlayIcon(painter);
+
+ // time
+ QString timeString;
+ int duration = video->duration();
+ if ( duration > 3600 )
+ timeString = QTime().addSecs(duration).toString("h:mm:ss");
+ else
+ timeString = QTime().addSecs(duration).toString("m:ss");
+ drawTime(painter, timeString, line);
+
+ }
+
+ if (isActive) painter->setFont(boldFont);
+ const QFontMetricsF fm(painter->font());
+ const QFontMetricsF boldMetrics(boldFont);
+
+ // text color
+ if (isSelected)
+ painter->setPen(QPen(option.palette.brush(QPalette::HighlightedText), 0));
+ else
+ painter->setPen(QPen(option.palette.brush(QPalette::Text), 0));
+
+ // title
+ QString videoTitle = video->title();
+ QRectF textBox = line.adjusted(PADDING+THUMB_WIDTH, PADDING, -2 * PADDING, -PADDING);
+ textBox = painter->boundingRect( textBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, videoTitle);
+ painter->drawText(textBox, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, videoTitle);
+
+ painter->setFont(smallerFont);
+
+ // published date
+ QString publishedString = video->published().date().toString(Qt::DefaultLocaleShortDate);
+ QSizeF publishedStringSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, publishedString ) );
+ QPointF textLoc(PADDING+THUMB_WIDTH, PADDING*2 + textBox.height());
+ QRectF publishedTextBox( textLoc , publishedStringSize);
+ painter->drawText(publishedTextBox, Qt::AlignLeft | Qt::AlignTop, publishedString);
+
+ // author
+ painter->save();
+ painter->setFont(smallerBoldFont);
+ if (!isSelected && !isActive)
+ painter->setPen(QPen(option.palette.brush(QPalette::Mid), 0));
+ QString authorString = video->author();
+ QSizeF authorStringSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, authorString ) );
+ textLoc.setX(textLoc.x() + publishedStringSize.width() + PADDING);
+ QRectF authorTextBox( textLoc , authorStringSize);
+ painter->drawText(authorTextBox, Qt::AlignLeft | Qt::AlignTop, authorString);
+ painter->restore();
+
+ // view count
+ if (video->viewCount() >= 0) {
+ painter->save();
+ QLocale locale;
+ QString viewCountString = tr("%1 views").arg(locale.toString(video->viewCount()));
+ QSizeF viewCountStringSize(QFontMetrics(painter->font()).size( Qt::TextSingleLine, viewCountString ) );
+ textLoc.setX(textLoc.x() + authorStringSize.width() + PADDING);
+ QRectF viewCountTextBox( textLoc , viewCountStringSize);
+ painter->drawText(viewCountTextBox, Qt::AlignLeft | Qt::AlignBottom, viewCountString);
+ painter->restore();
+ }
+
+ /*
+ QLinearGradient myGradient;
+ QPen myPen;
+ QFont myFont;
+ QPointF baseline(authorTextBox.x(), authorTextBox.y() + authorTextBox.height());
+ QPainterPath myPath;
+ myPath.addText(baseline, boldFont, authorString);
+ painter->setBrush(palette.color(QPalette::WindowText));
+ painter->setPen(palette.color(QPalette::Dark));
+ painter->setRenderHints (QPainter::Antialiasing, true);
+ painter->drawPath(myPath);
+ */
+
+ // separator
+ painter->setPen(option.palette.color(QPalette::Midlight));
+ painter->drawLine(THUMB_WIDTH, THUMB_HEIGHT, line.width(), THUMB_HEIGHT);
+ if (!video->thumbnail().isNull())
+ painter->setPen(Qt::black);
+ painter->drawLine(0, THUMB_HEIGHT, THUMB_WIDTH-1, THUMB_HEIGHT);
+
+ painter->restore();
+
+}
+
+QPointF PrettyItemDelegate::centerImage( const QPixmap& pixmap, const QRectF& rect ) const {
+ qreal pixmapRatio = ( qreal )pixmap.width() / ( qreal )pixmap.height();
+
+ qreal moveByX = 0.0;
+ qreal moveByY = 0.0;
+
+ if ( pixmapRatio >= 1 )
+ moveByY = ( rect.height() - ( rect.width() / pixmapRatio ) ) / 2.0;
+ else
+ moveByX = ( rect.width() - ( rect.height() * pixmapRatio ) ) / 2.0;
+
+ return QPointF( moveByX, moveByY );
+}
+
+void PrettyItemDelegate::paintActiveOverlay( QPainter *painter, qreal x, qreal y, qreal w, qreal h ) const {
+
+ QPalette palette;
+ QColor highlightColor = palette.color(QPalette::Highlight);
+ QColor backgroundColor = palette.color(QPalette::Base);
+ const float animation = 0.25;
+ const int gradientRange = 16;
+
+ QColor color2 = QColor::fromHsv(
+ highlightColor.hue(),
+ (int) (backgroundColor.saturation() * (1.0f - animation) + highlightColor.saturation() * animation),
+ (int) (backgroundColor.value() * (1.0f - animation) + highlightColor.value() * animation)
+ );
+ QColor color1 = QColor::fromHsv(
+ color2.hue(),
+ qMax(color2.saturation() - gradientRange, 0),
+ qMin(color2.value() + gradientRange, 255)
+ );
+ QRect rect((int) x, (int) y, (int) w, (int) h);
+ painter->save();
+ painter->setPen(Qt::NoPen);
+ QLinearGradient linearGradient(0, 0, 0, rect.height());
+ linearGradient.setColorAt(0.0, color1);
+ linearGradient.setColorAt(1.0, color2);
+ painter->setBrush(linearGradient);
+ painter->drawRect(rect);
+ painter->restore();
+}
+
+void PrettyItemDelegate::paintPlayIcon(QPainter *painter) const {
+ painter->save();
+ painter->setOpacity(.5);
+ painter->drawPixmap(playIcon.rect(), playIcon);
+ painter->restore();
+}
+
+void PrettyItemDelegate::drawTime(QPainter *painter, QString time, QRectF line) const {
+ static const int timePadding = 4;
+ QRectF textBox = painter->boundingRect(line, Qt::AlignLeft | Qt::AlignTop, time);
+ // add padding
+ textBox.adjust(0, 0, timePadding, 0);
+ // move to bottom right corner of the thumb
+ textBox.translate(THUMB_WIDTH - textBox.width(), THUMB_HEIGHT - textBox.height());
+
+ painter->save();
+ painter->setPen(Qt::NoPen);
+ painter->setBrush(Qt::black);
+ painter->setOpacity(.5);
+ painter->drawRect(textBox);
+ painter->restore();
+
+ painter->save();
+ painter->setPen(Qt::white);
+ painter->drawText(textBox, Qt::AlignCenter, time);
+ painter->restore();
+}
--- /dev/null
+#ifndef PRETTYITEMDELEGATE_H
+#define PRETTYITEMDELEGATE_H
+
+#include <QModelIndex>
+#include <QStyledItemDelegate>
+
+class QPainter;
+
+class PrettyItemDelegate : public QStyledItemDelegate {
+
+ Q_OBJECT
+
+public:
+ PrettyItemDelegate( QObject* parent = 0 );
+ ~PrettyItemDelegate();
+
+ QSize sizeHint( const QStyleOptionViewItem&, const QModelIndex& ) const;
+ void paint( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+
+private:
+ void createPlayIcon();
+ void paintBody( QPainter*, const QStyleOptionViewItem&, const QModelIndex& ) const;
+ QPointF centerImage( const QPixmap&, const QRectF& ) const;
+
+ // active track painting
+ void paintActiveOverlay( QPainter *painter, qreal x, qreal y, qreal w, qreal h ) const;
+ void paintPlayIcon(QPainter *painter) const;
+
+ // Paints the video duration
+ void drawTime(QPainter *painter, QString time, QRectF line) const;
+
+ static const qreal THUMB_WIDTH;
+ static const qreal THUMB_HEIGHT;
+ static const qreal PADDING;
+
+ QPixmap playIcon;
+ QFont boldFont;
+ QFont smallerFont;
+ QFont smallerBoldFont;
+};
+
+#endif
--- /dev/null
+#include "playlistwidget.h"
+
+PlaylistWidget::PlaylistWidget (QWidget *parent, THBlackBar *tabBar, QListView *listView)
+ : QWidget(parent) {
+ QBoxLayout *layout = new QVBoxLayout();
+ layout->setMargin(0);
+ layout->setSpacing(0);
+ layout->addWidget(tabBar);
+ layout->addWidget(listView);
+ setLayout(layout);
+}
--- /dev/null
+#ifndef PLAYLISTWIDGET_H
+#define PLAYLISTWIDGET_H
+
+#include <QtGui>
+#include "thblackbar.h"
+
+class PlaylistWidget : public QWidget
+{
+public:
+ PlaylistWidget(QWidget *parent, THBlackBar *tabBar, QListView *listView);
+};
+
+#endif // PLAYLISTWIDGET_H
--- /dev/null
+#include "qtlockedfile.h"
--- /dev/null
+#include "qtsingleapplication.h"
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#include "qtlocalpeer.h"
+#include <QtCore/QCoreApplication>
+#include <QtCore/QTime>
+
+#if defined(Q_OS_WIN)
+#include <QtCore/QLibrary>
+#include <QtCore/qt_windows.h>
+typedef BOOL(WINAPI*PProcessIdToSessionId)(DWORD,DWORD*);
+static PProcessIdToSessionId pProcessIdToSessionId = 0;
+#endif
+#if defined(Q_OS_UNIX)
+#include <time.h>
+#endif
+
+namespace QtLP_Private {
+#include "qtlockedfile.cpp"
+#if defined(Q_OS_WIN)
+#include "qtlockedfile_win.cpp"
+#else
+#include "qtlockedfile_unix.cpp"
+#endif
+}
+
+const char* QtLocalPeer::ack = "ack";
+
+QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId)
+ : QObject(parent), id(appId)
+{
+ QString prefix = id;
+ if (id.isEmpty()) {
+ id = QCoreApplication::applicationFilePath();
+#if defined(Q_OS_WIN)
+ id = id.toLower();
+#endif
+ prefix = id.section(QLatin1Char('/'), -1);
+ }
+ prefix.remove(QRegExp("[^a-zA-Z]"));
+ prefix.truncate(6);
+
+ QByteArray idc = id.toUtf8();
+ quint16 idNum = qChecksum(idc.constData(), idc.size());
+ socketName = QLatin1String("qtsingleapp-") + prefix
+ + QLatin1Char('-') + QString::number(idNum, 16);
+
+#if defined(Q_OS_WIN)
+ if (!pProcessIdToSessionId) {
+ QLibrary lib("kernel32");
+ pProcessIdToSessionId = (PProcessIdToSessionId)lib.resolve("ProcessIdToSessionId");
+ }
+ if (pProcessIdToSessionId) {
+ DWORD sessionId = 0;
+ pProcessIdToSessionId(GetCurrentProcessId(), &sessionId);
+ socketName += QLatin1Char('-') + QString::number(sessionId, 16);
+ }
+#else
+ socketName += QLatin1Char('-') + QString::number(::getuid(), 16);
+#endif
+
+ server = new QLocalServer(this);
+ QString lockName = QDir(QDir::tempPath()).absolutePath()
+ + QLatin1Char('/') + socketName
+ + QLatin1String("-lockfile");
+ lockFile.setFileName(lockName);
+ lockFile.open(QIODevice::ReadWrite);
+}
+
+
+
+bool QtLocalPeer::isClient()
+{
+ if (lockFile.isLocked())
+ return false;
+
+ if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
+ return true;
+
+ bool res = server->listen(socketName);
+#if defined(Q_OS_UNIX) && (QT_VERSION >= QT_VERSION_CHECK(4,5,0))
+ // ### Workaround
+ if (!res && server->serverError() == QAbstractSocket::AddressInUseError) {
+ QFile::remove(QDir::cleanPath(QDir::tempPath())+QLatin1Char('/')+socketName);
+ res = server->listen(socketName);
+ }
+#endif
+ if (!res)
+ qWarning("QtSingleCoreApplication: listen on local socket failed, %s", qPrintable(server->errorString()));
+ QObject::connect(server, SIGNAL(newConnection()), SLOT(receiveConnection()));
+ return false;
+}
+
+
+bool QtLocalPeer::sendMessage(const QString &message, int timeout)
+{
+ if (!isClient())
+ return false;
+
+ QLocalSocket socket;
+ bool connOk = false;
+ for(int i = 0; i < 2; i++) {
+ // Try twice, in case the other instance is just starting up
+ socket.connectToServer(socketName);
+ connOk = socket.waitForConnected(timeout/2);
+ if (connOk || i)
+ break;
+ int ms = 250;
+#if defined(Q_OS_WIN)
+ Sleep(DWORD(ms));
+#else
+ struct timespec ts = { ms / 1000, (ms % 1000) * 1000 * 1000 };
+ nanosleep(&ts, NULL);
+#endif
+ }
+ if (!connOk)
+ return false;
+
+ QByteArray uMsg(message.toUtf8());
+ QDataStream ds(&socket);
+ ds.writeBytes(uMsg.constData(), uMsg.size());
+ bool res = socket.waitForBytesWritten(timeout);
+ res &= socket.waitForReadyRead(timeout); // wait for ack
+ res &= (socket.read(qstrlen(ack)) == ack);
+ return res;
+}
+
+
+void QtLocalPeer::receiveConnection()
+{
+ QLocalSocket* socket = server->nextPendingConnection();
+ if (!socket)
+ return;
+
+ while (socket->bytesAvailable() < (int)sizeof(quint32))
+ socket->waitForReadyRead();
+ QDataStream ds(socket);
+ QByteArray uMsg;
+ quint32 remaining;
+ ds >> remaining;
+ uMsg.resize(remaining);
+ int got = 0;
+ char* uMsgBuf = uMsg.data();
+ do {
+ got = ds.readRawData(uMsgBuf, remaining);
+ remaining -= got;
+ uMsgBuf += got;
+ } while (remaining && got >= 0 && socket->waitForReadyRead(2000));
+ if (got < 0) {
+ qWarning() << "QtLocalPeer: Message reception failed" << socket->errorString();
+ delete socket;
+ return;
+ }
+ QString message(QString::fromUtf8(uMsg));
+ socket->write(ack, qstrlen(ack));
+ socket->waitForBytesWritten(1000);
+ delete socket;
+ emit messageReceived(message); //### (might take a long time to return)
+}
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#include <QtNetwork/QLocalServer>
+#include <QtNetwork/QLocalSocket>
+#include <QtCore/QDir>
+
+namespace QtLP_Private {
+#include "qtlockedfile.h"
+}
+
+class QtLocalPeer : public QObject
+{
+ Q_OBJECT
+
+public:
+ QtLocalPeer(QObject *parent = 0, const QString &appId = QString());
+ bool isClient();
+ bool sendMessage(const QString &message, int timeout);
+ QString applicationId() const
+ { return id; }
+
+Q_SIGNALS:
+ void messageReceived(const QString &message);
+
+protected Q_SLOTS:
+ void receiveConnection();
+
+protected:
+ QString id;
+ QString socketName;
+ QLocalServer* server;
+ QtLP_Private::QtLockedFile lockFile;
+
+private:
+ static const char* ack;
+};
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+#include "qtlockedfile.h"
+
+/*!
+ \class QtLockedFile
+
+ \brief The QtLockedFile class extends QFile with advisory locking
+ functions.
+
+ A file may be locked in read or write mode. Multiple instances of
+ \e QtLockedFile, created in multiple processes running on the same
+ machine, may have a file locked in read mode. Exactly one instance
+ may have it locked in write mode. A read and a write lock cannot
+ exist simultaneously on the same file.
+
+ The file locks are advisory. This means that nothing prevents
+ another process from manipulating a locked file using QFile or
+ file system functions offered by the OS. Serialization is only
+ guaranteed if all processes that access the file use
+ QLockedFile. Also, while holding a lock on a file, a process
+ must not open the same file again (through any API), or locks
+ can be unexpectedly lost.
+
+ The lock provided by an instance of \e QtLockedFile is released
+ whenever the program terminates. This is true even when the
+ program crashes and no destructors are called.
+*/
+
+/*! \enum QtLockedFile::LockMode
+
+ This enum describes the available lock modes.
+
+ \value ReadLock A read lock.
+ \value WriteLock A write lock.
+ \value NoLock Neither a read lock nor a write lock.
+*/
+
+/*!
+ Constructs an unlocked \e QtLockedFile object. This constructor
+ behaves in the same way as \e QFile::QFile().
+
+ \sa QFile::QFile()
+*/
+QtLockedFile::QtLockedFile()
+ : QFile()
+{
+#ifdef Q_OS_WIN
+ wmutex = 0;
+ rmutex = 0;
+#endif
+ m_lock_mode = NoLock;
+}
+
+/*!
+ Constructs an unlocked QtLockedFile object with file \a name. This
+ constructor behaves in the same way as \e QFile::QFile(const
+ QString&).
+
+ \sa QFile::QFile()
+*/
+QtLockedFile::QtLockedFile(const QString &name)
+ : QFile(name)
+{
+#ifdef Q_OS_WIN
+ wmutex = 0;
+ rmutex = 0;
+#endif
+ m_lock_mode = NoLock;
+}
+
+/*!
+ Opens the file in OpenMode \a mode.
+
+ This is identical to QFile::open(), with the one exception that the
+ Truncate mode flag is disallowed. Truncation would conflict with the
+ advisory file locking, since the file would be modified before the
+ write lock is obtained. If truncation is required, use resize(0)
+ after obtaining the write lock.
+
+ Returns true if successful; otherwise false.
+
+ \sa QFile::open(), QFile::resize()
+*/
+bool QtLockedFile::open(OpenMode mode)
+{
+ if (mode & QIODevice::Truncate) {
+ qWarning("QtLockedFile::open(): Truncate mode not allowed.");
+ return false;
+ }
+ return QFile::open(mode);
+}
+
+/*!
+ Returns \e true if this object has a in read or write lock;
+ otherwise returns \e false.
+
+ \sa lockMode()
+*/
+bool QtLockedFile::isLocked() const
+{
+ return m_lock_mode != NoLock;
+}
+
+/*!
+ Returns the type of lock currently held by this object, or \e
+ QtLockedFile::NoLock.
+
+ \sa isLocked()
+*/
+QtLockedFile::LockMode QtLockedFile::lockMode() const
+{
+ return m_lock_mode;
+}
+
+/*!
+ \fn bool QtLockedFile::lock(LockMode mode, bool block = true)
+
+ Obtains a lock of type \a mode. The file must be opened before it
+ can be locked.
+
+ If \a block is true, this function will block until the lock is
+ aquired. If \a block is false, this function returns \e false
+ immediately if the lock cannot be aquired.
+
+ If this object already has a lock of type \a mode, this function
+ returns \e true immediately. If this object has a lock of a
+ different type than \a mode, the lock is first released and then a
+ new lock is obtained.
+
+ This function returns \e true if, after it executes, the file is
+ locked by this object, and \e false otherwise.
+
+ \sa unlock(), isLocked(), lockMode()
+*/
+
+/*!
+ \fn bool QtLockedFile::unlock()
+
+ Releases a lock.
+
+ If the object has no lock, this function returns immediately.
+
+ This function returns \e true if, after it executes, the file is
+ not locked by this object, and \e false otherwise.
+
+ \sa lock(), isLocked(), lockMode()
+*/
+
+/*!
+ \fn QtLockedFile::~QtLockedFile()
+
+ Destroys the \e QtLockedFile object. If any locks were held, they
+ are released.
+*/
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+#ifndef QTLOCKEDFILE_H
+#define QTLOCKEDFILE_H
+
+#include <QtCore/QFile>
+#ifdef Q_OS_WIN
+#include <QtCore/QVector>
+#endif
+
+#if defined(Q_WS_WIN)
+# if !defined(QT_QTLOCKEDFILE_EXPORT) && !defined(QT_QTLOCKEDFILE_IMPORT)
+# define QT_QTLOCKEDFILE_EXPORT
+# elif defined(QT_QTLOCKEDFILE_IMPORT)
+# if defined(QT_QTLOCKEDFILE_EXPORT)
+# undef QT_QTLOCKEDFILE_EXPORT
+# endif
+# define QT_QTLOCKEDFILE_EXPORT __declspec(dllimport)
+# elif defined(QT_QTLOCKEDFILE_EXPORT)
+# undef QT_QTLOCKEDFILE_EXPORT
+# define QT_QTLOCKEDFILE_EXPORT __declspec(dllexport)
+# endif
+#else
+# define QT_QTLOCKEDFILE_EXPORT
+#endif
+
+class QT_QTLOCKEDFILE_EXPORT QtLockedFile : public QFile
+{
+public:
+ enum LockMode { NoLock = 0, ReadLock, WriteLock };
+
+ QtLockedFile();
+ QtLockedFile(const QString &name);
+ ~QtLockedFile();
+
+ bool open(OpenMode mode);
+
+ bool lock(LockMode mode, bool block = true);
+ bool unlock();
+ bool isLocked() const;
+ LockMode lockMode() const;
+
+private:
+#ifdef Q_OS_WIN
+ Qt::HANDLE wmutex;
+ Qt::HANDLE rmutex;
+ QVector<Qt::HANDLE> rmutexes;
+ QString mutexname;
+
+ Qt::HANDLE getMutexHandle(int idx, bool doCreate);
+ bool waitMutex(Qt::HANDLE mutex, bool doBlock);
+
+#endif
+ LockMode m_lock_mode;
+};
+
+#endif
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "qtlockedfile.h"
+
+bool QtLockedFile::lock(LockMode mode, bool block)
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::lock(): file is not opened");
+ return false;
+ }
+
+ if (mode == NoLock)
+ return unlock();
+
+ if (mode == m_lock_mode)
+ return true;
+
+ if (m_lock_mode != NoLock)
+ unlock();
+
+ struct flock fl;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_type = (mode == ReadLock) ? F_RDLCK : F_WRLCK;
+ int cmd = block ? F_SETLKW : F_SETLK;
+ int ret = fcntl(handle(), cmd, &fl);
+
+ if (ret == -1) {
+ if (errno != EINTR && errno != EAGAIN)
+ qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
+ return false;
+ }
+
+
+ m_lock_mode = mode;
+ return true;
+}
+
+
+bool QtLockedFile::unlock()
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::unlock(): file is not opened");
+ return false;
+ }
+
+ if (!isLocked())
+ return true;
+
+ struct flock fl;
+ fl.l_whence = SEEK_SET;
+ fl.l_start = 0;
+ fl.l_len = 0;
+ fl.l_type = F_UNLCK;
+ int ret = fcntl(handle(), F_SETLKW, &fl);
+
+ if (ret == -1) {
+ qWarning("QtLockedFile::lock(): fcntl: %s", strerror(errno));
+ return false;
+ }
+
+ m_lock_mode = NoLock;
+ return true;
+}
+
+QtLockedFile::~QtLockedFile()
+{
+ if (isOpen())
+ unlock();
+}
+
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+#include "qtlockedfile.h"
+#include <qt_windows.h>
+#include <QtCore/QFileInfo>
+
+#define MUTEX_PREFIX "QtLockedFile mutex "
+// Maximum number of concurrent read locks. Must not be greater than MAXIMUM_WAIT_OBJECTS
+#define MAX_READERS MAXIMUM_WAIT_OBJECTS
+
+Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
+{
+ if (mutexname.isEmpty()) {
+ QFileInfo fi(*this);
+ mutexname = QString::fromLatin1(MUTEX_PREFIX)
+ + fi.absoluteFilePath().toLower();
+ }
+ QString mname(mutexname);
+ if (idx >= 0)
+ mname += QString::number(idx);
+
+ Qt::HANDLE mutex;
+ if (doCreate) {
+ QT_WA( { mutex = CreateMutexW(NULL, FALSE, (TCHAR*)mname.utf16()); },
+ { mutex = CreateMutexA(NULL, FALSE, mname.toLocal8Bit().constData()); } );
+ if (!mutex) {
+ qErrnoWarning("QtLockedFile::lock(): CreateMutex failed");
+ return 0;
+ }
+ }
+ else {
+ QT_WA( { mutex = OpenMutexW(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, (TCHAR*)mname.utf16()); },
+ { mutex = OpenMutexA(SYNCHRONIZE | MUTEX_MODIFY_STATE, FALSE, mname.toLocal8Bit().constData()); } );
+ if (!mutex) {
+ if (GetLastError() != ERROR_FILE_NOT_FOUND)
+ qErrnoWarning("QtLockedFile::lock(): OpenMutex failed");
+ return 0;
+ }
+ }
+ return mutex;
+}
+
+bool QtLockedFile::waitMutex(Qt::HANDLE mutex, bool doBlock)
+{
+ Q_ASSERT(mutex);
+ DWORD res = WaitForSingleObject(mutex, doBlock ? INFINITE : 0);
+ switch (res) {
+ case WAIT_OBJECT_0:
+ case WAIT_ABANDONED:
+ return true;
+ break;
+ case WAIT_TIMEOUT:
+ break;
+ default:
+ qErrnoWarning("QtLockedFile::lock(): WaitForSingleObject failed");
+ }
+ return false;
+}
+
+
+
+bool QtLockedFile::lock(LockMode mode, bool block)
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::lock(): file is not opened");
+ return false;
+ }
+
+ if (mode == NoLock)
+ return unlock();
+
+ if (mode == m_lock_mode)
+ return true;
+
+ if (m_lock_mode != NoLock)
+ unlock();
+
+ if (!wmutex && !(wmutex = getMutexHandle(-1, true)))
+ return false;
+
+ if (!waitMutex(wmutex, block))
+ return false;
+
+ if (mode == ReadLock) {
+ int idx = 0;
+ for (; idx < MAX_READERS; idx++) {
+ rmutex = getMutexHandle(idx, false);
+ if (!rmutex || waitMutex(rmutex, false))
+ break;
+ CloseHandle(rmutex);
+ }
+ bool ok = true;
+ if (idx >= MAX_READERS) {
+ qWarning("QtLockedFile::lock(): too many readers");
+ rmutex = 0;
+ ok = false;
+ }
+ else if (!rmutex) {
+ rmutex = getMutexHandle(idx, true);
+ if (!rmutex || !waitMutex(rmutex, false))
+ ok = false;
+ }
+ if (!ok && rmutex) {
+ CloseHandle(rmutex);
+ rmutex = 0;
+ }
+ ReleaseMutex(wmutex);
+ if (!ok)
+ return false;
+ }
+ else {
+ Q_ASSERT(rmutexes.isEmpty());
+ for (int i = 0; i < MAX_READERS; i++) {
+ Qt::HANDLE mutex = getMutexHandle(i, false);
+ if (mutex)
+ rmutexes.append(mutex);
+ }
+ if (rmutexes.size()) {
+ DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
+ TRUE, block ? INFINITE : 0);
+ if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
+ if (res != WAIT_TIMEOUT)
+ qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
+ m_lock_mode = WriteLock; // trick unlock() to clean up - semiyucky
+ unlock();
+ return false;
+ }
+ }
+ }
+
+ m_lock_mode = mode;
+ return true;
+}
+
+bool QtLockedFile::unlock()
+{
+ if (!isOpen()) {
+ qWarning("QtLockedFile::unlock(): file is not opened");
+ return false;
+ }
+
+ if (!isLocked())
+ return true;
+
+ if (m_lock_mode == ReadLock) {
+ ReleaseMutex(rmutex);
+ CloseHandle(rmutex);
+ rmutex = 0;
+ }
+ else {
+ foreach(Qt::HANDLE mutex, rmutexes) {
+ ReleaseMutex(mutex);
+ CloseHandle(mutex);
+ }
+ rmutexes.clear();
+ ReleaseMutex(wmutex);
+ }
+
+ m_lock_mode = QtLockedFile::NoLock;
+ return true;
+}
+
+QtLockedFile::~QtLockedFile()
+{
+ if (isOpen())
+ unlock();
+ if (wmutex)
+ CloseHandle(wmutex);
+}
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#include "qtsingleapplication.h"
+#include "qtlocalpeer.h"
+#include <QtGui/QWidget>
+
+
+/*!
+ \class QtSingleApplication qtsingleapplication.h
+ \brief The QtSingleApplication class provides an API to detect and
+ communicate with running instances of an application.
+
+ This class allows you to create applications where only one
+ instance should be running at a time. I.e., if the user tries to
+ launch another instance, the already running instance will be
+ activated instead. Another usecase is a client-server system,
+ where the first started instance will assume the role of server,
+ and the later instances will act as clients of that server.
+
+ By default, the full path of the executable file is used to
+ determine whether two processes are instances of the same
+ application. You can also provide an explicit identifier string
+ that will be compared instead.
+
+ The application should create the QtSingleApplication object early
+ in the startup phase, and call isRunning() or sendMessage() to
+ find out if another instance of this application is already
+ running. Startup parameters (e.g. the name of the file the user
+ wanted this new instance to open) can be passed to the running
+ instance in the sendMessage() function.
+
+ If isRunning() or sendMessage() returns false, it means that no
+ other instance is running, and this instance has assumed the role
+ as the running instance. The application should continue with the
+ initialization of the application user interface before entering
+ the event loop with exec(), as normal. The messageReceived()
+ signal will be emitted when the application receives messages from
+ another instance of the same application.
+
+ If isRunning() or sendMessage() returns true, another instance is
+ already running, and the application should terminate or enter
+ client mode.
+
+ If a message is received it might be helpful to the user to raise
+ the application so that it becomes visible. To facilitate this,
+ QtSingleApplication provides the setActivationWindow() function
+ and the activateWindow() slot.
+
+ Here's an example that shows how to convert an existing
+ application to use QtSingleApplication. It is very simple and does
+ not make use of all QtSingleApplication's functionality (see the
+ examples for that).
+
+ \code
+ // Original
+ int main(int argc, char **argv)
+ {
+ QApplication app(argc, argv);
+
+ MyMainWidget mmw;
+
+ mmw.show();
+ return app.exec();
+ }
+
+ // Single instance
+ int main(int argc, char **argv)
+ {
+ QtSingleApplication app(argc, argv);
+
+ if (app.isRunning())
+ return 0;
+
+ MyMainWidget mmw;
+
+ app.setActivationWindow(&mmw);
+
+ mmw.show();
+ return app.exec();
+ }
+ \endcode
+
+ Once this QtSingleApplication instance is destroyed(for example,
+ when the user quits), when the user next attempts to run the
+ application this instance will not, of course, be encountered. The
+ next instance to call isRunning() or sendMessage() will assume the
+ role as the new running instance.
+
+ For console (non-GUI) applications, QtSingleCoreApplication may be
+ used instead of this class, to avoid the dependency on the QtGui
+ library.
+
+ \sa QtSingleCoreApplication
+*/
+
+
+void QtSingleApplication::sysInit(const QString &appId)
+{
+ actWin = 0;
+ peer = new QtLocalPeer(this, appId);
+ connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
+}
+
+
+/*!
+ Creates a QtSingleApplication object. The application identifier
+ will be QCoreApplication::applicationFilePath(). \a argc, \a
+ argv, and \a GUIenabled are passed on to the QAppliation constructor.
+
+ If you are creating a console application (i.e. setting \a
+ GUIenabled to false), you may consider using
+ QtSingleCoreApplication instead.
+*/
+
+QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
+ : QApplication(argc, argv, GUIenabled)
+{
+ sysInit();
+}
+
+
+/*!
+ Creates a QtSingleApplication object with the application
+ identifier \a appId. \a argc and \a argv are passed on to the
+ QAppliation constructor.
+*/
+
+QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
+ : QApplication(argc, argv)
+{
+ sysInit(appId);
+}
+
+
+/*!
+ Creates a QtSingleApplication object. The application identifier
+ will be QCoreApplication::applicationFilePath(). \a argc, \a
+ argv, and \a type are passed on to the QAppliation constructor.
+*/
+QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
+ : QApplication(argc, argv, type)
+{
+ sysInit();
+}
+
+
+#if defined(Q_WS_X11)
+/*!
+ Special constructor for X11, ref. the documentation of
+ QApplication's corresponding constructor. The application identifier
+ will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
+ and \a cmap are passed on to the QApplication constructor.
+*/
+QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
+ : QApplication(dpy, visual, cmap)
+{
+ sysInit();
+}
+
+/*!
+ Special constructor for X11, ref. the documentation of
+ QApplication's corresponding constructor. The application identifier
+ will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
+ argv, \a visual, and \a cmap are passed on to the QApplication
+ constructor.
+*/
+QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
+ : QApplication(dpy, argc, argv, visual, cmap)
+{
+ sysInit();
+}
+
+/*!
+ Special constructor for X11, ref. the documentation of
+ QApplication's corresponding constructor. The application identifier
+ will be \a appId. \a dpy, \a argc, \a
+ argv, \a visual, and \a cmap are passed on to the QApplication
+ constructor.
+*/
+QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
+ : QApplication(dpy, argc, argv, visual, cmap)
+{
+ sysInit(appId);
+}
+#endif
+
+
+/*!
+ Returns true if another instance of this application is running;
+ otherwise false.
+
+ This function does not find instances of this application that are
+ being run by a different user (on Windows: that are running in
+ another session).
+
+ \sa sendMessage()
+*/
+
+bool QtSingleApplication::isRunning()
+{
+ return peer->isClient();
+}
+
+
+/*!
+ Tries to send the text \a message to the currently running
+ instance. The QtSingleApplication object in the running instance
+ will emit the messageReceived() signal when it receives the
+ message.
+
+ This function returns true if the message has been sent to, and
+ processed by, the current instance. If there is no instance
+ currently running, or if the running instance fails to process the
+ message within \a timeout milliseconds, this function return false.
+
+ \sa isRunning(), messageReceived()
+*/
+bool QtSingleApplication::sendMessage(const QString &message, int timeout)
+{
+ return peer->sendMessage(message, timeout);
+}
+
+
+/*!
+ Returns the application identifier. Two processes with the same
+ identifier will be regarded as instances of the same application.
+*/
+QString QtSingleApplication::id() const
+{
+ return peer->applicationId();
+}
+
+
+/*!
+ Sets the activation window of this application to \a aw. The
+ activation window is the widget that will be activated by
+ activateWindow(). This is typically the application's main window.
+
+ If \a activateOnMessage is true (the default), the window will be
+ activated automatically every time a message is received, just prior
+ to the messageReceived() signal being emitted.
+
+ \sa activateWindow(), messageReceived()
+*/
+
+void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
+{
+ actWin = aw;
+ if (activateOnMessage)
+ connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
+ else
+ disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
+}
+
+
+/*!
+ Returns the applications activation window if one has been set by
+ calling setActivationWindow(), otherwise returns 0.
+
+ \sa setActivationWindow()
+*/
+QWidget* QtSingleApplication::activationWindow() const
+{
+ return actWin;
+}
+
+
+/*!
+ De-minimizes, raises, and activates this application's activation window.
+ This function does nothing if no activation window has been set.
+
+ This is a convenience function to show the user that this
+ application instance has been activated when he has tried to start
+ another instance.
+
+ This function should typically be called in response to the
+ messageReceived() signal. By default, that will happen
+ automatically, if an activation window has been set.
+
+ \sa setActivationWindow(), messageReceived(), initialize()
+*/
+void QtSingleApplication::activateWindow()
+{
+ if (actWin) {
+ actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
+ actWin->raise();
+ actWin->activateWindow();
+ }
+}
+
+
+/*!
+ \fn void QtSingleApplication::messageReceived(const QString& message)
+
+ This signal is emitted when the current instance receives a \a
+ message from another instance of this application.
+
+ \sa sendMessage(), setActivationWindow(), activateWindow()
+*/
+
+
+/*!
+ \fn void QtSingleApplication::initialize(bool dummy = true)
+
+ \obsolete
+*/
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#include <QtGui/QApplication>
+
+class QtLocalPeer;
+
+#if defined(Q_WS_WIN)
+# if !defined(QT_QTSINGLEAPPLICATION_EXPORT) && !defined(QT_QTSINGLEAPPLICATION_IMPORT)
+# define QT_QTSINGLEAPPLICATION_EXPORT
+# elif defined(QT_QTSINGLEAPPLICATION_IMPORT)
+# if defined(QT_QTSINGLEAPPLICATION_EXPORT)
+# undef QT_QTSINGLEAPPLICATION_EXPORT
+# endif
+# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllimport)
+# elif defined(QT_QTSINGLEAPPLICATION_EXPORT)
+# undef QT_QTSINGLEAPPLICATION_EXPORT
+# define QT_QTSINGLEAPPLICATION_EXPORT __declspec(dllexport)
+# endif
+#else
+# define QT_QTSINGLEAPPLICATION_EXPORT
+#endif
+
+class QT_QTSINGLEAPPLICATION_EXPORT QtSingleApplication : public QApplication
+{
+ Q_OBJECT
+
+public:
+ QtSingleApplication(int &argc, char **argv, bool GUIenabled = true);
+ QtSingleApplication(const QString &id, int &argc, char **argv);
+ QtSingleApplication(int &argc, char **argv, Type type);
+#if defined(Q_WS_X11)
+ QtSingleApplication(Display* dpy, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
+ QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE cmap= 0);
+ QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual = 0, Qt::HANDLE colormap = 0);
+#endif
+
+ bool isRunning();
+ QString id() const;
+
+ void setActivationWindow(QWidget* aw, bool activateOnMessage = true);
+ QWidget* activationWindow() const;
+
+ // Obsolete:
+ void initialize(bool dummy = true)
+ { isRunning(); Q_UNUSED(dummy) }
+
+public Q_SLOTS:
+ bool sendMessage(const QString &message, int timeout = 5000);
+ void activateWindow();
+
+
+Q_SIGNALS:
+ void messageReceived(const QString &message);
+
+
+private:
+ void sysInit(const QString &appId = QString());
+ QtLocalPeer *peer;
+ QWidget *actWin;
+};
--- /dev/null
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+QT *= network
+
+qtsingleapplication-uselib:!qtsingleapplication-buildlib {
+ LIBS += -L$$QTSINGLEAPPLICATION_LIBDIR -l$$QTSINGLEAPPLICATION_LIBNAME
+} else {
+ SOURCES += $$PWD/qtsingleapplication.cpp $$PWD/qtlocalpeer.cpp
+ HEADERS += $$PWD/qtsingleapplication.h $$PWD/qtlocalpeer.h
+}
+
+win32 {
+ contains(TEMPLATE, lib):contains(CONFIG, shared):DEFINES += QT_QTSINGLEAPPLICATION_EXPORT
+ else:qtsingleapplication-uselib:DEFINES += QT_QTSINGLEAPPLICATION_IMPORT
+}
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#include "qtsinglecoreapplication.h"
+#include "qtlocalpeer.h"
+
+/*!
+ \class QtSingleCoreApplication qtsinglecoreapplication.h
+ \brief A variant of the QtSingleApplication class for non-GUI applications.
+
+ This class is a variant of QtSingleApplication suited for use in
+ console (non-GUI) applications. It is an extension of
+ QCoreApplication (instead of QApplication). It does not require
+ the QtGui library.
+
+ The API and usage is identical to QtSingleApplication, except that
+ functions relating to the "activation window" are not present, for
+ obvious reasons. Please refer to the QtSingleApplication
+ documentation for explanation of the usage.
+
+ A QtSingleCoreApplication instance can communicate to a
+ QtSingleApplication instance if they share the same application
+ id. Hence, this class can be used to create a light-weight
+ command-line tool that sends commands to a GUI application.
+
+ \sa QtSingleApplication
+*/
+
+/*!
+ Creates a QtSingleCoreApplication object. The application identifier
+ will be QCoreApplication::applicationFilePath(). \a argc and \a
+ argv are passed on to the QCoreAppliation constructor.
+*/
+
+QtSingleCoreApplication::QtSingleCoreApplication(int &argc, char **argv)
+ : QCoreApplication(argc, argv)
+{
+ peer = new QtLocalPeer(this);
+ connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
+}
+
+
+/*!
+ Creates a QtSingleCoreApplication object with the application
+ identifier \a appId. \a argc and \a argv are passed on to the
+ QCoreAppliation constructor.
+*/
+QtSingleCoreApplication::QtSingleCoreApplication(const QString &appId, int &argc, char **argv)
+ : QCoreApplication(argc, argv)
+{
+ peer = new QtLocalPeer(this, appId);
+ connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
+}
+
+
+/*!
+ Returns true if another instance of this application is running;
+ otherwise false.
+
+ This function does not find instances of this application that are
+ being run by a different user (on Windows: that are running in
+ another session).
+
+ \sa sendMessage()
+*/
+
+bool QtSingleCoreApplication::isRunning()
+{
+ return peer->isClient();
+}
+
+
+/*!
+ Tries to send the text \a message to the currently running
+ instance. The QtSingleCoreApplication object in the running instance
+ will emit the messageReceived() signal when it receives the
+ message.
+
+ This function returns true if the message has been sent to, and
+ processed by, the current instance. If there is no instance
+ currently running, or if the running instance fails to process the
+ message within \a timeout milliseconds, this function return false.
+
+ \sa isRunning(), messageReceived()
+*/
+
+bool QtSingleCoreApplication::sendMessage(const QString &message, int timeout)
+{
+ return peer->sendMessage(message, timeout);
+}
+
+
+/*!
+ Returns the application identifier. Two processes with the same
+ identifier will be regarded as instances of the same application.
+*/
+
+QString QtSingleCoreApplication::id() const
+{
+ return peer->applicationId();
+}
+
+
+/*!
+ \fn void QtSingleCoreApplication::messageReceived(const QString& message)
+
+ This signal is emitted when the current instance receives a \a
+ message from another instance of this application.
+
+ \sa sendMessage()
+*/
--- /dev/null
+/****************************************************************************
+**
+** This file is part of a Qt Solutions component.
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Solutions Commercial License Agreement provided
+** with the Software or, alternatively, in accordance with the terms
+** contained in a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** Please note Third Party Software included with Qt Solutions may impose
+** additional restrictions and it is the user's responsibility to ensure
+** that they have met the licensing requirements of the GPL, LGPL, or Qt
+** Solutions Commercial license and the relevant license of the Third
+** Party Software they are using.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+**
+****************************************************************************/
+
+
+#include <QtCore/QCoreApplication>
+
+class QtLocalPeer;
+
+class QtSingleCoreApplication : public QCoreApplication
+{
+ Q_OBJECT
+
+public:
+ QtSingleCoreApplication(int &argc, char **argv);
+ QtSingleCoreApplication(const QString &id, int &argc, char **argv);
+
+ bool isRunning();
+ QString id() const;
+
+public Q_SLOTS:
+ bool sendMessage(const QString &message, int timeout = 5000);
+
+
+Q_SIGNALS:
+ void messageReceived(const QString &message);
+
+
+private:
+ QtLocalPeer* peer;
+};
--- /dev/null
+INCLUDEPATH += $$PWD
+DEPENDPATH += $$PWD
+HEADERS += $$PWD/qtsinglecoreapplication.h $$PWD/qtlocalpeer.h
+SOURCES += $$PWD/qtsinglecoreapplication.cpp $$PWD/qtlocalpeer.cpp
+
+QT *= network
+
+win32:contains(TEMPLATE, lib):contains(CONFIG, shared) {
+ DEFINES += QT_QTSINGLECOREAPPLICATION_EXPORT=__declspec(dllexport)
+}
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "searchlineedit.h"
+
+#include <QtGui/QPainter>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QMenu>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOptionFrameV2>
+
+#include "googlesuggest.h"
+
+ClearButton::ClearButton(QWidget *parent)
+ : QAbstractButton(parent)
+{
+ setCursor(Qt::ArrowCursor);
+ setToolTip(tr("Clear"));
+ setVisible(false);
+ setFocusPolicy(Qt::NoFocus);
+}
+
+void ClearButton::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+ QPainter painter(this);
+ int height = this->height();
+
+ painter.setRenderHint(QPainter::Antialiasing, true);
+ QColor color = palette().color(QPalette::Mid);
+ painter.setBrush(isDown()
+ ? palette().color(QPalette::Dark)
+ : palette().color(QPalette::Mid));
+ painter.setPen(painter.brush().color());
+ int size = width();
+ int offset = size / 3.5;
+ int radius = size - offset * 2;
+ painter.drawEllipse(offset, offset, radius, radius);
+
+ painter.setPen(QPen(palette().color(QPalette::Base),2));
+ int border = offset * 1.6;
+ painter.drawLine(border, border, width() - border, height - border);
+ painter.drawLine(border, height - border, width() - border, border);
+}
+
+void ClearButton::textChanged(const QString &text)
+{
+ setVisible(!text.isEmpty());
+}
+
+/*
+ Search icon on the left hand side of the search widget
+ When a menu is set a down arrow appears
+ */
+class SearchButton : public QAbstractButton {
+public:
+ SearchButton(QWidget *parent = 0);
+ void paintEvent(QPaintEvent *event);
+ QMenu *m_menu;
+
+protected:
+ void mousePressEvent(QMouseEvent *event);
+};
+
+SearchButton::SearchButton(QWidget *parent)
+ : QAbstractButton(parent),
+ m_menu(0)
+{
+ setObjectName(QLatin1String("SearchButton"));
+ setCursor(Qt::ArrowCursor);
+ setFocusPolicy(Qt::NoFocus);
+}
+
+void SearchButton::mousePressEvent(QMouseEvent *event)
+{
+ if (m_menu && event->button() == Qt::LeftButton) {
+ QWidget *p = parentWidget();
+ if (p) {
+ QPoint r = p->mapToGlobal(QPoint(0, p->height()));
+ m_menu->exec(QPoint(r.x() + height() / 2, r.y()));
+ }
+ event->accept();
+ }
+ QAbstractButton::mousePressEvent(event);
+}
+
+void SearchButton::paintEvent(QPaintEvent *event)
+{
+ Q_UNUSED(event);
+ QPainterPath myPath;
+
+ int radius = (height() / 5) * 2;
+ QRect circle(height() / 5.5, height() / 3.5, radius, radius);
+ myPath.addEllipse(circle);
+
+ myPath.arcMoveTo(circle, 315);
+ QPointF c = myPath.currentPosition();
+ int diff = height() / 6;
+ myPath.lineTo(qMin(width() - 2, (int)c.x() + diff), c.y() + diff);
+
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::Antialiasing, true);
+ painter.setPen(QPen(palette().color(QPalette::Mid), height() / 10));
+ painter.drawPath(myPath);
+
+ if (m_menu) {
+ QPainterPath dropPath;
+ dropPath.arcMoveTo(circle, 320);
+ QPointF c = dropPath.currentPosition();
+ c = QPointF(c.x() + 3.5, c.y() + 0.5);
+ dropPath.moveTo(c);
+ dropPath.lineTo(c.x() + 4, c.y());
+ dropPath.lineTo(c.x() + 2, c.y() + 2);
+ dropPath.closeSubpath();
+ painter.setPen(Qt::darkGray);
+ painter.setBrush(Qt::darkGray);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ painter.drawPath(dropPath);
+ }
+ painter.end();
+}
+
+/*
+ SearchLineEdit is an enhanced QLineEdit
+ - A Search icon on the left with optional menu
+ - When there is no text and doesn't have focus an "inactive text" is displayed
+ - When there is text a clear button is displayed on the right hand side
+ */
+SearchLineEdit::SearchLineEdit(QWidget *parent) : ExLineEdit(parent),
+m_searchButton(new SearchButton(this))
+{
+ connect(lineEdit(), SIGNAL(textChanged(const QString &)),
+ this, SIGNAL(textChanged(const QString &)));
+
+ connect(lineEdit(), SIGNAL(returnPressed()),
+ this, SLOT(returnPressed()));
+
+ setLeftWidget(m_searchButton);
+ m_inactiveText = tr("Search");
+
+ QSizePolicy policy = sizePolicy();
+ setSizePolicy(QSizePolicy::Preferred, policy.verticalPolicy());
+
+ // completion
+ completion = new GSuggestCompletion(this, m_lineEdit);
+
+}
+
+void SearchLineEdit::paintEvent(QPaintEvent *event)
+{
+ if (lineEdit()->text().isEmpty() && !hasFocus() && !m_inactiveText.isEmpty()) {
+ ExLineEdit::paintEvent(event);
+ QStyleOptionFrameV2 panel;
+ initStyleOption(&panel);
+ QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
+ QFontMetrics fm = fontMetrics();
+ int horizontalMargin = lineEdit()->x();
+ QRect lineRect(horizontalMargin + r.x(), r.y() + (r.height() - fm.height() + 1) / 2,
+ r.width() - 2 * horizontalMargin, fm.height());
+ QPainter painter(this);
+ painter.setPen(palette().brush(QPalette::Disabled, QPalette::Text).color());
+ painter.drawText(lineRect, Qt::AlignLeft|Qt::AlignVCenter, m_inactiveText);
+ } else {
+ ExLineEdit::paintEvent(event);
+ }
+}
+
+void SearchLineEdit::resizeEvent(QResizeEvent *event)
+{
+ updateGeometries();
+ ExLineEdit::resizeEvent(event);
+}
+
+void SearchLineEdit::updateGeometries()
+{
+ int menuHeight = height();
+ int menuWidth = menuHeight + 1;
+ if (!m_searchButton->m_menu)
+ menuWidth = (menuHeight / 5) * 4;
+ m_searchButton->resize(QSize(menuWidth, menuHeight));
+}
+
+QString SearchLineEdit::inactiveText() const
+{
+ return m_inactiveText;
+}
+
+void SearchLineEdit::setInactiveText(const QString &text)
+{
+ m_inactiveText = text;
+}
+
+void SearchLineEdit::setMenu(QMenu *menu)
+{
+ if (m_searchButton->m_menu)
+ m_searchButton->m_menu->deleteLater();
+ m_searchButton->m_menu = menu;
+ updateGeometries();
+}
+
+QMenu *SearchLineEdit::menu() const
+{
+ if (!m_searchButton->m_menu) {
+ m_searchButton->m_menu = new QMenu(m_searchButton);
+ if (isVisible())
+ (const_cast<SearchLineEdit*>(this))->updateGeometries();
+ }
+ return m_searchButton->m_menu;
+}
+
+void SearchLineEdit::returnPressed()
+{
+ if (!lineEdit()->text().isEmpty()) {
+ completion->preventSuggest();
+ emit search(lineEdit()->text());
+ }
+}
+
+void SearchLineEdit::enableSuggest() {
+ completion->enableSuggest();
+}
+
+void SearchLineEdit::preventSuggest() {
+ completion->preventSuggest();
+}
+
+void SearchLineEdit::focusInEvent(QFocusEvent *event) {
+ ExLineEdit::focusInEvent(event);
+ enableSuggest();
+}
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef SEARCHLINEEDIT_H
+#define SEARCHLINEEDIT_H
+
+#include "urllineedit.h"
+
+#include <QtGui/QLineEdit>
+#include <QtGui/QAbstractButton>
+
+QT_BEGIN_NAMESPACE
+class QMenu;
+QT_END_NAMESPACE
+
+class SearchButton;
+class GSuggestCompletion;
+
+/*
+ Clear button on the right hand side of the search widget.
+ Hidden by default
+ "A circle with an X in it"
+ */
+class ClearButton : public QAbstractButton
+{
+ Q_OBJECT
+
+public:
+ ClearButton(QWidget *parent = 0);
+ void paintEvent(QPaintEvent *event);
+
+public slots:
+ void textChanged(const QString &text);
+};
+
+
+class SearchLineEdit : public ExLineEdit
+{
+ Q_OBJECT
+ Q_PROPERTY(QString inactiveText READ inactiveText WRITE setInactiveText)
+
+signals:
+ void textChanged(const QString &text);
+ void search(const QString &text);
+
+public:
+ SearchLineEdit(QWidget *parent = 0);
+
+ QString inactiveText() const;
+ void setInactiveText(const QString &text);
+
+ QMenu *menu() const;
+ void setMenu(QMenu *menu);
+ void updateGeometries();
+ void enableSuggest();
+ void preventSuggest();
+ void selectAll() { lineEdit()->selectAll(); };
+
+protected:
+ void resizeEvent(QResizeEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void focusInEvent(QFocusEvent *event);
+
+private slots:
+ void returnPressed();
+
+private:
+
+ SearchButton *m_searchButton;
+ QString m_inactiveText;
+
+ GSuggestCompletion *completion;
+};
+
+#endif // SEARCHLINEEDIT_H
+
--- /dev/null
+#include "searchparams.h"
+
+SearchParams::SearchParams() {
+ m_sortBy = SortByRelevance;
+}
--- /dev/null
+#ifndef SEARCHPARAMS_H
+#define SEARCHPARAMS_H
+
+#include <QObject>
+
+
+
+class SearchParams : public QObject {
+
+public:
+ SearchParams();
+
+ const QString keywords() const { return m_keywords; }
+ void setKeywords( QString keywords ) { m_keywords = keywords; }
+
+ int sortBy() const { return m_sortBy; }
+ void setSortBy( int sortBy ) { m_sortBy = sortBy; }
+
+ enum SortBy {
+ SortByRelevance = 1,
+ SortByNewest,
+ SortByViewCount
+ };
+
+private:
+ QString m_keywords;
+ int m_sortBy;
+
+};
+
+#endif // SEARCHPARAMS_H
--- /dev/null
+#include "spacer.h"
+
+Spacer::Spacer(QWidget *parent, QWidget *child) : QWidget(parent) {
+ QBoxLayout *layout = new QHBoxLayout();
+ layout->addWidget(child);
+ setLayout(layout);
+}
--- /dev/null
+#ifndef SPACER_H
+#define SPACER_H
+
+#include <QtGui>
+
+class Spacer : public QWidget
+{
+public:
+ Spacer(QWidget *parent, QWidget *child);
+};
+
+#endif // SPACER_H
--- /dev/null
+#include <QPainter>
+#include <QPaintEvent>
+#include <QList>
+#include <QtGui>
+
+#include "thblackbar.h"
+
+/* ============================================================================
+ * PRIVATE Class
+ */
+class THBlackBar::Private {
+ public:
+ QList<QAction *> actionList;
+ QAction *checkedAction;
+ QAction *hoveredAction;
+};
+
+/* ============================================================================
+ * PUBLIC Constructor/Destructors
+ */
+THBlackBar::THBlackBar (QWidget *parent)
+ : QWidget(parent), d(new THBlackBar::Private)
+{
+ // Setup Widget Options
+ setMouseTracking(true);
+
+ // Setup Members
+ d->hoveredAction = NULL;
+ d->checkedAction = NULL;
+}
+
+THBlackBar::~THBlackBar() {
+ delete d;
+}
+
+/* ============================================================================
+ * PUBLIC Methods
+ */
+QAction *THBlackBar::addAction (QAction *action) {
+ action->setCheckable(true);
+ d->actionList.append(action);
+ return(action);
+}
+
+QAction *THBlackBar::addAction (const QString& text) {
+ QAction *action = new QAction(text, this);
+ action->setCheckable(true);
+ d->actionList.append(action);
+ return(action);
+}
+
+void THBlackBar::setCheckedAction(int index) {
+ if (d->checkedAction)
+ d->checkedAction->setChecked(false);
+ d->checkedAction = d->actionList.at(index);
+ d->checkedAction->setChecked(true);
+ update();
+}
+
+QSize THBlackBar::minimumSizeHint (void) const {
+ int itemsWidth = calculateButtonWidth() * d->actionList.size();
+ return(QSize(100 + itemsWidth, 32));
+}
+
+/* ============================================================================
+ * PROTECTED Methods
+ */
+void THBlackBar::paintEvent (QPaintEvent *event) {
+ int height = event->rect().height();
+ int width = event->rect().width();
+ // int mh = (height / 2);
+
+ // THPainter p(this);
+ QPainter p(this);
+
+ /*
+ // Draw Background
+ QLinearGradient linearGradUp(QPointF(0, 0), QPointF(0, mh));
+ linearGradUp.setColorAt(0, QColor(0x97, 0x97, 0x97));
+ linearGradUp.setColorAt(1, QColor(0x4d, 0x4d, 0x4d));
+ p.fillRect(0, 0, width, mh, QBrush(linearGradUp));
+
+ QLinearGradient linearGradDw(QPointF(0, mh), QPointF(0, height));
+ linearGradDw.setColorAt(0, QColor(0x3a, 0x3a, 0x3a));
+ linearGradDw.setColorAt(1, QColor(0x42, 0x42, 0x42));
+ p.fillRect(0, mh, width, mh, QBrush(linearGradDw));
+ */
+
+ // Calculate Buttons Size & Location
+ int buttonWidth = width / d->actionList.size(); // calculateButtonWidth();
+ // int buttonsWidth = width; // buttonWidth * d->actionList.size();
+ int buttonsX = 0; // (width / 2) - (buttonsWidth / 2);
+
+ // Draw Buttons
+ // p.translate(0, 4);
+ QRect rect(buttonsX, 0, buttonWidth, height);
+ foreach (QAction *action, d->actionList) {
+ drawButton(&p, rect, action);
+ rect.moveLeft(rect.x() + rect.width());
+ }
+ // p.translate(0, -4);
+
+ // Draw Buttons Shadow
+ // p.fillRect(buttonsX, height - 4, buttonsWidth, 1, QColor(0x6d, 0x6d, 0x6d));
+
+ p.end();
+}
+
+void THBlackBar::mouseMoveEvent (QMouseEvent *event) {
+ QWidget::mouseMoveEvent(event);
+
+ QAction *action = hoveredAction(event->pos());
+
+ if (action == NULL && d->hoveredAction != NULL) {
+ // d->hoveredAction->hover(false);
+ d->hoveredAction = NULL;
+ update();
+ } else if (action != NULL) {
+ d->hoveredAction = action;
+ action->hover();
+ update();
+
+ // status tip
+ QMainWindow* mainWindow = dynamic_cast<QMainWindow*>(window());
+ if (mainWindow) mainWindow->statusBar()->showMessage(action->statusTip());
+ }
+}
+
+void THBlackBar::mousePressEvent (QMouseEvent *event) {
+ QWidget::mousePressEvent(event);
+
+ if (d->hoveredAction != NULL) {
+
+ if (d->checkedAction != NULL) {
+ // already checked
+ if (d->checkedAction == d->hoveredAction) return;
+ d->checkedAction->setChecked(false);
+ }
+
+ d->checkedAction = d->hoveredAction;
+ d->hoveredAction->setChecked(true);
+ d->hoveredAction->trigger();
+
+ update();
+ }
+}
+
+void THBlackBar::leaveEvent(QEvent *event) {
+ // status tip
+ QMainWindow* mainWindow = static_cast<QMainWindow*>(window());
+ if (mainWindow) mainWindow->statusBar()->clearMessage();
+}
+
+QAction *THBlackBar::hoveredAction (const QPoint& pos) const {
+ if (pos.y() <= 0 || pos.y() >= height())
+ return(NULL);
+
+ /*
+ int buttonWidth = calculateButtonWidth();
+ int buttonsWidth = buttonWidth * d->actionList.size();
+ int buttonsX = (width() / 2) - (buttonsWidth / 2);
+ */
+
+ int buttonWidth = width() / d->actionList.size(); // calculateButtonWidth();
+ int buttonsWidth = width(); // buttonWidth * d->actionList.size();
+ int buttonsX = 0; // (width / 2) - (buttonsWidth / 2);
+
+ if (pos.x() <= buttonsX || pos.x() >= (buttonsX + buttonsWidth))
+ return(NULL);
+
+ int buttonIndex = (pos.x() - buttonsX) / buttonWidth;
+
+ if (buttonIndex >= d->actionList.size())
+ return(NULL);
+ return(d->actionList[buttonIndex]);
+}
+
+int THBlackBar::calculateButtonWidth (void) const {
+ QFont smallerBoldFont;
+ smallerBoldFont.setBold(true);
+ smallerBoldFont.setPointSize(smallerBoldFont.pointSize()*.85);
+ QFontMetrics fontMetrics(smallerBoldFont);
+ int tmpItemWidth, itemWidth = 0;
+ foreach (QAction *action, d->actionList) {
+ tmpItemWidth = fontMetrics.width(action->text());
+ if (itemWidth < tmpItemWidth) itemWidth = tmpItemWidth;
+ }
+ return itemWidth;
+}
+
+
+/* ============================================================================
+ * PRIVATE Methods
+ */
+void THBlackBar::drawUnselectedButton ( QPainter *painter,
+ const QRect& rect,
+ const QAction *action)
+{
+ QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, rect.height() / 2));
+ linearGrad.setColorAt(0, QColor(0x8e, 0x8e, 0x8e));
+ linearGrad.setColorAt(1, QColor(0x5c, 0x5c, 0x5c));
+ /*
+ QPalette palette;
+ linearGrad.setColorAt(0, palette.color(QPalette::Dark));
+ linearGrad.setColorAt(1, palette.color(QPalette::Midlight));
+*/
+ drawButton(painter, rect, linearGrad, QColor(0x41, 0x41, 0x41), action);
+ // drawButton(painter, rect, linearGrad, palette.color(QPalette::Shadow), action);
+}
+
+void THBlackBar::drawSelectedButton ( QPainter *painter,
+ const QRect& rect,
+ const QAction *action)
+{
+ QLinearGradient linearGrad(QPointF(0, 0), QPointF(0, rect.height() / 2));
+ linearGrad.setColorAt(0, QColor(0x6d, 0x6d, 0x6d));
+ linearGrad.setColorAt(1, QColor(0x25, 0x25, 0x25));
+ drawButton(painter, rect, linearGrad, QColor(0x00, 0x00, 0x00), action);
+}
+
+void THBlackBar::drawButton ( QPainter *painter,
+ const QRect& rect,
+ const QAction *action)
+{
+ if (action->isChecked())
+ drawSelectedButton(painter, rect, action);
+ else
+ drawUnselectedButton(painter, rect, action);
+}
+
+void THBlackBar::drawButton ( QPainter *painter,
+ const QRect& rect,
+ const QLinearGradient& gradient,
+ const QColor& color,
+ const QAction *action)
+{
+ painter->save();
+
+ int height = rect.height();
+ int width = rect.width();
+ int mh = (height / 2);
+
+ painter->translate(rect.x(), rect.y());
+ painter->setPen(QColor(0x28, 0x28, 0x28));
+
+ painter->fillRect(0, 0, width, mh, QBrush(gradient));
+ painter->fillRect(0, mh, width, mh, color);
+ painter->drawRect(0, 0, width, height);
+
+ QFont smallerBoldFont;
+ smallerBoldFont.setBold(true);
+ smallerBoldFont.setPointSize(smallerBoldFont.pointSize()*.85);
+ painter->setFont(smallerBoldFont);
+ painter->setPen(QPen(QColor(0xff, 0xff, 0xff), 1));
+ painter->drawText(0, 1, width, height, Qt::AlignCenter, action->text());
+
+ painter->restore();
+}
+
--- /dev/null
+#ifndef _THBLACKBAR_H_
+#define _THBLACKBAR_H_
+
+#include <QWidget>
+#include <QAction>
+
+class THBlackBar : public QWidget {
+
+ Q_OBJECT
+
+ public:
+ THBlackBar (QWidget *parent = 0);
+ ~THBlackBar();
+
+ public:
+ QAction *addAction (QAction *action);
+ QAction *addAction (const QString& text);
+ void setCheckedAction(int index);
+
+ QSize minimumSizeHint (void) const;
+
+ protected:
+ void paintEvent (QPaintEvent *event);
+
+ void mouseMoveEvent (QMouseEvent *event);
+ void mousePressEvent (QMouseEvent *event);
+ void leaveEvent(QEvent *event);
+
+ private:
+ void drawUnselectedButton ( QPainter *painter,
+ const QRect& rect,
+ const QAction *action);
+ void drawSelectedButton ( QPainter *painter,
+ const QRect& rect,
+ const QAction *action);
+ void drawButton ( QPainter *painter,
+ const QRect& rect,
+ const QAction *action);
+ void drawButton ( QPainter *painter,
+ const QRect& rect,
+ const QLinearGradient& gradient,
+ const QColor& color,
+ const QAction *action);
+
+ QAction *hoveredAction (const QPoint& pos) const;
+ int calculateButtonWidth (void) const;
+
+ private:
+ class Private;
+ Private *d;
+};
+
+#endif /* !_THBLACKBAR_H_ */
+
--- /dev/null
+DEPENDPATH += $$PWD
+INCLUDEPATH += $$PWD
+HEADERS += thblackbar.h
+SOURCES += thblackbar.cpp
--- /dev/null
+#include "updatechecker.h"
+#include "networkaccess.h"
+#include "Constants.h"
+
+namespace The {
+ NetworkAccess* http();
+}
+
+UpdateChecker::UpdateChecker() {
+ m_needUpdate = false;
+}
+
+void UpdateChecker::checkForUpdate() {
+ QUrl updateUrl(QString(Constants::WEBSITE) + "-ws/release.xml");
+ // QUrl updateUrl("http://flavio.tordini.org:8012/release.xml");
+
+ QObject *reply = The::http()->get(updateUrl);
+ connect(reply, SIGNAL(data(QByteArray)), SLOT(requestFinished(QByteArray)));
+
+}
+
+void UpdateChecker::requestFinished(QByteArray data) {
+ UpdateCheckerStreamReader reader;
+ reader.read(data);
+ m_needUpdate = reader.needUpdate();
+ m_remoteVersion = reader.remoteVersion();
+ if (m_needUpdate && !m_remoteVersion.isEmpty()) emit newVersion(m_remoteVersion);
+}
+
+QString UpdateChecker::remoteVersion() {
+ return m_remoteVersion;
+}
+
+// --- Reader ---
+
+bool UpdateCheckerStreamReader::read(QByteArray data) {
+ addData(data);
+
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == "release") {
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement() && name() == "version") {
+ QString remoteVersion = readElementText();
+ qDebug() << remoteVersion << QString(Constants::VERSION);
+ m_needUpdate = remoteVersion != QString(Constants::VERSION);
+ m_remoteVersion = remoteVersion;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return !error();
+}
+
+QString UpdateCheckerStreamReader::remoteVersion() {
+ return m_remoteVersion;
+}
--- /dev/null
+#ifndef UPDATECHECKER_H
+#define UPDATECHECKER_H
+
+#include <QXmlStreamReader>
+#include <QNetworkReply>
+
+class UpdateChecker : public QObject {
+ Q_OBJECT
+
+public:
+ UpdateChecker();
+ void checkForUpdate();
+ QString remoteVersion();
+
+signals:
+ void newVersion(QString);
+
+private slots:
+ void requestFinished(QByteArray);
+
+private:
+
+ bool m_needUpdate;
+ QString m_remoteVersion;
+ QNetworkReply *networkReply;
+
+};
+
+class UpdateCheckerStreamReader : public QXmlStreamReader {
+
+public:
+ bool read(QByteArray data);
+ QString remoteVersion();
+ bool needUpdate() { return m_needUpdate; }
+
+private:
+ QString m_remoteVersion;
+ bool m_needUpdate;
+
+};
+
+#endif // UPDATECHECKER_H
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "urllineedit.h"
+#include "searchlineedit.h"
+
+#include <QtCore/QEvent>
+
+#include <QtGui/QApplication>
+#include <QtGui/QCompleter>
+#include <QtGui/QFocusEvent>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QLabel>
+#include <QtGui/QLineEdit>
+#include <QtGui/QPainter>
+#include <QtGui/QStyle>
+#include <QtGui/QStyleOptionFrameV2>
+
+#include <QtCore/QDebug>
+
+ExLineEdit::ExLineEdit(QWidget *parent)
+ : QWidget(parent)
+ , m_leftWidget(0)
+ , m_lineEdit(new QLineEdit(this))
+ , m_clearButton(0)
+{
+ setFocusPolicy(m_lineEdit->focusPolicy());
+ setAttribute(Qt::WA_InputMethodEnabled);
+ setSizePolicy(m_lineEdit->sizePolicy());
+ setBackgroundRole(m_lineEdit->backgroundRole());
+ setMouseTracking(true);
+ setAcceptDrops(true);
+ setAttribute(Qt::WA_MacShowFocusRect, true);
+ QPalette p = m_lineEdit->palette();
+ setPalette(p);
+
+ // line edit
+ m_lineEdit->setFrame(false);
+ m_lineEdit->setFocusProxy(this);
+ m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
+ QPalette clearPalette = m_lineEdit->palette();
+ clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent));
+ m_lineEdit->setPalette(clearPalette);
+
+ // clearButton
+ m_clearButton = new ClearButton(this);
+ connect(m_clearButton, SIGNAL(clicked()),
+ m_lineEdit, SLOT(clear()));
+ connect(m_lineEdit, SIGNAL(textChanged(const QString&)),
+ m_clearButton, SLOT(textChanged(const QString&)));
+}
+
+void ExLineEdit::setFont(const QFont &font) {
+ m_lineEdit->setFont(font);
+ updateGeometries();
+}
+
+void ExLineEdit::setLeftWidget(QWidget *widget)
+{
+ m_leftWidget = widget;
+}
+
+QWidget *ExLineEdit::leftWidget() const
+{
+ return m_leftWidget;
+}
+
+void ExLineEdit::resizeEvent(QResizeEvent *event)
+{
+ Q_ASSERT(m_leftWidget);
+ updateGeometries();
+ QWidget::resizeEvent(event);
+}
+
+void ExLineEdit::updateGeometries()
+{
+ QStyleOptionFrameV2 panel;
+ initStyleOption(&panel);
+ QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
+
+ int padding = 3;
+ // int height = rect.height() + padding*2;
+ int width = rect.width();
+
+ // int m_leftWidgetHeight = m_leftWidget->height();
+ m_leftWidget->setGeometry(rect.x() + 2, 0,
+ m_leftWidget->width(), m_leftWidget->height());
+
+ int clearButtonWidth = this->height();
+ m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(), padding,
+ width - clearButtonWidth - m_leftWidget->width(), this->height() - padding*2);
+
+ m_clearButton->setGeometry(this->width() - clearButtonWidth, 0,
+ clearButtonWidth, this->height());
+}
+
+void ExLineEdit::initStyleOption(QStyleOptionFrameV2 *option) const
+{
+ option->initFrom(this);
+ option->rect = contentsRect();
+ option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this);
+ option->midLineWidth = 0;
+ option->state |= QStyle::State_Sunken;
+ if (m_lineEdit->isReadOnly())
+ option->state |= QStyle::State_ReadOnly;
+#ifdef QT_KEYPAD_NAVIGATION
+ if (hasEditFocus())
+ option->state |= QStyle::State_HasEditFocus;
+#endif
+ option->features = QStyleOptionFrameV2::None;
+}
+
+QSize ExLineEdit::sizeHint() const
+{
+ m_lineEdit->setFrame(true);
+ QSize size = m_lineEdit->sizeHint();
+ m_lineEdit->setFrame(false);
+ return size;
+}
+
+void ExLineEdit::focusInEvent(QFocusEvent *event)
+{
+ m_lineEdit->event(event);
+ QWidget::focusInEvent(event);
+}
+
+void ExLineEdit::focusOutEvent(QFocusEvent *event)
+{
+ m_lineEdit->event(event);
+
+ if (m_lineEdit->completer()) {
+ connect(m_lineEdit->completer(), SIGNAL(activated(QString)),
+ m_lineEdit, SLOT(setText(QString)));
+ connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)),
+ m_lineEdit, SLOT(_q_completionHighlighted(QString)));
+ }
+ QWidget::focusOutEvent(event);
+}
+
+void ExLineEdit::keyPressEvent(QKeyEvent *event)
+{
+ m_lineEdit->event(event);
+ QWidget::keyPressEvent(event);
+}
+
+bool ExLineEdit::event(QEvent *event)
+{
+ if (event->type() == QEvent::ShortcutOverride ||
+ event->type() == QEvent::InputMethod)
+ m_lineEdit->event(event);
+ return QWidget::event(event);
+}
+
+void ExLineEdit::paintEvent(QPaintEvent *)
+{
+ QPainter p(this);
+ QStyleOptionFrameV2 panel;
+ initStyleOption(&panel);
+ style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
+}
--- /dev/null
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the demonstration applications of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial Usage
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://www.qtsoftware.com/contact.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef URLLINEEDIT_H
+#define URLLINEEDIT_H
+
+#include <QtCore/QUrl>
+#include <QtGui/QWidget>
+#include <QtGui/QLineEdit>
+#include <QtGui/QStyleOptionFrame>
+
+QT_BEGIN_NAMESPACE
+class QLineEdit;
+QT_END_NAMESPACE
+
+class ClearButton;
+class ExLineEdit : public QWidget
+{
+ Q_OBJECT
+
+public:
+ ExLineEdit(QWidget *parent = 0);
+
+ inline QLineEdit *lineEdit() const { return m_lineEdit; }
+
+ void setLeftWidget(QWidget *widget);
+ QWidget *leftWidget() const;
+ void clear() {
+ m_lineEdit->clear();
+ }
+ QString text() {
+ return m_lineEdit->text();
+ }
+ QSize sizeHint() const;
+ void updateGeometries();
+ void setFont(const QFont &);
+
+protected:
+ void focusInEvent(QFocusEvent *event);
+ void focusOutEvent(QFocusEvent *event);
+ void keyPressEvent(QKeyEvent *event);
+ void paintEvent(QPaintEvent *event);
+ void resizeEvent(QResizeEvent *event);
+ bool event(QEvent *event);
+ void initStyleOption(QStyleOptionFrameV2 *option) const;
+
+ QWidget *m_leftWidget;
+ QLineEdit *m_lineEdit;
+ ClearButton *m_clearButton;
+};
+
+#endif // URLLINEEDIT_H
+
--- /dev/null
+#include "video.h"
+#include "networkaccess.h"
+#include <QtNetwork>
+#include "videodefinition.h"
+
+namespace The {
+ NetworkAccess* http();
+}
+
+Video::Video() : m_duration(0),
+m_viewCount(-1),
+definitionCode(0),
+elIndex(0) { }
+
+void Video::preloadThumbnail() {
+ if (m_thumbnailUrls.isEmpty()) return;
+ QObject *reply = The::http()->get(m_thumbnailUrls.first());
+ connect(reply, SIGNAL(data(QByteArray)), SLOT(setThumbnail(QByteArray)));
+}
+
+void Video::setThumbnail(QByteArray bytes) {
+ m_thumbnail = QImage::fromData(bytes);
+ emit gotThumbnail();
+}
+
+const QImage Video::thumbnail() const {
+ return m_thumbnail;
+}
+
+static const QStringList elTypes = QStringList() << "embedded" << "vevo" << "detailpage";
+
+void Video::loadStreamUrl() {
+
+ // https://develop.participatoryculture.org/trac/democracy/browser/trunk/tv/portable/flashscraper.py
+
+ // Get Video ID
+ // youtube-dl line 428
+ // QRegExp re("^((?:http://)?(?:\\w+\\.)?youtube\\.com/(?:(?:v/)|(?:(?:watch(?:\\.php)?)?\\?(?:.+&)?v=)))?([0-9A-Za-z_-]+)(?(1).+)?$");
+ QRegExp re("^http://www\\.youtube\\.com/watch\\?v=([0-9A-Za-z_-]+).*");
+ bool match = re.exactMatch(m_webpage.toString());
+ if (!match || re.numCaptures() < 1) {
+ emit errorStreamUrl(QString("Cannot get video id for %1").arg(m_webpage.toString()));
+ return;
+ }
+ videoId = re.cap(1);
+
+ getVideoInfo();
+
+}
+
+void Video::getVideoInfo() {
+
+ if (elIndex > elTypes.size() - 1) {
+ // Don't panic! We have a plan B.
+ // get the youtube video webpage
+ QObject *reply = The::http()->get(webpage().toString());
+ connect(reply, SIGNAL(data(QByteArray)), SLOT(scrapeWebPage(QByteArray)));
+ connect(reply, SIGNAL(error(QNetworkReply*)), SLOT(errorVideoInfo(QNetworkReply*)));
+ // see you in scrapWebPage(QByteArray)
+ return;
+ }
+
+ // Get Video Token
+ QUrl videoInfoUrl = QUrl(QString(
+ "http://www.youtube.com/get_video_info?video_id=%1&el=%2&ps=default&eurl="
+ ).arg(videoId, elTypes.at(elIndex)));
+
+ QObject *reply = The::http()->get(videoInfoUrl);
+ connect(reply, SIGNAL(data(QByteArray)), SLOT(gotVideoInfo(QByteArray)));
+ connect(reply, SIGNAL(error(QNetworkReply*)), SLOT(errorVideoInfo(QNetworkReply*)));
+
+ // see you in gotVideoInfo...
+
+}
+
+void Video::gotVideoInfo(QByteArray data) {
+ QString videoInfo = QString::fromUtf8(data);
+
+ QRegExp re = QRegExp("^.*&token=([^&]+).*$");
+ bool match = re.exactMatch(videoInfo);
+
+ // handle regexp failure
+ if (!match || re.numCaptures() < 1) {
+ // Don't panic! We're gonna try another magic "el" param
+ elIndex++;
+ getVideoInfo();
+ return;
+ }
+
+ QString videoToken = re.cap(1);
+ // FIXME proper decode
+ videoToken = videoToken.replace("%3D", "=");
+ // we'll need this in gotHeadHeaders()
+ this->videoToken = videoToken;
+
+ // qDebug() << "token" << videoToken;
+
+ QSettings settings;
+ QString definitionName = settings.value("definition").toString();
+ int definitionCode = VideoDefinition::getDefinitionCode(definitionName);
+ if (definitionCode == 18) {
+ // This is assumed always available
+ foundVideoUrl(videoToken, 18);
+ } else {
+ findVideoUrl(definitionCode);
+ }
+
+}
+
+void Video::foundVideoUrl(QString videoToken, int definitionCode) {
+
+ QUrl videoUrl = QUrl(QString(
+ "http://www.youtube.com/get_video?video_id=%1&t=%2&eurl=&el=embedded&ps=default&fmt=%3"
+ ).arg(videoId, videoToken, QString::number(definitionCode)));
+
+ m_streamUrl = videoUrl;
+ emit gotStreamUrl(videoUrl);
+}
+
+void Video::errorVideoInfo(QNetworkReply *reply) {
+ emit errorStreamUrl(tr("Network error: %1 for %2").arg(reply->errorString(), reply->url().toString()));
+}
+
+void Video::scrapeWebPage(QByteArray data) {
+
+ QString videoHTML = QString::fromUtf8(data);
+ QRegExp re(".*, \"t\": \"([^\"]+)\".*");
+ bool match = re.exactMatch(videoHTML);
+
+ // on regexp failure, stop and report error
+ if (!match || re.numCaptures() < 1) {
+ emit errorStreamUrl("Error parsing video page");
+ return;
+ }
+
+ QString videoToken = re.cap(1);
+ // FIXME proper decode
+ videoToken = videoToken.replace("%3D", "=");
+
+ // we'll need this in gotHeadHeaders()
+ this->videoToken = videoToken;
+
+ // qDebug() << "token" << videoToken;
+
+ QSettings settings;
+ QString definitionName = settings.value("definition").toString();
+ int definitionCode = VideoDefinition::getDefinitionCode(definitionName);
+ if (definitionCode == 18) {
+ // This is assumed always available
+ foundVideoUrl(videoToken, 18);
+ } else {
+ findVideoUrl(definitionCode);
+ }
+
+}
+
+void Video::gotHeadHeaders(QNetworkReply* reply) {
+ int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+ // qDebug() << "gotHeaders" << statusCode;
+ if (statusCode == 200) {
+ foundVideoUrl(videoToken, definitionCode);
+ } else {
+
+ // try next (lower quality) definition
+ /*
+ QStringList definitionNames = VideoDefinition::getDefinitionNames();
+ int currentIndex = definitionNames.indexOf(currentDefinition);
+ int previousIndex = 0;
+ if (currentIndex > 0) {
+ previousIndex = currentIndex - 1;
+ }
+ if (previousIndex > 0) {
+ QString nextDefinitionName = definitionNames.at(previousIndex);
+ findVideoUrl(nextDefinitionName);
+ } else {
+ foundVideoUrl(videoToken, 18);
+ }*/
+
+
+ QList<int> definitionCodes = VideoDefinition::getDefinitionCodes();
+ int currentIndex = definitionCodes.indexOf(definitionCode);
+ int previousIndex = 0;
+ if (currentIndex > 0) {
+ previousIndex = currentIndex - 1;
+ int definitionCode = definitionCodes.at(previousIndex);
+ if (definitionCode == 18) {
+ // This is assumed always available
+ foundVideoUrl(videoToken, 18);
+ } else {
+ findVideoUrl(definitionCode);
+ }
+
+ } else {
+ foundVideoUrl(videoToken, 18);
+ }
+
+ }
+}
+
+void Video::findVideoUrl(int definitionCode) {
+ this->definitionCode = definitionCode;
+
+ QUrl videoUrl = QUrl(QString(
+ "http://www.youtube.com/get_video?video_id=%1&t=%2&eurl=&el=embedded&ps=default&fmt=%3"
+ ).arg(videoId, videoToken, QString::number(definitionCode)));
+
+ QObject *reply = The::http()->head(videoUrl);
+ connect(reply, SIGNAL(finished(QNetworkReply*)), SLOT(gotHeadHeaders(QNetworkReply*)));
+ // connect(reply, SIGNAL(error(QNetworkReply*)), SLOT(errorVideoInfo(QNetworkReply*)));
+
+ // see you in gotHeadHeaders()
+
+}
--- /dev/null
+#ifndef VIDEO_H
+#define VIDEO_H
+
+#include <QtGui>
+#include <QtNetwork>
+
+class Video : public QObject {
+
+ Q_OBJECT
+
+public:
+ Video();
+
+ const QString title() const { return m_title; }
+ void setTitle( QString title ) { m_title = title; }
+
+ const QString description() const { return m_description; }
+ void setDescription( QString description ) { m_description = description; }
+
+ const QString author() const { return m_author; }
+ void setAuthor( QString author ) { m_author = author; }
+
+ const QUrl webpage() const { return m_webpage; }
+ void setWebpage( QUrl webpage ) { m_webpage = webpage; }
+
+ QList<QUrl> thumbnailUrls() const { return m_thumbnailUrls; }
+ void addThumbnailUrl(QUrl url) {
+ m_thumbnailUrls << url;
+ }
+
+ void preloadThumbnail();
+ const QImage thumbnail() const;
+
+ int duration() const { return m_duration; }
+ void setDuration( int duration ) { m_duration = duration; }
+
+ int viewCount() const { return m_viewCount; }
+ void setViewCount( int viewCount ) { m_viewCount = viewCount; }
+
+ const QDateTime published() const { return m_published; }
+ void setPublished( QDateTime published ) { m_published = published; }
+
+ bool getDefinitionCode() const { return definitionCode; }
+
+ void loadStreamUrl();
+ QUrl getStreamUrl() { return m_streamUrl; }
+
+public slots:
+ void setThumbnail(QByteArray bytes);
+
+signals:
+ void gotThumbnail();
+ void gotStreamUrl(QUrl streamUrl);
+ void errorStreamUrl(QString message);
+
+private slots:
+ void gotVideoInfo(QByteArray);
+ void errorVideoInfo(QNetworkReply*);
+ void scrapeWebPage(QByteArray);
+ void gotHeadHeaders(QNetworkReply*);
+
+private:
+ void getVideoInfo();
+ void findVideoUrl(int definitionCode);
+ void foundVideoUrl(QString videoToken, int definitionCode);
+
+ QString m_title;
+ QString m_description;
+ QString m_author;
+ QUrl m_webpage;
+ QUrl m_streamUrl;
+ QImage m_thumbnail;
+ QList<QUrl> m_thumbnailUrls;
+ int m_duration;
+ QDateTime m_published;
+ int m_viewCount;
+
+ // The YouTube video id
+ // This is needed by the gotVideoInfo callback
+ QString videoId;
+
+ QString videoToken;
+ int definitionCode;
+
+ // current index for the elTypes list
+ // needed to iterate on elTypes
+ int elIndex;
+};
+
+// This is required in order to use QPointer<Video> as a QVariant
+// as used by the Model/View playlist
+typedef QPointer<Video> VideoPointer;
+Q_DECLARE_METATYPE(VideoPointer)
+
+#endif // VIDEO_H
--- /dev/null
+#include "videoareawidget.h"
+#include "videomimedata.h"
+
+VideoAreaWidget::VideoAreaWidget(QWidget *parent) : QWidget(parent) {
+ QBoxLayout *vLayout = new QVBoxLayout(this);
+ vLayout->setMargin(0);
+ vLayout->setSpacing(0);
+
+ // hidden message widget
+ messageLabel = new QLabel(this);
+ messageLabel->setOpenExternalLinks(true);
+ messageLabel->setMargin(7);
+ messageLabel->setBackgroundRole(QPalette::ToolTipBase);
+ messageLabel->setForegroundRole(QPalette::ToolTipText);
+ messageLabel->setAutoFillBackground(true);
+ messageLabel->setWordWrap(true);
+ messageLabel->hide();
+ vLayout->addWidget(messageLabel);
+
+ stackedLayout = new QStackedLayout();
+ vLayout->addLayout(stackedLayout);
+
+ setLayout(vLayout);
+ setAcceptDrops(true);
+
+ setMouseTracking(true);
+}
+
+void VideoAreaWidget::setVideoWidget(QWidget *videoWidget) {
+ this->videoWidget = videoWidget;
+ videoWidget->setMouseTracking(true);
+ stackedLayout->addWidget(videoWidget);
+}
+
+void VideoAreaWidget::setLoadingWidget(LoadingWidget *loadingWidget) {
+ this->loadingWidget = loadingWidget;
+ stackedLayout->addWidget(loadingWidget);
+}
+
+void VideoAreaWidget::showVideo() {
+ stackedLayout->setCurrentWidget(videoWidget);
+}
+
+void VideoAreaWidget::showError(QString message) {
+ // loadingWidget->setError(message);
+ messageLabel->setText(message);
+ messageLabel->show();
+ stackedLayout->setCurrentWidget(loadingWidget);
+}
+
+void VideoAreaWidget::showLoading(Video *video) {
+ this->loadingWidget->setVideo(video);
+ stackedLayout->setCurrentWidget(loadingWidget);
+ messageLabel->hide();
+ messageLabel->clear();
+}
+
+void VideoAreaWidget::clear() {
+ stackedLayout->setCurrentWidget(loadingWidget);
+ loadingWidget->clear();
+ messageLabel->hide();
+ messageLabel->clear();
+}
+
+void VideoAreaWidget::mouseDoubleClickEvent(QMouseEvent *event) {
+ if (event->button() == Qt::LeftButton)
+ emit doubleClicked();
+}
+
+void VideoAreaWidget::mousePressEvent(QMouseEvent *event) {
+ QWidget::mousePressEvent(event);
+
+ if(event->button() == Qt::RightButton)
+ emit rightClicked();
+}
+
+void VideoAreaWidget::dragEnterEvent(QDragEnterEvent *event) {
+ // qDebug() << event->mimeData()->formats();
+ if (event->mimeData()->hasFormat("application/x-minitube-video")) {
+ event->acceptProposedAction();
+ }
+}
+
+void VideoAreaWidget::dropEvent(QDropEvent *event) {
+
+ const VideoMimeData* videoMimeData = dynamic_cast<const VideoMimeData*>( event->mimeData() );
+ if(!videoMimeData ) return;
+
+ QList<Video*> droppedVideos = videoMimeData->videos();
+ if (droppedVideos.isEmpty())
+ return;
+ Video *video = droppedVideos.first();
+ int row = listModel->rowForVideo(video);
+ if (row != -1)
+ listModel->setActiveRow(row);
+ event->acceptProposedAction();
+}
+
+void VideoAreaWidget::mouseMoveEvent(QMouseEvent *event) {
+ QWidget::mouseMoveEvent(event);
+
+ QWidget* mainWindow = window();
+ if (!mainWindow->isFullScreen()) return;
+
+ // qDebug() << "VideoAreaWidget::mouseMoveEvent" << event->pos();
+
+ const int x = event->pos().x();
+ const int y = event->pos().y();
+
+ bool visible = y <= 0;
+ bool ret = QMetaObject::invokeMethod(mainWindow, "showFullscreenToolbar", Qt::DirectConnection, Q_ARG(bool, visible));
+ if (!ret) qDebug() << "showFullscreenToolbar invokeMethod failed";
+
+ visible = x <= 0;
+ ret = QMetaObject::invokeMethod(mainWindow, "showFullscreenPlaylist", Qt::DirectConnection, Q_ARG(bool, visible));
+ if (!ret) qDebug() << "showFullscreenPlaylist invokeMethod failed";
+}
--- /dev/null
+#ifndef VIDEOAREAWIDGET_H
+#define VIDEOAREAWIDGET_H
+
+#include <QWidget>
+#include "video.h"
+#include "loadingwidget.h"
+#include "ListModel.h"
+
+class VideoAreaWidget : public QWidget {
+
+ Q_OBJECT
+
+public:
+ VideoAreaWidget(QWidget *parent);
+ void setVideoWidget(QWidget *videoWidget);
+ void setLoadingWidget(LoadingWidget *loadingWidget);
+ void showLoading(Video* video);
+ void showVideo();
+ void showError(QString message);
+ void clear();
+ void setListModel(ListModel *listModel) {
+ this->listModel = listModel;
+ }
+
+signals:
+ void doubleClicked();
+ void rightClicked();
+
+protected:
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dropEvent(QDropEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+
+private:
+ QStackedLayout *stackedLayout;
+ QWidget *videoWidget;
+ LoadingWidget *loadingWidget;
+ ListModel *listModel;
+ QLabel *messageLabel;
+
+};
+
+#endif // VIDEOAREAWIDGET_H
--- /dev/null
+#include "videodefinition.h"
+
+QStringList VideoDefinition::getDefinitionNames() {
+ static QStringList definitionNames = QStringList() << "360p" << "720p" << "1080p";
+ return definitionNames;
+}
+
+QList<int> VideoDefinition::getDefinitionCodes() {
+ static QList<int> definitionCodes = QList<int>() << 18 << 22 << 37;
+ return definitionCodes;
+}
+
+QHash<QString, int> VideoDefinition::getDefinitions() {
+ static QHash<QString, int> definitions;
+ if (definitions.isEmpty()) {
+ definitions.insert("360p", 18);
+ definitions.insert("720p", 22);
+ definitions.insert("1080p", 37);
+ }
+ return definitions;
+}
+
+int VideoDefinition::getDefinitionCode(QString name) {
+ return VideoDefinition::getDefinitions().value(name);
+}
--- /dev/null
+#ifndef VIDEODEFINITION_H
+#define VIDEODEFINITION_H
+
+#include <QtCore>
+
+class VideoDefinition {
+
+public:
+ static QStringList getDefinitionNames();
+ static QList<int> getDefinitionCodes();
+ static QHash<QString, int> getDefinitions();
+ static int getDefinitionCode(QString name);
+
+};
+
+#endif // VIDEODEFINITION_H
--- /dev/null
+#include "videomimedata.h"
+
+VideoMimeData::VideoMimeData() {}
+
+QStringList VideoMimeData::formats() const {
+ QStringList formats( QMimeData::formats() );
+ formats.append("application/x-minitube-video");
+ return formats;
+}
+
+bool VideoMimeData::hasFormat( const QString &mimeType ) const {
+ return mimeType == "application/x-minitube-video";
+}
--- /dev/null
+#ifndef VIDEOMIMEDATA_H
+#define VIDEOMIMEDATA_H
+
+#include <QMimeData>
+#include "video.h"
+
+class VideoMimeData : public QMimeData {
+
+public:
+ VideoMimeData();
+
+ virtual QStringList formats() const;
+ virtual bool hasFormat( const QString &mimeType ) const;
+
+ QList<Video*> videos() const { return m_videos; }
+
+ void addVideo(Video *video) {
+ m_videos << video;
+ }
+
+private:
+ QList<Video*> m_videos;
+
+};
+
+#endif // VIDEOMIMEDATA_H
--- /dev/null
+#include "videowidget.h"
+
+VideoWidget::VideoWidget(QWidget *parent) : Phonon::VideoWidget(parent) {
+ // mouse autohide
+ setMouseTracking(true);
+ mouseTimer = new QTimer(this);
+ mouseTimer->setInterval(3000);
+ mouseTimer->setSingleShot(true);
+ connect(mouseTimer, SIGNAL(timeout()), SLOT(hideMouse()));
+}
+
+void VideoWidget::mouseMoveEvent(QMouseEvent *event) {
+ Phonon::VideoWidget::mouseMoveEvent(event);
+
+ // qDebug() << "VideoWidget::mouseMoveEvent" << event->pos();
+
+ // show the normal cursor
+ unsetCursor();
+
+ // then hide it again after a few seconds
+ mouseTimer->start();
+}
+
+void VideoWidget::hideMouse() {
+ // qDebug() << "hideMouse()";
+ setCursor(Qt::BlankCursor);
+}
--- /dev/null
+#ifndef VIDEOWIDGET_H
+#define VIDEOWIDGET_H
+
+#include <QtGui>
+#include <phonon/videowidget.h>
+#include <QTimer>
+
+class VideoWidget : public Phonon::VideoWidget {
+
+ Q_OBJECT
+
+public:
+ VideoWidget(QWidget *parent);
+
+protected:
+ void mouseMoveEvent (QMouseEvent *event);
+
+private slots:
+ void hideMouse();
+
+private:
+ QTimer *mouseTimer;
+
+};
+
+#endif // VIDEOWIDGET_H
--- /dev/null
+#include "youtubesearch.h"
+#include "youtubestreamreader.h"
+#include "Constants.h"
+#include "networkaccess.h"
+
+namespace The {
+ NetworkAccess* http();
+}
+
+YouTubeSearch::YouTubeSearch() : QObject() {}
+
+void YouTubeSearch::search(SearchParams *searchParams, int max, int skip) {
+ this->abortFlag = false;
+
+ QString urlString = QString(
+ "http://gdata.youtube.com/feeds/api/videos?q=%1&max-results=%2&start-index=%3")
+ .arg(searchParams->keywords(), QString::number(max), QString::number(skip));
+
+ // Useful to test with a local webserver
+ /*
+ urlString = QString("http://localhost/oringo/video.xml?q=%1&max-results=%2&start-index=%3")
+ .arg(searchParams->keywords(), QString::number(max), QString::number(skip));
+ */
+
+ switch (searchParams->sortBy()) {
+ case SearchParams::SortByNewest:
+ urlString.append("&orderby=published");
+ break;
+ case SearchParams::SortByViewCount:
+ urlString.append("&orderby=viewCount");
+ break;
+ }
+
+ QUrl url(urlString);
+
+ QObject *reply = The::http()->get(url);
+ connect(reply, SIGNAL(data(QByteArray)), SLOT(parseResults(QByteArray)));
+ connect(reply, SIGNAL(error(QNetworkReply*)), SLOT(error(QNetworkReply*)));
+
+}
+
+void YouTubeSearch::error(QNetworkReply *reply) {
+ emit error(reply->errorString());
+}
+
+void YouTubeSearch::parseResults(QByteArray data) {
+
+ YouTubeStreamReader reader;
+ if (!reader.read(data)) {
+ qDebug() << "Error parsing XML";
+ }
+ videos = reader.getVideos();
+
+ foreach (Video *video, videos) {
+ // send it to the model
+ emit gotVideo(video);
+ }
+
+ foreach (Video *video, videos) {
+ // preload the thumb
+ if (abortFlag) return;
+ video->preloadThumbnail();
+ }
+
+ emit finished(videos.size());
+}
+
+QList<Video*> YouTubeSearch::getResults() {
+ return videos;
+}
+
+void YouTubeSearch::abort() {
+ this->abortFlag = true;
+}
--- /dev/null
+#ifndef YOUTUBESEARCH_H
+#define YOUTUBESEARCH_H
+
+#include "video.h"
+#include "searchparams.h"
+
+class YouTubeSearch : public QObject {
+
+ Q_OBJECT
+
+public:
+ YouTubeSearch();
+ void search(SearchParams *searchParams, int max, int skip);
+ void abort();
+ QList<Video*> getResults();
+
+signals:
+ void gotVideo(Video*);
+ void finished(int total);
+ void error(QString message);
+
+private slots:
+ void parseResults(QByteArray data);
+ void error(QNetworkReply *reply);
+
+private:
+
+ QList<Video*> videos;
+
+ bool abortFlag;
+
+};
+
+#endif // YOUTUBESEARCH_H
--- /dev/null
+#include "youtubestreamreader.h"
+#include <QtGui>
+
+
+YouTubeStreamReader::YouTubeStreamReader() {
+
+}
+
+bool YouTubeStreamReader::read(QByteArray data) {
+ addData(data);
+
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement()) {
+ if (name() == "feed") {
+ while (!atEnd()) {
+ readNext();
+ if (isStartElement() && name() == "entry") {
+ readEntry();
+ }
+ }
+ }
+ }
+ }
+
+ return !error();
+}
+
+void YouTubeStreamReader::readMediaGroup() {
+
+}
+
+void YouTubeStreamReader::readEntry() {
+ Video* video = new Video();
+ // qDebug(" *** ENTRY ***");
+
+ while (!atEnd()) {
+ readNext();
+
+ /*
+ qDebug() << name();
+ QXmlStreamAttribute attribute;
+ foreach (attribute, attributes())
+ qDebug() << attribute.name() << ":" << attribute.value();
+ */
+
+ if (isEndElement() && name() == "entry") break;
+ if (isStartElement()) {
+
+ if (name() == "link"
+ && attributes().value("rel").toString() == "alternate"
+ && attributes().value("type").toString() == "text/html"
+ ) {
+ QString webpage = attributes().value("href").toString();
+ // qDebug() << "Webpage: " << webpage;
+ video->setWebpage(QUrl(webpage));
+ } else if (name() == "author") {
+ readNext();
+ if (name() == "name") {
+ QString author = readElementText();
+ // qDebug() << "Author: " << author;
+ video->setAuthor(author);
+ }
+ } else if (name() == "published") {
+ video->setPublished(QDateTime::fromString(readElementText(), Qt::ISODate));
+ } else if (namespaceUri() == "http://gdata.youtube.com/schemas/2007" && name() == "statistics") {
+
+ QString viewCount = attributes().value("viewCount").toString();
+ // qDebug() << "viewCount: " << viewCount;
+ video->setViewCount(viewCount.toInt());
+ }
+ else if (namespaceUri() == "http://search.yahoo.com/mrss/" && name() == "group") {
+
+ // read media group
+ while (!atEnd()) {
+ readNext();
+ if (isEndElement() && name() == "group") break;
+ if (isStartElement()) {
+ if (name() == "thumbnail") {
+ // qDebug() << "Thumb: " << attributes().value("url").toString();
+ // video->thumbnailUrls() << QUrl(attributes().value("url").toString());
+ video->addThumbnailUrl(QUrl(attributes().value("url").toString()));
+ }
+ else if (name() == "title") {
+ QString title = readElementText();
+ // qDebug() << "Title: " << title;
+ video->setTitle(title);
+ }
+ else if (name() == "description") {
+ QString desc = readElementText();
+ // qDebug() << "Description: " << desc;
+ video->setDescription(desc);
+ }
+ else if (name() == "duration") {
+ QString duration = attributes().value("seconds").toString();
+ // qDebug() << "Duration: " << duration;
+ video->setDuration(duration.toInt());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ videos.append(video);
+
+}
+
+QList<Video*> YouTubeStreamReader::getVideos() {
+ return videos;
+}
--- /dev/null
+#ifndef YOUTUBESTREAMREADER_H
+#define YOUTUBESTREAMREADER_H
+
+#include <QXmlStreamReader>
+#include <QBuffer>
+#include "video.h"
+
+class YouTubeStreamReader : public QXmlStreamReader
+{
+public:
+ YouTubeStreamReader();
+ bool read(QByteArray data);
+ QList<Video*> getVideos();
+
+private:
+ void readMediaGroup();
+ void readEntry();
+ QList<Video*> videos;
+};
+
+#endif // YOUTUBESTREAMREADER_H