diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | c90c389a8a8d9d8661e9772ec4144c5cf2039f23 (patch) | |
tree | 6d8391395bce9eaea4ad78958617edb20c6a7573 /atlantik | |
download | tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.tar.gz tdegames-c90c389a8a8d9d8661e9772ec4144c5cf2039f23.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegames@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'atlantik')
130 files changed, 12278 insertions, 0 deletions
diff --git a/atlantik/AUTHORS b/atlantik/AUTHORS new file mode 100644 index 00000000..5ef9d50f --- /dev/null +++ b/atlantik/AUTHORS @@ -0,0 +1 @@ +Rob Kaper <[email protected]> diff --git a/atlantik/COPYING b/atlantik/COPYING new file mode 100644 index 00000000..c13faf0d --- /dev/null +++ b/atlantik/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) 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 +this service 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 make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. 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. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +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. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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. + + 12. 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 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. + + 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 +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 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 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision 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, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This 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 Library General +Public License instead of this License. diff --git a/atlantik/COPYING.LIB b/atlantik/COPYING.LIB new file mode 100644 index 00000000..ae23fcfd --- /dev/null +++ b/atlantik/COPYING.LIB @@ -0,0 +1,504 @@ + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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. + + 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 + + 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! + + diff --git a/atlantik/ChangeLog b/atlantik/ChangeLog new file mode 100644 index 00000000..8f889261 --- /dev/null +++ b/atlantik/ChangeLog @@ -0,0 +1,633 @@ +0.7.5 (KDE 3.4) +----- + +- Show mortgage and house prices/values on estate views. +- Make token image a saved configuration setting, use KIconDialog. +- Avoid scrollbar by using KWrappedListViewItem. + +0.7.2 (KDE 3.3.2) +----- + +- Proper use of host and port in kio_atlantik: fixes problems with + invitations sent by newer clients. +- bugfix: scroll player views when they get too big. (#69043) +- bugfix: show correct amount of players in trade widget. + +0.7.1 (KDE 3.3.1) +----- + +- Don't show warning dialog when exiting a game that ended. (#88617) + +0.7.0 (KDE 3.3) +----- + +- Event log +- Use of KStatusBar +- Game master can boot other players to lounge during game setup (#52631) +- Support gameupdate tag, deprecate updategamelist (requires monopd >= 0.9.0) +- Support individual configupdate tags +- Show estate names on board (#61858) +- Properly withdraw from a game prior to intended client exits, to avoid + triggering monopd's reconnection timeout. + +0.6.3 +----- + +- bugfix: avoid crash when unresolvable hosts are in the meta server list +- bugfix: fix crash when network core is reset while readbuffer isn't empty +- bugfix: chat view can be cleared (#69044) + +0.6.1 +----- + +- hide development servers identifying themselves with "-dev" + +0.6.0 +----- + +- support for custom tokens +- don't connect to meta server unless user has configured to do so +- support for KNotify events +- option to hide development servers (on by default) +- gui to connect to custom server +- klatencytimer: support for server ping times +- option to show timestamp in chat messages + +0.5.5 +----- + +- bugfix: fix wild pointer when removing trade items (#68589) +- bugfix: set proper palette color for EstateDetails so Keramik buttons + don't look out of place + +0.5.4 +----- + +- bugfix: don't interrupt token movement when player leaves jail on doubles +- bugfix: add m_atlanticCore checks in Board, fixes some Atlantik Designer + crashes +- bugfix: don't show players from other games in auction and trade widgets + on monopd 0.9.0 servers +- bugfix: valgrind found two crash conditions when leaving game + configuration widget or auction widget (#66498) + +0.5.3 +----- + +- fix problem where sometimes the select game widget appears + after starting a game +- removed buggy trademap in network code for decent ptrlist in core +- memory management: reset complete core when going to select server page +- store reconnection cookie +- hide token when player goes bankrupt +- prevent player from building/unmortgaging when in debt +- disable auction/usecard menu item when not available (requires monopd >= 0.8.1) +- make use of trade revisions (monopd >= 0.8.2 recommended) +- don't tell game has started when it has not +- sort user column in server list by number, not alphabetically +- show non-game users when not in a game +- prevent double close buttons on estate details + +0.5.2 +----- + +- correctly handle utf-8 over the network +- only show localhost server when it is available +- leaving a game and starting a new game correctly reinits atlanticCore +- use disability to join game when size == MAX in gameupdate (games in + updategamelist now have canbejoined boolean attribute) +- using playerupdate for player list in SelectConfiguration +- use portfolioview instead of klistview for players during config +- better handling of display messages from server +- fixed token animation + +0.5.1 +----- + +- fixed potential double initialization of gameboard +- don't crash when removing money from a trade +- properly quote arguments given to KProcess in kio_atlantik +- valgrind leak and unitialised memory access fixes + +0.5.0 +----- + +- fixed dangling pointer for removeGUI(Trade *) in AtlanticCore +- player name change doesn't make it to trade money items +- fixed token positioning on game start +- fixes to work with monopd 0.6.0 API + +0.4.0 +----- + +- token geometry is now aware of estate colour captions +- queue display widgets + - fix buttons, they have specific targets, not just the current widget + - delete buttons in EstateDetails::newUpdate() +- commandline parameters host, port and game supported (for auto-join) +- kio_atlantik allows for easy connecting from other applications + (kopete/kmail) +- leave game and leave server options +- pre-game configuration + +2002-07-08 (kaper) +---------- + +- support for auto-connect and auto-join + +2002-07-07 (kaper) +---------- + +- request full update when getting invalid data from the network +- gui bugfixes + +2002-07-04 (kaper) (atlantik-0.3.0) +---------- + +- clear display on <display/> + +2002-07-03 (kaper) +---------- + +- removing trade money works again, fixed possible crashes in trade and + auction deletion within network API + +2002-06-30 (kaper) +---------- + +- monopd no longer sends gamelist on connect, so request it +- more intelligent EstateDetails, shows no useless info anymore and added + groupname, price and isMortgaged +- 10% or $200 taxes finally implemented! (requires monopd CVS >= 20020701) +- removed <br> from messagewindow, apparently Qt autowraps (again??) + +2002-06-27 (kaper) +---------- + +- recently committed some changes to be up-to-date with some API monopd + changes +- generalised BoardDisplay::displayCard() into displayText() so I can fix + the missing jail notification bug + +2002-04-29 (kaper) +---------- + +- dropped QSocket for KExtendedSocket + +2002-03-30 (kaper) +---------- + +- monopd API: support for estategroupupdate +- build portfolioview upon game start for better layouting + +2002-02-19 (kaper) +---------- + +- Trading done except for small esthetic TODOs. + +2002-02-13 (kaper) +---------- + +- Nicer button layouts (QSpacerItems, KIcon::SizeSmall, margin/spacingHints) + +2002-02-11 (kaper) +---------- + +- Gametypes no longer hardcoded but fetched from monopd server +- Trading money, rejecting trades! + +2002-01-31 (kaper) +---------- + +- Bugfixes +- Trades! (ok, just the estates and no way to accept, but still ;) + +2002-01-08 (kaper) +---------- + +- Auctions! +- Board resize updates tokens again + +2001-12-22 (katz) +--------- + +- Add support for setting AtlantikBoard's size in its ctor; + simply tell it maxEstates. Right now for Atlantik's board + it simply uses a hard-coded 40 +- in Designer, implement 'smaller' nad 'larger' menu entries, + now able to save and load boards with any size!!! +- add boardinfo.[h/cpp] that has a BoardInfo class that has board information, + and a class to View/Edit it +- designer uses it, doesn't read/write the info yet tho + +2001-12-20 (katz) +--------- + +- fix using user's colors for openNew in designer + +2001-12-20 (katz) +--------- + +Designer: +- gets its first entry in ChangeLog, because designer has been + on the whole useless before this +- supports chance and cc cards; loads and saves properly +- doesn't crash in random places +- loads and saves in Cap's new format +- fix probs with the swallowed dialogs +- don't use defaultcity.conf in openNew(); make board with + user's KDE colors! pretty :-) doesn'twork tho, neil will fix +- use KComboBox now QComboBox +- maybe some other things? + +2001-12-20 (kaper) +---------- + +- Moved network stuff to libatlantiknetwork + +2001-12-19 (kaper) +---------- + +- Better toolbar disable/enable code (API changes in monopd) +- Bugfixes for m_playerSelf +- preparations to use KExtendedSocket instead of QSocket +- using KPushButton instead of QPushButton + +2001-12-18 (kaper) +---------- + +- moved Trade to libatlantic +- libatlantic now includes AtlanticCore wrapper + +2001-12-17 (kaper) +---------- + +- moved object management to Network class +- moved Estate and Player to libatlantic + +2001-12-16 (kaper) +---------- + +- monopd no longer 'includes' estates in trades, but has a proper + targetplayer for them. added support for this API update, as well as the + update regarding money trades + +2001-12-14 (kaper) +---------- + +- better looking portfolios +- support for displaying game types in game list +- ability to choose between city or atlantic gametype +- GUI to create a trade + +2001-11-29 (kaper) +---------- + +- Portfolios are _truly_ dynamic now. :-) + +2001-11-27 (kaper) +---------- + +- Set version to 0.1.2 CVS. + +2001-11-27 (kaper) (0.1.1 release) +---------- + +- PortfolioViews and PortfolioEstates work again! +- Tagged 0.1.1 release. + +2001-11-23 (kaper) +---------- + +- Trading skeleton +- Better implementation of connection between Player and PortfolioView +- Various code cleanups + +2001-11-21 (kaper) +---------- + +- Very basic skeleton for atlanticd (monopd-compatible server) + +2001-11-15 (kaper) +---------- + +- Even more dynamic thinking: estateview actions now completely depend on + server data instead of own checks. + +2001-11-14 (kaper) +---------- + +- Tokens are correctly positioned at startup and token animation is working + again. +- Chance/community cards are displayed in board center. + +2001-11-12 (kaper) +---------- + +- EstateViews have correct orientation again. +- Fixed weird Quartz behavior on large resolutions. + +2001-11-11 (kaper) +---------- + +- First changes to replace KMessageBox with in-window widget. +- Starting games is possible again. +- Connected Estate::changed to EstateView::estateChanged. +- Added informational message at game startup regarding current Atlantik + state (buggy, at least). +- No longer using fixed geometry. +- Dynamic (server guided) colour support for estates. +- Board configuration settings update properly again. +- Starting Player / Token relationship as we did for Estate / EstateView +- Tokens move again (animation not in operation yet). +- Right Mouse Button actions on estates are properly working again. + +2001-11-05 (kaper) +---------- + +- SelectGame and SelectConfiguration KWizard replacement widgets done. +- Better icon loading. +- Better error checking when connecting to a server. + +2001-10-19 (kaper) +---------- + +- Rewriting new game wizard into regular widgets, SelectServer done. +- Internal changes. + +2001-10-10 (kaper) +---------- + +- Estates are created dynamically now! +- Lots of internal changes regarding player and estateupdates. +- monopd API change: mortgages are now a toggle. + +2001-10-09 (kaper) +---------- + +- Portfolioviews are now generated dynamically. The Atlantik class manages + the creation and updates of the content are done by the (new) Player + class. Atlantik does act as intermediate here, though, eventually being + responsible for both player and widget management. +- Player objects/views are only created when playerupdate contains init=1 +- Estate class created, simplified grid layout code for board. +- Temporarily removed gameboard spacer code. + +2001-10-05 (kaper) +---------- + +- Qt3 updates. +- Small monopd API updates. + +2001-09-04 (kaper) +---------- + +- Been a while since the last update, due to the renaming to Atlantik (now + mostly taken care of, thus this entry), new game concept (in progress) and + my vacation to San Francisco (unfortunately no longer in progress). + +2001-08-06 (kaper) +---------- + +- Monopigator works! :-) + +2001-07-30 (kaper) +---------- + +- Estateupdate visual update fixes. +- Using can_be_mortgaged and can_be_unmortgaged attributes of monopd's + estateupdate. +- New app icons by Bart Szyszka :-) +- Token confirmation disabled for jumpToken when resizing gameboard or after + directmove instrution from server. + +2001-07-19 (kaper) +---------- + +- Network interface for trades completed, all commands and signals are in + place. + +2001-07-17 (kaper) +---------- + +- Encapsulated actual monopd API commands in gameNetwork +- Extended gameNetwork to support trading API commands +- RMB actions on estates only available when owned by player respresented by + this client + +2001-07-16 (kaper) +---------- + +- Small bugfix connecting standard roll action to correct slot. +- Code documentation! (at least for the KMonop class) +- Quartz effects! (configurable) + +2001-07-13 (neil) +---------- + +- UI: make the SelectGame widgets respond as the user may expect them to + +2001-07-01 (kaper) +---------- + +- Using KStdGameAction more and more (requires kdenonbeta version for roll + action) +- Updated to be compatible with recent monopd API changes + +2001-06-29 (kaper) +---------- + +- Bugfix: when owner=-1 in estateupdate, KMonop now clears the + portfolio/board estateviews. +- Added icon for Go. +- New config option to highlite unowned properties. +- Seperated server messages from chat. + +2001-06-27 (kaper) +---------- + +- Updated TODO (some wishlist items, changed version roadmap) +- Added a lot of i18n strings! + +2001-06-26 (kaper) +---------- + +- New config option: mortgaged properties can be grayed out on the gameboard +- Slightly increased size of portfolio estates +- Added RMB popup to estates with mortgage/unmortgage and build/sell house + actions +- Added luxury tax and community chest icons. + +2001-06-24 (kaper) +---------- + +- Server port no longer hardcoded, added extra default server (running + monopd CVS). +- Game board visualization of houses and hotels! + +2001-06-21 (kaper) +---------- + +- Network code parses <estateupdate> attribs houses and mortgaged. + +2001-06-19 (kaper) +---------- + +- Added "end turn" button. +- Added "pay to leave jail" button. +- Added playername to config dialog. +- Updated parsing of <updateplayerlist> changes in monopd. + +2001-06-17 (kaper) +---------- + +- Upgraded version to pre-0.2.0 + +2001-06-17 (kaper) (0.1.0 release) +---------- + +- Happy birthday Katy. Love, Rob. +- Integrated recent monopd updates. +- Some internal code changes. +- Added support for <updategamelist type="edit"> +- Added support for <updateplayerlist> which replaced <playerlist> +- Tagged 0.1.0 release + +2001-06-10 +---------- + +- Portfolioestate/board recognize utilities as ownable estates. +- Prepared utilities for icons. + +2001-06-09 +---------- + +- Configuration works! +- Location confirmation upon jumpToken. +- Unowned indication also for railroads. + +2001-06-05 +---------- + +- More PlayerUpdate* changes. + +2001-06-05 +---------- + +- Added parsing of <msg type="chat"> message which is new in monopd. + Chatting can thus be done through the console (lineedit field) now. +- Some changes to configure dialog, none that influence behavior though. +- Got tired of passing netw through all classes, it's pretty general anyway + so I made it a general variable. +- PlayerUpdate* changes (movetoken was removed from monopd API) + +2001-06-01 +---------- + +- Added parsing of <movetoken> command which is new in monopd +- Sending .t# command to monopd which is now required during token movement + +2001-05-30 +---------- + +- Token is now a nice icon (not yet transparent though, unfortunately I + couldn't get that to work right) + +2001-05-28 +---------- + +- Added board icons for train and chance estates +- Token which has turn is raised to make sure it's on top + +2001-05-27 +---------- + +- Moved some of the XML parsing code back to GameNetwork::processNode +- Changed version (back.. ssht!) to pre-0.0.2 +- Internal improvements to network/newgamewizard code (more accurate slots + and button validation) + +2001-05-27 (0.0.1 release) +---------- + +- Visual feedback showing who's turn it is +- Roll/buy buttons only enabled during turn +- Tagged 0.0.1 release + +2001-05-20 +---------- + +- Small cosmetic changes. +- New application icons, icons installdir changed. +- Configure dialog (looks nice, doesn't load/save yet) + +2001-05-16 +---------- + +- Message view autoscrolls. +- Small (cosmetic) portfolioview updates. +- Visual display on board showing which properties are still for sale + +2001-05-15 +---------- + +- New game dialog improvements (select game page checks network status and + gamelist availability +- Tokens are actually moving over the board! (instead of jumping) + +2001-05-08 +---------- + +- Portfolios built upon "playerupdate" message instead of final playerlist, + since we'll get plenty more updates anyway. +- Token placed on location hinted by playerupdate. +- Input box at bottom left corner can be used to send messages to the server + to compensate for any commands not yet implemented. Such as .n to set your + name and .r to roll. +- Cash and estates in portfolio get updated after purchase/rent. + +2001-05-07 +---------- + +- Wizard notifies game server we're starting the game upon finish. Bugfix in + KMonop::slotStartNewGame which checks whether wizard still exists before + trying to hide it. +- Portfolio overviews are built upon game start, requires monopd which sends + final attribute along with playerlist. +- Framework for token class. +- Informational messages from server are shown in output textbox. +- Only sending start game command when wizard is finished, not when it is + cancelled. + +2001-05-03 +---------- + +- Various code cleanups, keeping things neat. +- Playerlist and gamelist are automatically sent by server, manual request + no longer required. + +2001-05-02 +---------- + +- Playerlist is fetched from server. +- Playerlist is interpreted and updated when someone enters. +- Option to finish setup and launch game, closes all wizards. +- Network object moved to KMonop, where it belongs. Wizard and its pages use + pointers. + +2001-04-30 +---------- + +- NewGameDialog is now a wizard. A connection to the server is made and a + list of available games to join fetched, using Qt's XML parsing + capabilities. + +2001-04-27 +---------- + +- Turned NewGameDialog into modal dialog. + +2001-04-26 +---------- + +- Initial ChangeLog entry. diff --git a/atlantik/INSTALL b/atlantik/INSTALL new file mode 100644 index 00000000..34523708 --- /dev/null +++ b/atlantik/INSTALL @@ -0,0 +1,33 @@ +Contents +-------- + + 1. Compiling the CVS version + 2. Compiling a release tarball + 3. Installing a finished build + 4. Starting the application + +1. Compiling the CVS version +---------------------------- + +cd kdegames && make -f Makefile.cvs && ./configure && cd atlantik && make + +2. Compiling a release tarball +------------------------------ + +cd atlantik-x.y.z && ./configure && make + +3. Installing a finished build +------------------------------ + +As root; + +make install + +4. Starting the application +--------------------------- + +Click on K->Games->Board->Atlantik or run atlantik from konsole or minicli. + +Please note that Atlantik is only a client! You will need to connect to a +monopd server on the Internet or run one locally! See the README file for +more details on the Atlantik/monopd client/server concept. diff --git a/atlantik/Makefile.am b/atlantik/Makefile.am new file mode 100644 index 00000000..d4389577 --- /dev/null +++ b/atlantik/Makefile.am @@ -0,0 +1,13 @@ +SUBDIRS = libatlantic libatlantikclient libatlantikui client \ + kio_atlantik pics themes + +EXTRA_DIST = atlantik.desktop + +xdg_apps_DATA = atlantik.desktop + +rcdir = $(kde_datadir)/atlantik +rc_DATA = atlantikui.rc eventsrc + +messages: rc.cpp + $(XGETTEXT) `find . -name '*.cpp'` -o $(podir)/atlantik.pot + diff --git a/atlantik/README b/atlantik/README new file mode 100644 index 00000000..c51d2859 --- /dev/null +++ b/atlantik/README @@ -0,0 +1,94 @@ +Contents +-------- + +1. Introduction +2. Download +3. Mailinglists +4. Roadmap +5. Designer +6. Legal issues + +1. Introduction +--------------- + +Atlantik is a KDE client for playing Monopoly-like games on the monopd +network. + +Purpose of the Atlantic board game is to acquire land in major cities in +North America and Europe while being a transatlantic traveller. One of the +game modes plays like the popular real estate board game based on Atlantic +City street names. + +Atlantik was previously known as KMonop and might still be referred to as +such in some documentation. + +2. Download +----------- + +Atlantik can be downloaded from + +http://unixcode.org/atlantik/ + +and monopd can be downloaded from + +http://unixcode.org/monopd/ + +However, the latest versions of both projects are found in CVS. + +Atlantik is located in the CVS repository of the KDE project in the module +kdegames. See http://www.kde.org/anoncvs.html for instructions how to +download KDE modules from CVS. Atlantik is included in the kdegames package +since the KDE 3.1 release. + +For more information on monopd CVS see the monopd pages on +http://sourceforge.net/projects/monopd/ + +Both monopd and Atlantik are in heavy development and it is important to match +versions when connecting to a game server. One can choose a suitable server +through the Monopigator interface. + +3. Mailinglists +--------------= + +There are mailinglists available for discussion of Atlantik development. The +atlantik-devel list is for general discussion and development of the +codebase, the atlantik-cvs list has all the CVS commits in it and the +atlantik-artists list is for the development of GFX/SFX for Atlantik. + +See http://mail.kde.org/mailman/listinfo/atlantik-devel +See http://mail.kde.org/mailman/listinfo/atlantik-cvs +and http://mail.kde.org/mailman/listinfo/atlantik-artists + +on information on subscribing, posting and list archives. + +There is a seperate mailinglist for monopd related discussion: + +To subscribe, send e-mail to: [email protected] +To post, send e-mail to: [email protected] + +4. Roadmap +---------- + +The TODO file gives a nice approximation of desired functionality and +priorities. It can be used as roadmap or checklist. + +5. Designer +----------- + +Atlantik Designer is a game board designer that will create game config +files for monopd. You can find it in KDE CVS, module kdeaddons. + +6. Legal issues +--------------- + +Many people have expressed their concerns about possible copyrights, +trademarks and patents applicable to Monopoly� and the possible implications +for Atlantik (and monopd) development and distribution. + +I believe that Atlantik and monopd are completely clear of violating any +copyrights, trademarks or patents and that there are no legal issues that +might affect development or distibution of either application. + +For more information, please read + +http://unixcode.org/atlantik/legal.html diff --git a/atlantik/README.KDE-3.0 b/atlantik/README.KDE-3.0 new file mode 100644 index 00000000..c941aaa9 --- /dev/null +++ b/atlantik/README.KDE-3.0 @@ -0,0 +1,7 @@ +Atlantik uses KExtendedSocket to connect to monopd servers. Due to some bugs +in KBufferedIO and KExtendedSocket in kdelibs, you might experience +unexplained crashes when using Atlantik with KDE 3.0, 3.0.1 or 3.0.2. + +It is recommended to run Atlantik with at least KDE 3.0.3 or 3.1 Beta1, or a +KDE CVS checkout of the HEAD branch recent enough to contain revision 1.6 of +kdelibs/kdecore/kbufferedio.cpp and revision 1.39 of kextsock.cpp. diff --git a/atlantik/README.packaging b/atlantik/README.packaging new file mode 100644 index 00000000..90608a7c --- /dev/null +++ b/atlantik/README.packaging @@ -0,0 +1,25 @@ +Notes for packaging stand-alone releases that will work with all of KDE 3.x: + +kdegames/configure.in.in +------------------------ + +#MIN_CONFIG(3.0) + +doc/ +---- + +Remove da/ and "da" SUBDIRS entry from Makefile.in, it has a non-backward +compatible entity. + +Ensure + +<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.1.2-Based Variant V1.0//EN" "dtd/kdex.dtd" [ + +as type so older KDE versions will work. + +Makefile.am +----------- + +-xdg_apps_DATA = atlantik.desktop ++appsdir = $(kde_appsdir)/Games/Board ++apps_DATA = atlantik.desktop diff --git a/atlantik/TODO b/atlantik/TODO new file mode 100644 index 00000000..42160d39 --- /dev/null +++ b/atlantik/TODO @@ -0,0 +1,48 @@ +- not implemented +^ in progress +v implemented + +monopd API changes (features) +------------------ + +- API: allow for reconnect with .R +- API: cardupdate message to inform clients of text on cards they own, plus + owner= attribute to replace playerupdate's outofjailcards= +- API: new command .Tc to add cards to trade +- API: tradecard message in tradeupdate + +Bugfixes +-------- + +- Update messages views after resize. +- all player/core dependencies in Board should only be there in Mode::Play +- don't display trade results over auction, but stack it behind it in the queue +- "retrieving server list" stats message is not signalled on auto-load + +For 0.6.0 +--------- + +- use kde preferences for timestamp format (12/24h, etc) +- make build/unmortgage protection configurable +- use gameupdate for game list in SelectGame +- .D command +- cards in portfolio +- support for trading cards +- Support .gd game description. +- support .es (sell estate), depends on game::allowestatesales + +For 0.7.0 +--------- + +- invite button + - kaddressbook hooks + - e-mail invites + - IM invites +- multiplayer support (multiple local players) + +For 1.0.0 +--------- + +- header documentation +- visualization of owners on board itself +- themes (Star Trek/Wars, Kiki Dunst, Simpsons, etc) diff --git a/atlantik/atlanticd/Makefile.am b/atlantik/atlanticd/Makefile.am new file mode 100644 index 00000000..65e3475a --- /dev/null +++ b/atlantik/atlanticd/Makefile.am @@ -0,0 +1,10 @@ +KDE_OPTIONS = qtonly + +bin_PROGRAMS = atlanticd + +INCLUDES = -I$(top_srcdir)/atlantik/libatlantic $(QT_INCLUDES) +LDADD = ../libatlantic/libatlantic.la + +atlanticd_SOURCES = atlanticclient.cpp atlanticdaemon.cpp main.cpp serversocket.cpp + +METASOURCES = AUTO diff --git a/atlantik/atlanticd/README b/atlantik/atlanticd/README new file mode 100644 index 00000000..a0bf03b1 --- /dev/null +++ b/atlantik/atlanticd/README @@ -0,0 +1,6 @@ +The purpose of atlanticd is to provide a monopd-compatible server, for +inclusion with the Atlantik client. + +Eventually atlanticd will be full-featured and a capable monopd replacement, +but at this very moment it's still a prototype and not useful for actual +games. diff --git a/atlantik/atlanticd/TODO b/atlantik/atlanticd/TODO new file mode 100644 index 00000000..fb121b4e --- /dev/null +++ b/atlantik/atlanticd/TODO @@ -0,0 +1,11 @@ +This is a very basic TODO, only aimed at the most urgent goals and +requirements. A complete reference would be the existing functionality of +monopd. + +v create base class, AtlanticDaemon + v add monopigator method and timer + v create serversocket here + - let serversocket signal and atlanticd create client object + - create game object + - send list of games upon new connect + diff --git a/atlantik/atlanticd/atlanticclient.cpp b/atlantik/atlanticd/atlanticclient.cpp new file mode 100644 index 00000000..0445165d --- /dev/null +++ b/atlantik/atlanticd/atlanticclient.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qtextstream.h> +#include <qtimer.h> + +#include "atlanticclient.h" +#include "atlanticclient.moc" + +AtlanticClient::AtlanticClient(QObject *parent, const char *name) : QSocket(parent, name) +{ + connect(this, SIGNAL(readyRead()), this, SLOT(readData())); +} + +void AtlanticClient::sendData(const QString &data) +{ + writeBlock(data.latin1(), data.length()); +} + +void AtlanticClient::readData() +{ + if (canReadLine()) + { + emit clientInput(this, readLine()); + + // There might be more data + QTimer::singleShot(0, this, SLOT(readData())); + } + else + { + // Maximum message size. Messages won't get bigger than 32k anyway, so + // if we didn't receive a newline by now, we probably won't anyway. + if (bytesAvailable() > (1024 * 32)) + flush(); + } +} diff --git a/atlantik/atlanticd/atlanticclient.h b/atlantik/atlanticd/atlanticclient.h new file mode 100644 index 00000000..7b47b0f3 --- /dev/null +++ b/atlantik/atlanticd/atlanticclient.h @@ -0,0 +1,36 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef CLIENT_H +#define CLIENT_H + +#include <qsocket.h> + +class AtlanticClient : public QSocket +{ +Q_OBJECT + +public: + AtlanticClient(QObject *parent = 0, const char *name = 0); + void sendData(const QString &data); + +private slots: + void readData(); + +signals: + void clientInput(AtlanticClient *client, const QString &data); +}; +#endif diff --git a/atlantik/atlanticd/atlanticdaemon.cpp b/atlantik/atlanticd/atlanticdaemon.cpp new file mode 100644 index 00000000..3fb80cf0 --- /dev/null +++ b/atlantik/atlanticd/atlanticdaemon.cpp @@ -0,0 +1,72 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qtimer.h> +#include <qsocket.h> +#include <qstring.h> + +#include <atlantic_core.h> + +#include "atlanticclient.h" +#include "atlanticdaemon.h" +#include "atlanticdaemon.moc" +#include "serversocket.h" + +AtlanticDaemon::AtlanticDaemon() +{ + m_serverSocket = new ServerSocket(1234, 100); + connect(m_serverSocket, SIGNAL(newClient(AtlanticClient *)), this, SLOT(newClient(AtlanticClient *))); + + m_atlanticCore = new AtlanticCore(this, "atlanticCore"); + + // Create socket for Monopigator + m_monopigatorSocket = new QSocket(); + connect(m_monopigatorSocket, SIGNAL(connected()), this, SLOT(monopigatorConnected())); + + // Register server + monopigatorRegister(); +} + +AtlanticDaemon::~AtlanticDaemon() +{ + delete m_monopigatorSocket; +} + +void AtlanticDaemon::monopigatorRegister() +{ + m_monopigatorSocket->connectToHost("gator.monopd.net", 80); +} + +void AtlanticDaemon::monopigatorConnected() +{ + QString get = "GET /register.php?host=capsi.com&port=1234&version=atlanticd-prototype HTTP/1.1\nHost: gator.monopd.net\n\n"; + m_monopigatorSocket->writeBlock(get.latin1(), get.length()); + m_monopigatorSocket->close(); + + // Monopigator clears old entries, so keep registering every 180s + QTimer::singleShot(180000, this, SLOT(monopigatorRegister())); +} + +void AtlanticDaemon::newClient(AtlanticClient *client) +{ + m_clients.append(client); + + connect(client, SIGNAL(clientInput(AtlanticClient *, const QString &)), this, SLOT(clientInput(AtlanticClient *, const QString &))); +} + +void AtlanticDaemon::clientInput(AtlanticClient *client, const QString &data) +{ +} diff --git a/atlantik/atlanticd/atlanticdaemon.h b/atlantik/atlanticd/atlanticdaemon.h new file mode 100644 index 00000000..729a960e --- /dev/null +++ b/atlantik/atlanticd/atlanticdaemon.h @@ -0,0 +1,48 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIC_ATLANTICDAEMON_H +#define ATLANTIC_ATLANTICDAEMON_H + +#include <qptrlist.h> + +class QSocket; + +class AtlanticCore; +class AtlanticClient; +class ServerSocket; + +class AtlanticDaemon : public QObject +{ +Q_OBJECT + +public: + AtlanticDaemon(); + ~AtlanticDaemon(); +private slots: + void monopigatorRegister(); + void monopigatorConnected(); + void newClient(AtlanticClient *client); + void clientInput(AtlanticClient *client, const QString &data); + +private: + QSocket *m_monopigatorSocket; + ServerSocket *m_serverSocket; + AtlanticCore *m_atlanticCore; + QPtrList<AtlanticClient> m_clients; +}; + +#endif diff --git a/atlantik/atlanticd/main.cpp b/atlantik/atlanticd/main.cpp new file mode 100644 index 00000000..235dcd00 --- /dev/null +++ b/atlantik/atlanticd/main.cpp @@ -0,0 +1,27 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qapplication.h> + +#include "atlanticdaemon.h" + +int main(int argc, char *argv[]) +{ + new AtlanticDaemon(); + + QApplication qapplication(argc, argv); + qapplication.exec(); +} diff --git a/atlantik/atlanticd/serversocket.cpp b/atlantik/atlanticd/serversocket.cpp new file mode 100644 index 00000000..2056a754 --- /dev/null +++ b/atlantik/atlanticd/serversocket.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include "atlanticclient.h" +#include "serversocket.h" + +ServerSocket::ServerSocket(int port, int backlog) : QServerSocket(port, backlog) +{ +} + +void ServerSocket::newConnection(int socket) +{ + AtlanticClient *client = new AtlanticClient(this, "socket"); + client->setSocket(socket); + + emit newClient(client); +} + +#include "serversocket.moc" diff --git a/atlantik/atlanticd/serversocket.h b/atlantik/atlanticd/serversocket.h new file mode 100644 index 00000000..fce347e9 --- /dev/null +++ b/atlantik/atlanticd/serversocket.h @@ -0,0 +1,35 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef SERVERSOCKET_H +#define SERVERSOCKET_H + +#include <qserversocket.h> + +class AtlanticClient; + +class ServerSocket : public QServerSocket +{ +Q_OBJECT + +public: + ServerSocket(int port, int backlog); + void newConnection(int socket); + +signals: + void newClient(AtlanticClient *client); +}; +#endif diff --git a/atlantik/atlantik.desktop b/atlantik/atlantik.desktop new file mode 100644 index 00000000..d5191956 --- /dev/null +++ b/atlantik/atlantik.desktop @@ -0,0 +1,84 @@ +[Desktop Entry] +Exec=atlantik -caption "%c" %i %m +Name=Atlantik +Name[ar]=لعبة الرقعة (Atlantik) +Name[be]=Атлантыка +Name[bn]=আটলান্টিক +Name[eo]=Atlantiko +Name[fi]=Monopoli +Name[hi]=अटलांटिक +Name[lv]=Atlantija +Name[ne]=एटलान्टिक +Name[pa]=ਐਟਲਾਂਟਿਕ +Name[ta]=அட்லான்டிக் +Name[tg]=Атлантик +Name[th]=แอตแลนติค +Name[wa]=Atlantike +Name[zh_TW]=Atlantik 大富翁 +Name[zu]=I-Atlantik +GenericName=Monopoly®-like Board Games +GenericName[ar]=ألعاب الرقعة الشبيهة بمونوبولي +GenericName[be]=Настольная гульня тыпу Манаполія +GenericName[bg]=Монополи® +GenericName[bn]=মনোপলি®-জাতীয় ছকভিত্তিক খেলা +GenericName[br]=Ur c'hoari a seurt gant Monopoly® +GenericName[bs]=Igre nalik na Monopol® +GenericName[ca]=Jocs de taula semblants al Monopoly® +GenericName[cs]=Deskové hry podobné Monopoly® +GenericName[cy]=Gêmau Bwrdd tebyg i Monopoly® +GenericName[da]=Matador®-lignende brætspil +GenericName[de]=Monopoly®-ähnliche Brettspiele +GenericName[el]=Επιτραπέζια παιχνίδια παρόμοια με το Monopoly® +GenericName[eo]=Monopoly-similaj bretludoj +GenericName[es]=Juegos de tablero estilo Monopoly® +GenericName[et]=Monopoli stiilis mängud +GenericName[eu]=Monopoly® bezalako mahai jokuak +GenericName[fa]=بازیهای شبیه تک قطبی تخته +GenericName[fi]=Monopoli®-tyyliset lautapelit +GenericName[fr]=Jeux de plateau dans le style du Monopoly® +GenericName[he]=משחקי לוח נוסח Monopoly® +GenericName[hi]=मोनोपॉली-®-जैसे बिसात के खेल +GenericName[hr]=Igre poput Monopola® +GenericName[hu]=Monopoly-szerű játék +GenericName[is]=Monopoly®- Borðleikir +GenericName[it]=Gioco da tavolo simile a Monopoly® +GenericName[ja]=モノポリーのようなボードゲーム +GenericName[km]=ល្បែងក្ដារដូច Monopoly® +GenericName[lt]=Monopolio tipo stalo žaidimas +GenericName[lv]=Monopoly® līdzīga spēle +GenericName[mk]=Игри на табла во стилот на Монопол® +GenericName[nb]=Monopol-aktige brettspill +GenericName[nds]=Monopoly-liek Spelen +GenericName[ne]=एकाधिकार® जस्तो बोर्ड खेल +GenericName[nl]=Monopoly®-achtige bordspellen +GenericName[nn]=Monopol®-liknande brettspel +GenericName[pa]=Monopoly®-ਵਰਗੀ ਬੋਰਡ ਖੇਡ +GenericName[pl]=Gra planszowa podobna do Monopoly® +GenericName[pt]=Jogo de Tabuleiro tipo Monopoly® +GenericName[pt_BR]=Jogo parecido com Banco Imobiliário® +GenericName[ro]=Un joc de tip Monopoly® +GenericName[ru]=Атлантик +GenericName[se]=Monopol®-lágan duolbbášspeallu +GenericName[sk]=Hry typu Monopoly® +GenericName[sl]=Ploščadna igra, podobna Monopoliju® +GenericName[sr]=Игре на табли налик на Монопол +GenericName[sr@Latn]=Igre na tabli nalik na Monopol +GenericName[sv]=Monopol®-liknande brädspel +GenericName[ta]=Monopoly போல போர்ட் விளையாட்டுகள் +GenericName[tg]=Бозии Рӯимизӣ ба монанди Монополия® +GenericName[tr]=Monopoly®-benzeri tahta oyunları +GenericName[uk]=Ігри на дошці схожі на гру Монополія® +GenericName[uz]=Monopoly® oʻyiniga oʻxshagan stol oʻyini +GenericName[uz@cyrillic]=Monopoly® ўйинига ўхшаган стол ўйини +GenericName[ven]=Mutambo wa kha Bodo unanga Monopoly® +GenericName[wa]=Djeus di platea djinre monopoly +GenericName[zh_CN]=类似 Monopoly® 的棋类游戏 +GenericName[zh_TW]=類似Monopoly®大富翁棋盤遊戲 +GenericName[zu]=Imidlalo efana ne-Monopoly yebhodi +Type=Application +DocPath=atlantik/index.html +Terminal=false +Icon=atlantik +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi +Categories=Qt;KDE;Game;BoardGame; diff --git a/atlantik/atlantikui.rc b/atlantik/atlantikui.rc new file mode 100644 index 00000000..1f37d2f9 --- /dev/null +++ b/atlantik/atlantikui.rc @@ -0,0 +1,24 @@ +<!DOCTYPE kpartgui> +<kpartgui name="atlantik" version="2"> +<MenuBar> + <Menu name="game"><text>&Game</text> + <Action name="showeventlog"/> + </Menu> + <Menu name="move"><text>&Move</text> + <Action name="move_roll"/> + <Action name="buy_estate"/> + <Action name="auction"/> + <Action name="move_endturn"/> + <Action name="move_jailcard"/> + <Action name="move_jailpay"/> + <Action name="move_jailroll"/> + </Menu> +</MenuBar> +<ToolBar name="moveToolBar"> + <Action name="move_roll"/> + <Action name="buy_estate"/> + <Action name="auction"/> + <Action name="move_endturn"/> + <Action name="move_jailpay"/> +</ToolBar> +</kpartgui> diff --git a/atlantik/client/Makefile.am b/atlantik/client/Makefile.am new file mode 100644 index 00000000..25eb24e1 --- /dev/null +++ b/atlantik/client/Makefile.am @@ -0,0 +1,11 @@ +bin_PROGRAMS = atlantik +INCLUDES = -I$(top_srcdir)/libkdegames -I$(srcdir)/../libatlantic -I$(srcdir)/../libatlantikclient -I$(srcdir)/../libatlantikui $(all_includes) +atlantik_LDFLAGS = $(all_libraries) $(KDE_RPATH) +atlantik_LDADD = ../libatlantikui/libatlantikui.la ../libatlantikclient/libatlantikclient.la $(LIB_KDEGAMES) $(LIB_KIO) +atlantik_DEPENDENCIES = $(LIB_KDEGAMES_DEP) + +atlantik_SOURCES = atlantik.cpp configdlg.cpp event.cpp eventlogwidget.cpp \ + main.cpp monopigator.cpp selectconfiguration_widget.cpp \ + selectgame_widget.cpp selectserver_widget.cpp + +METASOURCES = AUTO diff --git a/atlantik/client/atlantik.cpp b/atlantik/client/atlantik.cpp new file mode 100644 index 00000000..56bae64b --- /dev/null +++ b/atlantik/client/atlantik.cpp @@ -0,0 +1,853 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <errno.h> + +#include <qcolor.h> +#include <qdatetime.h> +#include <qlineedit.h> +#include <qscrollview.h> +#include <qpopupmenu.h> + +#include <kaboutapplication.h> +#include <kaction.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <kconfig.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <knotifyclient.h> +#include <knotifydialog.h> +#include <kstatusbar.h> +#include <kstdgameaction.h> +#include <kstdaction.h> +#include <ktoolbar.h> + +#include <kdeversion.h> +#undef KDE_3_2_FEATURES +#if defined(KDE_MAKE_VERSION) +#if KDE_VERSION >= KDE_MAKE_VERSION(3,2,0) + #define KDE_3_2_FEATURES +#endif +#endif + +#include <kdebug.h> + +#include <atlantic_core.h> +#include <auction.h> +#include <estate.h> +#include <player.h> +#include <trade.h> +#include "atlantik.moc" + +#include <atlantik_network.h> + +#include <board.h> +#include <trade_widget.h> + +#include "eventlogwidget.h" +#include "main.h" +#include "selectserver_widget.h" +#include "selectgame_widget.h" +#include "selectconfiguration_widget.h" + +LogTextEdit::LogTextEdit( QWidget *parent, const char *name ) : QTextEdit( parent, name ) +{ +#ifdef KDE_3_2_FEATURES + m_clear = KStdAction::clear( this, SLOT( clear() ), 0 ); +#else + m_clear = new KAction( i18n("Clear"), "clear", NULL, this, SLOT( clear() ), static_cast<KActionCollection *>(0), "clear" ); +#endif + m_selectAll = KStdAction::selectAll( this, SLOT( selectAll() ), 0 ); + m_copy = KStdAction::copy( this, SLOT( copy() ), 0 ); +} + +LogTextEdit::~LogTextEdit() +{ + delete m_clear; + delete m_selectAll; + delete m_copy; +} + +QPopupMenu *LogTextEdit::createPopupMenu( const QPoint & ) +{ + QPopupMenu *rmbMenu = new QPopupMenu( this ); + m_clear->plug( rmbMenu ); + rmbMenu->insertSeparator(); + m_copy->setEnabled( hasSelectedText() ); + m_copy->plug( rmbMenu ); + m_selectAll->plug( rmbMenu ); + + return rmbMenu; +} + +Atlantik::Atlantik () + : KMainWindow (), + m_runningGame( false ) +{ + // Read application configuration + readConfig(); + + // Toolbar: Game +// KStdGameAction::gameNew(this, SLOT(slotNewGame()), actionCollection(), "game_new"); + m_showEventLog = new KAction(i18n("Show Event &Log")/*, "atlantik_showeventlog"*/, CTRL+Key_L, this, SLOT(showEventLog()), actionCollection(), "showeventlog"); + KStdGameAction::quit(kapp, SLOT(closeAllWindows()), actionCollection(), "game_quit"); + + // Toolbar: Settings + KStdAction::preferences(this, SLOT(slotConfigure()), actionCollection()); + KStdAction::configureNotifications(this, SLOT(configureNotifications()), actionCollection()); + + // Initialize pointers to 0L + m_configDialog = 0; + m_board = 0; + m_eventLogWidget = 0; + m_selectServer = 0; + m_selectGame = 0; + m_selectConfiguration = 0; + m_atlantikNetwork = 0; + + // Game and network core + m_atlanticCore = new AtlanticCore(this, "atlanticCore"); + connect(m_atlanticCore, SIGNAL(createGUI(Player *)), this, SLOT(newPlayer(Player *))); + connect(m_atlanticCore, SIGNAL(removeGUI(Player *)), this, SLOT(removeGUI(Player *))); + connect(m_atlanticCore, SIGNAL(createGUI(Trade *)), this, SLOT(newTrade(Trade *))); + connect(m_atlanticCore, SIGNAL(removeGUI(Trade *)), this, SLOT(removeGUI(Trade *))); + + initEventLog(); + initNetworkObject(); + + // Menu,toolbar: Move + m_roll = KStdGameAction::roll(this, SIGNAL(rollDice()), actionCollection()); + m_roll->setEnabled(false); + m_buyEstate = new KAction(i18n("&Buy"), "atlantik_buy_estate", CTRL+Key_B, this, SIGNAL(buyEstate()), actionCollection(), "buy_estate"); + m_buyEstate->setEnabled(false); + m_auctionEstate = new KAction(i18n("&Auction"), "auction", CTRL+Key_A, this, SIGNAL(auctionEstate()), actionCollection(), "auction"); + m_auctionEstate->setEnabled(false); + m_endTurn = KStdGameAction::endTurn(this, SIGNAL(endTurn()), actionCollection()); + m_endTurn->setEnabled(false); + m_jailCard = new KAction(i18n("Use Card to Leave Jail")/*, "atlantik_move_jail_card"*/, 0, this, SIGNAL(jailCard()), actionCollection(), "move_jailcard"); + m_jailCard->setEnabled(false); + m_jailPay = new KAction(i18n("&Pay to Leave Jail"), "jail_pay", CTRL+Key_P, this, SIGNAL(jailPay()), actionCollection(), "move_jailpay"); + m_jailPay->setEnabled(false); + m_jailRoll = new KAction(i18n("Roll to Leave &Jail")/*, "atlantik_move_jail_roll"*/, CTRL+Key_J, this, SIGNAL(jailRoll()), actionCollection(), "move_jailroll"); + m_jailRoll->setEnabled(false); + + // Mix code and XML into GUI + KMainWindow::createGUI(); + applyMainWindowSettings( KGlobal::config(), "AtlantikMainWindow" ); + KMainWindow::statusBar()->insertItem("Atlantik " ATLANTIK_VERSION_STRING, 0); + KMainWindow::statusBar()->insertItem(QString::null, 1); + connect(statusBar(), SIGNAL(released(int)), this, SLOT(statusBarClick(int))); + + // Main widget, containing all others + m_mainWidget = new QWidget(this, "main"); + m_mainWidget->show(); + m_mainLayout = new QGridLayout(m_mainWidget, 3, 2); + setCentralWidget(m_mainWidget); + + // Vertical view area for portfolios. + m_portfolioScroll = new QScrollView(m_mainWidget, "pfScroll"); + m_mainLayout->addWidget( m_portfolioScroll, 0, 0 ); + m_portfolioScroll->setHScrollBarMode( QScrollView::AlwaysOff ); + m_portfolioScroll->setResizePolicy( QScrollView::AutoOneFit ); + m_portfolioScroll->setFixedHeight( 200 ); + m_portfolioScroll->hide(); + + m_portfolioWidget = new QWidget( m_portfolioScroll->viewport(), "pfWidget" ); + m_portfolioScroll->addChild( m_portfolioWidget ); + m_portfolioWidget->show(); + + m_portfolioLayout = new QVBoxLayout(m_portfolioWidget); + m_portfolioViews.setAutoDelete(true); + + // Nice label +// m_portfolioLabel = new QLabel(i18n("Players"), m_portfolioWidget, "pfLabel"); +// m_portfolioLayout->addWidget(m_portfolioLabel); +// m_portfolioLabel->show(); + + // Text view for chat and status messages from server. + m_serverMsgs = new LogTextEdit(m_mainWidget, "serverMsgs"); + m_serverMsgs->setTextFormat(QTextEdit::PlainText); + m_serverMsgs->setReadOnly(true); + m_serverMsgs->setHScrollBarMode(QScrollView::AlwaysOff); + m_serverMsgs->setMinimumWidth(200); + m_mainLayout->addWidget(m_serverMsgs, 1, 0); + + // LineEdit to enter commands and chat messages. + m_input = new QLineEdit(m_mainWidget, "input"); + m_mainLayout->addWidget(m_input, 2, 0); + + m_serverMsgs->setFocusProxy(m_input); + + connect(m_input, SIGNAL(returnPressed()), this, SLOT(slotSendMsg())); + + // Set stretching where we want it. + m_mainLayout->setRowStretch(1, 1); // make m_board+m_serverMsgs stretch vertically, not the rest + m_mainLayout->setColStretch(1, 1); // make m_board stretch horizontally, not the rest + + // Check command-line args to see if we need to connect or show Monopigator window + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + QCString host = args->getOption("host"); + QCString port = args->getOption("port"); + if (!host.isNull() && !port.isNull()) + m_atlantikNetwork->serverConnect(host, port.toInt()); + else + showSelectServer(); +} + +void Atlantik::readConfig() +{ + // Read configuration settings + KConfig *config = kapp->config(); + + // General configuration + config->setGroup("General"); + m_config.chatTimestamps = config->readBoolEntry("ChatTimeStamps", false); + + // Personalization configuration + config->setGroup("Personalization"); + m_config.playerName = config->readEntry("PlayerName", "Atlantik"); + m_config.playerImage = config->readEntry("PlayerImage", "cube.png"); + + // Board configuration + config->setGroup("Board"); + m_config.indicateUnowned = config->readBoolEntry("IndicateUnowned", true); + m_config.highliteUnowned = config->readBoolEntry("HighliteUnowned", false); + m_config.darkenMortgaged = config->readBoolEntry("DarkenMortgaged", true); + m_config.animateTokens = config->readBoolEntry("AnimateToken", false); + m_config.quartzEffects = config->readBoolEntry("QuartzEffects", true); + + // Meta server configuation + config->setGroup("Monopigator"); + m_config.connectOnStart = config->readBoolEntry("ConnectOnStart", false); + m_config.hideDevelopmentServers = config->readBoolEntry("HideDevelopmentServers", true); + + // Portfolio colors + config->setGroup("WM"); + QColor activeDefault(204, 204, 204), inactiveDefault(153, 153, 153); + m_config.activeColor = config->readColorEntry("activeBackground", &activeDefault); + m_config.inactiveColor = config->readColorEntry("inactiveBlend", &inactiveDefault); +} + +void Atlantik::newPlayer(Player *player) +{ + initBoard(); + m_board->addToken(player); + addPortfolioView(player); + + // Player::changed() is not connected until later this method, so + // we'd better force an update. + playerChanged(player); + + connect(player, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); + connect(player, SIGNAL(gainedTurn()), this, SLOT(gainedTurn())); + connect(player, SIGNAL(changed(Player *)), m_board, SLOT(playerChanged(Player *))); + + KNotifyClient::event(winId(), "newplayer"); +} + +void Atlantik::newEstate(Estate *estate) +{ + initBoard(); + m_board->addEstateView(estate, m_config.indicateUnowned, m_config.highliteUnowned, m_config.darkenMortgaged, m_config.quartzEffects); +} + +void Atlantik::newTrade(Trade *trade) +{ + TradeDisplay *tradeDisplay = new TradeDisplay(trade, m_atlanticCore, 0, "tradeDisplay"); + m_tradeGUIMap[trade] = tradeDisplay; + tradeDisplay->show(); +} + +void Atlantik::newAuction(Auction *auction) +{ + initBoard(); + m_board->addAuctionWidget(auction); +} + +void Atlantik::removeGUI(Player *player) +{ + // Find and remove portfolioview + PortfolioView *portfolioView = findPortfolioView(player); + if (portfolioView) + m_portfolioViews.remove(portfolioView); + + if (m_board) + m_board->removeToken(player); +} + +void Atlantik::removeGUI(Trade *trade) +{ + if (TradeDisplay *tradeDisplay = m_tradeGUIMap[trade]) + delete tradeDisplay; +} + +void Atlantik::showSelectServer() +{ + if (m_selectServer) + return; + + m_selectServer = new SelectServer(m_config.connectOnStart, m_config.hideDevelopmentServers, m_mainWidget, "selectServer"); + m_mainLayout->addMultiCellWidget(m_selectServer, 0, 2, 1, 1); + m_selectServer->show(); + + if (m_selectGame) + { + delete m_selectGame; + m_selectGame = 0; + } + + m_atlanticCore->reset(true); + initNetworkObject(); + + connect(m_selectServer, SIGNAL(serverConnect(const QString, int)), m_atlantikNetwork, SLOT(serverConnect(const QString, int))); + connect(m_selectServer, SIGNAL(msgStatus(const QString &)), this, SLOT(slotMsgStatus(const QString &))); + + m_selectServer->slotRefresh( m_config.connectOnStart ); +} + +void Atlantik::showSelectGame() +{ + if (m_selectGame) + return; + + m_selectGame = new SelectGame(m_atlanticCore, m_mainWidget, "selectGame"); + m_atlanticCore->emitGames(); + + m_mainLayout->addMultiCellWidget(m_selectGame, 0, 2, 1, 1); + m_selectGame->show(); + + // Reset core and GUI + if (m_board) + { + m_board->hide(); + m_board->reset(); +// delete m_board; +// m_board = 0; + + // m_portfolioViews.clear(); + m_atlanticCore->reset(); + } + + if (m_selectServer) + { + delete m_selectServer; + m_selectServer = 0; + } + if (m_selectConfiguration) + { + delete m_selectConfiguration; + m_selectConfiguration = 0; + } + + connect(m_selectGame, SIGNAL(joinGame(int)), m_atlantikNetwork, SLOT(joinGame(int))); + connect(m_selectGame, SIGNAL(newGame(const QString &)), m_atlantikNetwork, SLOT(newGame(const QString &))); + connect(m_selectGame, SIGNAL(leaveServer()), this, SLOT(showSelectServer())); + connect(m_selectGame, SIGNAL(msgStatus(const QString &)), this, SLOT(slotMsgStatus(const QString &))); +} + +void Atlantik::showSelectConfiguration() +{ + if (m_selectConfiguration) + return; + + if (m_selectGame) + { + delete m_selectGame; + m_selectGame = 0; + } + + m_selectConfiguration = new SelectConfiguration(m_atlanticCore, m_mainWidget, "selectConfiguration"); + m_mainLayout->addMultiCellWidget(m_selectConfiguration, 0, 2, 1, 1); + m_selectConfiguration->show(); + + connect(m_atlanticCore, SIGNAL(createGUI(ConfigOption *)), m_selectConfiguration, SLOT(addConfigOption(ConfigOption *))); + connect(m_atlantikNetwork, SIGNAL(gameOption(QString, QString, QString, QString, QString)), m_selectConfiguration, SLOT(gameOption(QString, QString, QString, QString, QString))); + connect(m_atlantikNetwork, SIGNAL(gameInit()), m_selectConfiguration, SLOT(initGame())); + connect(m_selectConfiguration, SIGNAL(startGame()), m_atlantikNetwork, SLOT(startGame())); + connect(m_selectConfiguration, SIGNAL(leaveGame()), m_atlantikNetwork, SLOT(leaveGame())); + connect(m_selectConfiguration, SIGNAL(changeOption(int, const QString &)), m_atlantikNetwork, SLOT(changeOption(int, const QString &))); + connect(m_selectConfiguration, SIGNAL(buttonCommand(QString)), m_atlantikNetwork, SLOT(writeData(QString))); + connect(m_selectConfiguration, SIGNAL(iconSelected(const QString &)), m_atlantikNetwork, SLOT(setImage(const QString &))); + connect(m_selectConfiguration, SIGNAL(statusMessage(const QString &)), this, SLOT(slotMsgStatus(const QString &))); +} + +void Atlantik::initBoard() +{ + if (m_board) + return; + + m_board = new AtlantikBoard(m_atlanticCore, 40, AtlantikBoard::Play, m_mainWidget, "board"); + m_board->setViewProperties(m_config.indicateUnowned, m_config.highliteUnowned, m_config.darkenMortgaged, m_config.quartzEffects, m_config.animateTokens); + + connect(m_atlantikNetwork, SIGNAL(displayDetails(QString, bool, bool, Estate *)), m_board, SLOT(insertDetails(QString, bool, bool, Estate *))); + connect(m_atlantikNetwork, SIGNAL(addCommandButton(QString, QString, bool)), m_board, SLOT(displayButton(QString, QString, bool))); + connect(m_atlantikNetwork, SIGNAL(addCloseButton()), m_board, SLOT(addCloseButton())); + connect(m_board, SIGNAL(tokenConfirmation(Estate *)), m_atlantikNetwork, SLOT(tokenConfirmation(Estate *))); + connect(m_board, SIGNAL(buttonCommand(QString)), m_atlantikNetwork, SLOT(writeData(QString))); +} + +void Atlantik::showBoard() +{ + if (m_selectGame) + { + delete m_selectGame; + m_selectGame = 0; + } + + if (m_selectConfiguration) + { + delete m_selectConfiguration; + m_selectConfiguration = 0; + } + + if (!m_board) + initBoard(); + + m_runningGame = true; + + m_mainLayout->addMultiCellWidget(m_board, 0, 2, 1, 1); + m_board->displayDefault(); + m_board->show(); + + PortfolioView *portfolioView = 0; + for (QPtrListIterator<PortfolioView> it(m_portfolioViews); *it; ++it) + if ((portfolioView = dynamic_cast<PortfolioView*>(*it))) + portfolioView->buildPortfolio(); +} + +void Atlantik::freezeBoard() +{ + if (!m_board) + showBoard(); + + m_runningGame = false; + // TODO: m_board->freeze(); +} + +void Atlantik::slotNetworkConnected() +{ +} + +void Atlantik::slotNetworkError(int errnum) +{ + QString errMsg(i18n("Error connecting: ")); + + switch (m_atlantikNetwork->status()) + { + case IO_ConnectError: + if (errnum == ECONNREFUSED) + errMsg.append(i18n("connection refused by host.")); + else + errMsg.append(i18n("could not connect to host.")); + break; + + case IO_LookupError: + errMsg.append(i18n("host not found.")); + break; + + default: + errMsg.append(i18n("unknown error.")); + } + + serverMsgsAppend(errMsg); + + // Re-init network object + initNetworkObject(); +} + +void Atlantik::networkClosed(int status) +{ + switch( status ) + { + case KBufferedIO::involuntary: + slotMsgStatus( i18n("Connection with server %1:%2 lost.").arg(m_atlantikNetwork->host()).arg(m_atlantikNetwork->port()), QString("connect_no") ); + showSelectServer(); + break; + default: + if ( !m_atlantikNetwork->host().isEmpty() ) + slotMsgStatus( i18n("Disconnected from %1:%2.").arg(m_atlantikNetwork->host()).arg(m_atlantikNetwork->port()), QString("connect_no") ); + break; + } +} + +void Atlantik::slotConfigure() +{ + if (m_configDialog == 0) + m_configDialog = new ConfigDialog(this); + m_configDialog->show(); + + connect(m_configDialog, SIGNAL(okClicked()), this, SLOT(slotUpdateConfig())); +} + +void Atlantik::showEventLog() +{ + if (!m_eventLogWidget) + m_eventLogWidget = new EventLogWidget(m_eventLog, 0); + m_eventLogWidget->show(); +} + +void Atlantik::configureNotifications() +{ + KNotifyDialog::configure(this); +} + +void Atlantik::slotUpdateConfig() +{ + KConfig *config=kapp->config(); + bool optBool, configChanged = false; + QString optStr; + + optBool = m_configDialog->chatTimestamps(); + if (m_config.chatTimestamps != optBool) + { + m_config.chatTimestamps = optBool; + configChanged = true; + } + + optStr = m_configDialog->playerName(); + if (m_config.playerName != optStr) + { + m_config.playerName = optStr; + m_atlantikNetwork->setName(optStr); + } + + optStr = m_configDialog->playerImage(); + if (m_config.playerImage != optStr) + { + m_config.playerImage = optStr; + m_atlantikNetwork->setImage(optStr); + } + + optBool = m_configDialog->indicateUnowned(); + if (m_config.indicateUnowned != optBool) + { + m_config.indicateUnowned = optBool; + configChanged = true; + } + + optBool = m_configDialog->highliteUnowned(); + if (m_config.highliteUnowned != optBool) + { + m_config.highliteUnowned = optBool; + configChanged = true; + } + + optBool = m_configDialog->darkenMortgaged(); + if (m_config.darkenMortgaged != optBool) + { + m_config.darkenMortgaged = optBool; + configChanged = true; + } + + optBool = m_configDialog->animateToken(); + if (m_config.animateTokens != optBool) + { + m_config.animateTokens = optBool; + configChanged = true; + } + + optBool = m_configDialog->quartzEffects(); + if (m_config.quartzEffects != optBool) + { + m_config.quartzEffects = optBool; + configChanged = true; + } + + optBool = m_configDialog->connectOnStart(); + if (m_config.connectOnStart != optBool) + { + m_config.connectOnStart = optBool; + configChanged = true; + } + + optBool = m_configDialog->hideDevelopmentServers(); + if (m_config.hideDevelopmentServers != optBool) + { + m_config.hideDevelopmentServers = optBool; + if (m_selectServer) + m_selectServer->setHideDevelopmentServers(optBool); + + configChanged = true; + } + + config->setGroup("General"); + config->writeEntry("ChatTimeStamps", m_config.chatTimestamps); + + config->setGroup("Personalization"); + config->writeEntry("PlayerName", m_config.playerName); + config->writeEntry("PlayerImage", m_config.playerImage); + + config->setGroup("Board"); + config->writeEntry("IndicateUnowned", m_config.indicateUnowned); + config->writeEntry("HighliteUnowned", m_config.highliteUnowned); + config->writeEntry("DarkenMortgaged", m_config.darkenMortgaged); + config->writeEntry("AnimateToken", m_config.animateTokens); + config->writeEntry("QuartzEffects", m_config.quartzEffects); + + config->setGroup("Monopigator"); + config->writeEntry("ConnectOnStart", m_config.connectOnStart); + config->writeEntry("HideDevelopmentServers", m_config.hideDevelopmentServers); + + config->sync(); + + if (configChanged && m_board) + m_board->setViewProperties(m_config.indicateUnowned, m_config.highliteUnowned, m_config.darkenMortgaged, m_config.quartzEffects, m_config.animateTokens); +} + +void Atlantik::slotSendMsg() +{ + m_atlantikNetwork->cmdChat(m_input->text()); + m_input->setText(QString::null); +} + +void Atlantik::slotMsgInfo(QString msg) +{ + serverMsgsAppend(msg); +} + +void Atlantik::slotMsgError(QString msg) +{ + serverMsgsAppend("Error: " + msg); +} + +void Atlantik::slotMsgStatus(const QString &message, const QString &icon) +{ + KMainWindow::statusBar()->changeItem(message, 1); + m_eventLog->addEvent(message, icon); +} + +void Atlantik::slotMsgChat(QString player, QString msg) +{ + if (m_config.chatTimestamps) + { + QTime time = QTime::currentTime(); + serverMsgsAppend(QString("[%1] %2: %3").arg(time.toString("hh:mm")).arg(player).arg(msg)); + } + else + serverMsgsAppend(player + ": " + msg); + KNotifyClient::event(winId(), "chat"); +} + +void Atlantik::serverMsgsAppend(QString msg) +{ + // Use append, not setText(old+new) because that one doesn't wrap + m_serverMsgs->append(msg); + m_serverMsgs->ensureVisible(0, m_serverMsgs->contentsHeight()); +} + +void Atlantik::playerChanged(Player *player) +{ + PortfolioView *portfolioView = findPortfolioView(player); + if (!portfolioView) + portfolioView = addPortfolioView(player); + + Player *playerSelf = m_atlanticCore->playerSelf(); + if (player == playerSelf) + { + // We changed ourselves.. + PortfolioView *portfolioView = 0; + for (QPtrListIterator<PortfolioView> it(m_portfolioViews); *it; ++it) + if ((portfolioView = dynamic_cast<PortfolioView*>(*it))) + { + // Clear all portfolios if we're not in game + if ( !player->game() ) + portfolioView->clearPortfolio(); + + // Show players in our game, hide the rest + Player *pTmp = portfolioView->player(); + if (pTmp->game() == playerSelf->game()) + portfolioView->show(); + else + portfolioView->hide(); + } + if (!player->game()) + showSelectGame(); + else + { + if ( !m_board || m_board->isHidden() ) + showSelectConfiguration(); + } + + m_roll->setEnabled(player->canRoll()); + m_buyEstate->setEnabled(player->canBuy()); + m_auctionEstate->setEnabled(player->canAuction()); + + // TODO: Should be more finetuned, but monopd doesn't send can_endturn can_payjail can_jailroll yet + m_endTurn->setEnabled(player->hasTurn() && !(player->canRoll() || player->canBuy() || player->inJail())); + m_jailCard->setEnabled(player->canUseCard()); + m_jailPay->setEnabled(player->hasTurn() && player->inJail()); + m_jailRoll->setEnabled(player->hasTurn() && player->inJail()); + } + else + { + // Another player changed, check if we need to show or hide + // his/her portfolioView. + if (playerSelf) + { + if (player->game() == playerSelf->game()) + portfolioView->show(); + else + portfolioView->hide(); + } + else if ( !player->game() ) + portfolioView->hide(); + } +} + +void Atlantik::gainedTurn() +{ + KNotifyClient::event(winId(), "gainedturn", i18n("It is your turn now.") ); +} + +void Atlantik::initEventLog() +{ + m_eventLog = new EventLog(); +} + +void Atlantik::initNetworkObject() +{ + if (m_atlantikNetwork) + { + m_atlantikNetwork->reset(); + return; + } + + m_atlantikNetwork = new AtlantikNetwork(m_atlanticCore); + connect(m_atlantikNetwork, SIGNAL(msgInfo(QString)), this, SLOT(slotMsgInfo(QString))); + connect(m_atlantikNetwork, SIGNAL(msgError(QString)), this, SLOT(slotMsgError(QString))); + connect(m_atlantikNetwork, SIGNAL(msgStatus(const QString &, const QString &)), this, SLOT(slotMsgStatus(const QString &, const QString &))); + connect(m_atlantikNetwork, SIGNAL(msgChat(QString, QString)), this, SLOT(slotMsgChat(QString, QString))); + + connect(m_atlantikNetwork, SIGNAL(connectionSuccess()), this, SLOT(slotNetworkConnected())); + connect(m_atlantikNetwork, SIGNAL(connectionFailed(int)), this, SLOT(slotNetworkError(int))); + connect(m_atlantikNetwork, SIGNAL(closed(int)), this, SLOT(networkClosed(int))); + + connect(m_atlantikNetwork, SIGNAL(receivedHandshake()), this, SLOT(sendHandshake())); + + connect(m_atlantikNetwork, SIGNAL(gameConfig()), this, SLOT(showSelectConfiguration())); + connect(m_atlantikNetwork, SIGNAL(gameInit()), this, SLOT(initBoard())); + connect(m_atlantikNetwork, SIGNAL(gameRun()), this, SLOT(showBoard())); + connect(m_atlantikNetwork, SIGNAL(gameEnd()), this, SLOT(freezeBoard())); + + connect(m_atlantikNetwork, SIGNAL(newEstate(Estate *)), this, SLOT(newEstate(Estate *))); + connect(m_atlantikNetwork, SIGNAL(newAuction(Auction *)), this, SLOT(newAuction(Auction *))); + + connect(m_atlantikNetwork, SIGNAL(clientCookie(QString)), this, SLOT(clientCookie(QString))); + connect(m_atlantikNetwork, SIGNAL(networkEvent(const QString &, const QString &)), m_eventLog, SLOT(addEvent(const QString &, const QString &))); + + connect(this, SIGNAL(rollDice()), m_atlantikNetwork, SLOT(rollDice())); + connect(this, SIGNAL(buyEstate()), m_atlantikNetwork, SLOT(buyEstate())); + connect(this, SIGNAL(auctionEstate()), m_atlantikNetwork, SLOT(auctionEstate())); + connect(this, SIGNAL(endTurn()), m_atlantikNetwork, SLOT(endTurn())); + connect(this, SIGNAL(jailCard()), m_atlantikNetwork, SLOT(jailCard())); + connect(this, SIGNAL(jailPay()), m_atlantikNetwork, SLOT(jailPay())); + connect(this, SIGNAL(jailRoll()), m_atlantikNetwork, SLOT(jailRoll())); +} + +void Atlantik::clientCookie(QString cookie) +{ + KConfig *config = kapp->config(); + + if (cookie.isNull()) + { + if (config->hasGroup("Reconnection")) + config->deleteGroup("Reconnection", true); + } + else if (m_atlantikNetwork) + { + config->setGroup("Reconnection"); + config->writeEntry("Host", m_atlantikNetwork->host()); + config->writeEntry("Port", m_atlantikNetwork->port()); + config->writeEntry("Cookie", cookie); + } + else + return; + + config->sync(); +} + +void Atlantik::sendHandshake() +{ + m_atlantikNetwork->setName(m_config.playerName); + m_atlantikNetwork->setImage(m_config.playerImage); + + // Check command-line args to see if we need to auto-join + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + QCString game = args->getOption("game"); + if (!game.isNull()) + m_atlantikNetwork->joinGame(game.toInt()); +} + +void Atlantik::statusBarClick(int item) +{ + if ( item == 0 ) + { + KAboutApplication dialog(kapp->aboutData(), this); + dialog.exec(); + } + else if ( item == 1) + showEventLog(); +} + +PortfolioView *Atlantik::addPortfolioView(Player *player) +{ + PortfolioView *portfolioView = new PortfolioView(m_atlanticCore, player, m_config.activeColor, m_config.inactiveColor, m_portfolioWidget); + m_portfolioViews.append(portfolioView); + if ( m_portfolioViews.count() > 0 && m_portfolioScroll->isHidden() ) + m_portfolioScroll->show(); + + connect(player, SIGNAL(changed(Player *)), portfolioView, SLOT(playerChanged())); + connect(portfolioView, SIGNAL(newTrade(Player *)), m_atlantikNetwork, SLOT(newTrade(Player *))); + connect(portfolioView, SIGNAL(kickPlayer(Player *)), m_atlantikNetwork, SLOT(kickPlayer(Player *))); + connect(portfolioView, SIGNAL(estateClicked(Estate *)), m_board, SLOT(prependEstateDetails(Estate *))); + + m_portfolioLayout->addWidget(portfolioView); + portfolioView->show(); + + return portfolioView; +} + +PortfolioView *Atlantik::findPortfolioView(Player *player) +{ + PortfolioView *portfolioView = 0; + for (QPtrListIterator<PortfolioView> it(m_portfolioViews); (portfolioView = *it) ; ++it) + if (player == portfolioView->player()) + return portfolioView; + + return 0; +} + +void Atlantik::closeEvent(QCloseEvent *e) +{ + Game *gameSelf = m_atlanticCore->gameSelf(); + Player *playerSelf = m_atlanticCore->playerSelf(); + + int result = KMessageBox::Continue; + if ( gameSelf && !playerSelf->isBankrupt() && m_runningGame ) + result = KMessageBox::warningContinueCancel( this, i18n("You are currently part of an active game. Are you sure you want to close Atlantik? If you do, you forfeit the game."), i18n("Close & Forfeit?"), i18n("Close && Forfeit") ); + + if ( result == KMessageBox::Continue ) + { + if ( m_atlantikNetwork ) + m_atlantikNetwork->leaveGame(); + + saveMainWindowSettings(kapp->config(), "AtlantikMainWindow"); + KMainWindow::closeEvent(e); + } +} diff --git a/atlantik/client/atlantik.h b/atlantik/client/atlantik.h new file mode 100644 index 00000000..94f2ca7c --- /dev/null +++ b/atlantik/client/atlantik.h @@ -0,0 +1,268 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_ATLANTIK_H +#define ATLANTIK_ATLANTIK_H + +#include <qwidget.h> +#include <qlayout.h> +#include <qtextedit.h> +#include <qlabel.h> +#include <qptrlist.h> + +#include <kmainwindow.h> + +#include "configdlg.h" +#include "portfolioview.h" +#include "board.h" + +class QScrollView; + +class AtlanticCore; +class AtlantikNetwork; + +struct AtlantikConfig +{ + // General options; + bool chatTimestamps; + + // Personalization options + QString playerName, playerImage; + + // Board options + bool indicateUnowned; + bool highliteUnowned; + bool darkenMortgaged; + bool quartzEffects; + bool animateTokens; + + // Meta server options + bool connectOnStart; + bool hideDevelopmentServers; + + // Portfolio colors + QColor activeColor, inactiveColor; +}; + +class EventLog; +class EventLogWidget; +class SelectServer; +class SelectGame; +class SelectConfiguration; +class TradeDisplay; + +class Player; +class Estate; +class Trade; + +class LogTextEdit : public QTextEdit +{ +Q_OBJECT + +public: + LogTextEdit( QWidget *parent = 0, const char *name = 0 ); + virtual ~LogTextEdit(); + + QPopupMenu *createPopupMenu( const QPoint & pos ); + +private: + KAction *m_clear, *m_selectAll, *m_copy; +}; + +/** + * Main Atlantik window. + * Manages gameboard, portfolios and pretty much everything else. + * + * @author Rob Kaper <[email protected]> + */ +class Atlantik : public KMainWindow +{ +Q_OBJECT + +public: + /** + * Create an Atlantik window. + * + */ + Atlantik(); + + /** + * Read the configuration settings using KConfig. + * + */ + void readConfig(); + + /** + * Appends a message the text view. + * + * @param msg Message to be appended. + */ + void serverMsgsAppend(QString msg); + + AtlantikConfig config() { return m_config; } + +private slots: + void showSelectServer(); + void showSelectGame(); + void showSelectConfiguration(); + void initBoard(); + void showBoard(); + void freezeBoard(); + void clientCookie(QString cookie); + void sendHandshake(); + void statusBarClick(int); + +public slots: + + /** + * A network connection has been established, so we can show the game + * list instead of the server list. + * + */ + void slotNetworkConnected(); + + /** + * An error occurred while setting up the network connection. Inform the + * user. + * + * @param errno See http://doc.trolltech.com/3.0/qsocket.html#Error-enum + */ + void slotNetworkError(int errnum); + + void networkClosed(int status); + + /** + * Creates a new modeless configure dialog or raises it when it already exists. + * + */ + void slotConfigure(); + + /** + * Opens the event log widget. + * + */ + void showEventLog(); + + /** + * Opens the KNotify dialog for configuration events. + * + */ + void configureNotifications(); + + /** + * Reads values from configuration dialog and stores them into + * global configuration struct. If values have changed, appropriate + * methods within the application are called. Configuration is saved + * to file in any case. + * + */ + void slotUpdateConfig(); + + /** + * Writes the contents of the text input field to the network + * interface and clears the text input field. + * + */ + void slotSendMsg(); + + /** + * Informs serverMsgs() to append an incoming message from the + * server to the text view as informational message. + * + * @param msg The message to be appended. + */ + void slotMsgInfo(QString msg); + + void slotMsgStatus(const QString &message, const QString &icon = QString::null); + + /** + * Informs serverMsgs() to append an incoming message from the + * server to the text view as error message. + * + * @param msg The error message to be appended. + */ + void slotMsgError(QString msg); + + /** + * Informs serverMsgs() to append an incoming message from the + * server to the text view as chat message. + * + * @param player The name of the player chatting. + * @param msg The chat message to be appended. + */ + void slotMsgChat(QString player, QString msg); + + void newPlayer(Player *player); + void newEstate(Estate *estate); + void newTrade(Trade *trade); + void newAuction(Auction *auction); + + void removeGUI(Player *player); + void removeGUI(Trade *trade); + + void playerChanged(Player *player); + void gainedTurn(); + +signals: + void rollDice(); + void buyEstate(); + void auctionEstate(); + void endTurn(); + void jailCard(); + void jailPay(); + void jailRoll(); + +protected: + void closeEvent(QCloseEvent *); + +private: + void initEventLog(); + void initNetworkObject(); + PortfolioView *addPortfolioView(Player *player); + PortfolioView *findPortfolioView(Player *player); + + QScrollView *m_portfolioScroll; + QWidget *m_mainWidget, *m_portfolioWidget; + QGridLayout *m_mainLayout; + QVBoxLayout *m_portfolioLayout; + + QLabel *m_portfolioLabel; + QLineEdit *m_input; + QTextEdit *m_serverMsgs; + + KAction *m_roll, *m_buyEstate, *m_auctionEstate, *m_endTurn, + *m_jailCard, *m_jailPay, *m_jailRoll, *m_configure, + *m_showEventLog; + + AtlanticCore *m_atlanticCore; + AtlantikNetwork *m_atlantikNetwork; + AtlantikConfig m_config; + + ConfigDialog *m_configDialog; + AtlantikBoard *m_board; + SelectServer *m_selectServer; + SelectGame *m_selectGame; + SelectConfiguration *m_selectConfiguration; + EventLog *m_eventLog; + EventLogWidget *m_eventLogWidget; + + QPtrList<PortfolioView> m_portfolioViews; + QMap<Trade *, TradeDisplay *> m_tradeGUIMap; + + bool m_runningGame; +}; + +#endif diff --git a/atlantik/client/configdlg.cpp b/atlantik/client/configdlg.cpp new file mode 100644 index 00000000..a8e152b5 --- /dev/null +++ b/atlantik/client/configdlg.cpp @@ -0,0 +1,334 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qlayout.h> +#include <qgroupbox.h> +#include <qwhatsthis.h> +#include <qlabel.h> + +#include <kdeversion.h> +#undef KDE_3_1_FEATURES +#undef KDE_3_3_FEATURES +#if defined(KDE_MAKE_VERSION) +#if KDE_VERSION >= KDE_MAKE_VERSION(3,1,0) +#define KDE_3_1_FEATURES +#endif +#if KDE_VERSION >= KDE_MAKE_VERSION(3,2,90) +#define KDE_3_3_FEATURES +#endif +#endif + +#include <kicondialog.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <kstandarddirs.h> + +#include "atlantik.h" +#include "configdlg.moc" + +ConfigDialog::ConfigDialog(Atlantik* parent, const char *name) : KDialogBase(IconList, i18n("Configure Atlantik"), Ok|Cancel, Ok, parent, "config_atlantik", false, name) +{ + m_parent = parent; + p_general = addPage(i18n("General"), i18n("General"), BarIcon("configure", KIcon::SizeMedium)); + p_p13n = addPage(i18n("Personalization"), i18n("Personalization"), BarIcon("personal", KIcon::SizeMedium)); + p_board = addPage(i18n("Board"), i18n("Board"), BarIcon("monop_board", KIcon::SizeMedium)); + p_monopigator = addPage(i18n("Meta Server"), i18n("Meta Server"), BarIcon("network", KIcon::SizeMedium)); + + configGeneral = new ConfigGeneral(this, p_general, "configGeneral"); + configPlayer = new ConfigPlayer(this, p_p13n, "configPlayer"); + configBoard = new ConfigBoard(this, p_board, "configBoard"); + configMonopigator = new ConfigMonopigator(this, p_monopigator, "configMonopigator"); + + setMinimumSize(sizeHint()); +} + +bool ConfigDialog::chatTimestamps() +{ + return configGeneral->chatTimestamps(); +} + +bool ConfigDialog::indicateUnowned() +{ + return configBoard->indicateUnowned(); +} + +bool ConfigDialog::highliteUnowned() +{ + return configBoard->highliteUnowned(); +} + +bool ConfigDialog::darkenMortgaged() +{ + return configBoard->darkenMortgaged(); +} + +bool ConfigDialog::animateToken() +{ + return configBoard->animateToken(); +} + +bool ConfigDialog::quartzEffects() +{ + return configBoard->quartzEffects(); +} + +QString ConfigDialog::playerName() +{ + return configPlayer->playerName(); +} + +QString ConfigDialog::playerImage() +{ + return configPlayer->playerImage(); +} + +bool ConfigDialog::connectOnStart() +{ + return configMonopigator->connectOnStart(); +} + +bool ConfigDialog::hideDevelopmentServers() +{ + return configMonopigator->hideDevelopmentServers(); +} + +AtlantikConfig ConfigDialog::config() +{ + return m_parent->config(); +} + +ConfigPlayer::ConfigPlayer(ConfigDialog* configDialog, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_configDialog = configDialog; + QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint()); + + QLabel *label = new QLabel(i18n("Player name:"), parent); + layout->addWidget(label); + + m_playerName = new QLineEdit(parent); + layout->addWidget(m_playerName); + + QLabel *label2 = new QLabel(i18n("Player image:"), parent); + layout->addWidget(label2); + + m_playerIcon = new KPushButton(parent, "playerIcon"); + layout->addWidget(m_playerIcon); + + connect( m_playerIcon, SIGNAL(clicked()), this, SLOT(chooseImage()) ); + + layout->addStretch(1); + + reset(); +} + +QString ConfigPlayer::playerName() +{ + return m_playerName->text(); +} + +QString ConfigPlayer::playerImage() +{ + return m_playerImage; +} +void ConfigPlayer::chooseImage() +{ + KIconDialog iconDialog( this, "iconDialog" ); +#ifdef KDE_3_1_FEATURES + iconDialog.setCustomLocation( locate("appdata", "themes/default/tokens/") ); +#endif + +#ifdef KDE_3_3_FEATURES + iconDialog.setup( KIcon::Desktop, KIcon::Application, false, 0, true, true, true ); // begin with user icons, lock editing +#else + iconDialog.setup( KIcon::Desktop, KIcon::Application, false, 0, true ); // begin with user icons +#endif + + QString image = iconDialog.openDialog(); + + if ( image.isEmpty() ) + return; + + QStringList splitPath = QStringList::split( '/', image ); + m_playerImage = splitPath[ splitPath.count()-1 ]; + + setImage(); +} + +void ConfigPlayer::setImage() +{ + QString filename = locate("data", "atlantik/themes/default/tokens/" + m_playerImage); + if (KStandardDirs::exists(filename)) + m_playerIcon->setPixmap( QPixmap(filename) ); +} + +void ConfigPlayer::reset() +{ + m_playerName->setText(m_configDialog->config().playerName); + m_playerImage = m_configDialog->config().playerImage; + setImage(); +} + +ConfigMonopigator::ConfigMonopigator(ConfigDialog *configDialog, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_configDialog = configDialog; + QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint()); + + m_connectOnStart = new QCheckBox(i18n("Request list of Internet servers on start-up"), parent); + layout->addWidget(m_connectOnStart); + + QString message=i18n( + "If checked, Atlantik connects to a meta server on start-up to\n" + "request a list of Internet servers.\n"); + QWhatsThis::add(m_connectOnStart, message); + + m_hideDevelopmentServers = new QCheckBox(i18n("Hide development servers"), parent); + layout->addWidget(m_hideDevelopmentServers); + + message=i18n( + "Some of the Internet servers might be running development\n" + "versions of the server software. If checked, Atlantik will not\n" + "display these servers.\n"); + QWhatsThis::add(m_hideDevelopmentServers, message); + + layout->addStretch(1); + + reset(); +} + +bool ConfigMonopigator::connectOnStart() +{ + return m_connectOnStart->isChecked(); +} + +bool ConfigMonopigator::hideDevelopmentServers() +{ + return m_hideDevelopmentServers->isChecked(); +} + +void ConfigMonopigator::reset() +{ + m_connectOnStart->setChecked(m_configDialog->config().connectOnStart); + m_hideDevelopmentServers->setChecked(m_configDialog->config().hideDevelopmentServers); +} + +ConfigGeneral::ConfigGeneral(ConfigDialog *configDialog, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_configDialog = configDialog; + QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint()); + + m_chatTimestamps = new QCheckBox(i18n("Show timestamps in chat messages"), parent); + layout->addWidget(m_chatTimestamps); + + QString message=i18n( + "If checked, Atlantik will add timestamps in front of chat\n" + "messages.\n"); + QWhatsThis::add(m_chatTimestamps, message); + + layout->addStretch(1); + + reset(); +} + +bool ConfigGeneral::chatTimestamps() +{ + return m_chatTimestamps->isChecked(); +} + +void ConfigGeneral::reset() +{ + m_chatTimestamps->setChecked(m_configDialog->config().chatTimestamps); +} + +ConfigBoard::ConfigBoard(ConfigDialog *configDialog, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_configDialog = configDialog; + QVBoxLayout *layout = new QVBoxLayout(parent, KDialog::marginHint(), KDialog::spacingHint()); + + QGroupBox *box = new QGroupBox(1, Qt::Horizontal, i18n("Game Status Feedback"), parent); + layout->addWidget(box); + + m_indicateUnowned = new QCheckBox(i18n("Display title deed card on unowned properties"), box); + QString message=i18n( + "If checked, unowned properties on the board display an estate\n" + "card to indicate the property is for sale.\n"); + QWhatsThis::add(m_indicateUnowned, message); + + m_highliteUnowned = new QCheckBox(i18n("Highlight unowned properties"), box); + message=i18n( + "If checked, unowned properties on the board are highlighted to\n" + "indicate the property is for sale.\n"); + QWhatsThis::add(m_highliteUnowned, message); + + m_darkenMortgaged = new QCheckBox(i18n("Darken mortgaged properties"), box); + message=i18n( + "If checked, mortgaged properties on the board will be colored\n" + "darker than of the default color.\n"); + QWhatsThis::add(m_darkenMortgaged, message); + + m_animateToken = new QCheckBox(i18n("Animate token movement"), box); + message=i18n( + "If checked, tokens will move across the board\n" + "instead of jumping directly to their new location.\n"); + QWhatsThis::add(m_animateToken, message); + + m_quartzEffects = new QCheckBox(i18n("Quartz effects"), box); + message=i18n( + "If checked, the colored headers of street estates on the board " + "will have a Quartz effect similar to the Quartz KWin style.\n"); + QWhatsThis::add(m_quartzEffects, message); + +// box = new QGroupBox(1, Qt::Horizontal, i18n("Size"), parent); +// layout->addWidget(box); + + layout->addStretch(1); + + reset(); +} + +bool ConfigBoard::indicateUnowned() +{ + return m_indicateUnowned->isChecked(); +} + +bool ConfigBoard::highliteUnowned() +{ + return m_highliteUnowned->isChecked(); +} + +bool ConfigBoard::darkenMortgaged() +{ + return m_darkenMortgaged->isChecked(); +} + +bool ConfigBoard::animateToken() +{ + return m_animateToken->isChecked(); +} + +bool ConfigBoard::quartzEffects() +{ + return m_quartzEffects->isChecked(); +} + +void ConfigBoard::reset() +{ + m_indicateUnowned->setChecked(m_configDialog->config().indicateUnowned); + m_highliteUnowned->setChecked(m_configDialog->config().highliteUnowned); + m_darkenMortgaged->setChecked(m_configDialog->config().darkenMortgaged); + m_animateToken->setChecked(m_configDialog->config().animateTokens); + m_quartzEffects->setChecked(m_configDialog->config().quartzEffects); +} diff --git a/atlantik/client/configdlg.h b/atlantik/client/configdlg.h new file mode 100644 index 00000000..c1f74294 --- /dev/null +++ b/atlantik/client/configdlg.h @@ -0,0 +1,139 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_CONFIGDLG_H +#define ATLANTIK_CONFIGDLG_H + +#include <qwidget.h> +#include <qcheckbox.h> +#include <qlineedit.h> + +#include <kdialogbase.h> + +class QString; + +class KPushButton; + +class Atlantik; +class ConfigDialog; + +struct AtlantikConfig; + +class ConfigPlayer : public QWidget +{ +Q_OBJECT + +public: + ConfigPlayer(ConfigDialog *configDialog, QWidget *parent, const char *name=0); + + QString playerName(); + QString playerImage(); + +private slots: + void chooseImage(); + +private: + void setImage(); + void reset(); + + ConfigDialog *m_configDialog; + QLineEdit *m_playerName; + QString m_playerImage; + KPushButton *m_playerIcon; +}; + +class ConfigBoard : public QWidget +{ +Q_OBJECT + +public: + ConfigBoard(ConfigDialog *configDialog, QWidget *parent, const char *name=0); + + bool indicateUnowned(); + bool highliteUnowned(); + bool darkenMortgaged(); + bool animateToken(); + bool quartzEffects(); + +private: + void reset(); + + ConfigDialog *m_configDialog; + QCheckBox *m_indicateUnowned, *m_highliteUnowned, *m_darkenMortgaged, *m_animateToken, *m_quartzEffects; +}; + +class ConfigMonopigator : public QWidget +{ +Q_OBJECT + +public: + ConfigMonopigator(ConfigDialog *dialog, QWidget *parent, const char *name = 0); + + bool connectOnStart(); + bool hideDevelopmentServers(); + +private: + void reset(); + + ConfigDialog *m_configDialog; + QCheckBox *m_connectOnStart, *m_hideDevelopmentServers; +}; + +class ConfigGeneral : public QWidget +{ +Q_OBJECT + +public: + ConfigGeneral(ConfigDialog *dialog, QWidget *parent, const char *name = 0); + + bool chatTimestamps(); + +private: + void reset(); + + ConfigDialog *m_configDialog; + QCheckBox *m_chatTimestamps; +}; + +class ConfigDialog : public KDialogBase +{ +Q_OBJECT + +public: + ConfigDialog(Atlantik *parent, const char *name=0); + + bool chatTimestamps(); + bool indicateUnowned(); + bool highliteUnowned(); + bool darkenMortgaged(); + bool animateToken(); + bool quartzEffects(); + AtlantikConfig config(); + QString playerName(); + QString playerImage(); + bool connectOnStart(); + bool hideDevelopmentServers(); + +private: + Atlantik *m_parent; + QFrame *p_general, *p_p13n, *p_board, *p_monopigator; + ConfigPlayer *configPlayer; + ConfigBoard *configBoard; + ConfigMonopigator *configMonopigator; + ConfigGeneral *configGeneral; +}; + +#endif diff --git a/atlantik/client/event.cpp b/atlantik/client/event.cpp new file mode 100644 index 00000000..218f6b87 --- /dev/null +++ b/atlantik/client/event.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qdatetime.h> +#include <qstring.h> + +#include "event.moc" + +Event::Event(const QDateTime &dateTime, const QString &description, const QString &icon) +{ + m_dateTime = dateTime; + m_description = description; + m_icon = icon; +} + +QDateTime Event::dateTime() const +{ + return m_dateTime; +} + +QString Event::description() const +{ + return m_description; +} + +QString Event::icon() const +{ + return m_icon; +} diff --git a/atlantik/client/event.h b/atlantik/client/event.h new file mode 100644 index 00000000..f2f56444 --- /dev/null +++ b/atlantik/client/event.h @@ -0,0 +1,40 @@ +// Copyright (c) 2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_EVENT_H +#define ATLANTIK_EVENT_H + +#include <qobject.h> + +class QDateTime; +class QString; + +class Event : public QObject +{ +Q_OBJECT + +public: + Event(const QDateTime &dateTime, const QString &description, const QString &icon = QString::null); + QDateTime dateTime() const; + QString description() const; + QString icon() const; + +private: + QDateTime m_dateTime; + QString m_description, m_icon; +}; + +#endif diff --git a/atlantik/client/eventlogwidget.cpp b/atlantik/client/eventlogwidget.cpp new file mode 100644 index 00000000..b0f77ab8 --- /dev/null +++ b/atlantik/client/eventlogwidget.cpp @@ -0,0 +1,123 @@ +// Copyright (c) 2003-2004 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <iostream> + +#include <qheader.h> +#include <qlayout.h> +#include <qdatetime.h> + +#include <klocale.h> +#include <klistview.h> +#include <kdialogbase.h> +#include <kfiledialog.h> +#include <kiconloader.h> +#include <kpushbutton.h> +#include <kstringhandler.h> + +#include "event.h" +#include "eventlogwidget.moc" + +EventLog::EventLog() +{ +} + +void EventLog::addEvent(const QString &description, const QString &icon) +{ + Event *event = new Event(QDateTime::currentDateTime(), description, icon); + m_events.append(event); + emit newEvent(event); +} + +QPtrList<Event> EventLog::events() +{ + return m_events; +} + +EventLogWidget::EventLogWidget(EventLog *eventLog, QWidget *parent, const char *name) + : QWidget(parent, name, + WType_Dialog | WStyle_Customize | WStyle_DialogBorder | WStyle_Title | + WStyle_Minimize | WStyle_ContextHelp ) +{ + m_eventLog = eventLog; + + connect(m_eventLog, SIGNAL(newEvent(Event *)), this, SLOT(addEvent(Event *))); + + setCaption(i18n("Event Log")); + + QVBoxLayout *listCompBox = new QVBoxLayout(this, KDialog::marginHint()); + + m_eventList = new KListView(this, "eventList"); + listCompBox->addWidget(m_eventList); + + m_eventList->addColumn(i18n("Date/Time")); + m_eventList->addColumn(i18n("Description")); + m_eventList->header()->setClickEnabled( false ); + + QHBoxLayout *actionBox = new QHBoxLayout(this, 0, KDialog::spacingHint()); + listCompBox->addItem(actionBox); + + actionBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + m_saveButton = new KPushButton(BarIcon("filesave", KIcon::SizeSmall), i18n("&Save As..."), this); + actionBox->addWidget(m_saveButton); + + connect(m_saveButton, SIGNAL(clicked()), this, SLOT(save())); + + // Populate + QPtrList<Event> events = m_eventLog->events(); + for (QPtrListIterator<Event> it( events ); (*it) ; ++it) + addEvent( (*it) ); +} + +void EventLogWidget::addEvent(Event *event) +{ + // FIXME: allow a way to view non-squeezed message + // FIXME: allow a way to show older messages + + if ( m_eventList->childCount() >= 25 ) + delete m_eventList->firstChild(); + + QString description = KStringHandler::rsqueeze( event->description(), 200 ); + KListViewItem *item = new KListViewItem(m_eventList, event->dateTime().toString("yyyy-MM-dd hh:mm:ss zzz"), description); + if (event->icon().isEmpty()) + item->setPixmap(1, QPixmap(SmallIcon("atlantik"))); + else + item->setPixmap(1, QPixmap(SmallIcon(event->icon()))); + + m_eventList->ensureItemVisible(item); +} + +void EventLogWidget::closeEvent(QCloseEvent *e) +{ + e->accept(); +} + +void EventLogWidget::save() +{ + QFile file( KFileDialog::getSaveFileName() ); + if ( file.open( IO_WriteOnly ) ) + { + QTextStream stream(&file); + + stream << i18n( "Atlantik log file, saved at %1." ).arg( QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") ) << endl; + + QPtrList<Event> events = m_eventLog->events(); + for (QPtrListIterator<Event> it( events ); (*it) ; ++it) + stream << (*it)->dateTime().toString("yyyy-MM-dd hh:mm:ss") << " " << (*it)->description() << endl; + file.close(); + } +} diff --git a/atlantik/client/eventlogwidget.h b/atlantik/client/eventlogwidget.h new file mode 100644 index 00000000..4b925d47 --- /dev/null +++ b/atlantik/client/eventlogwidget.h @@ -0,0 +1,73 @@ +// Copyright (c) 2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_EVENTLOGWIDGET_H +#define ATLANTIK_EVENTLOGWIDGET_H + +#include <qwidget.h> +#include <qmap.h> + +class QString; + +class Event; + +class KListView; +class KListViewItem; +class KPushButton; + +class EventLog : public QObject +{ +Q_OBJECT + +public: + EventLog(); + QPtrList<Event> events(); + +public slots: + void addEvent(const QString &description, const QString &icon = QString::null); + +signals: + void newEvent(Event *event); + +private: + QPtrList<Event> m_events; +}; + +class EventLogWidget : public QWidget +{ +Q_OBJECT + +public: + enum EventLogType { Default, Net_In, Net_Out }; + + EventLogWidget(EventLog *eventLog, QWidget *parent=0, const char *name = 0); + +public slots: + void addEvent(Event *event); + +protected: + void closeEvent(QCloseEvent *e); + +private slots: + void save(); + +private: + EventLog *m_eventLog; + KListView *m_eventList; + KPushButton *m_saveButton; +}; + +#endif diff --git a/atlantik/client/main.cpp b/atlantik/client/main.cpp new file mode 100644 index 00000000..5f0e2fc6 --- /dev/null +++ b/atlantik/client/main.cpp @@ -0,0 +1,78 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <kaboutdata.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kapplication.h> +#include <kglobal.h> + +#include "main.h" +#include "atlantik.h" + +static KCmdLineOptions options[] = +{ + { "h", 0, 0 }, + { "host <argument>", I18N_NOOP("Connect to this host"), 0 }, + { "p", 0, 0 }, + { "port <argument>", I18N_NOOP("Connect at this port"), "1234" }, + { "g", 0, 0 }, + { "game <argument>", I18N_NOOP("Join this game"), 0 }, + KCmdLineLastOption +}; + +int main(int argc, char *argv[]) +{ + KAboutData aboutData( + "atlantik", + I18N_NOOP("Atlantik"), ATLANTIK_VERSION_STRING, + I18N_NOOP("The Atlantic board game"), + KAboutData::License_GPL, + I18N_NOOP("(c) 1998-2004 Rob Kaper"), + I18N_NOOP("KDE client for playing Monopoly-like games on the monopd network."), + "http://unixcode.org/atlantik/" + ); + + aboutData.addAuthor("Rob Kaper", I18N_NOOP("main author"), "[email protected]", "http://capsi.com/"); + + // Patches and artists + aboutData.addCredit("Thiago Macieira", I18N_NOOP("KExtendedSocket support"), "[email protected]"); + aboutData.addCredit("Albert Astals Cid", I18N_NOOP("various patches"), "[email protected]"); + + aboutData.addCredit("Bart Szyszka", I18N_NOOP("application icon"), "[email protected]", "http://www.gigabee.com/"); + aboutData.addCredit("Rob Malda", I18N_NOOP("token icons"), "", "http://cmdrtaco.net/"); + aboutData.addCredit("Elhay Achiam", I18N_NOOP("icons"), "[email protected]"); + aboutData.addCredit("Carlo Caneva", I18N_NOOP("icons"), "[email protected]", "http://www.molecola.com/"); + + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions (options); + + KApplication::addCmdLineOptions(); + KApplication kapplication; + KGlobal::locale()->insertCatalogue("libkdegames"); + + if (kapplication.isRestored()) + RESTORE(Atlantik) + else + { + Atlantik *atlantik = new Atlantik; + atlantik->setMinimumSize(640, 480); + atlantik->setCaption(i18n("The Atlantic Board Game")); + atlantik->show(); + } + + return kapplication.exec(); +} diff --git a/atlantik/client/main.h b/atlantik/client/main.h new file mode 100644 index 00000000..4c2f00c6 --- /dev/null +++ b/atlantik/client/main.h @@ -0,0 +1,29 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_MAIN_H +#define ATLANTIK_MAIN_H + +#define ATLANTIK_VERSION 075 +#define ATLANTIK_VERSION_STRING "0.7.5" + +#define ATLANTIK_VERSION_MAJOR 0 +#define ATLANTIK_VERSION_MINOR 7 +#define ATLANTIK_VERSION_RELEASE 5 + +int main(int, char *[]); + +#endif diff --git a/atlantik/client/monopigator.cpp b/atlantik/client/monopigator.cpp new file mode 100644 index 00000000..83ef0d42 --- /dev/null +++ b/atlantik/client/monopigator.cpp @@ -0,0 +1,164 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qdom.h> +#include <qptrlist.h> +#include <qregexp.h> + +#include <kextendedsocket.h> + +#include "monopigator.moc" +#include "main.h" + +Monopigator::Monopigator() +{ + m_downloadData = 0; + m_job = 0; + m_timer = 0; +} + +Monopigator::~Monopigator() +{ + if (m_job) + m_job -> kill(); + delete m_downloadData; + m_downloadData=0L; +} + +void Monopigator::loadData(const KURL &url) +{ + delete m_downloadData; + m_downloadData = new QBuffer(); + m_downloadData->open(IO_WriteOnly); + m_downloadData->reset(); + + m_job = KIO::get(url, true, false); + m_job->addMetaData(QString::fromLatin1("UserAgent"), QString::fromLatin1("Atlantik/" ATLANTIK_VERSION_STRING)); + + if (!m_timer) + { + m_timer = new QTimer(this); + m_timer->start(10000, true); + } + + connect(m_job, SIGNAL(data(KIO::Job *, const QByteArray &)), SLOT(slotData(KIO::Job *, const QByteArray &))); + connect(m_job, SIGNAL(result(KIO::Job *)), SLOT(slotResult(KIO::Job *))); + connect(m_timer, SIGNAL(timeout()), SLOT(slotTimeout())); +} + +void Monopigator::slotData(KIO::Job *, const QByteArray &data) +{ + m_timer->stop(); + m_downloadData->writeBlock(data.data(), data.size()); +} + +void Monopigator::slotResult(KIO::Job *job) +{ + processData(m_downloadData->buffer(), !job->error()); + m_job = 0; +} + +void Monopigator::slotTimeout() +{ + if (m_job) + m_job -> kill(); + m_job = 0; + + emit timeout(); +} + +void Monopigator::processData(const QByteArray &data, bool okSoFar) +{ + if (okSoFar) + { + QString xmlData(data); + QDomDocument domDoc; + if (domDoc.setContent(xmlData)) + { + QDomElement eTop = domDoc.documentElement(); + if (eTop.tagName() != "monopigator") + return; + + QDomNode n = eTop.firstChild(); + while(!n.isNull()) + { + QDomElement e = n.toElement(); + if(!e.isNull()) + { + if (e.tagName() == "server") + emit monopigatorAdd(e.attributeNode(QString("ip")).value(), e.attributeNode(QString("host")).value(), e.attributeNode(QString("port")).value(), e.attributeNode(QString("version")).value(), e.attributeNode(QString("users")).value().toInt()); + } + n = n.nextSibling(); + } + emit finished(); + } + } +} + +MonopigatorEntry::MonopigatorEntry(QListView *parent, QString host, QString latency, QString version, QString users, QString port, QString ip) : QObject(), QListViewItem(parent, host, latency, version, users, port) +{ + m_isDev = ( version.find( QRegExp("(CVS|-dev)") ) != -1 ) ? true : false; + + setEnabled(false); + parent->sort(); + + if ( !ip.isEmpty() ) + host = ip; + m_latencySocket = new KExtendedSocket( host, port.toInt(), KExtendedSocket::inputBufferedSocket | KExtendedSocket::noResolve ); + connect(m_latencySocket, SIGNAL(lookupFinished(int)), this, SLOT(resolved())); + connect(m_latencySocket, SIGNAL(connectionSuccess()), this, SLOT(connected())); + m_latencySocket->startAsyncConnect(); +} + +void MonopigatorEntry::resolved() +{ + time.start(); +} + +void MonopigatorEntry::connected() +{ + setText( 1, QString::number(time.elapsed()) ); + setEnabled(true); + listView()->sort(); + delete m_latencySocket; +} + +int MonopigatorEntry::compare(QListViewItem *i, int col, bool ascending) const +{ + // Colums 1 and 3 are integers (latency and users) + if (col == 1 || col == 3) + { + int myVal = text(col).toInt(), iVal = i->text(col).toInt(); + if (myVal == iVal) + return 0; + else if (myVal > iVal) + return 1; + else + return -1; + } + return key( col, ascending ).compare( i->key( col, ascending) ); +} + +bool MonopigatorEntry::isDev() const +{ + return m_isDev; +} + +void MonopigatorEntry::showDevelopmentServers(bool show) +{ + if ( isVisible() != show ) + setVisible(show); +} diff --git a/atlantik/client/monopigator.h b/atlantik/client/monopigator.h new file mode 100644 index 00000000..1fd57b1b --- /dev/null +++ b/atlantik/client/monopigator.h @@ -0,0 +1,79 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_MONOPIGATOR_H +#define ATLANTIK_MONOPIGATOR_H + +#include <qobject.h> +#include <qbuffer.h> +#include <qlistview.h> +#include <qtimer.h> + +#include <kio/job.h> +#include <kurl.h> + +class KExtendedSocket; +class QTime; + +class Monopigator : public QObject +{ +Q_OBJECT + +public: + Monopigator(); + ~Monopigator(); + void loadData(const KURL &); + +signals: + void monopigatorAdd(QString ip, QString host, QString port, QString version, int users); + void finished(); + void timeout(); + +private slots: + void slotData(KIO::Job *, const QByteArray &); + void slotResult(KIO::Job *); + void slotTimeout(); + +private: + void processData(const QByteArray &, bool = true); + + QBuffer *m_downloadData; + QTimer *m_timer; + KIO::Job *m_job; +}; + +class MonopigatorEntry : public QObject, public QListViewItem +{ +Q_OBJECT + +public: + MonopigatorEntry(QListView *parent, QString host, QString latency, QString version, QString users, QString port, QString ip); + int compare(QListViewItem *i, int col, bool ascending) const; + bool isDev() const; + +private slots: + void resolved(); + void connected(); + void showDevelopmentServers(bool show); + +private: + KExtendedSocket *m_latencySocket; + QTime time; + QListView *m_parent; + bool m_isDev; +}; + +#endif diff --git a/atlantik/client/selectconfiguration_widget.cpp b/atlantik/client/selectconfiguration_widget.cpp new file mode 100644 index 00000000..0e7d5cdb --- /dev/null +++ b/atlantik/client/selectconfiguration_widget.cpp @@ -0,0 +1,189 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <iostream> + +#include <qcheckbox.h> +#include <qradiobutton.h> + +#include <kdebug.h> +#include <kdialog.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> + +#include <atlantic_core.h> +#include <configoption.h> +#include <game.h> +#include <player.h> + +#include "selectconfiguration_widget.moc" + +SelectConfiguration::SelectConfiguration(AtlanticCore *atlanticCore, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_atlanticCore = atlanticCore; + m_game = 0; + + m_mainLayout = new QVBoxLayout(this, KDialog::marginHint()); + Q_CHECK_PTR(m_mainLayout); + + // Game configuration. + m_configBox = new QVGroupBox(i18n("Game Configuration"), this, "configBox"); + m_mainLayout->addWidget(m_configBox); + + // Player buttons. + QHBoxLayout *playerButtons = new QHBoxLayout(m_mainLayout, KDialog::spacingHint()); + playerButtons->setMargin(0); + + playerButtons->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + // Vertical spacer. + m_mainLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + // Server buttons. + QHBoxLayout *serverButtons = new QHBoxLayout(m_mainLayout, KDialog::spacingHint()); + serverButtons->setMargin(0); + + m_backButton = new KPushButton(SmallIcon("back"), i18n("Leave Game"), this); + serverButtons->addWidget(m_backButton); + + connect(m_backButton, SIGNAL(clicked()), this, SIGNAL(leaveGame())); + + serverButtons->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + m_startButton = new KPushButton(SmallIconSet("forward"), i18n("Start Game"), this); + serverButtons->addWidget(m_startButton); + m_startButton->setEnabled(false); + + connect(m_startButton, SIGNAL(clicked()), this, SIGNAL(startGame())); + + Player *playerSelf = m_atlanticCore->playerSelf(); + playerChanged(playerSelf); + connect(playerSelf, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); + + emit statusMessage(i18n("Retrieving configuration list...")); +} + +void SelectConfiguration::initGame() +{ + emit statusMessage(i18n("Game started. Retrieving full game data...")); +} + +void SelectConfiguration::addConfigOption(ConfigOption *configOption) +{ + // FIXME: only bool types supported! + QCheckBox *checkBox = new QCheckBox(configOption->description(), m_configBox, "checkbox"); + m_configMap[(QObject *)checkBox] = configOption; + m_configBoxMap[configOption] = checkBox; + + checkBox->setChecked( configOption->value().toInt() ); + checkBox->setEnabled( configOption->edit() && m_atlanticCore->selfIsMaster() ); + checkBox->show(); + + connect(checkBox, SIGNAL(clicked()), this, SLOT(changeOption())); + connect(configOption, SIGNAL(changed(ConfigOption *)), this, SLOT(optionChanged(ConfigOption *))); +} + +void SelectConfiguration::gameOption(QString title, QString type, QString value, QString edit, QString command) +{ + // Find if option exists in GUI yet + if (QCheckBox *checkBox = dynamic_cast<QCheckBox *>(m_checkBoxMap[command])) + { + checkBox->setChecked(value.toInt()); + checkBox->setEnabled(edit.toInt()); + return; + } + + // Create option + if (type == "bool") + { + QCheckBox *checkBox = new QCheckBox(title, m_configBox, "checkbox"); + m_optionCommandMap[(QObject *)checkBox] = command; + m_checkBoxMap[command] = checkBox; + checkBox->setChecked(value.toInt()); + checkBox->setEnabled(edit.toInt()); + checkBox->show(); + + connect(checkBox, SIGNAL(clicked()), this, SLOT(optionChanged())); + } + // TODO: create options other than type=bool + + // TODO: Enable edit for master only +} + +void SelectConfiguration::changeOption() +{ + ConfigOption *configOption = m_configMap[(QObject *)QObject::sender()]; + if (configOption) + { + kdDebug() << "checked " << ((QCheckBox *)QObject::sender())->isChecked() << endl; + emit changeOption( configOption->id(), QString::number( ((QCheckBox *)QObject::sender())->isChecked() ) ); + } +} + +void SelectConfiguration::optionChanged(ConfigOption *configOption) +{ + QCheckBox *checkBox = m_configBoxMap[configOption]; + if (checkBox) + { + checkBox->setText( configOption->description() ); + checkBox->setChecked( configOption->value().toInt() ); + checkBox->setEnabled( configOption->edit() && m_atlanticCore->selfIsMaster() ); + } +} + +void SelectConfiguration::optionChanged() +{ + QString command = m_optionCommandMap[(QObject *)QObject::sender()]; + + if (QCheckBox *checkBox = m_checkBoxMap[command]) + { + command.append(QString::number(checkBox->isChecked())); + emit buttonCommand(command); + } +} + +void SelectConfiguration::slotEndUpdate() +{ + emit statusMessage(i18n("Retrieved configuration list.")); +} + +void SelectConfiguration::playerChanged(Player *player) +{ + kdDebug() << "playerChanged" << endl; + + if (player->game() != m_game) + { + kdDebug() << "playerChanged::change" << endl; + + if (m_game) + disconnect(m_game, SIGNAL(changed(Game *)), this, SLOT(gameChanged(Game *))); + + m_game = player->game(); + + if (m_game) + connect(m_game, SIGNAL(changed(Game *)), this, SLOT(gameChanged(Game *))); + } +} + +void SelectConfiguration::gameChanged(Game *game) +{ + m_startButton->setEnabled( game->master() == m_atlanticCore->playerSelf() ); + + for (QMapIterator<ConfigOption *, QCheckBox *> it = m_configBoxMap.begin() ; it != m_configBoxMap.end() ; ++it) + (*it)->setEnabled( it.key()->edit() && m_atlanticCore->selfIsMaster() ); +} diff --git a/atlantik/client/selectconfiguration_widget.h b/atlantik/client/selectconfiguration_widget.h new file mode 100644 index 00000000..033a0eb0 --- /dev/null +++ b/atlantik/client/selectconfiguration_widget.h @@ -0,0 +1,80 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_SELECTCONFIGURATION_WIDGET_H +#define ATLANTIK_SELECTCONFIGURATION_WIDGET_H + +#include <qwidget.h> +#include <qlayout.h> +#include <qvgroupbox.h> + +#include <klistview.h> +#include <kpushbutton.h> + +class QCheckBox; +class QListViewItem; + +class AtlanticCore; +class ConfigOption; +class Game; +class Player; + +class SelectConfiguration : public QWidget +{ +Q_OBJECT + +public: + SelectConfiguration(AtlanticCore *atlanticCore, QWidget *parent, const char *name=0); + + void setCanStart(const bool &canStart); + QString hostToConnect() const; + int portToConnect(); + +private slots: + void addConfigOption(ConfigOption *configOption); + void changeOption(); + void gameOption(QString title, QString type, QString value, QString edit, QString command); + void optionChanged(ConfigOption *configOption); + void optionChanged(); + void slotEndUpdate(); + void initGame(); + void playerChanged(Player *player); + void gameChanged(Game *game); + +signals: + void startGame(); + void leaveGame(); + void joinConfiguration(int configurationId); + void newConfiguration(); + void changeOption(int configId, const QString &value); + void buttonCommand(QString); + void iconSelected(const QString &); + void statusMessage(const QString &message); + +private: + QVBoxLayout *m_mainLayout; + QVGroupBox *m_configBox, *m_messageBox; + KPushButton *m_backButton, *m_startButton; + QMap <QObject *, QString> m_optionCommandMap; + QMap <QObject *, ConfigOption *> m_configMap; + QMap <ConfigOption *, QCheckBox *> m_configBoxMap; + QMap <QString, QCheckBox *> m_checkBoxMap; + QMap <Player *, QListViewItem *> m_items; + Game *m_game; + AtlanticCore *m_atlanticCore; +}; + +#endif diff --git a/atlantik/client/selectgame_widget.cpp b/atlantik/client/selectgame_widget.cpp new file mode 100644 index 00000000..85d4f886 --- /dev/null +++ b/atlantik/client/selectgame_widget.cpp @@ -0,0 +1,192 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qvgroupbox.h> +#include <qradiobutton.h> + +#include <kdebug.h> +#include <kdialog.h> +#include <klocale.h> +#include <kiconloader.h> +#include <knotifyclient.h> + +#include <atlantic_core.h> +#include <game.h> +#include <player.h> + +#include "selectgame_widget.h" + +SelectGame::SelectGame(AtlanticCore *atlanticCore, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_atlanticCore = atlanticCore; + + connect(m_atlanticCore, SIGNAL(createGUI(Game *)), this, SLOT(addGame(Game *))); + connect(m_atlanticCore, SIGNAL(removeGUI(Game *)), this, SLOT(delGame(Game *))); + + m_mainLayout = new QVBoxLayout(this, KDialog::marginHint()); + Q_CHECK_PTR(m_mainLayout); + + QVGroupBox *groupBox; + groupBox = new QVGroupBox(i18n("Create or Select monopd Game"), this, "groupBox"); + m_mainLayout->addWidget(groupBox); + + // List of games + m_gameList = new KListView(groupBox, "m_gameList"); + m_gameList->addColumn(i18n("Game")); + m_gameList->addColumn(i18n("Description")); + m_gameList->addColumn(i18n("Id")); + m_gameList->addColumn(i18n("Players")); + m_gameList->setAllColumnsShowFocus(true); +// m_mainLayout->addWidget(m_gameList); + + connect(m_gameList, SIGNAL(clicked(QListViewItem *)), this, SLOT(validateConnectButton())); + connect(m_gameList, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(connectClicked())); + connect(m_gameList, SIGNAL(rightButtonClicked(QListViewItem *, const QPoint &, int)), this, SLOT(validateConnectButton())); + connect(m_gameList, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(validateConnectButton())); + + QHBoxLayout *buttonBox = new QHBoxLayout(m_mainLayout, KDialog::spacingHint()); + + KPushButton *backButton = new KPushButton(SmallIcon("back"), i18n("Server List"), this); + buttonBox->addWidget(backButton); + + connect(backButton, SIGNAL(clicked()), this, SIGNAL(leaveServer())); + + buttonBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + m_connectButton = new KPushButton(SmallIconSet("forward"), i18n("Create Game"), this); + m_connectButton->setEnabled(false); + buttonBox->addWidget(m_connectButton); + + connect(m_connectButton, SIGNAL(clicked()), this, SLOT(connectClicked())); + +} + +void SelectGame::addGame(Game *game) +{ + connect(game, SIGNAL(changed(Game *)), this, SLOT(updateGame(Game *))); + + if (game->id() == -1) + { + QListViewItem *item = new QListViewItem( m_gameList, i18n("Create a new %1 Game").arg(game->name()), game->description(), QString::null, QString::null, game->type() ); + item->setPixmap(0, QPixmap(SmallIcon("filenew"))); + } + else + { + Player *master = game->master(); + QListViewItem *item = new QListViewItem( m_gameList, i18n("Join %1's %2 Game").arg( (master ? master->name() : QString::null), game->name() ), game->description(), QString::number(game->id()), QString::number(game->players()), game->type() ); + item->setPixmap( 0, QPixmap(SmallIcon("atlantik")) ); + item->setEnabled(game->canBeJoined()); + + KNotifyClient::event(winId(), "newgame"); + + connect(master, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); + } + +// validateConnectButton(); +} + +void SelectGame::delGame(Game *game) +{ + QListViewItem *item = findItem(game); + if (!item) + return; + + delete item; + + validateConnectButton(); +} + +void SelectGame::updateGame(Game *game) +{ + QListViewItem *item = findItem(game); + if (!item) + return; + + item->setText( 1, game->description() ); + + if (game->id() == -1) + item->setText(0, i18n("Create a new %1 Game").arg(game->name())); + else + { + Player *master = game->master(); + item->setText( 0, i18n("Join %1's %2 Game").arg( (master ? master->name() : QString::null), game->name() ) ); + item->setText( 3, QString::number( game->players() ) ); + item->setEnabled( game->canBeJoined() ); + + connect(master, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); + } + m_gameList->triggerUpdate(); + + validateConnectButton(); +} + +void SelectGame::playerChanged(Player *player) +{ + QListViewItem *item = m_gameList->firstChild(); + Game *game = 0; + + while (item) + { + game = m_atlanticCore->findGame( item->text(2).toInt() ); + if ( game && game->master() == player ) + { + item->setText( 0, i18n("Join %1's %2 Game").arg( player->name(), game->name() ) ); + return; + } + item = item->nextSibling(); + } +} + +QListViewItem *SelectGame::findItem(Game *game) +{ + QListViewItem *item = m_gameList->firstChild(); + while (item) + { + if ( (game->id() == -1 || item->text(2) == QString::number(game->id())) && item->text(4) == game->type() ) + return item; + + item = item->nextSibling(); + } + return 0; +} + +void SelectGame::validateConnectButton() +{ + if (QListViewItem *item = m_gameList->selectedItem()) + { + if (item->text(2).toInt() > 0) + m_connectButton->setText(i18n("Join Game")); + else + m_connectButton->setText(i18n("Create Game")); + + m_connectButton->setEnabled(true); + } + else + m_connectButton->setEnabled(false); +} + +void SelectGame::connectClicked() +{ + if (QListViewItem *item = m_gameList->selectedItem()) + { + if (int gameId = item->text(2).toInt()) + emit joinGame(gameId); + else + emit newGame(item->text(4)); + } +} + +#include "selectgame_widget.moc" diff --git a/atlantik/client/selectgame_widget.h b/atlantik/client/selectgame_widget.h new file mode 100644 index 00000000..d47e905e --- /dev/null +++ b/atlantik/client/selectgame_widget.h @@ -0,0 +1,65 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_SELECTGAME_WIDGET_H +#define ATLANTIK_SELECTGAME_WIDGET_H + +#include <qwidget.h> +#include <qlayout.h> + +#include <klistview.h> +#include <kpushbutton.h> + +class AtlanticCore; +class Game; +class Player; + +class SelectGame : public QWidget +{ +Q_OBJECT + +public: + SelectGame(AtlanticCore *atlanticCore, QWidget *parent, const char *name=0); + + void initPage(); + bool validateNext(); + QString hostToConnect() const; + int portToConnect(); + +private slots: + void connectClicked(); + void addGame(Game *game); + void delGame(Game *game); + void updateGame(Game *game); + void playerChanged(Player *player); + void validateConnectButton(); + +signals: + void joinGame(int gameId); + void newGame(const QString &gameType); + void leaveServer(); + void msgStatus(const QString &status); + +private: + QListViewItem *findItem(Game *game); + + AtlanticCore *m_atlanticCore; + QVBoxLayout *m_mainLayout; + KListView *m_gameList; + KPushButton *m_connectButton; +}; + +#endif diff --git a/atlantik/client/selectserver_widget.cpp b/atlantik/client/selectserver_widget.cpp new file mode 100644 index 00000000..39c07b50 --- /dev/null +++ b/atlantik/client/selectserver_widget.cpp @@ -0,0 +1,178 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qlabel.h> +#include <qlayout.h> +#include <qradiobutton.h> +#include <qsizepolicy.h> +#include <qvbuttongroup.h> +#include <qhgroupbox.h> + +#include <kdialog.h> +#include <kextendedsocket.h> +#include <klocale.h> +#include <kiconloader.h> + +#include "selectserver_widget.moc" + +SelectServer::SelectServer(bool useMonopigatorOnStart, bool hideDevelopmentServers, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_hideDevelopmentServers = hideDevelopmentServers; + + m_mainLayout = new QVBoxLayout(this, KDialog::marginHint()); + Q_CHECK_PTR(m_mainLayout); + + // Custom server group + QHGroupBox *customGroup = new QHGroupBox(i18n("Enter Custom monopd Server"), this, "customGroup"); + m_mainLayout->addWidget(customGroup); + + QLabel *hostLabel = new QLabel(i18n("Hostname:"), customGroup); + + m_hostEdit = new KLineEdit(customGroup); + m_hostEdit->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum)); + + QLabel *portLabel = new QLabel(i18n("Port:"), customGroup); + + m_portEdit = new KLineEdit(QString::number(1234), customGroup); + m_portEdit->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum)); + + KPushButton *connectButton = new KPushButton( KGuiItem(i18n("Connect"), "network"), customGroup); + connect(connectButton, SIGNAL(clicked()), this, SLOT(customConnect())); + + // Server list group + QVButtonGroup *bgroup = new QVButtonGroup(i18n("Select monopd Server"), this, "bgroup"); + bgroup->setExclusive(true); + m_mainLayout->addWidget(bgroup); + + // List of servers + m_serverList = new KListView(bgroup, "m_serverList"); + m_serverList->addColumn(i18n("Host")); + m_serverList->addColumn(i18n("Latency")); + m_serverList->addColumn(i18n("Version")); + m_serverList->addColumn(i18n("Users")); + m_serverList->setAllColumnsShowFocus(true); + m_serverList->setSorting(1); +// m_mainLayout->addWidget(m_serverList); + + connect(m_serverList, SIGNAL(clicked(QListViewItem *)), this, SLOT(validateConnectButton())); + connect(m_serverList, SIGNAL(doubleClicked(QListViewItem *)), this, SLOT(slotConnect())); + connect(m_serverList, SIGNAL(rightButtonClicked(QListViewItem *, const QPoint &, int)), this, SLOT(validateConnectButton())); + connect(m_serverList, SIGNAL(selectionChanged(QListViewItem *)), this, SLOT(validateConnectButton())); + + QHBoxLayout *buttonBox = new QHBoxLayout(m_mainLayout, KDialog::spacingHint()); + buttonBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + // Server List / Refresh + m_refreshButton = new KPushButton( KGuiItem(useMonopigatorOnStart ? i18n("Reload Server List") : i18n("Get Server List"), useMonopigatorOnStart ? "reload" : "network"), this); + buttonBox->addWidget(m_refreshButton); + + connect(m_refreshButton, SIGNAL(clicked()), this, SLOT(slotRefresh())); + + // Connect + m_connectButton = new KPushButton(BarIconSet("forward", KIcon::SizeSmall), i18n("Connect"), this); + m_connectButton->setEnabled(false); + buttonBox->addWidget(m_connectButton); + + connect(m_connectButton, SIGNAL(clicked()), this, SLOT(slotConnect())); + + // Monopigator + m_monopigator = new Monopigator(); + + connect(m_monopigator, SIGNAL(monopigatorAdd(QString, QString, QString, QString, int)), this, SLOT(slotMonopigatorAdd(QString, QString, QString, QString, int))); + connect(m_monopigator, SIGNAL(finished()), SLOT(monopigatorFinished())); + connect(m_monopigator, SIGNAL(timeout()), SLOT(monopigatorTimeout())); +} + +SelectServer::~SelectServer() +{ + delete m_monopigator; +} + +void SelectServer::setHideDevelopmentServers(bool hideDevelopmentServers) +{ + if ( m_hideDevelopmentServers != hideDevelopmentServers ) + { + m_hideDevelopmentServers = hideDevelopmentServers; + emit showDevelopmentServers( !m_hideDevelopmentServers ); + } +} + +void SelectServer::initMonopigator() +{ + // Hardcoded, but there aren't any other Monopigator root servers at the moment + emit msgStatus(i18n("Retrieving server list...")); + + m_refreshButton->setGuiItem(KGuiItem(i18n("Reload Server List"), "reload")); + m_monopigator->loadData(KURL( "http://monopd-gator.kde.org/")); +} + +void SelectServer::slotMonopigatorAdd(QString ip, QString host, QString port, QString version, int users) +{ + MonopigatorEntry *item = new MonopigatorEntry(m_serverList, host, QString::number(9999), version, (users == -1) ? i18n("unknown") : QString::number(users), port, ip); + item->setPixmap(0, BarIcon("atlantik", KIcon::SizeSmall)); + + if ( item->isDev() ) + { + item->setVisible( !m_hideDevelopmentServers ); + connect(this, SIGNAL(showDevelopmentServers(bool)), item, SLOT(showDevelopmentServers(bool))); + } + + validateConnectButton(); +} + +void SelectServer::monopigatorFinished() +{ + emit msgStatus(i18n("Retrieved server list.")); + m_refreshButton->setEnabled(true); +} + +void SelectServer::monopigatorTimeout() +{ + emit msgStatus(i18n("Error while retrieving the server list.")); + m_refreshButton->setEnabled(true); +} + +void SelectServer::validateConnectButton() +{ + if (m_serverList->selectedItem()) + m_connectButton->setEnabled(true); + else + m_connectButton->setEnabled(false); +} + +void SelectServer::slotRefresh(bool useMonopigator) +{ + m_serverList->clear(); + validateConnectButton(); + + if (useMonopigator) + { + m_refreshButton->setEnabled(false); + initMonopigator(); + } +} + +void SelectServer::slotConnect() +{ + if (QListViewItem *item = m_serverList->selectedItem()) + emit serverConnect(item->text(0), item->text(4).toInt()); +} + +void SelectServer::customConnect() +{ + if (!m_hostEdit->text().isEmpty() && !m_portEdit->text().isEmpty()) + emit serverConnect(m_hostEdit->text(), m_portEdit->text().toInt()); +} diff --git a/atlantik/client/selectserver_widget.h b/atlantik/client/selectserver_widget.h new file mode 100644 index 00000000..c5d1b586 --- /dev/null +++ b/atlantik/client/selectserver_widget.h @@ -0,0 +1,73 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_SELECTSERVER_WIDGET_H +#define ATLANTIK_SELECTSERVER_WIDGET_H + +#include <qwidget.h> +#include <qlayout.h> +#include <qradiobutton.h> + +#include <klineedit.h> +#include <klistview.h> +#include <kpushbutton.h> + +#include "monopigator.h" + +class KExtendedSocket; + +class SelectServer : public QWidget +{ +Q_OBJECT + +public: + SelectServer(bool useMonopigatorOnStart, bool hideDevelopmentServers, QWidget *parent, const char *name=0); + virtual ~SelectServer(); + + void initPage(); + void setHideDevelopmentServers(bool hideDevelopmentServers); + bool validateNext(); + QString hostToConnect() const; + int portToConnect(); + +public slots: + void validateConnectButton(); + void slotRefresh(bool useMonopigator = true); + void slotMonopigatorAdd(QString ip, QString host, QString port, QString version, int users); + +private slots: + void slotConnect(); + void customConnect(); + void monopigatorFinished(); + void monopigatorTimeout(); + +signals: + void serverConnect(const QString host, int port); + void msgStatus(const QString &message); + void showDevelopmentServers(bool show); + +private: + void initMonopigator(); + + QVBoxLayout *m_mainLayout; + KListView *m_serverList; + KLineEdit *m_hostEdit, *m_portEdit; + KPushButton *m_addServerButton, *m_refreshButton, *m_customConnect, *m_connectButton; + Monopigator *m_monopigator; + bool m_hideDevelopmentServers; +}; + +#endif diff --git a/atlantik/eventsrc b/atlantik/eventsrc new file mode 100644 index 00000000..a6d0327c --- /dev/null +++ b/atlantik/eventsrc @@ -0,0 +1,475 @@ +[!Global!] +IconName=atlantik +Comment=Atlantik +Comment[be]=Атлантыка +Comment[bn]=আটলান্টিক +Comment[eo]=Atlantiko +Comment[hi]=अटलांटिक +Comment[lv]=Atlantija +Comment[mk]=Атлантик +Comment[ne]=एटलान्टिक +Comment[pa]=ਐਟਲਾਟਿਕ +Comment[ta]=அட்லாண்டிக் +Comment[tg]=Атлантик +Comment[wa]=Atlantike + +[gainedturn] +Name=Gained Turn +Name[ar]=ربحت دورا +Name[be]=Канец ходу +Name[bg]=Придобит ред +Name[bn]=চাল দিন +Name[bs]=Potez dobiven +Name[ca]=Et toca jugar +Name[cs]=Získán tah +Name[cy]=Cael Tro +Name[da]=Vundet tur +Name[de]=Gewonnene Runde +Name[el]=Κερδισμένη προσπάθεια +Name[eo]=Gajnita vico +Name[es]=Turno ganado +Name[et]=Omandatud käik +Name[eu]=Irabazitako txanda +Name[fa]=نوبت به دست آمده +Name[fi]=Voitettu kierros +Name[fr]=Tour gagné +Name[gl]=Quenda Gañada +Name[he]=הרווחת תור +Name[hi]=लाभ वाली बारी +Name[hr]=Dobiven potez +Name[hu]=Nyert forduló +Name[is]=Græddi leik +Name[it]=Turno guadagnato +Name[ja]=順番が回ってきました +Name[km]=បានយកវេន +Name[lt]=Gautas ėjimas +Name[lv]=Iegūts gājiens +Name[mk]=Добиен потег +Name[nb]=Ekstratur +Name[nds]=Wunnen Törn +Name[ne]=प्राप्त मौका +Name[nl]=Gewonnen ronde +Name[nn]=Ekstratur +Name[pl]=Zyskany ruch +Name[pt]=Jogada Ganha +Name[pt_BR]=Rodada vencida +Name[ru]=Конец хода +Name[se]=Liigemátki +Name[sk]=Získaní ťah +Name[sl]=Dobljena poteza +Name[sr]=Добијен потез +Name[sr@Latn]=Dobijen potez +Name[sv]=Du vann omgången +Name[ta]=திருப்பப்பட்டது +Name[tg]=Gained Чархиш +Name[tr]=Karlı Sıra +Name[uk]=Кінець ходу +Name[wa]=Djeu wangnî +Name[zh_CN]=获得一次机会 +Name[zh_TW]=增加的回合 +Comment=It is your turn now +Comment[ar]=دورك الآن +Comment[be]=Ваш ход +Comment[bg]=Придобит ред +Comment[bn]=এখন আপনার চাল +Comment[br]=Din eo bremañ +Comment[bs]=Na vas je red +Comment[ca]=És el teu torn +Comment[cs]=Jste na tahu +Comment[cy]=Eich tro chi ydy o rwan +Comment[da]=Det er din tur nu +Comment[de]=Sie sind am Zug +Comment[el]=Είναι η σειρά σας τώρα +Comment[eo]=Estas nun via vico +Comment[es]=Es su turno +Comment[et]=Sinu kord täringut veeretada +Comment[eu]=Zure txanda da +Comment[fa]=اکنون نوبت شماست +Comment[fi]=Sinun vuoro +Comment[fr]=C'est à votre tour de jeter les dés +Comment[gl]=É a súa quenda +Comment[he]=תורך עכשיו +Comment[hi]=यह अब आपकी बारी है +Comment[hr]=Vi ste na potezu +Comment[hu]=Most Ön következik +Comment[is]=Þú átt að gera +Comment[it]=Ora tocca a te +Comment[ja]=あなたの番です +Comment[km]=ឥឡូវវាជាវេនរបស់អ្នក +Comment[lt]=Dabar Jūsų ėjimas +Comment[lv]=Šis ir jūsu gājiens +Comment[mk]=Вие сте на потег +Comment[nb]=Det er din tur nå +Comment[nds]=Nu büst Du an de Reeg +Comment[ne]=अब तपाईँको पालो हो +Comment[nl]=U bent aan de beurt +Comment[nn]=Det er din tur no +Comment[pa]=ਹੁਣ ਤੁਹਾਡੀ ਵਾਰੀ ਏ +Comment[pl]=Twój ruch +Comment[pt]=É a sua vez de jogar +Comment[pt_BR]=É a sua vez de jogar agora +Comment[ro]=Este rîndul dumneavoastră +Comment[ru]=Ваша очередь +Comment[se]=Du vuorru dál +Comment[sk]=Ste na ťahu +Comment[sl]=Sedaj je vaša poteza +Comment[sr]=Сада је ваш потез +Comment[sr@Latn]=Sada je vaš potez +Comment[sv]=Det är din tur nu +Comment[ta]=இது உங்களுடைய முறை +Comment[tg]=Ҳоло навбати шумо аст +Comment[tr]=Sıra şimdi sizde +Comment[uk]=Тепер ваша черга +Comment[uz]=Endi siz yuriysiz +Comment[uz@cyrillic]=Энди сиз юрийсиз +Comment[wa]=C' est a vos asteure +Comment[zh_CN]=轮到您了 +Comment[zh_TW]=該您擲骰子了 +default_presentation=80 + +[chat] +Name=Chat +Name[ar]=دردشة +Name[be]=Размова +Name[bg]=Изпратено съобщение +Name[bn]=আড্ডা +Name[br]=Flapañ +Name[bs]=Razgovor +Name[ca]=Xat +Name[cs]=Rozhovor +Name[cy]=Sgwrs +Name[el]=Κουβέντα +Name[eo]=Babilu +Name[et]=Vestlus +Name[eu]=Berriketa +Name[fa]=گپ +Name[fi]=Keskustelu +Name[fr]=Discussion +Name[he]=צ'ט +Name[hi]=गपशप +Name[hr]=Brbljanje +Name[hu]=Csevegés +Name[is]=Spjall +Name[ja]=チャット +Name[km]=សន្ទនា +Name[lt]=Pokalbiai +Name[lv]=Čats +Name[mk]=Разговор +Name[nb]=Prat +Name[nds]=Klönen +Name[ne]=कुराकानी +Name[nl]=Gesprek +Name[nn]=Prat +Name[pa]=ਗੱਲਬਾਤ +Name[pl]=Rozmowa +Name[pt]=Conversar +Name[pt_BR]=Bate-papo +Name[ru]=Чат +Name[se]=Buillar +Name[sk]=Rozhovor +Name[sl]=Pogovor +Name[sr]=Ћаскање +Name[sr@Latn]=Ćaskanje +Name[sv]=Chatt +Name[ta]=அரட்டை +Name[tg]=Чат +Name[tr]=Muhabbet +Name[uk]=Розмова +Name[uz@cyrillic]=Чат +Name[wa]=Berdelaedje +Name[zh_CN]=聊天 +Name[zh_TW]=聊天 +Comment=A player sends a chat message +Comment[ar]=لقد أرسل لاعب رسالة دردشة +Comment[be]=Гульнёўца сказаў +Comment[bg]=Изпратено е съобщение от играч +Comment[bn]=একজন খেলোয়াড় একটি বার্তা পাঠালেন +Comment[bs]=Igrač je poslao poruku +Comment[ca]=Un jugador envia un missatge de xat +Comment[cs]=Hráč odesílá zprávu +Comment[cy]=Mae chwaraewr yn danfon neges sgwrs +Comment[da]=En spiller sender en chat-besked +Comment[de]=Ein Spieler sendet eine Chat-Nachricht +Comment[el]=Ένας παίκτης στέλνει ένα μήνυμα κουβέντας +Comment[eo]=Ludanto sendas babilmesaĝon al Vi +Comment[es]=Un jugador ha enviado un mensaje +Comment[et]=Mängija saatis vestlusteate +Comment[eu]=Jokalari batek berriketarako mezu bat bidali du +Comment[fa]=یک بازیکن یک پیام گپ را ارسال میکند +Comment[fi]=Pelaaja lähettää viestin +Comment[fr]=Un joueur envoie un message +Comment[gl]=Un xogador enviou unha mensaxe +Comment[he]=שחקן שולח הודעת צ'ט +Comment[hi]=एक खिलाड़ी ने गपशप संदेश भेजा +Comment[hr]=Igrač je poslao poruku brbljanja +Comment[hu]=Egy játékos szöveges üzenetet küld +Comment[is]=Leikmaður sendir skilaboð +Comment[it]=Un giocatore ha inviato un messaggio +Comment[ja]=プレイヤーがチャットメッセージを送信しました +Comment[km]=អ្នកលេងផ្ញើសារសន្ទនា +Comment[lt]=Žaidėjas siunčia žinutę +Comment[lv]=Spēlētājs nosūta čata ziņu +Comment[mk]=Играчот испраќа порака за разговор +Comment[nb]=En spiller har sendt en pratemelding +Comment[nds]=En Speler sendt en Klöön-Naricht +Comment[ne]=खेलाडिले कुराकानी सन्देश पठाउदछ +Comment[nl]=Een speler stuurt een bericht +Comment[nn]=Ein spelar har sendt ei pratemelding +Comment[pa]=ਇੱਕ ਖਿਡਾਰੀ ਇੱਕ ਹੀ ਸੁਨੇਹਾ ਭੇਜ ਸਕਦਾ ਹੈ +Comment[pl]=Gracz wysyła wiadomość w oknie rozmowy +Comment[pt]=Um jogador envia uma mensagem +Comment[pt_BR]=Um jogador enviou uma mensagem +Comment[ru]=Игрок сказал +Comment[se]=Speallár lea sádden buillardandieđu +Comment[sk]=Hráč poslal správu +Comment[sl]=Igralec pošilja pogovorno sporočilo +Comment[sr]=Играч је послао ћаскајућу поруку +Comment[sr@Latn]=Igrač je poslao ćaskajuću poruku +Comment[sv]=En spelare skickar ett chattmeddelande +Comment[ta]= ஒரு விளையாட்டாளர் அரட்டை செய்தியை அனுப்புகிறார் +Comment[tg]=Бозингар паёми чат фиристод +Comment[tr]=Oyuncu bir mesaj gönderdi +Comment[uk]=Гравець відсилає повідомлення +Comment[uz]=Oʻyinchi xabar joʻnatayapti +Comment[uz@cyrillic]=Ўйинчи хабар жўнатаяпти +Comment[wa]=On djouweu evoye on messaedje di berdelaedje +Comment[zh_CN]=一个玩家发送了一条聊天信息 +Comment[zh_TW]=一個玩家送出了一條聊天訊息 +default_presentation=64 + +[newplayer] +Name=New player +Name[ar]=لاعب جديد +Name[be]=Новы гульнёўца +Name[bg]=Нов играч +Name[bn]=নতুন খেলোয়াড় +Name[br]=C'hoarier nevez +Name[bs]=Novi igrač +Name[ca]=Nou jugador +Name[cs]=Nový hráč +Name[cy]=Chwaraewr Newydd +Name[da]=Ny spiller +Name[de]=Neuer Spieler +Name[el]=Νέος παίκτης +Name[eo]=Nova Ludanto +Name[es]=Nuevo jugador +Name[et]=Uus mängija +Name[eu]=Jokalari berria +Name[fa]=بازیکن جدید +Name[fi]=Uusi pelaaja +Name[fr]=Nouveau joueur +Name[ga]=Imreoir nua +Name[gl]=Novo xogador +Name[he]=שחקן חדש +Name[hi]=नया खिलाड़ी +Name[hr]=Novi igrač +Name[hu]=Új játékos +Name[is]=Nýr leikmaður +Name[it]=Nuovo giocatore +Name[ja]=新規プレイヤー +Name[km]=អ្នកលេងថ្មី +Name[lt]=Naujas žaidėjas +Name[lv]=Jauns spēlētājs +Name[mk]=Нов играч +Name[nb]=Ny spiller +Name[nds]=Nieg Speler +Name[ne]=नयाँ खेलाडी +Name[nl]=Nieuwe speler +Name[nn]=Ny spelar +Name[pa]=ਨਵਾਂ ਖਿਡਾਰੀ +Name[pl]=Nowy gracz +Name[pt]=Novo jogador +Name[pt_BR]=Novo jogador +Name[ro]=Jucător nou +Name[ru]=Новый игрок +Name[se]=Ođđa speallár +Name[sk]=Nový hráč +Name[sl]=Nov igralec +Name[sr]=Нови играч +Name[sr@Latn]=Novi igrač +Name[sv]=Ny spelare +Name[ta]=புதிய விளையாட்டு வீரர் +Name[tg]=Бозингари нав +Name[tr]=Yeni oynatıcı +Name[uk]=Новий гравець +Name[uz]=Yangi oʻyinchi +Name[uz@cyrillic]=Янги ўйинчи +Name[wa]=Novea djouweu +Name[zh_CN]=新玩家 +Name[zh_TW]=新玩家 +Comment=A new player joins the game +Comment[ar]=لقد اشترك لاعب جديد في اللعبة +Comment[be]=Новы гульнёўца далучыўся да гульні +Comment[bg]=Нов играч се присъедини към играта +Comment[bn]=একজন নতুন খেলোয়াড় খেলায় যোগ দিয়েছেন +Comment[bs]=Novi igrač se uključuje u igru +Comment[ca]=Un nou jugador s'uneix a la partida +Comment[cs]=Nový hráč se připojuje ke hře +Comment[cy]=Mae chwaraewr newydd yn ymuno â'r gêm +Comment[da]=En ny spiller går med i spillet +Comment[de]=Ein neuer Spieler ist hinzugekommen +Comment[el]=Ένας νέος παίκτης μπαίνει στο παιχνίδι +Comment[eo]=Nova ludanto ekpartoprenas +Comment[es]=Un nuevo jugador se une a la partida +Comment[et]=Mänguga liitus uus mängija +Comment[eu]=Jokalari berri batek jokoarekin bat egin du +Comment[fa]=یک بازیکن جدید به بازی میپیوندد +Comment[fi]=Uusi pelaaja liittyi peliin +Comment[fr]=Un nouveau joueur vient de se joindre à la partie +Comment[gl]=Un novo xogador entra na partida +Comment[he]=שחקן חדש מצטרף למשחק +Comment[hi]=एक नया खिलाड़ी खेल में शामिल हुआ +Comment[hr]=Igri se pridružio novi igrač +Comment[hu]=Egy új játékos csatlakozik a játékhoz +Comment[is]=Nýr leikmaður tengist leiknum +Comment[it]=C'è un nuovo giocatore in gara +Comment[ja]=新しいプレイヤーがゲームに参加しました +Comment[km]=អ្នកលេងថ្មីចូលរួមល្បែង +Comment[lt]=Prisijungia naujas žaidėjas +Comment[lv]=Jauns spēlētājs pievienojas spēlei +Comment[mk]=Нов играч се приклучува на играта +Comment[nb]=En ny spiller bilr med i spillet +Comment[nds]=En nieg Speler maakt mit +Comment[ne]=नयाँ खेलाडीले खेलमा भाग लिन्छ +Comment[nl]=Een nieuwe speler neemt deel aan het spel +Comment[nn]=Ein ny spelar vert med i spelet +Comment[pa]=ਖੇਡ ਵਿੱਚ ਨਵਾਂ ਖਿਡਾਰੀ ਆਇਆ +Comment[pl]=Nowy gracz dołączył do gry +Comment[pt]=Um novo jogador junta-se ao jogo +Comment[pt_BR]=Um novo jogador entrou no jogo +Comment[ro]=Un jucător nou se alătură jocului +Comment[ru]=Новый игрок присоединился к игре +Comment[se]=Ođđa speallár searvvai speallui +Comment[sk]=Nový hráč sa pridal k hre +Comment[sl]=Nov igralec se je pridružil igri +Comment[sr]=Нови играч се придружио игри +Comment[sr@Latn]=Novi igrač se pridružio igri +Comment[sv]=En ny spelare går med i spelet +Comment[ta]=ஒரு புதிய விளையாட்டாளர் சேருகிறார் +Comment[tg]=Бозингари нав ба бозӣ ҳамроҳ шуд +Comment[tr]=Yeni bir oyuncu oyuna girdi +Comment[uk]=Новий гравець приєднується до гри +Comment[uz]=Oʻyinga yangi oʻyinchi qoʻshilayapti +Comment[uz@cyrillic]=Ўйинга янги ўйинчи қўшилаяпти +Comment[wa]=On novea djouweu s' a raloyî å djeu +Comment[zh_CN]=一个新玩家加入了游戏 +Comment[zh_TW]=一個新玩家加入此遊戲 + +[newgame] +Name=New game +Name[ar]=لعبة جديدة +Name[be]=Новая гульня +Name[bg]=Нова игра +Name[bn]=নতুন খেলা +Name[br]=C'hoari nevez +Name[bs]=Nova igra +Name[ca]=Nova partida +Name[cs]=Nová hra +Name[cy]=Gêm Newydd +Name[da]=Nyt spil +Name[de]=Neues Spiel +Name[el]=Νέο παιχνίδι +Name[eo]=Nova Ludo +Name[es]=Partida nueva +Name[et]=Uus mäng +Name[eu]=Jokoi berria +Name[fa]=بازی جدید +Name[fi]=Uusi peli +Name[fr]=Nouveau jeu +Name[ga]=Cluiche Nua +Name[gl]=Novo xogo +Name[he]=משחק חדש +Name[hi]=नया खेल +Name[hr]=Nova igra +Name[hu]=Új játék +Name[is]=Nýr leikur +Name[it]=Nuova partita +Name[ja]=新規ゲーム +Name[km]=ល្បែងថ្មី +Name[lt]=Naujas žaidimas +Name[lv]=Jauna spēle +Name[mk]=Нова игра +Name[nb]=Nytt spill +Name[nds]=Nieg Speel +Name[ne]=नयाँ खेल +Name[nl]=Nieuw spel +Name[nn]=Nytt spel +Name[pa]=ਨਵੀਂ ਖੇਡ +Name[pl]=Nowa gra +Name[pt]=Novo jogo +Name[pt_BR]=Novo jogo +Name[ro]=Joc nou +Name[ru]=Новая игра +Name[se]=Ođđa speallu +Name[sk]=Nová hra +Name[sl]=Nova igra +Name[sr]=Нова игра +Name[sr@Latn]=Nova igra +Name[sv]=Nytt spel +Name[ta]=புதிய விளையாட்டு +Name[tg]=Бозии нав +Name[tr]=Yeni oyun +Name[uk]=Нова гра +Name[uz]=Yangi oʻyin +Name[uz@cyrillic]=Янги ўйин +Name[wa]=Novea djeu +Name[zh_CN]=新游戏 +Name[zh_TW]=新遊戲 +Comment=A new game is created +Comment[ar]=لقد انشئت لعبة جديدة +Comment[be]=Створаная новая гульня +Comment[bg]=Създадена е нова игра +Comment[bn]=একটি নতুন খেলা আরম্ভ হয়েছে +Comment[br]=Krouet eo ur c'hoari nevez +Comment[bs]=Napravljena je nova igra +Comment[ca]=Es crea una nova partida +Comment[cs]=Je vytvořena nová hra +Comment[cy]=Mae gêm newydd wedi ei greu +Comment[da]=Et nyt spil bliver oprettet +Comment[de]=Es beginnt ein neues Spiel +Comment[el]=Ένα νέο παιχνίδι δημιουργείται +Comment[eo]=Nova ludo kreiĝis +Comment[es]=Una nueva partida ha sido creada +Comment[et]=Loodi uus mäng +Comment[eu]=Joko berri bat sortu da +Comment[fa]=یک بازی جدید ایجاد میشود +Comment[fi]=Uusi peli luotiin +Comment[fr]=Une nouvelle partie vient d'être créée +Comment[gl]=Creouse unha nova partida +Comment[he]=נוצר משחק חדש +Comment[hi]=एक नया खेल बनाया गया +Comment[hr]=Pokrenuta je nova igra +Comment[hu]=Új játék jön létre +Comment[is]=Nýr leikur er búinn til +Comment[it]=Viene avviata una nuova partita +Comment[ja]=新しいゲームを作成しました +Comment[km]=ល្បែងថ្មីត្រូវបានបង្កើត +Comment[lt]=Sukuriamas naujas žaidimas +Comment[lv]=Jauna spēle ir izveidota +Comment[mk]=Создадена е нова игра +Comment[nb]=Et nytt spill startes +Comment[nds]=En nieg Speel warrt opstellt +Comment[ne]=नयाँ खेल सिर्जना गरियो +Comment[nl]=Er is een nieuw spel aangemaakt +Comment[nn]=Eit nytt spel vert starta +Comment[pa]=ਇੱਕ ਨਵੀਂ ਖੇਡ ਬਣਾਈ ਗਈ ਹੈ +Comment[pl]=Utworzenie nowej gry +Comment[pt]=Um novo jogo é criado +Comment[pt_BR]=Um novo jogo foi criado +Comment[ro]=Este creat un joc nou +Comment[ru]=Начата новая игра +Comment[se]=Ođđa speallu ráhkaduvvo +Comment[sk]=Vytvorená nová hra +Comment[sl]=Ustvarjena je bila nova igra +Comment[sr]=Направљена је нова игра +Comment[sr@Latn]=Napravljena je nova igra +Comment[sv]=Ett nytt spel har skapats +Comment[ta]=ஒரு புது விளையாட்டு உருவாக்கப்படுகிறது +Comment[tg]=Бозии нав офарида шуд +Comment[tr]=Yeni bir oyun başlatıldı +Comment[uk]=Нову гру створено +Comment[uz]=Yangi oʻyin yaratilmoqda +Comment[uz@cyrillic]=Янги ўйин яратилмоқда +Comment[wa]=On novea djeu a stî enondé +Comment[zh_CN]=创建了一个新游戏 +Comment[zh_TW]=一個新遊戲開啟完成 diff --git a/atlantik/kio_atlantik/Makefile.am b/atlantik/kio_atlantik/Makefile.am new file mode 100644 index 00000000..69279666 --- /dev/null +++ b/atlantik/kio_atlantik/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/atlantik/libatlantic $(all_includes) +METASOURCES = AUTO + +kde_module_LTLIBRARIES = kio_atlantik.la + +kio_atlantik_la_SOURCES = kio_atlantik.cpp +kio_atlantik_la_LIBADD = $(LIB_KIO) +kio_atlantik_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +noinst_HEADERS = kio_atlantik.h + +kdelnk_DATA = atlantik.protocol +kdelnkdir = $(kde_servicesdir) + +messages: + $(XGETTEXT) *.cpp -o $(podir)/kio_atlantik.pot diff --git a/atlantik/kio_atlantik/atlantik.protocol b/atlantik/kio_atlantik/atlantik.protocol new file mode 100644 index 00000000..6839c736 --- /dev/null +++ b/atlantik/kio_atlantik/atlantik.protocol @@ -0,0 +1,7 @@ +[Protocol] +exec=kio_atlantik +protocol=atlantik +input=none +output=none +reading=true +Icon=atlantik diff --git a/atlantik/kio_atlantik/kio_atlantik.cpp b/atlantik/kio_atlantik/kio_atlantik.cpp new file mode 100644 index 00000000..3707d41b --- /dev/null +++ b/atlantik/kio_atlantik/kio_atlantik.cpp @@ -0,0 +1,70 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <stdlib.h> + +#include <qtextstream.h> + +#include <kdeversion.h> +#undef KDE_3_1_FEATURES +#ifdef KDE_MAKE_VERSION +#if KDE_VERSION > KDE_MAKE_VERSION (3, 1, 0) +#define KDE_3_1_FEATURES +#endif +#endif +#include <kio/slavebase.h> +#include <kinstance.h> +#include <kprocess.h> + +#include "kio_atlantik.h" +#include "libatlantic_export.h" + +extern "C" +{ + int LIBATLANTIC_EXPORT kdemain( int, char **argv ) + { + KInstance instance( "kio_atlantik" ); + AtlantikProtocol slave(argv[2], argv[3]); + slave.dispatchLoop(); + return 0; + } +} + +void AtlantikProtocol::get( const KURL& url ) +{ + KProcess *proc = new KProcess; + *proc << "atlantik"; + +#ifdef KDE_3_1_FEATURES + QString host = url.hasHost() ? url.host() : KProcess::quote( url.queryItem("host") ); +#else + QString host = url.hasHost() ? url.host() : url.queryItem("host"); +#endif + QString port = QString::number( url.port() ? url.port() : 1234 ); + int game = url.queryItem("game").toInt(); + QString gameString = game ? QString::number( game ) : QString::null; + + if (!host.isNull() && !port.isNull()) + { + *proc << "--host" << host << "--port" << port; + if (!gameString.isNull()) + *proc << "--game" << gameString; + } + + proc->start(KProcess::DontCare); + proc->detach(); + finished(); +} diff --git a/atlantik/kio_atlantik/kio_atlantik.h b/atlantik/kio_atlantik/kio_atlantik.h new file mode 100644 index 00000000..ac794ca9 --- /dev/null +++ b/atlantik/kio_atlantik/kio_atlantik.h @@ -0,0 +1,22 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// version 2 as published by the Free Software Foundation. +// +// 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; see the file COPYING. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +class AtlantikProtocol : public KIO::SlaveBase +{ +public: + AtlantikProtocol( const QCString &pool, const QCString &app) : SlaveBase( "atlantik", pool, app ) {} + virtual void get( const KURL& url ); +}; diff --git a/atlantik/libatlantic/Makefile.am b/atlantik/libatlantic/Makefile.am new file mode 100644 index 00000000..314a0215 --- /dev/null +++ b/atlantik/libatlantic/Makefile.am @@ -0,0 +1,15 @@ +KDE_OPTIONS = qtonly + +INCLUDES = $(all_includes) +lib_LTLIBRARIES = libatlantic.la +libatlantic_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -no-undefined -version-info 3:0:2 +libatlantic_la_LIBADD = $(LIB_QT) + +libatlantic_la_SOURCES = atlantic_core.cpp auction.cpp configoption.cpp estate.cpp \ + estategroup.cpp game.cpp player.cpp trade.cpp + +libatlanticincludedir = $(includedir)/atlantic +libatlanticinclude_HEADERS = atlantic_core.h auction.h configoption.h estate.h \ + estategroup.h game.h player.h trade.h libatlantic_export.h + +METASOURCES = AUTO diff --git a/atlantik/libatlantic/atlantic_core.cpp b/atlantik/libatlantic/atlantic_core.cpp new file mode 100644 index 00000000..39e1200e --- /dev/null +++ b/atlantik/libatlantic/atlantic_core.cpp @@ -0,0 +1,369 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <iostream> + +#include "atlantic_core.h" + +#include "auction.h" +#include "configoption.h" +#include "estate.h" +#include "estategroup.h" +#include "game.h" +#include "player.h" +#include "trade.h" + +AtlanticCore::AtlanticCore(QObject *parent, const char *name) : QObject(parent, name) +{ + m_playerSelf = 0; +} + +void AtlanticCore::reset(bool deletePermanents) +{ + m_auctions.setAutoDelete(true); + m_auctions.clear(); + m_auctions.setAutoDelete(false); + m_estates.setAutoDelete(true); + m_estates.clear(); + m_estates.setAutoDelete(false); + m_estateGroups.setAutoDelete(true); + m_estateGroups.clear(); + m_estateGroups.setAutoDelete(false); + m_configOptions.setAutoDelete(true); + m_configOptions.clear(); + m_configOptions.setAutoDelete(false); + + Trade *trade = 0; + for (QPtrListIterator<Trade> it(m_trades); (trade = *it) ; ++it) + { + emit removeGUI(trade); + trade->deleteLater(); + } + m_trades.clear(); + + Player *player = 0; + for (QPtrListIterator<Player> it(m_players); (player = *it) ; ++it) + { + if (deletePermanents) + { + emit removeGUI(player); + player->deleteLater(); + } + else + { + player->setLocation(0); + player->setDestination(0); + } + } + if (deletePermanents) + { + m_players.clear(); + m_playerSelf = 0; + + Game *game = 0; + for (QPtrListIterator<Game> it(m_games); (game = *it) ; ++it) + { + emit removeGUI(game); + game->deleteLater(); + } + m_games.clear(); + } +} + +bool AtlanticCore::selfIsMaster() const +{ + return (m_playerSelf && m_playerSelf->game() && m_playerSelf->game()->master() == m_playerSelf); +} + +void AtlanticCore::setPlayerSelf(Player *player) +{ + m_playerSelf = player; +} + +Player *AtlanticCore::playerSelf() +{ + return m_playerSelf; +} + +QPtrList<Player> AtlanticCore::players() +{ + return m_players; +} + +Player *AtlanticCore::newPlayer(int playerId, const bool &playerSelf) +{ + Player *player = new Player(playerId); + m_players.append(player); + + if (playerSelf) + { + player->setIsSelf(playerSelf); + m_playerSelf = player; + } + + emit createGUI(player); + + return player; +} + +Player *AtlanticCore::findPlayer(int playerId) +{ + Player *player = 0; + for (QPtrListIterator<Player> it(m_players); (player = *it) ; ++it) + if (player->id() == playerId) + return player; + + return 0; +} + +void AtlanticCore::removePlayer(Player *player) +{ + m_players.remove(player); + emit removeGUI(player); + player->deleteLater(); +} + +QPtrList<Game> AtlanticCore::games() +{ + return m_games; +} + +Game *AtlanticCore::newGame(int gameId, const QString &type) +{ + Game *game = new Game(gameId); + m_games.append(game); + + if ( !type.isNull() ) + game->setType(type); + + emit createGUI(game); + + return game; +} + +Game *AtlanticCore::findGame(const QString &type) +{ + Game *game = 0; + for (QPtrListIterator<Game> it(m_games); (game = *it) ; ++it) + if (game->id() == -1 && game->type() == type) + return game; + + return 0; +} + +Game *AtlanticCore::findGame(int gameId) +{ + if (gameId == -1) + return 0; + + Game *game = 0; + for (QPtrListIterator<Game> it(m_games); (game = *it) ; ++it) + if (game->id() == gameId) + return game; + + return 0; +} + +Game *AtlanticCore::gameSelf() +{ + return( m_playerSelf ? m_playerSelf->game() : 0 ); +} + +void AtlanticCore::removeGame(Game *game) +{ + m_games.remove(game); + emit removeGUI(game); + game->deleteLater(); +} + +void AtlanticCore::emitGames() +{ + for (QPtrListIterator<Game> it(m_games); (*it) ; ++it) + emit createGUI( (*it) ); +} + +QPtrList<Estate> AtlanticCore::estates() +{ + return m_estates; +} + +Estate *AtlanticCore::newEstate(int estateId) +{ + Estate *estate = new Estate(estateId); + m_estates.append(estate); + return estate; +} + +Estate *AtlanticCore::findEstate(int estateId) +{ + Estate *estate = 0; + for (QPtrListIterator<Estate> it(m_estates); (estate = *it) ; ++it) + if (estate->id() == estateId) + return estate; + + return 0; +} + +Estate *AtlanticCore::estateAfter(Estate *estate) +{ + Estate *eFirst = 0, *eTmp = 0; + bool useNext = false; + for (QPtrListIterator<Estate> it(m_estates); (eTmp = *it) ; ++it) + { + if (!eFirst) + eFirst = eTmp; + if (eTmp == estate) + useNext = true; + else if (useNext) + return eTmp; + } + return eFirst; +} + +QPtrList<EstateGroup> AtlanticCore::estateGroups() +{ + return m_estateGroups; +} + +EstateGroup *AtlanticCore::newEstateGroup(int groupId) +{ + EstateGroup *estateGroup = new EstateGroup(groupId); + m_estateGroups.append(estateGroup); + return estateGroup; +} + +EstateGroup *AtlanticCore::findEstateGroup(int groupId) +{ + EstateGroup *estateGroup = 0; + for (QPtrListIterator<EstateGroup> it(m_estateGroups); (estateGroup = *it) ; ++it) + if (estateGroup->id() == groupId) + return estateGroup; + + return 0; +} + +QPtrList<Trade> AtlanticCore::trades() +{ + return m_trades; +} + +Trade *AtlanticCore::newTrade(int tradeId) +{ + Trade *trade = new Trade(tradeId); + m_trades.append(trade); + + emit createGUI(trade); + + return trade; +} + +Trade *AtlanticCore::findTrade(int tradeId) +{ + Trade *trade = 0; + for (QPtrListIterator<Trade> it(m_trades); (trade = *it) ; ++it) + if (trade->tradeId() == tradeId) + return trade; + + return 0; +} + +void AtlanticCore::removeTrade(Trade *trade) +{ + m_trades.remove(trade); + emit removeGUI(trade); + trade->deleteLater(); +} + +QPtrList<Auction> AtlanticCore::auctions() +{ + return m_auctions; +} + +Auction *AtlanticCore::newAuction(int auctionId, Estate *estate) +{ + Auction *auction = new Auction(auctionId, estate); + m_auctions.append(auction); + return auction; +} + +void AtlanticCore::delAuction(Auction *auction) +{ + m_auctions.remove(auction); + delete auction; +} + +ConfigOption *AtlanticCore::newConfigOption(int configId) +{ + ConfigOption *configOption = new ConfigOption(configId); + m_configOptions.append(configOption); + + emit createGUI(configOption); + + return configOption; +} + +void AtlanticCore::removeConfigOption(ConfigOption *configOption) +{ + m_configOptions.remove(configOption); + emit removeGUI(configOption); + configOption->deleteLater(); +} + +ConfigOption *AtlanticCore::findConfigOption(int configId) +{ + ConfigOption *configOption = 0; + for (QPtrListIterator<ConfigOption> it(m_configOptions); (configOption = *it) ; ++it) + if (configOption->id() == configId) + return configOption; + + return 0; +} + +void AtlanticCore::printDebug() +{ + Player *player = 0; + for (QPtrListIterator<Player> it(m_players); (player = *it) ; ++it) + if (player == m_playerSelf) + std::cout << "PS: " << player->name().latin1() << ", game " << QString::number(player->game() ? player->game()->id() : -1).latin1() << std::endl; + else + std::cout << " P: " << player->name().latin1() << ", game " << QString::number(player->game() ? player->game()->id() : -1).latin1() << std::endl; + + Game *game = 0; + for (QPtrListIterator<Game> it(m_games); (game = *it) ; ++it) + std::cout << " G: " << QString::number(game->id()).latin1() << ", master: " << QString::number(game->master() ? game->master()->id() : -1 ).latin1() << std::endl; + + Estate *estate = 0; + for (QPtrListIterator<Estate> it(m_estates); (estate = *it) ; ++it) + std::cout << " E: " << estate->name().latin1() << std::endl; + + EstateGroup *estateGroup = 0; + for (QPtrListIterator<EstateGroup> it(m_estateGroups); (estateGroup = *it) ; ++it) + std::cout << "EG: " << estateGroup->name().latin1() << std::endl; + + Auction *auction = 0; + for (QPtrListIterator<Auction> it(m_auctions); (auction = *it) ; ++it) + std::cout << " A: " << QString::number(auction->auctionId()).latin1() << std::endl; + + Trade *trade = 0; + for (QPtrListIterator<Trade> it(m_trades); (trade = *it) ; ++it) + std::cout << " T: " << QString::number(trade->tradeId()).latin1() << std::endl; + + ConfigOption *configOption = 0; + for (QPtrListIterator<ConfigOption> it(m_configOptions); (configOption = *it) ; ++it) + std::cout << "CO:" << QString::number(configOption->id()).latin1() << " " << configOption->name().latin1() << " " << configOption->value().latin1() << std::endl; +} + +#include "atlantic_core.moc" diff --git a/atlantik/libatlantic/atlantic_core.h b/atlantik/libatlantic/atlantic_core.h new file mode 100644 index 00000000..bca5b783 --- /dev/null +++ b/atlantik/libatlantic/atlantic_core.h @@ -0,0 +1,105 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_CORE_H +#define LIBATLANTIC_CORE_H + +#include <qobject.h> +#include <qptrlist.h> + +#include "libatlantic_export.h" + +class Player; +class ConfigOption; +class Estate; +class EstateGroup; +class Game; +class Trade; +class Auction; + +class LIBATLANTIC_EXPORT AtlanticCore : public QObject +{ +Q_OBJECT + +public: + AtlanticCore(QObject *parent, const char *name); + + void reset(bool deletePermanents = false); + + bool selfIsMaster() const; + + void setPlayerSelf(Player *player); + Player *playerSelf(); + + QPtrList<Player> players(); + Player *newPlayer(int playerId, const bool &playerSelf = false); + Player *findPlayer(int playerId); + void removePlayer(Player *player); + + QPtrList<Game> games(); + Game *newGame(int gameId, const QString &type = QString::null); + Game *findGame(const QString &type); // finds game types + Game *findGame(int gameId); // finds actual games + Game *gameSelf(); + void removeGame(Game *game); + void emitGames(); + + QPtrList<Estate> estates(); + Estate *newEstate(int estateId); + Estate *findEstate(int estateId); + Estate *estateAfter(Estate *estate); + + QPtrList<EstateGroup> estateGroups(); + EstateGroup *newEstateGroup(int groupId); + EstateGroup *findEstateGroup(int groupId); + + QPtrList<Trade> trades(); + Trade *newTrade(int tradeId); + Trade *findTrade(int tradeId); + void removeTrade(Trade *trade); + + QPtrList<Auction> auctions(); + Auction *newAuction(int auctionId, Estate *estate); + void delAuction(Auction *auction); + + ConfigOption *newConfigOption(int configId); + void removeConfigOption(ConfigOption *configOption); + ConfigOption *findConfigOption(int configId); + + void printDebug(); + +signals: + void createGUI(Player *player); + void removeGUI(Player *player); + void createGUI(Game *game); + void removeGUI(Game *game); + void createGUI(Trade *trade); + void removeGUI(Trade *trade); + void createGUI(ConfigOption *configOption); + void removeGUI(ConfigOption *configOption); + +private: + Player *m_playerSelf; + QPtrList<Player> m_players; + QPtrList<Game> m_games; + QPtrList<Estate> m_estates; + QPtrList<EstateGroup> m_estateGroups; + QPtrList<Trade> m_trades; + QPtrList<Auction> m_auctions; + QPtrList<ConfigOption> m_configOptions; +}; + +#endif diff --git a/atlantik/libatlantic/auction.cpp b/atlantik/libatlantic/auction.cpp new file mode 100644 index 00000000..70734c4e --- /dev/null +++ b/atlantik/libatlantic/auction.cpp @@ -0,0 +1,56 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include "auction.h" +#include "auction.moc" +#include "player.h" +#include "estate.h" + +Auction::Auction(int auctionId, Estate *estate) : QObject() +{ + m_auctionId = auctionId; + m_estate = estate; + m_status = 0; + m_changed = false; +} + +Auction::~Auction() +{ + emit completed(); +} + +void Auction::setStatus(int status) +{ + if (m_status != status) + { + m_status = status; + m_changed = true; + } +} + +void Auction::newBid(Player *player, int amount) +{ + emit updateBid(player, amount); +} + +void Auction::update(bool force) +{ + if (m_changed || force) + { + emit changed(); + m_changed = false; + } +} diff --git a/atlantik/libatlantic/auction.h b/atlantik/libatlantic/auction.h new file mode 100644 index 00000000..cc44cce5 --- /dev/null +++ b/atlantik/libatlantic/auction.h @@ -0,0 +1,57 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_AUCTION_H +#define LIBATLANTIC_AUCTION_H + +#include <qobject.h> + +#include "libatlantic_export.h" + +class Player; +class Estate; + +class LIBATLANTIC_EXPORT Auction : public QObject +{ +Q_OBJECT + +public: + Auction(int auctionId, Estate *estate); + virtual ~Auction(); + + int auctionId() { return m_auctionId; } + Estate *estate() { return m_estate; } + + void setStatus(int status); + int status() { return m_status; } + + void newBid(Player *player, int bid); + + void update(bool force = false); + +signals: + void changed(); + void completed(); + void bid(Auction *auction, int amount); + void updateBid(Player *player, int amount); + +private: + bool m_changed; + int m_auctionId, m_status; + Estate *m_estate; +}; + +#endif diff --git a/atlantik/libatlantic/configoption.cpp b/atlantik/libatlantic/configoption.cpp new file mode 100644 index 00000000..00a8eb12 --- /dev/null +++ b/atlantik/libatlantic/configoption.cpp @@ -0,0 +1,99 @@ +// Copyright (c) 2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include "configoption.h" + +ConfigOption::ConfigOption(int configId) : QObject() +{ + m_id = configId; + m_name = ""; + m_description = ""; + m_edit = false; + m_value = ""; + m_changed = false; +} + +int ConfigOption::id() +{ + return m_id; +} + +void ConfigOption::setName(const QString &name) +{ + if (m_name != name) + { + m_name = name; + m_changed = true; + } +} + +QString ConfigOption::name() const +{ + return m_name; +} + +void ConfigOption::setDescription(const QString &description) +{ + if (m_description != description) + { + m_description = description; + m_changed = true; + } +} + +QString ConfigOption::description() const +{ + return m_description; +} + +void ConfigOption::setEdit(bool edit) +{ + if (m_edit != edit) + { + m_edit = edit; + m_changed = true; + } +} + +bool ConfigOption::edit() +{ + return m_edit; +} + +void ConfigOption::setValue(const QString &value) +{ + if (m_value != value) + { + m_value = value; + m_changed = true; + } +} + +QString ConfigOption::value() const +{ + return m_value; +} + +void ConfigOption::update(bool force) +{ + if (m_changed || force) + { + emit changed(this); + m_changed = false; + } +} + +#include "configoption.moc" diff --git a/atlantik/libatlantic/configoption.h b/atlantik/libatlantic/configoption.h new file mode 100644 index 00000000..a29d6b45 --- /dev/null +++ b/atlantik/libatlantic/configoption.h @@ -0,0 +1,51 @@ +// Copyright (c) 2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_CONFIGOPTION_H +#define LIBATLANTIC_CONFIGOPTION_H + +#include <qobject.h> +#include <qstring.h> + +#include "libatlantic_export.h" + +class LIBATLANTIC_EXPORT ConfigOption : public QObject +{ +Q_OBJECT + +public: + ConfigOption(int configId); + int id(); + void setName(const QString &name); + QString name() const; + void setDescription(const QString &description); + QString description() const; + void setEdit(bool edit); + bool edit(); + void setValue(const QString &value); + QString value() const; + void update(bool force = false); + +signals: + void changed(ConfigOption *configOption); + +private: + int m_id; + bool m_changed, m_edit; + QString m_name, m_description, m_value; +}; + +#endif diff --git a/atlantik/libatlantic/estate.cpp b/atlantik/libatlantic/estate.cpp new file mode 100644 index 00000000..eef69280 --- /dev/null +++ b/atlantik/libatlantic/estate.cpp @@ -0,0 +1,163 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +//#include <kdebug.h> + +#include "estate.h" +#include "estate.moc" +#include "player.h" + +Estate::Estate(int estateId) : QObject() +{ + m_id = estateId; + m_name = QString::null; + m_owner = 0; + m_houses = 0; + m_price = 0; + m_money = 0; + m_estateGroup = 0; + m_changed = m_canBeOwned = m_canBuyHouses = m_canSellHouses = m_isMortgaged = m_canToggleMortgage = false; + m_bgColor = QColor(); + m_color = QColor(); +} + +void Estate::setEstateGroup(EstateGroup *estateGroup) +{ + if (m_estateGroup != estateGroup) + m_estateGroup = estateGroup; +} + +void Estate::setOwner(Player *player) +{ + if (m_owner != player) + { + m_owner = player; + m_changed = true; + } +} +bool Estate::isOwned() const +{ + if (m_owner) + return true; + else + return false; +} + +bool Estate::isOwnedBySelf() const +{ + if (m_owner && m_owner->isSelf()) + return true; + else + return false; +} + +void Estate::setHouses(unsigned int houses) +{ + if (m_houses != houses) + m_houses = houses; + m_changed = true; +} + +void Estate::setName(QString name) +{ + if (m_name != name) + { + m_name = name; + m_changed = true; + } +} + +QString Estate::name() const +{ + return m_name; +} + +void Estate::setColor(QColor color) +{ + if (m_color != color) + { + m_color = color; + m_changed = true; + } +} + +void Estate::setBgColor(QColor color) +{ + if (m_bgColor != color) + { + m_bgColor = color; + m_changed = true; + } +} + +void Estate::setCanBeOwned(const bool canBeOwned) +{ + if (m_canBeOwned != canBeOwned) + m_canBeOwned = canBeOwned; +} + +void Estate::setCanBuyHouses(const bool canBuyHouses) +{ + if (m_canBuyHouses != canBuyHouses) + m_canBuyHouses = canBuyHouses; +} + +void Estate::setCanSellHouses(const bool canSellHouses) +{ + if (m_canSellHouses != canSellHouses) + m_canSellHouses = canSellHouses; +} + +void Estate::setIsMortgaged(const bool isMortgaged) +{ + if (m_isMortgaged != isMortgaged) + { + m_isMortgaged = isMortgaged; + m_changed = true; + } +} + +void Estate::setCanToggleMortgage(const bool canToggleMortgage) +{ + if (m_canToggleMortgage != canToggleMortgage) + { + m_canToggleMortgage = canToggleMortgage; + m_changed = true; + } +} + +void Estate::setMoney(int money) +{ + if (m_money != money) + { + m_money = money; + m_changed = true; + } +} + +int Estate::money() +{ + return m_money; +} + +void Estate::update(bool force) +{ + if (m_changed || force) + { + emit changed(); + m_changed = false; + } +} diff --git a/atlantik/libatlantic/estate.h b/atlantik/libatlantic/estate.h new file mode 100644 index 00000000..b6b768a5 --- /dev/null +++ b/atlantik/libatlantic/estate.h @@ -0,0 +1,95 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_ESTATE_H +#define LIBATLANTIC_ESTATE_H + +#include <qobject.h> +#include <qcolor.h> + +#include "libatlantic_export.h" + +class EstateGroup; +class Player; + +class LIBATLANTIC_EXPORT Estate : public QObject +{ +Q_OBJECT + +public: + Estate(int estateId); + int id() { return m_id; } + void setName(QString name); + QString name() const; + void setEstateGroup(EstateGroup *estateGroup); + EstateGroup *estateGroup() { return m_estateGroup; } + void setOwner(Player *player); + bool isOwned() const; + bool isOwnedBySelf() const; + Player *owner() { return m_owner; } + void setHouses(unsigned int houses); + unsigned int houses() { return m_houses; } + void setCanBeOwned(const bool canBeOwned); + bool canBeOwned() const { return m_canBeOwned; } + void setCanBuyHouses(const bool canBuyHouses); + bool canBuyHouses() const { return m_canBuyHouses; } + void setCanSellHouses(const bool canSellHouses); + bool canSellHouses() const { return m_canSellHouses; } + void setHousePrice(const unsigned int housePrice) { m_housePrice = housePrice; } + unsigned int housePrice() const { return m_housePrice; } + void setHouseSellPrice(const unsigned int houseSellPrice) { m_houseSellPrice = houseSellPrice; } + unsigned int houseSellPrice() const { return m_houseSellPrice; } + void setIsMortgaged(const bool isMortgaged); + bool isMortgaged() const { return m_isMortgaged; } + void setCanToggleMortgage(const bool canToggleMortgage); + bool canToggleMortgage() const { return m_canToggleMortgage; } + void setMortgagePrice(const unsigned int mortgagePrice) { m_mortgagePrice = mortgagePrice; } + unsigned int mortgagePrice() const { return m_mortgagePrice; } + void setUnmortgagePrice(const unsigned int unmortgagePrice) { m_unmortgagePrice = unmortgagePrice; } + unsigned int unmortgagePrice() const { return m_unmortgagePrice; } + void setColor(QColor color); + QColor color() const { return m_color; } + void setBgColor(QColor color); + QColor bgColor() const { return m_bgColor; } + void setPrice(const unsigned int price) { m_price = price; } + unsigned int price() const { return m_price; } + void setMoney(int money); + int money(); + void update(bool force = false); + +signals: + void changed(); + void estateToggleMortgage(Estate *estate); + void estateHouseBuy(Estate *estate); + void estateHouseSell(Estate *estate); + void newTrade(Player *player); + void LMBClicked(Estate *estate); + +protected: + bool m_changed; + int m_id; + +private: + QString m_name; + Player *m_owner; + EstateGroup *m_estateGroup; + unsigned int m_houses, m_price, m_housePrice, m_houseSellPrice, m_mortgagePrice, m_unmortgagePrice; + int m_money; + bool m_canBeOwned, m_canBuyHouses, m_canSellHouses, m_isMortgaged, m_canToggleMortgage; + QColor m_bgColor, m_color; +}; + +#endif diff --git a/atlantik/libatlantic/estategroup.cpp b/atlantik/libatlantic/estategroup.cpp new file mode 100644 index 00000000..e0148afc --- /dev/null +++ b/atlantik/libatlantic/estategroup.cpp @@ -0,0 +1,41 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include "estategroup.h" +#include "estategroup.moc" + +EstateGroup::EstateGroup(const int id) : QObject() +{ + m_id = id; +} + +void EstateGroup::setName(const QString name) +{ + if (m_name != name) + { + m_name = name; + m_changed = true; + } +} + +void EstateGroup::update(bool force) +{ + if (m_changed || force) + { + emit changed(); + m_changed = false; + } +} diff --git a/atlantik/libatlantic/estategroup.h b/atlantik/libatlantic/estategroup.h new file mode 100644 index 00000000..3e08a9ce --- /dev/null +++ b/atlantik/libatlantic/estategroup.h @@ -0,0 +1,44 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_ESTATEGROUP_H +#define LIBATLANTIC_ESTATEGROUP_H + +#include <qobject.h> + +#include "libatlantic_export.h" + +class LIBATLANTIC_EXPORT EstateGroup : public QObject +{ +Q_OBJECT + +public: + EstateGroup(const int id); + int id() { return m_id; } + void setName(const QString name); + QString name() const { return m_name; } + void update(bool force = false); + +signals: + void changed(); + +private: + int m_id; + bool m_changed; + QString m_name; +}; + +#endif diff --git a/atlantik/libatlantic/game.cpp b/atlantik/libatlantic/game.cpp new file mode 100644 index 00000000..1f4eb244 --- /dev/null +++ b/atlantik/libatlantic/game.cpp @@ -0,0 +1,130 @@ +// Copyright (c) 2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qstring.h> + +#include "game.h" + +Game::Game(int gameId) : QObject() +{ + m_id = gameId; + m_description = QString::null; + m_type = QString::null; + m_players = 0; + m_master = 0; + + m_changed = false; +} + +int Game::id() const +{ + return m_id; +} + +void Game::setCanBeJoined(const bool &canBeJoined) +{ + if (m_canBeJoined != canBeJoined) + { + m_canBeJoined = canBeJoined; + m_changed = true; + } +} + +bool Game::canBeJoined() const +{ + return m_canBeJoined; +} + +void Game::setDescription(const QString &description) +{ + if (m_description != description) + { + m_description = description; + m_changed = true; + } +} + +QString Game::description() const +{ + return m_description; +} + +void Game::setName(const QString &name) +{ + if (m_name != name) + { + m_name = name; + m_changed = true; + } +} + +QString Game::name() const +{ + return m_name; +} + +void Game::setType(const QString &type) +{ + if (m_type != type) + { + m_type = type; + m_changed = true; + } +} + +QString Game::type() const +{ + return m_type; +} + +void Game::update(bool force) +{ + if (m_changed || force) + { + emit changed(this); + m_changed = false; + } +} + +int Game::players() +{ + return m_players; +} + +void Game::setPlayers(int players) +{ + if (m_players != players) + { + m_players = players; + m_changed = true; + } +} + +Player *Game::master() +{ + return m_master; +} + +void Game::setMaster(Player *master) +{ + if (m_master != master) + { + m_master = master; + m_changed = true; + } +} + +#include "game.moc" diff --git a/atlantik/libatlantic/game.h b/atlantik/libatlantic/game.h new file mode 100644 index 00000000..8eaa85f6 --- /dev/null +++ b/atlantik/libatlantic/game.h @@ -0,0 +1,62 @@ +// Copyright (c) 2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_GAME_H +#define LIBATLANTIC_GAME_H + +#include <qobject.h> + +#include "libatlantic_export.h" + +class QString; + +class Player; + +class LIBATLANTIC_EXPORT Game : public QObject +{ +Q_OBJECT + +public: + Game(int gameId); + + int id() const; + void setCanBeJoined(const bool &canBeJoined); + bool canBeJoined() const; + void setDescription(const QString &description); + QString description() const; + void setName(const QString &name); + QString name() const; + void setType(const QString &type); + QString type() const; + int players(); + void setPlayers(int players); + Player *master(); + void setMaster(Player *master); + + void update(bool force = false); + +signals: + void changed(Game *game); + +private: + bool m_changed; + bool m_canBeJoined; + QString m_description, m_name, m_type; + int m_id, m_players; + Player *m_master; +}; + +#endif diff --git a/atlantik/libatlantic/libatlantic_export.h b/atlantik/libatlantic/libatlantic_export.h new file mode 100644 index 00000000..6ea0423a --- /dev/null +++ b/atlantik/libatlantic/libatlantic_export.h @@ -0,0 +1,25 @@ +// Copyright (c) 2004 Dirk Mueller <[email protected]> + +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_EXPORT_H +#define LIBATLANTIC_EXPORT_H + +#include <kdemacros.h> + +#define LIBATLANTIC_EXPORT KDE_EXPORT + +#endif diff --git a/atlantik/libatlantic/player.cpp b/atlantik/libatlantic/player.cpp new file mode 100644 index 00000000..ab5e9268 --- /dev/null +++ b/atlantik/libatlantic/player.cpp @@ -0,0 +1,183 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include "player.h" +#include "player.moc" +#include "estate.h" + +Player::Player(int playerId) : QObject() +{ + m_id = playerId; + m_game = 0; + m_name = ""; + m_host = ""; + m_image = ""; + m_location = m_destination = 0; + m_money = 0; + m_changed = m_isSelf = false; + m_bankrupt = m_hasDebt = m_hasTurn = m_canRoll = m_canBuy = m_canAuction = m_canUseCard = m_inJail = false; +} + +void Player::setGame(Game *game) +{ + if (m_game != game) + { + m_game = game; + m_changed = true; + } +} + +Game *Player::game() +{ + return m_game; +} + +void Player::setLocation(Estate *location) +{ + if (m_location != location) + { + m_location = location; + m_changed = true; + } +} + +void Player::setDestination(Estate *destination) +{ + if (m_destination != destination) + { + m_destination = destination; + m_changed = true; + } +} + +void Player::setBankrupt(bool bankrupt) +{ + if (m_bankrupt != bankrupt) + { + m_bankrupt = bankrupt; + m_changed = true; + } +} + +void Player::setHasDebt(bool hasDebt) +{ + if (m_hasDebt != hasDebt) + { + m_hasDebt = hasDebt; + m_changed = true; + } +} + +void Player::setHasTurn(const bool hasTurn) +{ + if (m_hasTurn != hasTurn) + { + m_hasTurn = hasTurn; + m_changed = true; + if (m_hasTurn && m_isSelf) + emit gainedTurn(); + } +} + +void Player::setCanRoll(bool canRoll) +{ + if (m_canRoll != canRoll) + { + m_canRoll = canRoll; + m_changed = true; + } +} + +void Player::setCanBuy(bool canBuy) +{ + if (m_canBuy != canBuy) + { + m_canBuy = canBuy; + m_changed = true; + } +} + +void Player::setCanAuction(bool canAuction) +{ + if (m_canAuction != canAuction) + { + m_canAuction = canAuction; + m_changed = true; + } +} + +void Player::setCanUseCard(bool canUseCard) +{ + if (m_canUseCard != canUseCard) + { + m_canUseCard = canUseCard; + m_changed = true; + } +} + +void Player::setInJail(const bool inJail) +{ + if (m_inJail != inJail) + { + m_inJail = inJail; + m_changed = true; + } +} + +void Player::setName(const QString _n) +{ + if (m_name != _n) + { + m_name = _n; + m_changed = true; + } +} + +void Player::setHost(const QString &host) +{ + if (m_host != host) + { + m_host = host; + m_changed = true; + } +} + +void Player::setImage(const QString &image) +{ + if (m_image != image) + { + m_image = image; + m_changed = true; + } +} + +void Player::setMoney(unsigned int money) +{ + if (m_money != money) + { + m_money = money; + m_changed = true; + } +} + +void Player::update(bool force) +{ + if (m_changed || force) + { + emit changed(this); + m_changed = false; + } +} diff --git a/atlantik/libatlantic/player.h b/atlantik/libatlantic/player.h new file mode 100644 index 00000000..571276ef --- /dev/null +++ b/atlantik/libatlantic/player.h @@ -0,0 +1,84 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_PLAYER_H +#define LIBATLANTIC_PLAYER_H + +#include <qobject.h> +#include <qstring.h> + +#include "libatlantic_export.h" + +class Estate; +class Game; + +class LIBATLANTIC_EXPORT Player : public QObject +{ +Q_OBJECT + +public: + Player(int playerId); + + int id() { return m_id; } + void setGame(Game *game); + Game *game(); + void setLocation(Estate *location); + Estate *location() { return m_location; } + void setDestination(Estate *destination); + Estate *destination() { return m_destination; } + void setIsSelf(const bool isSelf) { m_isSelf = isSelf; } + bool isSelf() const { return m_isSelf; } + void setBankrupt(bool bankrupt); + bool isBankrupt() { return m_bankrupt; } + void setHasDebt(bool hasDebt); + bool hasDebt() { return m_hasDebt; } + void setHasTurn(const bool hasTurn); + bool hasTurn() const { return m_hasTurn; } + void setCanRoll(bool canRoll); + bool canRoll() const { return m_canRoll; } + void setCanBuy(bool canBuy); + bool canBuy() const { return m_canBuy; } + void setCanAuction(bool canAuction); + bool canAuction() const { return m_canAuction; } + void setCanUseCard(bool canUseCard); + bool canUseCard() const { return m_canUseCard; } + void setInJail(const bool inJail); + bool inJail() const { return m_inJail; } + void setName(const QString _n); + QString name() const { return m_name; } + void setHost(const QString &host); + QString host() const { return m_host; } + void setImage(const QString &image); + const QString image() const { return m_image; } + void setMoney(unsigned int _m); + unsigned int money() const { return m_money; } + void update(bool force = false); + +signals: + void changed(Player *player); + void gainedTurn(); + +private: + int m_id; + bool m_changed, m_isSelf; + bool m_bankrupt, m_hasDebt, m_hasTurn, m_canRoll, m_canBuy, m_canAuction, m_canUseCard, m_inJail; + unsigned int m_money; + QString m_name, m_host, m_image; + Game *m_game; + Estate *m_location, *m_destination; +}; + +#endif diff --git a/atlantik/libatlantic/trade.cpp b/atlantik/libatlantic/trade.cpp new file mode 100644 index 00000000..b516dc70 --- /dev/null +++ b/atlantik/libatlantic/trade.cpp @@ -0,0 +1,200 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include "trade.h" +#include "trade.moc" +#include "player.h" +#include "estate.h" + +Trade::Trade(int tradeId) +{ + m_tradeId = tradeId; + m_revision = 0; + m_changed = m_rejected = false; +} + +void Trade::setRevision(int revision) +{ + m_revision = revision; +} + +int Trade::revision() const +{ + return m_revision; +} + +void Trade::addPlayer(Player *player) +{ + m_playerAcceptMap[player] = false; +} + +void Trade::removePlayer(Player *player) +{ + m_playerAcceptMap[player] = false; +} + +unsigned int Trade::count( bool acceptOnly ) +{ + unsigned int count = 0; + for (QMapIterator<Player *, bool> it = m_playerAcceptMap.begin() ; it != m_playerAcceptMap.end() ; ++it) + if ( !acceptOnly || it.data() ) + count++; + return count; +} + +void Trade::updateEstate(Estate *estate, Player *to) +{ + TradeEstate *t=0; + + for (QPtrListIterator<TradeItem> i(mTradeItems); *i; ++i) + { + t=dynamic_cast<TradeEstate*>(*i); + + if (!t) + continue; + + if (t->estate()==estate) + break; + + t=0; + } + if (t) + { + if (to) + { + if (t->to() == to) + return; + t->setTo(to); + } + else + { + mTradeItems.removeRef(t); + emit itemRemoved(t); + t->deleteLater(); + } + } + else if (estate && to) + { + // new trade + t = new TradeEstate(estate, this, to); + + mTradeItems.append(t); + emit itemAdded(t); + } +} + +void Trade::updateMoney(unsigned int money, Player *from, Player *to) +{ + TradeMoney *t=0; + + for (QPtrListIterator<TradeItem> i(mTradeItems); *i; ++i) + { + t=dynamic_cast<TradeMoney*>(*i); + + if (!t) + continue; + + if (t->from() == from && t->to() == to && t->money()) + break; + + t=0; + } + if (t) + { + if (from && to && money) + { + if (t->money() == money) + return; + t->setMoney(money); + } + else + { + mTradeItems.removeRef(t); + emit itemRemoved(t); + t->deleteLater(); + } + } + else if (from && to && money) + { + // new trade + t = new TradeMoney(money, this, from, to); + + mTradeItems.append(t); + emit itemAdded(t); + } +} + +void Trade::updateAccept(Player *player, bool accept) +{ + if (m_playerAcceptMap[player] != accept) + { + m_playerAcceptMap[player] = accept; + m_changed = true; + } +} + +void Trade::reject(Player *player) +{ + m_rejected = true; + emit rejected(player); +} + +void Trade::update(bool force) +{ + if (m_changed || force) + { + emit changed(this); + m_changed = false; + } +} + +TradeItem::TradeItem(Trade *trade, Player *from, Player *to) : mFrom(from), mTo(to), mTrade(trade) +{ + connect(from, SIGNAL(changed(Player *)), this, SLOT(playerChanged())); + connect(to, SIGNAL(changed(Player *)), this, SLOT(playerChanged())); +} + +void TradeItem::playerChanged() +{ + emit changed(this); +} + +TradeEstate::TradeEstate(Estate *estate, Trade *trade, Player *to) : TradeItem(trade, estate->owner(), to), mEstate(estate) +{ +} + +QString TradeEstate::text() const +{ + return mEstate->name(); +} + +TradeMoney::TradeMoney(unsigned int money, Trade *trade, Player *from, Player *to) : TradeItem(trade, from, to), m_money(money) +{ +} + +void TradeMoney::setMoney(unsigned int money) +{ + if (m_money != money) + { + m_money = money; + emit changed(this); + } +} + +QString TradeMoney::text() const +{ + return QString("$%1").arg(m_money); +} diff --git a/atlantik/libatlantic/trade.h b/atlantik/libatlantic/trade.h new file mode 100644 index 00000000..5d8f3c01 --- /dev/null +++ b/atlantik/libatlantic/trade.h @@ -0,0 +1,152 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIC_TRADE_H +#define LIBATLANTIC_TRADE_H + +#include <qobject.h> +#include <qstring.h> +#include <qptrlist.h> + +#include "libatlantic_export.h" +#include "player.h" + +class Player; +class Trade; +class Estate; + +class LIBATLANTIC_EXPORT TradeItem : public QObject +{ +Q_OBJECT + +public: + TradeItem(Trade *trade, Player *from, Player *to); + virtual ~TradeItem() { } + + Player *from() { return mFrom; } + Player *to() { return mTo; } + void setTo(Player *p) { mTo=p; } + Trade *trade() { return mTrade; } + + /** + * how to visualize this + **/ + virtual QString text() const=0; + +signals: + void changed(TradeItem *); + +private slots: + void playerChanged(); + +private: + Player *mFrom, *mTo; + Trade *mTrade; +}; + +class LIBATLANTIC_EXPORT TradeEstate : public TradeItem +{ +Q_OBJECT + +public: + TradeEstate(Estate *estate, Trade *trade, Player *to); + + Estate *estate() { return mEstate; } + + virtual QString text() const; + +signals: + void updateEstate(Trade *trade, Estate *estate, Player *player); + void updateMoney(Trade *trade, unsigned int money, Player *from, Player *to); + +private: + Estate *mEstate; +}; + +class LIBATLANTIC_EXPORT TradeMoney : public TradeItem +{ +Q_OBJECT + +public: + TradeMoney(unsigned int money, Trade *trade, Player *from, Player *to); + + unsigned int money() const { return m_money; } + void setMoney(unsigned int money); + + virtual QString text() const; + +signals: + void changed(TradeItem *tradeItem); + +private: + unsigned int m_money; +}; + + +class LIBATLANTIC_EXPORT Trade : public QObject +{ +Q_OBJECT + +public: + Trade(int tradeId); + int tradeId() { return m_tradeId; } + + void setRevision(int revision); + int revision() const; + + void addPlayer(Player *player); + void removePlayer(Player *player); + + unsigned int count( bool acceptOnly ); + + bool isRejected() { return m_rejected; } + +private slots: + /** + * tell someone that this changed + **/ +// void changed(TradeItem *i) { emit itemChanged(i); } + +public: + void update(bool force = false); + void updateEstate(Estate *estate, Player *player); + void updateMoney(unsigned int money, Player *from, Player *to); + void updateAccept(Player *player, bool accept); + void reject(Player *player); + +signals: + void changed(Trade *); + void rejected(Player *player); + + void itemAdded(TradeItem *); + void itemRemoved(TradeItem *); + + void updateEstate(Trade *trade, Estate *estate, Player *to); + void updateMoney(Trade *trade, unsigned int money, Player *from, Player *to); + void reject(Trade *trade); + void accept(Trade *trade); + +private: + bool m_changed, m_rejected; + int m_tradeId, m_revision; + + QPtrList<Player> mPlayers; + QMap<Player *, bool> m_playerAcceptMap; + + QPtrList<TradeItem> mTradeItems; +}; + +#endif diff --git a/atlantik/libatlantikclient/Makefile.am b/atlantik/libatlantikclient/Makefile.am new file mode 100644 index 00000000..92c79eb2 --- /dev/null +++ b/atlantik/libatlantikclient/Makefile.am @@ -0,0 +1,10 @@ +INCLUDES = -I$(top_srcdir)/atlantik/libatlantic $(all_includes) +lib_LTLIBRARIES = libatlantikclient.la +libatlantikclient_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -no-undefined -version-info 3:0:2 +libatlantikclient_la_LIBADD = ../libatlantic/libatlantic.la $(LIB_KIO) + +libatlantikclient_la_SOURCES = atlantik_network.cpp monopdprotocol.cpp + +noinst_HEADERS = atlantik_network.h monopdprotocol.h + +METASOURCES = AUTO diff --git a/atlantik/libatlantikclient/atlantik_network.cpp b/atlantik/libatlantikclient/atlantik_network.cpp new file mode 100644 index 00000000..7b1926d3 --- /dev/null +++ b/atlantik/libatlantikclient/atlantik_network.cpp @@ -0,0 +1,928 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <iostream> + +#include <qdom.h> +#include <qtextcodec.h> +#include <qtextstream.h> +#include <qtimer.h> + +#include <kdebug.h> +#include <klocale.h> + +#include <atlantic_core.h> +#include <auction.h> +#include <configoption.h> +#include <estate.h> +#include <estategroup.h> +#include <game.h> +#include <player.h> +#include <trade.h> + +#include "atlantik_network.h" + +AtlantikNetwork::AtlantikNetwork(AtlanticCore *atlanticCore) : KExtendedSocket(0, 0, KExtendedSocket::inputBufferedSocket) +{ + m_atlanticCore = atlanticCore; + m_textStream = new QTextStream(this); + m_textStream->setCodec(QTextCodec::codecForName("utf8")); + m_playerId = -1; + m_serverVersion = ""; + + QObject::connect(this, SIGNAL(readyRead()), this, SLOT(slotRead())); + QObject::connect(this, SIGNAL(lookupFinished(int)), + this, SLOT(slotLookupFinished(int))); + QObject::connect(this, SIGNAL(connectionSuccess()), + this, SLOT(slotConnectionSuccess())); + QObject::connect(this, SIGNAL(connectionFailed(int)), + this, SLOT(slotConnectionFailed(int))); +} + +AtlantikNetwork::~AtlantikNetwork(void) +{ + delete m_textStream; +} + +void AtlantikNetwork::rollDice() +{ + writeData(".r"); +} + +void AtlantikNetwork::buyEstate() +{ + writeData(".eb"); +} + +void AtlantikNetwork::auctionEstate() +{ + writeData(".ea"); +} + +void AtlantikNetwork::startGame() +{ + writeData(".gs"); +} + +void AtlantikNetwork::reconnect(const QString &cookie) +{ + writeData(".R" + cookie); +} + +void AtlantikNetwork::leaveGame() +{ + writeData(".gx"); +} + +void AtlantikNetwork::endTurn() +{ + writeData(".E"); +} + +void AtlantikNetwork::setName(QString name) +{ + // Almost deprecated, will be replaced by libmonopdprotocol + writeData(QString(".n%1").arg(name)); +} + +void AtlantikNetwork::tokenConfirmation(Estate *estate) +{ + writeData(QString(".t%1").arg(estate ? estate->id() : -1)); +} + +void AtlantikNetwork::estateToggleMortgage(Estate *estate) +{ + writeData(QString(".em%1").arg(estate ? estate->id() : -1)); +} + +void AtlantikNetwork::estateHouseBuy(Estate *estate) +{ + writeData(QString(".hb%1").arg(estate ? estate->id() : -1)); +} + +void AtlantikNetwork::estateHouseSell(Estate *estate) +{ + writeData(QString(".hs%1").arg(estate ? estate->id() : -1)); +} + +void AtlantikNetwork::newGame(const QString &gameType) +{ + writeData(QString(".gn%1").arg(gameType)); +} + +void AtlantikNetwork::joinGame(int gameId) +{ + writeData(QString(".gj%1").arg(gameId)); +} + +void AtlantikNetwork::cmdChat(QString msg) +{ + writeData(msg); +} + +void AtlantikNetwork::newTrade(Player *player) +{ + writeData(QString(".Tn%1").arg(player ? player->id() : -1)); +} + +void AtlantikNetwork::kickPlayer(Player *player) +{ + writeData(QString(".gk%1").arg(player ? player->id() : -1)); +} + +void AtlantikNetwork::tradeUpdateEstate(Trade *trade, Estate *estate, Player *player) +{ + writeData(QString(".Te%1:%2:%3").arg(trade ? trade->tradeId() : -1).arg(estate ? estate->id() : -1).arg(player ? player->id() : -1)); +} + +void AtlantikNetwork::tradeUpdateMoney(Trade *trade, unsigned int money, Player *pFrom, Player *pTo) +{ + writeData(QString(".Tm%1:%2:%3:%4").arg(trade ? trade->tradeId() : -1).arg(pFrom ? pFrom->id() : -1).arg(pTo ? pTo->id() : -1).arg(money)); +} + +void AtlantikNetwork::tradeReject(Trade *trade) +{ + writeData(QString(".Tr%1").arg(trade ? trade->tradeId() : -1)); +} + +void AtlantikNetwork::tradeAccept(Trade *trade) +{ + writeData(QString(".Ta%1:%2").arg(trade ? trade->tradeId() : -1).arg(trade ? trade->revision() : -1)); +} + +void AtlantikNetwork::auctionBid(Auction *auction, int amount) +{ + writeData(QString(".ab%1:%2").arg(auction ? auction->auctionId() : -1).arg(amount)); +} + +void AtlantikNetwork::setImage(const QString &name) +{ + writeData(QString(".pi%1").arg(name)); +} + +void AtlantikNetwork::jailPay() +{ + writeData(".jp"); +} + +void AtlantikNetwork::jailRoll() +{ + writeData(".jr"); +} + +void AtlantikNetwork::jailCard() +{ + writeData(".jc"); +} + +void AtlantikNetwork::changeOption(int configId, const QString &value) +{ + writeData( QString(".gc%1:%2").arg(configId).arg(value) ); +} + +void AtlantikNetwork::writeData(QString msg) +{ + emit networkEvent(msg, "1rightarrow"); + msg.append("\n"); + if (socketStatus() == KExtendedSocket::connected) + *m_textStream << msg; + else + kdDebug() << "warning: socket not connected!" << endl; +} + +void AtlantikNetwork::slotRead() +{ + if ( socketStatus() != KExtendedSocket::connected ) + return; + + if (canReadLine()) + { + processMsg(m_textStream->readLine()); + // There might be more data + QTimer::singleShot(0, this, SLOT(slotRead())); + } + else + { + // Maximum message size. Messages won't get bigger than 32k anyway, so + // if we didn't receive a newline by now, we probably won't anyway. + if (bytesAvailable() > (1024 * 32)) + flush(); + } +} + +void AtlantikNetwork::processMsg(const QString &msg) +{ + emit networkEvent(msg, "1leftarrow"); + + QDomDocument dom; + dom.setContent(msg); + QDomElement e = dom.documentElement(); + if (e.tagName() != "monopd") + { + // Invalid data, request full update from server + writeData(".f"); + return; + } + QDomNode n = e.firstChild(); + processNode(n); + m_atlanticCore->printDebug(); +} + +void AtlantikNetwork::processNode(QDomNode n) +{ + QDomAttr a; + + for ( ; !n.isNull() ; n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + if(!e.isNull()) + { + if (e.tagName() == "server") + { + a = e.attributeNode( QString("version") ); + if ( !a.isNull() ) + m_serverVersion = a.value(); + + emit receivedHandshake(); + } + else if (e.tagName() == "msg") + { + a = e.attributeNode(QString("type")); + if (!a.isNull()) + { + if (a.value() == "error") + emit msgError(e.attributeNode(QString("value")).value()); + else if (a.value() == "info") + emit msgInfo(e.attributeNode(QString("value")).value()); + else if (a.value() == "chat") + emit msgChat(e.attributeNode(QString("author")).value(), e.attributeNode(QString("value")).value()); + } + } + else if (e.tagName() == "display") + { + int estateId = -1; + + a = e.attributeNode(QString("estateid")); + if (!a.isNull()) + { + estateId = a.value().toInt(); + Estate *estate; + estate = m_atlanticCore->findEstate(a.value().toInt()); + + emit displayDetails(e.attributeNode(QString("text")).value(), e.attributeNode(QString("cleartext")).value().toInt(), e.attributeNode(QString("clearbuttons")).value().toInt(), estate); + + bool hasButtons = false; + for( QDomNode nButtons = n.firstChild() ; !nButtons.isNull() ; nButtons = nButtons.nextSibling() ) + { + QDomElement eButton = nButtons.toElement(); + if (!eButton.isNull() && eButton.tagName() == "button") + { + emit addCommandButton(eButton.attributeNode(QString("command")).value(), eButton.attributeNode(QString("caption")).value(), eButton.attributeNode(QString("enabled")).value().toInt()); + hasButtons = true; + } + } + + if (!hasButtons) + emit addCloseButton(); + } + } + else if (e.tagName() == "client") + { + a = e.attributeNode(QString("playerid")); + if (!a.isNull()) + m_playerId = a.value().toInt(); + + a = e.attributeNode(QString("cookie")); + if (!a.isNull()) + emit clientCookie(a.value()); + } + else if (e.tagName() == "configupdate") + { + int configId = -1; + a = e.attributeNode(QString("configid")); + if (!a.isNull()) + { + configId = a.value().toInt(); + ConfigOption *configOption; + if (!(configOption = m_atlanticCore->findConfigOption(configId))) + configOption = m_atlanticCore->newConfigOption( configId ); + + a = e.attributeNode(QString("name")); + if (configOption && !a.isNull()) + configOption->setName(a.value()); + + a = e.attributeNode(QString("description")); + if (configOption && !a.isNull()) + configOption->setDescription(a.value()); + + a = e.attributeNode(QString("edit")); + if (configOption && !a.isNull()) + configOption->setEdit(a.value().toInt()); + + a = e.attributeNode(QString("value")); + if (configOption && !a.isNull()) + configOption->setValue(a.value()); + + if (configOption) + configOption->update(); + } + + int gameId = -1; + a = e.attributeNode(QString("gameid")); + if (!a.isNull()) + { + gameId = a.value().toInt(); + for( QDomNode nOptions = n.firstChild() ; !nOptions.isNull() ; nOptions = nOptions.nextSibling() ) + { + QDomElement eOption = nOptions.toElement(); + if (!eOption.isNull() && eOption.tagName() == "option") + emit gameOption(eOption.attributeNode(QString("title")).value(), eOption.attributeNode(QString("type")).value(), eOption.attributeNode(QString("value")).value(), eOption.attributeNode(QString("edit")).value(), eOption.attributeNode(QString("command")).value()); + } + emit endConfigUpdate(); + } + } + else if (e.tagName() == "deletegame") + { + a = e.attributeNode(QString("gameid")); + if (!a.isNull()) + { + int gameId = a.value().toInt(); + + Game *game = m_atlanticCore->findGame(gameId); + if (game) + m_atlanticCore->removeGame(game); + } + } + else if (e.tagName() == "gameupdate") + { + int gameId = -1; + + a = e.attributeNode(QString("gameid")); + if (!a.isNull()) + { + gameId = a.value().toInt(); + + Player *playerSelf = m_atlanticCore->playerSelf(); + if ( playerSelf && playerSelf->game() ) + kdDebug() << "gameupdate for " << QString::number(gameId) << " with playerSelf in game " << QString::number(playerSelf->game()->id()) << endl; + else + kdDebug() << "gameupdate for " << QString::number(gameId) << endl; + + + Game *game = 0; + if (gameId == -1) + { + a = e.attributeNode(QString("gametype")); + if ( !a.isNull() && !(game = m_atlanticCore->findGame(a.value())) ) + game = m_atlanticCore->newGame(gameId, a.value()); + } + else if (!(game = m_atlanticCore->findGame(gameId))) + game = m_atlanticCore->newGame(gameId); + + a = e.attributeNode(QString("canbejoined")); + if (game && !a.isNull()) + game->setCanBeJoined(a.value().toInt()); + + a = e.attributeNode(QString("description")); + if (game && !a.isNull()) + game->setDescription(a.value()); + + a = e.attributeNode(QString("name")); + if (game && !a.isNull()) + game->setName(a.value()); + + a = e.attributeNode(QString("players")); + if (game && !a.isNull()) + game->setPlayers(a.value().toInt()); + + a = e.attributeNode(QString("master")); + if (game && !a.isNull()) + { + // Ensure setMaster succeeds by creating player if necessary + Player *player = m_atlanticCore->findPlayer( a.value().toInt() ); + if ( !player ) + player = m_atlanticCore->newPlayer( a.value().toInt() ); + game->setMaster( player ); + } + + QString status = e.attributeNode(QString("status")).value(); + if ( m_serverVersion.left(4) == "0.9." || (playerSelf && playerSelf->game() == game) ) + { + if (status == "config") + emit gameConfig(); + else if (status == "init") + emit gameInit(); + else if (status == "run") + emit gameRun(); + else if (status == "end") + emit gameEnd(); + } + + if (game) + game->update(); + } + } + else if (e.tagName() == "deleteplayer") + { + a = e.attributeNode(QString("playerid")); + if (!a.isNull()) + { + int playerId = a.value().toInt(); + + Player *player = m_atlanticCore->findPlayer(playerId); + if (player) + m_atlanticCore->removePlayer(player); + } + } + else if (e.tagName() == "playerupdate") + { + int playerId = -1; + + a = e.attributeNode(QString("playerid")); + if (!a.isNull()) + { + playerId = a.value().toInt(); + + Player *player; + if (!(player = m_atlanticCore->findPlayer(playerId))) + player = m_atlanticCore->newPlayer( playerId, (m_playerId == playerId) ); + + // Update player name + a = e.attributeNode(QString("name")); + if (player && !a.isNull()) + player->setName(a.value()); + + // Update player game + a = e.attributeNode(QString("game")); + if (player && !a.isNull()) + { + int gameId = a.value().toInt(); + if (gameId == -1) + player->setGame( 0 ); + else + { + // Ensure setGame succeeds by creating game if necessary + Game *game = m_atlanticCore->findGame(a.value().toInt()); + if (!game) + game = m_atlanticCore->newGame(a.value().toInt()); // + player->setGame( game ); + } + } + + // Update player host + a = e.attributeNode(QString("host")); + if (player && !a.isNull()) + player->setHost(a.value()); + + // Update player image/token + a = e.attributeNode(QString("image")); + if (player && !a.isNull()) + player->setImage(a.value()); + + // Update player money + a = e.attributeNode(QString("money")); + if (player && !a.isNull()) + player->setMoney(a.value().toInt()); + + a = e.attributeNode(QString("bankrupt")); + if (player && !a.isNull()) + player->setBankrupt(a.value().toInt()); + + a = e.attributeNode(QString("hasdebt")); + if (player && !a.isNull()) + player->setHasDebt(a.value().toInt()); + + a = e.attributeNode(QString("hasturn")); + if (player && !a.isNull()) + player->setHasTurn(a.value().toInt()); + + // Update whether player can roll + a = e.attributeNode(QString("can_roll")); + if (player && !a.isNull()) + player->setCanRoll(a.value().toInt()); + + // Update whether player can buy + a = e.attributeNode(QString("can_buyestate")); + if (player && !a.isNull()) + player->setCanBuy(a.value().toInt()); + + // Update whether player can auction + a = e.attributeNode(QString("canauction")); + if (player && !a.isNull()) + player->setCanAuction(a.value().toInt()); + + // Update whether player can use a card + a = e.attributeNode(QString("canusecard")); + if (player && !a.isNull()) + player->setCanUseCard(a.value().toInt()); + + // Update whether player is jailed + a = e.attributeNode(QString("jailed")); + if (player && !a.isNull()) + { + player->setInJail(a.value().toInt()); + // TODO: emit signal with player ptr so board can setText and display something + } + + // Update player location + a = e.attributeNode(QString("location")); + if (!a.isNull()) + { + m_playerLocationMap[player] = a.value().toInt(); + + bool directMove = false; + + Estate *estate = m_atlanticCore->findEstate(a.value().toInt()); + + a = e.attributeNode(QString("directmove")); + if (!a.isNull()) + directMove = a.value().toInt(); + + if (player && estate) + { + if (directMove) + player->setLocation(estate); + else + player->setDestination(estate); + } + } + + if (player) + player->update(); + } + } + else if (e.tagName() == "estategroupupdate") + { + a = e.attributeNode(QString("groupid")); + if (!a.isNull()) + { + int groupId = a.value().toInt(); + + EstateGroup *estateGroup = 0; + bool b_newEstateGroup = false; + + if (!(estateGroup = m_atlanticCore->findEstateGroup(groupId))) + { + // Create EstateGroup object + estateGroup = m_atlanticCore->newEstateGroup(a.value().toInt()); + b_newEstateGroup = true; + } + + a = e.attributeNode(QString("name")); + if (estateGroup && !a.isNull()) + estateGroup->setName(a.value()); + + // Emit signal so GUI implementations can create view(s) + // TODO: port to atlanticcore and create view there + if (estateGroup) + { + if (b_newEstateGroup) + emit newEstateGroup(estateGroup); + estateGroup->update(); + } + } + } + else if (e.tagName() == "estateupdate") + { + int estateId = -1; + + a = e.attributeNode(QString("estateid")); + if (!a.isNull()) + { + estateId = a.value().toInt(); + + Estate *estate = 0; + bool b_newEstate = false; + + // FIXME: allow any estateId, GUI should not use it to determin its geometry + if (estateId >= 0 && estateId < 100 && !(estate = m_atlanticCore->findEstate(a.value().toInt()))) + { + // Create estate object + estate = m_atlanticCore->newEstate(estateId); + b_newEstate = true; + + QObject::connect(estate, SIGNAL(estateToggleMortgage(Estate *)), this, SLOT(estateToggleMortgage(Estate *))); + QObject::connect(estate, SIGNAL(estateHouseBuy(Estate *)), this, SLOT(estateHouseBuy(Estate *))); + QObject::connect(estate, SIGNAL(estateHouseSell(Estate *)), this, SLOT(estateHouseSell(Estate *))); + QObject::connect(estate, SIGNAL(newTrade(Player *)), this, SLOT(newTrade(Player *))); + + // Players without estate should get one + Player *player = 0; + QPtrList<Player> playerList = m_atlanticCore->players(); + for (QPtrListIterator<Player> it(playerList); (player = *it) ; ++it) + if (m_playerLocationMap[player] == estate->id()) + player->setLocation(estate); + } + + a = e.attributeNode(QString("name")); + if (estate && !a.isNull()) + estate->setName(a.value()); + + a = e.attributeNode(QString("color")); + if (estate && !a.isNull() && !a.value().isEmpty()) + estate->setColor(a.value()); + + a = e.attributeNode(QString("bgcolor")); + if (estate && !a.isNull()) + estate->setBgColor(a.value()); + + a = e.attributeNode(QString("owner")); + Player *player = m_atlanticCore->findPlayer(a.value().toInt()); + if (estate && !a.isNull()) + estate->setOwner(player); + + a = e.attributeNode(QString("houses")); + if (estate && !a.isNull()) + estate->setHouses(a.value().toInt()); + + a = e.attributeNode(QString("mortgaged")); + if (estate && !a.isNull()) + estate->setIsMortgaged(a.value().toInt()); + + a = e.attributeNode(QString("group")); + if (!a.isNull()) + { + EstateGroup *estateGroup = m_atlanticCore->findEstateGroup(a.value().toInt()); + if (estate) + estate->setEstateGroup(estateGroup); + } + + a = e.attributeNode(QString("can_toggle_mortgage")); + if (estate && !a.isNull()) + estate->setCanToggleMortgage(a.value().toInt()); + + a = e.attributeNode(QString("can_be_owned")); + if (estate && !a.isNull()) + estate->setCanBeOwned(a.value().toInt()); + + a = e.attributeNode(QString("can_buy_houses")); + if (estate && !a.isNull()) + estate->setCanBuyHouses(a.value().toInt()); + + a = e.attributeNode(QString("can_sell_houses")); + if (estate && !a.isNull()) + estate->setCanSellHouses(a.value().toInt()); + + a = e.attributeNode(QString("price")); + if (estate && !a.isNull()) + estate->setPrice(a.value().toInt()); + + a = e.attributeNode(QString("houseprice")); + if (estate && !a.isNull()) + estate->setHousePrice(a.value().toInt()); + + a = e.attributeNode(QString("sellhouseprice")); + if (estate && !a.isNull()) + estate->setHouseSellPrice(a.value().toInt()); + + a = e.attributeNode(QString("mortgageprice")); + if (estate && !a.isNull()) + estate->setMortgagePrice(a.value().toInt()); + + a = e.attributeNode(QString("unmortgageprice")); + if (estate && !a.isNull()) + estate->setUnmortgagePrice(a.value().toInt()); + + a = e.attributeNode(QString("money")); + if (estate && !a.isNull()) + estate->setMoney(a.value().toInt()); + + // Emit signal so GUI implementations can create view(s) + // TODO: port to atlanticcore and create view there + if (estate) + { + if (b_newEstate) + emit newEstate(estate); + estate->update(); + } + } + } + else if (e.tagName() == "tradeupdate") + { + a = e.attributeNode(QString("tradeid")); + if (!a.isNull()) + { + int tradeId = a.value().toInt(); + + Trade *trade = m_atlanticCore->findTrade(tradeId); + if (!trade) + { + // Create trade object + trade = m_atlanticCore->newTrade(tradeId); + + QObject::connect(trade, SIGNAL(updateEstate(Trade *, Estate *, Player *)), this, SLOT(tradeUpdateEstate(Trade *, Estate *, Player *))); + QObject::connect(trade, SIGNAL(updateMoney(Trade *, unsigned int, Player *, Player *)), this, SLOT(tradeUpdateMoney(Trade *, unsigned int, Player *, Player *))); + QObject::connect(trade, SIGNAL(reject(Trade *)), this, SLOT(tradeReject(Trade *))); + QObject::connect(trade, SIGNAL(accept(Trade *)), this, SLOT(tradeAccept(Trade *))); + } + + a = e.attributeNode(QString("revision")); + if (trade && !a.isNull()) + trade->setRevision(a.value().toInt()); + + QString type = e.attributeNode(QString("type")).value(); + if (type=="new") + { + // TODO: trade->setActor + // Player *player = m_atlanticCore->findPlayer(e.attributeNode(QString("actor")).value().toInt()); + // if (trade && player) + // trade->setActor(player); + + QDomNode n_player = n.firstChild(); + while(!n_player.isNull()) + { + QDomElement e_player = n_player.toElement(); + if (!e_player.isNull() && e_player.tagName() == "tradeplayer") + { + Player *player = m_atlanticCore->findPlayer(e_player.attributeNode(QString("playerid")).value().toInt()); + if (trade && player) + { + trade->addPlayer(player); + QObject::connect(m_atlanticCore, SIGNAL(removePlayer(Player *)), trade, SLOT(removePlayer(Player *))); + } + } + n_player = n_player.nextSibling(); + } + } + else if (type=="accepted" && trade) + emit msgTradeUpdateAccepted(trade); + else if (type=="completed" && trade) + { + m_atlanticCore->removeTrade(trade); + trade = 0; + } + else if (type=="rejected") + { + Player *player = m_atlanticCore->findPlayer(e.attributeNode(QString("actor")).value().toInt()); + if (trade) + trade->reject(player); + if ( player && player == m_atlanticCore->playerSelf() ) + { + m_atlanticCore->removeTrade(trade); + trade = 0; + } + } + else + { + // No type specified, edit is implied. + + QDomNode n_child = n.firstChild(); + while(!n_child.isNull()) + { + QDomElement e_child = n_child.toElement(); + if (!e_child.isNull()) + { + if (e_child.tagName() == "tradeplayer") + { + a = e_child.attributeNode(QString("playerid")); + if (!a.isNull()) + { + Player *player = m_atlanticCore->findPlayer(a.value().toInt()); + + a = e_child.attributeNode(QString("accept")); + if (trade && player && !a.isNull()) + trade->updateAccept(player, (bool)(a.value().toInt())); + } + } + else if (e_child.tagName() == "tradeestate") + { + a = e_child.attributeNode(QString("estateid")); + if (!a.isNull()) + { + Estate *estate = m_atlanticCore->findEstate(a.value().toInt()); + a = e_child.attributeNode(QString("targetplayer")); + if (!a.isNull()) + { + Player *player = m_atlanticCore->findPlayer(a.value().toInt()); + // Allow NULL player, it will remove the component + if (trade && estate) + trade->updateEstate(estate, player); + } + } + } + else if (e_child.tagName() == "trademoney") + { + Player *pFrom = 0, *pTo = 0; + + a = e_child.attributeNode(QString("playerfrom")); + if (!a.isNull()) + pFrom = m_atlanticCore->findPlayer(a.value().toInt()); + + a = e_child.attributeNode(QString("playerto")); + if (!a.isNull()) + pTo = m_atlanticCore->findPlayer(a.value().toInt()); + + a = e_child.attributeNode(QString("money")); + kdDebug() << "tradeupdatemoney" << (pFrom ? "1" : "0") << (pTo ? "1" : "0") << (a.isNull() ? "0" : "1") << endl; + if (trade && pFrom && pTo && !a.isNull()) + trade->updateMoney(a.value().toInt(), pFrom, pTo); + } + } + n_child = n_child.nextSibling(); + } + } + + if (trade) + trade->update(); + } + } + else if (e.tagName() == "auctionupdate") + { + a = e.attributeNode(QString("auctionid")); + if (!a.isNull()) + { + int auctionId = a.value().toInt(); + + Auction *auction; + bool b_newAuction = false; + if (!(auction = m_auctions[auctionId])) + { + // Create auction object + auction = m_atlanticCore->newAuction(auctionId, m_atlanticCore->findEstate(e.attributeNode(QString("estateid")).value().toInt())); + m_auctions[auctionId] = auction; + + QObject::connect(auction, SIGNAL(bid(Auction *, int)), this, SLOT(auctionBid(Auction *, int))); + + b_newAuction = true; + } + + a = e.attributeNode(QString("highbidder")); + if (!a.isNull()) + { + Player *player = m_atlanticCore->findPlayer(e.attributeNode(QString("highbidder")).value().toInt()); + a = e.attributeNode(QString("highbid")); + if (auction && !a.isNull()) + auction->newBid(player, a.value().toInt()); + } + + a = e.attributeNode(QString("status")); + if (auction && !a.isNull()) + { + int status = a.value().toInt(); + auction->setStatus(status); + + // TODO: find a good way to visualise "sold!" + if (status == 3) + { + m_atlanticCore->delAuction(auction); + m_auctions[auctionId] = 0; + auction = 0; + } + } + + // Emit signal so GUI implementations can create view(s) + // TODO: port to atlanticcore and create view there + if (auction) + { + if (b_newAuction) + emit newAuction(auction); + auction->update(); + } + } + } + else + kdDebug() << "ignored TAG: " << e.tagName() << endl; + } + // TODO: remove permanently? + // QDomNode node = n.firstChild(); + // processNode(node); + } +} + +void AtlantikNetwork::serverConnect(const QString host, int port) +{ + setAddress(host, port); + enableRead(true); + emit msgStatus(i18n("Connecting to %1:%2...").arg(host).arg(QString::number(port)), "connect_creating"); + startAsyncConnect(); +} + +void AtlantikNetwork::slotLookupFinished(int count) +{ + emit msgStatus(i18n("Server host name lookup finished...")); +} + +void AtlantikNetwork::slotConnectionSuccess() +{ + emit msgStatus(i18n("Connected to %1:%2.").arg(host()).arg(port()), "connect_established"); +} + +void AtlantikNetwork::slotConnectionFailed(int error) +{ + emit msgStatus(i18n("Connection failed! Error code: %1").arg(error), "connect_no"); +} + +#include "atlantik_network.moc" diff --git a/atlantik/libatlantikclient/atlantik_network.h b/atlantik/libatlantikclient/atlantik_network.h new file mode 100644 index 00000000..087a01be --- /dev/null +++ b/atlantik/libatlantikclient/atlantik_network.h @@ -0,0 +1,155 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIK_NETWORK_H +#define LIBATLANTIK_NETWORK_H + +#include <qmap.h> + +#include <kextsock.h> +#include "libatlantic_export.h" +class QDomNode; +class QTextStream; + +class AtlanticCore; + +class Player; +class Estate; +class EstateGroup; +class Trade; +class Auction; + +class LIBATLANTIC_EXPORT AtlantikNetwork : public KExtendedSocket +{ +Q_OBJECT + +public: + AtlantikNetwork(AtlanticCore *atlanticCore); + virtual ~AtlantikNetwork(void); + void setName(QString name); + void cmdChat(QString msg); + +private slots: + void writeData(QString msg); + void rollDice(); + void endTurn(); + void newGame(const QString &gameType); + void reconnect(const QString &cookie); + void startGame(); + void buyEstate(); + void auctionEstate(); + void estateToggleMortgage(Estate *estate); + void estateHouseBuy(Estate *estate); + void estateHouseSell(Estate *estate); + void jailCard(); + void jailPay(); + void jailRoll(); + void newTrade(Player *player); + void kickPlayer(Player *player); + void tokenConfirmation(Estate *); + void tradeUpdateEstate(Trade *trade, Estate *estate, Player *player); + void tradeUpdateMoney(Trade *trade, unsigned int money, Player *pFrom, Player *pTo); + void tradeReject(Trade *trade); + void tradeAccept(Trade *trade); + void auctionBid(Auction *auction, int amount); + void changeOption(int, const QString &value); + void slotLookupFinished(int count); + void slotConnectionSuccess(); + void slotConnectionFailed(int error); + +public slots: + void serverConnect(const QString host, int port); + void joinGame(int gameId); + void leaveGame(); + void slotRead(); + void setImage(const QString &name); + +signals: + /** + * A new estate was created. This signal might be replaced with one in + * the AtlanticCore class in the future, but it is here now because we + * do not want GUI implementations to create a view until the + * estateupdate message has been fully parsed. + * + * @param estate Created Estate object. + */ + void newEstate(Estate *estate); + + /** + * A new estate group was created. This signal might be replaced with + * one in the AtlanticCore class in the future, but it is here now + * because we do not want GUI implementations to create a view until the + * estategroupupdate message has been fully parsed. + * + * @param estateGroup Created EstateGroup object. + */ + void newEstateGroup(EstateGroup *estateGroup); + + void msgInfo(QString); + void msgError(QString); + void msgChat(QString, QString); + void msgStatus(const QString &data, const QString &icon = QString::null); + void networkEvent(const QString &data, const QString &icon); + + void displayDetails(QString text, bool clearText, bool clearButtons, Estate *estate = 0); + void addCommandButton(QString command, QString caption, bool enabled); + void addCloseButton(); + + void gameOption(QString title, QString type, QString value, QString edit, QString command); + void endConfigUpdate(); + + void gameConfig(); + void gameInit(); + void gameRun(); + void gameEnd(); + + /** + * The trade has been completed. Emitted after all necessary estate and + * player updates are processed. + * + * @param trade Trade + */ + void msgTradeUpdateAccepted(Trade *trade); + + /** + * One of the players rejected the trade and the trade object has been + * deleted from the server. + * + * @param trade Trade + * @param playerId Unique player identifier of rejecting player + */ + void msgTradeUpdateRejected(Trade *trade, int playerId); + + void newAuction(Auction *auction); + void auctionCompleted(Auction *auction); + void receivedHandshake(); + void clientCookie(QString cookie); + +private: + void processMsg(const QString &msg); + void processNode(QDomNode); + + AtlanticCore *m_atlanticCore; + QTextStream *m_textStream; + + int m_playerId; + QString m_serverVersion; + + QMap<Player *, int> m_playerLocationMap; + QMap<int, Auction *> m_auctions; +}; + +#endif diff --git a/atlantik/libatlantikclient/monopdprotocol.cpp b/atlantik/libatlantikclient/monopdprotocol.cpp new file mode 100644 index 00000000..5f6c401b --- /dev/null +++ b/atlantik/libatlantikclient/monopdprotocol.cpp @@ -0,0 +1,80 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qstring.h> + +/* +#include <atlantic_core.h> +#include <player.h> +#include <estate.h> +#include <estategroup.h> +#include <trade.h> +#include <auction.h> +*/ + +#include <estate.h> + +#include "monopdprotocol.h" +#include "monopdprotocol.moc" + +MonopdProtocol::MonopdProtocol() : QObject() +{ +} + +void MonopdProtocol::auctionEstate() +{ + sendData(QString::fromLatin1(".ea")); +} + +void MonopdProtocol::buyEstate() +{ + sendData(QString::fromLatin1(".eb")); +} + +void MonopdProtocol::confirmTokenLocation(Estate *estate) +{ + QString data(".t"); + data.append(QString::number(estate ? estate->id() : -1)); + sendData(data); +} + +void MonopdProtocol::endTurn() +{ + sendData(QString::fromLatin1(".E")); +} + +void MonopdProtocol::rollDice() +{ + sendData(QString::fromLatin1(".r")); +} + +void MonopdProtocol::setName(QString name) +{ + QString data(".n"); + data.append(name); + sendData(data); +} + +void MonopdProtocol::startGame() +{ + sendData(QString::fromLatin1(".gs")); +} + +void MonopdProtocol::sendData(QString) +{ + // Your reimplementation of this method should send send data over the + // network. +} diff --git a/atlantik/libatlantikclient/monopdprotocol.h b/atlantik/libatlantikclient/monopdprotocol.h new file mode 100644 index 00000000..0fc16ad8 --- /dev/null +++ b/atlantik/libatlantikclient/monopdprotocol.h @@ -0,0 +1,58 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +// WARNING: this codebase is not being used yet. Please use AtlantikNetwork +// until the protocol seperation has been completed. + +#ifndef MONOPDPROTOCOL_H_H +#define MONOPDPROTOCOL_H_H + +#include <qobject.h> + +class QString; + +/* +class AtlanticCore; + +class Player; +class EstateGroup; +class Trade; +class Auction; +*/ + +class Estate; + +class MonopdProtocol : public QObject +{ +Q_OBJECT + +public: + MonopdProtocol(); + +private slots: + void auctionEstate(); + void buyEstate(); + void confirmTokenLocation(Estate *estate); + void endTurn(); + void rollDice(); + void setName(QString name); + void startGame(); + +private: + virtual void sendData(QString data); +}; + +#endif diff --git a/atlantik/libatlantikui/Makefile.am b/atlantik/libatlantikui/Makefile.am new file mode 100644 index 00000000..2e3bbbed --- /dev/null +++ b/atlantik/libatlantikui/Makefile.am @@ -0,0 +1,15 @@ +INCLUDES = -I$(top_srcdir)/atlantik/libatlantic $(all_includes) +lib_LTLIBRARIES = libatlantikui.la +libatlantikui_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) -no-undefined -version-info 3:0:2 +libatlantikui_la_LIBADD = ../libatlantic/libatlantic.la $(LIB_KIO) + +libatlantikui_la_SOURCES = auction_widget.cpp board.cpp estatedetails.cpp \ + estateview.cpp kwrappedlistviewitem.cpp portfolioestate.cpp \ + portfolioview.cpp token.cpp trade_widget.cpp + +libatlantikuiincludedir = $(includedir)/atlantik/ui +libatlantikuiinclude_HEADERS = auction_widget.h board.h estatedetails.h \ + estateview.h kwrappedlistviewitem.h portfolioestate.h \ + portfolioview.h token.h trade_widget.h libatlantikui_export.h + +METASOURCES = AUTO diff --git a/atlantik/libatlantikui/auction_widget.cpp b/atlantik/libatlantikui/auction_widget.cpp new file mode 100644 index 00000000..e7dc7fd8 --- /dev/null +++ b/atlantik/libatlantikui/auction_widget.cpp @@ -0,0 +1,141 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qvgroupbox.h> +#include <qhbox.h> +#include <qspinbox.h> +#include <qlabel.h> + +#include <kdebug.h> + +#include <kdialog.h> +#include <kiconloader.h> +#include <klocale.h> +#include <kpushbutton.h> + +#include <atlantic_core.h> +#include <player.h> +#include <estate.h> +#include <auction.h> + +#include "auction_widget.moc" + +AuctionWidget::AuctionWidget(AtlanticCore *atlanticCore, Auction *auction, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_atlanticCore = atlanticCore; + + m_auction = auction; + connect(m_auction, SIGNAL(changed()), this, SLOT(auctionChanged())); + connect(m_auction, SIGNAL(updateBid(Player *, int)), this, SLOT(updateBid(Player *, int))); + connect(this, SIGNAL(bid(Auction *, int)), m_auction, SIGNAL(bid(Auction *, int))); + + m_mainLayout = new QVBoxLayout(this, KDialog::marginHint()); + Q_CHECK_PTR(m_mainLayout); + + // Player list + Estate *estate = auction->estate(); + m_playerGroupBox = new QVGroupBox(estate ? i18n("Auction: %1").arg(estate->name()) : i18n("Auction"), this, "groupBox"); + m_mainLayout->addWidget(m_playerGroupBox); + + m_playerList = new KListView(m_playerGroupBox); + m_playerList->addColumn(i18n("Player")); + m_playerList->addColumn(i18n("Bid")); + m_playerList->setSorting(1, false); + + KListViewItem *item; + Player *player, *pSelf = m_atlanticCore->playerSelf(); + + QPtrList<Player> playerList = m_atlanticCore->players(); + for (QPtrListIterator<Player> it(playerList); *it; ++it) + { + if ( (player = *it) && player->game() == pSelf->game() ) + { + item = new KListViewItem(m_playerList, player->name(), QString("0")); + item->setPixmap(0, QPixmap(SmallIcon("personal"))); + m_playerItems[player] = item; + + connect(player, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); + } + } + + // Bid spinbox and button + QHBox *bidBox = new QHBox(this); + m_mainLayout->addWidget(bidBox); + + m_bidSpinBox = new QSpinBox(1, 10000, 1, bidBox); + + KPushButton *bidButton = new KPushButton(i18n("Make Bid"), bidBox, "bidButton"); + connect(bidButton, SIGNAL(clicked()), this, SLOT(slotBidButtonClicked())); + + // Status label + m_statusLabel = new QLabel(this, "statusLabel"); + m_mainLayout->addWidget(m_statusLabel); +} + +void AuctionWidget::auctionChanged() +{ + QString status; + switch (m_auction->status()) + { + case 1: + status = i18n("Going once..."); + break; + + case 2: + status = i18n("Going twice..."); + break; + + case 3: + status = i18n("Sold!"); + break; + + default: + status = QString::null; + } + m_statusLabel->setText(status); +} + +void AuctionWidget::playerChanged(Player *player) +{ + if (!player) + return; + + QListViewItem *item; + if (!(item = m_playerItems[player])) + return; + + item->setText(0, player->name()); + m_playerList->triggerUpdate(); +} + +void AuctionWidget::updateBid(Player *player, int amount) +{ + if (!player) + return; + + QListViewItem *item; + if (!(item = m_playerItems[player])) + return; + + item->setText(1, QString::number(amount)); + m_bidSpinBox->setMinValue(amount+1); + m_playerList->triggerUpdate(); +} + +void AuctionWidget::slotBidButtonClicked() +{ + emit bid(m_auction, m_bidSpinBox->value()); +} diff --git a/atlantik/libatlantikui/auction_widget.h b/atlantik/libatlantikui/auction_widget.h new file mode 100644 index 00000000..a87b8fc4 --- /dev/null +++ b/atlantik/libatlantikui/auction_widget.h @@ -0,0 +1,65 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_AUCTION_WIDGET_H +#define ATLANTIK_AUCTION_WIDGET_H + +#include <qwidget.h> +#include <qlayout.h> +#include <qmap.h> + +#include <klistview.h> + +class QVGroupBox; +class QSpinBox; +class QLabel; + +class KListViewItem; + +class AtlanticCore; +class Player; +class Auction; + +class AuctionWidget : public QWidget +{ +Q_OBJECT + +public: + AuctionWidget(AtlanticCore *atlanticCore, Auction *auction, QWidget *parent, const char *name=0); + +private slots: + void auctionChanged(); + void playerChanged(Player *player); + void updateBid(Player *player, int amount); + void slotBidButtonClicked(); + +signals: + void bid(Auction *auction, int amount); + +private: + QVBoxLayout *m_mainLayout; + QVGroupBox *m_playerGroupBox; + QSpinBox *m_bidSpinBox; + QMap<Player *, KListViewItem *> m_playerItems; + QLabel *m_statusLabel; + + KListView *m_playerList; + + AtlanticCore *m_atlanticCore; + Auction *m_auction; +}; + +#endif diff --git a/atlantik/libatlantikui/board.cpp b/atlantik/libatlantikui/board.cpp new file mode 100644 index 00000000..a4fdf3ce --- /dev/null +++ b/atlantik/libatlantikui/board.cpp @@ -0,0 +1,601 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <iostream> + +#include <qpainter.h> +#include <qstring.h> + +#include <kdebug.h> +#include <klocale.h> + +#include <atlantic_core.h> +#include <player.h> +#include <estate.h> +#include <auction.h> + +#include "auction_widget.h" +#include "estatedetails.h" +#include "estateview.h" +#include "token.h" + +#include "board.h" +#include "board.moc" + +AtlantikBoard::AtlantikBoard(AtlanticCore *atlanticCore, int maxEstates, DisplayMode mode, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_atlanticCore = atlanticCore; + m_maxEstates = maxEstates; + m_mode = mode; + m_animateTokens = false; + m_lastServerDisplay = 0; + + setMinimumSize(QSize(500, 500)); + + int sideLen = maxEstates/4; + + // Animated token movement + m_movingToken = 0; + m_timer = new QTimer(this); + connect(m_timer, SIGNAL(timeout()), this, SLOT(slotMoveToken())); + m_resumeTimer = false; + + m_gridLayout = new QGridLayout(this, sideLen+1, sideLen+1); + for(int i=0;i<=sideLen;i++) + { + if (i==0 || i==sideLen) + { + m_gridLayout->setRowStretch(i, 3); + m_gridLayout->setColStretch(i, 3); + } + else + { + m_gridLayout->setRowStretch(i, 2); + m_gridLayout->setColStretch(i, 2); + } + } + +// spacer = new QWidget(this); +// m_gridLayout->addWidget(spacer, sideLen, sideLen); // SE + + m_displayQueue.setAutoDelete(true); + m_estateViews.setAutoDelete(true); + m_tokens.setAutoDelete(true); + + displayDefault(); +} + +AtlantikBoard::~AtlantikBoard() +{ + reset(); +} + +void AtlantikBoard::reset() +{ + kdDebug() << "AtlantikBoard::reset" << endl; + + m_tokens.clear(); + m_estateViews.clear(); + m_displayQueue.clear(); + m_lastServerDisplay = 0; + m_movingToken = 0; +} + +void AtlantikBoard::setViewProperties(bool indicateUnowned, bool highliteUnowned, bool darkenMortgaged, bool quartzEffects, bool animateTokens) +{ + if (m_animateTokens != animateTokens) + m_animateTokens = animateTokens; + + // Update EstateViews + EstateView *estateView; + for (QPtrListIterator<EstateView> it(m_estateViews); *it; ++it) + if ((estateView = dynamic_cast<EstateView*>(*it))) + estateView->setViewProperties(indicateUnowned, highliteUnowned, darkenMortgaged, quartzEffects); +} + +int AtlantikBoard::heightForWidth(int width) +{ + return width; +} + +EstateView *AtlantikBoard::findEstateView(Estate *estate) +{ + EstateView *estateView; + for (QPtrListIterator<EstateView> i(m_estateViews); *i; ++i) + { + estateView = dynamic_cast<EstateView*>(*i); + if (estateView && estateView->estate() == estate) + return estateView; + } + return 0; +} + +void AtlantikBoard::addEstateView(Estate *estate, bool indicateUnowned, bool highliteUnowned, bool darkenMortgaged, bool quartzEffects) +{ + QString icon = QString(); + int estateId = estate->id(); + EstateOrientation orientation = North; + int sideLen = m_gridLayout->numRows() - 1; + + if (estateId < sideLen) + orientation = North; + else if (estateId < 2*sideLen) + orientation = East; + else if (estateId < 3*sideLen) + orientation = South; + else //if (estateId < 4*sideLen) + orientation = West; + + EstateView *estateView = new EstateView(estate, orientation, icon, indicateUnowned, highliteUnowned, darkenMortgaged, quartzEffects, this, "estateview"); + m_estateViews.append(estateView); + + connect(estate, SIGNAL(changed()), estateView, SLOT(estateChanged())); + connect(estateView, SIGNAL(estateToggleMortgage(Estate *)), estate, SIGNAL(estateToggleMortgage(Estate *))); + connect(estateView, SIGNAL(LMBClicked(Estate *)), estate, SIGNAL(LMBClicked(Estate *))); + connect(estateView, SIGNAL(estateHouseBuy(Estate *)), estate, SIGNAL(estateHouseBuy(Estate *))); + connect(estateView, SIGNAL(estateHouseSell(Estate *)), estate, SIGNAL(estateHouseSell(Estate *))); + connect(estateView, SIGNAL(newTrade(Player *)), estate, SIGNAL(newTrade(Player *))); + + // Designer has its own LMBClicked slot + if (m_mode == Play) + connect(estateView, SIGNAL(LMBClicked(Estate *)), this, SLOT(prependEstateDetails(Estate *))); + + if (estateId<sideLen) + m_gridLayout->addWidget(estateView, sideLen, sideLen-estateId); + else if (estateId<2*sideLen) + m_gridLayout->addWidget(estateView, 2*sideLen-estateId, 0); + else if (estateId<3*sideLen) + m_gridLayout->addWidget(estateView, 0, estateId-2*sideLen); + else + m_gridLayout->addWidget(estateView, estateId-3*sideLen, sideLen); + + estateView->show(); + + if (m_atlanticCore) + { + Player *player = 0; + QPtrList<Player> playerList = m_atlanticCore->players(); + for (QPtrListIterator<Player> it(playerList); (player = *it) ; ++it) + if (player->location() == estate) + addToken(player); + } +} + +void AtlantikBoard::addAuctionWidget(Auction *auction) +{ + AuctionWidget *auctionW = new AuctionWidget(m_atlanticCore, auction, this); + m_lastServerDisplay = auctionW; + m_displayQueue.prepend(auctionW); + updateCenter(); + + connect(auction, SIGNAL(completed()), this, SLOT(displayDefault())); +} + +Token *AtlantikBoard::findToken(Player *player) +{ + Token *token = 0; + for (QPtrListIterator<Token> it(m_tokens); (token = *it) ; ++it) + if (token->player() == player) + return token; + return 0; +} + +void AtlantikBoard::addToken(Player *player) +{ + if (!player->location()) + { + kdDebug() << "addToken ignored - estateView null" << endl; + return; + } + + Player *playerSelf = 0; + if (m_atlanticCore) + playerSelf = m_atlanticCore->playerSelf(); + + if (playerSelf && playerSelf->game() != player->game() ) + { + kdDebug() << "addToken ignored - not in same game as playerSelf" << endl; + return; + } + + kdDebug() << "addToken" << endl; + + Token *token = new Token(player, this, "token"); + m_tokens.append(token); + connect(player, SIGNAL(changed(Player *)), token, SLOT(playerChanged())); + + jumpToken(token); + + // Timer to reinit the gameboard _after_ event loop + QTimer::singleShot(100, this, SLOT(slotResizeAftermath())); +} + +void AtlantikBoard::playerChanged(Player *player) +{ + kdDebug() << "playerChanged: playerLoc " << (player->location() ? player->location()->name() : "none") << endl; + + Player *playerSelf = 0; + if (m_atlanticCore) + playerSelf = m_atlanticCore->playerSelf(); + + // Update token + Token *token = findToken(player); + if (token) + { + kdDebug() << "playerChanged: tokenLoc " << (token->location() ? token->location()->name() : "none") << endl; + if (player->isBankrupt() || (playerSelf && playerSelf->game() != player->game()) ) + token->hide(); + if (player->hasTurn()) + token->raise(); + + bool jump = false, move = false; + + if (token->inJail() != player->inJail()) + { + token->setInJail(player->inJail()); + + // If any status such as jail is ever allowed to + // change in the future, during movement, this needs + // to be addressed in moveToken and subsequent steps. + if (token != m_movingToken) + jump = true; + } + + if (token->location() != player->location()) + { + token->setLocation(player->location()); + jump = true; + } + + if (player->destination() && token->destination() != player->destination()) + { + if (m_animateTokens) + { + token->setDestination(player->destination()); + move = true; + } + else + { + token->setLocation(player->destination()); + jump = true; + } + } + + if (move) + moveToken(token); + else if (jump) + jumpToken(token); + } + else + addToken(player); +} + +void AtlantikBoard::removeToken(Player *player) +{ + Token *token = findToken(player); + if (!token) + return; + + if (token == m_movingToken) + { + m_timer->stop(); + m_movingToken = 0; + } + + m_tokens.remove(token); +} + +void AtlantikBoard::jumpToken(Token *token) +{ + if (!token || !token->location()) + return; + + kdDebug() << "jumpToken to " << token->location()->name() << endl; + + QPoint tGeom = calculateTokenDestination(token); + token->setGeometry(tGeom.x(), tGeom.y(), token->width(), token->height()); + + Player *player = token->player(); + if (player) + { + player->setLocation(token->location()); + player->setDestination(0); + + if (token->isHidden() && !player->isBankrupt()) + token->show(); + } + + if (token == m_movingToken) + { + m_timer->stop(); + + if (!m_resumeTimer) + m_movingToken = 0; + } + + emit tokenConfirmation(token->location()); +} + +void AtlantikBoard::moveToken(Token *token) +{ + kdDebug() << "moveToken to " << token->destination()->name() << endl; + + m_movingToken = token; + + // Start timer + m_timer->start(15); +} + +QPoint AtlantikBoard::calculateTokenDestination(Token *token, Estate *eDest) +{ + if (!eDest) + eDest = token->location(); + + EstateView *evDest = findEstateView(eDest); + if (!evDest) + return QPoint(0, 0); + + int x = 0, y = 0; + if (token->player()->inJail()) + { + x = evDest->geometry().right() - token->width() - 2; + y = evDest->geometry().top(); + } + else + { + x = evDest->geometry().center().x() - (token->width()/2); + y = evDest->geometry().center().y() - (token->height()/2); + +/* + // Re-center because of EstateView headers + switch(evDest->orientation()) + { + case North: + y += evDest->height()/8; break; + case East: + x -= evDest->width()/8; break; + case South: + y -= evDest->height()/8; break; + case West: + x += evDest->width()/8; break; + } +*/ + } + return QPoint(x, y); +} + +void AtlantikBoard::slotMoveToken() +{ + // Requires a core with estates to operate on + if (!m_atlanticCore) + { + kdDebug() << "slotMoveToken ignored - no atlanticCore" << endl; + return; + } + + // Do we actually have a token to move? + if (!m_movingToken) + { + m_timer->stop(); + return; + } + + // Where are we? + int xCurrent = m_movingToken->geometry().x(); + int yCurrent = m_movingToken->geometry().y(); + + // Where do we want to go today? + Estate *eDest = m_atlanticCore->estateAfter(m_movingToken->location()); + QPoint tGeom = calculateTokenDestination(m_movingToken, eDest); + + int xDest = tGeom.x(); + int yDest = tGeom.y(); + + if (xDest - xCurrent > 1) + xDest = xCurrent + 2; + else if (xCurrent - xDest > 1) + xDest = xCurrent - 2; + else + xDest = xCurrent; + + if (yDest - yCurrent > 1) + yDest = yCurrent + 2; + else if (yCurrent - yDest > 1) + yDest = yCurrent - 2; + else + yDest = yCurrent; + +// kdDebug() << "TOKEN: at " << xCurrent << "," << yCurrent << " and going to " << xDest << "," << yDest << endl; + + if (xCurrent != xDest || yCurrent != yDest) + { + m_movingToken->setGeometry(xDest, yDest, m_movingToken->width(), m_movingToken->height()); + return; + } + + // We have arrived at our destination! + m_movingToken->setLocation(eDest); + m_movingToken->player()->setLocation(eDest); + emit tokenConfirmation(eDest); + + // We have arrived at our _final_ destination! + if (eDest == m_movingToken->destination()) + { + m_movingToken->setDestination(0); + m_movingToken->player()->setDestination(0); + + m_timer->stop(); + m_movingToken = 0; + } +} + +void AtlantikBoard::resizeEvent(QResizeEvent *) +{ + // Stop moving tokens, slotResizeAftermath will re-enable this + if (m_timer!=0 && m_timer->isActive()) + { + m_timer->stop(); + m_resumeTimer=true; + } + +/* + // Adjust spacer to make sure board stays a square + int q = e->size().width() - e->size().height(); + if (q > 0) + { + QSize s(q, 0); + spacer->setFixedSize(s); + } + else + { + QSize s(0, -q); + spacer->setFixedSize(s); + } +*/ + // Timer to reinit the gameboard _after_ resizeEvent + QTimer::singleShot(0, this, SLOT(slotResizeAftermath())); +} + +void AtlantikBoard::slotResizeAftermath() +{ + kdDebug() << "AtlantikBoard::slotResizeAftermath" << endl; + // Move tokens back to their last known location (this has to be done + // _after_ resizeEvent has returned to make sure we have the correct + // adjusted estate geometries. + + Token *token = 0; + for (QPtrListIterator<Token> it(m_tokens); (token = *it) ; ++it) + jumpToken(token); + + // Restart the timer that was stopped in resizeEvent + if (m_resumeTimer && m_timer!=0 && !m_timer->isActive()) + { + m_timer->start(15); + m_resumeTimer=false; + } +} + +void AtlantikBoard::displayDefault() +{ + switch(m_displayQueue.count()) + { + case 0: + m_displayQueue.prepend(new QWidget(this)); + break; + case 1: + if (EstateDetails *display = dynamic_cast<EstateDetails*>(m_lastServerDisplay)) + display->setEstate(0); + break; + default: + if (m_displayQueue.getFirst() == m_lastServerDisplay) + m_lastServerDisplay = 0; + m_displayQueue.removeFirst(); + break; + } + updateCenter(); +} + +void AtlantikBoard::displayButton(QString command, QString caption, bool enabled) +{ + if (EstateDetails *display = dynamic_cast<EstateDetails*>(m_lastServerDisplay)) + display->addButton(command, caption, enabled); +} + +void AtlantikBoard::addCloseButton() +{ + EstateDetails *eDetails = 0; + if ((eDetails = dynamic_cast<EstateDetails*>(m_lastServerDisplay)) && eDetails != m_displayQueue.getLast()) + eDetails->addCloseButton(); +} + +void AtlantikBoard::insertDetails(QString text, bool clearText, bool clearButtons, Estate *estate) +{ + EstateDetails *eDetails = 0; + + if ((eDetails = dynamic_cast<EstateDetails*>(m_lastServerDisplay))) + { + if (clearText) + eDetails->setText(text); + else + eDetails->appendText(text); + + if (clearButtons) + eDetails->clearButtons(); + + eDetails->setEstate(estate); + return; + } + + if (m_displayQueue.getFirst() != m_lastServerDisplay) + m_displayQueue.removeFirst(); + + eDetails = new EstateDetails(estate, text, this); + m_lastServerDisplay = eDetails; + connect(eDetails, SIGNAL(buttonCommand(QString)), this, SIGNAL(buttonCommand(QString))); + connect(eDetails, SIGNAL(buttonClose()), this, SLOT(displayDefault())); + + m_displayQueue.insert(0, eDetails); + updateCenter(); +} + +void AtlantikBoard::prependEstateDetails(Estate *estate) +{ + if (!estate) + return; + + EstateDetails *eDetails = 0; + + if (m_displayQueue.getFirst() == m_lastServerDisplay) + { + eDetails = new EstateDetails(estate, QString::null, this); + m_displayQueue.prepend(eDetails); + + connect(eDetails, SIGNAL(buttonCommand(QString)), this, SIGNAL(buttonCommand(QString))); + connect(eDetails, SIGNAL(buttonClose()), this, SLOT(displayDefault())); + } + else + { + eDetails = dynamic_cast<EstateDetails*> ( m_displayQueue.getFirst() ); + if (eDetails) + { + eDetails->setEstate(estate); + eDetails->setText( QString::null ); + // eDetails->clearButtons(); + } + else + { + kdDebug() << "manual estatedetails with first in queue neither server nor details" << endl; + return; + } + } + + eDetails->addDetails(); + eDetails->addCloseButton(); + + updateCenter(); +} + +void AtlantikBoard::updateCenter() +{ + QWidget *center = m_displayQueue.getFirst(); + m_gridLayout->addMultiCellWidget(center, 1, m_gridLayout->numRows()-2, 1, m_gridLayout->numCols()-2); + center->show(); +} + +QWidget *AtlantikBoard::centerWidget() +{ + return m_displayQueue.getFirst(); +} diff --git a/atlantik/libatlantikui/board.h b/atlantik/libatlantikui/board.h new file mode 100644 index 00000000..deedb3d6 --- /dev/null +++ b/atlantik/libatlantikui/board.h @@ -0,0 +1,102 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_BOARD_H +#define ATLANTIK_BOARD_H + +#include <qwidget.h> +#include <qtimer.h> +#include <qlayout.h> +#include <qptrlist.h> +#include "libatlantikui_export.h" +class QPoint; + +class AtlanticCore; +class Auction; +class Estate; +class Player; +class Token; + +class EstateView; + +class LIBATLANTIKUI_EXPORT AtlantikBoard : public QWidget +{ +Q_OBJECT + +public: + enum DisplayMode { Play, Edit }; + + AtlantikBoard(AtlanticCore *atlanticCore, int maxEstates, DisplayMode mode, QWidget *parent, const char *name=0); + ~AtlantikBoard(); + void reset(); + + void setViewProperties(bool indicateUnowned, bool highliteUnowned, bool darkenMortgaged, bool quartzEffects, bool animateTokens); + int heightForWidth(int); + void addEstateView(Estate *estate, bool indicateUnowned = false, bool highliteUnowned = false, bool darkenMortgaged = false, bool quartzEffects = false); + void addAuctionWidget(Auction *auction); + + void addToken(Player *player); + void removeToken(Player *player); + + void indicateUnownedChanged(); + EstateView *findEstateView(Estate *estate); + QWidget *centerWidget(); + +public slots: + void slotMoveToken(); + void slotResizeAftermath(); + void displayDefault(); + +private slots: + void playerChanged(Player *player); + void displayButton(QString command, QString caption, bool enabled); + void prependEstateDetails(Estate *); + void insertDetails(QString text, bool clearText, bool clearButtons, Estate *estate = 0); + void addCloseButton(); + +signals: + void tokenConfirmation(Estate *estate); + void buttonCommand(QString command); + +protected: + void resizeEvent(QResizeEvent *); + +private: + Token *findToken(Player *player); + void jumpToken(Token *token); + void moveToken(Token *token); + QPoint calculateTokenDestination(Token *token, Estate *estate = 0); + + void updateCenter(); + + AtlanticCore *m_atlanticCore; + DisplayMode m_mode; + + QWidget *spacer, *m_lastServerDisplay; + QGridLayout *m_gridLayout; + Token *m_movingToken; + QTimer *m_timer; + bool m_resumeTimer; + + bool m_animateTokens; + int m_maxEstates; + + QPtrList<EstateView> m_estateViews; + QPtrList<Token> m_tokens; + QPtrList<QWidget> m_displayQueue; +}; + +#endif diff --git a/atlantik/libatlantikui/estatedetails.cpp b/atlantik/libatlantikui/estatedetails.cpp new file mode 100644 index 00000000..d143033c --- /dev/null +++ b/atlantik/libatlantikui/estatedetails.cpp @@ -0,0 +1,327 @@ +// Copyright (c) 2002-2004 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qpainter.h> +#include <qpixmap.h> +#include <qlayout.h> +#include <qptrlist.h> +#include <qregexp.h> +#include <qvgroupbox.h> + +#include <kdialog.h> +#include <kglobalsettings.h> +#include <kiconloader.h> +#include <klistview.h> +#include <klocale.h> +#include <kpixmap.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +#include <kdebug.h> + +#include <estate.h> +#include <estategroup.h> +#include <player.h> + +#include "estatedetails.h" +#include "kwrappedlistviewitem.h" + +EstateDetails::EstateDetails(Estate *estate, QString text, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_pixmap = 0; + m_quartzBlocks = 0; + b_recreate = true; + m_recreateQuartz = true; + + m_estate = 0; + + m_closeButton = 0; + m_buttons.setAutoDelete(true); + + m_mainLayout = new QVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint()); + Q_CHECK_PTR(m_mainLayout); + + m_mainLayout->addItem(new QSpacerItem(KDialog::spacingHint(), KDialog::spacingHint()+50, QSizePolicy::Fixed, QSizePolicy::Minimum)); + + m_infoListView = new KListView(this, "infoListView"); + m_infoListView->addColumn(m_estate ? m_estate->name() : QString("") ); + m_infoListView->setSorting(-1); + m_mainLayout->addWidget(m_infoListView); + + appendText(text); + + m_buttonBox = new QHBoxLayout(m_mainLayout, KDialog::spacingHint()); + m_buttonBox->setMargin(0); + + m_buttonBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + setEstate(estate); +} + +EstateDetails::~EstateDetails() +{ + delete m_pixmap; + delete m_quartzBlocks; + delete m_infoListView; +} + +void EstateDetails::paintEvent(QPaintEvent *) +{ + if (m_recreateQuartz) + { +/* + if (m_quartzBlocks) + { + delete m_quartzBlocks; + m_quartzBlocks = 0; + } + + if (m_estate->color().isValid()) + { + m_quartzBlocks = new KPixmap(); + + if (m_orientation == North || m_orientation == South) + m_quartzBlocks->resize(25, m_titleHeight-2); + else + m_quartzBlocks->resize(25, m_titleWidth-2); + + drawQuartzBlocks(m_quartzBlocks, *m_quartzBlocks, m_estate->color().light(60), m_estate->color()); + m_quartzBlocks = rotatePixmap(m_quartzBlocks); + } +*/ + m_recreateQuartz = false; + b_recreate = true; + } + + if (b_recreate) + { + delete m_pixmap; + m_pixmap = new QPixmap(width(), height()); + + QColor greenHouse(0, 255, 0); + QColor redHotel(255, 51, 51); + QPainter painter; + painter.begin(m_pixmap, this); + + painter.setPen(Qt::black); + + painter.setBrush(m_estate ? m_estate->bgColor() : Qt::white); + painter.drawRect(rect()); + +/* + // Paint icon only when it exists and fits + if (icon!=0 && width() > icon->width() && height() > icon->height()) + painter.drawPixmap( (width() - icon->width())/2, (height() - icon->height())/2, *icon); +*/ + + if (m_estate) + { + int titleHeight = 50; + QColor titleColor = (m_estate->color().isValid() ? m_estate->color() : m_estate->bgColor().light(80)); + + KPixmap* quartzBuffer = new KPixmap; + quartzBuffer->resize(25, (height()/4)-2); + + QPainter quartzPainter; + quartzPainter.begin(quartzBuffer, this); + + painter.setBrush(titleColor); + painter.drawRect(0, 0, width(), titleHeight); + + if (m_quartzBlocks) + { + quartzPainter.drawPixmap(0, 0, *m_quartzBlocks); + painter.drawPixmap(1, 1, *quartzBuffer); + } + + if (m_estate->houses() > 0) + { + int titleWidth = width() / 5; + + if (m_estate->houses() == 5) + { + // Hotel + painter.setBrush(redHotel); + painter.drawRect(2, 2, titleWidth-4, titleHeight-4); + } + else + { + // Houses + painter.setBrush(greenHouse); + int h = titleHeight-4, w = titleWidth-4; + for ( unsigned int i=0 ; i < m_estate->houses() ; i++ ) + painter.drawRect(2+(i*(w+2)), 2, w, h); + } + } + + quartzPainter.end(); + delete quartzBuffer; + + // TODO: steal blur code from kicker/taskbar/taskcontainer.cpp + + // Estate name + painter.setPen(Qt::white); + int fontSize = KGlobalSettings::generalFont().pointSize(); + if (fontSize == -1) + fontSize = KGlobalSettings::generalFont().pixelSize(); + + painter.setFont(QFont(KGlobalSettings::generalFont().family(), fontSize * 2, QFont::Bold)); + painter.drawText(KDialog::marginHint(), KDialog::marginHint(), width()-KDialog::marginHint(), titleHeight, Qt::AlignJustify, m_estate->name()); + + painter.setPen(Qt::black); + + int xText = 0; + + // Estate group + if (m_estate->estateGroup()) + { + xText = titleHeight - fontSize - KDialog::marginHint(); + painter.setFont(QFont(KGlobalSettings::generalFont().family(), fontSize, QFont::Bold)); + painter.drawText(5, xText, width()-10, titleHeight, Qt::AlignRight, m_estate->estateGroup()->name().upper()); + } + + xText = titleHeight + fontSize + 5; + painter.setFont(QFont(KGlobalSettings::generalFont().family(), fontSize, QFont::Normal)); + } + b_recreate = false; + + } + bitBlt(this, 0, 0, m_pixmap); +} + +void EstateDetails::resizeEvent(QResizeEvent *) +{ + m_recreateQuartz = true; + b_recreate = true; +} + +void EstateDetails::addDetails() +{ + if (m_estate) + { + QListViewItem *infoText = 0; + + // Price + if (m_estate->price()) + { + infoText = new QListViewItem(m_infoListView, m_infoListView->lastItem(), i18n("Price: %1").arg(m_estate->price())); + infoText->setPixmap(0, QPixmap(SmallIcon("info"))); + } + + // Owner, houses, isMortgaged + if (m_estate && m_estate->canBeOwned()) + { + infoText = new QListViewItem(m_infoListView, m_infoListView->lastItem(), i18n("Owner: %1").arg(m_estate->owner() ? m_estate->owner()->name() : i18n("unowned"))); + infoText->setPixmap(0, QPixmap(SmallIcon("info"))); + + if (m_estate->isOwned()) + { + infoText = new QListViewItem(m_infoListView, m_infoListView->lastItem(), i18n("Houses: %1").arg(m_estate->houses())); + infoText->setPixmap(0, QPixmap(SmallIcon("info"))); + + infoText = new QListViewItem(m_infoListView, m_infoListView->lastItem(), i18n("Mortgaged: %1").arg(m_estate->isMortgaged() ? i18n("Yes") : i18n("No"))); + infoText->setPixmap(0, QPixmap(SmallIcon("info"))); + } + } + } +} + +void EstateDetails::addButton(QString command, QString caption, bool enabled) +{ + KPushButton *button = new KPushButton(caption, this); + m_buttons.append(button); + m_buttonCommandMap[(QObject *)button] = command; + m_buttonBox->addWidget(button); + + if (m_estate) + { + QColor bgColor, fgColor; + bgColor = m_estate->bgColor().light(110); + fgColor = ( bgColor.red() + bgColor.green() + bgColor.blue() < 255 ) ? Qt::white : Qt::black; + + button->setPaletteForegroundColor( fgColor ); + button->setPaletteBackgroundColor( bgColor ); + } + button->setEnabled(enabled); + button->show(); + + connect(button, SIGNAL(pressed()), this, SLOT(buttonPressed())); +} + +void EstateDetails::addCloseButton() +{ + if (!m_closeButton) + { + m_closeButton = new KPushButton(KStdGuiItem::close(), this); + m_buttonBox->addWidget(m_closeButton); + m_closeButton->show(); + connect(m_closeButton, SIGNAL(pressed()), this, SIGNAL(buttonClose())); + } +} + +void EstateDetails::setEstate(Estate *estate) +{ + if (m_estate != estate) + { + m_estate = estate; + + m_infoListView->setColumnText( 0, m_estate ? m_estate->name() : QString("") ); + + b_recreate = true; + update(); + } +} + +void EstateDetails::setText(QString text) +{ + m_infoListView->clear(); + appendText(text); +} + +void EstateDetails::appendText(QString text) +{ + if ( text.isEmpty() ) + return; + + KWrappedListViewItem *infoText = new KWrappedListViewItem(m_infoListView, m_infoListView->lastItem(), text); + + if ( text.find( QRegExp("rolls") ) != -1 ) + infoText->setPixmap(0, QPixmap(SmallIcon("roll"))); + else + infoText->setPixmap(0, QPixmap(SmallIcon("atlantik"))); + + m_infoListView->ensureItemVisible( infoText ); +} + +void EstateDetails::clearButtons() +{ + if (m_closeButton) + { + delete m_closeButton; + m_closeButton = 0; + } + + // Delete buttons + m_buttons.clear(); + m_buttonCommandMap.clear(); +} + +void EstateDetails::buttonPressed() +{ + emit buttonCommand(QString(m_buttonCommandMap[(QObject *)QObject::sender()])); +} + +#include "estatedetails.moc" diff --git a/atlantik/libatlantikui/estatedetails.h b/atlantik/libatlantikui/estatedetails.h new file mode 100644 index 00000000..b8264a51 --- /dev/null +++ b/atlantik/libatlantikui/estatedetails.h @@ -0,0 +1,77 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_ESTATEDETAILS_H +#define ATLANTIK_ESTATEDETAILS_H + +#include <qwidget.h> + +class QPixmap; +class QString; +class QHBoxLayout; +class QVBoxLayout; +class QVGroupBox; + +class KListView; +class KPixmap; +class KPushButton; + +class Player; +class Estate; + +class EstateDetails : public QWidget +{ +Q_OBJECT + +public: + EstateDetails(Estate *estate, QString text, QWidget *parent, const char *name = 0); + ~EstateDetails(); + Estate *estate() { return m_estate; } + + void addDetails(); + void addButton(const QString command, const QString caption, bool enabled); + void addCloseButton(); + void setEstate(Estate *estate); + void setText(QString text); + void appendText(QString text); + void clearButtons(); + +protected: + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *); + +private slots: + void buttonPressed(); + +signals: + void buttonCommand(QString); + void buttonClose(); + +private: + Estate *m_estate; + QPixmap *m_pixmap; + KPixmap *m_quartzBlocks; + KListView *m_infoListView; + KPushButton *m_closeButton; + bool b_recreate, m_recreateQuartz; + QVBoxLayout *m_mainLayout; + QHBoxLayout *m_buttonBox; + QVGroupBox *m_textGroupBox; + QMap <QObject *, QString> m_buttonCommandMap; + QPtrList<KPushButton> m_buttons; +}; + +#endif diff --git a/atlantik/libatlantikui/estateview.cpp b/atlantik/libatlantikui/estateview.cpp new file mode 100644 index 00000000..b8c3f38c --- /dev/null +++ b/atlantik/libatlantikui/estateview.cpp @@ -0,0 +1,558 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qtooltip.h> +#include <qpainter.h> +#include <qtimer.h> +#include <qwmatrix.h> +#include <qcursor.h> + +#include <kdebug.h> +#include <kdeversion.h> +#include <kdialogbase.h> +#include <kglobalsettings.h> +#include <klocale.h> +#include <kpixmapeffect.h> +#include <kpopupmenu.h> +#include <kstandarddirs.h> +#include <kstringhandler.h> + +#include <player.h> +#include <estate.h> + +#include "estateview.moc" +#include "config.h" + +EstateView::EstateView(Estate *estate, EstateOrientation orientation, const QString &_icon, bool indicateUnowned, bool highliteUnowned, bool darkenMortgaged, bool quartzEffects, QWidget *parent, const char *name) : QWidget(parent, name, WResizeNoErase) +{ + m_estate = estate; + m_orientation = orientation; + + m_indicateUnowned = indicateUnowned; + m_highliteUnowned = highliteUnowned; + m_darkenMortgaged = darkenMortgaged; + m_quartzEffects = quartzEffects; + + setBackgroundMode(NoBackground); // avoid flickering + + qpixmap = 0; + b_recreate = true; + + m_quartzBlocks = 0; + m_recreateQuartz = true; + + pe = 0; + updatePE(); + + icon = new QPixmap(locate("data", "atlantik/pics/" + _icon)); + icon = rotatePixmap(icon); + + updateToolTip(); +} + +void EstateView::updateToolTip() +{ + QToolTip::remove(this); + + if ( m_estate ) + { + QString toolTip = m_estate->name(); + if ( m_estate->isOwned() ) + { + toolTip.append( "\n" + i18n("Owner: %1").arg( m_estate->owner()->name() ) ); + if ( m_estate->isMortgaged() ) + toolTip.append( "\n" + i18n("Unmortgage Price: %1").arg( m_estate->unmortgagePrice() ) ); + else + toolTip.append( "\n" + i18n("Mortgage Value: %1").arg( m_estate->mortgagePrice() ) ); + if ( m_estate->canSellHouses() ) + toolTip.append( "\n" + i18n("House Value: %1").arg( m_estate->houseSellPrice() ) ); + if ( m_estate->canBuyHouses() ) + toolTip.append( "\n" + i18n("House Price: %1").arg( m_estate->housePrice() ) ); + } + else if ( m_estate->canBeOwned() ) + toolTip.append( "\n" + i18n("Price: %1").arg( m_estate->price() ) ); + else if ( m_estate->money() ) + toolTip.append( "\n" + i18n("Money: %1").arg( m_estate->money() ) ); + + QToolTip::add( this, toolTip ); + } +} + +void EstateView::setViewProperties(bool indicateUnowned, bool highliteUnowned, bool darkenMortgaged, bool quartzEffects) +{ + if (m_indicateUnowned != indicateUnowned) + { + m_indicateUnowned = indicateUnowned; + b_recreate = true; + updatePE(); + } + + if (m_highliteUnowned != highliteUnowned) + { + m_highliteUnowned = highliteUnowned; + b_recreate = true; + } + + if (m_darkenMortgaged != darkenMortgaged) + { + m_darkenMortgaged = darkenMortgaged; + b_recreate = true; + } + + if (m_quartzEffects != quartzEffects) + { + m_quartzEffects = quartzEffects; + b_recreate = true; +// m_recreateQuartz = true; + } + + if (b_recreate || m_recreateQuartz) + update(); +} + +QPixmap *EstateView::rotatePixmap(QPixmap *p) +{ + if (p==0 || p->isNull()) + return 0; + + QWMatrix m; + + switch(m_orientation) + { + case East: + m.rotate(90); + break; + case West: + m.rotate(-90); + break; + case South: + m.rotate(180); + break; + default:; + } + *p = p->xForm(m); + return p; +} + +KPixmap *EstateView::rotatePixmap(KPixmap *p) +{ + if (p==0 || p->isNull()) + return 0; + + QWMatrix m; + + switch(m_orientation) + { + case East: + m.rotate(90); + break; + case West: + m.rotate(-90); + break; + case South: + m.rotate(180); + break; + default:; + } + *p = p->xForm(m); + return p; +} + +void EstateView::updatePE() +{ + // Don't show a when a property is not unowned, cannot be owned at all + // or when the user has configured Atlantik not to show them. + if (m_estate->isOwned() || !m_estate->canBeOwned() || m_indicateUnowned==false) + { + delete pe; + pe = 0; + } + else + { + if (pe==0) + { + // Display a coloured portfolioestate to indicate property is + // for sale + pe = new PortfolioEstate(m_estate, 0, true, this, "board-portfolioestate"); + repositionPortfolioEstate(); + + pe->show(); + } + else if (!pe->isVisible()) + pe->show(); + } +} + +void EstateView::estateChanged() +{ + updateToolTip(); + + b_recreate = true; + m_recreateQuartz = true; + + update(); + updatePE(); +} + +void EstateView::repositionPortfolioEstate() +{ + if (pe!=0) + { + int x = (m_orientation == West ? (width()-2 - pe->width()) : 2); + int y = (m_orientation == North ? (height()-2 - pe->height()) : 2); + pe->setGeometry(x, y, pe->width(), pe->height()); + } +} + +void EstateView::paintEvent(QPaintEvent *) +{ + m_titleHeight = height()/4; + m_titleWidth = width()/4; + + if (m_recreateQuartz) + { + if (m_quartzBlocks) + { + delete m_quartzBlocks; + m_quartzBlocks = 0; + } + + if (m_estate->color().isValid()) + { + m_quartzBlocks = new KPixmap(); + + if (m_orientation == North || m_orientation == South) + m_quartzBlocks->resize(25, m_titleHeight-2); + else + m_quartzBlocks->resize(25, m_titleWidth-2); + + drawQuartzBlocks(m_quartzBlocks, *m_quartzBlocks, m_estate->color().light(60), m_estate->color()); + m_quartzBlocks = rotatePixmap(m_quartzBlocks); + } + + m_recreateQuartz = false; + b_recreate = true; + } + + if (b_recreate) + { + delete qpixmap; + qpixmap = new QPixmap(width(), height()); + + QColor greenHouse(0, 255, 0); + QColor redHotel(255, 51, 51); + QPainter painter; + painter.begin(qpixmap, this); + + painter.setPen(Qt::black); + + if (m_darkenMortgaged==true && m_estate->isMortgaged()) + painter.setBrush(m_estate->bgColor().light(10)); + else if (m_highliteUnowned==true && m_estate->canBeOwned() && !m_estate->isOwned()) + painter.setBrush(m_estate->bgColor().light(190)); + else + painter.setBrush(m_estate->bgColor()); + + painter.drawRect(rect()); + + // Paint icon only when it exists and fits + if (icon!=0 && width() > icon->width() && height() > icon->height()) + painter.drawPixmap( (width() - icon->width())/2, (height() - icon->height())/2, *icon); + + if (m_estate->color().isValid()) + { + KPixmap* quartzBuffer = new KPixmap; + if (m_orientation == North || m_orientation == South) + quartzBuffer->resize(25, m_titleHeight-2); + else + quartzBuffer->resize(m_titleWidth-2, 25); + + QPainter quartzPainter; + quartzPainter.begin(quartzBuffer, this); + + painter.setBrush(m_estate->color()); + switch(m_orientation) + { + case North: + painter.drawRect(0, 0, width(), m_titleHeight); + + if (m_quartzEffects && m_quartzBlocks) + { + quartzPainter.drawPixmap(0, 0, *m_quartzBlocks); + painter.drawPixmap(1, 1, *quartzBuffer); + } + + if (m_estate->houses() > 0) + { + if (m_estate->houses() == 5) + { + // Hotel + painter.setBrush(redHotel); + painter.drawRect(2, 2, (width()/2)-4, (m_titleHeight)-4); + } + else + { + // Houses + painter.setBrush(greenHouse); + int h = (m_titleHeight)-4, w = (m_titleWidth)-4; + for( unsigned int i=0 ; i < m_estate->houses() ; i++ ) + painter.drawRect(2+(i*(w+2)), 2, w, h); + } + } + break; + case South: + painter.drawRect(0, height()-(m_titleHeight), width(), m_titleHeight); + + if (m_quartzEffects && m_quartzBlocks) + { + quartzPainter.drawPixmap(0, 0, *m_quartzBlocks); + painter.drawPixmap(width()-quartzBuffer->width()-1, height()-m_titleHeight+1, *quartzBuffer); + } + + if (m_estate->houses() > 0) + { + if (m_estate->houses() == 5) + { + // Hotel + painter.setBrush(redHotel); + painter.drawRect(2, (3*(m_titleHeight))+2, (width()/2)-4, (m_titleHeight)-4); + } + else + { + // Houses + painter.setBrush(greenHouse); + int h = (m_titleHeight)-4, w = (m_titleWidth)-4; + for( unsigned int i=0 ; i < m_estate->houses() ; i++ ) + painter.drawRect(2+(i*(w+2)), (3*(m_titleHeight))+2, w, h); + } + } + break; + case West: + painter.drawRect(0, 0, m_titleWidth, height()); + + if (m_quartzEffects && m_quartzBlocks) + { + quartzPainter.drawPixmap(0, 0, *m_quartzBlocks); + painter.drawPixmap(1, height()-quartzBuffer->height()-1, *quartzBuffer); + } + + if (m_estate->houses() > 0) + { + if (m_estate->houses() == 5) + { + // Hotel + painter.setBrush(redHotel); + painter.drawRect(2, 2, (m_titleWidth)-4, (height()/2)-4); + } + else + { + // Houses + painter.setBrush(greenHouse); + int h = (m_titleHeight)-4, w = (m_titleWidth)-4; + for( unsigned int i=0 ; i < m_estate->houses() ; i++ ) + painter.drawRect(2, 2+(i*(h+2)), w, h); + } + } + break; + case East: + painter.drawRect(width()-(m_titleWidth), 0, m_titleWidth, height()); + + if (m_quartzEffects && m_quartzBlocks) + { + quartzPainter.drawPixmap(0, 0, *m_quartzBlocks); + painter.drawPixmap(width()-quartzBuffer->width()-1, 1, *quartzBuffer); + } + + if (m_estate->houses() > 0) + { + if (m_estate->houses() == 5) + { + // Hotel + painter.setBrush(redHotel); + painter.drawRect((3*(m_titleWidth))+2, 2, (m_titleWidth)-4, (height()/2)-4); + } + else + { + // Houses + painter.setBrush(greenHouse); + int h = (m_titleHeight)-4, w = (m_titleWidth)-4; + for( unsigned int i=0 ; i < m_estate->houses() ; i++ ) + painter.drawRect((3*(m_titleWidth))+2, 2+(i*(h+2)), w, h); + } + } + break; + } + + + quartzPainter.end(); + delete quartzBuffer; + } + + QFont font = QFont( KGlobalSettings::generalFont().family(), KGlobalSettings::generalFont().pointSize(), QFont::Normal ); + painter.setFont(font); + QString estateName = m_estate->name(); +#if defined(KDE_MAKE_VERSION) +#if KDE_VERSION >= KDE_MAKE_VERSION(3,2,0) + if ( m_estate->color().isValid() && ( m_orientation == West || m_orientation == East ) ) + estateName = KStringHandler::rPixelSqueeze( m_estate->name(), QFontMetrics( font ), 3*width()/4 ); + else + estateName = KStringHandler::rPixelSqueeze( m_estate->name(), QFontMetrics( font ), width() ); +#endif +#endif + if (m_estate->color().isValid() && m_orientation == West) + painter.drawText( width()/4 + 2, height()/2, estateName ); + else + painter.drawText(2, height()/2, estateName ); + + b_recreate = false; + } + bitBlt(this, 0, 0, qpixmap); +} + +void EstateView::resizeEvent(QResizeEvent *) +{ + m_recreateQuartz = true; + b_recreate = true; + + QTimer::singleShot(0, this, SLOT(slotResizeAftermath())); +} + +void EstateView::mousePressEvent(QMouseEvent *e) +{ + if (e->button()==RightButton && m_estate->isOwned()) + { + KPopupMenu *rmbMenu = new KPopupMenu(this); + rmbMenu->insertTitle(m_estate->name()); + + if (m_estate->isOwnedBySelf()) + { + Player *player = m_estate->owner(); + + // Mortgage toggle + if (m_estate->isMortgaged()) + { + rmbMenu->insertItem(i18n("Unmortgage"), 0); + if (!m_estate->canToggleMortgage() || player->hasDebt()) + rmbMenu->setItemEnabled(0, false); + } + else + { + rmbMenu->insertItem(i18n("Mortgage"), 0); + if (!m_estate->canToggleMortgage()) + rmbMenu->setItemEnabled(0, false); + } + + // Estate construction + if (m_estate->houses()>=4) + rmbMenu->insertItem(i18n("Build Hotel"), 1); + else + rmbMenu->insertItem(i18n("Build House"), 1); + + if (!m_estate->canBuyHouses() || player->hasDebt()) + rmbMenu->setItemEnabled(1, false); + + // Estate destruction + if (m_estate->houses()==5) + rmbMenu->insertItem(i18n("Sell Hotel"), 2); + else + rmbMenu->insertItem(i18n("Sell House"), 2); + + if (!(m_estate->canSellHouses())) + rmbMenu->setItemEnabled(2, false); + } + else + { + // Request trade + if (Player *player = m_estate->owner()) + rmbMenu->insertItem(i18n("Request Trade with %1").arg(player->name()), 3); + } + + KPopupMenu *pm = dynamic_cast<KPopupMenu *>(rmbMenu); + if (pm) { + connect(pm, SIGNAL(activated(int)), this, SLOT(slotMenuAction(int))); + } + QPoint g = QCursor::pos(); + rmbMenu->exec(g); + delete rmbMenu; + } + else if (e->button()==LeftButton) + emit LMBClicked(m_estate); +} + +void EstateView::slotResizeAftermath() +{ + repositionPortfolioEstate(); +} + +void EstateView::slotMenuAction(int item) +{ + switch (item) + { + case 0: + emit estateToggleMortgage(m_estate); + break; + + case 1: + emit estateHouseBuy(m_estate); + break; + + case 2: + emit estateHouseSell(m_estate); + break; + + case 3: + emit newTrade(m_estate->owner()); + break; + } +} + +// Kudos to Gallium <[email protected]> for writing the Quartz KWin style and +// letting me use the ultra slick algorithm! +void EstateView::drawQuartzBlocks(KPixmap *pi, KPixmap &p, const QColor &c1, const QColor &c2) +{ + QPainter px; + + if (pi==0 || pi->isNull()) + return; + + px.begin(pi); + + KPixmapEffect::gradient(p, c1, c2, KPixmapEffect::HorizontalGradient); + + px.fillRect( 2, 1, 3, 3, c1.light(120) ); + px.fillRect( 2, 5, 3, 3, c1 ); + px.fillRect( 2, 9, 3, 3, c1.light(110) ); + px.fillRect( 2, 13, 3, 3, c1 ); + + px.fillRect( 6, 1, 3, 3, c1.light(110) ); + px.fillRect( 6, 5, 3, 3, c2.light(110) ); + px.fillRect( 6, 9, 3, 3, c1.light(120) ); + px.fillRect( 6, 13, 3, 3, c2.light(130) ); + + px.fillRect( 10, 5, 3, 3, c1.light(110) ); + px.fillRect( 10, 9, 3, 3, c2.light(120) ); + px.fillRect( 10, 13, 3, 3, c2.light(150) ); + + px.fillRect( 14, 1, 3, 3, c1.dark(110) ); + px.fillRect( 14, 9, 3, 3, c2.light(120) ); + px.fillRect( 14, 13, 3, 3, c1.dark(120) ); + + px.fillRect( 18, 5, 3, 3, c1.light(110) ); + px.fillRect( 18, 13, 3, 3, c1.dark(110) ); + + px.fillRect( 22, 9, 3, 3, c2.light(120)); + px.fillRect( 22, 13, 3, 3, c2.light(110) ); +} diff --git a/atlantik/libatlantikui/estateview.h b/atlantik/libatlantikui/estateview.h new file mode 100644 index 00000000..864c8983 --- /dev/null +++ b/atlantik/libatlantikui/estateview.h @@ -0,0 +1,80 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_ESTATEVIEW_H +#define ATLANTIK_ESTATEVIEW_H + +#include <qwidget.h> +#include <qpixmap.h> + +#include <kpixmap.h> + +#include "portfolioestate.h" + +enum EstateOrientation { North=0, East=1, South=2, West=3 }; + +class Player; +class Estate; + +class EstateView : public QWidget +{ +Q_OBJECT + + public: + EstateView(Estate *estate, EstateOrientation orientation, const QString &, bool indicateUnowned, bool highliteUnowned, bool darkenMortgaged, bool quartzEffects, QWidget *parent, const char *name = 0); + void setViewProperties(bool indicateUnowned, bool highliteUnowned, bool darkenMortgaged, bool quartzEffects); + Estate *estate() { return m_estate; } + void updatePE(); + EstateOrientation orientation() { return m_orientation; } + + public slots: + void slotResizeAftermath(); + + signals: + void estateToggleMortgage(Estate *estate); + void estateHouseBuy(Estate *estate); + void estateHouseSell(Estate *estate); + void newTrade(Player *player); + void LMBClicked(Estate *estate); + + protected: + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *); + void mousePressEvent(QMouseEvent *); + +private: + void updateToolTip(); + + QPixmap *rotatePixmap(QPixmap *); + KPixmap *rotatePixmap(KPixmap *); + void drawQuartzBlocks(KPixmap *pi, KPixmap &p, const QColor &c1, const QColor &c2); + void repositionPortfolioEstate(); + + Estate *m_estate; + QPixmap *qpixmap, *icon; + KPixmap *m_quartzBlocks; + bool m_indicateUnowned, m_highliteUnowned, m_darkenMortgaged, m_quartzEffects; + bool b_recreate, m_recreateQuartz; + int m_titleWidth, m_titleHeight; + EstateOrientation m_orientation; + PortfolioEstate *pe; + + private slots: + void slotMenuAction(int); + void estateChanged(); +}; + +#endif diff --git a/atlantik/libatlantikui/kwrappedlistviewitem.cpp b/atlantik/libatlantikui/kwrappedlistviewitem.cpp new file mode 100644 index 00000000..7bd9e2cf --- /dev/null +++ b/atlantik/libatlantikui/kwrappedlistviewitem.cpp @@ -0,0 +1,116 @@ +// Copyright (c) 2004 Rob Kaper <[email protected]>. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. + +#include <qheader.h> +#include <qstring.h> + +#include <kglobalsettings.h> +#include <klistview.h> +#include <kwordwrap.h> + +#include "kwrappedlistviewitem.h" + +KWrappedListViewItem::KWrappedListViewItem( QListView *parent, QString text, QString t2 ) +: QObject(), KListViewItem( parent ) +{ + init( parent, text, t2 ); +} + +KWrappedListViewItem::KWrappedListViewItem( QListView *parent, QListViewItem *after, QString text, QString t2 ) +: QObject(), KListViewItem( parent, after ) +{ + init( parent, text, t2 ); +} + +void KWrappedListViewItem::setup() +{ + widthChanged(); +} + +/* +int KWrappedListViewItem::width( const QFontMetrics&, const QListView*, int ) const +{ + return m_wrap->boundingRect().width(); +} +*/ + +void KWrappedListViewItem::wrapColumn( int c ) +{ + if ( c != m_wrapColumn ) + return; + + QListView *lv = listView(); + if ( !lv ) + return; + + QFont font = QFont( KGlobalSettings::generalFont().family(), KGlobalSettings::generalFont().pointSize(), QFont::Normal ); + QFontMetrics fm = QFontMetrics( font ); + + int wrapWidth = lv->width(); + for ( int i = 0 ; i < m_wrapColumn ; i++ ) + wrapWidth -= ( width(fm, lv, i) + lv->itemMargin() ); + + if ( pixmap(c) ) + wrapWidth -= ( pixmap( c )->width() + lv->itemMargin() ); + + QScrollBar *scrollBar = lv->verticalScrollBar(); + if ( !scrollBar->isHidden() ) + wrapWidth -= scrollBar->width(); + + QRect rect = QRect( 0, 0, wrapWidth - 20, -1 ); + + KWordWrap *wrap = KWordWrap::formatText( fm, rect, 0, m_origText ); + setText( c, wrap->wrappedString() ); + + int lc = text(c).contains( QChar( '\n' ) ) + 1; + setHeight( wrap->boundingRect().height() + lc*lv->itemMargin() ); + + widthChanged( c ); + + delete wrap; +} + +void KWrappedListViewItem::init( QListView *parent, QString text, QString t2 ) +{ + m_wrapColumn = 0; + setMultiLinesEnabled( true ); + parent->setResizeMode( QListView::LastColumn ); + + m_origText = text; + + if ( !t2.isNull() ) + { + setText( 0, text ); + m_origText = t2; + m_wrapColumn = 1; + } + else + m_origText = text; + + wrapColumn( m_wrapColumn ); + + connect( parent->header(), SIGNAL(sizeChange(int, int, int)), this, SLOT(wrapColumn(int))); +} + +#include "kwrappedlistviewitem.moc" diff --git a/atlantik/libatlantikui/kwrappedlistviewitem.h b/atlantik/libatlantikui/kwrappedlistviewitem.h new file mode 100644 index 00000000..056cef6d --- /dev/null +++ b/atlantik/libatlantikui/kwrappedlistviewitem.h @@ -0,0 +1,54 @@ +// Copyright (c) 2004 Rob Kaper <[email protected]>. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. + +#ifndef KWRAPPEDLISTVIEWITEM_H +#define KWRAPPEDLISTVIEWITEM_H + +#include <qobject.h> +#include <qstring.h> + +#include <klistview.h> + +class KWordWrap; + +class KWrappedListViewItem : public QObject, public KListViewItem +{ +Q_OBJECT + +public: + KWrappedListViewItem( QListView *parent, QString text, QString=QString::null ); + KWrappedListViewItem( QListView *parent, QListViewItem *after, QString text, QString=QString::null ); + void setup(); +// int width(const QFontMetrics& fm, const QListView* lv, int c) const; + +private slots: + void wrapColumn( int c ); + +private: + void init( QListView *parent, QString text, QString=QString::null ); + QString m_origText; + int m_wrapColumn; +}; + +#endif diff --git a/atlantik/libatlantikui/libatlantikui_export.h b/atlantik/libatlantikui/libatlantikui_export.h new file mode 100644 index 00000000..9ea1695f --- /dev/null +++ b/atlantik/libatlantikui/libatlantikui_export.h @@ -0,0 +1,25 @@ +// Copyright (c) 2004 Dirk Mueller <[email protected]> + +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef LIBATLANTIKUI_EXPORT_H +#define LIBATLANTIKUI_EXPORT_H + +#include <kdemacros.h> + +#define LIBATLANTIKUI_EXPORT KDE_EXPORT + +#endif diff --git a/atlantik/libatlantikui/portfolioestate.cpp b/atlantik/libatlantikui/portfolioestate.cpp new file mode 100644 index 00000000..625fb055 --- /dev/null +++ b/atlantik/libatlantikui/portfolioestate.cpp @@ -0,0 +1,94 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qcolor.h> +#include <qpainter.h> +#include <qrect.h> + +#include "portfolioestate.moc" +#include "estate.h" + +PortfolioEstate::PortfolioEstate(Estate *estate, Player *player, bool alwaysOwned, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_estate = estate; + m_player = player; + m_alwaysOwned = alwaysOwned; + + QSize s(PE_WIDTH, PE_HEIGHT); + setFixedSize(s); + + b_recreate = true; +} + +void PortfolioEstate::estateChanged() +{ + b_recreate = true; + update(); +} + +QPixmap PortfolioEstate::drawPixmap(Estate *estate, Player *player, bool alwaysOwned) +{ + QColor lightGray(204, 204, 204), darkGray(153, 153, 153); + QPixmap qpixmap(PE_WIDTH, PE_HEIGHT); + QPainter painter; + painter.begin(&qpixmap); + + painter.setPen(lightGray); + painter.setBrush(white); + painter.drawRect(QRect(0, 0, PE_WIDTH, PE_HEIGHT)); + if (alwaysOwned || (estate && estate->isOwned() && player == estate->owner())) + { + painter.setPen(darkGray); + for (int y=5;y<=13;y+=2) + painter.drawLine(2, y, 10, y); + + painter.setPen(Qt::white); + painter.drawPoint(8, 5); + painter.drawPoint(8, 7); + painter.drawPoint(8, 9); + painter.drawPoint(5, 11); + painter.drawPoint(9, 11); + painter.drawPoint(3, 13); + painter.drawPoint(10, 13); + + painter.setPen(estate->color()); + painter.setBrush(estate->color()); + } + else + { + painter.setPen(lightGray); + painter.setBrush(lightGray); + } + painter.drawRect(0, 0, PE_WIDTH, 3); + + return qpixmap; +} + +void PortfolioEstate::paintEvent(QPaintEvent *) +{ + if (b_recreate) + { + m_pixmap = drawPixmap(m_estate, m_player, m_alwaysOwned); + b_recreate = false; + } + bitBlt(this, 0, 0, &m_pixmap); +} + +void PortfolioEstate::mousePressEvent(QMouseEvent *e) +{ + if (e->button()==LeftButton) + emit estateClicked(m_estate); +} diff --git a/atlantik/libatlantikui/portfolioestate.h b/atlantik/libatlantikui/portfolioestate.h new file mode 100644 index 00000000..65bd5db3 --- /dev/null +++ b/atlantik/libatlantikui/portfolioestate.h @@ -0,0 +1,55 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_PORTFOLIOESTATE_H +#define ATLANTIK_PORTFOLIOESTATE_H + +#include <qpixmap.h> +#include <qwidget.h> + +#define PE_WIDTH 13 +#define PE_HEIGHT 16 + +class Estate; +class Player; + +class PortfolioEstate : public QWidget +{ +Q_OBJECT + +public: + PortfolioEstate(Estate *estate, Player *player, bool alwaysOwned, QWidget *parent, const char *name = 0); + Estate *estate() { return m_estate; } + static QPixmap drawPixmap(Estate *estate, Player *player = 0, bool alwaysOwned = true); + +protected: + void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent *); + +private slots: + void estateChanged(); + +signals: + void estateClicked(Estate *estate); + +private: + Estate *m_estate; + Player *m_player; + QPixmap m_pixmap; + bool b_recreate, m_alwaysOwned; +}; + +#endif diff --git a/atlantik/libatlantikui/portfolioview.cpp b/atlantik/libatlantikui/portfolioview.cpp new file mode 100644 index 00000000..c07d426b --- /dev/null +++ b/atlantik/libatlantikui/portfolioview.cpp @@ -0,0 +1,295 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <qpainter.h> +#include <qcursor.h> + +#include <kdebug.h> +#include <kdialogbase.h> +#include <kiconeffect.h> +#include <kglobalsettings.h> +#include <klocale.h> +#include <kpopupmenu.h> +#include <kstandarddirs.h> + +#include <atlantic_core.h> +#include <config.h> +#include <player.h> +#include <estate.h> +#include <estategroup.h> + +#include "portfolioview.moc" + +#define PE_DISTW 4 +#define PE_DISTH 4 +#define PE_SPACE 2 +#define PE_MARGINW 5 +#define PE_MARGINH 2 +#define ICONSIZE 48 + +PortfolioView::PortfolioView(AtlanticCore *core, Player *player, QColor activeColor, QColor inactiveColor, QWidget *parent, const char *name) : QWidget(parent, name) +{ + m_atlanticCore = core; + m_player = player; + m_activeColor = activeColor; + m_inactiveColor = inactiveColor; + m_lastPE = 0; + + qpixmap = 0; + b_recreate = true; + + m_portfolioEstates.setAutoDelete(true); + setBackgroundColor(Qt::white); + setMinimumHeight(ICONSIZE); + + // Init icon + m_image = 0; + m_imageName = "hamburger.png"; + loadIcon(); +} + +PortfolioView::~PortfolioView() +{ + clearPortfolio(); + delete m_image; + delete qpixmap; +} + +Player *PortfolioView::player() +{ + return m_player; +} + +void PortfolioView::buildPortfolio() +{ + if ( m_portfolioEstates.count() ) + clearPortfolio(); + + // Loop through estate groups in order + QPtrList<EstateGroup> estateGroups = m_atlanticCore->estateGroups(); + PortfolioEstate *lastPE = 0, *firstPEprevGroup = 0; + + int x = 100, y = 25, marginHint = 5, bottom; + bottom = ICONSIZE - PE_HEIGHT - marginHint; + + EstateGroup *estateGroup; + for (QPtrListIterator<EstateGroup> it(estateGroups); *it; ++it) + { + if ((estateGroup = *it)) + { + // New group + lastPE = 0; + + // Loop through estates + QPtrList<Estate> estates = m_atlanticCore->estates(); + Estate *estate; + for (QPtrListIterator<Estate> it(estates); *it; ++it) + { + if ((estate = *it) && estate->estateGroup() == estateGroup) + { + // Create PE + PortfolioEstate *portfolioEstate = new PortfolioEstate(estate, m_player, false, this, "portfolioestate"); + m_portfolioEstates.append(portfolioEstate); + + connect(portfolioEstate, SIGNAL(estateClicked(Estate *)), this, SIGNAL(estateClicked(Estate *))); + if (lastPE) + { + x = lastPE->x() + 2; + y = lastPE->y() + 4; + if (y > bottom) + bottom = y; + } + else if (firstPEprevGroup) + { + x = firstPEprevGroup->x() + PE_WIDTH + 8; + y = 20 + marginHint; + firstPEprevGroup = portfolioEstate; + } + else + { + x = ICONSIZE + marginHint; + y = 20 + marginHint; + if (y > bottom) + bottom = y; + firstPEprevGroup = portfolioEstate; + } + + portfolioEstate->setGeometry(x, y, portfolioEstate->width(), portfolioEstate->height()); + portfolioEstate->show(); + + connect(estate, SIGNAL(changed()), portfolioEstate, SLOT(estateChanged())); + + lastPE = portfolioEstate; + } + } + } + } + setMinimumWidth(x + PE_WIDTH + marginHint); + int minHeight = bottom + PE_HEIGHT + marginHint; + if (minHeight > minimumHeight()) + setMinimumHeight(minHeight); +} + +void PortfolioView::clearPortfolio() +{ + m_portfolioEstates.clear(); +} + +void PortfolioView::loadIcon() +{ + if (m_imageName == m_player->image()) + return; + m_imageName = m_player->image(); + + delete m_image; + m_image = 0; + + if (!m_imageName.isEmpty()) + { + QString filename = locate("data", "atlantik/themes/default/tokens/" + m_imageName); + if (KStandardDirs::exists(filename)) + m_image = new QPixmap(filename); + } + + if (!m_image) + { + return; + +/* + m_imageName = "hamburger.png"; + + QString filename = locate("data", "atlantik/themes/default/tokens/" + m_imageName); + if (KStandardDirs::exists(filename)) + m_image = new QPixmap(filename); +*/ + } + else if (ICONSIZE > minimumHeight()) + setMinimumHeight(ICONSIZE); + + QWMatrix m; + m.scale(double(ICONSIZE) / m_image->width(), double(ICONSIZE) / m_image->height()); + QPixmap *scaledPixmap = new QPixmap(ICONSIZE, ICONSIZE); + *scaledPixmap = m_image->xForm(m); + + delete m_image; + m_image = scaledPixmap; +} + +void PortfolioView::paintEvent(QPaintEvent *) +{ + if (b_recreate) + { + delete qpixmap; + qpixmap = new QPixmap(width(), height()); + + QPainter painter; + painter.begin(qpixmap, this); + + painter.setPen(Qt::white); + painter.setBrush(Qt::white); + painter.drawRect(rect()); + + painter.setPen(m_player->hasTurn() ? m_activeColor : Qt::black); + painter.setBrush(m_player->hasTurn() ? m_activeColor : Qt::black); + painter.drawRect(0, 0, width(), 20); + + if (m_image) + { + painter.setPen(Qt::black); + painter.setBrush(Qt::white); + painter.drawRect(0, 0, ICONSIZE, ICONSIZE); + + painter.drawPixmap(0, 0, *m_image); + } + + painter.setPen(Qt::white); + painter.setFont(QFont(KGlobalSettings::generalFont().family(), KGlobalSettings::generalFont().pointSize(), QFont::Bold)); + painter.drawText(ICONSIZE + KDialog::marginHint(), 15, m_player->name()); + + if ( m_portfolioEstates.count() ) + painter.drawText(width() - 50, 15, QString::number(m_player->money())); + else + { + painter.setPen(Qt::black); + painter.setBrush(Qt::white); + + painter.setFont(QFont(KGlobalSettings::generalFont().family(), KGlobalSettings::generalFont().pointSize(), QFont::Normal)); + painter.drawText(ICONSIZE + KDialog::marginHint(), 30, m_player->host()); + } + + b_recreate = false; + } + bitBlt(this, 0, 0, qpixmap); +} + +void PortfolioView::resizeEvent(QResizeEvent *) +{ + b_recreate = true; +} + +void PortfolioView::playerChanged() +{ + loadIcon(); + + b_recreate = true; + update(); +} + +void PortfolioView::mousePressEvent(QMouseEvent *e) +{ + Player *playerSelf = m_atlanticCore->playerSelf(); + + if ( e->button()==RightButton && (m_player != playerSelf) ) + { + KPopupMenu *rmbMenu = new KPopupMenu(this); + rmbMenu->insertTitle(m_player->name()); + + if ( m_portfolioEstates.count() ) + { + // Start trade + rmbMenu->insertItem(i18n("Request Trade with %1").arg(m_player->name()), 0); + } + else + { + // Kick player + rmbMenu->insertItem(i18n("Boot Player %1 to Lounge").arg(m_player->name()), 0); + rmbMenu->setItemEnabled( 0, m_atlanticCore->selfIsMaster() ); + } + + connect(rmbMenu, SIGNAL(activated(int)), this, SLOT(slotMenuAction(int))); + QPoint g = QCursor::pos(); + rmbMenu->exec(g); + } +} + +void PortfolioView::slotMenuAction(int item) +{ + switch (item) + { + case 0: + if ( m_portfolioEstates.count() ) + emit newTrade(m_player); + else + emit kickPlayer(m_player); + break; + } +} +#undef PE_DISTW +#undef PE_DISTH +#undef PE_SPACE +#undef PE_MARGINW +#undef PE_MARGINH +#undef ICONSIZE diff --git a/atlantik/libatlantikui/portfolioview.h b/atlantik/libatlantikui/portfolioview.h new file mode 100644 index 00000000..26317e2b --- /dev/null +++ b/atlantik/libatlantikui/portfolioview.h @@ -0,0 +1,73 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_PORTFOLIOVIEW_H +#define ATLANTIK_PORTFOLIOVIEW_H + +#include <qwidget.h> +#include <qpixmap.h> +#include <qptrlist.h> + +#include "portfolioestate.h" +#include "libatlantikui_export.h" +class QColor; +class QString; + +class AtlanticCore; +class Player; +class Estate; + +class LIBATLANTIKUI_EXPORT PortfolioView : public QWidget +{ +Q_OBJECT + +public: + PortfolioView(AtlanticCore *core, Player *_player, QColor activeColor, QColor inactiveColor, QWidget *parent, const char *name = 0); + ~PortfolioView(); + + void buildPortfolio(); + void clearPortfolio(); + + Player *player(); + +protected: + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *); + void mousePressEvent(QMouseEvent *); + +signals: + void newTrade(Player *player); + void kickPlayer(Player *player); + void estateClicked(Estate *); + +private slots: + void playerChanged(); + void slotMenuAction(int item); + +private: + void loadIcon(); + + AtlanticCore *m_atlanticCore; + Player *m_player; + PortfolioEstate *m_lastPE; + QColor m_activeColor, m_inactiveColor; + QPixmap *qpixmap, *m_image; + QString m_imageName; + bool b_recreate; + QPtrList<PortfolioEstate> m_portfolioEstates; +}; + +#endif diff --git a/atlantik/libatlantikui/token.cpp b/atlantik/libatlantikui/token.cpp new file mode 100644 index 00000000..6f13333f --- /dev/null +++ b/atlantik/libatlantikui/token.cpp @@ -0,0 +1,157 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <iostream> + +#include <qpainter.h> +#include <qpixmap.h> +#include <qfont.h> + +#include <kdebug.h> + +#include <kstandarddirs.h> +#include <kglobalsettings.h> + +#include "board.h" +#include "estate.h" +#include "player.h" + +#include "token.moc" + +#define TOKEN_ICONSIZE 32 + +Token::Token(Player *player, AtlantikBoard *parent, const char *name) : QWidget(parent, name) +{ + setBackgroundMode(NoBackground); // avoid flickering + + m_parentBoard = parent; + + m_player = player; + connect(m_player, SIGNAL(changed(Player *)), this, SLOT(playerChanged())); + + m_inJail = m_player->inJail(); + m_location = m_player->location(); + m_destination = 0; + + qpixmap = 0; + b_recreate = true; + + // Init icon + m_image = 0; + loadIcon(); + + setFixedSize(QSize(TOKEN_ICONSIZE, TOKEN_ICONSIZE + KGlobalSettings::generalFont().pointSize())); +} + +Token::~Token() +{ + delete m_image; +} + +Player *Token::player() +{ + return m_player; +} + +void Token::setLocation(Estate *location) +{ + if (m_location != location) + m_location = location; +} + +void Token::setDestination(Estate *estateView) +{ + if (m_destination != estateView) + m_destination = estateView; +} + +void Token::playerChanged() +{ + if (m_imageName != m_player->image()) + loadIcon(); + + b_recreate = true; + update(); +} + +void Token::loadIcon() +{ + m_imageName = m_player->image(); + + delete m_image; + m_image = 0; + + if (!m_imageName.isEmpty()) + { + QString filename = locate("data", "atlantik/themes/default/tokens/" + m_imageName); + if (KStandardDirs::exists(filename)) + m_image = new QPixmap(filename); + } + + if (!m_image) + { + m_imageName = "hamburger.png"; + + QString filename = locate("data", "atlantik/themes/default/tokens/" + m_imageName); + if (KStandardDirs::exists(filename)) + m_image = new QPixmap(filename); + } + + QWMatrix m; + m.scale(double(TOKEN_ICONSIZE) / m_image->width(), double(TOKEN_ICONSIZE) / m_image->height()); + QPixmap *scaledPixmap = new QPixmap(TOKEN_ICONSIZE, TOKEN_ICONSIZE); + *scaledPixmap = m_image->xForm(m); + + delete m_image; + m_image = scaledPixmap; +} + +void Token::paintEvent(QPaintEvent *) +{ + if (b_recreate) + { + delete qpixmap; + qpixmap = new QPixmap(width(), height()); + + QPainter painter; + painter.begin(qpixmap, this); + + if (m_image) + { + painter.setPen(Qt::black); + painter.setBrush(Qt::white); + painter.drawRect(0, 0, TOKEN_ICONSIZE, TOKEN_ICONSIZE); + + painter.drawPixmap(0, 0, *m_image); + } + + painter.setPen(Qt::black); + painter.setBrush(Qt::black); + painter.drawRect(0, TOKEN_ICONSIZE, width(), KGlobalSettings::generalFont().pointSize()); + + painter.setPen(Qt::white); + painter.setFont(QFont(KGlobalSettings::generalFont().family(), KGlobalSettings::generalFont().pointSize(), QFont::DemiBold)); + painter.drawText(1, height()-1, (m_player ? m_player->name() : QString::null)); + + b_recreate = false; + } + bitBlt(this, 0, 0, qpixmap); +} + +void Token::resizeEvent(QResizeEvent *) +{ + b_recreate = true; +} diff --git a/atlantik/libatlantikui/token.h b/atlantik/libatlantikui/token.h new file mode 100644 index 00000000..f0e52f2b --- /dev/null +++ b/atlantik/libatlantikui/token.h @@ -0,0 +1,62 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef ATLANTIK_TOKEN_H +#define ATLANTIK_TOKEN_H + +#include <qwidget.h> + +class QPixmap; + +class Player; +class Estate; +class AtlantikBoard; + +class Token : public QWidget +{ +Q_OBJECT + + public: + Token (Player *player, AtlantikBoard *parent, const char *name = 0); + ~Token(); + Player *player(); + void setLocation(Estate *estate); + Estate *location() { return m_location; } + void setDestination(Estate *estate); + Estate *destination() { return m_destination; } + void setInJail (bool inJail) { m_inJail = inJail; } + bool inJail() { return m_inJail; } + + private slots: + void playerChanged(); + + protected: + void paintEvent(QPaintEvent *); + void resizeEvent(QResizeEvent *); + +private: + void loadIcon(); + + Player *m_player; + Estate *m_location, *m_destination; + bool m_inJail; + AtlantikBoard *m_parentBoard; + bool b_recreate; + QPixmap *qpixmap, *m_image; + QString m_imageName; +}; + +#endif diff --git a/atlantik/libatlantikui/trade_widget.cpp b/atlantik/libatlantikui/trade_widget.cpp new file mode 100644 index 00000000..b2658abb --- /dev/null +++ b/atlantik/libatlantikui/trade_widget.cpp @@ -0,0 +1,374 @@ +// Copyright (c) 2002-2003 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include <iostream> + +#include <qlayout.h> +#include <qhgroupbox.h> +#include <qheader.h> +#include <qpopupmenu.h> +#include <qcursor.h> +#include <qvalidator.h> +#include <qmap.h> +#include <qlabel.h> +#include <qspinbox.h> + +#include <klocale.h> +#include <klistview.h> +#include <kdebug.h> +#include <kdialogbase.h> +#include <klineedit.h> +#include <kiconloader.h> +#include <kpushbutton.h> +#include <kcombobox.h> +#include <kpopupmenu.h> + +#include <atlantic_core.h> +#include <player.h> +#include <estate.h> +#include <trade.h> +#include <portfolioestate.h> + +#include "trade_widget.moc" + +TradeDisplay::TradeDisplay(Trade *trade, AtlanticCore *atlanticCore, QWidget *parent, const char *name) + : QWidget(parent, name, + WType_Dialog | WStyle_Customize | WStyle_DialogBorder | WStyle_Title | + WStyle_Minimize | WStyle_ContextHelp ) +{ + m_trade = trade; + m_atlanticCore = atlanticCore; + + setCaption(i18n("Trade %1").arg(trade->tradeId())); + + QVBoxLayout *listCompBox = new QVBoxLayout(this, KDialog::marginHint()); + + m_updateComponentBox = new QHGroupBox(i18n("Add Component"), this); + listCompBox->addWidget(m_updateComponentBox); + + m_editTypeCombo = new KComboBox(m_updateComponentBox); + m_editTypeCombo->insertItem(i18n("Estate")); + m_editTypeCombo->insertItem(i18n("Money")); + + connect(m_editTypeCombo, SIGNAL(activated(int)), this, SLOT(setTypeCombo(int))); + + m_estateCombo = new KComboBox(m_updateComponentBox); + QPtrList<Estate> estateList = m_atlanticCore->estates(); + Estate *estate; + for (QPtrListIterator<Estate> it(estateList); *it; ++it) + { + if ((estate = *it) && estate->isOwned()) + { + m_estateCombo->insertItem( PortfolioEstate::drawPixmap(estate), estate->name() ); + m_estateMap[m_estateCombo->count() - 1] = estate; + m_estateRevMap[estate] = m_estateCombo->count() - 1; + } + } + + connect(m_estateCombo, SIGNAL(activated(int)), this, SLOT(setEstateCombo(int))); + + m_moneyBox = new QSpinBox(0, 10000, 1, m_updateComponentBox); + + QPtrList<Player> playerList = m_atlanticCore->players(); + Player *player, *pSelf = m_atlanticCore->playerSelf(); + + m_fromLabel = new QLabel(m_updateComponentBox); + m_fromLabel->setText(i18n("From")); + m_playerFromCombo = new KComboBox(m_updateComponentBox); + + m_toLabel = new QLabel(m_updateComponentBox); + m_toLabel->setText(i18n("To")); + m_playerTargetCombo = new KComboBox(m_updateComponentBox); + + for (QPtrListIterator<Player> it(playerList); *it; ++it) + { + if ((player = *it) && player->game() == pSelf->game()) + { + m_playerFromCombo->insertItem(player->name()); + m_playerFromMap[m_playerFromCombo->count() - 1] = player; + m_playerFromRevMap[player] = m_playerFromCombo->count() - 1; + + m_playerTargetCombo->insertItem(player->name()); + m_playerTargetMap[m_playerTargetCombo->count() - 1] = player; + m_playerTargetRevMap[player] = m_playerTargetCombo->count() - 1; + + connect(player, SIGNAL(changed(Player *)), this, SLOT(playerChanged(Player *))); + } + } + + m_updateButton = new KPushButton(i18n("Update"), m_updateComponentBox); + m_updateButton->setEnabled(false); + + connect(m_updateButton, SIGNAL(clicked()), this, SLOT(updateComponent())); + + m_componentList = new KListView(this, "componentList"); + listCompBox->addWidget(m_componentList); + + m_componentList->addColumn(i18n("Player")); + m_componentList->addColumn(i18n("Gives")); + m_componentList->addColumn(i18n("Player")); + m_componentList->addColumn(i18n("Item")); + + connect(m_componentList, SIGNAL(contextMenu(KListView*, QListViewItem *, const QPoint&)), SLOT(contextMenu(KListView *, QListViewItem *, const QPoint&))); + connect(m_componentList, SIGNAL(clicked(QListViewItem *)), this, SLOT(setCombos(QListViewItem *))); + + QHBoxLayout *actionBox = new QHBoxLayout(this, 0, KDialog::spacingHint()); + listCompBox->addItem(actionBox); + + actionBox->addItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum)); + + m_rejectButton = new KPushButton(BarIcon("cancel", KIcon::SizeSmall), i18n("Reject"), this); + actionBox->addWidget(m_rejectButton); + + connect(m_rejectButton, SIGNAL(clicked()), this, SLOT(reject())); + + m_acceptButton = new KPushButton(BarIcon("ok", KIcon::SizeSmall), i18n("Accept"), this); +// m_acceptButton->setEnabled(false); + actionBox->addWidget(m_acceptButton); + + connect(m_acceptButton, SIGNAL(clicked()), this, SLOT(accept())); + + m_status = new QLabel(this); + listCompBox->addWidget(m_status); + m_status->setText( i18n( "%1 out of %2 players accept current trade proposal." ).arg( m_trade->count( true ) ).arg( m_trade->count( false ) ) ); + +// mPlayerList->header()->hide(); +// mPlayerList->setRootIsDecorated(true); +// mPlayerList->setResizeMode(KListView::AllColumns); + + connect(m_trade, SIGNAL(itemAdded(TradeItem *)), this, SLOT(tradeItemAdded(TradeItem *))); + connect(m_trade, SIGNAL(itemRemoved(TradeItem *)), this, SLOT(tradeItemRemoved(TradeItem *))); + connect(m_trade, SIGNAL(changed(Trade *)), this, SLOT(tradeChanged())); + connect(m_trade, SIGNAL(rejected(Player *)), this, SLOT(tradeRejected(Player *))); + connect(this, SIGNAL(updateEstate(Trade *, Estate *, Player *)), m_trade, SIGNAL(updateEstate(Trade *, Estate *, Player *))); + connect(this, SIGNAL(updateMoney(Trade *, unsigned int, Player *, Player *)), m_trade, SIGNAL(updateMoney(Trade *, unsigned int, Player *, Player *))); + connect(this, SIGNAL(reject(Trade *)), m_trade, SIGNAL(reject(Trade *))); + connect(this, SIGNAL(accept(Trade *)), m_trade, SIGNAL(accept(Trade *))); + + setTypeCombo(m_editTypeCombo->currentItem()); + setEstateCombo(m_estateCombo->currentItem()); + + m_contextTradeItem = 0; +} + +void TradeDisplay::closeEvent(QCloseEvent *e) +{ + // Don't send network event when trade is already rejected + if (m_trade->isRejected()) + m_atlanticCore->removeTrade(m_trade); + else + emit reject(m_trade); + + e->accept(); +} + +void TradeDisplay::tradeItemAdded(TradeItem *tradeItem) +{ + KListViewItem *item = new KListViewItem(m_componentList, (tradeItem->from() ? tradeItem->from()->name() : QString("?")), i18n("gives is transitive ;)", "gives"), (tradeItem->to() ? tradeItem->to()->name() : QString("?")), tradeItem->text()); + connect(tradeItem, SIGNAL(changed(TradeItem *)), this, SLOT(tradeItemChanged(TradeItem *))); + + item->setPixmap(0, QPixmap(SmallIcon("personal"))); + item->setPixmap(2, QPixmap(SmallIcon("personal"))); + + if (TradeEstate *tradeEstate = dynamic_cast<TradeEstate*>(tradeItem)) + item->setPixmap(3, PortfolioEstate::drawPixmap(tradeEstate->estate())); +// else if (TradeMoney *tradeMoney = dynamic_cast<TradeMoney*>(tradeItem)) +// item->setPixmap(3, PortfolioEstate::pixMap(tradeEstate->estate())); + + m_componentMap[tradeItem] = item; + m_componentRevMap[item] = tradeItem; +} + +void TradeDisplay::tradeItemRemoved(TradeItem *t) +{ + KListViewItem *item = m_componentMap[t]; + delete item; + m_componentMap[t] = 0; +} + +void TradeDisplay::tradeItemChanged(TradeItem *t) +{ + KListViewItem *item = m_componentMap[t]; + if (item) + { + item->setText(0, t->from() ? t->from()->name() : QString("?")); + item->setPixmap(0, QPixmap(SmallIcon("personal"))); + item->setText(2, t->to() ? t->to()->name() : QString("?")); + item->setPixmap(2, QPixmap(SmallIcon("personal"))); + item->setText(3, t->text()); + } +} + +void TradeDisplay::tradeChanged() +{ + // TODO: add notification whether playerSelf has accepted or not and + // enable/disable accept button based on that + m_status->setText( i18n( "%1 out of %2 players accept current trade proposal." ).arg( m_trade->count( true ) ).arg( m_trade->count( false ) ) ); +} + +void TradeDisplay::playerChanged(Player *player) +{ + m_playerFromCombo->changeItem(player->name(), m_playerFromRevMap[player]); + m_playerTargetCombo->changeItem(player->name(), m_playerTargetRevMap[player]); + + TradeItem *item = 0; + for (QMap<KListViewItem *, TradeItem *>::Iterator it=m_componentRevMap.begin() ; it != m_componentRevMap.end() && (item = *it) ; ++it) + tradeItemChanged(item); +} + +void TradeDisplay::tradeRejected(Player *player) +{ + if (player) + m_status->setText(i18n("Trade proposal was rejected by %1.").arg(player->name())); + else + m_status->setText(i18n("Trade proposal was rejected.")); + + // Disable GUI elements + m_updateButton->setEnabled(false); + m_componentList->setEnabled(false); + m_rejectButton->setEnabled(false); + m_acceptButton->setEnabled(false); + + // TODO: add/enable close button +} + +void TradeDisplay::setTypeCombo(int index) +{ + switch (index) + { + case 0: + // Editing estate component + + m_estateCombo->show(); + m_estateCombo->setMaximumWidth(9999); + + m_moneyBox->hide(); + m_moneyBox->setMaximumWidth(0); + + setEstateCombo(m_estateCombo->currentItem()); // also updates playerfromCombo + m_playerFromCombo->setEnabled(false); + + m_updateButton->setEnabled( m_estateCombo->count() > 0 ); + + break; + + case 1: + // Editing money component + + m_estateCombo->hide(); + m_estateCombo->setMaximumWidth(0); + + m_moneyBox->show(); + m_moneyBox->setMaximumWidth(9999); + + m_playerFromCombo->setEnabled(true); + + m_updateButton->setEnabled(true); + + break; + } +} + +void TradeDisplay::setEstateCombo(int index) +{ + if (m_estateCombo->currentItem() != index) + m_estateCombo->setCurrentItem(index); + + if (Estate *estate = m_estateMap[index]) + m_playerFromCombo->setCurrentItem( m_playerFromRevMap[estate->owner()] ); +} + +void TradeDisplay::setCombos(QListViewItem *i) +{ + TradeItem *item = m_componentRevMap[(KListViewItem *)(i)]; + if (TradeEstate *tradeEstate = dynamic_cast<TradeEstate*>(item)) + { + setTypeCombo(0); + setEstateCombo( m_estateRevMap[tradeEstate->estate()] ); // also updates playerFromCombo + m_playerTargetCombo->setCurrentItem( m_playerTargetRevMap[tradeEstate->to()] ); + } + else if (TradeMoney *tradeMoney = dynamic_cast<TradeMoney*>(item)) + { + setTypeCombo(1); + m_moneyBox->setValue( tradeMoney->money() ); + m_playerFromCombo->setCurrentItem( m_playerFromRevMap[tradeMoney->from()] ); + m_playerTargetCombo->setCurrentItem( m_playerTargetRevMap[tradeMoney->to()] ); + } +} + +void TradeDisplay::updateComponent() +{ + Estate *estate; + Player *pFrom, *pTarget; + + switch (m_editTypeCombo->currentItem()) + { + case 0: + // Updating estate component + estate = m_estateMap[m_estateCombo->currentItem()]; + pTarget = m_playerTargetMap[m_playerTargetCombo->currentItem()]; + + if (estate && pTarget) + emit updateEstate(m_trade, estate, pTarget); + + break; + + case 1: + // Updating money component + pFrom = m_playerFromMap[m_playerFromCombo->currentItem()]; + pTarget = m_playerTargetMap[m_playerTargetCombo->currentItem()]; + + if (pFrom && pTarget) + emit updateMoney(m_trade, m_moneyBox->value(), pFrom, pTarget); + + break; + } +} + +void TradeDisplay::reject() +{ + emit reject(m_trade); +} + +void TradeDisplay::accept() +{ + emit accept(m_trade); +} + +void TradeDisplay::contextMenu(KListView *, QListViewItem *i, const QPoint& p) +{ + m_contextTradeItem = m_componentRevMap[(KListViewItem *)(i)]; + + KPopupMenu *rmbMenu = new KPopupMenu(this); +// rmbMenu->insertTitle( ... ); + rmbMenu->insertItem(i18n("Remove From Trade"), 0); + + connect(rmbMenu, SIGNAL(activated(int)), this, SLOT(contextMenuClicked(int))); + rmbMenu->exec(p); +} + +void TradeDisplay::contextMenuClicked(int) +{ + if (!m_contextTradeItem) + return; + + if (TradeEstate *tradeEstate = dynamic_cast<TradeEstate*>(m_contextTradeItem)) + emit updateEstate(m_trade, tradeEstate->estate(), 0); + else if (TradeMoney *tradeMoney = dynamic_cast<TradeMoney*>(m_contextTradeItem)) + emit updateMoney(m_trade, 0, tradeMoney->from(), tradeMoney->to()); + + m_contextTradeItem = 0; +} diff --git a/atlantik/libatlantikui/trade_widget.h b/atlantik/libatlantikui/trade_widget.h new file mode 100644 index 00000000..642cc919 --- /dev/null +++ b/atlantik/libatlantikui/trade_widget.h @@ -0,0 +1,98 @@ +// Copyright (c) 2002 Rob Kaper <[email protected]> +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License version 2.1 as published by the Free Software Foundation. +// +// 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; see the file COPYING.LIB. If not, write to +// the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#ifndef TRADEWIDGET_H +#define TRADEWIDGET_H + +#include <qwidget.h> +#include <qmap.h> +#include "libatlantikui_export.h" + +class QHGroupBox; +class QLabel; +class QListViewItem; +class QSpinBox; + +class KListView; +class KListViewItem; +class KComboBox; +class KPushButton; + +class AtlanticCore; +class Player; +class Trade; +class TradeItem; + +class LIBATLANTIKUI_EXPORT TradeDisplay : public QWidget +{ +Q_OBJECT + +public: + TradeDisplay(Trade *trade, AtlanticCore *atlanticCore, QWidget *parent=0, const char *name = 0); + + Trade *trade() { return mTrade; } + +protected: + void closeEvent(QCloseEvent *e); + +private slots: + void tradeItemAdded(TradeItem *); + void tradeItemRemoved(TradeItem *); + void tradeItemChanged(TradeItem *); + void tradeChanged(); + void playerChanged(Player *player); + void tradeRejected(Player *); + + void setTypeCombo(int); + void setEstateCombo(int); + void setCombos(QListViewItem *i); + + void updateComponent(); + void reject(); + void accept(); + + void contextMenu(KListView *l, QListViewItem *i, const QPoint& p); + void contextMenuClicked(int item); + +signals: + void updateEstate(Trade *trade, Estate *estate, Player *to); + void updateMoney(Trade *trade, unsigned int money, Player *from, Player *to); + void reject(Trade *trade); + void accept(Trade *trade); + +private: + QHGroupBox *m_updateComponentBox; + QLabel *m_status, *m_fromLabel, *m_toLabel; + QSpinBox *m_moneyBox; + + KComboBox *m_editTypeCombo, *m_playerFromCombo, *m_playerTargetCombo, *m_estateCombo; + KListView *m_componentList; + KPushButton *m_updateButton, *m_rejectButton, *m_acceptButton; + + AtlanticCore *m_atlanticCore; + Trade *mTrade, *m_trade; + TradeItem *m_contextTradeItem; + + // TODO: Wouldn't QPair make more sense here? + QMap<TradeItem *, KListViewItem *> m_componentMap; + QMap<KListViewItem *, TradeItem *> m_componentRevMap; + QMap<int, Estate *> m_estateMap; + QMap<Estate *, int> m_estateRevMap; + QMap<int, Player *> m_playerFromMap, m_playerTargetMap; + QMap<Player *, int> m_playerFromRevMap, m_playerTargetRevMap; +}; + +#endif diff --git a/atlantik/pics/Makefile.am b/atlantik/pics/Makefile.am new file mode 100644 index 00000000..e0fd3547 --- /dev/null +++ b/atlantik/pics/Makefile.am @@ -0,0 +1,3 @@ +SUBDIRS = board misc toolbar + +KDE_ICON = atlantik diff --git a/atlantik/pics/board/Makefile.am b/atlantik/pics/board/Makefile.am new file mode 100644 index 00000000..1a6d0d6c --- /dev/null +++ b/atlantik/pics/board/Makefile.am @@ -0,0 +1,2 @@ +boardicondir = $(kde_datadir)/atlantik/pics +boardicon_DATA = arrow.png qmark-blue.png qmark-red.png token.png train.png diff --git a/atlantik/pics/board/arrow.png b/atlantik/pics/board/arrow.png Binary files differnew file mode 100644 index 00000000..167d4766 --- /dev/null +++ b/atlantik/pics/board/arrow.png diff --git a/atlantik/pics/board/qmark-blue.png b/atlantik/pics/board/qmark-blue.png Binary files differnew file mode 100644 index 00000000..6462dff0 --- /dev/null +++ b/atlantik/pics/board/qmark-blue.png diff --git a/atlantik/pics/board/qmark-red.png b/atlantik/pics/board/qmark-red.png Binary files differnew file mode 100644 index 00000000..6aff93b3 --- /dev/null +++ b/atlantik/pics/board/qmark-red.png diff --git a/atlantik/pics/board/token.png b/atlantik/pics/board/token.png Binary files differnew file mode 100644 index 00000000..eba2ed1b --- /dev/null +++ b/atlantik/pics/board/token.png diff --git a/atlantik/pics/board/train.png b/atlantik/pics/board/train.png Binary files differnew file mode 100644 index 00000000..4603e537 --- /dev/null +++ b/atlantik/pics/board/train.png diff --git a/atlantik/pics/hi16-app-atlantik.png b/atlantik/pics/hi16-app-atlantik.png Binary files differnew file mode 100644 index 00000000..e89961c6 --- /dev/null +++ b/atlantik/pics/hi16-app-atlantik.png diff --git a/atlantik/pics/hi32-app-atlantik.png b/atlantik/pics/hi32-app-atlantik.png Binary files differnew file mode 100644 index 00000000..daa8ec15 --- /dev/null +++ b/atlantik/pics/hi32-app-atlantik.png diff --git a/atlantik/pics/hi48-app-atlantik.png b/atlantik/pics/hi48-app-atlantik.png Binary files differnew file mode 100644 index 00000000..5a259675 --- /dev/null +++ b/atlantik/pics/hi48-app-atlantik.png diff --git a/atlantik/pics/misc/Makefile.am b/atlantik/pics/misc/Makefile.am new file mode 100644 index 00000000..9652d96c --- /dev/null +++ b/atlantik/pics/misc/Makefile.am @@ -0,0 +1,2 @@ +atlantikicondir = $(kde_datadir)/atlantik/icons +atlantikicon_ICON = AUTO diff --git a/atlantik/pics/misc/cr32-action-monop_board.png b/atlantik/pics/misc/cr32-action-monop_board.png Binary files differnew file mode 100644 index 00000000..c610aadc --- /dev/null +++ b/atlantik/pics/misc/cr32-action-monop_board.png diff --git a/atlantik/pics/toolbar/Makefile.am b/atlantik/pics/toolbar/Makefile.am new file mode 100644 index 00000000..76f0a0a7 --- /dev/null +++ b/atlantik/pics/toolbar/Makefile.am @@ -0,0 +1,2 @@ +atlantiktoolbardir = $(kde_datadir)/atlantik/icons +atlantiktoolbar_ICON = AUTO diff --git a/atlantik/pics/toolbar/cr16-action-jail_pay.png b/atlantik/pics/toolbar/cr16-action-jail_pay.png Binary files differnew file mode 100644 index 00000000..952b0ead --- /dev/null +++ b/atlantik/pics/toolbar/cr16-action-jail_pay.png diff --git a/atlantik/pics/toolbar/cr22-action-atlantik_buy_estate.png b/atlantik/pics/toolbar/cr22-action-atlantik_buy_estate.png Binary files differnew file mode 100644 index 00000000..2dec599e --- /dev/null +++ b/atlantik/pics/toolbar/cr22-action-atlantik_buy_estate.png diff --git a/atlantik/pics/toolbar/cr22-action-jail_pay.png b/atlantik/pics/toolbar/cr22-action-jail_pay.png Binary files differnew file mode 100644 index 00000000..d45caec4 --- /dev/null +++ b/atlantik/pics/toolbar/cr22-action-jail_pay.png diff --git a/atlantik/pics/toolbar/cr32-action-atlantik_buy_estate.png b/atlantik/pics/toolbar/cr32-action-atlantik_buy_estate.png Binary files differnew file mode 100644 index 00000000..e1a86e47 --- /dev/null +++ b/atlantik/pics/toolbar/cr32-action-atlantik_buy_estate.png diff --git a/atlantik/pics/toolbar/cr32-action-auction.png b/atlantik/pics/toolbar/cr32-action-auction.png Binary files differnew file mode 100644 index 00000000..0a179532 --- /dev/null +++ b/atlantik/pics/toolbar/cr32-action-auction.png diff --git a/atlantik/pics/toolbar/cr32-action-jail_pay.png b/atlantik/pics/toolbar/cr32-action-jail_pay.png Binary files differnew file mode 100644 index 00000000..915a7e46 --- /dev/null +++ b/atlantik/pics/toolbar/cr32-action-jail_pay.png diff --git a/atlantik/pics/toolbar/lo16-action-atlantik_buy_estate.png b/atlantik/pics/toolbar/lo16-action-atlantik_buy_estate.png Binary files differnew file mode 100644 index 00000000..3007a2df --- /dev/null +++ b/atlantik/pics/toolbar/lo16-action-atlantik_buy_estate.png diff --git a/atlantik/themes/Makefile.am b/atlantik/themes/Makefile.am new file mode 100644 index 00000000..dcc4764a --- /dev/null +++ b/atlantik/themes/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = default diff --git a/atlantik/themes/default/Makefile.am b/atlantik/themes/default/Makefile.am new file mode 100644 index 00000000..7890f6ec --- /dev/null +++ b/atlantik/themes/default/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = tokens diff --git a/atlantik/themes/default/tokens/Makefile.am b/atlantik/themes/default/tokens/Makefile.am new file mode 100644 index 00000000..17e38396 --- /dev/null +++ b/atlantik/themes/default/tokens/Makefile.am @@ -0,0 +1,5 @@ +icondir = $(kde_datadir)/atlantik/themes/default/tokens +icon_DATA = badge.png beachball.png bell.png bomb.png cat.png cookie.png \ + cube.png eyeball.png flag.png ghost.png globe.png hamburger.png \ + lips.png puzzle.png pyramid.png skull.png traffic_light.png \ + wizard.png diff --git a/atlantik/themes/default/tokens/badge.png b/atlantik/themes/default/tokens/badge.png Binary files differnew file mode 100644 index 00000000..e0b58dee --- /dev/null +++ b/atlantik/themes/default/tokens/badge.png diff --git a/atlantik/themes/default/tokens/beachball.png b/atlantik/themes/default/tokens/beachball.png Binary files differnew file mode 100644 index 00000000..7247b78f --- /dev/null +++ b/atlantik/themes/default/tokens/beachball.png diff --git a/atlantik/themes/default/tokens/bell.png b/atlantik/themes/default/tokens/bell.png Binary files differnew file mode 100644 index 00000000..cf5ac8c2 --- /dev/null +++ b/atlantik/themes/default/tokens/bell.png diff --git a/atlantik/themes/default/tokens/bomb.png b/atlantik/themes/default/tokens/bomb.png Binary files differnew file mode 100644 index 00000000..dfdf434c --- /dev/null +++ b/atlantik/themes/default/tokens/bomb.png diff --git a/atlantik/themes/default/tokens/cat.png b/atlantik/themes/default/tokens/cat.png Binary files differnew file mode 100644 index 00000000..78b51245 --- /dev/null +++ b/atlantik/themes/default/tokens/cat.png diff --git a/atlantik/themes/default/tokens/cookie.png b/atlantik/themes/default/tokens/cookie.png Binary files differnew file mode 100644 index 00000000..8944fa29 --- /dev/null +++ b/atlantik/themes/default/tokens/cookie.png diff --git a/atlantik/themes/default/tokens/cube.png b/atlantik/themes/default/tokens/cube.png Binary files differnew file mode 100644 index 00000000..d2487696 --- /dev/null +++ b/atlantik/themes/default/tokens/cube.png diff --git a/atlantik/themes/default/tokens/eyeball.png b/atlantik/themes/default/tokens/eyeball.png Binary files differnew file mode 100644 index 00000000..56660202 --- /dev/null +++ b/atlantik/themes/default/tokens/eyeball.png diff --git a/atlantik/themes/default/tokens/flag.png b/atlantik/themes/default/tokens/flag.png Binary files differnew file mode 100644 index 00000000..d0b1f15f --- /dev/null +++ b/atlantik/themes/default/tokens/flag.png diff --git a/atlantik/themes/default/tokens/ghost.png b/atlantik/themes/default/tokens/ghost.png Binary files differnew file mode 100644 index 00000000..03efcc2a --- /dev/null +++ b/atlantik/themes/default/tokens/ghost.png diff --git a/atlantik/themes/default/tokens/globe.png b/atlantik/themes/default/tokens/globe.png Binary files differnew file mode 100644 index 00000000..33741975 --- /dev/null +++ b/atlantik/themes/default/tokens/globe.png diff --git a/atlantik/themes/default/tokens/hamburger.png b/atlantik/themes/default/tokens/hamburger.png Binary files differnew file mode 100644 index 00000000..d994115c --- /dev/null +++ b/atlantik/themes/default/tokens/hamburger.png diff --git a/atlantik/themes/default/tokens/lips.png b/atlantik/themes/default/tokens/lips.png Binary files differnew file mode 100644 index 00000000..171fa3a1 --- /dev/null +++ b/atlantik/themes/default/tokens/lips.png diff --git a/atlantik/themes/default/tokens/puzzle.png b/atlantik/themes/default/tokens/puzzle.png Binary files differnew file mode 100644 index 00000000..7f70b8d6 --- /dev/null +++ b/atlantik/themes/default/tokens/puzzle.png diff --git a/atlantik/themes/default/tokens/pyramid.png b/atlantik/themes/default/tokens/pyramid.png Binary files differnew file mode 100644 index 00000000..e0792d20 --- /dev/null +++ b/atlantik/themes/default/tokens/pyramid.png diff --git a/atlantik/themes/default/tokens/skull.png b/atlantik/themes/default/tokens/skull.png Binary files differnew file mode 100644 index 00000000..07361122 --- /dev/null +++ b/atlantik/themes/default/tokens/skull.png diff --git a/atlantik/themes/default/tokens/traffic_light.png b/atlantik/themes/default/tokens/traffic_light.png Binary files differnew file mode 100644 index 00000000..0f2f6476 --- /dev/null +++ b/atlantik/themes/default/tokens/traffic_light.png diff --git a/atlantik/themes/default/tokens/wizard.png b/atlantik/themes/default/tokens/wizard.png Binary files differnew file mode 100644 index 00000000..c7ad6f50 --- /dev/null +++ b/atlantik/themes/default/tokens/wizard.png |