diff --git a/CHANGELOG.mkdn b/CHANGELOG.mkdn
deleted file mode 100644
index 5f2dce4..0000000
--- a/CHANGELOG.mkdn
+++ /dev/null
@@ -1,167 +0,0 @@
-Pesterchum 3.41
-===============
-
-Visit http://nova.xzibition.com/~illuminatedwax/help.html for tutorial.
-
-**Stable**: Visit https://github.com/illuminatedwax/pesterchum for git access and source code.
-
-**Bleeding Edge**: Visit https://github.com/kiooeht/pesterchum for git access and source code.
-
-**Mac**: For Mac specific git access and source code visit https://github.com/Lexicality/pesterchum.
-
-(Note: Bleeding Edge is up-to-date with all Mac specific changes.)
-
-CHANGELOG
----------
-## 3.41.4
-* Makefile for Linux installing - Kiooeht [evacipatedBox]
-* Recognize www. as link - Kiooeht [evacipatedBox]
-* Pester menu option to just pester a handle - Kiooeht [evacipatedBox]
-* Update to randomEncounter interface - Kiooeht [evacipatedBox]
-* Italics, bold, and underline - Kiooeht [evacipatedBox]
-* FTP and Magnet links - oakwhiz
-* Userlist search - oakwhiz
-* Chanserv in menus - Cerxi [binaryCabalist]
-* Lua quirks
-* Multi-select memo chooser - [alGore]
-* Auto-identify with NickServ - Kiooeht [evacipatedBox]
-* Auto-join memos - Kiooeht [evacipatedBox]
-* Bug fixes
- * Don't require pygame (it's kind of optional, you just don't get sound) - Kiooeht [evacipatedBox]
- * Allow add chum dialog to open after adding an existing chum - Kiooeht [evacipatedBox]
- * Unicode everything - ghostDunk
- * Delete groups when using online numbers - Kiooeht [evacipatedBox]
- * Add chums when using manual sorting - Kiooeht [evacipatedBox]
- * Memo case insensitive for userlist and modes - Kiooeht [evacipatedBox]
- * Move hidden chums when deleting group - Kiooeht [evacipatedBox]
- * Don't allow rename groups with parenthesis - Kiooeht [evacipatedBox]
- * Wrap long error messages - Kiooeht [evacipatedBox]
- * chdir into quirks folder for Lua quirks - [alGore]
- * Toast notifications don't require sound to be on - Kiooeht [evacipatedBox]
- * Don't close Pesterchum if a window is closed while main window minimized - Kiooeht [evacipatedBox]
-
-
-### 3.41.3
-* Add group option when adding chum - ghostDunk
-* OOC Mode - ghostDunk
-* Improve animated gifs - ghostDunk
-* Set IRC away on idle - Kiooeht [evacipatedBox]
-* Remote quirk shutoff in memos - Kiooeht [evacipatedBox]
-* Compress exit dumps into one line - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Display channel mode change message - Kiooeht [evacipatedBox]
-* Disable quirks in +c memos - Lexi [lexicalNuance]
-* Founder, admin, and halfop support - Kiooeht [evacipatedBox]
-* Button for direct access to logs directory - Kiooeht [evacipatedBox]
-* Auto-update from zip and tar - Kiooeht [evacipatedBox]
-* Minimizable memo userlist - Kiooeht [evacipatedBox] (Idea: [alGore], [lostGash])
-* Chumroll notifications on chum sign-in/out - Kiooeht [evacipatedBox]
-* Chum notes - Kiooeht [evacipatedBox]
-* Customizable name alerts - Kiooeht [evacipatedBox]
-* Update bug reporter - Kiooeht [evacipatedBox]
-* Explain why a chumhandle is invalid - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Netsplit notification in memos - Kiooeht [evacipatedBox]
-* Toast Notifications - Kiooeht [evacipatedBox]
-* Disable randomEncounter options when it's offline - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Sort list of memos alphabetically or by number of users - Kiooeht [evacipatedBox] (Idea: [lostGash])
-* Low-bandwidth mode - Kiooeht [evacipatedBox] (Idea: [canLover])
-* New smilies - Kiooeht [evacipatedBox]
-* Refresh theme in options - Kiooeht [evacipatedBox]
-* Separate tabbed/untabbed windows for conversaions and memos - Kiooeht [evacipatedBox]
-* Manually rearrange chumroll - Kiooeht [evacipatedBox] (Idea: [turntableAbbess (aka. TA of SGRILL)])
-* Using user data directory for all OSs - Kiooeht [evacipatedBox]
-* Lots more user created themes - ghostDunk
-* Bug fixes
- * Don't delete random chum when blocking someone not on chumroll - Kiooeht [evacipatedBox]
- * Openning global userlist doesn't reset OP status of memo users - Kiooeht [evacipatedBox]
- * Alt characters don't break on random replace - Kiooeht [evacipatedBox]
- * Trollian 2.5 tray icon is now Trollian icon - Kiooeht [evacipatedBox]
- * Don't screw up tags with the mispeller - Kiooeht [evacipatedBox]
- * Don't break if profile uses non-existant theme - Kiooeht [evacipatedBox]
- * Properly rearrange groups when not displaying number of online chums - Kiooeht [evacipatedBox]
-* Mac Bug fixes
- * Create all datadir stuff - Lexi [lexicalNuance]
-
-### 3.41
-* Individually turn quirks on and off - Kiooeht [evacipatedBox]
-* More canon trollian theme timeline indicators - [binaryCabalist]
-* By mood chum sorting - Kiooeht [evacipatedBox]
-* Chum groups - Kiooeht [evacipatedBox]
-* Turn logging on and off - Kiooeht [evacipatedBox]
-* Customizable idle time - Kiooeht [evacipatedBox]
-* Different sound for memos - Kiooeht [evacipatedBox]
-* Animated smilies - Kiooeht [evacipatedBox]
-* Delete profiles - Kiooeht [evacipatedBox]
-* Customize minimize and close button actions - Kiooeht [evacipatedBox]
-* Receive notices from services you're talking to - Kiooeht [evacipatedBox]
-* Automatically turn off quirks when talking to bots - Kiooeht [evacipatedBox]
-* Rearrange options menu, make tabbed - Kiooeht [evacipatedBox]
-* Rearrange memos window for readability - Kiooeht [evacipatedBox]
-* Give voice to memo users - Kiooeht [evacipatedBox]
-* Theme checking - Kiooeht [evacipatedBox]
-* Display (De)OP/Voice messages in memos - Kiooeht [evacipatedBox]
-* Advanced Mode: Alter IRC user mode - Kiooeht [evacipatedBox]
-* Logviewer chum search - Kiooeht [evacipatedBox]
-* Logviewer log search - Kiooeht [evacipatedBox]
-* Set server and port from command line - Kiooeht [evacipatedBox]
-* Invite-only memos, invite chums to memos - Kiooeht [evacipatedBox]
-* Check Pyqt4 and pygame are installed and correct versions - Kiooeht [evacipatedBox]
-* Advanced Mode: View memo (channel) modes - Kiooeht [evacipatedBox]
-* Quirk groups - Kiooeht [evacipatedBox]
-* CTCP Version reply - Kiooeht [evacipatedBox]
-* Check for Pesterchum updates - Kiooeht [evacipatedBox]
-* Memo OP options: Secret, Invite-only, Mute - Kiooeht [evacipatedBox]
-* Notify user if channel blocks message - Kiooeht [evacipatedBox]
-* Bug reporter - Kiooeht [evacipatedBox]
-* Python quirks (users can create own quirk functions) - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Incorporate support for the new randomEncounter - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Only GETMOOD for people online (less spam!) - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Quirk tester in quirk window - Kiooeht [evacipatedBox] (Idea: [alGore])
-* Show and support giving kick reasons - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Make adding quirks into multi-page wizard - Kiooeht [evacipatedBox]
-* Flash the taskbar on new messages - Kiooeht [evacipatedBox]
-* Third beep sound for when your initials are mentioned in memos - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* Ctrl + click to copy links - Kiooeht [evacipatedBox]
-* Say something when server is full - Kiooeht [evacipatedBox]
-* Ping server if no ping from server to test connection - Kiooeht [evacipatedBox] (Idea: Lexi [lexicalNuance])
-* MSPA comic update notifier - Kiooeht [evacipatedBox]
-* Volume control - Kiooeht [evacipatedBox]
-* Debug mode - illuminatedwax [ghostDunk]
-* Bug fixes
- * Logviewer updates - Kiooeht [evacipatedBox]
- * Memo scrollbar thing - Kiooeht [evacipatedBox]
- * Time arrows in enamel - Kiooeht [evacipatedBox]
- * Quirk order actually works - Kiooeht [evacipatedBox]
- * Stay in memos on profile switch - Kiooeht [evacipatedBox]
- * Auto rejoin memos on reconnect - Kiooeht [evacipatedBox]
- * De-Op in memos correctly - Kiooeht [evacipatedBox]
- * Don't blow up if someone's not using Pesterchum in a memo - Kiooeht [evacipatedBox]
- * Make 'logs' and 'profiles' directories if non-existant - Kiooeht [evacipatedBox]
- * Don't split messages in bad places - Kiooeht [evacipatedBox]
- * Chumhandles must match EXACTLY to register mood changes - Kiooeht [evacipatedBox]
- * Menu bar text colour correct when default system colour isn't black - Kiooeht [evacipatedBox]
- * End all colour tags and restart them on split messages - Kiooeht [evacipatedBox]
- * Chat input box right-click menus - Kiooeht [evacipatedBox]
- * Don't overflow random colours into colourless messages - Kiooeht [evacipatedBox]
- * Only open links on left click - Kiooeht [evacipatedBox]
-
-### 3.14.1
-* Pesterchum 3.14 - illuminatedwax [ghostDunk]
-* Art - Grimlive [aquaMarinist]
-* Quirks lower() function - Kiooeht [evacipatedBox]
-* Quirks scrabble() function - Kiooeht [evacipatedBox]
-* Quirks reverse() function - illuminatedwax [ghostDunk]
-* Timestamps - Kiooeht [evacipatedBox]
-* Logviewer - Kiooeht [evacipatedBox]
-* Quirk ordering - [alGore]
-* # of users in a memo - [alGore]
-* @links to users - illuminatedwax [ghostDunk]
-* Support for REPORT and ALT to calSprite built in - illuminatedwax [ghostDunk]
-* Bug fixes:
- * mixer bug fixed
- * "flags" bug fixed
- * incorrect characters in memos no longer break log file names
- * memos now do not break on case-sensitivity
- * fixed QDB address
- * now lines too long to send in a single message are split up correctly
- * quirk replace bug fixed
- * pesterClientXXX profiles no longer saved
diff --git a/INSTALL b/INSTALL
deleted file mode 100644
index 7a4ed15..0000000
--- a/INSTALL
+++ /dev/null
@@ -1,28 +0,0 @@
-There is no installing.
-
-Basically this is a mishmosh of source code that will run by invoking:
-
-python pesterchum.py
-
-You will need these libraries:
-PyQt >= 4.6 (implies Qt 4.6!)
-pygame
-
-The setup files are all broken. If you are building on Mac, Archaemic
-has been kind enough to give us a head start in the setup-py2app.py
-and py2app.sh files. Check out the MACBUILD file for his comments.
-
-If you are building on Windows, the setup.py file has some
-commented-out lines that should give you a clue as to what you need to
-do. Talk to me if you reeeeally want to build on Windows.
-
-On Linux, you need to have the PyQt4 and pygame libraries installed:
-
-Debian: apt-get install python-qt4 python-pgame
-Arch: pacman -S pyqt4 python-pygame
-
-then run ./pesterchum (basically a shell script that runs python pesterchum.py)
-
-The point of all this is that the only person besides myself that I
-expect to create builds are the awesome people that volunteer to help
-me build on a Mac.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 4f0c389..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,687 +0,0 @@
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-
- Copyright (C)
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see .
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- Copyright (C)
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-.
diff --git a/MacBuild/GPL.res b/MacBuild/GPL.res
deleted file mode 100644
index 447c37b..0000000
--- a/MacBuild/GPL.res
+++ /dev/null
@@ -1,1151 +0,0 @@
-data 'STR#' (5000, "English") {
- $"0006 0745 6E67 6C69 7368 0541 6772 6565" /* ...English.Agree */
- $"0844 6973 6167 7265 6505 5072 696E 7407" /* .Disagree.Print. */
- $"5361 7665 2E2E 2E79 4966 2079 6F75 2061" /* Save...yIf you a */
- $"6772 6565 2077 6974 6820 7468 6520 7465" /* gree with the te */
- $"726D 7320 6F66 2074 6869 7320 6C69 6365" /* rms of this lice */
- $"6E73 652C 2063 6C69 636B 2022 4167 7265" /* nse, click "Agre */
- $"6522 2074 6F20 6163 6365 7373 2074 6865" /* e" to access the */
- $"2073 6F66 7477 6172 652E 2049 6620 796F" /* software. If yo */
- $"7520 646F 206E 6F74 2061 6772 6565 2C20" /* u do not agree, */
- $"7072 6573 7320 2244 6973 6167 7265 6522" /* press "Disagree" */
- $"2E" /* . */
-};
-
-data 'TEXT' (5000, "English") {
- $"0909 2020 2020 474E 5520 4745 4E45 5241" /* ÆÆ GNU GENERA */
- $"4C20 5055 424C 4943 204C 4943 454E 5345" /* L PUBLIC LICENSE */
- $"0D09 0920 2020 2020 2020 5665 7273 696F" /* .ÆÆ Versio */
- $"6E20 322C 204A 756E 6520 3139 3931 0D0D" /* n 2, June 1991.. */
- $"2043 6F70 7972 6967 6874 2028 4329 2031" /* Copyright (C) 1 */
- $"3938 392C 2031 3939 3120 4672 6565 2053" /* 989, 1991 Free S */
- $"6F66 7477 6172 6520 466F 756E 6461 7469" /* oftware Foundati */
- $"6F6E 2C20 496E 632E 0D20 2020 2020 2020" /* on, Inc.. */
- $"2020 2020 2020 2020 2020 2020 2020 2020" /* */
- $"3539 2054 656D 706C 6520 506C 6163 652C" /* 59 Temple Place, */
- $"2053 7569 7465 2033 3330 2C20 426F 7374" /* Suite 330, Bost */
- $"6F6E 2C20 4D41 2020 3032 3131 312D 3133" /* on, MA 02111-13 */
- $"3037 2020 5553 410D 2045 7665 7279 6F6E" /* 07 USA. Everyon */
- $"6520 6973 2070 6572 6D69 7474 6564 2074" /* e is permitted t */
- $"6F20 636F 7079 2061 6E64 2064 6973 7472" /* o copy and distr */
- $"6962 7574 6520 7665 7262 6174 696D 2063" /* ibute verbatim c */
- $"6F70 6965 730D 206F 6620 7468 6973 206C" /* opies. of this l */
- $"6963 656E 7365 2064 6F63 756D 656E 742C" /* icense document, */
- $"2062 7574 2063 6861 6E67 696E 6720 6974" /* but changing it */
- $"2069 7320 6E6F 7420 616C 6C6F 7765 642E" /* is not allowed. */
- $"0D0D 0909 0920 2020 2050 7265 616D 626C" /* ..ÆÆÆ Preambl */
- $"650D 0D20 2054 6865 206C 6963 656E 7365" /* e.. The license */
- $"7320 666F 7220 6D6F 7374 2073 6F66 7477" /* s for most softw */
- $"6172 6520 6172 6520 6465 7369 676E 6564" /* are are designed */
- $"2074 6F20 7461 6B65 2061 7761 7920 796F" /* to take away yo */
- $"7572 0D66 7265 6564 6F6D 2074 6F20 7368" /* ur.freedom to sh */
- $"6172 6520 616E 6420 6368 616E 6765 2069" /* are and change i */
- $"742E 2020 4279 2063 6F6E 7472 6173 742C" /* t. By contrast, */
- $"2074 6865 2047 4E55 2047 656E 6572 616C" /* the GNU General */
- $"2050 7562 6C69 630D 4C69 6365 6E73 6520" /* Public.License */
- $"6973 2069 6E74 656E 6465 6420 746F 2067" /* is intended to g */
- $"7561 7261 6E74 6565 2079 6F75 7220 6672" /* uarantee your fr */
- $"6565 646F 6D20 746F 2073 6861 7265 2061" /* eedom to share a */
- $"6E64 2063 6861 6E67 6520 6672 6565 0D73" /* nd change free.s */
- $"6F66 7477 6172 652D 2D74 6F20 6D61 6B65" /* oftware--to make */
- $"2073 7572 6520 7468 6520 736F 6674 7761" /* sure the softwa */
- $"7265 2069 7320 6672 6565 2066 6F72 2061" /* re is free for a */
- $"6C6C 2069 7473 2075 7365 7273 2E20 2054" /* ll its users. T */
- $"6869 730D 4765 6E65 7261 6C20 5075 626C" /* his.General Publ */
- $"6963 204C 6963 656E 7365 2061 7070 6C69" /* ic License appli */
- $"6573 2074 6F20 6D6F 7374 206F 6620 7468" /* es to most of th */
- $"6520 4672 6565 2053 6F66 7477 6172 650D" /* e Free Software. */
- $"466F 756E 6461 7469 6F6E 2773 2073 6F66" /* Foundation's sof */
- $"7477 6172 6520 616E 6420 746F 2061 6E79" /* tware and to any */
- $"206F 7468 6572 2070 726F 6772 616D 2077" /* other program w */
- $"686F 7365 2061 7574 686F 7273 2063 6F6D" /* hose authors com */
- $"6D69 7420 746F 0D75 7369 6E67 2069 742E" /* mit to.using it. */
- $"2020 2853 6F6D 6520 6F74 6865 7220 4672" /* (Some other Fr */
- $"6565 2053 6F66 7477 6172 6520 466F 756E" /* ee Software Foun */
- $"6461 7469 6F6E 2073 6F66 7477 6172 6520" /* dation software */
- $"6973 2063 6F76 6572 6564 2062 790D 7468" /* is covered by.th */
- $"6520 474E 5520 4C69 6272 6172 7920 4765" /* e GNU Library Ge */
- $"6E65 7261 6C20 5075 626C 6963 204C 6963" /* neral Public Lic */
- $"656E 7365 2069 6E73 7465 6164 2E29 2020" /* ense instead.) */
- $"596F 7520 6361 6E20 6170 706C 7920 6974" /* You can apply it */
- $"2074 6F0D 796F 7572 2070 726F 6772 616D" /* to.your program */
- $"732C 2074 6F6F 2E0D 0D20 2057 6865 6E20" /* s, too... When */
- $"7765 2073 7065 616B 206F 6620 6672 6565" /* we speak of free */
- $"2073 6F66 7477 6172 652C 2077 6520 6172" /* software, we ar */
- $"6520 7265 6665 7272 696E 6720 746F 2066" /* e referring to f */
- $"7265 6564 6F6D 2C20 6E6F 740D 7072 6963" /* reedom, not.pric */
- $"652E 2020 4F75 7220 4765 6E65 7261 6C20" /* e. Our General */
- $"5075 626C 6963 204C 6963 656E 7365 7320" /* Public Licenses */
- $"6172 6520 6465 7369 676E 6564 2074 6F20" /* are designed to */
- $"6D61 6B65 2073 7572 6520 7468 6174 2079" /* make sure that y */
- $"6F75 0D68 6176 6520 7468 6520 6672 6565" /* ou.have the free */
- $"646F 6D20 746F 2064 6973 7472 6962 7574" /* dom to distribut */
- $"6520 636F 7069 6573 206F 6620 6672 6565" /* e copies of free */
- $"2073 6F66 7477 6172 6520 2861 6E64 2063" /* software (and c */
- $"6861 7267 6520 666F 720D 7468 6973 2073" /* harge for.this s */
- $"6572 7669 6365 2069 6620 796F 7520 7769" /* ervice if you wi */
- $"7368 292C 2074 6861 7420 796F 7520 7265" /* sh), that you re */
- $"6365 6976 6520 736F 7572 6365 2063 6F64" /* ceive source cod */
- $"6520 6F72 2063 616E 2067 6574 2069 740D" /* e or can get it. */
- $"6966 2079 6F75 2077 616E 7420 6974 2C20" /* if you want it, */
- $"7468 6174 2079 6F75 2063 616E 2063 6861" /* that you can cha */
- $"6E67 6520 7468 6520 736F 6674 7761 7265" /* nge the software */
- $"206F 7220 7573 6520 7069 6563 6573 206F" /* or use pieces o */
- $"6620 6974 0D69 6E20 6E65 7720 6672 6565" /* f it.in new free */
- $"2070 726F 6772 616D 733B 2061 6E64 2074" /* programs; and t */
- $"6861 7420 796F 7520 6B6E 6F77 2079 6F75" /* hat you know you */
- $"2063 616E 2064 6F20 7468 6573 6520 7468" /* can do these th */
- $"696E 6773 2E0D 0D20 2054 6F20 7072 6F74" /* ings... To prot */
- $"6563 7420 796F 7572 2072 6967 6874 732C" /* ect your rights, */
- $"2077 6520 6E65 6564 2074 6F20 6D61 6B65" /* we need to make */
- $"2072 6573 7472 6963 7469 6F6E 7320 7468" /* restrictions th */
- $"6174 2066 6F72 6269 640D 616E 796F 6E65" /* at forbid.anyone */
- $"2074 6F20 6465 6E79 2079 6F75 2074 6865" /* to deny you the */
- $"7365 2072 6967 6874 7320 6F72 2074 6F20" /* se rights or to */
- $"6173 6B20 796F 7520 746F 2073 7572 7265" /* ask you to surre */
- $"6E64 6572 2074 6865 2072 6967 6874 732E" /* nder the rights. */
- $"0D54 6865 7365 2072 6573 7472 6963 7469" /* .These restricti */
- $"6F6E 7320 7472 616E 736C 6174 6520 746F" /* ons translate to */
- $"2063 6572 7461 696E 2072 6573 706F 6E73" /* certain respons */
- $"6962 696C 6974 6965 7320 666F 7220 796F" /* ibilities for yo */
- $"7520 6966 2079 6F75 0D64 6973 7472 6962" /* u if you.distrib */
- $"7574 6520 636F 7069 6573 206F 6620 7468" /* ute copies of th */
- $"6520 736F 6674 7761 7265 2C20 6F72 2069" /* e software, or i */
- $"6620 796F 7520 6D6F 6469 6679 2069 742E" /* f you modify it. */
- $"0D0D 2020 466F 7220 6578 616D 706C 652C" /* .. For example, */
- $"2069 6620 796F 7520 6469 7374 7269 6275" /* if you distribu */
- $"7465 2063 6F70 6965 7320 6F66 2073 7563" /* te copies of suc */
- $"6820 6120 7072 6F67 7261 6D2C 2077 6865" /* h a program, whe */
- $"7468 6572 0D67 7261 7469 7320 6F72 2066" /* ther.gratis or f */
- $"6F72 2061 2066 6565 2C20 796F 7520 6D75" /* or a fee, you mu */
- $"7374 2067 6976 6520 7468 6520 7265 6369" /* st give the reci */
- $"7069 656E 7473 2061 6C6C 2074 6865 2072" /* pients all the r */
- $"6967 6874 7320 7468 6174 0D79 6F75 2068" /* ights that.you h */
- $"6176 652E 2020 596F 7520 6D75 7374 206D" /* ave. You must m */
- $"616B 6520 7375 7265 2074 6861 7420 7468" /* ake sure that th */
- $"6579 2C20 746F 6F2C 2072 6563 6569 7665" /* ey, too, receive */
- $"206F 7220 6361 6E20 6765 7420 7468 650D" /* or can get the. */
- $"736F 7572 6365 2063 6F64 652E 2020 416E" /* source code. An */
- $"6420 796F 7520 6D75 7374 2073 686F 7720" /* d you must show */
- $"7468 656D 2074 6865 7365 2074 6572 6D73" /* them these terms */
- $"2073 6F20 7468 6579 206B 6E6F 7720 7468" /* so they know th */
- $"6569 720D 7269 6768 7473 2E0D 0D20 2057" /* eir.rights... W */
- $"6520 7072 6F74 6563 7420 796F 7572 2072" /* e protect your r */
- $"6967 6874 7320 7769 7468 2074 776F 2073" /* ights with two s */
- $"7465 7073 3A20 2831 2920 636F 7079 7269" /* teps: (1) copyri */
- $"6768 7420 7468 6520 736F 6674 7761 7265" /* ght the software */
- $"2C20 616E 640D 2832 2920 6F66 6665 7220" /* , and.(2) offer */
- $"796F 7520 7468 6973 206C 6963 656E 7365" /* you this license */
- $"2077 6869 6368 2067 6976 6573 2079 6F75" /* which gives you */
- $"206C 6567 616C 2070 6572 6D69 7373 696F" /* legal permissio */
- $"6E20 746F 2063 6F70 792C 0D64 6973 7472" /* n to copy,.distr */
- $"6962 7574 6520 616E 642F 6F72 206D 6F64" /* ibute and/or mod */
- $"6966 7920 7468 6520 736F 6674 7761 7265" /* ify the software */
- $"2E0D 0D20 2041 6C73 6F2C 2066 6F72 2065" /* ... Also, for e */
- $"6163 6820 6175 7468 6F72 2773 2070 726F" /* ach author's pro */
- $"7465 6374 696F 6E20 616E 6420 6F75 7273" /* tection and ours */
- $"2C20 7765 2077 616E 7420 746F 206D 616B" /* , we want to mak */
- $"6520 6365 7274 6169 6E0D 7468 6174 2065" /* e certain.that e */
- $"7665 7279 6F6E 6520 756E 6465 7273 7461" /* veryone understa */
- $"6E64 7320 7468 6174 2074 6865 7265 2069" /* nds that there i */
- $"7320 6E6F 2077 6172 7261 6E74 7920 666F" /* s no warranty fo */
- $"7220 7468 6973 2066 7265 650D 736F 6674" /* r this free.soft */
- $"7761 7265 2E20 2049 6620 7468 6520 736F" /* ware. If the so */
- $"6674 7761 7265 2069 7320 6D6F 6469 6669" /* ftware is modifi */
- $"6564 2062 7920 736F 6D65 6F6E 6520 656C" /* ed by someone el */
- $"7365 2061 6E64 2070 6173 7365 6420 6F6E" /* se and passed on */
- $"2C20 7765 0D77 616E 7420 6974 7320 7265" /* , we.want its re */
- $"6369 7069 656E 7473 2074 6F20 6B6E 6F77" /* cipients to know */
- $"2074 6861 7420 7768 6174 2074 6865 7920" /* that what they */
- $"6861 7665 2069 7320 6E6F 7420 7468 6520" /* have is not the */
- $"6F72 6967 696E 616C 2C20 736F 0D74 6861" /* original, so.tha */
- $"7420 616E 7920 7072 6F62 6C65 6D73 2069" /* t any problems i */
- $"6E74 726F 6475 6365 6420 6279 206F 7468" /* ntroduced by oth */
- $"6572 7320 7769 6C6C 206E 6F74 2072 6566" /* ers will not ref */
- $"6C65 6374 206F 6E20 7468 6520 6F72 6967" /* lect on the orig */
- $"696E 616C 0D61 7574 686F 7273 2720 7265" /* inal.authors' re */
- $"7075 7461 7469 6F6E 732E 0D0D 2020 4669" /* putations... Fi */
- $"6E61 6C6C 792C 2061 6E79 2066 7265 6520" /* nally, any free */
- $"7072 6F67 7261 6D20 6973 2074 6872 6561" /* program is threa */
- $"7465 6E65 6420 636F 6E73 7461 6E74 6C79" /* tened constantly */
- $"2062 7920 736F 6674 7761 7265 0D70 6174" /* by software.pat */
- $"656E 7473 2E20 2057 6520 7769 7368 2074" /* ents. We wish t */
- $"6F20 6176 6F69 6420 7468 6520 6461 6E67" /* o avoid the dang */
- $"6572 2074 6861 7420 7265 6469 7374 7269" /* er that redistri */
- $"6275 746F 7273 206F 6620 6120 6672 6565" /* butors of a free */
- $"0D70 726F 6772 616D 2077 696C 6C20 696E" /* .program will in */
- $"6469 7669 6475 616C 6C79 206F 6274 6169" /* dividually obtai */
- $"6E20 7061 7465 6E74 206C 6963 656E 7365" /* n patent license */
- $"732C 2069 6E20 6566 6665 6374 206D 616B" /* s, in effect mak */
- $"696E 6720 7468 650D 7072 6F67 7261 6D20" /* ing the.program */
- $"7072 6F70 7269 6574 6172 792E 2020 546F" /* proprietary. To */
- $"2070 7265 7665 6E74 2074 6869 732C 2077" /* prevent this, w */
- $"6520 6861 7665 206D 6164 6520 6974 2063" /* e have made it c */
- $"6C65 6172 2074 6861 7420 616E 790D 7061" /* lear that any.pa */
- $"7465 6E74 206D 7573 7420 6265 206C 6963" /* tent must be lic */
- $"656E 7365 6420 666F 7220 6576 6572 796F" /* ensed for everyo */
- $"6E65 2773 2066 7265 6520 7573 6520 6F72" /* ne's free use or */
- $"206E 6F74 206C 6963 656E 7365 6420 6174" /* not licensed at */
- $"2061 6C6C 2E0D 0D20 2054 6865 2070 7265" /* all... The pre */
- $"6369 7365 2074 6572 6D73 2061 6E64 2063" /* cise terms and c */
- $"6F6E 6469 7469 6F6E 7320 666F 7220 636F" /* onditions for co */
- $"7079 696E 672C 2064 6973 7472 6962 7574" /* pying, distribut */
- $"696F 6E20 616E 640D 6D6F 6469 6669 6361" /* ion and.modifica */
- $"7469 6F6E 2066 6F6C 6C6F 772E 0D0C 0D09" /* tion follow....Æ */
- $"0920 2020 2047 4E55 2047 454E 4552 414C" /* Æ GNU GENERAL */
- $"2050 5542 4C49 4320 4C49 4345 4E53 450D" /* PUBLIC LICENSE. */
- $"2020 2054 4552 4D53 2041 4E44 2043 4F4E" /* TERMS AND CON */
- $"4449 5449 4F4E 5320 464F 5220 434F 5059" /* DITIONS FOR COPY */
- $"494E 472C 2044 4953 5452 4942 5554 494F" /* ING, DISTRIBUTIO */
- $"4E20 414E 4420 4D4F 4449 4649 4341 5449" /* N AND MODIFICATI */
- $"4F4E 0D0D 2020 302E 2054 6869 7320 4C69" /* ON.. 0. This Li */
- $"6365 6E73 6520 6170 706C 6965 7320 746F" /* cense applies to */
- $"2061 6E79 2070 726F 6772 616D 206F 7220" /* any program or */
- $"6F74 6865 7220 776F 726B 2077 6869 6368" /* other work which */
- $"2063 6F6E 7461 696E 730D 6120 6E6F 7469" /* contains.a noti */
- $"6365 2070 6C61 6365 6420 6279 2074 6865" /* ce placed by the */
- $"2063 6F70 7972 6967 6874 2068 6F6C 6465" /* copyright holde */
- $"7220 7361 7969 6E67 2069 7420 6D61 7920" /* r saying it may */
- $"6265 2064 6973 7472 6962 7574 6564 0D75" /* be distributed.u */
- $"6E64 6572 2074 6865 2074 6572 6D73 206F" /* nder the terms o */
- $"6620 7468 6973 2047 656E 6572 616C 2050" /* f this General P */
- $"7562 6C69 6320 4C69 6365 6E73 652E 2020" /* ublic License. */
- $"5468 6520 2250 726F 6772 616D 222C 2062" /* The "Program", b */
- $"656C 6F77 2C0D 7265 6665 7273 2074 6F20" /* elow,.refers to */
- $"616E 7920 7375 6368 2070 726F 6772 616D" /* any such program */
- $"206F 7220 776F 726B 2C20 616E 6420 6120" /* or work, and a */
- $"2277 6F72 6B20 6261 7365 6420 6F6E 2074" /* "work based on t */
- $"6865 2050 726F 6772 616D 220D 6D65 616E" /* he Program".mean */
- $"7320 6569 7468 6572 2074 6865 2050 726F" /* s either the Pro */
- $"6772 616D 206F 7220 616E 7920 6465 7269" /* gram or any deri */
- $"7661 7469 7665 2077 6F72 6B20 756E 6465" /* vative work unde */
- $"7220 636F 7079 7269 6768 7420 6C61 773A" /* r copyright law: */
- $"0D74 6861 7420 6973 2074 6F20 7361 792C" /* .that is to say, */
- $"2061 2077 6F72 6B20 636F 6E74 6169 6E69" /* a work containi */
- $"6E67 2074 6865 2050 726F 6772 616D 206F" /* ng the Program o */
- $"7220 6120 706F 7274 696F 6E20 6F66 2069" /* r a portion of i */
- $"742C 0D65 6974 6865 7220 7665 7262 6174" /* t,.either verbat */
- $"696D 206F 7220 7769 7468 206D 6F64 6966" /* im or with modif */
- $"6963 6174 696F 6E73 2061 6E64 2F6F 7220" /* ications and/or */
- $"7472 616E 736C 6174 6564 2069 6E74 6F20" /* translated into */
- $"616E 6F74 6865 720D 6C61 6E67 7561 6765" /* another.language */
- $"2E20 2028 4865 7265 696E 6166 7465 722C" /* . (Hereinafter, */
- $"2074 7261 6E73 6C61 7469 6F6E 2069 7320" /* translation is */
- $"696E 636C 7564 6564 2077 6974 686F 7574" /* included without */
- $"206C 696D 6974 6174 696F 6E20 696E 0D74" /* limitation in.t */
- $"6865 2074 6572 6D20 226D 6F64 6966 6963" /* he term "modific */
- $"6174 696F 6E22 2E29 2020 4561 6368 206C" /* ation".) Each l */
- $"6963 656E 7365 6520 6973 2061 6464 7265" /* icensee is addre */
- $"7373 6564 2061 7320 2279 6F75 222E 0D0D" /* ssed as "you"... */
- $"4163 7469 7669 7469 6573 206F 7468 6572" /* Activities other */
- $"2074 6861 6E20 636F 7079 696E 672C 2064" /* than copying, d */
- $"6973 7472 6962 7574 696F 6E20 616E 6420" /* istribution and */
- $"6D6F 6469 6669 6361 7469 6F6E 2061 7265" /* modification are */
- $"206E 6F74 0D63 6F76 6572 6564 2062 7920" /* not.covered by */
- $"7468 6973 204C 6963 656E 7365 3B20 7468" /* this License; th */
- $"6579 2061 7265 206F 7574 7369 6465 2069" /* ey are outside i */
- $"7473 2073 636F 7065 2E20 2054 6865 2061" /* ts scope. The a */
- $"6374 206F 660D 7275 6E6E 696E 6720 7468" /* ct of.running th */
- $"6520 5072 6F67 7261 6D20 6973 206E 6F74" /* e Program is not */
- $"2072 6573 7472 6963 7465 642C 2061 6E64" /* restricted, and */
- $"2074 6865 206F 7574 7075 7420 6672 6F6D" /* the output from */
- $"2074 6865 2050 726F 6772 616D 0D69 7320" /* the Program.is */
- $"636F 7665 7265 6420 6F6E 6C79 2069 6620" /* covered only if */
- $"6974 7320 636F 6E74 656E 7473 2063 6F6E" /* its contents con */
- $"7374 6974 7574 6520 6120 776F 726B 2062" /* stitute a work b */
- $"6173 6564 206F 6E20 7468 650D 5072 6F67" /* ased on the.Prog */
- $"7261 6D20 2869 6E64 6570 656E 6465 6E74" /* ram (independent */
- $"206F 6620 6861 7669 6E67 2062 6565 6E20" /* of having been */
- $"6D61 6465 2062 7920 7275 6E6E 696E 6720" /* made by running */
- $"7468 6520 5072 6F67 7261 6D29 2E0D 5768" /* the Program)..Wh */
- $"6574 6865 7220 7468 6174 2069 7320 7472" /* ether that is tr */
- $"7565 2064 6570 656E 6473 206F 6E20 7768" /* ue depends on wh */
- $"6174 2074 6865 2050 726F 6772 616D 2064" /* at the Program d */
- $"6F65 732E 0D0D 2020 312E 2059 6F75 206D" /* oes... 1. You m */
- $"6179 2063 6F70 7920 616E 6420 6469 7374" /* ay copy and dist */
- $"7269 6275 7465 2076 6572 6261 7469 6D20" /* ribute verbatim */
- $"636F 7069 6573 206F 6620 7468 6520 5072" /* copies of the Pr */
- $"6F67 7261 6D27 730D 736F 7572 6365 2063" /* ogram's.source c */
- $"6F64 6520 6173 2079 6F75 2072 6563 6569" /* ode as you recei */
- $"7665 2069 742C 2069 6E20 616E 7920 6D65" /* ve it, in any me */
- $"6469 756D 2C20 7072 6F76 6964 6564 2074" /* dium, provided t */
- $"6861 7420 796F 750D 636F 6E73 7069 6375" /* hat you.conspicu */
- $"6F75 736C 7920 616E 6420 6170 7072 6F70" /* ously and approp */
- $"7269 6174 656C 7920 7075 626C 6973 6820" /* riately publish */
- $"6F6E 2065 6163 6820 636F 7079 2061 6E20" /* on each copy an */
- $"6170 7072 6F70 7269 6174 650D 636F 7079" /* appropriate.copy */
- $"7269 6768 7420 6E6F 7469 6365 2061 6E64" /* right notice and */
- $"2064 6973 636C 6169 6D65 7220 6F66 2077" /* disclaimer of w */
- $"6172 7261 6E74 793B 206B 6565 7020 696E" /* arranty; keep in */
- $"7461 6374 2061 6C6C 2074 6865 0D6E 6F74" /* tact all the.not */
- $"6963 6573 2074 6861 7420 7265 6665 7220" /* ices that refer */
- $"746F 2074 6869 7320 4C69 6365 6E73 6520" /* to this License */
- $"616E 6420 746F 2074 6865 2061 6273 656E" /* and to the absen */
- $"6365 206F 6620 616E 7920 7761 7272 616E" /* ce of any warran */
- $"7479 3B0D 616E 6420 6769 7665 2061 6E79" /* ty;.and give any */
- $"206F 7468 6572 2072 6563 6970 6965 6E74" /* other recipient */
- $"7320 6F66 2074 6865 2050 726F 6772 616D" /* s of the Program */
- $"2061 2063 6F70 7920 6F66 2074 6869 7320" /* a copy of this */
- $"4C69 6365 6E73 650D 616C 6F6E 6720 7769" /* License.along wi */
- $"7468 2074 6865 2050 726F 6772 616D 2E0D" /* th the Program.. */
- $"0D59 6F75 206D 6179 2063 6861 7267 6520" /* .You may charge */
- $"6120 6665 6520 666F 7220 7468 6520 7068" /* a fee for the ph */
- $"7973 6963 616C 2061 6374 206F 6620 7472" /* ysical act of tr */
- $"616E 7366 6572 7269 6E67 2061 2063 6F70" /* ansferring a cop */
- $"792C 2061 6E64 0D79 6F75 206D 6179 2061" /* y, and.you may a */
- $"7420 796F 7572 206F 7074 696F 6E20 6F66" /* t your option of */
- $"6665 7220 7761 7272 616E 7479 2070 726F" /* fer warranty pro */
- $"7465 6374 696F 6E20 696E 2065 7863 6861" /* tection in excha */
- $"6E67 6520 666F 7220 6120 6665 652E 0D0D" /* nge for a fee... */
- $"2020 322E 2059 6F75 206D 6179 206D 6F64" /* 2. You may mod */
- $"6966 7920 796F 7572 2063 6F70 7920 6F72" /* ify your copy or */
- $"2063 6F70 6965 7320 6F66 2074 6865 2050" /* copies of the P */
- $"726F 6772 616D 206F 7220 616E 7920 706F" /* rogram or any po */
- $"7274 696F 6E0D 6F66 2069 742C 2074 6875" /* rtion.of it, thu */
- $"7320 666F 726D 696E 6720 6120 776F 726B" /* s forming a work */
- $"2062 6173 6564 206F 6E20 7468 6520 5072" /* based on the Pr */
- $"6F67 7261 6D2C 2061 6E64 2063 6F70 7920" /* ogram, and copy */
- $"616E 640D 6469 7374 7269 6275 7465 2073" /* and.distribute s */
- $"7563 6820 6D6F 6469 6669 6361 7469 6F6E" /* uch modification */
- $"7320 6F72 2077 6F72 6B20 756E 6465 7220" /* s or work under */
- $"7468 6520 7465 726D 7320 6F66 2053 6563" /* the terms of Sec */
- $"7469 6F6E 2031 0D61 626F 7665 2C20 7072" /* tion 1.above, pr */
- $"6F76 6964 6564 2074 6861 7420 796F 7520" /* ovided that you */
- $"616C 736F 206D 6565 7420 616C 6C20 6F66" /* also meet all of */
- $"2074 6865 7365 2063 6F6E 6469 7469 6F6E" /* these condition */
- $"733A 0D0D 2020 2020 6129 2059 6F75 206D" /* s:.. a) You m */
- $"7573 7420 6361 7573 6520 7468 6520 6D6F" /* ust cause the mo */
- $"6469 6669 6564 2066 696C 6573 2074 6F20" /* dified files to */
- $"6361 7272 7920 7072 6F6D 696E 656E 7420" /* carry prominent */
- $"6E6F 7469 6365 730D 2020 2020 7374 6174" /* notices. stat */
- $"696E 6720 7468 6174 2079 6F75 2063 6861" /* ing that you cha */
- $"6E67 6564 2074 6865 2066 696C 6573 2061" /* nged the files a */
- $"6E64 2074 6865 2064 6174 6520 6F66 2061" /* nd the date of a */
- $"6E79 2063 6861 6E67 652E 0D0D 2020 2020" /* ny change... */
- $"6229 2059 6F75 206D 7573 7420 6361 7573" /* b) You must caus */
- $"6520 616E 7920 776F 726B 2074 6861 7420" /* e any work that */
- $"796F 7520 6469 7374 7269 6275 7465 206F" /* you distribute o */
- $"7220 7075 626C 6973 682C 2074 6861 7420" /* r publish, that */
- $"696E 0D20 2020 2077 686F 6C65 206F 7220" /* in. whole or */
- $"696E 2070 6172 7420 636F 6E74 6169 6E73" /* in part contains */
- $"206F 7220 6973 2064 6572 6976 6564 2066" /* or is derived f */
- $"726F 6D20 7468 6520 5072 6F67 7261 6D20" /* rom the Program */
- $"6F72 2061 6E79 0D20 2020 2070 6172 7420" /* or any. part */
- $"7468 6572 656F 662C 2074 6F20 6265 206C" /* thereof, to be l */
- $"6963 656E 7365 6420 6173 2061 2077 686F" /* icensed as a who */
- $"6C65 2061 7420 6E6F 2063 6861 7267 6520" /* le at no charge */
- $"746F 2061 6C6C 2074 6869 7264 0D20 2020" /* to all third. */
- $"2070 6172 7469 6573 2075 6E64 6572 2074" /* parties under t */
- $"6865 2074 6572 6D73 206F 6620 7468 6973" /* he terms of this */
- $"204C 6963 656E 7365 2E0D 0D20 2020 2063" /* License... c */
- $"2920 4966 2074 6865 206D 6F64 6966 6965" /* ) If the modifie */
- $"6420 7072 6F67 7261 6D20 6E6F 726D 616C" /* d program normal */
- $"6C79 2072 6561 6473 2063 6F6D 6D61 6E64" /* ly reads command */
- $"7320 696E 7465 7261 6374 6976 656C 790D" /* s interactively. */
- $"2020 2020 7768 656E 2072 756E 2C20 796F" /* when run, yo */
- $"7520 6D75 7374 2063 6175 7365 2069 742C" /* u must cause it, */
- $"2077 6865 6E20 7374 6172 7465 6420 7275" /* when started ru */
- $"6E6E 696E 6720 666F 7220 7375 6368 0D20" /* nning for such. */
- $"2020 2069 6E74 6572 6163 7469 7665 2075" /* interactive u */
- $"7365 2069 6E20 7468 6520 6D6F 7374 206F" /* se in the most o */
- $"7264 696E 6172 7920 7761 792C 2074 6F20" /* rdinary way, to */
- $"7072 696E 7420 6F72 2064 6973 706C 6179" /* print or display */
- $"2061 6E0D 2020 2020 616E 6E6F 756E 6365" /* an. announce */
- $"6D65 6E74 2069 6E63 6C75 6469 6E67 2061" /* ment including a */
- $"6E20 6170 7072 6F70 7269 6174 6520 636F" /* n appropriate co */
- $"7079 7269 6768 7420 6E6F 7469 6365 2061" /* pyright notice a */
- $"6E64 2061 0D20 2020 206E 6F74 6963 6520" /* nd a. notice */
- $"7468 6174 2074 6865 7265 2069 7320 6E6F" /* that there is no */
- $"2077 6172 7261 6E74 7920 286F 7220 656C" /* warranty (or el */
- $"7365 2C20 7361 7969 6E67 2074 6861 7420" /* se, saying that */
- $"796F 7520 7072 6F76 6964 650D 2020 2020" /* you provide. */
- $"6120 7761 7272 616E 7479 2920 616E 6420" /* a warranty) and */
- $"7468 6174 2075 7365 7273 206D 6179 2072" /* that users may r */
- $"6564 6973 7472 6962 7574 6520 7468 6520" /* edistribute the */
- $"7072 6F67 7261 6D20 756E 6465 720D 2020" /* program under. */
- $"2020 7468 6573 6520 636F 6E64 6974 696F" /* these conditio */
- $"6E73 2C20 616E 6420 7465 6C6C 696E 6720" /* ns, and telling */
- $"7468 6520 7573 6572 2068 6F77 2074 6F20" /* the user how to */
- $"7669 6577 2061 2063 6F70 7920 6F66 2074" /* view a copy of t */
- $"6869 730D 2020 2020 4C69 6365 6E73 652E" /* his. License. */
- $"2020 2845 7863 6570 7469 6F6E 3A20 6966" /* (Exception: if */
- $"2074 6865 2050 726F 6772 616D 2069 7473" /* the Program its */
- $"656C 6620 6973 2069 6E74 6572 6163 7469" /* elf is interacti */
- $"7665 2062 7574 0D20 2020 2064 6F65 7320" /* ve but. does */
- $"6E6F 7420 6E6F 726D 616C 6C79 2070 7269" /* not normally pri */
- $"6E74 2073 7563 6820 616E 2061 6E6E 6F75" /* nt such an annou */
- $"6E63 656D 656E 742C 2079 6F75 7220 776F" /* ncement, your wo */
- $"726B 2062 6173 6564 206F 6E0D 2020 2020" /* rk based on. */
- $"7468 6520 5072 6F67 7261 6D20 6973 206E" /* the Program is n */
- $"6F74 2072 6571 7569 7265 6420 746F 2070" /* ot required to p */
- $"7269 6E74 2061 6E20 616E 6E6F 756E 6365" /* rint an announce */
- $"6D65 6E74 2E29 0D0C 0D54 6865 7365 2072" /* ment.)...These r */
- $"6571 7569 7265 6D65 6E74 7320 6170 706C" /* equirements appl */
- $"7920 746F 2074 6865 206D 6F64 6966 6965" /* y to the modifie */
- $"6420 776F 726B 2061 7320 6120 7768 6F6C" /* d work as a whol */
- $"652E 2020 4966 0D69 6465 6E74 6966 6961" /* e. If.identifia */
- $"626C 6520 7365 6374 696F 6E73 206F 6620" /* ble sections of */
- $"7468 6174 2077 6F72 6B20 6172 6520 6E6F" /* that work are no */
- $"7420 6465 7269 7665 6420 6672 6F6D 2074" /* t derived from t */
- $"6865 2050 726F 6772 616D 2C0D 616E 6420" /* he Program,.and */
- $"6361 6E20 6265 2072 6561 736F 6E61 626C" /* can be reasonabl */
- $"7920 636F 6E73 6964 6572 6564 2069 6E64" /* y considered ind */
- $"6570 656E 6465 6E74 2061 6E64 2073 6570" /* ependent and sep */
- $"6172 6174 6520 776F 726B 7320 696E 0D74" /* arate works in.t */
- $"6865 6D73 656C 7665 732C 2074 6865 6E20" /* hemselves, then */
- $"7468 6973 204C 6963 656E 7365 2C20 616E" /* this License, an */
- $"6420 6974 7320 7465 726D 732C 2064 6F20" /* d its terms, do */
- $"6E6F 7420 6170 706C 7920 746F 2074 686F" /* not apply to tho */
- $"7365 0D73 6563 7469 6F6E 7320 7768 656E" /* se.sections when */
- $"2079 6F75 2064 6973 7472 6962 7574 6520" /* you distribute */
- $"7468 656D 2061 7320 7365 7061 7261 7465" /* them as separate */
- $"2077 6F72 6B73 2E20 2042 7574 2077 6865" /* works. But whe */
- $"6E20 796F 750D 6469 7374 7269 6275 7465" /* n you.distribute */
- $"2074 6865 2073 616D 6520 7365 6374 696F" /* the same sectio */
- $"6E73 2061 7320 7061 7274 206F 6620 6120" /* ns as part of a */
- $"7768 6F6C 6520 7768 6963 6820 6973 2061" /* whole which is a */
- $"2077 6F72 6B20 6261 7365 640D 6F6E 2074" /* work based.on t */
- $"6865 2050 726F 6772 616D 2C20 7468 6520" /* he Program, the */
- $"6469 7374 7269 6275 7469 6F6E 206F 6620" /* distribution of */
- $"7468 6520 7768 6F6C 6520 6D75 7374 2062" /* the whole must b */
- $"6520 6F6E 2074 6865 2074 6572 6D73 206F" /* e on the terms o */
- $"660D 7468 6973 204C 6963 656E 7365 2C20" /* f.this License, */
- $"7768 6F73 6520 7065 726D 6973 7369 6F6E" /* whose permission */
- $"7320 666F 7220 6F74 6865 7220 6C69 6365" /* s for other lice */
- $"6E73 6565 7320 6578 7465 6E64 2074 6F20" /* nsees extend to */
- $"7468 650D 656E 7469 7265 2077 686F 6C65" /* the.entire whole */
- $"2C20 616E 6420 7468 7573 2074 6F20 6561" /* , and thus to ea */
- $"6368 2061 6E64 2065 7665 7279 2070 6172" /* ch and every par */
- $"7420 7265 6761 7264 6C65 7373 206F 6620" /* t regardless of */
- $"7768 6F20 7772 6F74 6520 6974 2E0D 0D54" /* who wrote it...T */
- $"6875 732C 2069 7420 6973 206E 6F74 2074" /* hus, it is not t */
- $"6865 2069 6E74 656E 7420 6F66 2074 6869" /* he intent of thi */
- $"7320 7365 6374 696F 6E20 746F 2063 6C61" /* s section to cla */
- $"696D 2072 6967 6874 7320 6F72 2063 6F6E" /* im rights or con */
- $"7465 7374 0D79 6F75 7220 7269 6768 7473" /* test.your rights */
- $"2074 6F20 776F 726B 2077 7269 7474 656E" /* to work written */
- $"2065 6E74 6972 656C 7920 6279 2079 6F75" /* entirely by you */
- $"3B20 7261 7468 6572 2C20 7468 6520 696E" /* ; rather, the in */
- $"7465 6E74 2069 7320 746F 0D65 7865 7263" /* tent is to.exerc */
- $"6973 6520 7468 6520 7269 6768 7420 746F" /* ise the right to */
- $"2063 6F6E 7472 6F6C 2074 6865 2064 6973" /* control the dis */
- $"7472 6962 7574 696F 6E20 6F66 2064 6572" /* tribution of der */
- $"6976 6174 6976 6520 6F72 0D63 6F6C 6C65" /* ivative or.colle */
- $"6374 6976 6520 776F 726B 7320 6261 7365" /* ctive works base */
- $"6420 6F6E 2074 6865 2050 726F 6772 616D" /* d on the Program */
- $"2E0D 0D49 6E20 6164 6469 7469 6F6E 2C20" /* ...In addition, */
- $"6D65 7265 2061 6767 7265 6761 7469 6F6E" /* mere aggregation */
- $"206F 6620 616E 6F74 6865 7220 776F 726B" /* of another work */
- $"206E 6F74 2062 6173 6564 206F 6E20 7468" /* not based on th */
- $"6520 5072 6F67 7261 6D0D 7769 7468 2074" /* e Program.with t */
- $"6865 2050 726F 6772 616D 2028 6F72 2077" /* he Program (or w */
- $"6974 6820 6120 776F 726B 2062 6173 6564" /* ith a work based */
- $"206F 6E20 7468 6520 5072 6F67 7261 6D29" /* on the Program) */
- $"206F 6E20 6120 766F 6C75 6D65 206F 660D" /* on a volume of. */
- $"6120 7374 6F72 6167 6520 6F72 2064 6973" /* a storage or dis */
- $"7472 6962 7574 696F 6E20 6D65 6469 756D" /* tribution medium */
- $"2064 6F65 7320 6E6F 7420 6272 696E 6720" /* does not bring */
- $"7468 6520 6F74 6865 7220 776F 726B 2075" /* the other work u */
- $"6E64 6572 0D74 6865 2073 636F 7065 206F" /* nder.the scope o */
- $"6620 7468 6973 204C 6963 656E 7365 2E0D" /* f this License.. */
- $"0D20 2033 2E20 596F 7520 6D61 7920 636F" /* . 3. You may co */
- $"7079 2061 6E64 2064 6973 7472 6962 7574" /* py and distribut */
- $"6520 7468 6520 5072 6F67 7261 6D20 286F" /* e the Program (o */
- $"7220 6120 776F 726B 2062 6173 6564 206F" /* r a work based o */
- $"6E20 6974 2C0D 756E 6465 7220 5365 6374" /* n it,.under Sect */
- $"696F 6E20 3229 2069 6E20 6F62 6A65 6374" /* ion 2) in object */
- $"2063 6F64 6520 6F72 2065 7865 6375 7461" /* code or executa */
- $"626C 6520 666F 726D 2075 6E64 6572 2074" /* ble form under t */
- $"6865 2074 6572 6D73 206F 660D 5365 6374" /* he terms of.Sect */
- $"696F 6E73 2031 2061 6E64 2032 2061 626F" /* ions 1 and 2 abo */
- $"7665 2070 726F 7669 6465 6420 7468 6174" /* ve provided that */
- $"2079 6F75 2061 6C73 6F20 646F 206F 6E65" /* you also do one */
- $"206F 6620 7468 6520 666F 6C6C 6F77 696E" /* of the followin */
- $"673A 0D0D 2020 2020 6129 2041 6363 6F6D" /* g:.. a) Accom */
- $"7061 6E79 2069 7420 7769 7468 2074 6865" /* pany it with the */
- $"2063 6F6D 706C 6574 6520 636F 7272 6573" /* complete corres */
- $"706F 6E64 696E 6720 6D61 6368 696E 652D" /* ponding machine- */
- $"7265 6164 6162 6C65 0D20 2020 2073 6F75" /* readable. sou */
- $"7263 6520 636F 6465 2C20 7768 6963 6820" /* rce code, which */
- $"6D75 7374 2062 6520 6469 7374 7269 6275" /* must be distribu */
- $"7465 6420 756E 6465 7220 7468 6520 7465" /* ted under the te */
- $"726D 7320 6F66 2053 6563 7469 6F6E 730D" /* rms of Sections. */
- $"2020 2020 3120 616E 6420 3220 6162 6F76" /* 1 and 2 abov */
- $"6520 6F6E 2061 206D 6564 6975 6D20 6375" /* e on a medium cu */
- $"7374 6F6D 6172 696C 7920 7573 6564 2066" /* stomarily used f */
- $"6F72 2073 6F66 7477 6172 6520 696E 7465" /* or software inte */
- $"7263 6861 6E67 653B 206F 722C 0D0D 2020" /* rchange; or,.. */
- $"2020 6229 2041 6363 6F6D 7061 6E79 2069" /* b) Accompany i */
- $"7420 7769 7468 2061 2077 7269 7474 656E" /* t with a written */
- $"206F 6666 6572 2C20 7661 6C69 6420 666F" /* offer, valid fo */
- $"7220 6174 206C 6561 7374 2074 6872 6565" /* r at least three */
- $"0D20 2020 2079 6561 7273 2C20 746F 2067" /* . years, to g */
- $"6976 6520 616E 7920 7468 6972 6420 7061" /* ive any third pa */
- $"7274 792C 2066 6F72 2061 2063 6861 7267" /* rty, for a charg */
- $"6520 6E6F 206D 6F72 6520 7468 616E 2079" /* e no more than y */
- $"6F75 720D 2020 2020 636F 7374 206F 6620" /* our. cost of */
- $"7068 7973 6963 616C 6C79 2070 6572 666F" /* physically perfo */
- $"726D 696E 6720 736F 7572 6365 2064 6973" /* rming source dis */
- $"7472 6962 7574 696F 6E2C 2061 2063 6F6D" /* tribution, a com */
- $"706C 6574 650D 2020 2020 6D61 6368 696E" /* plete. machin */
- $"652D 7265 6164 6162 6C65 2063 6F70 7920" /* e-readable copy */
- $"6F66 2074 6865 2063 6F72 7265 7370 6F6E" /* of the correspon */
- $"6469 6E67 2073 6F75 7263 6520 636F 6465" /* ding source code */
- $"2C20 746F 2062 650D 2020 2020 6469 7374" /* , to be. dist */
- $"7269 6275 7465 6420 756E 6465 7220 7468" /* ributed under th */
- $"6520 7465 726D 7320 6F66 2053 6563 7469" /* e terms of Secti */
- $"6F6E 7320 3120 616E 6420 3220 6162 6F76" /* ons 1 and 2 abov */
- $"6520 6F6E 2061 206D 6564 6975 6D0D 2020" /* e on a medium. */
- $"2020 6375 7374 6F6D 6172 696C 7920 7573" /* customarily us */
- $"6564 2066 6F72 2073 6F66 7477 6172 6520" /* ed for software */
- $"696E 7465 7263 6861 6E67 653B 206F 722C" /* interchange; or, */
- $"0D0D 2020 2020 6329 2041 6363 6F6D 7061" /* .. c) Accompa */
- $"6E79 2069 7420 7769 7468 2074 6865 2069" /* ny it with the i */
- $"6E66 6F72 6D61 7469 6F6E 2079 6F75 2072" /* nformation you r */
- $"6563 6569 7665 6420 6173 2074 6F20 7468" /* eceived as to th */
- $"6520 6F66 6665 720D 2020 2020 746F 2064" /* e offer. to d */
- $"6973 7472 6962 7574 6520 636F 7272 6573" /* istribute corres */
- $"706F 6E64 696E 6720 736F 7572 6365 2063" /* ponding source c */
- $"6F64 652E 2020 2854 6869 7320 616C 7465" /* ode. (This alte */
- $"726E 6174 6976 6520 6973 0D20 2020 2061" /* rnative is. a */
- $"6C6C 6F77 6564 206F 6E6C 7920 666F 7220" /* llowed only for */
- $"6E6F 6E63 6F6D 6D65 7263 6961 6C20 6469" /* noncommercial di */
- $"7374 7269 6275 7469 6F6E 2061 6E64 206F" /* stribution and o */
- $"6E6C 7920 6966 2079 6F75 0D20 2020 2072" /* nly if you. r */
- $"6563 6569 7665 6420 7468 6520 7072 6F67" /* eceived the prog */
- $"7261 6D20 696E 206F 626A 6563 7420 636F" /* ram in object co */
- $"6465 206F 7220 6578 6563 7574 6162 6C65" /* de or executable */
- $"2066 6F72 6D20 7769 7468 2073 7563 680D" /* form with such. */
- $"2020 2020 616E 206F 6666 6572 2C20 696E" /* an offer, in */
- $"2061 6363 6F72 6420 7769 7468 2053 7562" /* accord with Sub */
- $"7365 6374 696F 6E20 6220 6162 6F76 652E" /* section b above. */
- $"290D 0D54 6865 2073 6F75 7263 6520 636F" /* )..The source co */
- $"6465 2066 6F72 2061 2077 6F72 6B20 6D65" /* de for a work me */
- $"616E 7320 7468 6520 7072 6566 6572 7265" /* ans the preferre */
- $"6420 666F 726D 206F 6620 7468 6520 776F" /* d form of the wo */
- $"726B 2066 6F72 0D6D 616B 696E 6720 6D6F" /* rk for.making mo */
- $"6469 6669 6361 7469 6F6E 7320 746F 2069" /* difications to i */
- $"742E 2020 466F 7220 616E 2065 7865 6375" /* t. For an execu */
- $"7461 626C 6520 776F 726B 2C20 636F 6D70" /* table work, comp */
- $"6C65 7465 2073 6F75 7263 650D 636F 6465" /* lete source.code */
- $"206D 6561 6E73 2061 6C6C 2074 6865 2073" /* means all the s */
- $"6F75 7263 6520 636F 6465 2066 6F72 2061" /* ource code for a */
- $"6C6C 206D 6F64 756C 6573 2069 7420 636F" /* ll modules it co */
- $"6E74 6169 6E73 2C20 706C 7573 2061 6E79" /* ntains, plus any */
- $"0D61 7373 6F63 6961 7465 6420 696E 7465" /* .associated inte */
- $"7266 6163 6520 6465 6669 6E69 7469 6F6E" /* rface definition */
- $"2066 696C 6573 2C20 706C 7573 2074 6865" /* files, plus the */
- $"2073 6372 6970 7473 2075 7365 6420 746F" /* scripts used to */
- $"0D63 6F6E 7472 6F6C 2063 6F6D 7069 6C61" /* .control compila */
- $"7469 6F6E 2061 6E64 2069 6E73 7461 6C6C" /* tion and install */
- $"6174 696F 6E20 6F66 2074 6865 2065 7865" /* ation of the exe */
- $"6375 7461 626C 652E 2020 486F 7765 7665" /* cutable. Howeve */
- $"722C 2061 7320 610D 7370 6563 6961 6C20" /* r, as a.special */
- $"6578 6365 7074 696F 6E2C 2074 6865 2073" /* exception, the s */
- $"6F75 7263 6520 636F 6465 2064 6973 7472" /* ource code distr */
- $"6962 7574 6564 206E 6565 6420 6E6F 7420" /* ibuted need not */
- $"696E 636C 7564 650D 616E 7974 6869 6E67" /* include.anything */
- $"2074 6861 7420 6973 206E 6F72 6D61 6C6C" /* that is normall */
- $"7920 6469 7374 7269 6275 7465 6420 2869" /* y distributed (i */
- $"6E20 6569 7468 6572 2073 6F75 7263 6520" /* n either source */
- $"6F72 2062 696E 6172 790D 666F 726D 2920" /* or binary.form) */
- $"7769 7468 2074 6865 206D 616A 6F72 2063" /* with the major c */
- $"6F6D 706F 6E65 6E74 7320 2863 6F6D 7069" /* omponents (compi */
- $"6C65 722C 206B 6572 6E65 6C2C 2061 6E64" /* ler, kernel, and */
- $"2073 6F20 6F6E 2920 6F66 2074 6865 0D6F" /* so on) of the.o */
- $"7065 7261 7469 6E67 2073 7973 7465 6D20" /* perating system */
- $"6F6E 2077 6869 6368 2074 6865 2065 7865" /* on which the exe */
- $"6375 7461 626C 6520 7275 6E73 2C20 756E" /* cutable runs, un */
- $"6C65 7373 2074 6861 7420 636F 6D70 6F6E" /* less that compon */
- $"656E 740D 6974 7365 6C66 2061 6363 6F6D" /* ent.itself accom */
- $"7061 6E69 6573 2074 6865 2065 7865 6375" /* panies the execu */
- $"7461 626C 652E 0D0D 4966 2064 6973 7472" /* table...If distr */
- $"6962 7574 696F 6E20 6F66 2065 7865 6375" /* ibution of execu */
- $"7461 626C 6520 6F72 206F 626A 6563 7420" /* table or object */
- $"636F 6465 2069 7320 6D61 6465 2062 7920" /* code is made by */
- $"6F66 6665 7269 6E67 0D61 6363 6573 7320" /* offering.access */
- $"746F 2063 6F70 7920 6672 6F6D 2061 2064" /* to copy from a d */
- $"6573 6967 6E61 7465 6420 706C 6163 652C" /* esignated place, */
- $"2074 6865 6E20 6F66 6665 7269 6E67 2065" /* then offering e */
- $"7175 6976 616C 656E 740D 6163 6365 7373" /* quivalent.access */
- $"2074 6F20 636F 7079 2074 6865 2073 6F75" /* to copy the sou */
- $"7263 6520 636F 6465 2066 726F 6D20 7468" /* rce code from th */
- $"6520 7361 6D65 2070 6C61 6365 2063 6F75" /* e same place cou */
- $"6E74 7320 6173 0D64 6973 7472 6962 7574" /* nts as.distribut */
- $"696F 6E20 6F66 2074 6865 2073 6F75 7263" /* ion of the sourc */
- $"6520 636F 6465 2C20 6576 656E 2074 686F" /* e code, even tho */
- $"7567 6820 7468 6972 6420 7061 7274 6965" /* ugh third partie */
- $"7320 6172 6520 6E6F 740D 636F 6D70 656C" /* s are not.compel */
- $"6C65 6420 746F 2063 6F70 7920 7468 6520" /* led to copy the */
- $"736F 7572 6365 2061 6C6F 6E67 2077 6974" /* source along wit */
- $"6820 7468 6520 6F62 6A65 6374 2063 6F64" /* h the object cod */
- $"652E 0D0C 0D20 2034 2E20 596F 7520 6D61" /* e.... 4. You ma */
- $"7920 6E6F 7420 636F 7079 2C20 6D6F 6469" /* y not copy, modi */
- $"6679 2C20 7375 626C 6963 656E 7365 2C20" /* fy, sublicense, */
- $"6F72 2064 6973 7472 6962 7574 6520 7468" /* or distribute th */
- $"6520 5072 6F67 7261 6D0D 6578 6365 7074" /* e Program.except */
- $"2061 7320 6578 7072 6573 736C 7920 7072" /* as expressly pr */
- $"6F76 6964 6564 2075 6E64 6572 2074 6869" /* ovided under thi */
- $"7320 4C69 6365 6E73 652E 2020 416E 7920" /* s License. Any */
- $"6174 7465 6D70 740D 6F74 6865 7277 6973" /* attempt.otherwis */
- $"6520 746F 2063 6F70 792C 206D 6F64 6966" /* e to copy, modif */
- $"792C 2073 7562 6C69 6365 6E73 6520 6F72" /* y, sublicense or */
- $"2064 6973 7472 6962 7574 6520 7468 6520" /* distribute the */
- $"5072 6F67 7261 6D20 6973 0D76 6F69 642C" /* Program is.void, */
- $"2061 6E64 2077 696C 6C20 6175 746F 6D61" /* and will automa */
- $"7469 6361 6C6C 7920 7465 726D 696E 6174" /* tically terminat */
- $"6520 796F 7572 2072 6967 6874 7320 756E" /* e your rights un */
- $"6465 7220 7468 6973 204C 6963 656E 7365" /* der this License */
- $"2E0D 486F 7765 7665 722C 2070 6172 7469" /* ..However, parti */
- $"6573 2077 686F 2068 6176 6520 7265 6365" /* es who have rece */
- $"6976 6564 2063 6F70 6965 732C 206F 7220" /* ived copies, or */
- $"7269 6768 7473 2C20 6672 6F6D 2079 6F75" /* rights, from you */
- $"2075 6E64 6572 0D74 6869 7320 4C69 6365" /* under.this Lice */
- $"6E73 6520 7769 6C6C 206E 6F74 2068 6176" /* nse will not hav */
- $"6520 7468 6569 7220 6C69 6365 6E73 6573" /* e their licenses */
- $"2074 6572 6D69 6E61 7465 6420 736F 206C" /* terminated so l */
- $"6F6E 6720 6173 2073 7563 680D 7061 7274" /* ong as such.part */
- $"6965 7320 7265 6D61 696E 2069 6E20 6675" /* ies remain in fu */
- $"6C6C 2063 6F6D 706C 6961 6E63 652E 0D0D" /* ll compliance... */
- $"2020 352E 2059 6F75 2061 7265 206E 6F74" /* 5. You are not */
- $"2072 6571 7569 7265 6420 746F 2061 6363" /* required to acc */
- $"6570 7420 7468 6973 204C 6963 656E 7365" /* ept this License */
- $"2C20 7369 6E63 6520 796F 7520 6861 7665" /* , since you have */
- $"206E 6F74 0D73 6967 6E65 6420 6974 2E20" /* not.signed it. */
- $"2048 6F77 6576 6572 2C20 6E6F 7468 696E" /* However, nothin */
- $"6720 656C 7365 2067 7261 6E74 7320 796F" /* g else grants yo */
- $"7520 7065 726D 6973 7369 6F6E 2074 6F20" /* u permission to */
- $"6D6F 6469 6679 206F 720D 6469 7374 7269" /* modify or.distri */
- $"6275 7465 2074 6865 2050 726F 6772 616D" /* bute the Program */
- $"206F 7220 6974 7320 6465 7269 7661 7469" /* or its derivati */
- $"7665 2077 6F72 6B73 2E20 2054 6865 7365" /* ve works. These */
- $"2061 6374 696F 6E73 2061 7265 0D70 726F" /* actions are.pro */
- $"6869 6269 7465 6420 6279 206C 6177 2069" /* hibited by law i */
- $"6620 796F 7520 646F 206E 6F74 2061 6363" /* f you do not acc */
- $"6570 7420 7468 6973 204C 6963 656E 7365" /* ept this License */
- $"2E20 2054 6865 7265 666F 7265 2C20 6279" /* . Therefore, by */
- $"0D6D 6F64 6966 7969 6E67 206F 7220 6469" /* .modifying or di */
- $"7374 7269 6275 7469 6E67 2074 6865 2050" /* stributing the P */
- $"726F 6772 616D 2028 6F72 2061 6E79 2077" /* rogram (or any w */
- $"6F72 6B20 6261 7365 6420 6F6E 2074 6865" /* ork based on the */
- $"0D50 726F 6772 616D 292C 2079 6F75 2069" /* .Program), you i */
- $"6E64 6963 6174 6520 796F 7572 2061 6363" /* ndicate your acc */
- $"6570 7461 6E63 6520 6F66 2074 6869 7320" /* eptance of this */
- $"4C69 6365 6E73 6520 746F 2064 6F20 736F" /* License to do so */
- $"2C20 616E 640D 616C 6C20 6974 7320 7465" /* , and.all its te */
- $"726D 7320 616E 6420 636F 6E64 6974 696F" /* rms and conditio */
- $"6E73 2066 6F72 2063 6F70 7969 6E67 2C20" /* ns for copying, */
- $"6469 7374 7269 6275 7469 6E67 206F 7220" /* distributing or */
- $"6D6F 6469 6679 696E 670D 7468 6520 5072" /* modifying.the Pr */
- $"6F67 7261 6D20 6F72 2077 6F72 6B73 2062" /* ogram or works b */
- $"6173 6564 206F 6E20 6974 2E0D 0D20 2036" /* ased on it... 6 */
- $"2E20 4561 6368 2074 696D 6520 796F 7520" /* . Each time you */
- $"7265 6469 7374 7269 6275 7465 2074 6865" /* redistribute the */
- $"2050 726F 6772 616D 2028 6F72 2061 6E79" /* Program (or any */
- $"2077 6F72 6B20 6261 7365 6420 6F6E 2074" /* work based on t */
- $"6865 0D50 726F 6772 616D 292C 2074 6865" /* he.Program), the */
- $"2072 6563 6970 6965 6E74 2061 7574 6F6D" /* recipient autom */
- $"6174 6963 616C 6C79 2072 6563 6569 7665" /* atically receive */
- $"7320 6120 6C69 6365 6E73 6520 6672 6F6D" /* s a license from */
- $"2074 6865 0D6F 7269 6769 6E61 6C20 6C69" /* the.original li */
- $"6365 6E73 6F72 2074 6F20 636F 7079 2C20" /* censor to copy, */
- $"6469 7374 7269 6275 7465 206F 7220 6D6F" /* distribute or mo */
- $"6469 6679 2074 6865 2050 726F 6772 616D" /* dify the Program */
- $"2073 7562 6A65 6374 2074 6F0D 7468 6573" /* subject to.thes */
- $"6520 7465 726D 7320 616E 6420 636F 6E64" /* e terms and cond */
- $"6974 696F 6E73 2E20 2059 6F75 206D 6179" /* itions. You may */
- $"206E 6F74 2069 6D70 6F73 6520 616E 7920" /* not impose any */
- $"6675 7274 6865 720D 7265 7374 7269 6374" /* further.restrict */
- $"696F 6E73 206F 6E20 7468 6520 7265 6369" /* ions on the reci */
- $"7069 656E 7473 2720 6578 6572 6369 7365" /* pients' exercise */
- $"206F 6620 7468 6520 7269 6768 7473 2067" /* of the rights g */
- $"7261 6E74 6564 2068 6572 6569 6E2E 0D59" /* ranted herein..Y */
- $"6F75 2061 7265 206E 6F74 2072 6573 706F" /* ou are not respo */
- $"6E73 6962 6C65 2066 6F72 2065 6E66 6F72" /* nsible for enfor */
- $"6369 6E67 2063 6F6D 706C 6961 6E63 6520" /* cing compliance */
- $"6279 2074 6869 7264 2070 6172 7469 6573" /* by third parties */
- $"2074 6F0D 7468 6973 204C 6963 656E 7365" /* to.this License */
- $"2E0D 0D20 2037 2E20 4966 2C20 6173 2061" /* ... 7. If, as a */
- $"2063 6F6E 7365 7175 656E 6365 206F 6620" /* consequence of */
- $"6120 636F 7572 7420 6A75 6467 6D65 6E74" /* a court judgment */
- $"206F 7220 616C 6C65 6761 7469 6F6E 206F" /* or allegation o */
- $"6620 7061 7465 6E74 0D69 6E66 7269 6E67" /* f patent.infring */
- $"656D 656E 7420 6F72 2066 6F72 2061 6E79" /* ement or for any */
- $"206F 7468 6572 2072 6561 736F 6E20 286E" /* other reason (n */
- $"6F74 206C 696D 6974 6564 2074 6F20 7061" /* ot limited to pa */
- $"7465 6E74 2069 7373 7565 7329 2C0D 636F" /* tent issues),.co */
- $"6E64 6974 696F 6E73 2061 7265 2069 6D70" /* nditions are imp */
- $"6F73 6564 206F 6E20 796F 7520 2877 6865" /* osed on you (whe */
- $"7468 6572 2062 7920 636F 7572 7420 6F72" /* ther by court or */
- $"6465 722C 2061 6772 6565 6D65 6E74 206F" /* der, agreement o */
- $"720D 6F74 6865 7277 6973 6529 2074 6861" /* r.otherwise) tha */
- $"7420 636F 6E74 7261 6469 6374 2074 6865" /* t contradict the */
- $"2063 6F6E 6469 7469 6F6E 7320 6F66 2074" /* conditions of t */
- $"6869 7320 4C69 6365 6E73 652C 2074 6865" /* his License, the */
- $"7920 646F 206E 6F74 0D65 7863 7573 6520" /* y do not.excuse */
- $"796F 7520 6672 6F6D 2074 6865 2063 6F6E" /* you from the con */
- $"6469 7469 6F6E 7320 6F66 2074 6869 7320" /* ditions of this */
- $"4C69 6365 6E73 652E 2020 4966 2079 6F75" /* License. If you */
- $"2063 616E 6E6F 740D 6469 7374 7269 6275" /* cannot.distribu */
- $"7465 2073 6F20 6173 2074 6F20 7361 7469" /* te so as to sati */
- $"7366 7920 7369 6D75 6C74 616E 656F 7573" /* sfy simultaneous */
- $"6C79 2079 6F75 7220 6F62 6C69 6761 7469" /* ly your obligati */
- $"6F6E 7320 756E 6465 7220 7468 6973 0D4C" /* ons under this.L */
- $"6963 656E 7365 2061 6E64 2061 6E79 206F" /* icense and any o */
- $"7468 6572 2070 6572 7469 6E65 6E74 206F" /* ther pertinent o */
- $"626C 6967 6174 696F 6E73 2C20 7468 656E" /* bligations, then */
- $"2061 7320 6120 636F 6E73 6571 7565 6E63" /* as a consequenc */
- $"6520 796F 750D 6D61 7920 6E6F 7420 6469" /* e you.may not di */
- $"7374 7269 6275 7465 2074 6865 2050 726F" /* stribute the Pro */
- $"6772 616D 2061 7420 616C 6C2E 2020 466F" /* gram at all. Fo */
- $"7220 6578 616D 706C 652C 2069 6620 6120" /* r example, if a */
- $"7061 7465 6E74 0D6C 6963 656E 7365 2077" /* patent.license w */
- $"6F75 6C64 206E 6F74 2070 6572 6D69 7420" /* ould not permit */
- $"726F 7961 6C74 792D 6672 6565 2072 6564" /* royalty-free red */
- $"6973 7472 6962 7574 696F 6E20 6F66 2074" /* istribution of t */
- $"6865 2050 726F 6772 616D 2062 790D 616C" /* he Program by.al */
- $"6C20 7468 6F73 6520 7768 6F20 7265 6365" /* l those who rece */
- $"6976 6520 636F 7069 6573 2064 6972 6563" /* ive copies direc */
- $"746C 7920 6F72 2069 6E64 6972 6563 746C" /* tly or indirectl */
- $"7920 7468 726F 7567 6820 796F 752C 2074" /* y through you, t */
- $"6865 6E0D 7468 6520 6F6E 6C79 2077 6179" /* hen.the only way */
- $"2079 6F75 2063 6F75 6C64 2073 6174 6973" /* you could satis */
- $"6679 2062 6F74 6820 6974 2061 6E64 2074" /* fy both it and t */
- $"6869 7320 4C69 6365 6E73 6520 776F 756C" /* his License woul */
- $"6420 6265 2074 6F0D 7265 6672 6169 6E20" /* d be to.refrain */
- $"656E 7469 7265 6C79 2066 726F 6D20 6469" /* entirely from di */
- $"7374 7269 6275 7469 6F6E 206F 6620 7468" /* stribution of th */
- $"6520 5072 6F67 7261 6D2E 0D0D 4966 2061" /* e Program...If a */
- $"6E79 2070 6F72 7469 6F6E 206F 6620 7468" /* ny portion of th */
- $"6973 2073 6563 7469 6F6E 2069 7320 6865" /* is section is he */
- $"6C64 2069 6E76 616C 6964 206F 7220 756E" /* ld invalid or un */
- $"656E 666F 7263 6561 626C 6520 756E 6465" /* enforceable unde */
- $"720D 616E 7920 7061 7274 6963 756C 6172" /* r.any particular */
- $"2063 6972 6375 6D73 7461 6E63 652C 2074" /* circumstance, t */
- $"6865 2062 616C 616E 6365 206F 6620 7468" /* he balance of th */
- $"6520 7365 6374 696F 6E20 6973 2069 6E74" /* e section is int */
- $"656E 6465 6420 746F 0D61 7070 6C79 2061" /* ended to.apply a */
- $"6E64 2074 6865 2073 6563 7469 6F6E 2061" /* nd the section a */
- $"7320 6120 7768 6F6C 6520 6973 2069 6E74" /* s a whole is int */
- $"656E 6465 6420 746F 2061 7070 6C79 2069" /* ended to apply i */
- $"6E20 6F74 6865 720D 6369 7263 756D 7374" /* n other.circumst */
- $"616E 6365 732E 0D0D 4974 2069 7320 6E6F" /* ances...It is no */
- $"7420 7468 6520 7075 7270 6F73 6520 6F66" /* t the purpose of */
- $"2074 6869 7320 7365 6374 696F 6E20 746F" /* this section to */
- $"2069 6E64 7563 6520 796F 7520 746F 2069" /* induce you to i */
- $"6E66 7269 6E67 6520 616E 790D 7061 7465" /* nfringe any.pate */
- $"6E74 7320 6F72 206F 7468 6572 2070 726F" /* nts or other pro */
- $"7065 7274 7920 7269 6768 7420 636C 6169" /* perty right clai */
- $"6D73 206F 7220 746F 2063 6F6E 7465 7374" /* ms or to contest */
- $"2076 616C 6964 6974 7920 6F66 2061 6E79" /* validity of any */
- $"0D73 7563 6820 636C 6169 6D73 3B20 7468" /* .such claims; th */
- $"6973 2073 6563 7469 6F6E 2068 6173 2074" /* is section has t */
- $"6865 2073 6F6C 6520 7075 7270 6F73 6520" /* he sole purpose */
- $"6F66 2070 726F 7465 6374 696E 6720 7468" /* of protecting th */
- $"650D 696E 7465 6772 6974 7920 6F66 2074" /* e.integrity of t */
- $"6865 2066 7265 6520 736F 6674 7761 7265" /* he free software */
- $"2064 6973 7472 6962 7574 696F 6E20 7379" /* distribution sy */
- $"7374 656D 2C20 7768 6963 6820 6973 0D69" /* stem, which is.i */
- $"6D70 6C65 6D65 6E74 6564 2062 7920 7075" /* mplemented by pu */
- $"626C 6963 206C 6963 656E 7365 2070 7261" /* blic license pra */
- $"6374 6963 6573 2E20 204D 616E 7920 7065" /* ctices. Many pe */
- $"6F70 6C65 2068 6176 6520 6D61 6465 0D67" /* ople have made.g */
- $"656E 6572 6F75 7320 636F 6E74 7269 6275" /* enerous contribu */
- $"7469 6F6E 7320 746F 2074 6865 2077 6964" /* tions to the wid */
- $"6520 7261 6E67 6520 6F66 2073 6F66 7477" /* e range of softw */
- $"6172 6520 6469 7374 7269 6275 7465 640D" /* are distributed. */
- $"7468 726F 7567 6820 7468 6174 2073 7973" /* through that sys */
- $"7465 6D20 696E 2072 656C 6961 6E63 6520" /* tem in reliance */
- $"6F6E 2063 6F6E 7369 7374 656E 7420 6170" /* on consistent ap */
- $"706C 6963 6174 696F 6E20 6F66 2074 6861" /* plication of tha */
- $"740D 7379 7374 656D 3B20 6974 2069 7320" /* t.system; it is */
- $"7570 2074 6F20 7468 6520 6175 7468 6F72" /* up to the author */
- $"2F64 6F6E 6F72 2074 6F20 6465 6369 6465" /* /donor to decide */
- $"2069 6620 6865 206F 7220 7368 6520 6973" /* if he or she is */
- $"2077 696C 6C69 6E67 0D74 6F20 6469 7374" /* willing.to dist */
- $"7269 6275 7465 2073 6F66 7477 6172 6520" /* ribute software */
- $"7468 726F 7567 6820 616E 7920 6F74 6865" /* through any othe */
- $"7220 7379 7374 656D 2061 6E64 2061 206C" /* r system and a l */
- $"6963 656E 7365 6520 6361 6E6E 6F74 0D69" /* icensee cannot.i */
- $"6D70 6F73 6520 7468 6174 2063 686F 6963" /* mpose that choic */
- $"652E 0D0D 5468 6973 2073 6563 7469 6F6E" /* e...This section */
- $"2069 7320 696E 7465 6E64 6564 2074 6F20" /* is intended to */
- $"6D61 6B65 2074 686F 726F 7567 686C 7920" /* make thoroughly */
- $"636C 6561 7220 7768 6174 2069 7320 6265" /* clear what is be */
- $"6C69 6576 6564 2074 6F0D 6265 2061 2063" /* lieved to.be a c */
- $"6F6E 7365 7175 656E 6365 206F 6620 7468" /* onsequence of th */
- $"6520 7265 7374 206F 6620 7468 6973 204C" /* e rest of this L */
- $"6963 656E 7365 2E0D 0C0D 2020 382E 2049" /* icense.... 8. I */
- $"6620 7468 6520 6469 7374 7269 6275 7469" /* f the distributi */
- $"6F6E 2061 6E64 2F6F 7220 7573 6520 6F66" /* on and/or use of */
- $"2074 6865 2050 726F 6772 616D 2069 7320" /* the Program is */
- $"7265 7374 7269 6374 6564 2069 6E0D 6365" /* restricted in.ce */
- $"7274 6169 6E20 636F 756E 7472 6965 7320" /* rtain countries */
- $"6569 7468 6572 2062 7920 7061 7465 6E74" /* either by patent */
- $"7320 6F72 2062 7920 636F 7079 7269 6768" /* s or by copyrigh */
- $"7465 6420 696E 7465 7266 6163 6573 2C20" /* ted interfaces, */
- $"7468 650D 6F72 6967 696E 616C 2063 6F70" /* the.original cop */
- $"7972 6967 6874 2068 6F6C 6465 7220 7768" /* yright holder wh */
- $"6F20 706C 6163 6573 2074 6865 2050 726F" /* o places the Pro */
- $"6772 616D 2075 6E64 6572 2074 6869 7320" /* gram under this */
- $"4C69 6365 6E73 650D 6D61 7920 6164 6420" /* License.may add */
- $"616E 2065 7870 6C69 6369 7420 6765 6F67" /* an explicit geog */
- $"7261 7068 6963 616C 2064 6973 7472 6962" /* raphical distrib */
- $"7574 696F 6E20 6C69 6D69 7461 7469 6F6E" /* ution limitation */
- $"2065 7863 6C75 6469 6E67 0D74 686F 7365" /* excluding.those */
- $"2063 6F75 6E74 7269 6573 2C20 736F 2074" /* countries, so t */
- $"6861 7420 6469 7374 7269 6275 7469 6F6E" /* hat distribution */
- $"2069 7320 7065 726D 6974 7465 6420 6F6E" /* is permitted on */
- $"6C79 2069 6E20 6F72 2061 6D6F 6E67 0D63" /* ly in or among.c */
- $"6F75 6E74 7269 6573 206E 6F74 2074 6875" /* ountries not thu */
- $"7320 6578 636C 7564 6564 2E20 2049 6E20" /* s excluded. In */
- $"7375 6368 2063 6173 652C 2074 6869 7320" /* such case, this */
- $"4C69 6365 6E73 6520 696E 636F 7270 6F72" /* License incorpor */
- $"6174 6573 0D74 6865 206C 696D 6974 6174" /* ates.the limitat */
- $"696F 6E20 6173 2069 6620 7772 6974 7465" /* ion as if writte */
- $"6E20 696E 2074 6865 2062 6F64 7920 6F66" /* n in the body of */
- $"2074 6869 7320 4C69 6365 6E73 652E 0D0D" /* this License... */
- $"2020 392E 2054 6865 2046 7265 6520 536F" /* 9. The Free So */
- $"6674 7761 7265 2046 6F75 6E64 6174 696F" /* ftware Foundatio */
- $"6E20 6D61 7920 7075 626C 6973 6820 7265" /* n may publish re */
- $"7669 7365 6420 616E 642F 6F72 206E 6577" /* vised and/or new */
- $"2076 6572 7369 6F6E 730D 6F66 2074 6865" /* versions.of the */
- $"2047 656E 6572 616C 2050 7562 6C69 6320" /* General Public */
- $"4C69 6365 6E73 6520 6672 6F6D 2074 696D" /* License from tim */
- $"6520 746F 2074 696D 652E 2020 5375 6368" /* e to time. Such */
- $"206E 6577 2076 6572 7369 6F6E 7320 7769" /* new versions wi */
- $"6C6C 0D62 6520 7369 6D69 6C61 7220 696E" /* ll.be similar in */
- $"2073 7069 7269 7420 746F 2074 6865 2070" /* spirit to the p */
- $"7265 7365 6E74 2076 6572 7369 6F6E 2C20" /* resent version, */
- $"6275 7420 6D61 7920 6469 6666 6572 2069" /* but may differ i */
- $"6E20 6465 7461 696C 2074 6F0D 6164 6472" /* n detail to.addr */
- $"6573 7320 6E65 7720 7072 6F62 6C65 6D73" /* ess new problems */
- $"206F 7220 636F 6E63 6572 6E73 2E0D 0D45" /* or concerns...E */
- $"6163 6820 7665 7273 696F 6E20 6973 2067" /* ach version is g */
- $"6976 656E 2061 2064 6973 7469 6E67 7569" /* iven a distingui */
- $"7368 696E 6720 7665 7273 696F 6E20 6E75" /* shing version nu */
- $"6D62 6572 2E20 2049 6620 7468 6520 5072" /* mber. If the Pr */
- $"6F67 7261 6D0D 7370 6563 6966 6965 7320" /* ogram.specifies */
- $"6120 7665 7273 696F 6E20 6E75 6D62 6572" /* a version number */
- $"206F 6620 7468 6973 204C 6963 656E 7365" /* of this License */
- $"2077 6869 6368 2061 7070 6C69 6573 2074" /* which applies t */
- $"6F20 6974 2061 6E64 2022 616E 790D 6C61" /* o it and "any.la */
- $"7465 7220 7665 7273 696F 6E22 2C20 796F" /* ter version", yo */
- $"7520 6861 7665 2074 6865 206F 7074 696F" /* u have the optio */
- $"6E20 6F66 2066 6F6C 6C6F 7769 6E67 2074" /* n of following t */
- $"6865 2074 6572 6D73 2061 6E64 2063 6F6E" /* he terms and con */
- $"6469 7469 6F6E 730D 6569 7468 6572 206F" /* ditions.either o */
- $"6620 7468 6174 2076 6572 7369 6F6E 206F" /* f that version o */
- $"7220 6F66 2061 6E79 206C 6174 6572 2076" /* r of any later v */
- $"6572 7369 6F6E 2070 7562 6C69 7368 6564" /* ersion published */
- $"2062 7920 7468 6520 4672 6565 0D53 6F66" /* by the Free.Sof */
- $"7477 6172 6520 466F 756E 6461 7469 6F6E" /* tware Foundation */
- $"2E20 2049 6620 7468 6520 5072 6F67 7261" /* . If the Progra */
- $"6D20 646F 6573 206E 6F74 2073 7065 6369" /* m does not speci */
- $"6679 2061 2076 6572 7369 6F6E 206E 756D" /* fy a version num */
- $"6265 7220 6F66 0D74 6869 7320 4C69 6365" /* ber of.this Lice */
- $"6E73 652C 2079 6F75 206D 6179 2063 686F" /* nse, you may cho */
- $"6F73 6520 616E 7920 7665 7273 696F 6E20" /* ose any version */
- $"6576 6572 2070 7562 6C69 7368 6564 2062" /* ever published b */
- $"7920 7468 6520 4672 6565 2053 6F66 7477" /* y the Free Softw */
- $"6172 650D 466F 756E 6461 7469 6F6E 2E0D" /* are.Foundation.. */
- $"0D20 2031 302E 2049 6620 796F 7520 7769" /* . 10. If you wi */
- $"7368 2074 6F20 696E 636F 7270 6F72 6174" /* sh to incorporat */
- $"6520 7061 7274 7320 6F66 2074 6865 2050" /* e parts of the P */
- $"726F 6772 616D 2069 6E74 6F20 6F74 6865" /* rogram into othe */
- $"7220 6672 6565 0D70 726F 6772 616D 7320" /* r free.programs */
- $"7768 6F73 6520 6469 7374 7269 6275 7469" /* whose distributi */
- $"6F6E 2063 6F6E 6469 7469 6F6E 7320 6172" /* on conditions ar */
- $"6520 6469 6666 6572 656E 742C 2077 7269" /* e different, wri */
- $"7465 2074 6F20 7468 6520 6175 7468 6F72" /* te to the author */
- $"0D74 6F20 6173 6B20 666F 7220 7065 726D" /* .to ask for perm */
- $"6973 7369 6F6E 2E20 2046 6F72 2073 6F66" /* ission. For sof */
- $"7477 6172 6520 7768 6963 6820 6973 2063" /* tware which is c */
- $"6F70 7972 6967 6874 6564 2062 7920 7468" /* opyrighted by th */
- $"6520 4672 6565 0D53 6F66 7477 6172 6520" /* e Free.Software */
- $"466F 756E 6461 7469 6F6E 2C20 7772 6974" /* Foundation, writ */
- $"6520 746F 2074 6865 2046 7265 6520 536F" /* e to the Free So */
- $"6674 7761 7265 2046 6F75 6E64 6174 696F" /* ftware Foundatio */
- $"6E3B 2077 6520 736F 6D65 7469 6D65 730D" /* n; we sometimes. */
- $"6D61 6B65 2065 7863 6570 7469 6F6E 7320" /* make exceptions */
- $"666F 7220 7468 6973 2E20 204F 7572 2064" /* for this. Our d */
- $"6563 6973 696F 6E20 7769 6C6C 2062 6520" /* ecision will be */
- $"6775 6964 6564 2062 7920 7468 6520 7477" /* guided by the tw */
- $"6F20 676F 616C 730D 6F66 2070 7265 7365" /* o goals.of prese */
- $"7276 696E 6720 7468 6520 6672 6565 2073" /* rving the free s */
- $"7461 7475 7320 6F66 2061 6C6C 2064 6572" /* tatus of all der */
- $"6976 6174 6976 6573 206F 6620 6F75 7220" /* ivatives of our */
- $"6672 6565 2073 6F66 7477 6172 6520 616E" /* free software an */
- $"640D 6F66 2070 726F 6D6F 7469 6E67 2074" /* d.of promoting t */
- $"6865 2073 6861 7269 6E67 2061 6E64 2072" /* he sharing and r */
- $"6575 7365 206F 6620 736F 6674 7761 7265" /* euse of software */
- $"2067 656E 6572 616C 6C79 2E0D 0D09 0909" /* generally...ÆÆÆ */
- $"2020 2020 4E4F 2057 4152 5241 4E54 590D" /* NO WARRANTY. */
- $"0D20 2031 312E 2042 4543 4155 5345 2054" /* . 11. BECAUSE T */
- $"4845 2050 524F 4752 414D 2049 5320 4C49" /* HE PROGRAM IS LI */
- $"4345 4E53 4544 2046 5245 4520 4F46 2043" /* CENSED FREE OF C */
- $"4841 5247 452C 2054 4845 5245 2049 5320" /* HARGE, THERE IS */
- $"4E4F 2057 4152 5241 4E54 590D 464F 5220" /* NO WARRANTY.FOR */
- $"5448 4520 5052 4F47 5241 4D2C 2054 4F20" /* THE PROGRAM, TO */
- $"5448 4520 4558 5445 4E54 2050 4552 4D49" /* THE EXTENT PERMI */
- $"5454 4544 2042 5920 4150 504C 4943 4142" /* TTED BY APPLICAB */
- $"4C45 204C 4157 2E20 2045 5843 4550 5420" /* LE LAW. EXCEPT */
- $"5748 454E 0D4F 5448 4552 5749 5345 2053" /* WHEN.OTHERWISE S */
- $"5441 5445 4420 494E 2057 5249 5449 4E47" /* TATED IN WRITING */
- $"2054 4845 2043 4F50 5952 4947 4854 2048" /* THE COPYRIGHT H */
- $"4F4C 4445 5253 2041 4E44 2F4F 5220 4F54" /* OLDERS AND/OR OT */
- $"4845 5220 5041 5254 4945 530D 5052 4F56" /* HER PARTIES.PROV */
- $"4944 4520 5448 4520 5052 4F47 5241 4D20" /* IDE THE PROGRAM */
- $"2241 5320 4953 2220 5749 5448 4F55 5420" /* "AS IS" WITHOUT */
- $"5741 5252 414E 5459 204F 4620 414E 5920" /* WARRANTY OF ANY */
- $"4B49 4E44 2C20 4549 5448 4552 2045 5850" /* KIND, EITHER EXP */
- $"5245 5353 4544 0D4F 5220 494D 504C 4945" /* RESSED.OR IMPLIE */
- $"442C 2049 4E43 4C55 4449 4E47 2C20 4255" /* D, INCLUDING, BU */
- $"5420 4E4F 5420 4C49 4D49 5445 4420 544F" /* T NOT LIMITED TO */
- $"2C20 5448 4520 494D 504C 4945 4420 5741" /* , THE IMPLIED WA */
- $"5252 414E 5449 4553 204F 460D 4D45 5243" /* RRANTIES OF.MERC */
- $"4841 4E54 4142 494C 4954 5920 414E 4420" /* HANTABILITY AND */
- $"4649 544E 4553 5320 464F 5220 4120 5041" /* FITNESS FOR A PA */
- $"5254 4943 554C 4152 2050 5552 504F 5345" /* RTICULAR PURPOSE */
- $"2E20 2054 4845 2045 4E54 4952 4520 5249" /* . THE ENTIRE RI */
- $"534B 2041 530D 544F 2054 4845 2051 5541" /* SK AS.TO THE QUA */
- $"4C49 5459 2041 4E44 2050 4552 464F 524D" /* LITY AND PERFORM */
- $"414E 4345 204F 4620 5448 4520 5052 4F47" /* ANCE OF THE PROG */
- $"5241 4D20 4953 2057 4954 4820 594F 552E" /* RAM IS WITH YOU. */
- $"2020 5348 4F55 4C44 2054 4845 0D50 524F" /* SHOULD THE.PRO */
- $"4752 414D 2050 524F 5645 2044 4546 4543" /* GRAM PROVE DEFEC */
- $"5449 5645 2C20 594F 5520 4153 5355 4D45" /* TIVE, YOU ASSUME */
- $"2054 4845 2043 4F53 5420 4F46 2041 4C4C" /* THE COST OF ALL */
- $"204E 4543 4553 5341 5259 2053 4552 5649" /* NECESSARY SERVI */
- $"4349 4E47 2C0D 5245 5041 4952 204F 5220" /* CING,.REPAIR OR */
- $"434F 5252 4543 5449 4F4E 2E0D 0D20 2031" /* CORRECTION... 1 */
- $"322E 2049 4E20 4E4F 2045 5645 4E54 2055" /* 2. IN NO EVENT U */
- $"4E4C 4553 5320 5245 5155 4952 4544 2042" /* NLESS REQUIRED B */
- $"5920 4150 504C 4943 4142 4C45 204C 4157" /* Y APPLICABLE LAW */
- $"204F 5220 4147 5245 4544 2054 4F20 494E" /* OR AGREED TO IN */
- $"2057 5249 5449 4E47 0D57 494C 4C20 414E" /* WRITING.WILL AN */
- $"5920 434F 5059 5249 4748 5420 484F 4C44" /* Y COPYRIGHT HOLD */
- $"4552 2C20 4F52 2041 4E59 204F 5448 4552" /* ER, OR ANY OTHER */
- $"2050 4152 5459 2057 484F 204D 4159 204D" /* PARTY WHO MAY M */
- $"4F44 4946 5920 414E 442F 4F52 0D52 4544" /* ODIFY AND/OR.RED */
- $"4953 5452 4942 5554 4520 5448 4520 5052" /* ISTRIBUTE THE PR */
- $"4F47 5241 4D20 4153 2050 4552 4D49 5454" /* OGRAM AS PERMITT */
- $"4544 2041 424F 5645 2C20 4245 204C 4941" /* ED ABOVE, BE LIA */
- $"424C 4520 544F 2059 4F55 2046 4F52 2044" /* BLE TO YOU FOR D */
- $"414D 4147 4553 2C0D 494E 434C 5544 494E" /* AMAGES,.INCLUDIN */
- $"4720 414E 5920 4745 4E45 5241 4C2C 2053" /* G ANY GENERAL, S */
- $"5045 4349 414C 2C20 494E 4349 4445 4E54" /* PECIAL, INCIDENT */
- $"414C 204F 5220 434F 4E53 4551 5545 4E54" /* AL OR CONSEQUENT */
- $"4941 4C20 4441 4D41 4745 5320 4152 4953" /* IAL DAMAGES ARIS */
- $"494E 470D 4F55 5420 4F46 2054 4845 2055" /* ING.OUT OF THE U */
- $"5345 204F 5220 494E 4142 494C 4954 5920" /* SE OR INABILITY */
- $"544F 2055 5345 2054 4845 2050 524F 4752" /* TO USE THE PROGR */
- $"414D 2028 494E 434C 5544 494E 4720 4255" /* AM (INCLUDING BU */
- $"5420 4E4F 5420 4C49 4D49 5445 440D 544F" /* T NOT LIMITED.TO */
- $"204C 4F53 5320 4F46 2044 4154 4120 4F52" /* LOSS OF DATA OR */
- $"2044 4154 4120 4245 494E 4720 5245 4E44" /* DATA BEING REND */
- $"4552 4544 2049 4E41 4343 5552 4154 4520" /* ERED INACCURATE */
- $"4F52 204C 4F53 5345 5320 5355 5354 4149" /* OR LOSSES SUSTAI */
- $"4E45 4420 4259 0D59 4F55 204F 5220 5448" /* NED BY.YOU OR TH */
- $"4952 4420 5041 5254 4945 5320 4F52 2041" /* IRD PARTIES OR A */
- $"2046 4149 4C55 5245 204F 4620 5448 4520" /* FAILURE OF THE */
- $"5052 4F47 5241 4D20 544F 204F 5045 5241" /* PROGRAM TO OPERA */
- $"5445 2057 4954 4820 414E 5920 4F54 4845" /* TE WITH ANY OTHE */
- $"520D 5052 4F47 5241 4D53 292C 2045 5645" /* R.PROGRAMS), EVE */
- $"4E20 4946 2053 5543 4820 484F 4C44 4552" /* N IF SUCH HOLDER */
- $"204F 5220 4F54 4845 5220 5041 5254 5920" /* OR OTHER PARTY */
- $"4841 5320 4245 454E 2041 4456 4953 4544" /* HAS BEEN ADVISED */
- $"204F 4620 5448 450D 504F 5353 4942 494C" /* OF THE.POSSIBIL */
- $"4954 5920 4F46 2053 5543 4820 4441 4D41" /* ITY OF SUCH DAMA */
- $"4745 532E 0D0D 0909 2020 2020 2045 4E44" /* GES...ÆÆ END */
- $"204F 4620 5445 524D 5320 414E 4420 434F" /* OF TERMS AND CO */
- $"4E44 4954 494F 4E53 0D0C 0D09 2020 2020" /* NDITIONS...Æ */
- $"486F 7720 746F 2041 7070 6C79 2054 6865" /* How to Apply The */
- $"7365 2054 6572 6D73 2074 6F20 596F 7572" /* se Terms to Your */
- $"204E 6577 2050 726F 6772 616D 730D 0D20" /* New Programs.. */
- $"2049 6620 796F 7520 6465 7665 6C6F 7020" /* If you develop */
- $"6120 6E65 7720 7072 6F67 7261 6D2C 2061" /* a new program, a */
- $"6E64 2079 6F75 2077 616E 7420 6974 2074" /* nd you want it t */
- $"6F20 6265 206F 6620 7468 6520 6772 6561" /* o be of the grea */
- $"7465 7374 0D70 6F73 7369 626C 6520 7573" /* test.possible us */
- $"6520 746F 2074 6865 2070 7562 6C69 632C" /* e to the public, */
- $"2074 6865 2062 6573 7420 7761 7920 746F" /* the best way to */
- $"2061 6368 6965 7665 2074 6869 7320 6973" /* achieve this is */
- $"2074 6F20 6D61 6B65 2069 740D 6672 6565" /* to make it.free */
- $"2073 6F66 7477 6172 6520 7768 6963 6820" /* software which */
- $"6576 6572 796F 6E65 2063 616E 2072 6564" /* everyone can red */
- $"6973 7472 6962 7574 6520 616E 6420 6368" /* istribute and ch */
- $"616E 6765 2075 6E64 6572 2074 6865 7365" /* ange under these */
- $"2074 6572 6D73 2E0D 0D20 2054 6F20 646F" /* terms... To do */
- $"2073 6F2C 2061 7474 6163 6820 7468 6520" /* so, attach the */
- $"666F 6C6C 6F77 696E 6720 6E6F 7469 6365" /* following notice */
- $"7320 746F 2074 6865 2070 726F 6772 616D" /* s to the program */
- $"2E20 2049 7420 6973 2073 6166 6573 740D" /* . It is safest. */
- $"746F 2061 7474 6163 6820 7468 656D 2074" /* to attach them t */
- $"6F20 7468 6520 7374 6172 7420 6F66 2065" /* o the start of e */
- $"6163 6820 736F 7572 6365 2066 696C 6520" /* ach source file */
- $"746F 206D 6F73 7420 6566 6665 6374 6976" /* to most effectiv */
- $"656C 790D 636F 6E76 6579 2074 6865 2065" /* ely.convey the e */
- $"7863 6C75 7369 6F6E 206F 6620 7761 7272" /* xclusion of warr */
- $"616E 7479 3B20 616E 6420 6561 6368 2066" /* anty; and each f */
- $"696C 6520 7368 6F75 6C64 2068 6176 6520" /* ile should have */
- $"6174 206C 6561 7374 0D74 6865 2022 636F" /* at least.the "co */
- $"7079 7269 6768 7422 206C 696E 6520 616E" /* pyright" line an */
- $"6420 6120 706F 696E 7465 7220 746F 2077" /* d a pointer to w */
- $"6865 7265 2074 6865 2066 756C 6C20 6E6F" /* here the full no */
- $"7469 6365 2069 7320 666F 756E 642E 0D0D" /* tice is found... */
- $"2020 2020 3C6F 6E65 206C 696E 6520 746F" /* . */
- $"436F 7079 7269 6768 7420 2843 2920 3139" /* Copyright (C) 19 */
- $"7979 2020 3C6E 616D 6520 6F66 2061 7574" /* yy .. This p */
- $"726F 6772 616D 2069 7320 6672 6565 2073" /* rogram is free s */
- $"6F66 7477 6172 653B 2079 6F75 2063 616E" /* oftware; you can */
- $"2072 6564 6973 7472 6962 7574 6520 6974" /* redistribute it */
- $"2061 6E64 2F6F 7220 6D6F 6469 6679 0D20" /* and/or modify. */
- $"2020 2069 7420 756E 6465 7220 7468 6520" /* it under the */
- $"7465 726D 7320 6F66 2074 6865 2047 4E55" /* terms of the GNU */
- $"2047 656E 6572 616C 2050 7562 6C69 6320" /* General Public */
- $"4C69 6365 6E73 6520 6173 2070 7562 6C69" /* License as publi */
- $"7368 6564 2062 790D 2020 2020 7468 6520" /* shed by. the */
- $"4672 6565 2053 6F66 7477 6172 6520 466F" /* Free Software Fo */
- $"756E 6461 7469 6F6E 3B20 6569 7468 6572" /* undation; either */
- $"2076 6572 7369 6F6E 2032 206F 6620 7468" /* version 2 of th */
- $"6520 4C69 6365 6E73 652C 206F 720D 2020" /* e License, or. */
- $"2020 2861 7420 796F 7572 206F 7074 696F" /* (at your optio */
- $"6E29 2061 6E79 206C 6174 6572 2076 6572" /* n) any later ver */
- $"7369 6F6E 2E0D 0D20 2020 2054 6869 7320" /* sion... This */
- $"7072 6F67 7261 6D20 6973 2064 6973 7472" /* program is distr */
- $"6962 7574 6564 2069 6E20 7468 6520 686F" /* ibuted in the ho */
- $"7065 2074 6861 7420 6974 2077 696C 6C20" /* pe that it will */
- $"6265 2075 7365 6675 6C2C 0D20 2020 2062" /* be useful,. b */
- $"7574 2057 4954 484F 5554 2041 4E59 2057" /* ut WITHOUT ANY W */
- $"4152 5241 4E54 593B 2077 6974 686F 7574" /* ARRANTY; without */
- $"2065 7665 6E20 7468 6520 696D 706C 6965" /* even the implie */
- $"6420 7761 7272 616E 7479 206F 660D 2020" /* d warranty of. */
- $"2020 4D45 5243 4841 4E54 4142 494C 4954" /* MERCHANTABILIT */
- $"5920 6F72 2046 4954 4E45 5353 2046 4F52" /* Y or FITNESS FOR */
- $"2041 2050 4152 5449 4355 4C41 5220 5055" /* A PARTICULAR PU */
- $"5250 4F53 452E 2020 5365 6520 7468 650D" /* RPOSE. See the. */
- $"2020 2020 474E 5520 4765 6E65 7261 6C20" /* GNU General */
- $"5075 626C 6963 204C 6963 656E 7365 2066" /* Public License f */
- $"6F72 206D 6F72 6520 6465 7461 696C 732E" /* or more details. */
- $"0D0D 2020 2020 596F 7520 7368 6F75 6C64" /* .. You should */
- $"2068 6176 6520 7265 6365 6976 6564 2061" /* have received a */
- $"2063 6F70 7920 6F66 2074 6865 2047 4E55" /* copy of the GNU */
- $"2047 656E 6572 616C 2050 7562 6C69 6320" /* General Public */
- $"4C69 6365 6E73 650D 2020 2020 616C 6F6E" /* License. alon */
- $"6720 7769 7468 2074 6869 7320 7072 6F67" /* g with this prog */
- $"7261 6D3B 2069 6620 6E6F 742C 2077 7269" /* ram; if not, wri */
- $"7465 2074 6F20 7468 6520 4672 6565 2053" /* te to the Free S */
- $"6F66 7477 6172 650D 2020 2020 466F 756E" /* oftware. Foun */
- $"6461 7469 6F6E 2C20 496E 632E 2C20 3539" /* dation, Inc., 59 */
- $"2054 656D 706C 6520 506C 6163 652C 2053" /* Temple Place, S */
- $"7569 7465 2033 3330 2C20 426F 7374 6F6E" /* uite 330, Boston */
- $"2C20 4D41 2020 3032 3131 312D 3133 3037" /* , MA 02111-1307 */
- $"2020 5553 410D 0D0D 416C 736F 2061 6464" /* USA...Also add */
- $"2069 6E66 6F72 6D61 7469 6F6E 206F 6E20" /* information on */
- $"686F 7720 746F 2063 6F6E 7461 6374 2079" /* how to contact y */
- $"6F75 2062 7920 656C 6563 7472 6F6E 6963" /* ou by electronic */
- $"2061 6E64 2070 6170 6572 206D 6169 6C2E" /* and paper mail. */
- $"0D0D 4966 2074 6865 2070 726F 6772 616D" /* ..If the program */
- $"2069 7320 696E 7465 7261 6374 6976 652C" /* is interactive, */
- $"206D 616B 6520 6974 206F 7574 7075 7420" /* make it output */
- $"6120 7368 6F72 7420 6E6F 7469 6365 206C" /* a short notice l */
- $"696B 6520 7468 6973 0D77 6865 6E20 6974" /* ike this.when it */
- $"2073 7461 7274 7320 696E 2061 6E20 696E" /* starts in an in */
- $"7465 7261 6374 6976 6520 6D6F 6465 3A0D" /* teractive mode:. */
- $"0D20 2020 2047 6E6F 6D6F 7669 7369 6F6E" /* . Gnomovision */
- $"2076 6572 7369 6F6E 2036 392C 2043 6F70" /* version 69, Cop */
- $"7972 6967 6874 2028 4329 2031 3979 7920" /* yright (C) 19yy */
- $"6E61 6D65 206F 6620 6175 7468 6F72 0D20" /* name of author. */
- $"2020 2047 6E6F 6D6F 7669 7369 6F6E 2063" /* Gnomovision c */
- $"6F6D 6573 2077 6974 6820 4142 534F 4C55" /* omes with ABSOLU */
- $"5445 4C59 204E 4F20 5741 5252 414E 5459" /* TELY NO WARRANTY */
- $"3B20 666F 7220 6465 7461 696C 7320 7479" /* ; for details ty */
- $"7065 2060 7368 6F77 2077 272E 0D20 2020" /* pe `show w'.. */
- $"2054 6869 7320 6973 2066 7265 6520 736F" /* This is free so */
- $"6674 7761 7265 2C20 616E 6420 796F 7520" /* ftware, and you */
- $"6172 6520 7765 6C63 6F6D 6520 746F 2072" /* are welcome to r */
- $"6564 6973 7472 6962 7574 6520 6974 0D20" /* edistribute it. */
- $"2020 2075 6E64 6572 2063 6572 7461 696E" /* under certain */
- $"2063 6F6E 6469 7469 6F6E 733B 2074 7970" /* conditions; typ */
- $"6520 6073 686F 7720 6327 2066 6F72 2064" /* e `show c' for d */
- $"6574 6169 6C73 2E0D 0D54 6865 2068 7970" /* etails...The hyp */
- $"6F74 6865 7469 6361 6C20 636F 6D6D 616E" /* othetical comman */
- $"6473 2060 7368 6F77 2077 2720 616E 6420" /* ds `show w' and */
- $"6073 686F 7720 6327 2073 686F 756C 6420" /* `show c' should */
- $"7368 6F77 2074 6865 2061 7070 726F 7072" /* show the appropr */
- $"6961 7465 0D70 6172 7473 206F 6620 7468" /* iate.parts of th */
- $"6520 4765 6E65 7261 6C20 5075 626C 6963" /* e General Public */
- $"204C 6963 656E 7365 2E20 204F 6620 636F" /* License. Of co */
- $"7572 7365 2C20 7468 6520 636F 6D6D 616E" /* urse, the comman */
- $"6473 2079 6F75 2075 7365 206D 6179 0D62" /* ds you use may.b */
- $"6520 6361 6C6C 6564 2073 6F6D 6574 6869" /* e called somethi */
- $"6E67 206F 7468 6572 2074 6861 6E20 6073" /* ng other than `s */
- $"686F 7720 7727 2061 6E64 2060 7368 6F77" /* how w' and `show */
- $"2063 273B 2074 6865 7920 636F 756C 6420" /* c'; they could */
- $"6576 656E 2062 650D 6D6F 7573 652D 636C" /* even be.mouse-cl */
- $"6963 6B73 206F 7220 6D65 6E75 2069 7465" /* icks or menu ite */
- $"6D73 2D2D 7768 6174 6576 6572 2073 7569" /* ms--whatever sui */
- $"7473 2079 6F75 7220 7072 6F67 7261 6D2E" /* ts your program. */
- $"0D0D 596F 7520 7368 6F75 6C64 2061 6C73" /* ..You should als */
- $"6F20 6765 7420 796F 7572 2065 6D70 6C6F" /* o get your emplo */
- $"7965 7220 2869 6620 796F 7520 776F 726B" /* yer (if you work */
- $"2061 7320 6120 7072 6F67 7261 6D6D 6572" /* as a programmer */
- $"2920 6F72 2079 6F75 720D 7363 686F 6F6C" /* ) or your.school */
- $"2C20 6966 2061 6E79 2C20 746F 2073 6967" /* , if any, to sig */
- $"6E20 6120 2263 6F70 7972 6967 6874 2064" /* n a "copyright d */
- $"6973 636C 6169 6D65 7222 2066 6F72 2074" /* isclaimer" for t */
- $"6865 2070 726F 6772 616D 2C20 6966 0D6E" /* he program, if.n */
- $"6563 6573 7361 7279 2E20 2048 6572 6520" /* ecessary. Here */
- $"6973 2061 2073 616D 706C 653B 2061 6C74" /* is a sample; alt */
- $"6572 2074 6865 206E 616D 6573 3A0D 0D20" /* er the names:.. */
- $"2059 6F79 6F64 796E 652C 2049 6E63 2E2C" /* Yoyodyne, Inc., */
- $"2068 6572 6562 7920 6469 7363 6C61 696D" /* hereby disclaim */
- $"7320 616C 6C20 636F 7079 7269 6768 7420" /* s all copyright */
- $"696E 7465 7265 7374 2069 6E20 7468 6520" /* interest in the */
- $"7072 6F67 7261 6D0D 2020 6047 6E6F 6D6F" /* program. `Gnomo */
- $"7669 7369 6F6E 2720 2877 6869 6368 206D" /* vision' (which m */
- $"616B 6573 2070 6173 7365 7320 6174 2063" /* akes passes at c */
- $"6F6D 7069 6C65 7273 2920 7772 6974 7465" /* ompilers) writte */
- $"6E20 6279 204A 616D 6573 2048 6163 6B65" /* n by James Hacke */
- $"722E 0D0D 2020 3C73 6967 6E61 7475 7265" /* r... , 1 */
- $"4170 7269 6C20 3139 3839 0D20 2054 7920" /* April 1989. Ty */
- $"436F 6F6E 2C20 5072 6573 6964 656E 7420" /* Coon, President */
- $"6F66 2056 6963 650D 0D54 6869 7320 4765" /* of Vice..This Ge */
- $"6E65 7261 6C20 5075 626C 6963 204C 6963" /* neral Public Lic */
- $"656E 7365 2064 6F65 7320 6E6F 7420 7065" /* ense does not pe */
- $"726D 6974 2069 6E63 6F72 706F 7261 7469" /* rmit incorporati */
- $"6E67 2079 6F75 7220 7072 6F67 7261 6D20" /* ng your program */
- $"696E 746F 0D70 726F 7072 6965 7461 7279" /* into.proprietary */
- $"2070 726F 6772 616D 732E 2020 4966 2079" /* programs. If y */
- $"6F75 7220 7072 6F67 7261 6D20 6973 2061" /* our program is a */
- $"2073 7562 726F 7574 696E 6520 6C69 6272" /* subroutine libr */
- $"6172 792C 2079 6F75 206D 6179 0D63 6F6E" /* ary, you may.con */
- $"7369 6465 7220 6974 206D 6F72 6520 7573" /* sider it more us */
- $"6566 756C 2074 6F20 7065 726D 6974 206C" /* eful to permit l */
- $"696E 6B69 6E67 2070 726F 7072 6965 7461" /* inking proprieta */
- $"7279 2061 7070 6C69 6361 7469 6F6E 7320" /* ry applications */
- $"7769 7468 2074 6865 0D6C 6962 7261 7279" /* with the.library */
- $"2E20 2049 6620 7468 6973 2069 7320 7768" /* . If this is wh */
- $"6174 2079 6F75 2077 616E 7420 746F 2064" /* at you want to d */
- $"6F2C 2075 7365 2074 6865 2047 4E55 204C" /* o, use the GNU L */
- $"6962 7261 7279 2047 656E 6572 616C 0D50" /* ibrary General.P */
- $"7562 6C69 6320 4C69 6365 6E73 6520 696E" /* ublic License in */
- $"7374 6561 6420 6F66 2074 6869 7320 4C69" /* stead of this Li */
- $"6365 6E73 652E 0D" /* cense.. */
-};
-
-data 'LPic' (5000) {
- $"0000 0001 0000 0000 0000" /* .......... */
-};
-
-data 'styl' (5000, "English") {
- $"0001 0000 0000 000C 0009 0015 0030 000C" /* .........Æ...0.. */
- $"0000 0000 0000" /* ...... */
-};
diff --git a/MacBuild/HOWTO b/MacBuild/HOWTO
deleted file mode 100644
index 184b51b..0000000
--- a/MacBuild/HOWTO
+++ /dev/null
@@ -1,18 +0,0 @@
-Don't.
-
-If you still want to, here's my terse step by step guide. I only know that this works in Snow Leopard on my mac. It might not work for you.
-1) Get python 2.6 from http://www.python.org/ftp/python/2.5.6/Python-2.5.6.tgz
-2) Compile it, using configure_python.sh in this directory. It expects to be placed one directory up from python, simply because I compiled everything from ~/python_compile/
-3) export PATH=/Library/Frameworks/Python.framework/Versions/2.6/bin/:$PATH for both you and root. Confirm with `which python`
-4) sudo su; easy_install pygame; easy_install py2app
-5) Get the QT library from http://qt.nokia.com/downloads/qt-for-open-source-cpp-development-on-mac-os-x/. Do not even consider
- trying to compile this whore of a library yourself, it's not worth it. Get the precompiled for your system. Install it.
-6) Get SIP from http://www.riverbankcomputing.co.uk/software/sip/download and compile it, making sure to use configure_sip.sh.
-7) Get PyQt4 from http://www.riverbankcomputing.co.uk/software/pyqt/download and compile it, also with my configure script (configure_pyqt4.sh). This will take ages.
-8) ./py2app.sh and wait for it to build everything and make itself into a purdy DMG
-9) Rejoice that you didn't have to spend two weeks compiling hundreds of versions of all things mentioned here, including an entire day simply waiting for QT to compile by
- itself on the offchance that this would make it work.
-
-If you want to make a nicer looking dmg file, play with dmg_background.png
-
-~Lex
diff --git a/MacBuild/configure_pyqt4.sh b/MacBuild/configure_pyqt4.sh
deleted file mode 100755
index ade4b0c..0000000
--- a/MacBuild/configure_pyqt4.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-echo "Lexi's lazy configuration. This is not an official configure script. Press enter to confirm this."
-read confirm
-if [ ! -d pyqt4 ]
-then
- echo "Rename your pyqt4 folder to pyqt4."
- exit 1
-fi
-cd pyqt4
-if [ -e makefile ]
-then
- make clean
-fi
-python configure.py \
- --confirm-license \
- --use-arch=i386 \
- --use-arch=x86_64 \
- --destdir=/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages \
- --verbose
-echo "---~ Done ~---"
diff --git a/MacBuild/configure_python.sh b/MacBuild/configure_python.sh
deleted file mode 100755
index 3ecb051..0000000
--- a/MacBuild/configure_python.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-#
-# Lexi's ./configure script
-#
-echo "Lexi's lazy configuration. This is not an official configure script. Press enter to confirm this."
-read confirm
-if [ ! -d python ]
-then
- echo "Rename your python folder to python."
- exit 1
-fi
-cd python
-if [ ! -d python ]
-then
- echo "Rename your python folder to python."
- exit 1
-fi
-if [ -e makefile ]
-then
- make clean
-fi
-./configure --enable-framework --enable-universalsdk=/ --with-universal-archs=intel MACOSX_DEPLOYMENT_TARGET=10.5
-echo "---~ Done ~---"
diff --git a/MacBuild/configure_sip.sh b/MacBuild/configure_sip.sh
deleted file mode 100755
index e8b66a1..0000000
--- a/MacBuild/configure_sip.sh
+++ /dev/null
@@ -1,21 +0,0 @@
-#!/bin/bash
-#
-# Lexi's Configurations
-#
-
-echo "Lexi's lazy configuration. This is not an official configure script. Press enter to confirm this."
-read confirm
-if [ ! -d sip ]
-then
- echo "Rename your sip folder to sip."
- exit 1
-fi
-cd sip
-if [ -e makefile ]
-then
- make clean
-fi
-python configure.py --arch=i386 --arch=x86_64 \
- --universal --deployment-target=10.5 \
- --destdir=/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/
-echo "---~ Done ~---"
diff --git a/MacBuild/conv3rt.sh b/MacBuild/conv3rt.sh
deleted file mode 100644
index d6656d5..0000000
--- a/MacBuild/conv3rt.sh
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/bin/bash
-# Lex's gif->png script
-
-for file in *.gif
-do
- convert ${file} ${file:0:$((${#file}-3))}"png"
-done
-
-for file in `ls | grep -G -e "-[1-9]\+.png"`
-do
- rm $file
-done
-
-for file in `ls | grep -e "-0.png"`
-do
- newfile=`echo $file | sed -e 's|\(.*\)-0.png|\1.png|'`
- mv $file $newfile
-done
-
-# for file in *.gif
-# do
-# rm ${file:0:$((${#file}-3))}"png"
-# done
diff --git a/MacBuild/dmg_background.png b/MacBuild/dmg_background.png
deleted file mode 100644
index 236deb6..0000000
Binary files a/MacBuild/dmg_background.png and /dev/null differ
diff --git a/MacBuild/dmg_background.xcf b/MacBuild/dmg_background.xcf
deleted file mode 100644
index 94246a2..0000000
Binary files a/MacBuild/dmg_background.xcf and /dev/null differ
diff --git a/Makefile b/Makefile
deleted file mode 100644
index 7cb7398..0000000
--- a/Makefile
+++ /dev/null
@@ -1,36 +0,0 @@
-PYTHON2_CMD ?= /usr/bin/python
-
-PREFIX ?= /usr/local
-LIBINSTALLDIR ?= /lib
-XDGCONFDIR ?= /etc/xdg
-
-PESTERCHUMBINDIR = ${DESTDIR}${PREFIX}/bin
-PESTERCHUMLIBDIR = $(DESTDIR)$(PREFIX)$(LIBINSTALLDIR)/pesterchum
-
-all:
- @echo "Ready to install..."
-
-make-install-dirs:
- mkdir -p ${PESTERCHUMBINDIR}
- mkdir -p ${PESTERCHUMLIBDIR}
- mkdir -p ${PESTERCHUMLIBDIR}/libs
- mkdir -p ${PESTERCHUMLIBDIR}/oyoyo
- mkdir -p ${PESTERCHUMLIBDIR}/quirks
- mkdir -p ${PESTERCHUMLIBDIR}/smilies
- mkdir -p ${PESTERCHUMLIBDIR}/themes
-
-uninstall:
- rm -f ${PESTERCHUMBINDIR}/pesterchum
- rm -rf ${PESTERCHUMLIBDIR}
-
-install: make-install-dirs
- install -m 644 *.py ${PESTERCHUMLIBDIR}
- install -m 644 libs/*.py ${PESTERCHUMLIBDIR}/libs
- install -m 644 oyoyo/*.py ${PESTERCHUMLIBDIR}/oyoyo
- install -m 644 quirks/*.py ${PESTERCHUMLIBDIR}/quirks
- install -m 644 smilies/* ${PESTERCHUMLIBDIR}/smilies
- cp -r themes/* ${PESTERCHUMLIBDIR}/themes
- @echo '#!/bin/sh' > ${PESTERCHUMBINDIR}/pesterchum
- @echo 'cd ${PREFIX}$(LIBINSTALLDIR)/pesterchum' >> ${PESTERCHUMBINDIR}/pesterchum
- @echo 'python2 pesterchum.py' >> ${PESTERCHUMBINDIR}/pesterchum
- chmod +x ${PESTERCHUMBINDIR}/pesterchum
diff --git a/PCskins.png b/PCskins.png
deleted file mode 100644
index da83820..0000000
Binary files a/PCskins.png and /dev/null differ
diff --git a/PYQUIRKS.mkdn b/PYQUIRKS.mkdn
deleted file mode 100644
index de4eb27..0000000
--- a/PYQUIRKS.mkdn
+++ /dev/null
@@ -1,88 +0,0 @@
-Python Quirk Functions
-===============
-
-Table of Contents
------------------
-1. Introduction
-2. Create A Module
-3. Functions In A Module
-4. Command Requirements
-5. Completed Quirk Function
-
-Introduction
----------------
-Over the course of this short tutorial you will learn:
-
-* How to create your own Quirk Functions
-* VERY basic Python syntax
-
-You will not learn:
-
-* How to write Python
-* How to bake a cake
-
-Throughout this tutorial there will be
-
-Instructions in special boxes.
-If you follow the instructions in these boxes, by the end of this tutorial
-you will have recreated the default reverse() Quirk Function.
-
-
-Create A Module
--------------------
-All Quirk Function Modules should be created in the 'quirks/' directory. File names must end in '.py'.
-You can have multiple Quirk Functions per Module.
-
-Each Module can also have a 'setup' function which will be called once, the moment the Module is loaded.
-
-
-Create 'reverse.py' in the 'quirks/' directory.
-
-
-Functions In A Module
---------------------------
-If you've ever done programming before, you should know what a function is. If not, I suggest picking up a good programming book (or e-book).
-
-In Python, function syntax looks like this:
-
-def function_name(myvar1, myvar2):
-
-'def' is used to declare that this is a function, and 'function_name' is obviously the name of your function.
-'myvar1' and 'myvar2' are variables coming into your function. For most of your functions, the only variable being passed will be 'text'.
-
-In Python, curly braces ({}) are not used to declare the beginning and end of a function. Instead, a colon (:) is used to declare the beginning of a function. After that, indentation is used to declare the body and end of a function.
-
-```python
-def reverserep(text):
- return text[::-1]
-```
-
-Command Requirements
-------------------------
-For a function to be registered as a Quirk Function, it must conform to three simple rules:
-
-1. It must have a command name.
-2. It must take exactly one arguement.
-3. It must return a string.
-
-What is meant by having a command name, is that a name for the Quirk Function has to be defined. This is done by defining the 'command' variable for a function.
-
-function_name.command = "name"
-
-```python
-reverserep.command = "reverse"
-```
-
-Completed Quirk Function
----------------------------
-Below is the completed, fully working, reverse Quirk Function. After it I will break down the pieces of each line.
-
-```python
-def reverserep(text):
- return text[::-1]
-reverserep.command = "reverse"
-```
-
-As stated before, to start a function, you need to use the keyword 'def'. All Quirk Functions must take exactly one argument (in this case 'text').
-In this example, the text is reversed and returned all in one line. 'text[::-1]' is the Pythonic way of reversing a list or string.
-The last line is the most important part. This tells Pesterchum to call this function whenever 'reverse()' is used in a quirk.
diff --git a/Pesterchum.png b/Pesterchum.png
deleted file mode 100644
index 4e76f52..0000000
Binary files a/Pesterchum.png and /dev/null differ
diff --git a/README-karxi.mkdn b/README-karxi.mkdn
deleted file mode 100644
index a2a86ce..0000000
--- a/README-karxi.mkdn
+++ /dev/null
@@ -1,184 +0,0 @@
-Welcome to Pesterchum 3.41!
-=============================
-
-## FOR NEW USERS
-This modification of Pesterchum is intended for people who are already familiar
-with using the base client.
-
-If you aren't, please check the standard build's [documentation][pchum-doc].
-
-[pchum-orig]: https://github.com/illuminatedwax/pesterchum
-[pchum-doc]: https://github.com/illuminatedwax/pesterchum/blob/master/README.mkdn
-
-## FOR EVERYONE ELSE
-Greetings! This is a modification of Pesterchum, made because Pesterchum is
-effectively no longer maintained, that is intended to fix a number of issues.
-
-The code used as a base is a newer version of Pesterchum than the one in
-circulation, and thus has plenty of useful features that can be found in the
-[CHANGELOG][changes].
-
-In addition, there are other features and improvements that have been made, and
-there are many more planned. Check the [TODO list][todo-done] to see what's
-been fixed, as well as what's [planned][todo-upcoming].
-
-[changes]: https://github.com/karxi/pesterchum/blob/master/CHANGELOG.mkdn
-[todo-done]: https://github.com/karxi/pesterchum/blob/master/TODO.mkdn#tododone
-[todo-upcoming]: https://github.com/karxi/pesterchum/blob/master/TODO.mkdn#features
-
-### Installation
-There isn't an automated installer yet, but the steps involved aren't all that
-difficult.
-
-#### Pitfalls
-* If you're on a 64-bit system (and most are these days), use those links. You
- can also use the 32 bit versions, if you choose, but you *cannot* mix them.
-* If you're on a 32-bit system but use the 64-bit installers, you'll get an
- error along the lines of "not a valid Win32 application", or the
- installer will simply fail.
-* This version of Pesterchum does not come compiled as an executable, and thus
- does not have Python/PyQt4 packaged with it. Those are necessary for
- Pesterchum to run, so you have to install them manually.
-
-#### First-Time Install
-Download links are for Windows, but a quick Google search will find everything
-necessary.
-
-1. Install **Python 2.7** or higher if you don't already have it:
- * [32 bit][python2-32]
- * [64 bit][python2-64]
-
- Be **sure** to add Python to the PATH if asked to do so during
- installation. It means Python will be usable from the console,
- which is necessary for this to run.
-
-2. Install **PyQt4**:
- * [32 bit][pyqt4-32]
- * [64 bit][pyqt4-64]
-
-3. **(LINUX)** Install **pygame**:
- * [pygame download page][pygame-dl]
- * You don't need to install this if you're using Windows. Linux users need
- to install it to enable sound, but it will otherwise work without it.
- * If you want to download this, you should probably do so using your native
- package manager.
-
-4. Download **Pesterchum**:
- * [Download from main branch][pchum-zip]
-
-5. Unzip Pesterchum somewhere easily-accessible.
-
-6. **If you have any custom themes**, copy/paste them into the 'themes' folder.
- You can find this in `%LOCALAPPDATA%\pesterchum`, which is the same as
- `%APPDATA%\..\Local\pesterchum`. Copy/paste one into Explorer's address bar
- and you'll end up where you need to be.
-
- Oftentimes the 'themes' folder doesn't exist in Pesterchum's user-specific
- config folder, so you'll have to make it and copy the custom themes into
- it.
-
- __If, for some reason, that doesn't work:__
-
- You can also copy the missing themes into the 'themes' folder of the version
- you just unzipped. **Don't overwrite any files** if you do this - the themes
- used by this have been updated, and the older default themes may break when
- used.
-
-7. Run Pesterchum! How you do this depends on the OS:
- * **(WINDOWS)** Run `w32-run-pchum.bat`.
- * **(LINUX)** Run `./pesterchum`, preferably via terminal.
- * Note that this is made to provide debugging information - so that if
- errors come up, they can be reported to me, and I can fix them.
-
-[python2-32]: https://www.python.org/ftp/python/2.7.12/python-2.7.12.msi
-[python2-64]: https://www.python.org/ftp/python/2.7.12/python-2.7.12.amd64.msi
-[pyqt4-32]: http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.11.4/PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe
-[pyqt4-64]: http://sourceforge.net/projects/pyqt/files/PyQt4/PyQt-4.11.4/PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x64.exe
-[pygame-dl]: http://www.pygame.org/download.shtml
-[pchum-zip]: https://github.com/karxi/pesterchum/archive/master.zip
-
-#### Upgrading
-**NOTE: This only applies to those who already have this patched Pesterchum
-installed.**
-**DO NOT extract this into a folder containing pesterchum.exe, because it WILL
-break.** Read up to **First-Time Install** if you're installing this version
-for the first time.
-Otherwise...
-
-Just re-download the [Pesterchum zip][pchum-zip] and extract it over your old
-installation, replacing everything that was already there. That's all there is
-to it!
-
-#### Having Problems?
-I can't offer much help in this regard; if you're getting errors, feel free to
-try to contact me, but if you're having trouble with the installers, there's
-little I can do. [How to install Python][howtogetpython] might help; failing
-that, Google saves lives.
-
-[howtogetpython]: http://www.howtogeek.com/197947/how-to-install-python-on-windows/
-
-
-
-SMILIES
--------
-None of the smilies have changed or been added, yet; this list is kept for
-posterity and easy reference.
-
-* `:rancorous:`
-* `:apple:`
-* `:bathearst:`
-* `:cathearst:`
-* `:woeful:`
-* `:pleasant:`
-* `:blueghost:`
-* `:slimer:`
-* `:candycorn:`
-* `:cheer:`
-* `:duhjohn:`
-* `:datrump:`
-* `:facepalm:`
-* `:bonk:`
-* `:mspa:`
-* `:gun:`
-* `:cal:`
-* `:amazedfirman:`
-* `:amazed:`
-* `:chummy:`
-* `:cool:`
-* `:smooth:`
-* `:distraughtfirman:`
-* `:distraught:`
-* `:insolent:`
-* `:bemused:`
-* `:3:`
-* `:mystified:`
-* `:pranky:`
-* `:tense:`
-* `:record:`
-* `:squiddle:`
-* `:tab:`
-* `:beetip:`
-* `:flipout:`
-* `:befuddled:`
-* `:pumpkin:`
-* `:trollcool:`
-* `:jadecry:`
-* `:ecstatic:`
-* `:relaxed:`
-* `:discontent:`
-* `:devious:`
-* `:sleek:`
-* `:detestful:`
-* `:mirthful:`
-* `:manipulative:`
-* `:vigorous:`
-* `:perky:`
-* `:acceptant:`
-* `:olliesouty:`
-* `:billiards:`
-* `:billiardslarge:`
-* `:whatdidyoudo:`
-
-
-
-[modeline]: vim:set autoindent ts=4 sts=4 sw=4 tw=79 expandtab:
diff --git a/README-pesterchum.mkdn b/README-pesterchum.mkdn
deleted file mode 100644
index 6b7c6c4..0000000
--- a/README-pesterchum.mkdn
+++ /dev/null
@@ -1,840 +0,0 @@
-Welcome to Pesterchum 3.41!
-=============================
-
-WHAT'S NEW?
------------
-* Check out the CHANGELOG file to see what's changed!
-
-What do I do now?
------------------
-
-Most questions can be answered by visiting the forums! Go to HELP->HELP
-and you'll be transported to the proper thread!
-
-Here's some tips to help you get started:
------------------------------------------
-
-- Some themes can be confusing if you haven't used the program
-already! Some hints:
- * Trollian: Moods are set by clicking the timelines, and you
-can add chums by clicking "Chumproll." Moods correspond to the troll
-that would most likely exhibit them. You can go offline by hitting the
-"Timelines" menu bar.
-
- * Gold: Add chums by hitting the two chumpeoples in the upper left
-corner. Go offline by clicking the "CHUMHANDLE:" label.
-
- * Enamel: Add chums by hitting the "CHUMROLL" label. Go offline by
-clicking the upper left hand corner.
-
-- Right-click is your friend! There are useful right click
-options on the chumroll, by clicking the chumhandle in a conversation,
-online userlist, or the list of memo browsers.
-
-Cool features:
---------------
-
-- Profile switching. Instantly switch profiles, loading your color and
-quirks with it.
-- Theme switching and creation. So far this comes with a few official
-themes! But you can also make your own: just make a new directory in
-the themes folder with the proper images and style.js file. The
-style.js file will be documented soon, but feel free to poke at it.
-- Memos. Memos that are a lot more like the ones in the comic and
-allow you to appear at multiple times in one chat.
-- Quirks: Prefix, suffix, simple replace, regexp replace (like in
-2.5), random replacement, and an auto-mispeller :P
-- Chum groups. Organize your chums into collapsible groups for easy
-management.
-- Block/user list
-- Add/block chums directly from a conversation, the userlist, or memo
-userlist.
-- Timestamps saved in logs and shown in conversations if wanted.
-- Logging. Logs are output in bbcode (for easy forum posting), html,
-and plain text.
-- Logviewer for easy log reading inside Pesterchum
-- Idling. You can set yourself idle manually, and the computer will
-set it for you after a configurable amount of time.
-- Improved /me. Any letters immediately following /me will be
-processed correctly. e.g. /me'd rather be fishing -> `-- ghostDunk'd
-[GD'D] rather be fishing --`
-- Hyperlinks! Now if someone types http://whatever it will turn into a
-link you can just click and follow. No more copy/paste.
-- Memo links. Link your friends to your memos.
-- Smilies. We've added about 30-40 smilies from the forums. There is a
-list later on in this readme.
-- Submit quotes directly to the Pesterchum QDB!
-
-FA%
----
-__Q:__ Norton says it has a virus and then deletes it!
-__A:__ Read this helpful Norton FAQ:
-
-Alright, here's a guide to by-passing Norton:
-
-* First, to download Pesterchum:
- 1. Make sure you're on a Moderator account. Moreso for the Norton steps than these ones.
- 2. Download the .zip file, not the .exe file.
- 3. Unzip the .zip file onto memory. Pesterchum should now be installed.
-
-* Now, to by-pass Norton:
- 1. Make sure you're still on a moderator account.
- 2. Open up Norton.
- 3. Click on 'Settings' up in the upperright hand corner.
- 4. Click on 'Anitivirus', off to the upper left. It has a small image of a needle or something similar off to it's side.
- 5. There's a word that reads 'SONAR protection' halfway to the bottomleft. Off to it's right, there's a bar that's half green. Click on the bar.
- 6. It will warn you about turning off SONAR. Have it set to turn back on when the system restarts.
- 7. If done properly, the background for the main page of Norton(what you saw on steps 2-3) has turned an apocaliptic red. Feel free to close Norton now. Keep in mind to stay off suspicious online sites now.
- 8. Open up Pesterchum, and let the chummy convos begin.
-
-* When finished:
- 1. Log off of Pesterchum. LOG OFF, NOT CLOSE IT.
- 2. Then, you can either shut off your comp, and Norton will re-enable SONAR, or you can repeat steps 1-5, except turning the red bar green. If done right, Norton will be it's happy color again.
- 3, Keep in mind that you must repeat all of this(other than the download) every time you want to get on Pesterchum.
-
-* Hope this is helpful!
-
-(This guide brought to you by the slightly combined efforts of empireomega and Xanaomin)
-
-------------------------------------------------------------------------------------
-
-__Q:__ I can't connect because my school/university/network/stolen wifi is blocking my connection! OR I can't seem to connect to the server at all and I'm not running any firewalls!
-__A:__ Edit your pesterchum.js file. Open it up in notepad or something, and then edit the beginning so it looks like this:
-
-```
-{"port": "1413", ....
-```
-
-where the .... is the rest of the gobbledygook there.
-
-------------------------------------------------------------------------------------
-
-__Q:__ The mood buttons on Pesterchum 6.0 don't match up to what it sets your mood to! What gives?
-__A:__ The mood names are just there to look canon. It is intentional.
-
-------------------------------------------------------------------------------------
-
-__Q:__ I'm appearing as offline to 2.5 users/other users appear the wrong
-mood? What's happeninggggg
-__A:__ The 2.5 people decided to change the mood protocol. When I made
-this program, I decided to go with Tinychat's original protocol (and
-extend it). So some moods will appear wrong between 2.5
-users. (\*COUGH\*tell them to switch to 3.14\*COUGH\*)
-
-------------------------------------------------------------------------------------
-
-__Q:__ Pesterchum 2.5 users don't get my /me messages correctly!
-__A:__ That's because they implemented the /me command differently.
-
-------------------------------------------------------------------------------------
-
-__Q:__ Can we resize the main window?
-__A:__ No. This is done so we can offer more flexible UI creation. It's a
-lot easier to make themes that look canon this way.
-
-------------------------------------------------------------------------------------
-
-__Q:__ Can we have different chum rolls for different users?
-__A:__ No. Instead what we now have crum groups to organize people.
-
-------------------------------------------------------------------------------------
-
-__Q:__ Can we delete profiles?
-__A:__ Yes. Go to the profile switcher, choose a profile and press DELETE.
-
-------------------------------------------------------------------------------------
-
-__Q:__ You should make it so you can ban specific time frames in memos.
-__A:__ This was too complicated to implement, and I don't have the UI
-quite figured out. This will probably go in a future update.
-
-
-DOCUMENTATION
--------------
-
-STARTING
---------
-
-If this is your first time running Pesterchum 3.14, you need to create
-a new profile. Just type in your chum handle in the box and click the
-color swatch to pick your color. Check the "default" checkbox to make
-this your default profile.
-
-BASIC PESTERING
----------------
-
-To begin pestering, first click the "ADD CHUM" button and type in
-their pester handle. The handle must be all lower case except for one
-capital letter. Once you've added that person, they will appear on
-your chumroll. You can double click to begin pestering them, or
-right-click to bring up a menu where you can pester them, block them,
-or remove them from your chumroll. (Or you can select them and hit
-"enter" OR hit the "PESTER" button.)
-
-Once you begin pestering somebody (or they begin pestering you), it
-will bring up the conversation window. Here you can type to your
-chum. Also remember that if you right-click on the area just above the
-Pesterlog, it will bring up a list of options: Quirks Off will turn
-your quirks off, Add Chum will add this chum to your list, and Block
-will block them. (Those last two options are useful if you are being
-pestered by someone you don't have on your list yet!)
-
-While pestering your chum, here are some useful features:
-
-* Type /me to create a system message. "/me facepalms." will generate:
-
- ```
- -- ghostDunk [GD] facepalms. --
- ```
-
- You can also append 's after /me like so: "/me's computer exploded."
-
- ```
- -- ghostDunk's [GD'S] computer exploded. --
- ```
-
- In fact, any characters you type after a /me before the space will
- be added: "/meing is the Ghost Nation's official pastime."
-
- ```
- -- ghostDunking [GDING] is the Ghost Nation's official pastime. --
- ```
-
-* Color tags! If you feel the need to talk about The Green Sun or add
- some appleberry blast to your conversation, just use color
- tags. These work like in TC 1.5: `colored text`. But in
- PC 3.14, you can type your color in a lot of different ways:
-
- - You can use the familiar r,g,b method:
- `The Green Sun`
- - You can use HTML tags:
- `DURR I'M KARKAT AND I'M A HUGE IDIOT`
- - You can even use [plain color names](http://en.wikipedia.org/wiki/Web_colors):
- `D4V3 TH1S 1S SO D3C4D3NT`
- - You don't even have to add the `` if you are lazy. Just use a
- new color tag whenever you want to change colors and PC 3.14 will
- add the extra tags for you.
-
-* URLs (anything with `http://` or `www.` in front of it) will automatically be
- detected and made into a link you can CLICK.
-
-* You can also link people to memos by typing "#" and the name of the
- menu like so: #R41NBOW_RUMPUS_P4RTYTOWN
- Clicking the link will open up the memo select menu.
-
-* Smilies! There are a list of smilies at the end of this document;
- they are based on the MSPA Forum smilies.
-
-* Don't worry about your quirks screwing up any of the above: PC will
- apply your quirks AFTER it figures out color codes, links, smilies, etc.
-
-* Pressing the up arrow will cycle through a history of your comments,
- so if you want to retype something, you can pull it up.
-
-* You can submit directly to the Pesterchum Quote Database! If you
- have a particualarly awesome conversation, you can submit it to the
- database by simply highlighting the good part of the conversation,
- right clicking it and choosing "Submit to Pesterchum QDB!"
-
-
-MEMOS
------
-
-One of the most interesting features to make was the memos, and make
-them as close to the comic as I could without actually inventing time
-travel. So here is the TIME TUTORIAL:
-
-* __Joining:__ When you go CLIENT->MEMOS, you'll see a list of memos pop up
--- those are memos people already have open. To join one, just
-highlight one of them. If you want to make a new memo, just type it in
-the input. If you'd like to make it secret, so that it doesn't appear
-in the list, check "HIDDEN CHANNEL". Then, choose what timeframe you
-want to appear to be in. So if you wanted to be in the future, you
-could move the slider to the right. You can also enter the time
-manually. Then hit JOIN.
-
-* __Explaining time:__ Time in memos, unlike Homestuck, will not be relative
-to your position. That is, if you choose 4:13 in the future, you will
-not see someone who has set their time as "current" (or "0") in the
-past: you will see them as "current" and yourself as "future." This is
-because we do not have time travel! Memo time setting is basically an
-RP mechanic: you are pretending to be from the future! It will also
-help keep everyone straight: everyone will see the same thing!
-
-* __The time slider:__ The slider shows your current position in the time
-stream. If you want to change your time frame, simply move the slider
-(or type a time in) and hit GO. This will open a new time frame, and
-the next time you type a message, the memo will show that you've
-responded to it in that time frame. You can now switch between your
-time frames simply by clicking the arrows in the right hand
-corner. (THIS COMES IN HANDY IF YOU WANT TO ARGUE WITH YOURSELF.) You
-can have any number of open time frames, and the program will number
-them in the order in which you open them (like in the comic). You can
-have one of your time frames cease responding to the memo by hitting
-"CLOSE." If you open that time frame again, the program will remember
-the number it originally gave it. If you want to be mysteeeeeeeerious,
-you can type in "?" and you will appear as ???.
-
-* __The memo viewer list:__ To the right is a list of people currently
-browsing the memo. A shade icon next to their name means they are the
-"operator" of the memo: meaning they can kick ("ban") people from the
-memo and make other people operators as well. A "ban" is not permanent
-(like in the comic), and the program will ask if you want to reconnect
-to the memo. You kick and op people by right clicking their name in
-the window. You can also add them to your chumroll!
-
-* __Inviting people to your memo:__ You can link to a memo by simply typing
-"#nameofmemo" in any conversation or memo window. So you can say:
-
- ```
- CG: NOW YOU, ME, AND EGBERT NEED TO HAVE A CHAT.
- CG: CLICK IT.
- CG: #FRUITYRUMPUSASSHOLEFACTORY
- ```
-
- and it will appear as a link that you can click, which will open the
- memo chooser window.
-
-CLIENT MENU
------------
-
-### OPTIONS: ###
-
-* __Chum List__
- * __Hide Offline Chums:__ Turning this option on will hide all offline chums
- off your chumroll.
-
- * __Show Empty Groups:__ Turning this option on will show empty groups.
-
- * __Show Number of Online Chums:__ Show number of online chums in each group.
-
- * __Sort Chums:__ How would you like your chums sorted?
-
-* __Conversations__
- * __Time Stamps:__ Turning this on will show timestamps in your chats.
-
- * __12/24 hour:__ Formatting for timestamps. Whether you want them in 12 or
- 24 hour time.
-
- * __Show Seconds:__ Turning this on will show the seconds in your timestamps.
-
- * __Show OP and Voice Messages in Memos:__ Whether or not you would like
- to see messages when people gain/lose OP or Voice.
-
- * __Use animated smilies:__ To animate or not to animate.
-
-* __Interface__
- * __Tabbed Conversations:__ Turns tabbed conversations on and off. Don't
- worry if you do this in the middle of a conversation, PC will save
- them for you.
-
- * __Minimize:__ What do you want the minimize button to do?
-
- * __Close:__ What do you want the close button to do?
-
-* __Sound__
- * __Sounds On:__ Uncheck to shut it the fuck up.
-
- * __Pester Sounds:__ Uncheck to only turn off Pester sounds.
-
- * __Memo Sounds:__ Uncheck to only turn off Memo sounds.
-
- * __Memo Mentions:__ Check to have a separate noise when your initials
- get mentioned in a memo.
-
-* __Logging__
- * __Log all Pesters:__ Log one-on-one chats.
-
- * __Log all Memos:__ Log everything said in memos.
-
- * __Log Time Stamps for Pesters__
-
- * __Log Time Stamps for Memos__
-
-* __Idle/Updates__
- * __Minutes before Idle:__ How long before you should be considered idle.
-
- * __Check for Pesterchum Updates:__ How often to check for updates
- to Pesterchum.
-
- * __Check for MSPA Updates:__ Check the MSPA site for updates to comics.
-
-* __Theme__
- * __Pick a Theme__
-
-### MEMOS: ###
-
-Opens the Memo list as above.
-
-### USERLIST: ###
-
-Shows a list of all the users that are currently logged onto
-Pesterchum. Right-click their names and select "ADD CHUM" to add them
-to your chum roll!
-
-### IDLE: ###
-
-Make yourself an idle chum. You will appear as idle until you
-uncheck this box, or if you *actually* go idle (stop using the
-computer) for 10 minutes and then come back.
-
-### IMPORT: ###
-
-Imports your old Pesterchum 2.0, 2.5 and Tinychum chum
-rolls. This will also import your old quirks from Pesterchum 2.5.
-
-### RECONNECT: ###
-
-Forces PC to reconnect to the server.
-
-### EXIT: ###
-
-noooooooooooooooooooooooo
-
-
-PROFILE MENU
-------------
-
-### QUIRKS: ###
-
-Opens the quirks menu. More on that below!
-
-### TROLLSLUM: ###
-
-Opens up the window where you can view people you've
-blocked. You can add and remove people to the list from here as well.
-
-### COLOR: ####
-
-Change your text color here!
-
-### SWITCH: ###
-
-Switch your profile! You can have any number of profiles, and
-PC will save your color, quirks, and theme for that profile. Chumrolls
-and block lists are the same for all profiles. Feel free to have
-multiple instances of PC running on two or more handles!
-
-
-HELP MENU
----------
-
-### HELP: ###
-
-Get taken to a handy dandy tutorial for Pesterchum!
-
-### CALSPRITE: ###
-
-Open a chat with calSprite (learn more about calSprite below).
-
-### NICKSERV: ###
-
-Open a chat with NickServ. If you don't know what NickServ is, you don't need to.
-
-### ABOUT: ###
-
-See which version of Pesterchum you have. Learn about all the awesome people
-that helped bring Pesterchum 3.14 to you!
-
-### REPORT BUG: ###
-
-Report any bugs you come across so we can fix them and make Pesterchum
-even better!
-
-
-CALSPRITE
----------
-
-calSprite is the bot that helps moderate canon handle usage! Simply pester
-calSprite with the world "HELP" (turn your quirks off!) and you
-will get instructions on how to use calSprite!
-
-
-QUIRKS
-------
-
-There are six kinds of quirks! I'll teach you how to use them all!
-(In this section, I will use quotes ("") around things so it's clearer
-to see exactly what to type! Don't include these quotes when using
-these examples!
-
-Also, note that your quirks will not work until you save them by
-hitting "OK" on the Quirk window.
-
-* __Prefix/Suffix:__
- This will put text before or after everything you
- say. So for example, we can use prefixes to emulate part of Nepeta or
- Equius' quirks:
-
- ```
- PREFIX: ":33 < "
- You type: "*ac twitches her friendly whiskers at ct*"
- Result:
- AC: :33 < *ac twitches her friendly whiskers at ct*
- ```
-
- ```
- PREFIX: "D --> "
- You type: "Hi"
- Result:
- CT: D --> Hi
- ```
-
- Suffixes work the same way, but at the end of the message:
-
- ```
- SUFFIX: "!!!"
- You type: hey there
- Result:
- GD: hey there!!!
- ```
-
- Remember that it doesn't automatically add a space! You'll need to add
- it in (see CT and AC examples again!)
-
-* __Simple Replace:__
-This will simply take a set of characters and replace them with other
-characters.
- * Let's add a quirk to our Nepeta:
-
- ```
- Replace: "ee" With: "33"
- You type: "*ac saunters from her dark cave a little bit sleepy from
- the recent kill*"
- Result:
- AC: :33 < *ac saunters from her dark cave a little bit sl33py from the
- recent kill*
- ```
-
- * Let's add two to Equius:
-
- ```
- Replace: "loo" With: "100"
- Replace: "x" With "%"
- You type: "look"
- Result:
- CT: D --> 100k
- ```
-
- ```
- You type: "What are you expecting to accomplish with this"
- Result:
- CT: D --> What are you e%pecting to accomplish with this
- ```
-
- * Aradia:
-
- ```
- Replace: "o" With: "0"
- You type: "and the reward would be within our reach"
- Result:
- AA: and the reward w0uld be within 0ur reach
- ```
-
- Notice that it is CASE SENSITIVE. So in the above case, if you typed
- "ABSCOND", it would not replace the "O".
-
- * Sollux:
-
- ```
- Replace: "i" With: "ii"
- Replace: "s" With: "2"
- ```
-
- * Eridan:
-
- ```
- Replace: "v" With: "vv"
- Replace: "w" With: "ww"
- ```
-
- * Feferi:
-
- ```
- Replace: "h" with: ")("
- Replace: "H" with: ")("
- Replace: "E" with: "-E"
- ```
-
-* __Regexp Replace:__
-This is a more complex kind of replacement. [Regexp](http://en.wikipedia.org/wiki/Regexp)
-stands for "regular expression", a kind of programming language (yes, it is a language)
-used to find and replace text. PC 3.14 also includes a few functions (`upper()`,
-`lower()`, `scramble()`). If you want to learn it on your own,
-I suggest you start with the [Python tutorial](http://docs.python.org/howto/regex.html)
-since PC 3.14 uses Python's regexps. Check out V2.5's tutorial too, as that is a pretty
-good start as well.
-
- * Let's start with Karkat. Regexps are just like your every day find and
- replace: they search for a string that matches what you want to
- replace, and replaces it with... the replacement.
-
- ```
- Regexp: "(.)" Replace with: "upper(\1)"
- ```
-
- Three concepts here. Let's look at the regexp. "(.)" has two things
- going on. The first is that ".". In regexp speak, "." is the wildcard:
- it will match *any* character -- and just one.
-
- The parentheses tell the regexp to *save* what's inside them so you
- can put it back when you replace. That's what the "\1" is for -- it
- means, "put the match inside parentheses #1 here". You can have any
- number of parentheses.
-
- * __"upper()"__ is a function special to PC 3.14 -- it will uppercase
- anything inside the parentheses. So in this case, upper will uppercase
- "\1" -- which, as you recall is what we found inside the
- parentheses. Which was *every* character. So to sum up, it replaces
- every character with an uppercase version of that character. WHICH
- MAKES YOU TALK LIKE THIS.
-
- * Let's look at Terezi next.
-
- ```
- Regexp: "[aA]" Replace with: "4"
- Regexp: "[iI]" Replace with: "1"
- Regexp: "[eE]" Replace with: "3"
- Regexp: "(.)" Replace with: "upper(\1)"
- ```
-
- We already know what the last line does. But what's up with those
- brackets? What's their deal? Basically, in regular expressions,
- brackets indicate a list of matching characters. So, basically any
- single character within the brackets will be matched. In this case,
- either "a" or "A" will be matched and replaced with "4," and likewise,
- "i" and "I" will be replaced with "1", and "e" and "E" will be
- replaced with "3."
-
- Just like there is an `upper()` function, there is also a `lower()`
- function. It acts just like `upper()` but instead makes everything
- inside the parentheses lowercase. This allows you to do things like:
-
- ```
- Regexp: "(.)" Replace with: "lower(\1)"
- You type: "I AM YELLING"
- Result:
- GD: i am yelling
- ```
-
- Along with the upper and lower functions is a `scramble()` function.
- The purpose of this function is to randomly scramble anything inside
- the parentheses.
-
- ```
- Regexp: "(\w)(\w*)(\w)" Replace with: "\1scramble(\2)\3"
- You type: "hello there"
- Result:
- GD: hlelo trhee
- ```
-
- This particular regular expression scrambles all of the letters in
- the middle of a word. Notice that the "h" and "o" at the beginning
- and end of hello remain in place while the other letters are scrambled.
-
- You should also know that "^" is a special character in brackets. If
- placed immediately after the opening bracket (like "[^"), then the
- brackets instead match every character *except* the ones in the
- brackets. So, for example, if you wanted to have a quirk where you
- capitalized all your letters *except* o, you'd do this:
-
- ```
- Regexp: "([^o])" Replace with: "upper(\1)"
- You type: "hello there"
- Result:
- GD: HELLo THERE
- ```
-
- You can also specify a *range* of characters inside the brackets, by
- using the "-" character. [a-z] will match any lowercase letter. You
- can combine them, too: [a-z0-9] will match any digit and lowercase letter.
-
- There are also different shortcuts for character types:
-
- ```
- \d matches any digit; same as [0-9]
- \D matches any non-digit; same as [^0-9]
- \s matches any spaces
- \S matches any non-space
- \w matches any alphanumeric character; same as [a-zA-Z0-9_]
- \W matches any non-alphanumeric character; same as [^a-zA-Z0-9_]
-
- Note \w and \W also match extended Latin or Unicode alphanumerics.
- ```
-
- You can include this inside brackets, too.
-
- There's also a special character, \\b. What \\b does is make sure that
- you are at the beginning or end of a word.
- * So with that knowledge, let's try Kanaya:
-
- ```
- Regexp: \b(\w) Replace with: upper(\1)
- You type: "i suggest you come to terms with it"
- Result:
- GA: I Suggest You Come To Terms With It
- ```
-
- Another feature of regular expressions is the ability to match
- *repeated* characters. There are three repeat characters: the "\*", the
- "+", "?", and "{m,n}". They work by playing them after the character,
- or character type you want to match. (So, you could say "\s+" or ".*")
-
- The "\*" character matches ZERO or more of that character. So, for
- example, "f\*" would match "", "f" and "ff" -- and any other character!
- That's right, every character counts as matching it zero times. Yeah,
- it's weird. I suggest you use...
-
- The "+" character matches ONE or more of that character. So, if we
- wanted to have a character that wanted to elongate their s's so that
- they used four 's's every time, like sssso, but didn't want to have
- eight s's when using words with double s's, like pass, we'd do this:
-
- ```
- Regexp: "s+" Replace with: "ssss"
- You type: "you shall not pass"
- Result:
- UU: you sssshall not passss
- ```
-
- As for the other two, I can't really think of any useful quirks to be
- made with them. But to let you know, "?" matches either 0 or 1 of that
- character, so "trolls?" would match "troll" and "trolls". "{m,n}"
- matches between m and n characters. (If you leave out 'n', any number
- of characters more than m will be matched: "s{3,}" will match 3 or more 's'.)
- So "s{2,4}" will match "ss", "sss", and "ssss" and that's it.
-
- Also, "?" is equivalent to "{0,1}", "*" is equivalent to "{0,}", and
- "+" is equivalent to "{1,}".
-
- Now with repeating expressions, we can do something like make EVERY
- other WORD capitalized:
-
- ```
- Regexp: "(\w+) (\w+)" Replace with: "upper(\1) \2"
- You type: "this is pretty annoying i bet"
- Result:
- GD: THIS is PRETTY annoying I bet
- ```
-
- The \1 represents the first word -- which has been matched because the
- word is alphanumeric characters, repeated once or more -- and \2
- represents the second word.
-
- Another operator to use is the "|", which will match more than one set
- of characters. For example, "black|red" will match "black" or
- "red". If you want to match something in the middle of words, you have
- to use parentheses: "(black|red) romance" will match "black romance"
- and "red romance".
-
- Finally, there are the "^" and "$" characters. Yes, we already did the
- "^" character, but this is OUTSIDE of brackets, not INSIDE. "^"
- matches the beginning of a message, and "$" matches the end of it. You
- can use this to make more sophisticated prefix and suffix
- behaviors. For example, if we have a quirk that adds "..." to the end
- of all our messages, we can set it up so it doesn't do that if we put
- punctuation [?!.] at the end. So:
-
- ```
- Regexp: "([^?!.])$" Replace with: "\1..."
- ```
-
- This will match the end of any message as long as it doesn't have
- "?", "!", or "." at the end. Then it will replace it with whatever the
- last character of the sentence was (remember we're replacing it, so we
- have to put it back!) and add "..." at the end.
-
- Careful with the beginning and ending replaces -- if you use more than
- one, you may not get what you expect because they will ALL be applied,
- one after the other! This is a bug in my opinion, that I plan to fix!
-
-* __Random replace:__
- Just like the regexp replace, except that instead of just one thing to
- replace it with, you give it a list. PC will then choose from that
- list randomly. So let's say I want to randomly end my sentences with
- either "bro" or "dog":
-
- ```
- Regexp: "$" Replace with: "bro" and "dog"
- ```
-
- * You can also imitate Araida's random "ribbits" in between words:
-
- ```
- Regexp: "\s" Replace with: " ribbit ", " ", " ", " ", " ", " ", etc....
- ```
-
- where " " is just a blank space added a bunch of times. (You can see
- how many blank spaces you've added by clicking on the list.) You have
- to add the spaces because each entry has the same chance of being
- selected. (Yes, I know this could be improved.) If you add " ribbit "
- and 9 spaces, " ribbit " will have a 1/10 chance of being picked.
-
- Also note that if you add more than one prefix or more than one
- suffix, it will pick randomly from them instead of adding them both!
-
-* __Mispeller__:
-Be careful with thsi one. The mispeller will randomly mispell x% of
-the words you type -- where x is the percentage you set the slider
-to. I have attempted to mimic SBaHJ mispelling style but whoof knows
-what will happen oh god ive created a mosnter
-
-
-SMILIES
--------
-Here's a list of smilies:
-
-* `:rancorous:`
-* `:apple:`
-* `:bathearst:`
-* `:cathearst:`
-* `:woeful:`
-* `:pleasant:`
-* `:blueghost:`
-* `:slimer:`
-* `:candycorn:`
-* `:cheer:`
-* `:duhjohn:`
-* `:datrump:`
-* `:facepalm:`
-* `:bonk:`
-* `:mspa:`
-* `:gun:`
-* `:cal:`
-* `:amazedfirman:`
-* `:amazed:`
-* `:chummy:`
-* `:cool:`
-* `:smooth:`
-* `:distraughtfirman:`
-* `:distraught:`
-* `:insolent:`
-* `:bemused:`
-* `:3:`
-* `:mystified:`
-* `:pranky:`
-* `:tense:`
-* `:record:`
-* `:squiddle:`
-* `:tab:`
-* `:beetip:`
-* `:flipout:`
-* `:befuddled:`
-* `:pumpkin:`
-* `:trollcool:`
-* `:jadecry:`
-* `:ecstatic:`
-* `:relaxed:`
-* `:discontent:`
-* `:devious:`
-* `:sleek:`
-* `:detestful:`
-* `:mirthful:`
-* `:manipulative:`
-* `:vigorous:`
-* `:perky:`
-* `:acceptant:`
-* `:olliesouty:`
-* `:billiards:`
-* `:billiardslarge:`
-* `:whatdidyoudo:`
diff --git a/README.md b/README.md
deleted file mode 100644
index c700b9b..0000000
--- a/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Pesterchum Alternate Servers
-Pesterchum with added functionality to connect to alternative servers. (And some other stuff.)
-
-Normal pesterchum documentation is in "README-pesterchum.mkdn" and the one for Karxi's fork is README-karxi.mkdn.
-
-## Servers
-If you'd like to connect to a different server than the default "pesterchum.xyz", put the server you'd like to connect to in the server.json file.
-
-## Tips for building
-- For windows use "setup.py". PyQt4 binaries for windows can be installed from it's sourceforce page if you don't want to go through the hell that's compiling it manually.
-- On mac you can install most of the dependencies via macports and build with "python setup-py2app.py py2app".
diff --git a/TODO.mkdn b/TODO.mkdn
deleted file mode 100644
index eb1dfc7..0000000
--- a/TODO.mkdn
+++ /dev/null
@@ -1,358 +0,0 @@
-# Todo
-
-## Git
-* Set up issue tracking for this fork, if possible (and move the TODO list)
-
-## Features
-* Log viewer needs to have BBCode/HTML/Text copy modes
-* Turn @ and # links on/off?
-* Show true bans? COMPRESS QUIT MESSAGES ON BAN
-* Colour saving boxes things?
-* Whowas for last seen online?
-* Tab completion of two letter names
-* Auto download/install updates via Windows installer
-* Make toast notifications only on certain chums
-* Local alisas for chums
-* Don't make new windows be all in your face and shit
-* Hide offline friends per group
-
-
-* Add support for displaying more verbose information (e.g. Cease messages which
- tell you more than the abbreviation of who left)
-* Make Pesterchum recognize conventional /mes so they aren't invisible
-* Make @XY and @xxxYyy formats ping their targets
-* Allow matches like @?XY and @FXY or @PXY3 - make them only match the target
- currently set to that.
-* Make @ notation not match @u@; and similar (make invalid nick chars break
- matches)
-* Allow use of @ and # links to switch between logs in log viewer (start with
- the closest time to the line of the log that's linking)
-* Improve log viewer in general (unbind instances from specific users/memos)
-* Fix hyperlink escaping (Qt seems to do this automatically - need a workaround)
-* Show bans if +h or higher (+h, +o, +a, +q)
-* Auto-invite (for people on the friends list?)
-* Right click on names for inviting, ACTUALLY banning, PMing, ... See also:
- Things proper IRC clients can do. (Set basic mode stuff up first, get the
- infrastructure in place.)
-
-* Add more comprehensive status support - IDLE, DND, INVISIBLE for now - or at
- least add similar functionality.
-* Improve Pesterchum's tracking of disconnections (check memos for quits...)
-* SEPARATE FUNCTIONALITY from CONNECTED STATE!! This is a huge problem! Being
- shunted off our nick closes windows and breaks things! Just D/C and
- reconnect?
- * It'd probably be best to give an option to either CHANGE NICKS or
- DISCONNECT upon nick collision...? But, then how would we GHOST?
- * Auto-disconnect if collision before joining channels, make it
- possible to disconnect (but not send messages, obviously)
- without losing everything
- * Maybe GHOSTing should use auto-identify to ensure- no, that doesn't
- work, because we can't ident into a specified nick without being ON
- it. Need GD's help to fix....
-
-* Make it possible to test quirk things and such without connecting? This'd be
- hard to separate out, but useful.
- * Make a quirk 'bin' that exists independent of profiles, and can be
- copied to/from at will.
- * Allow us to set quirks that apply to all profiles! For things like
- replacement quirks.
-
-* Right-click Time entry field to see those used? (Replace left/right buttons?)
- * Save commonly-used times on a per-handle basis!
-* Make the memo list highlight/recolor the names of channels you're in
- (including secret ones)
-* Add an option to Cycle (for log separation)
-
-* Add a separate 'Tweaks' section in Options
-* Fix graphical issues with dark themes vs. light themes (Qt/text too
- light/etc.)
-
-### Services
-* Use web connection to send offline messages in email-like fashion
- (Idea: ghostDunk)
-* Better NickServ registering
-* Implement **MemoServ** support
-* Tell user when NickServ handles are going to expire
-* Tell user when old handles have D/C'd? Offer autoghost support?!
-
-### GUI
-* Refactor code to make way for QShortcut usage. (Unify shortcut processing?)
- * Enable/Disable toggle (Firefox style option sheet-esque? Seems okay.)
- * Ctrl+W closes tab
- * Ctrl+Shift+PGUP/PGDN moves tab
- * Option to disable Ctrl+Tab's jump to newest
- * Ctrl+Shift+V "Mass Paste" option (parse lines in sequence)?
-* Make mouseovers (refocusing) reset idle timer (disableable)
-* Set up EVENT FILTERS in windows to redirect events to the right places
- * Make the context key (if used in the text area) append the menu options
- from the right-click menu
-* Make system messages use timestamps like everything else
-* Offer option for timestamps in memos
-* Make a status window/popup to contain logs of information like invites
-
-### "Security"
-**Note: The idea of security on this platform is pretty much laughable. Most of
-these changes are simply bandages being placed over fundamentally flawed
-design.**
-
-If you want Pesterchum to be more secure, either get ghostDunk to make changes
-to the server and its administration policies, or get everyone to switch to this
-version of the client. There aren't really any other options.
-
-* Flood protection (don't send because of the same target too many times in a
- row)
- * Just requires a timer + lastmessage date check.
-* Lock exploitable functionality to those on your friends list (optional)
- * Canon handles are excluded from this concern, but subject to flood
- controls regardless.
- * A measure of politeness is reasonable here - checking if a friend is on
- as a different handle should be okay, once IRC access is revamped.
- * Don't send MOOD answers to those not friended
- * Ignore pesters from those not on your friends list (optional)
- * Ignore pesters from those not sharing a memo? (optional)
-* Make BLOCKED list persistent, if it isn't already
- * Offer option to block hosts, not just handles...
- * Explain to the user that this option is very dangerous.
-
-### Advanced
-* Offer option for 'new' syntax adjustments
- * Replace: "???, ???, ??? ceased responding to memo." for parts.
- * "XY ({handle}) ({times}) ceased responding to memo."
- * If +h or above: Include host as well as handle.
- * Replace: "??? ceased responding to memo." for nickchanges.
- * "XY ({handle} {host?}) left memo; AB ({handle} joined memo."
- * Can violate the norms somewhat, these aren't theme-controlled.
- They're basically for power users/admins.
-* Offer GUI changes
- * Make tabs "{name} ({# of unread msgs})" if unread
- * Make themes able to define colors that are too dark to read for an
- individual window
- * Set up code for 'nudging' color codes into readable territory; presumably
- via an adjustable setting. (This CANNOT affect logs - just the log
- reader.)
-* Come up with a solution for duplicate times/handle abbreviations
- * Maybe make mouseover for the handles display the full handle?
-
-* Option to disable backwards compatibility:
- * For those that are *really* sure that this build is the build for
- them.
- * Should enable extra features, including ctag compression.
- * Allow manual compression changes via memo right-click menu for
- 'advanced' (per the setting) users
-
-## Todo/Done
-**Everything in this section has already been completed.**
-
-### GUI
-* Toggle individual tab flash / alert sounds (from the same right-click memo
- that lets us toggle OOC)
-* Make CTRL+PGUP/PGDN switch memo/pester tabs
-* Make Ctrl+J/K usable for tab changing
-* Make right-clicking on a tab open up the right-click menu one would get on
- right-clicking the title (frame??)
-* Right-click in userlist offers option to Pester
-* Make certain dialogues start on the safer of the two options
- * Make the Reconnect dialog start on Reconnect
- * Make the Rejoin dialog start on Rejoin
- * Make the Invite dialog start on Decline
-
-### Usability
-* Fix parser text-loss bug that plagues everyone (especially Chumdroid users)
-* Make /me messages that cut continue into more /me messages
-* Make sound work on Windows through QSound (disables volume control)
-* Color tags are now posted as their shorter hexadecimal forms, if applicable
- (255,255,255 -> #FFFFFF, for example)
-* Separate auto-idle and checkbox idle so they don't share a state (and make
- the first send set the timer for additional idle responses)
-* Stop us from sending IDLE messages to NickServ
-* Fix NickServ auto-login things
-* Make a window that can be used to interface with the script directly - a
- simple Python console
-* Make the memo name entry box accept a comma-separated list
-* Make console users able to check widget theme/style information via mouseover
- and key combo (for people making themes or debugging)
- * This is presently Ctrl+Alt+w, after opening the console (Ctrl+~).
-* LET PEOPLE TURN OFF HONKING - people already rename the soundfile and such to
- do this manually (append "honk":false to the end of pesterchum.js ; that kills it.)
-
-### Backend
-* Perpetual code cleanup, refactoring, simplification and general improvements
-* Syntax changes/updates and the like
-
-## Code
-**Improvements and changes pertaining to Pesterchum's internals.**
-
-### General
-* Implement new Lexer for the sake of everyone's sanity
- * This is half-done - rendering still uses the old lexer
-* Redo `PESTERCHUM:` processing/redo whole msg received processing chain
-* Redo text processing in general
-* Redo quirk processing (use pieces from Textsub if needed)
-* Pare down the PesterMemo object so it inherits more things from PesterConvo
- *implicitly*
-* SOONER OR LATER: Redo internal chum storage, centralize data into widely
- accessible manager objects, etc.
-* Also: Overhaul settings storage. Bring it more in line with the system Textsub
- used (if feeling masochistic), but simpler.
-* **Overhaul information storage** - chums, conversations, memos; all should be
- handled by a backend and merely RENDERED into Qt objects!!
-* Overhaul debugging
- * Give an actual (small) window with traceback that can be sent to dev(s)
- * Use the console for this?
-* Debug generic.py's CaseInsensitiveDict/replace it with mine
-* Overhaul messaging so **Chan/Nick/Memo Servs** all use the same code (and
- lexer)
-* **Separate Pesterchum system handling from window handling.** Dicts should be
- stored and maintained via dicts - even a refined version of what I used for
- textsub.
- * Doing it this way means I can fix the case in/sensitivity issue, too.
-* Set up framework for easily logging/accessing channels, users, etc...like
- what hexchat has.
-* More efficient framework for accessing stored user information - right now,
- Pesterchum keeps information on user colors and such on hand *forever*,
- meaning that things inevitably get clogged up with handles that are never
- really seen, or only seen once, or even just randomly generated. This is
- silly and should be changed; I'll probably make a namedtuple for users or
- something, and save it all to a separate JSON file or two.
- Said JSON file should keep the extra information on hand - or rather, the
- 'recent users' JSON file should keep most of the detailed information and be
- accessed first, with the larger 'inactive users' file being accessed to
- check for unfamiliar handles.
- These would have to output the old data to pesterchum.js for backwards
- compatibility purposes.
-* Finish creating the sound wrapper. Just make it check what the type of sound
- needed is upon creation, and instantiate a private class based off of that.
- * There is basically no good way to do this without moving to Qt5. I
- might try that myself later, but that's a long-term goal.
-* Stop from sending TIME notifications when unable
- * Until then: Hide resulting "no external messages"/+m messages.
-* Stop sending auto-IDLE messages unless the chat has been updated since the
- last one.
-* Make groups, chums, etc. preferentially load from the main directory, *then*
- check logs.
- * Compatibility is important, so update both if they exist. (Bluh!)
-
-### Debugging
-* Set up a simple function to display a traceback instead of silently moving on!
- * Use the console for this?
-* Make small, simplistic windows that allow the viewing of internal variables
- pertaining to things like set quirks, users present, etc.
- * Also let it display the stylesheet settings of the current window, or
- similar.
-* Make a console to display debug info without requiring us to run from terminal
-* Allow us to specify flags via command line
- * Let us specify a separate config (pesterchum.js) file!!
-* Make the console support color (not ctags, more stylesheet stuff) (need
- parser work for this)
-
-## Bugs
-* weird memo time bug
-* Windows doesn't show style sheet sometimes?? Maybe related to themes.
-* Issues with connecting? Client not closing connection right? People keep
- getting "nick taken" messages
-* When using mood sort, scroll position jumps to last selected chum
-* Closing a timeclone doesn't actually cease for everyone else
-* Kill Zalgo
-* Random invisible, tiny links to last link at end of every message
-* Chums not appearing on chumroll when initals are the same? (bS)
-* Recognize IRC 471, 473, 474 and 475
-* memo links aren't case sensitive
-
-* Mentions occasionally don't work (e.g. in /me)
-* Character times aren't 'forgotten' on Part
-* +c is not properly recognized on join, nor does it stop someone from
- reenabling their quirk (let ops and above ignore it?)
-* Chumlist handles groups pretty badly (no using the same name as a handle, for
- example? Needs an errormessage at least)
- * The whole chumlist handling system really ought to be refactored into
- something sane...the objects should only be there to render
-* PESTERCHUM: messages are sent to things like NickServ
-* Log folder/file names are not case-sensitive, so they break on non-Windows
- systems
-* Log viewer needs adjustments and sanity checking for log directories
-* Capitalized /me's don't render (should forcibly lowercase them)
-* 'pcd10' and similar users don't get proper abbreviations on part (ugh)
-
-* Volume control doesn't work without pygame
-* Sound on Linux doesn't work without pygame
-* Update checking code gives false positives (update to use json file from git?)
-* Pesterchum doesn't seem to close all of its file handles - it runs out of
- handles to use on Linux
- * Others have reported memory leak-induced crashes on Windows. These
- may or may not be related.
-* Pesterchum groups aren't carried over when profiles are copied!
-* Malformed Pesterchum profiles cause the program to crash and burn
- * What causes these? Exiting in the middle of a write operation? Threading
- issues?
-* Malformed Python quirks try to open an error dialog and crash if Pesterchum
- is opened as a module
-* Pesterchum's threading is messy and scary, and should probably be cleaned up
- some via the addition of locks
-* Pesterchum's file handling is atrocious - inefficient to the extreme.
- * There are multiple copies of things that really need only be loaded once
- in a lot of different places.
- * Memos don't seem to close their file handles properly. (Logs too??)
-
-## Windows Bugs
-* XP SP2: sometimes mouse clicks dont register? must be some kinda crash
-* On reconnect and nick change, momentary theme change causes menu items to
- stop working
-* Random chums won't show up on chumroll
-* Popup toast notifications cause main window to raise
-
-## Mac Bugs
-**Due to my lack of access to a Mac, these are unlikely to be fixed.**
-* Mac doesn't show tabs right, display gifs, highlighting thing?
-* SS: also the background image is broken
-* SS: in the one-on-one pester it resizes with the window
-* SS: but the memo one doesn't resize
-* SS: and the arrows next to the time thing overlap the CLOSE button
-* Lex: There seems to be a faint outline around most non-square themes.
-
-
-## Things that won't be done
-**Requests that, for one reason or another, will not be fulfilled.**
-
-### Scrapped Features
-**I'll explain why these ones won't happen.**
-
-> * More complex quirks: by-sound
-
-* This would require a way to determine what maps to a sound, and
- replace it.
- I've played with the idea before. It resulted in me needing to look
- up things like the [Metaphone Algorithm][metaphone] to figure out
- how it might be even remotely possible. The results were NOT a fun
- time; if this is ever implemented, it will be much, much later than
- just about everything else.
-[metaphone]: https://en.wikipedia.org/wiki/Metaphone
-
-> * Spy mode
-
-* I feel as though I shouldn't need to tell anyone why this is a bad idea.
- Some people already have this capability anyway; I used to be one of them.
- There's no real need to implement an inferior version into every single
- client on Pesterchum.
-
-> * "Someone has friended you" notifier
-> * Spectation notices (Idea: lexicalNuance) (probly WONTFIX)
-
-* These are milder invasions of privacy than the above, but they are still
- invasions of privacy.
-
-> * When 'banned' make impossible to connect using timestamp banned under
-
-* This is a lot of work for something that purely affects immersion - while
- also breaking a number of things in the process. Too much work for too
- little payoff.
-
-> * Use web connection to save profiles (Idea: ghostDunk)
-
-* There is no way to do this now that Pesterchum is basically unsupported; an
- external server would be necessary for storage.
- As such, you'll just have to settle for copying your profiles and logs when
- you change computers.
-
-
-
-[modeline]: vim:set autoindent ts=4 sts=4 sw=4 tw=79 expandtab:
diff --git a/VERSION.js b/VERSION.js
deleted file mode 100644
index 556c1e3..0000000
--- a/VERSION.js
+++ /dev/null
@@ -1 +0,0 @@
-{"major": 3.41, "minor": 4, "status": "A", "rev": 13, "utype": "dev"}
diff --git a/console.py b/console.py
deleted file mode 100644
index 6538bd1..0000000
--- a/console.py
+++ /dev/null
@@ -1,528 +0,0 @@
-# vim: set autoindent ts=4 sts=4 sw=4 textwidth=79 expandtab:
-# -*- coding=UTF-8; tab-width: 4 -*-
-from __future__ import print_function
-
-from PyQt4 import QtGui, QtCore
-import re, os, traceback, sys
-import time, datetime
-from os import remove
-
-import dataobjs, generic, memos, parsetools, ostools
-from version import _pcVersion
-
-try:
- from pnc.attrdict import AttrDict
-except ImportError:
- # Fall back on the old location, just in case
- from pnc.dep.attrdict import AttrDict
-#~from styling import styler
-
-_datadir = ostools.getDataDir()
-
-import logging
-logging.basicConfig(level=logging.WARNING)
-
-
-
-
-class ConsoleWindow(QtGui.QDialog):
-#~class ConsoleWindow(styler.PesterBaseWindow):
- # A simple console class, cobbled together from the corpse of another.
-
- stylesheet_path = "main/defaultwindow/style"
- # This is a holder for our text inputs.
- text = AttrDict()
- # I should probably put up constants for 'direction' if this is going to
- # get this complicated. TODO!
- incoming_prefix = "<<<"
- miscinfo_prefix = "==>"
- outgoing_prefix = ">>>"
- neutral_prefix = "!!!"
- waiting_prefix = "..."
-
- selected_widget = None
- show_info_on_select = True
-
- _CUSTOM_ENV = {}
-
- def __init__(self, parent):
- super(ConsoleWindow, self).__init__(parent)
- self.prnt = parent
- try:
- self.mainwindow = parent.mainwindow
- except:
- self.mainwindow = parent
- theme = self.mainwindow.theme
- # This won't initialize the sub-objects, because they don't exist yet.
- self.initTheme(theme)
-
- self.text = AttrDict()
- self.text.area = ConsoleText(theme, self)
- self.text.input = ConsoleInput(theme, self)
- self.text.input.setFocus()
-
- self.connect(self.text.input, QtCore.SIGNAL('returnPressed()'),
- self, QtCore.SLOT('sentMessage()'))
-
- self.text.history = dataobjs.PesterHistory()
-
- # For backing these up
- self.stdout = self.stderr = None
-
- layout_0 = QtGui.QVBoxLayout()
- layout_0.addWidget(self.text.area)
- layout_0.addWidget(self.text.input)
- self.setLayout(layout_0)
-
- def parent(self):
- return self.prnt
-
- def clearNewMessage(self):
- pass
-
- @QtCore.pyqtSlot()
- def sentMessage(self):
- text = self.text.input.text()
- # TODO: Make this deal with unicode text, it'll crash and burn as-is.
- text = str(text)
- text = text.rstrip()
-
- self.text.history.add(text)
- self.text.input.setText("")
-
- self.execInConsole(text)
- # Scroll down to the bottom so we can see the results.
- sb = self.text.area.verticalScrollBar()
- sb.setValue(sb.maximum())
-
- def addTraceback(self, tb=None):
- # We should do the formatting here, but eventually pass it to text.area
- # to addMessage whatever output we produced.
- # If we're called by addMessage - and we should be - then sys.stdout is
- # still being redirected into the console.
- # TODO: Just make an object for setting contexts (and thus optionally
- # redirecting prints). Use 'with', of course.
- # TODO: Make this exclude *our* processing from the traceback stack.
- try:
- self.addMessage(traceback.format_exc(), direction=0)
- except Exception as err:
- logging.error("Failed to display error message (???): %s" % err)
-
- def addMessage(self, msg, direction):
- # Redirect to where these things belong.
- self.text.area.addMessage(msg, direction=direction)
-
- def closeEvent(self, event):
- # TODO: Set up ESC to close the console...or refer to hiding it as
- # closing it. Not sure which is preferable.
- parent = self.parent()
- parent.console.is_open = False
- parent.console.window = None
- return super(ConsoleWindow, self).closeEvent(event)
-
- def hideEvent(self, event):
- parent = self.parent()
- parent.console.is_open = False
-
- def initTheme(self, theme):
- # Set up our style/window specifics
- self.changeTheme(theme)
- self.resize(400,600)
-
- def changeTheme(self, theme):
- self.setStyleSheet(theme[self.stylesheet_path])
- self.setWindowTitle("==> Console")
- if "area" in self.text and "input" in self.text:
- self.text.area.changeTheme(theme)
- self.text.input.changeTheme(theme)
-
- @QtCore.pyqtSlot()
- def designateCurrentWidget(self):
- # Display and save the current widget!
- # TODO: Consider (reversible) highlighting or selection or something
- # fancy. It'd help people write styles, wouldn't it?
- # ...just remember to use mouseRelease() if you work with hovering.
-
- # Direction: Misc. Info
- direction = 2
-
- pos = QtGui.QCursor.pos()
- wgt = QtGui.QApplication.widgetAt(pos)
- if wgt is None:
- # Don't set None, for now. May change this later.
- self.addMessage("You need to have your cursor over something " + \
- "in Pesterchum to use that.",
- direction=direction)
- return
-
- self.selected_widget = wgt
- nchild = len(wgt.children())
- output = []
- output.append("CONSOLE.selected_widget = {0!r}".format(wgt))
- output.append("{0: <4}Parent: {1!r}".format('', wgt.parent()))
- output.append("{0: <4}{1:4d} child{2}".format('',
- nchild, ("ren" if abs(nchild) != 1 else "") ))
- if self.show_info_on_select:
- qtss = None
- uses_ss = None
- try:
- qtss = wgt.styleSheet()
- except:
- pass
- else:
- if unicode(qtss) == unicode(""):
- uses_ss, ss_msg = False, "No"
- elif qtss is not None:
- uses_ss, ss_msg = True, "Yes"
- else:
- uses_ss, ss_msg = None, "Invalid"
-
- ss_par, ss_par_msg = None, ""
- if uses_ss is False:
- # TODO: Split this into a sub-function or integrate it into
- # Styler or *something*.
- # The stylesheet was probably defined on a parent higher up.
- # Rungs above the start
- i = 0
- # qtss is still "" from earlier
- while not qtss:
- try:
- ss_par = wgt.parent()
- qtss = ss_par.styleSheet()
- except:
- # Can't ascend...and we're still in loop, so we don't
- # have what we came for.
- # Either that, or it's incompatible, which means the
- # ones above are anyway.
- ss_par = False
- break
- else:
- # Indicate that we got this from a parent
- i += 1
-
- if not qtss:
- # There are no stylesheets here.
- if ss_par is False:
- # We had parent issues.
- # TODO: Specifically indicate invalid parent.
- uses_ss, ss_msg = None, "Invalid"
- else:
- uses_ss, ss_msg = False, "No"
- else:
- # We got a stylesheet out of this!
- uses_ss, ss_msg = True, "Yes"
- #~ss_par_msg = "{0: <4}...on parent ↑{1:d}: {2!r}".format('',
- ss_par_msg = "{0: <4}...on parent #{1:d}: {2!r}".format('',
- i, ss_par)
-
- msg = []
- msg.append("{0: <4}QtSS?: {1}".format('', ss_msg))
- # A stylesheet analyzer would be wonderful here. Perhaps something
- # that tells us how many parent classes define stylesheets?
- if uses_ss:
- if ss_par_msg:
- # We got this stylesheet from a parent object somewhere.
- msg.append(ss_par_msg)
- msg.append("{0: <4}".format("Stylesheet:"))
- for ln in qtss.split('\n'):
- msg.append("{0: <8}".format(ln))
-
- # Actually add this stuff to the result we're constructing
- output.extend(msg)
-
- output = '\n'.join(output)
- self.addMessage(output, direction=direction)
-
-
- # Actual console stuff.
- def execInConsole(self, scriptstr, env=None):
- # Since that's what imports *us*, this should be okay
- # Tab completion could be set up in ConsoleInput, and would be nice
- import pesterchum as pchum
-
- if env is None:
- env = pchum._retrieveGlobals()
-
- # Modify the environment the script will execute in.
- # Fetch from the class/instance first.
- _CUSTOM_ENV = self._CUSTOM_ENV.copy()
- # Modify with some hard-coded environmental additions.
- _CUSTOM_ENV.update({
- "CONSOLE": self,
- "MAINWIN": self.mainwindow,
- "PCONFIG": self.mainwindow.config,
- "exit": lambda: self.mainwindow.exitaction.trigger()
- })
- # Aliases.
- _CUSTOM_ENV.update({
- "quit": _CUSTOM_ENV["exit"]
- })
- # Add whatever additions were set in the main pesterchum file.
- _CUSTOM_ENV.update(pchum._CONSOLE_ENV)
-
- _CUSTOM_ENV_USED = []
- cenv = pchum.__dict__
- # Display the input we provided
- # We do this here, *before* we do our variable injection, so that it
- # doesn't have to be part of the try statement, where it could
- # potentially complicate matters/give false positives.
- self.addMessage(scriptstr, 1)
- for k in _CUSTOM_ENV:
- if k not in cenv:
- # Inject the variable for ease of use.
- cenv[k] = _CUSTOM_ENV[k]
- # Record that we injected it.
- _CUSTOM_ENV_USED.append(k)
- else:
- # Don't overwrite anything!
- warn = "Console environment item {0!r} already exists in CENV."
- warn.format(k)
- logging.warning(warn)
- # Because all we did was change a linked AttrDict, we should be fine
- # here.
- try:
- # Replace the old writer (for now)
- sysout, sys.stdout = sys.stdout, self
- try:
- code = compile(scriptstr + '\n', "", "single")
- # Will using cenv instead of env cause problems?...
- result = eval(code, cenv)
- except:
- # Something went wrong.
- self.addTraceback(sys.exc_info()[2])
- else:
- # No errors.
- if result is not None:
- print(repr(result))
- finally:
- # Restore system output.
- sys.stdout = sysout
- finally:
- # Try to clean us out of globals - this might be disabled
- # later.
- for k in _CUSTOM_ENV_USED:
- # Remove the key we added.
- cenv.pop(k, None)
-
- def write(self, data):
- # Replaces sys.stdout briefly
- # We only ever use this for receiving, so it's safe to assume the
- # direction is always -1.
- if not isinstance(data, list):
- data = data.split('\n')
- for line in data:
- if len(line):
- self.addMessage(line, -1)
-
-
-class ConsoleText(QtGui.QTextEdit):
- stylesheet_template = """
- QScrollBar:vertical {{ {style[convo/scrollbar/style]} }}
- QScrollBar::handle:vertical {{ {style[convo/scrollbar/handle]} }}
- QScrollBar::add-line:vertical {{ {style[convo/scrollbar/downarrow]} }}
- QScrollBar::sub-line:vertical {{ {style[convo/scrollbar/uparrow]} }}
- QScrollBar:up-arrow:vertical {{ {style[convo/scrollbar/uarrowstyle]} }}
- QScrollBar:down-arrow:vertical {{ {style[convo/scrollbar/darrowstyle]} }}
- """
- stylesheet_path = "convo/textarea/style"
- # NOTE: Qt applies stylesheets like switching CSS files. They are NOT
- # applied piecemeal.
- # TODO: Consider parsing the themes out into stylesheets with pieces that
- # we can hand to each widget.
-
- def __init__(self, theme, parent=None):
- super(ConsoleText, self).__init__(parent)
- if hasattr(self.window(), 'mainwindow'):
- self.mainwindow = self.window().mainwindow
- else:
- self.mainwindow = self.window()
-
- self.hasTabs = False
- self.initTheme(theme)
- self.setReadOnly(True)
- self.setMouseTracking(True)
- self.textSelected = False
-
- self.connect(self, QtCore.SIGNAL('copyAvailable(bool)'),
- self, QtCore.SLOT('textReady(bool)'))
- self.urls = {}
-
- # Stripped out animation init - it's all cruft to us.
-
- @QtCore.pyqtSlot(bool)
- def textReady(self, ready):
- self.textSelected = ready
-
- def initTheme(self, theme):
- # The basic style...
- stylesheet = "QTextEdit {{ {style[convo/textarea/style]} }}"
- if "convo/scrollbar" in theme:
- # TODO: Make all of this into a Styler mixin, so we can just feed
- # it a theme whenever we want to change.
- # We'd have to define the keys we're affecting, but that shouldn't
- # be too hard - it's what dicts are for.
-
- # Add the rest.
- stylesheet += '\n' + self.stylesheet_template
- stylesheet = stylesheet.format(style=theme)
- self.setStyleSheet(stylesheet)
-
- def addMessage(self, msg, direction):
- # Display a message we've received.
- # Direction > 0 == out (sent by us); < 0 == in (sent by script).
- if len(msg) == 0:
- return
- #~color = chum.colorcmd()
- #~initials = chum.initials()
- parent = self.window()
- mwindow = parent.mainwindow
-
- systemColor = QtGui.QColor(mwindow.theme["convo/systemMsgColor"])
-
- if mwindow.config.showTimeStamps():
- if mwindow.config.time12Format():
- timestamp = time.strftime("[%I:%M")
- else:
- timestamp = time.strftime("[%H:%M")
- if mwindow.config.showSeconds():
- timestamp += time.strftime(":%S] ")
- else:
- timestamp += "] "
- else:
- timestamp = ""
-
- # Figure out what prefix to use.
- if direction > 1:
- # Misc. Info
- prefix = parent.miscinfo_prefix
- elif direction > 0:
- # Outgoing.
- prefix = parent.outgoing_prefix
- elif direction < 0:
- # Incoming.
- prefix = parent.incoming_prefix
- elif direction == 0:
- # We could just 'else' here, but there might be some oddness later.
- prefix = parent.neutral_prefix
-
- # Later, this will have to escape things so we don't parse them,
- # likely...hm.
- #~result = "{} {} {!r}"
- # The input we get is already repr'd...we pass it via print, and thus
- # do that there.
- result = "{}{} {}\n"
- result = result.format(timestamp, prefix, msg)
- self.appendPlainText(result)
-
- # Direction doesn't matter here - it's the console.
- self.lastmsg = datetime.datetime.now()
- # This needs to finish being rewritten....
-
- def appendPlainText(self, text):
- """Add plain text to the end of the document, a la insertPlainText."""
- # Save the old cursor
- oldcur = self.textCursor()
- # Move the cursor to the end of the document for insertion
- self.moveCursor(QtGui.QTextCursor.End)
- # Insert the text
- self.insertPlainText(text)
- # Return the cursor to wherever it was prior
- self.setTextCursor(oldcur)
-
- def changeTheme(self, theme):
- self.initTheme(theme)
- sb = self.verticalScrollBar()
- sb.setValue(sb.maximum())
-
- def focusInEvent(self, event):
- self.window().clearNewMessage()
- super(ConsoleText, self).focusInEvent(event)
-
- def keyPressEvent(self, event):
- # NOTE: This doesn't give focus to the input bar, which it probably
- # should.
- # karxi: Test for tab changing?
- if self.window().text.input:
- if event.key() not in (QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown,
- QtCore.Qt.Key_Up, QtCore.Qt.Key_Down):
- self.window().text.input.keyPressEvent(event)
-
- super(ConsoleText, self).keyPressEvent(event)
-
- def mousePressEvent(self, event):
- if event.button() == QtCore.Qt.LeftButton:
- url = self.anchorAt(event.pos())
- if url != "":
- # Skip memo/handle recognition
- # NOTE: Ctrl+Click copies the URL. Maybe it should select it?
- if event.modifiers() == QtCore.Qt.ControlModifier:
- QtGui.QApplication.clipboard().setText(url)
- else:
- # This'll probably be removed. May change the lexer out.
- QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.TolerantMode))
-
- super(ConsoleText, self).mousePressEvent(event)
-
- def mouseMoveEvent(self, event):
- # Change our cursor when we roll over links (anchors).
- super(ConsoleText, self).mouseMoveEvent(event)
- if self.anchorAt(event.pos()):
- if self.viewport().cursor().shape != QtCore.Qt.PointingHandCursor:
- self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
- else:
- self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.IBeamCursor))
-
- def contextMenuEvent(self, event):
- # This is almost certainly no longer necessary.
- textMenu = self.createStandardContextMenu()
- #~if self.textSelected:
- #~ self.submitLogAction = QtGui.QAction("Submit to Pesterchum QDB", self)
- #~ self.connect(self.submitLogAction, QtCore.SIGNAL('triggered()'),
- #~ self, QtCore.SLOT('submitLog()'))
- #~ textMenu.addAction(self.submitLogAction)
- textMenu.exec_(event.globalPos())
-
-
-class ConsoleInput(QtGui.QLineEdit):
- """The actual text entry box on a ConsoleWindow."""
- # I honestly feel like this could just be made a private class of
- # ConsoleWindow, but...best not to overcomplicate things.
- stylesheet_path = "convo/input/style"
-
- def __init__(self, theme, parent=None):
- super(ConsoleInput, self).__init__(parent)
-
- self.changeTheme(theme)
-
- def changeTheme(self, theme):
- self.setStyleSheet(theme[self.stylesheet_path])
-
- def focusInEvent(self, event):
- # We gained focus. Notify the parent window that this happened.
- self.window().clearNewMessage()
- self.window().text.area.textCursor().clearSelection()
-
- super(ConsoleInput, self).focusInEvent(event)
-
- def keyPressEvent(self, event):
- evtkey = event.key()
- parent = self.window()
-
- # If a key is pressed here, we're not idle....
- # NOTE: Do we really want everyone knowing we're around if we're
- # messing around in the console? Hm.
- parent.mainwindow.idler.time = 0
-
- if evtkey == QtCore.Qt.Key_Up:
- text = unicode(self.text())
- next = parent.text.history.next(text)
- if next is not None:
- self.setText(next)
- elif evtkey == QtCore.Qt.Key_Down:
- prev = parent.text.history.prev()
- if prev is not None:
- self.setText(prev)
- elif evtkey in (QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown):
- parent.text.area.keyPressEvent(event)
- else:
- super(ConsoleInput, self).keyPressEvent(event)
diff --git a/convo.py b/convo.py
index 3aa4daf..2828022 100644
--- a/convo.py
+++ b/convo.py
@@ -1,11 +1,11 @@
from string import Template
import re
import platform
-import httplib, urllib
+import http.client, urllib.request, urllib.parse, urllib.error
from time import strftime
from copy import copy
from datetime import datetime, timedelta
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
from mood import Mood
from dataobjs import PesterProfile, PesterHistory
@@ -21,49 +21,42 @@ except ImportError:
# Fall back on the old location - just in case
from pnc.dep.attrdict import AttrDict
-class PesterTabWindow(QtGui.QFrame):
+class PesterTabWindow(QtWidgets.QFrame):
def __init__(self, mainwindow, parent=None, convo="convo"):
super(PesterTabWindow, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
self.setFocusPolicy(QtCore.Qt.ClickFocus)
self.mainwindow = mainwindow
- self.tabs = QtGui.QTabBar(self)
+ self.tabs = QtWidgets.QTabBar(self)
self.tabs.setMovable(True)
self.tabs.setTabsClosable(True)
- self.connect(self.tabs, QtCore.SIGNAL('currentChanged(int)'),
- self, QtCore.SLOT('changeTab(int)'))
- self.connect(self.tabs, QtCore.SIGNAL('tabCloseRequested(int)'),
- self, QtCore.SLOT('tabClose(int)'))
- self.connect(self.tabs, QtCore.SIGNAL('tabMoved(int, int)'),
- self, QtCore.SLOT('tabMoved(int, int)'))
+ self.tabs.currentChanged[int].connect(self.changeTab)
+ self.tabs.tabCloseRequested[int].connect(self.tabClose)
+ self.tabs.tabMoved[int, int].connect(self.tabMoved)
self.shortcuts = AttrDict()
- self.shortcuts.tabNext = QtGui.QShortcut(
+ self.shortcuts.tabNext = QtWidgets.QShortcut(
QtGui.QKeySequence('Ctrl+j'), self,
context=QtCore.Qt.WidgetWithChildrenShortcut)
- self.shortcuts.tabLast = QtGui.QShortcut(
+ self.shortcuts.tabLast = QtWidgets.QShortcut(
QtGui.QKeySequence('Ctrl+k'), self,
context=QtCore.Qt.WidgetWithChildrenShortcut)
# Note that we use reversed keys here.
- self.shortcuts.tabUp = QtGui.QShortcut(
+ self.shortcuts.tabUp = QtWidgets.QShortcut(
QtGui.QKeySequence('Ctrl+PgDown'), self,
context=QtCore.Qt.WidgetWithChildrenShortcut)
- self.shortcuts.tabDn = QtGui.QShortcut(
+ self.shortcuts.tabDn = QtWidgets.QShortcut(
QtGui.QKeySequence('Ctrl+PgUp'), self,
context=QtCore.Qt.WidgetWithChildrenShortcut)
- self.connect(self.shortcuts.tabNext, QtCore.SIGNAL('activated()'),
- self, QtCore.SLOT('nudgeTabNext()'))
- self.connect(self.shortcuts.tabUp, QtCore.SIGNAL('activated()'),
- self, QtCore.SLOT('nudgeTabNext()'))
- self.connect(self.shortcuts.tabLast, QtCore.SIGNAL('activated()'),
- self, QtCore.SLOT('nudgeTabLast()'))
- self.connect(self.shortcuts.tabDn, QtCore.SIGNAL('activated()'),
- self, QtCore.SLOT('nudgeTabLast()'))
+ self.shortcuts.tabNext.activated.connect(self.nudgeTabNext)
+ self.shortcuts.tabUp.activated.connect(self.nudgeTabNext)
+ self.shortcuts.tabLast.activated.connect(self.nudgeTabLast)
+ self.shortcuts.tabDn.activated.connect(self.nudgeTabLast)
self.initTheme(self.mainwindow.theme)
- self.layout = QtGui.QVBoxLayout()
+ self.layout = QtWidgets.QVBoxLayout()
self.layout.setContentsMargins(0,0,0,0)
self.layout.addWidget(self.tabs)
self.setLayout(self.layout)
@@ -116,7 +109,7 @@ class PesterTabWindow(QtGui.QFrame):
mods = event.modifiers()
if ((mods & QtCore.Qt.ControlModifier) and
keypress == QtCore.Qt.Key_Tab):
- handles = self.convos.keys()
+ handles = list(self.convos.keys())
waiting = self.mainwindow.waitingMessages.waitingHandles()
waitinghandles = list(set(handles) & set(waiting))
if len(waitinghandles) > 0:
@@ -153,7 +146,7 @@ class PesterTabWindow(QtGui.QFrame):
# The new index would be higher than the maximum; loop.
nind = nind % ct
# Otherwise, negative syntax should get it for us.
- nind = range(ct)[nind]
+ nind = list(range(ct))[nind]
# Change to the selected tab.
# Note that this will send out the usual callbacks that handle
# focusing and such.
@@ -164,7 +157,7 @@ class PesterTabWindow(QtGui.QFrame):
tabi = self.tabs.tabAt(event.pos())
if tabi < 0:
tabi = self.tabs.currentIndex()
- for h, i in self.tabIndices.items():
+ for h, i in list(self.tabIndices.items()):
if i == tabi:
# Our index matches, grab the object using our handle.
convo = self.convos[h]
@@ -203,7 +196,7 @@ class PesterTabWindow(QtGui.QFrame):
i = self.tabs.tabAt(self.mapFromGlobal(QtGui.QCursor.pos()))
if i == -1:
i = self.tabs.currentIndex()
- handle = unicode(self.tabs.tabText(i))
+ handle = str(self.tabs.tabText(i))
self.clearNewMessage(handle)
def convoHasFocus(self, handle):
i = self.tabIndices[handle]
@@ -237,24 +230,24 @@ class PesterTabWindow(QtGui.QFrame):
def changeTheme(self, theme):
self.initTheme(theme)
- for c in self.convos.values():
+ for c in list(self.convos.values()):
tabi = self.tabIndices[c.title()]
self.tabs.setTabIcon(tabi, c.icon())
currenttabi = self.tabs.currentIndex()
if currenttabi >= 0:
- currentHandle = unicode(self.tabs.tabText(self.tabs.currentIndex()))
+ currentHandle = str(self.tabs.tabText(self.tabs.currentIndex()))
self.setWindowIcon(self.convos[currentHandle].icon())
self.defaultTabTextColor = self.getTabTextColor()
@QtCore.pyqtSlot(int)
def tabClose(self, i):
- handle = unicode(self.tabs.tabText(i))
+ handle = str(self.tabs.tabText(i))
self.mainwindow.waitingMessages.messageAnswered(handle)
convo = self.convos[handle]
del self.convos[handle]
del self.tabIndices[handle]
self.tabs.removeTab(i)
- for (h, j) in self.tabIndices.iteritems():
+ for (h, j) in self.tabIndices.items():
if j > i:
self.tabIndices[h] = j-1
self.layout.removeWidget(convo)
@@ -264,7 +257,7 @@ class PesterTabWindow(QtGui.QFrame):
return
if self.currentConvo == convo:
currenti = self.tabs.currentIndex()
- currenth = unicode(self.tabs.tabText(currenti))
+ currenth = str(self.tabs.tabText(currenti))
self.currentConvo = self.convos[currenth]
self.currentConvo.raiseChat()
@@ -275,7 +268,7 @@ class PesterTabWindow(QtGui.QFrame):
if self.changedTab:
self.changedTab = False
return
- handle = unicode(self.tabs.tabText(i))
+ handle = str(self.tabs.tabText(i))
convo = self.convos[handle]
if self.currentConvo:
self.layout.removeWidget(self.currentConvo)
@@ -310,7 +303,7 @@ class PesterMovie(QtGui.QMovie):
if text.mainwindow.config.animations():
movie = self
url = text.urls[movie].toString()
- html = unicode(text.toHtml())
+ html = str(text.toHtml())
if html.find(url) != -1:
if text.hasTabs:
i = text.tabobject.tabIndices[text.parent().title()]
@@ -323,7 +316,7 @@ class PesterMovie(QtGui.QMovie):
text.urls[movie], movie.currentPixmap())
text.setLineWrapColumnOrWidth(text.lineWrapColumnOrWidth())
-class PesterText(QtGui.QTextEdit):
+class PesterText(QtWidgets.QTextEdit):
def __init__(self, theme, parent=None):
super(PesterText, self).__init__(parent)
if hasattr(self.parent(), 'mainwindow'):
@@ -339,33 +332,30 @@ class PesterText(QtGui.QTextEdit):
self.setReadOnly(True)
self.setMouseTracking(True)
self.textSelected = False
- self.connect(self, QtCore.SIGNAL('copyAvailable(bool)'),
- self, QtCore.SLOT('textReady(bool)'))
+ self.copyAvailable[bool].connect(self.textReady)
self.urls = {}
for k in smiledict:
self.addAnimation(QtCore.QUrl("smilies/%s" % (smiledict[k])), "smilies/%s" % (smiledict[k]))
- self.connect(self.mainwindow, QtCore.SIGNAL('animationSetting(bool)'),
- self, QtCore.SLOT('animateChanged(bool)'))
+ self.mainwindow.animationSetting[bool].connect(self.animateChanged)
def addAnimation(self, url, fileName):
movie = PesterMovie(self)
movie.setFileName(fileName)
movie.setCacheMode(QtGui.QMovie.CacheAll)
if movie.frameCount() > 1:
self.urls[movie] = url
- movie.connect(movie, QtCore.SIGNAL('frameChanged(int)'),
- movie, QtCore.SLOT('animate(int)'))
+ movie.frameChanged[int].connect(movie.animate)
#movie.start()
@QtCore.pyqtSlot(bool)
def animateChanged(self, animate):
if animate:
for m in self.urls:
- html = unicode(self.toHtml())
+ html = str(self.toHtml())
if html.find(self.urls[m].toString()) != -1:
if m.frameCount() > 1:
m.start()
else:
for m in self.urls:
- html = unicode(self.toHtml())
+ html = str(self.toHtml())
if html.find(self.urls[m].toString()) != -1:
if m.frameCount() > 1:
m.stop()
@@ -374,7 +364,7 @@ class PesterText(QtGui.QTextEdit):
def textReady(self, ready):
self.textSelected = ready
def initTheme(self, theme):
- if theme.has_key("convo/scrollbar"):
+ if "convo/scrollbar" in theme:
self.setStyleSheet("QTextEdit { %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }" % (theme["convo/textarea/style"], theme["convo/scrollbar/style"], theme["convo/scrollbar/handle"], theme["convo/scrollbar/downarrow"], theme["convo/scrollbar/uparrow"], theme["convo/scrollbar/uarrowstyle"], theme["convo/scrollbar/darrowstyle"] ))
else:
self.setStyleSheet("QTextEdit { %s }" % (theme["convo/textarea/style"]))
@@ -472,7 +462,7 @@ class PesterText(QtGui.QTextEdit):
sb.setValue(sb.maximum())
def focusInEvent(self, event):
self.parent().clearNewMessage()
- QtGui.QTextEdit.focusInEvent(self, event)
+ QtWidgets.QTextEdit.focusInEvent(self, event)
def isBot(self, *args, **kwargs):
return self.parent().isBot(*args, **kwargs)
@@ -499,16 +489,16 @@ class PesterText(QtGui.QTextEdit):
if url[0] == "#" and url != "#pesterchum":
self.parent().mainwindow.showMemos(url[1:])
elif url[0] == "@":
- handle = unicode(url[1:])
+ handle = str(url[1:])
self.parent().mainwindow.newConversation(handle)
else:
if event.modifiers() == QtCore.Qt.ControlModifier:
- QtGui.QApplication.clipboard().setText(url)
+ QtWidgets.QApplication.clipboard().setText(url)
else:
QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.TolerantMode))
- QtGui.QTextEdit.mousePressEvent(self, event)
+ QtWidgets.QTextEdit.mousePressEvent(self, event)
def mouseMoveEvent(self, event):
- QtGui.QTextEdit.mouseMoveEvent(self, event)
+ QtWidgets.QTextEdit.mouseMoveEvent(self, event)
if self.anchorAt(event.pos()):
if self.viewport().cursor().shape != QtCore.Qt.PointingHandCursor:
self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
@@ -535,22 +525,21 @@ class PesterText(QtGui.QTextEdit):
textdoc = QtGui.QTextDocument()
textdoc.setHtml(htmldata)
logdata = "%s\n%s" % (self.submitLogTitle(), textdoc.toPlainText())
- self.sending = QtGui.QDialog(self)
- layout = QtGui.QVBoxLayout()
- self.sending.sendinglabel = QtGui.QLabel("S3ND1NG...", self.sending)
- cancelbutton = QtGui.QPushButton("OK", self.sending)
- self.sending.connect(cancelbutton, QtCore.SIGNAL('clicked()'),
- self.sending, QtCore.SLOT('close()'))
+ self.sending = QtWidgets.QDialog(self)
+ layout = QtWidgets.QVBoxLayout()
+ self.sending.sendinglabel = QtWidgets.QLabel("S3ND1NG...", self.sending)
+ cancelbutton = QtWidgets.QPushButton("OK", self.sending)
+ cancelbutton.clicked.connect(self.sending.close)
layout.addWidget(self.sending.sendinglabel)
layout.addWidget(cancelbutton)
self.sending.setLayout(layout)
self.sending.show()
- params = urllib.urlencode({'quote': logdata, 'do': "add"})
+ params = urllib.parse.urlencode({'quote': logdata, 'do': "add"})
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
try:
pass
- hconn = httplib.HTTPConnection('qdb.pesterchum.net', 80,
+ hconn = http.client.HTTPConnection('qdb.pesterchum.net', 80,
timeout=15)
hconn.request("POST", "/index.php", params, headers)
response = hconn.getresponse()
@@ -563,7 +552,7 @@ class PesterText(QtGui.QTextEdit):
self.sending.sendinglabel.setText("F41L3D: %s" % (e))
del self.sending
-class PesterInput(QtGui.QLineEdit):
+class PesterInput(QtWidgets.QLineEdit):
stylesheet_path = "convo/input/style"
def __init__(self, theme, parent=None):
super(PesterInput, self).__init__(parent)
@@ -576,7 +565,7 @@ class PesterInput(QtGui.QLineEdit):
super(PesterInput, self).focusInEvent(event)
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Up:
- text = unicode(self.text())
+ text = str(self.text())
next = self.parent().history.next(text)
if next is not None:
self.setText(next)
@@ -589,7 +578,7 @@ class PesterInput(QtGui.QLineEdit):
self.parent().mainwindow.idler.time = 0
super(PesterInput, self).keyPressEvent(event)
-class PesterConvo(QtGui.QFrame):
+class PesterConvo(QtWidgets.QFrame):
def __init__(self, chum, initiated, mainwindow, parent=None):
super(PesterConvo, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
@@ -605,20 +594,19 @@ class PesterConvo(QtGui.QFrame):
t = Template(self.mainwindow.theme["convo/chumlabel/text"])
- self.chumLabel = QtGui.QLabel(t.safe_substitute(handle=chum.handle), self)
+ self.chumLabel = QtWidgets.QLabel(t.safe_substitute(handle=chum.handle), self)
self.chumLabel.setStyleSheet(self.mainwindow.theme["convo/chumlabel/style"])
self.chumLabel.setAlignment(self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]] | self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]])
self.chumLabel.setMaximumHeight(self.mainwindow.theme["convo/chumlabel/maxheight"])
self.chumLabel.setMinimumHeight(self.mainwindow.theme["convo/chumlabel/minheight"])
- self.chumLabel.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.MinimumExpanding))
+ self.chumLabel.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.MinimumExpanding))
self.textArea = PesterText(self.mainwindow.theme, self)
self.textInput = PesterInput(self.mainwindow.theme, self)
self.textInput.setFocus()
- self.connect(self.textInput, QtCore.SIGNAL('returnPressed()'),
- self, QtCore.SLOT('sentMessage()'))
+ self.textInput.returnPressed.connect(self.sentMessage)
- self.layout = QtGui.QVBoxLayout()
+ self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.chumLabel)
self.layout.addWidget(self.textArea)
self.layout.addWidget(self.textInput)
@@ -629,31 +617,24 @@ class PesterConvo(QtGui.QFrame):
self.setLayout(self.layout)
- self.optionsMenu = QtGui.QMenu(self)
+ self.optionsMenu = QtWidgets.QMenu(self)
self.optionsMenu.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
- self.addChumAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
- self.connect(self.addChumAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('addThisChum()'))
- self.blockAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self)
- self.connect(self.blockAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('blockThisChum()'))
- self.quirksOff = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self)
+ self.addChumAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
+ self.addChumAction.triggered.connect(self.addThisChum)
+ self.blockAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self)
+ self.blockAction.triggered.connect(self.blockThisChum)
+ self.quirksOff = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self)
self.quirksOff.setCheckable(True)
- self.connect(self.quirksOff, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleQuirks(bool)'))
- self.oocToggle = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self)
+ self.quirksOff.toggled[bool].connect(self.toggleQuirks)
+ self.oocToggle = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self)
self.oocToggle.setCheckable(True)
- self.connect(self.oocToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleOOC(bool)'))
- self.unblockchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self)
- self.connect(self.unblockchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('unblockChumSlot()'))
- self.reportchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/report"], self)
- self.connect(self.reportchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('reportThisChum()'))
- self.logchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
- self.connect(self.logchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('openChumLogs()'))
+ self.oocToggle.toggled[bool].connect(self.toggleOOC)
+ self.unblockchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self)
+ self.unblockchum.triggered.connect(self.unblockChumSlot)
+ self.reportchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/report"], self)
+ self.reportchum.triggered.connect(self.reportThisChum)
+ self.logchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
+ self.logchum.triggered.connect(self.openChumLogs)
# For this, we'll want to use setChecked to toggle these so they match
# the user's setting. Alternately (better), use a tristate checkbox, so
@@ -661,20 +642,17 @@ class PesterConvo(QtGui.QFrame):
# Easiest solution: Implement a 'Mute' option that overrides all
# notifications for that window, save for mentions.
# TODO: Look into setting up theme support here.
- self._beepToggle = QtGui.QAction("Beep on Message", self)
+ self._beepToggle = QtWidgets.QAction("Beep on Message", self)
self._beepToggle.setCheckable(True)
- self.connect(self._beepToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleBeep(bool)'))
+ self._beepToggle.toggled[bool].connect(self.toggleBeep)
- self._flashToggle = QtGui.QAction("Flash on Message", self)
+ self._flashToggle = QtWidgets.QAction("Flash on Message", self)
self._flashToggle.setCheckable(True)
- self.connect(self._flashToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleFlash(bool)'))
+ self._flashToggle.toggled[bool].connect(self.toggleFlash)
- self._muteToggle = QtGui.QAction("Mute Notifications", self)
+ self._muteToggle = QtWidgets.QAction("Mute Notifications", self)
self._muteToggle.setCheckable(True)
- self.connect(self._muteToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleMute(bool)'))
+ self._muteToggle.toggled[bool].connect(self.toggleMute)
self.optionsMenu.addAction(self.quirksOff)
self.optionsMenu.addAction(self.oocToggle)
@@ -755,7 +733,7 @@ class PesterConvo(QtGui.QFrame):
def updateColor(self, color):
self.chum.color = color
def addMessage(self, msg, me=True):
- if type(msg) in [str, unicode]:
+ if type(msg) in [str, str]:
lexmsg = lexMessage(msg)
else:
lexmsg = msg
@@ -870,7 +848,7 @@ class PesterConvo(QtGui.QFrame):
self.chumLabel.setAlignment(self.aligndict["h"][self.mainwindow.theme["convo/chumlabel/align/h"]] | self.aligndict["v"][self.mainwindow.theme["convo/chumlabel/align/v"]])
self.chumLabel.setMaximumHeight(self.mainwindow.theme["convo/chumlabel/maxheight"])
self.chumLabel.setMinimumHeight(self.mainwindow.theme["convo/chumlabel/minheight"])
- self.chumLabel.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding))
+ self.chumLabel.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding))
self.quirksOff.setText(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"])
self.addChumAction.setText(self.mainwindow.theme["main/menus/rclickchumlist/addchum"])
self.blockAction.setText(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"])
@@ -886,7 +864,7 @@ class PesterConvo(QtGui.QFrame):
# Offloaded to another function, like its sisters.
# Fetch the raw text from the input box.
text = self.textInput.text()
- text = unicode(self.textInput.text())
+ text = str(self.textInput.text())
return parsetools.kxhandleInput(self, text, flavor="convo")
@@ -912,8 +890,7 @@ class PesterConvo(QtGui.QFrame):
def openChumLogs(self):
currentChum = self.chum.handle
self.mainwindow.chumList.pesterlogviewer = PesterLogViewer(currentChum, self.mainwindow.config, self.mainwindow.theme, self.mainwindow)
- self.connect(self.mainwindow.chumList.pesterlogviewer, QtCore.SIGNAL('rejected()'),
- self.mainwindow.chumList, QtCore.SLOT('closeActiveLog()'))
+ self.mainwindow.chumList.pesterlogviewer.rejected.connect(self.mainwindow.chumList.closeActiveLog)
self.mainwindow.chumList.pesterlogviewer.show()
self.mainwindow.chumList.pesterlogviewer.raise_()
self.mainwindow.chumList.pesterlogviewer.activateWindow()
@@ -930,8 +907,8 @@ class PesterConvo(QtGui.QFrame):
def toggleMute(self, toggled):
self.notifications_muted = toggled
- messageSent = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- windowClosed = QtCore.pyqtSignal(QtCore.QString)
+ messageSent = QtCore.pyqtSignal('QString', 'QString')
+ windowClosed = QtCore.pyqtSignal('QString')
aligndict = {"h": {"center": QtCore.Qt.AlignHCenter,
"left": QtCore.Qt.AlignLeft,
diff --git a/dataobjs.py b/dataobjs.py
index 0ea6c58..f459126 100644
--- a/dataobjs.py
+++ b/dataobjs.py
@@ -1,4 +1,4 @@
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui
from datetime import *
import re
import random
@@ -111,7 +111,7 @@ class pesterQuirks(object):
newlist = []
for (i, o) in enumerate(lexed):
- if type(o) not in [str, unicode]:
+ if type(o) not in [str, str]:
if i == 0:
string = " "
for p in prefix:
@@ -135,7 +135,7 @@ class pesterQuirks(object):
final = []
for n in newlist:
- if type(n) in [str, unicode]:
+ if type(n) in [str, str]:
final.extend(lexMessage(n))
else:
final.append(n)
@@ -191,9 +191,9 @@ class PesterProfile(object):
def plaindict(self):
return (self.handle, {"handle": self.handle,
"mood": self.mood.name(),
- "color": unicode(self.color.name()),
- "group": unicode(self.group),
- "notes": unicode(self.notes)})
+ "color": str(self.color.name()),
+ "group": str(self.group),
+ "notes": str(self.notes)})
def blocked(self, config):
return self.handle in config.getBlocklist()
@@ -238,7 +238,7 @@ class PesterProfile(object):
(opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials))
else:
return "%s banned %s from responding to memo: [%s]." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials), unicode(reason))
+ (opchum.colorhtml(), opinit, self.colorhtml(), ", ".join(initials), str(reason))
else:
initials = timeGrammar.pcf+self.initials()+timeGrammar.number
if opchum.handle == reason:
@@ -246,7 +246,7 @@ class PesterProfile(object):
(opchum.colorhtml(), opinit, self.colorhtml(), initials)
else:
return "%s banned %s from responding to memo: [%s]." % \
- (opchum.colorhtml(), opinit, self.colorhtml(), initials, unicode(reason))
+ (opchum.colorhtml(), opinit, self.colorhtml(), initials, str(reason))
def memopermabanmsg(self, opchum, opgrammar, syscolor, timeGrammar):
initials = timeGrammar.pcf+self.initials()+timeGrammar.number
opinit = opgrammar.pcf+opchum.initials()+opgrammar.number
diff --git a/generic.py b/generic.py
index 2c7453e..219708b 100644
--- a/generic.py
+++ b/generic.py
@@ -1,4 +1,4 @@
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
from datetime import timedelta
class mysteryTime(timedelta):
@@ -17,7 +17,7 @@ class CaseInsensitiveDict(dict):
def __contains__(self, key):
return super(CaseInsensitiveDict, self).__contains__(key.lower())
def has_key(self, key):
- return super(CaseInsensitiveDict, self).has_key(key.lower())
+ return key.lower() in super(CaseInsensitiveDict, self)
def __delitem__(self, key):
super(CaseInsensitiveDict, self).__delitem__(key.lower())
@@ -28,7 +28,7 @@ class PesterList(list):
class PesterIcon(QtGui.QIcon):
def __init__(self, *x):
super(PesterIcon, self).__init__(x[0])
- if type(x[0]) in [str, unicode]:
+ if type(x[0]) in [str, str]:
self.icon_pixmap = QtGui.QPixmap(x[0])
else:
self.icon_pixmap = None
@@ -41,7 +41,7 @@ class PesterIcon(QtGui.QIcon):
except IndexError:
return None
-class RightClickList(QtGui.QListWidget):
+class RightClickList(QtWidgets.QListWidget):
def contextMenuEvent(self, event):
#fuckin Qt
if event.reason() == QtGui.QContextMenuEvent.Mouse:
@@ -53,7 +53,7 @@ class RightClickList(QtGui.QListWidget):
def getOptionsMenu(self):
return self.optionsMenu
-class RightClickTree(QtGui.QTreeWidget):
+class RightClickTree(QtWidgets.QTreeWidget):
def contextMenuEvent(self, event):
if event.reason() == QtGui.QContextMenuEvent.Mouse:
listing = self.itemAt(event.pos())
@@ -64,49 +64,47 @@ class RightClickTree(QtGui.QTreeWidget):
def getOptionsMenu(self):
return self.optionsMenu
-class MultiTextDialog(QtGui.QDialog):
+class MultiTextDialog(QtWidgets.QDialog):
def __init__(self, title, parent, *queries):
super(MultiTextDialog, self).__init__(parent)
self.setWindowTitle(title)
if len(queries) == 0:
return
self.inputs = {}
- layout_1 = QtGui.QHBoxLayout()
+ layout_1 = QtWidgets.QHBoxLayout()
for d in queries:
label = d["label"]
inputname = d["inputname"]
value = d.get("value", "")
- l = QtGui.QLabel(label, self)
+ l = QtWidgets.QLabel(label, self)
layout_1.addWidget(l)
- self.inputs[inputname] = QtGui.QLineEdit(value, self)
+ self.inputs[inputname] = QtWidgets.QLineEdit(value, self)
layout_1.addWidget(self.inputs[inputname])
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.accept)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.ok)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addLayout(layout_1)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
def getText(self):
r = self.exec_()
- if r == QtGui.QDialog.Accepted:
+ if r == QtWidgets.QDialog.Accepted:
retval = {}
- for (name, widget) in self.inputs.iteritems():
- retval[name] = unicode(widget.text())
+ for (name, widget) in self.inputs.items():
+ retval[name] = str(widget.text())
return retval
else:
return None
-class MovingWindow(QtGui.QFrame):
+class MovingWindow(QtWidgets.QFrame):
def __init__(self, *x, **y):
super(MovingWindow, self).__init__(*x, **y)
self.moving = None
@@ -133,7 +131,7 @@ class NoneSound(object):
def play(self): pass
def setVolume(self, v): pass
-class WMButton(QtGui.QPushButton):
+class WMButton(QtWidgets.QPushButton):
def __init__(self, icon, parent=None):
super(WMButton, self).__init__(icon, "", parent)
self.setIconSize(icon.realsize())
diff --git a/irc.py b/irc.py
index 09ced40..3449e1b 100644
--- a/irc.py
+++ b/irc.py
@@ -1,4 +1,4 @@
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui
from oyoyo.client import IRCClient
from oyoyo.cmdhandler import DefaultCommandHandler
from oyoyo import helpers, services
@@ -13,6 +13,12 @@ from generic import PesterList
from version import _pcVersion
import ostools
+try:
+ QString = unicode
+except NameError:
+ # Python 3
+ QString = str
+
if ostools.isOSXBundle():
logging.basicConfig(level=logging.WARNING)
else:
@@ -39,7 +45,7 @@ class PesterIRC(QtCore.QThread):
def run(self):
try:
self.IRCConnect()
- except socket.error, se:
+ except socket.error as se:
self.stopIRC = se
return
while 1:
@@ -47,12 +53,12 @@ class PesterIRC(QtCore.QThread):
try:
logging.debug("updateIRC()")
res = self.updateIRC()
- except socket.timeout, se:
+ except socket.timeout as se:
logging.debug("timeout in thread %s" % (self))
self.cli.close()
self.stopIRC = se
return
- except socket.error, se:
+ except socket.error as se:
if self.registeredIRC:
self.stopIRC = None
else:
@@ -74,13 +80,13 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot()
def updateIRC(self):
try:
- res = self.conn.next()
- except socket.timeout, se:
+ res = next(self.conn)
+ except socket.timeout as se:
if self.registeredIRC:
return True
else:
raise se
- except socket.error, se:
+ except socket.error as se:
raise se
except StopIteration:
self.conn = self.cli.conn()
@@ -98,18 +104,18 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot(PesterList)
def getMoods(self, chums):
self.cli.command_handler.getMood(*chums)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def sendNotice(self, text, handle):
- h = unicode(handle)
- t = unicode(text)
+ h = str(handle)
+ t = str(text)
try:
helpers.notice(self.cli, h, t)
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def sendMessage(self, text, handle):
- h = unicode(handle)
- textl = [unicode(text)]
+ h = str(handle)
+ textl = [str(text)]
def splittext(l):
if len(l[0]) > 450:
space = l[0].rfind(" ", 0,430)
@@ -152,18 +158,18 @@ class PesterIRC(QtCore.QThread):
helpers.msg(self.cli, h, t)
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString, bool)
+ @QtCore.pyqtSlot(QString, bool)
def startConvo(self, handle, initiated):
- h = unicode(handle)
+ h = str(handle)
try:
if initiated:
helpers.msg(self.cli, h, "PESTERCHUM:BEGIN")
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def endConvo(self, handle):
- h = unicode(handle)
+ h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:CEASE")
except socket.error:
@@ -191,28 +197,28 @@ class PesterIRC(QtCore.QThread):
@QtCore.pyqtSlot()
def updateColor(self):
me = self.mainwindow.profile()
- for h in self.mainwindow.convos.keys():
+ for h in list(self.mainwindow.convos.keys()):
try:
helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd()))
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def blockedChum(self, handle):
- h = unicode(handle)
+ h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:BLOCK")
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def unblockedChum(self, handle):
- h = unicode(handle)
+ h = str(handle)
try:
helpers.msg(self.cli, h, "PESTERCHUM:UNBLOCK")
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def requestNames(self, channel):
- c = unicode(channel)
+ c = str(channel)
try:
helpers.names(self.cli, c)
except socket.error:
@@ -223,60 +229,60 @@ class PesterIRC(QtCore.QThread):
helpers.channel_list(self.cli)
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def joinChannel(self, channel):
- c = unicode(channel)
+ c = str(channel)
try:
helpers.join(self.cli, c)
helpers.mode(self.cli, c, "", None)
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def leftChannel(self, channel):
- c = unicode(channel)
+ c = str(channel)
try:
helpers.part(self.cli, c)
self.cli.command_handler.joined = False
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def kickUser(self, handle, channel):
l = handle.split(":")
- c = unicode(channel)
- h = unicode(l[0])
+ c = str(channel)
+ h = str(l[0])
if len(l) > 1:
- reason = unicode(l[1])
+ reason = str(l[1])
if len(l) > 2:
for x in l[2:]:
- reason += unicode(":") + unicode(x)
+ reason += str(":") + str(x)
else:
reason = ""
try:
helpers.kick(self.cli, h, c, reason)
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString, QString)
def setChannelMode(self, channel, mode, command):
- c = unicode(channel)
- m = unicode(mode)
- cmd = unicode(command)
+ c = str(channel)
+ m = str(mode)
+ cmd = str(command)
if cmd == "":
cmd = None
try:
helpers.mode(self.cli, c, m, cmd)
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def channelNames(self, channel):
- c = unicode(channel)
+ c = str(channel)
try:
helpers.names(self.cli, c)
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def inviteChum(self, handle, channel):
- h = unicode(handle)
- c = unicode(channel)
+ h = str(handle)
+ c = str(channel)
try:
helpers.invite(self.cli, h, c)
except socket.error:
@@ -299,34 +305,34 @@ class PesterIRC(QtCore.QThread):
except socket.error:
self.setConnectionBroken()
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def killSomeQuirks(self, channel, handle):
- c = unicode(channel)
- h = unicode(handle)
+ c = str(channel)
+ h = str(handle)
try:
helpers.ctcp(self.cli, c, "NOQUIRKS", h)
except socket.error:
self.setConnectionBroken()
- moodUpdated = QtCore.pyqtSignal(QtCore.QString, Mood)
- colorUpdated = QtCore.pyqtSignal(QtCore.QString, QtGui.QColor)
- messageReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- memoReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString)
- noticeReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- inviteReceived = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- timeCommand = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString)
- namesReceived = QtCore.pyqtSignal(QtCore.QString, PesterList)
+ moodUpdated = QtCore.pyqtSignal('QString', Mood)
+ colorUpdated = QtCore.pyqtSignal('QString', QtGui.QColor)
+ messageReceived = QtCore.pyqtSignal('QString', 'QString')
+ memoReceived = QtCore.pyqtSignal('QString', 'QString', 'QString')
+ noticeReceived = QtCore.pyqtSignal('QString', 'QString')
+ inviteReceived = QtCore.pyqtSignal('QString', 'QString')
+ timeCommand = QtCore.pyqtSignal('QString', 'QString', 'QString')
+ namesReceived = QtCore.pyqtSignal('QString', PesterList)
channelListReceived = QtCore.pyqtSignal(PesterList)
- nickCollision = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- myHandleChanged = QtCore.pyqtSignal(QtCore.QString)
- chanInviteOnly = QtCore.pyqtSignal(QtCore.QString)
- modesUpdated = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
+ nickCollision = QtCore.pyqtSignal('QString', 'QString')
+ myHandleChanged = QtCore.pyqtSignal('QString')
+ chanInviteOnly = QtCore.pyqtSignal('QString')
+ modesUpdated = QtCore.pyqtSignal('QString', 'QString')
connected = QtCore.pyqtSignal()
- userPresentUpdate = QtCore.pyqtSignal(QtCore.QString, QtCore.QString,
- QtCore.QString)
- cannotSendToChan = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
+ userPresentUpdate = QtCore.pyqtSignal('QString', 'QString',
+ 'QString')
+ cannotSendToChan = QtCore.pyqtSignal('QString', 'QString')
tooManyPeeps = QtCore.pyqtSignal()
- quirkDisable = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString)
+ quirkDisable = QtCore.pyqtSignal('QString', 'QString', 'QString')
class PesterHandler(DefaultCommandHandler):
def notice(self, nick, chan, msg):
diff --git a/libs/feedparser.py b/libs/feedparser.py
index 91bec85..127c14f 100755
--- a/libs/feedparser.py
+++ b/libs/feedparser.py
@@ -66,11 +66,12 @@ TIDY_MARKUP = 0
PREFERRED_TIDY_INTERFACES = ["uTidy", "mxTidy"]
# ---------- required modules (should come with any Python distribution) ----------
-import sgmllib, re, sys, copy, urlparse, time, rfc822, types, cgi, urllib, urllib2
+import sgmllib, re, sys, copy, urllib.parse, time, rfc822, types, cgi, urllib.request, urllib.parse, urllib.error, urllib.request, urllib.error, urllib.parse
+# We *really* need to find a proper alternative for smgllib
try:
- from cStringIO import StringIO as _StringIO
+ from io import StringIO as _StringIO
except:
- from StringIO import StringIO as _StringIO
+ from io import StringIO as _StringIO
# ---------- optional modules (feedparser will work without these, but with reduced functionality) ----------
@@ -191,7 +192,7 @@ class FeedParserDict(UserDict):
if key == 'categories':
return [(tag['scheme'], tag['term']) for tag in UserDict.__getitem__(self, 'tags')]
realkey = self.keymap.get(key, key)
- if type(realkey) == types.ListType:
+ if type(realkey) == list:
for k in realkey:
if UserDict.has_key(self, k):
return UserDict.__getitem__(self, k)
@@ -200,21 +201,21 @@ class FeedParserDict(UserDict):
return UserDict.__getitem__(self, realkey)
def __setitem__(self, key, value):
- for k in self.keymap.keys():
+ for k in list(self.keymap.keys()):
if key == k:
key = self.keymap[k]
- if type(key) == types.ListType:
+ if type(key) == list:
key = key[0]
return UserDict.__setitem__(self, key, value)
def get(self, key, default=None):
- if self.has_key(key):
+ if key in self:
return self[key]
else:
return default
def setdefault(self, key, value):
- if not self.has_key(key):
+ if key not in self:
self[key] = value
return self[key]
@@ -233,7 +234,7 @@ class FeedParserDict(UserDict):
assert not key.startswith('_')
return self.__getitem__(key)
except:
- raise AttributeError, "object has no attribute '%s'" % key
+ raise AttributeError("object has no attribute '%s'" % key)
def __setattr__(self, key, value):
if key.startswith('_') or key == 'data':
@@ -242,7 +243,7 @@ class FeedParserDict(UserDict):
return self.__setitem__(key, value)
def __contains__(self, key):
- return self.has_key(key)
+ return key in self
def zopeCompatibilityHack():
global FeedParserDict
@@ -277,13 +278,13 @@ def _ebcdic_to_ascii(s):
)
import string
_ebcdic_to_ascii_map = string.maketrans( \
- ''.join(map(chr, range(256))), ''.join(map(chr, emap)))
+ ''.join(map(chr, list(range(256)))), ''.join(map(chr, emap)))
return s.translate(_ebcdic_to_ascii_map)
_urifixer = re.compile('^([A-Za-z][A-Za-z0-9+-.]*://)(/*)(.*?)')
def _urljoin(base, uri):
uri = _urifixer.sub(r'\1\3', uri)
- return urlparse.urljoin(base, uri)
+ return urllib.parse.urljoin(base, uri)
class _FeedParserMixin:
namespaces = {'': '',
@@ -357,7 +358,7 @@ class _FeedParserMixin:
def __init__(self, baseuri=None, baselang=None, encoding='utf-8'):
if _debug: sys.stderr.write('initializing FeedParser\n')
if not self._matchnamespaces:
- for k, v in self.namespaces.items():
+ for k, v in list(self.namespaces.items()):
self._matchnamespaces[k.lower()] = v
self.feeddata = FeedParserDict() # feed-level data
self.encoding = encoding # character encoding
@@ -420,7 +421,7 @@ class _FeedParserMixin:
self.trackNamespace(None, uri)
# track inline content
- if self.incontent and self.contentparams.has_key('type') and not self.contentparams.get('type', 'xml').endswith('xml'):
+ if self.incontent and 'type' in self.contentparams and not self.contentparams.get('type', 'xml').endswith('xml'):
# element declared itself as escaped markup, but it isn't really
self.contentparams['type'] = 'application/xhtml+xml'
if self.incontent and self.contentparams.get('type') == 'application/xhtml+xml':
@@ -436,7 +437,7 @@ class _FeedParserMixin:
return self.handle_data('<%s%s>' % (tag, ''.join([' %s="%s"' % t for t in attrs])), escape=0)
# match namespaces
- if tag.find(':') <> -1:
+ if tag.find(':') != -1:
prefix, suffix = tag.split(':', 1)
else:
prefix, suffix = '', tag
@@ -461,7 +462,7 @@ class _FeedParserMixin:
def unknown_endtag(self, tag):
if _debug: sys.stderr.write('end %s\n' % tag)
# match namespaces
- if tag.find(':') <> -1:
+ if tag.find(':') != -1:
prefix, suffix = tag.split(':', 1)
else:
prefix, suffix = '', tag
@@ -478,7 +479,7 @@ class _FeedParserMixin:
self.pop(prefix + suffix)
# track inline content
- if self.incontent and self.contentparams.has_key('type') and not self.contentparams.get('type', 'xml').endswith('xml'):
+ if self.incontent and 'type' in self.contentparams and not self.contentparams.get('type', 'xml').endswith('xml'):
# element declared itself as escaped markup, but it isn't really
self.contentparams['type'] = 'application/xhtml+xml'
if self.incontent and self.contentparams.get('type') == 'application/xhtml+xml':
@@ -506,7 +507,7 @@ class _FeedParserMixin:
c = int(ref[1:], 16)
else:
c = int(ref)
- text = unichr(c).encode('utf-8')
+ text = chr(c).encode('utf-8')
self.elementstack[-1][2].append(text)
def handle_entityref(self, ref):
@@ -518,16 +519,16 @@ class _FeedParserMixin:
else:
# entity resolution graciously donated by Aaron Swartz
def name2cp(k):
- import htmlentitydefs
+ import html.entities
if hasattr(htmlentitydefs, 'name2codepoint'): # requires Python 2.3
- return htmlentitydefs.name2codepoint[k]
- k = htmlentitydefs.entitydefs[k]
+ return html.entities.name2codepoint[k]
+ k = html.entities.entitydefs[k]
if k.startswith('') and k.endswith(';'):
return int(k[2:-1]) # not in latin-1
return ord(k)
try: name2cp(ref)
except KeyError: text = '&%s;' % ref
- else: text = unichr(name2cp(ref)).encode('utf-8')
+ else: text = chr(name2cp(ref)).encode('utf-8')
self.elementstack[-1][2].append(text)
def handle_data(self, text, escape=1):
@@ -579,11 +580,11 @@ class _FeedParserMixin:
self.version = 'rss10'
if loweruri == 'http://www.w3.org/2005/atom' and not self.version:
self.version = 'atom10'
- if loweruri.find('backend.userland.com/rss') <> -1:
+ if loweruri.find('backend.userland.com/rss') != -1:
# match any backend.userland.com namespace
uri = 'http://backend.userland.com/rss'
loweruri = uri
- if self._matchnamespaces.has_key(loweruri):
+ if loweruri in self._matchnamespaces:
self.namespacemap[prefix] = self._matchnamespaces[loweruri]
self.namespacesInUse[self._matchnamespaces[loweruri]] = uri
else:
@@ -645,9 +646,9 @@ class _FeedParserMixin:
if element in self.can_contain_dangerous_markup:
output = _sanitizeHTML(output, self.encoding)
- if self.encoding and type(output) != type(u''):
+ if self.encoding and type(output) != type(''):
try:
- output = unicode(output, self.encoding)
+ output = str(output, self.encoding)
except:
pass
@@ -704,7 +705,7 @@ class _FeedParserMixin:
def _mapToStandardPrefix(self, name):
colonpos = name.find(':')
- if colonpos <> -1:
+ if colonpos != -1:
prefix = name[:colonpos]
suffix = name[colonpos+1:]
prefix = self.namespacemap.get(prefix, prefix)
@@ -767,11 +768,11 @@ class _FeedParserMixin:
_start_feedinfo = _start_channel
def _cdf_common(self, attrsD):
- if attrsD.has_key('lastmod'):
+ if 'lastmod' in attrsD:
self._start_modified({})
self.elementstack[-1][-1] = attrsD['lastmod']
self._end_modified()
- if attrsD.has_key('href'):
+ if 'href' in attrsD:
self._start_link({})
self.elementstack[-1][-1] = attrsD['href']
self._end_link()
@@ -1147,7 +1148,7 @@ class _FeedParserMixin:
attrsD.setdefault('rel', 'alternate')
attrsD.setdefault('type', 'text/html')
attrsD = self._itsAnHrefDamnIt(attrsD)
- if attrsD.has_key('href'):
+ if 'href' in attrsD:
attrsD['href'] = self.resolveURI(attrsD['href'])
expectingText = self.infeed or self.inentry or self.insource
context = self._getContext()
@@ -1155,7 +1156,7 @@ class _FeedParserMixin:
context['links'].append(FeedParserDict(attrsD))
if attrsD['rel'] == 'enclosure':
self._start_enclosure(attrsD)
- if attrsD.has_key('href'):
+ if 'href' in attrsD:
expectingText = 0
if (attrsD.get('rel') == 'alternate') and (self.mapContentType(attrsD.get('type')) in self.html_types):
context['link'] = attrsD['href']
@@ -1178,7 +1179,7 @@ class _FeedParserMixin:
def _end_guid(self):
value = self.pop('id')
- self._save('guidislink', self.guidislink and not self._getContext().has_key('link'))
+ self._save('guidislink', self.guidislink and 'link' not in self._getContext())
if self.guidislink:
# guid acts as link, but only if 'ispermalink' is not present or is 'true',
# and only if the item doesn't already have a link element
@@ -1201,7 +1202,7 @@ class _FeedParserMixin:
def _start_description(self, attrsD):
context = self._getContext()
- if context.has_key('summary'):
+ if 'summary' in context:
self._summaryKey = 'content'
self._start_content(attrsD)
else:
@@ -1234,7 +1235,7 @@ class _FeedParserMixin:
def _start_generator(self, attrsD):
if attrsD:
attrsD = self._itsAnHrefDamnIt(attrsD)
- if attrsD.has_key('href'):
+ if 'href' in attrsD:
attrsD['href'] = self.resolveURI(attrsD['href'])
self._getContext()['generator_detail'] = FeedParserDict(attrsD)
self.push('generator', 1)
@@ -1242,7 +1243,7 @@ class _FeedParserMixin:
def _end_generator(self):
value = self.pop('generator')
context = self._getContext()
- if context.has_key('generator_detail'):
+ if 'generator_detail' in context:
context['generator_detail']['name'] = value
def _start_admin_generatoragent(self, attrsD):
@@ -1262,7 +1263,7 @@ class _FeedParserMixin:
def _start_summary(self, attrsD):
context = self._getContext()
- if context.has_key('summary'):
+ if 'summary' in context:
self._summaryKey = 'content'
self._start_content(attrsD)
else:
@@ -1352,7 +1353,7 @@ if _XML_AVAILABLE:
def startElementNS(self, name, qname, attrs):
namespace, localname = name
lowernamespace = str(namespace or '').lower()
- if lowernamespace.find('backend.userland.com/rss') <> -1:
+ if lowernamespace.find('backend.userland.com/rss') != -1:
# match any backend.userland.com namespace
namespace = 'http://backend.userland.com/rss'
lowernamespace = namespace
@@ -1361,12 +1362,12 @@ if _XML_AVAILABLE:
else:
givenprefix = None
prefix = self._matchnamespaces.get(lowernamespace, givenprefix)
- if givenprefix and (prefix == None or (prefix == '' and lowernamespace == '')) and not self.namespacesInUse.has_key(givenprefix):
- raise UndeclaredNamespace, "'%s' is not associated with a namespace" % givenprefix
+ if givenprefix and (prefix == None or (prefix == '' and lowernamespace == '')) and givenprefix not in self.namespacesInUse:
+ raise UndeclaredNamespace("'%s' is not associated with a namespace" % givenprefix)
if prefix:
localname = prefix + ':' + localname
localname = str(localname).lower()
- if _debug: sys.stderr.write('startElementNS: qname = %s, namespace = %s, givenprefix = %s, prefix = %s, attrs = %s, localname = %s\n' % (qname, namespace, givenprefix, prefix, attrs.items(), localname))
+ if _debug: sys.stderr.write('startElementNS: qname = %s, namespace = %s, givenprefix = %s, prefix = %s, attrs = %s, localname = %s\n' % (qname, namespace, givenprefix, prefix, list(attrs.items()), localname))
# qname implementation is horribly broken in Python 2.1 (it
# doesn't report any), and slightly broken in Python 2.2 (it
@@ -1376,7 +1377,7 @@ if _XML_AVAILABLE:
# at all). Thanks to MatejC for helping me test this and
# tirelessly telling me that it didn't work yet.
attrsD = {}
- for (namespace, attrlocalname), attrvalue in attrs._attrs.items():
+ for (namespace, attrlocalname), attrvalue in list(attrs._attrs.items()):
lowernamespace = (namespace or '').lower()
prefix = self._matchnamespaces.get(lowernamespace, '')
if prefix:
@@ -1384,7 +1385,7 @@ if _XML_AVAILABLE:
attrsD[str(attrlocalname).lower()] = attrvalue
for qname in attrs.getQNames():
attrsD[str(qname).lower()] = attrs.getValueByQName(qname)
- self.unknown_starttag(localname, attrsD.items())
+ self.unknown_starttag(localname, list(attrsD.items()))
def characters(self, text):
self.handle_data(text)
@@ -1436,7 +1437,7 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
data = re.sub(r'<([^<\s]+?)\s*/>', self._shorttag_replace, data)
data = data.replace(''', "'")
data = data.replace('"', '"')
- if self.encoding and type(data) == type(u''):
+ if self.encoding and type(data) == type(''):
data = data.encode(self.encoding)
sgmllib.SGMLParser.feed(self, data)
@@ -1454,10 +1455,10 @@ class _BaseHTMLProcessor(sgmllib.SGMLParser):
uattrs = []
# thanks to Kevin Marks for this breathtaking hack to deal with (valid) high-bit attribute values in UTF-8 feeds
for key, value in attrs:
- if type(value) != type(u''):
- value = unicode(value, self.encoding)
- uattrs.append((unicode(key, self.encoding), value))
- strattrs = u''.join([u' %s="%s"' % (key, value) for key, value in uattrs]).encode(self.encoding)
+ if type(value) != type(''):
+ value = str(value, self.encoding)
+ uattrs.append((str(key, self.encoding), value))
+ strattrs = ''.join([' %s="%s"' % (key, value) for key, value in uattrs]).encode(self.encoding)
if tag in self.elements_no_end_tag:
self.pieces.append('<%(tag)s%(strattrs)s />' % locals())
else:
@@ -1541,7 +1542,7 @@ class _LooseFeedParser(_FeedParserMixin, _BaseHTMLProcessor):
data = data.replace('"', '"')
data = data.replace(''', ''')
data = data.replace(''', ''')
- if self.contentparams.has_key('type') and not self.contentparams.get('type', 'xml').endswith('xml'):
+ if 'type' in self.contentparams and not self.contentparams.get('type', 'xml').endswith('xml'):
data = data.replace('<', '<')
data = data.replace('>', '>')
data = data.replace('&', '&')
@@ -1671,12 +1672,12 @@ def _sanitizeHTML(htmlSource, encoding):
except:
pass
if _tidy:
- utf8 = type(data) == type(u'')
+ utf8 = type(data) == type('')
if utf8:
data = data.encode('utf-8')
data = _tidy(data, output_xhtml=1, numeric_entities=1, wrap=0, char_encoding="utf8")
if utf8:
- data = unicode(data, 'utf-8')
+ data = str(data, 'utf-8')
if data.count(''):
@@ -1686,7 +1687,7 @@ def _sanitizeHTML(htmlSource, encoding):
data = data.strip().replace('\r\n', '\n')
return data
-class _FeedURLHandler(urllib2.HTTPDigestAuthHandler, urllib2.HTTPRedirectHandler, urllib2.HTTPDefaultErrorHandler):
+class _FeedURLHandler(urllib.request.HTTPDigestAuthHandler, urllib.request.HTTPRedirectHandler, urllib.request.HTTPDefaultErrorHandler):
def http_error_default(self, req, fp, code, msg, headers):
if ((code / 100) == 3) and (code != 304):
return self.http_error_302(req, fp, code, msg, headers)
@@ -1695,8 +1696,8 @@ class _FeedURLHandler(urllib2.HTTPDigestAuthHandler, urllib2.HTTPRedirectHandler
return infourl
def http_error_302(self, req, fp, code, msg, headers):
- if headers.dict.has_key('location'):
- infourl = urllib2.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
+ if 'location' in headers.dict:
+ infourl = urllib.request.HTTPRedirectHandler.http_error_302(self, req, fp, code, msg, headers)
else:
infourl = urllib.addinfourl(fp, headers, req.get_full_url())
if not hasattr(infourl, 'status'):
@@ -1704,8 +1705,8 @@ class _FeedURLHandler(urllib2.HTTPDigestAuthHandler, urllib2.HTTPRedirectHandler
return infourl
def http_error_301(self, req, fp, code, msg, headers):
- if headers.dict.has_key('location'):
- infourl = urllib2.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
+ if 'location' in headers.dict:
+ infourl = urllib.request.HTTPRedirectHandler.http_error_301(self, req, fp, code, msg, headers)
else:
infourl = urllib.addinfourl(fp, headers, req.get_full_url())
if not hasattr(infourl, 'status'):
@@ -1727,7 +1728,7 @@ class _FeedURLHandler(urllib2.HTTPDigestAuthHandler, urllib2.HTTPRedirectHandler
# header the server sent back (for the realm) and retry
# the request with the appropriate digest auth headers instead.
# This evil genius hack has been brought to you by Aaron Swartz.
- host = urlparse.urlparse(req.get_full_url())[1]
+ host = urllib.parse.urlparse(req.get_full_url())[1]
try:
assert sys.version.split()[0] >= '2.3.3'
assert base64 != None
@@ -1773,21 +1774,21 @@ def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, h
if url_file_stream_or_string == '-':
return sys.stdin
- if urlparse.urlparse(url_file_stream_or_string)[0] in ('http', 'https', 'ftp'):
+ if urllib.parse.urlparse(url_file_stream_or_string)[0] in ('http', 'https', 'ftp'):
if not agent:
agent = USER_AGENT
# test for inline user:password for basic auth
auth = None
if base64:
- urltype, rest = urllib.splittype(url_file_stream_or_string)
- realhost, rest = urllib.splithost(rest)
+ urltype, rest = urllib.parse.splittype(url_file_stream_or_string)
+ realhost, rest = urllib.parse.splithost(rest)
if realhost:
- user_passwd, realhost = urllib.splituser(realhost)
+ user_passwd, realhost = urllib.parse.splituser(realhost)
if user_passwd:
url_file_stream_or_string = '%s://%s%s' % (urltype, realhost, rest)
auth = base64.encodestring(user_passwd).strip()
# try to open with urllib2 (to use optional headers)
- request = urllib2.Request(url_file_stream_or_string)
+ request = urllib.request.Request(url_file_stream_or_string)
request.add_header('User-Agent', agent)
if etag:
request.add_header('If-None-Match', etag)
@@ -1814,7 +1815,7 @@ def _open_resource(url_file_stream_or_string, etag, modified, agent, referrer, h
if ACCEPT_HEADER:
request.add_header('Accept', ACCEPT_HEADER)
request.add_header('A-IM', 'feed') # RFC 3229 support
- opener = apply(urllib2.build_opener, tuple([_FeedURLHandler()] + handlers))
+ opener = urllib.request.build_opener(*tuple([_FeedURLHandler()] + handlers))
opener.addheaders = [] # RMK - must clear so we only send our custom User-Agent
try:
return opener.open(request)
@@ -1910,7 +1911,7 @@ def _parse_date_iso8601(dateString):
day = int(day)
# special case of the century - is the first year of the 21st century
# 2000 or 2001 ? The debate goes on...
- if 'century' in params.keys():
+ if 'century' in list(params.keys()):
year = (int(params['century']) - 1) * 100 + 1
# in ISO 8601 most fields are optional
for field in ['hour', 'minute', 'second', 'tzhour', 'tzmin']:
@@ -1946,17 +1947,17 @@ def _parse_date_iso8601(dateString):
registerDateHandler(_parse_date_iso8601)
# 8-bit date handling routines written by ytrewq1.
-_korean_year = u'\ub144' # b3e2 in euc-kr
-_korean_month = u'\uc6d4' # bff9 in euc-kr
-_korean_day = u'\uc77c' # c0cf in euc-kr
-_korean_am = u'\uc624\uc804' # bfc0 c0fc in euc-kr
-_korean_pm = u'\uc624\ud6c4' # bfc0 c8c4 in euc-kr
+_korean_year = '\ub144' # b3e2 in euc-kr
+_korean_month = '\uc6d4' # bff9 in euc-kr
+_korean_day = '\uc77c' # c0cf in euc-kr
+_korean_am = '\uc624\uc804' # bfc0 c0fc in euc-kr
+_korean_pm = '\uc624\ud6c4' # bfc0 c8c4 in euc-kr
_korean_onblog_date_re = \
re.compile('(\d{4})%s\s+(\d{2})%s\s+(\d{2})%s\s+(\d{2}):(\d{2}):(\d{2})' % \
(_korean_year, _korean_month, _korean_day))
_korean_nate_date_re = \
- re.compile(u'(\d{4})-(\d{2})-(\d{2})\s+(%s|%s)\s+(\d{,2}):(\d{,2}):(\d{,2})' % \
+ re.compile('(\d{4})-(\d{2})-(\d{2})\s+(%s|%s)\s+(\d{,2}):(\d{,2}):(\d{,2})' % \
(_korean_am, _korean_pm))
def _parse_date_onblog(dateString):
'''Parse a string according to the OnBlog 8-bit date format'''
@@ -2006,40 +2007,40 @@ registerDateHandler(_parse_date_mssql)
# Unicode strings for Greek date strings
_greek_months = \
{ \
- u'\u0399\u03b1\u03bd': u'Jan', # c9e1ed in iso-8859-7
- u'\u03a6\u03b5\u03b2': u'Feb', # d6e5e2 in iso-8859-7
- u'\u039c\u03ac\u03ce': u'Mar', # ccdcfe in iso-8859-7
- u'\u039c\u03b1\u03ce': u'Mar', # cce1fe in iso-8859-7
- u'\u0391\u03c0\u03c1': u'Apr', # c1f0f1 in iso-8859-7
- u'\u039c\u03ac\u03b9': u'May', # ccdce9 in iso-8859-7
- u'\u039c\u03b1\u03ca': u'May', # cce1fa in iso-8859-7
- u'\u039c\u03b1\u03b9': u'May', # cce1e9 in iso-8859-7
- u'\u0399\u03bf\u03cd\u03bd': u'Jun', # c9effded in iso-8859-7
- u'\u0399\u03bf\u03bd': u'Jun', # c9efed in iso-8859-7
- u'\u0399\u03bf\u03cd\u03bb': u'Jul', # c9effdeb in iso-8859-7
- u'\u0399\u03bf\u03bb': u'Jul', # c9f9eb in iso-8859-7
- u'\u0391\u03cd\u03b3': u'Aug', # c1fde3 in iso-8859-7
- u'\u0391\u03c5\u03b3': u'Aug', # c1f5e3 in iso-8859-7
- u'\u03a3\u03b5\u03c0': u'Sep', # d3e5f0 in iso-8859-7
- u'\u039f\u03ba\u03c4': u'Oct', # cfeaf4 in iso-8859-7
- u'\u039d\u03bf\u03ad': u'Nov', # cdefdd in iso-8859-7
- u'\u039d\u03bf\u03b5': u'Nov', # cdefe5 in iso-8859-7
- u'\u0394\u03b5\u03ba': u'Dec', # c4e5ea in iso-8859-7
+ '\u0399\u03b1\u03bd': 'Jan', # c9e1ed in iso-8859-7
+ '\u03a6\u03b5\u03b2': 'Feb', # d6e5e2 in iso-8859-7
+ '\u039c\u03ac\u03ce': 'Mar', # ccdcfe in iso-8859-7
+ '\u039c\u03b1\u03ce': 'Mar', # cce1fe in iso-8859-7
+ '\u0391\u03c0\u03c1': 'Apr', # c1f0f1 in iso-8859-7
+ '\u039c\u03ac\u03b9': 'May', # ccdce9 in iso-8859-7
+ '\u039c\u03b1\u03ca': 'May', # cce1fa in iso-8859-7
+ '\u039c\u03b1\u03b9': 'May', # cce1e9 in iso-8859-7
+ '\u0399\u03bf\u03cd\u03bd': 'Jun', # c9effded in iso-8859-7
+ '\u0399\u03bf\u03bd': 'Jun', # c9efed in iso-8859-7
+ '\u0399\u03bf\u03cd\u03bb': 'Jul', # c9effdeb in iso-8859-7
+ '\u0399\u03bf\u03bb': 'Jul', # c9f9eb in iso-8859-7
+ '\u0391\u03cd\u03b3': 'Aug', # c1fde3 in iso-8859-7
+ '\u0391\u03c5\u03b3': 'Aug', # c1f5e3 in iso-8859-7
+ '\u03a3\u03b5\u03c0': 'Sep', # d3e5f0 in iso-8859-7
+ '\u039f\u03ba\u03c4': 'Oct', # cfeaf4 in iso-8859-7
+ '\u039d\u03bf\u03ad': 'Nov', # cdefdd in iso-8859-7
+ '\u039d\u03bf\u03b5': 'Nov', # cdefe5 in iso-8859-7
+ '\u0394\u03b5\u03ba': 'Dec', # c4e5ea in iso-8859-7
}
_greek_wdays = \
{ \
- u'\u039a\u03c5\u03c1': u'Sun', # caf5f1 in iso-8859-7
- u'\u0394\u03b5\u03c5': u'Mon', # c4e5f5 in iso-8859-7
- u'\u03a4\u03c1\u03b9': u'Tue', # d4f1e9 in iso-8859-7
- u'\u03a4\u03b5\u03c4': u'Wed', # d4e5f4 in iso-8859-7
- u'\u03a0\u03b5\u03bc': u'Thu', # d0e5ec in iso-8859-7
- u'\u03a0\u03b1\u03c1': u'Fri', # d0e1f1 in iso-8859-7
- u'\u03a3\u03b1\u03b2': u'Sat', # d3e1e2 in iso-8859-7
+ '\u039a\u03c5\u03c1': 'Sun', # caf5f1 in iso-8859-7
+ '\u0394\u03b5\u03c5': 'Mon', # c4e5f5 in iso-8859-7
+ '\u03a4\u03c1\u03b9': 'Tue', # d4f1e9 in iso-8859-7
+ '\u03a4\u03b5\u03c4': 'Wed', # d4e5f4 in iso-8859-7
+ '\u03a0\u03b5\u03bc': 'Thu', # d0e5ec in iso-8859-7
+ '\u03a0\u03b1\u03c1': 'Fri', # d0e1f1 in iso-8859-7
+ '\u03a3\u03b1\u03b2': 'Sat', # d3e1e2 in iso-8859-7
}
_greek_date_format_re = \
- re.compile(u'([^,]+),\s+(\d{2})\s+([^\s]+)\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})\s+([^\s]+)')
+ re.compile('([^,]+),\s+(\d{2})\s+([^\s]+)\s+(\d{4})\s+(\d{2}):(\d{2}):(\d{2})\s+([^\s]+)')
def _parse_date_greek(dateString):
'''Parse a string according to a Greek 8-bit date format.'''
@@ -2061,22 +2062,22 @@ registerDateHandler(_parse_date_greek)
# Unicode strings for Hungarian date strings
_hungarian_months = \
{ \
- u'janu\u00e1r': u'01', # e1 in iso-8859-2
- u'febru\u00e1ri': u'02', # e1 in iso-8859-2
- u'm\u00e1rcius': u'03', # e1 in iso-8859-2
- u'\u00e1prilis': u'04', # e1 in iso-8859-2
- u'm\u00e1ujus': u'05', # e1 in iso-8859-2
- u'j\u00fanius': u'06', # fa in iso-8859-2
- u'j\u00falius': u'07', # fa in iso-8859-2
- u'augusztus': u'08',
- u'szeptember': u'09',
- u'okt\u00f3ber': u'10', # f3 in iso-8859-2
- u'november': u'11',
- u'december': u'12',
+ 'janu\u00e1r': '01', # e1 in iso-8859-2
+ 'febru\u00e1ri': '02', # e1 in iso-8859-2
+ 'm\u00e1rcius': '03', # e1 in iso-8859-2
+ '\u00e1prilis': '04', # e1 in iso-8859-2
+ 'm\u00e1ujus': '05', # e1 in iso-8859-2
+ 'j\u00fanius': '06', # fa in iso-8859-2
+ 'j\u00falius': '07', # fa in iso-8859-2
+ 'augusztus': '08',
+ 'szeptember': '09',
+ 'okt\u00f3ber': '10', # f3 in iso-8859-2
+ 'november': '11',
+ 'december': '12',
}
_hungarian_date_format_re = \
- re.compile(u'(\d{4})-([^-]+)-(\d{,2})T(\d{,2}):(\d{2})((\+|-)(\d{,2}:\d{2}))')
+ re.compile('(\d{4})-([^-]+)-(\d{,2})T(\d{,2}):(\d{2})((\+|-)(\d{,2}:\d{2}))')
def _parse_date_hungarian(dateString):
'''Parse a string according to a Hungarian 8-bit date format.'''
@@ -2232,7 +2233,7 @@ def _parse_date(dateString):
if len(date9tuple) != 9:
if _debug: sys.stderr.write('date handler function must return 9-tuple\n')
raise ValueError
- map(int, date9tuple)
+ list(map(int, date9tuple))
return date9tuple
except Exception as e:
if _debug: sys.stderr.write('%s raised %s\n' % (handler.__name__, repr(e)))
@@ -2313,39 +2314,39 @@ def _getCharacterEncoding(http_headers, xml_data):
elif xml_data[:4] == '\x00\x3c\x00\x3f':
# UTF-16BE
sniffed_xml_encoding = 'utf-16be'
- xml_data = unicode(xml_data, 'utf-16be').encode('utf-8')
+ xml_data = str(xml_data, 'utf-16be').encode('utf-8')
elif (len(xml_data) >= 4) and (xml_data[:2] == '\xfe\xff') and (xml_data[2:4] != '\x00\x00'):
# UTF-16BE with BOM
sniffed_xml_encoding = 'utf-16be'
- xml_data = unicode(xml_data[2:], 'utf-16be').encode('utf-8')
+ xml_data = str(xml_data[2:], 'utf-16be').encode('utf-8')
elif xml_data[:4] == '\x3c\x00\x3f\x00':
# UTF-16LE
sniffed_xml_encoding = 'utf-16le'
- xml_data = unicode(xml_data, 'utf-16le').encode('utf-8')
+ xml_data = str(xml_data, 'utf-16le').encode('utf-8')
elif (len(xml_data) >= 4) and (xml_data[:2] == '\xff\xfe') and (xml_data[2:4] != '\x00\x00'):
# UTF-16LE with BOM
sniffed_xml_encoding = 'utf-16le'
- xml_data = unicode(xml_data[2:], 'utf-16le').encode('utf-8')
+ xml_data = str(xml_data[2:], 'utf-16le').encode('utf-8')
elif xml_data[:4] == '\x00\x00\x00\x3c':
# UTF-32BE
sniffed_xml_encoding = 'utf-32be'
- xml_data = unicode(xml_data, 'utf-32be').encode('utf-8')
+ xml_data = str(xml_data, 'utf-32be').encode('utf-8')
elif xml_data[:4] == '\x3c\x00\x00\x00':
# UTF-32LE
sniffed_xml_encoding = 'utf-32le'
- xml_data = unicode(xml_data, 'utf-32le').encode('utf-8')
+ xml_data = str(xml_data, 'utf-32le').encode('utf-8')
elif xml_data[:4] == '\x00\x00\xfe\xff':
# UTF-32BE with BOM
sniffed_xml_encoding = 'utf-32be'
- xml_data = unicode(xml_data[4:], 'utf-32be').encode('utf-8')
+ xml_data = str(xml_data[4:], 'utf-32be').encode('utf-8')
elif xml_data[:4] == '\xff\xfe\x00\x00':
# UTF-32LE with BOM
sniffed_xml_encoding = 'utf-32le'
- xml_data = unicode(xml_data[4:], 'utf-32le').encode('utf-8')
+ xml_data = str(xml_data[4:], 'utf-32le').encode('utf-8')
elif xml_data[:3] == '\xef\xbb\xbf':
# UTF-8 with BOM
sniffed_xml_encoding = 'utf-8'
- xml_data = unicode(xml_data[3:], 'utf-8').encode('utf-8')
+ xml_data = str(xml_data[3:], 'utf-8').encode('utf-8')
else:
# ASCII-compatible
pass
@@ -2369,7 +2370,7 @@ def _getCharacterEncoding(http_headers, xml_data):
true_encoding = http_encoding or 'us-ascii'
elif http_content_type.startswith('text/'):
true_encoding = http_encoding or 'us-ascii'
- elif http_headers and (not http_headers.has_key('content-type')):
+ elif http_headers and ('content-type' not in http_headers):
true_encoding = xml_encoding or 'iso-8859-1'
else:
true_encoding = xml_encoding or 'utf-8'
@@ -2418,14 +2419,14 @@ def _toUTF8(data, encoding):
sys.stderr.write('trying utf-32le instead\n')
encoding = 'utf-32le'
data = data[4:]
- newdata = unicode(data, encoding)
+ newdata = str(data, encoding)
if _debug: sys.stderr.write('successfully converted %s data to unicode\n' % encoding)
declmatch = re.compile('^<\?xml[^>]*?>')
newdecl = ''''''
if declmatch.search(newdata):
newdata = declmatch.sub(newdecl, newdata)
else:
- newdata = newdecl + u'\n' + newdata
+ newdata = newdecl + '\n' + newdata
return newdata.encode('utf-8')
def _stripDoctype(data):
@@ -2511,7 +2512,7 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
result['encoding'], http_encoding, xml_encoding, sniffed_xml_encoding, acceptable_content_type = \
_getCharacterEncoding(http_headers, data)
if http_headers and (not acceptable_content_type):
- if http_headers.has_key('content-type'):
+ if 'content-type' in http_headers:
bozo_message = '%s is not an XML media type' % http_headers['content-type']
else:
bozo_message = 'no Content-type specified'
@@ -2629,18 +2630,18 @@ def parse(url_file_stream_or_string, etag=None, modified=None, agent=None, refer
if __name__ == '__main__':
if not sys.argv[1:]:
- print __doc__
+ print(__doc__)
sys.exit(0)
else:
urls = sys.argv[1:]
zopeCompatibilityHack()
from pprint import pprint
for url in urls:
- print url
- print
+ print(url)
+ print()
result = parse(url)
pprint(result)
- print
+ print()
#REVISION HISTORY
#1.0 - 9/27/2002 - MAP - fixed namespace processing on prefixed RSS 2.0 elements,
diff --git a/libs/pytwmn.py b/libs/pytwmn.py
index 49661fb..6b2d774 100644
--- a/libs/pytwmn.py
+++ b/libs/pytwmn.py
@@ -45,8 +45,8 @@ def init(host="127.0.0.1", port=None):
class Notification(object):
def __init__(self, title="", msg="", icon=""):
- self.title = unicode(title)
- self.msg = unicode(msg)
+ self.title = str(title)
+ self.msg = str(msg)
if icon.startswith("file://"):
icon = icon[7:]
self.icon = icon
diff --git a/logviewer.py b/logviewer.py
index 779781c..3c0b21e 100644
--- a/logviewer.py
+++ b/logviewer.py
@@ -3,19 +3,19 @@ import codecs
import re
import ostools
from time import strftime, strptime
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
from generic import RightClickList, RightClickTree
from parsetools import convertTags
from convo import PesterText
_datadir = ostools.getDataDir()
-class PesterLogSearchInput(QtGui.QLineEdit):
+class PesterLogSearchInput(QtWidgets.QLineEdit):
def __init__(self, theme, parent=None):
- QtGui.QLineEdit.__init__(self, parent)
+ QtWidgets.QLineEdit.__init__(self, parent)
self.setStyleSheet(theme["convo/input/style"] + "margin-right:0px;")
def keyPressEvent(self, event):
- QtGui.QLineEdit.keyPressEvent(self, event)
+ QtWidgets.QLineEdit.keyPressEvent(self, event)
if hasattr(self.parent(), 'textArea'):
if event.key() == QtCore.Qt.Key_Return:
self.parent().logSearch(self.text())
@@ -33,12 +33,12 @@ class PesterLogHighlighter(QtGui.QSyntaxHighlighter):
self.hilightstyle.setForeground(QtGui.QBrush(QtCore.Qt.black))
def highlightBlock(self, text):
for i in range(0, len(text)-(len(self.searchTerm)-1)):
- if unicode(text[i:i+len(self.searchTerm)]).lower() == unicode(self.searchTerm).lower():
+ if str(text[i:i+len(self.searchTerm)]).lower() == str(self.searchTerm).lower():
self.setFormat(i, len(self.searchTerm), self.hilightstyle)
-class PesterLogUserSelect(QtGui.QDialog):
+class PesterLogUserSelect(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.config = config
self.theme = theme
@@ -49,7 +49,7 @@ class PesterLogUserSelect(QtGui.QDialog):
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.setWindowTitle("Pesterlogs")
- instructions = QtGui.QLabel("Pick a memo or chumhandle:")
+ instructions = QtWidgets.QLabel("Pick a memo or chumhandle:")
if os.path.exists("%s/%s" % (self.logpath, self.handle)):
chumMemoList = os.listdir("%s/%s/" % (self.logpath, self.handle))
@@ -63,31 +63,28 @@ class PesterLogUserSelect(QtGui.QDialog):
self.chumsBox = RightClickList(self)
self.chumsBox.setStyleSheet(self.theme["main/chums/style"])
- self.chumsBox.optionsMenu = QtGui.QMenu(self)
+ self.chumsBox.optionsMenu = QtWidgets.QMenu(self)
for (i, t) in enumerate(chumMemoList):
- item = QtGui.QListWidgetItem(t)
+ item = QtWidgets.QListWidgetItem(t)
item.setTextColor(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
self.chumsBox.addItem(item)
self.search = PesterLogSearchInput(theme, self)
self.search.setFocus()
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- self.ok = QtGui.QPushButton("OK", self)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('viewActivatedLog()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.viewActivatedLog)
+ layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.ok)
- self.directory = QtGui.QPushButton("LOG DIRECTORY", self)
- self.connect(self.directory, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('openDir()'))
+ self.directory = QtWidgets.QPushButton("LOG DIRECTORY", self)
+ self.directory.clicked.connect(self.openDir)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(instructions)
layout_0.addWidget(self.chumsBox)
layout_0.addWidget(self.search)
@@ -111,8 +108,7 @@ class PesterLogUserSelect(QtGui.QDialog):
self.pesterlogviewer = None
if not self.pesterlogviewer:
self.pesterlogviewer = PesterLogViewer(selectedchum, self.config, self.theme, self.parent)
- self.connect(self.pesterlogviewer, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('closeActiveLog()'))
+ self.pesterlogviewer.rejected.connect(self.closeActiveLog)
self.pesterlogviewer.show()
self.pesterlogviewer.raise_()
self.pesterlogviewer.activateWindow()
@@ -127,9 +123,9 @@ class PesterLogUserSelect(QtGui.QDialog):
def openDir(self):
QtGui.QDesktopServices.openUrl(QtCore.QUrl("file:///" + os.path.join(_datadir, "logs"), QtCore.QUrl.TolerantMode))
-class PesterLogViewer(QtGui.QDialog):
+class PesterLogViewer(QtWidgets.QDialog):
def __init__(self, chum, config, theme, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.config = config
self.theme = theme
@@ -151,27 +147,26 @@ class PesterLogViewer(QtGui.QDialog):
self.logList = []
if not os.path.exists("%s/%s/%s/%s" % (self.logpath, self.handle, chum, self.format)) or len(self.logList) == 0:
- instructions = QtGui.QLabel("No Pesterlogs were found")
+ instructions = QtWidgets.QLabel("No Pesterlogs were found")
- self.ok = QtGui.QPushButton("CLOSE", self)
+ self.ok = QtWidgets.QPushButton("CLOSE", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.reject)
+ layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.ok)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(instructions)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
else:
- self.instructions = QtGui.QLabel("Pesterlog with " +self.chum+ " on")
+ self.instructions = QtWidgets.QLabel("Pesterlog with " +self.chum+ " on")
self.textArea = PesterLogText(theme, self.parent)
self.textArea.setReadOnly(True)
self.textArea.setFixedWidth(600)
- if theme.has_key("convo/scrollbar"):
+ if "convo/scrollbar" in theme:
self.textArea.setStyleSheet("QTextEdit { width:500px; %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }" % (theme["convo/textarea/style"], theme["convo/scrollbar/style"], theme["convo/scrollbar/handle"], theme["convo/scrollbar/downarrow"], theme["convo/scrollbar/uparrow"], theme["convo/scrollbar/uarrowstyle"], theme["convo/scrollbar/darrowstyle"] ))
else:
self.textArea.setStyleSheet("QTextEdit { width:500px; %s }" % (theme["convo/textarea/style"]))
@@ -180,15 +175,14 @@ class PesterLogViewer(QtGui.QDialog):
self.logList.reverse()
self.tree = RightClickTree()
- self.tree.optionsMenu = QtGui.QMenu(self)
+ self.tree.optionsMenu = QtWidgets.QMenu(self)
self.tree.setFixedSize(260, 300)
self.tree.header().hide()
- if theme.has_key("convo/scrollbar"):
+ if "convo/scrollbar" in theme:
self.tree.setStyleSheet("QTreeWidget { %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }" % (theme["convo/textarea/style"], theme["convo/scrollbar/style"], theme["convo/scrollbar/handle"], theme["convo/scrollbar/downarrow"], theme["convo/scrollbar/uparrow"], theme["convo/scrollbar/uarrowstyle"], theme["convo/scrollbar/darrowstyle"] ))
else:
self.tree.setStyleSheet("%s" % (theme["convo/textarea/style"]))
- self.connect(self.tree, QtCore.SIGNAL('itemSelectionChanged()'),
- self, QtCore.SLOT('loadSelectedLog()'))
+ self.tree.itemSelectionChanged.connect(self.loadSelectedLog)
self.tree.setSortingEnabled(False)
child_1 = None
@@ -196,11 +190,11 @@ class PesterLogViewer(QtGui.QDialog):
for (i,l) in enumerate(self.logList):
my = self.fileToMonthYear(l)
if my[0] != last[0]:
- child_1 = QtGui.QTreeWidgetItem(["%s %s" % (my[0], my[1])])
+ child_1 = QtWidgets.QTreeWidgetItem(["%s %s" % (my[0], my[1])])
self.tree.addTopLevelItem(child_1)
if i == 0:
child_1.setExpanded(True)
- child_1.addChild(QtGui.QTreeWidgetItem([self.fileToTime(l)]))
+ child_1.addChild(QtWidgets.QTreeWidgetItem([self.fileToTime(l)]))
last = self.fileToMonthYear(l)
self.hilight = PesterLogHighlighter(self.textArea)
@@ -208,38 +202,36 @@ class PesterLogViewer(QtGui.QDialog):
self.search = PesterLogSearchInput(theme, self)
self.search.setFocus()
- self.find = QtGui.QPushButton("Find", self)
+ self.find = QtWidgets.QPushButton("Find", self)
font = self.find.font()
font.setPointSize(8)
self.find.setFont(font)
self.find.setDefault(True)
self.find.setFixedSize(40, 20)
- layout_search = QtGui.QHBoxLayout()
+ layout_search = QtWidgets.QHBoxLayout()
layout_search.addWidget(self.search)
layout_search.addWidget(self.find)
- self.qdb = QtGui.QPushButton("Pesterchum QDB", self)
+ self.qdb = QtWidgets.QPushButton("Pesterchum QDB", self)
self.qdb.setFixedWidth(260)
- self.connect(self.qdb, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('openQDB()'))
- self.ok = QtGui.QPushButton("CLOSE", self)
+ self.qdb.clicked.connect(self.openQDB)
+ self.ok = QtWidgets.QPushButton("CLOSE", self)
self.ok.setFixedWidth(80)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.reject)
+ layout_ok = QtWidgets.QHBoxLayout()
# Website is offline so there's no point.
#layout_ok.addWidget(self.qdb)
layout_ok.addWidget(self.ok)
layout_ok.setAlignment(self.ok, QtCore.Qt.AlignRight)
- layout_logs = QtGui.QHBoxLayout()
+ layout_logs = QtWidgets.QHBoxLayout()
layout_logs.addWidget(self.tree)
- layout_right = QtGui.QVBoxLayout()
+ layout_right = QtWidgets.QVBoxLayout()
layout_right.addWidget(self.textArea)
layout_right.addLayout(layout_search)
layout_logs.addLayout(layout_right)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.instructions)
layout_0.addLayout(layout_logs)
layout_0.addLayout(layout_ok)
@@ -265,7 +257,7 @@ class PesterLogViewer(QtGui.QDialog):
textCur = self.textArea.textCursor()
textCur.movePosition(1)
self.textArea.setTextCursor(textCur)
- self.instructions.setText("Pesterlog with " +self.chum+ " on " + self.fileToTime(unicode(fname)))
+ self.instructions.setText("Pesterlog with " +self.chum+ " on " + self.fileToTime(str(fname)))
def logSearch(self, search):
self.hilight.searchTerm = search
@@ -285,20 +277,20 @@ class PesterLogText(PesterText):
PesterText.__init__(self, theme, parent)
def focusInEvent(self, event):
- QtGui.QTextEdit.focusInEvent(self, event)
+ QtWidgets.QTextEdit.focusInEvent(self, event)
def mousePressEvent(self, event):
url = self.anchorAt(event.pos())
if url != "":
if url[0] == "#" and url != "#pesterchum":
self.parent().parent.showMemos(url[1:])
elif url[0] == "@":
- handle = unicode(url[1:])
+ handle = str(url[1:])
self.parent().parent.newConversation(handle)
else:
QtGui.QDesktopServices.openUrl(QtCore.QUrl(url, QtCore.QUrl.TolerantMode))
- QtGui.QTextEdit.mousePressEvent(self, event)
+ QtWidgets.QTextEdit.mousePressEvent(self, event)
def mouseMoveEvent(self, event):
- QtGui.QTextEdit.mouseMoveEvent(self, event)
+ QtWidgets.QTextEdit.mouseMoveEvent(self, event)
if self.anchorAt(event.pos()):
if self.viewport().cursor().shape != QtCore.Qt.PointingHandCursor:
self.viewport().setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
diff --git a/luaquirks.py b/luaquirks.py
index b81e386..59319fc 100644
--- a/luaquirks.py
+++ b/luaquirks.py
@@ -4,7 +4,7 @@ try:
except ImportError:
lua = None
from quirks import ScriptQuirks
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
class LuaQuirks(ScriptQuirks):
def loadModule(self, name, filename):
@@ -18,7 +18,7 @@ class LuaQuirks(ScriptQuirks):
try:
return lua.require(name)
except Error as e:
- print e
+ print(e)
return None
finally:
os.chdir(CurrentDir)
@@ -48,11 +48,11 @@ class LuaQuirks(ScriptQuirks):
for name in module.commands:
CommandWrapper = Wrapper(module,name)
try:
- if not isinstance(CommandWrapper("test"), basestring):
+ if not isinstance(CommandWrapper("test"), str):
raise Exception
except:
- print "Quirk malformed: %s" % (name)
- msgbox = QtGui.QMessageBox()
+ print("Quirk malformed: %s" % (name))
+ msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Error!")
msgbox.setText("Quirk malformed: %s" % (name))
msgbox.exec_()
diff --git a/memos.py b/memos.py
index 88d704d..9b6e69d 100644
--- a/memos.py
+++ b/memos.py
@@ -1,7 +1,7 @@
from string import Template
import re
from copy import copy
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
from datetime import time, timedelta, datetime
from mood import Mood
@@ -13,6 +13,12 @@ from parsetools import convertTags, addTimeInitial, timeProtocol, \
import parsetools
from logviewer import PesterLogViewer
+try:
+ QString = unicode
+except NameError:
+ # Python 3
+ QString = str
+
def delta2txt(d, format="pc"):
if type(d) is mysteryTime:
return "?"
@@ -153,7 +159,7 @@ class TimeTracker(list):
except ValueError:
return None
def openTime(self, time):
- if self.open.has_key(time):
+ if time in self.open:
self.open[time] = True
def openCurrentTime(self):
timed = self.getTime()
@@ -179,21 +185,19 @@ class TimeTracker(list):
return TimeGrammar(temporal, pcf, when, 0)
return TimeGrammar(temporal, pcf, when, self.getRecord(timed))
-class TimeInput(QtGui.QLineEdit):
+class TimeInput(QtWidgets.QLineEdit):
def __init__(self, timeslider, parent):
super(TimeInput, self).__init__(parent)
self.timeslider = timeslider
self.setText("+0:00")
- self.connect(self.timeslider, QtCore.SIGNAL('valueChanged(int)'),
- self, QtCore.SLOT('setTime(int)'))
- self.connect(self, QtCore.SIGNAL('editingFinished()'),
- self, QtCore.SLOT('setSlider()'))
+ self.timeslider.valueChanged[int].connect(self.setTime)
+ self.editingFinished.connect(self.setSlider)
@QtCore.pyqtSlot(int)
def setTime(self, sliderval):
self.setText(self.timeslider.getTime())
@QtCore.pyqtSlot()
def setSlider(self):
- value = unicode(self.text())
+ value = str(self.text())
timed = txt2delta(value)
if type(timed) is mysteryTime:
self.timeslider.setValue(0)
@@ -210,7 +214,7 @@ class TimeInput(QtGui.QLineEdit):
text = delta2txt(timed)
self.setText(text)
-class TimeSlider(QtGui.QSlider):
+class TimeSlider(QtWidgets.QSlider):
def __init__(self, orientation, parent):
super(TimeSlider, self).__init__(orientation, parent)
self.setTracking(True)
@@ -258,22 +262,20 @@ class MemoText(PesterText):
self.setReadOnly(True)
self.setMouseTracking(True)
self.textSelected = False
- self.connect(self, QtCore.SIGNAL('copyAvailable(bool)'),
- self, QtCore.SLOT('textReady(bool)'))
+ self.copyAvailable[bool].connect(self.textReady)
self.urls = {}
for k in smiledict:
self.addAnimation(QtCore.QUrl("smilies/%s" % (smiledict[k])), "smilies/%s" % (smiledict[k]))
- self.connect(self.mainwindow, QtCore.SIGNAL('animationSetting(bool)'),
- self, QtCore.SLOT('animateChanged(bool)'))
+ self.mainwindow.animationSetting[bool].connect(self.animateChanged)
def initTheme(self, theme):
- if theme.has_key("memos/scrollbar"):
+ if "memos/scrollbar" in theme:
self.setStyleSheet("QTextEdit { %s } QScrollBar:vertical { %s } QScrollBar::handle:vertical { %s } QScrollBar::add-line:vertical { %s } QScrollBar::sub-line:vertical { %s } QScrollBar:up-arrow:vertical { %s } QScrollBar:down-arrow:vertical { %s }" % (theme["memos/textarea/style"], theme["memos/scrollbar/style"], theme["memos/scrollbar/handle"], theme["memos/scrollbar/downarrow"], theme["memos/scrollbar/uparrow"], theme["memos/scrollbar/uarrowstyle"], theme["memos/scrollbar/darrowstyle"] ))
else:
self.setStyleSheet("QTextEdit { %s }" % theme["memos/textarea/style"])
def addMessage(self, msg, chum):
- if type(msg) in [str, unicode]:
+ if type(msg) in [str, str]:
lexmsg = lexMessage(msg)
else:
lexmsg = msg
@@ -304,7 +306,7 @@ class MemoText(PesterText):
chum.color = color
systemColor = QtGui.QColor(window.theme["memos/systemMsgColor"])
if chum is not me:
- if parent.times.has_key(chum.handle):
+ if chum.handle in parent.times:
time = parent.times[chum.handle]
if time.getTime() is None:
# MY WAY OR THE HIGHWAY
@@ -352,81 +354,67 @@ class MemoInput(PesterInput):
class PesterMemo(PesterConvo):
# TODO: Clean up inheritance between these!! The inits are ugly.
def __init__(self, channel, timestr, mainwindow, parent=None):
- QtGui.QFrame.__init__(self, parent)
+ QtWidgets.QFrame.__init__(self, parent)
self.setAttribute(QtCore.Qt.WA_QuitOnClose, False)
self.channel = channel
self.setObjectName(self.channel)
self.mainwindow = mainwindow
self.time = TimeTracker(txt2delta(timestr))
self.setWindowTitle(channel)
- self.channelLabel = QtGui.QLabel(self)
- self.channelLabel.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding))
+ self.channelLabel = QtWidgets.QLabel(self)
+ self.channelLabel.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Expanding))
self.textArea = MemoText(self.mainwindow.theme, self)
self.textInput = MemoInput(self.mainwindow.theme, self)
self.textInput.setFocus()
- self.miniUserlist = QtGui.QPushButton(">\n>", self)
+ self.miniUserlist = QtWidgets.QPushButton(">\n>", self)
#self.miniUserlist.setStyleSheet("border:1px solid #a68168; border-width: 2px 0px 2px 2px; height: 90px; width: 10px; color: #cd8f9d; font-family: 'Arial'; background: white; margin-left: 2px;")
- self.connect(self.miniUserlist, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('toggleUserlist()'))
+ self.miniUserlist.clicked.connect(self.toggleUserlist)
self.userlist = RightClickList(self)
- self.userlist.setSizePolicy(QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Expanding))
- self.userlist.optionsMenu = QtGui.QMenu(self)
- self.pesterChumAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
- self.connect(self.pesterChumAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('newPesterSlot()'))
- self.addchumAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
- self.connect(self.addchumAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('addChumSlot()'))
- self.banuserAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/banuser"], self)
- self.connect(self.banuserAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('banSelectedUser()'))
- self.opAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/opuser"], self)
- self.connect(self.opAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('opSelectedUser()'))
- self.voiceAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/voiceuser"], self)
- self.connect(self.voiceAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('voiceSelectedUser()'))
- self.quirkDisableAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirkkill"], self)
- self.connect(self.quirkDisableAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('killQuirkUser()'))
+ self.userlist.setSizePolicy(QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding))
+ self.userlist.optionsMenu = QtWidgets.QMenu(self)
+ self.pesterChumAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
+ self.pesterChumAction.triggered.connect(self.newPesterSlot)
+ self.addchumAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
+ self.addchumAction.triggered.connect(self.addChumSlot)
+ self.banuserAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/banuser"], self)
+ self.banuserAction.triggered.connect(self.banSelectedUser)
+ self.opAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/opuser"], self)
+ self.opAction.triggered.connect(self.opSelectedUser)
+ self.voiceAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/voiceuser"], self)
+ self.voiceAction.triggered.connect(self.voiceSelectedUser)
+ self.quirkDisableAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirkkill"], self)
+ self.quirkDisableAction.triggered.connect(self.killQuirkUser)
self.userlist.optionsMenu.addAction(self.pesterChumAction)
self.userlist.optionsMenu.addAction(self.addchumAction)
# ban & op list added if we are op
- self.optionsMenu = QtGui.QMenu(self)
- self.oocToggle = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self)
+ self.optionsMenu = QtWidgets.QMenu(self)
+ self.oocToggle = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/ooc"], self)
self.oocToggle.setCheckable(True)
- self.connect(self.oocToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleOOC(bool)'))
- self.quirksOff = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self)
+ self.oocToggle.toggled[bool].connect(self.toggleOOC)
+ self.quirksOff = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"], self)
self.quirksOff.setCheckable(True)
- self.connect(self.quirksOff, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleQuirks(bool)'))
- self.logchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
- self.connect(self.logchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('openChumLogs()'))
- self.invitechum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self)
- self.connect(self.invitechum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('inviteChums()'))
+ self.quirksOff.toggled[bool].connect(self.toggleQuirks)
+ self.logchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
+ self.logchum.triggered.connect(self.openChumLogs)
+ self.invitechum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self)
+ self.invitechum.triggered.connect(self.inviteChums)
- self._beepToggle = QtGui.QAction("Beep on Message", self)
+ self._beepToggle = QtWidgets.QAction("Beep on Message", self)
self._beepToggle.setCheckable(True)
- self.connect(self._beepToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleBeep(bool)'))
+ self._beepToggle.toggled[bool].connect(self.toggleBeep)
- self._flashToggle = QtGui.QAction("Flash on Message", self)
+ self._flashToggle = QtWidgets.QAction("Flash on Message", self)
self._flashToggle.setCheckable(True)
- self.connect(self._flashToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleFlash(bool)'))
+ self._flashToggle.toggled[bool].connect(self.toggleFlash)
- self._muteToggle = QtGui.QAction("Mute Notifications", self)
+ self._muteToggle = QtWidgets.QAction("Mute Notifications", self)
self._muteToggle.setCheckable(True)
- self.connect(self._muteToggle, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleMute(bool)'))
+ self._muteToggle.toggled[bool].connect(self.toggleMute)
self.optionsMenu.addAction(self.quirksOff)
self.optionsMenu.addAction(self.oocToggle)
@@ -438,23 +426,19 @@ class PesterMemo(PesterConvo):
self.optionsMenu.addAction(self.logchum)
self.optionsMenu.addAction(self.invitechum)
- self.chanModeMenu = QtGui.QMenu(self.mainwindow.theme["main/menus/rclickchumlist/memosetting"], self)
- self.chanNoquirks = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memonoquirk"], self)
+ self.chanModeMenu = QtWidgets.QMenu(self.mainwindow.theme["main/menus/rclickchumlist/memosetting"], self)
+ self.chanNoquirks = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memonoquirk"], self)
self.chanNoquirks.setCheckable(True)
- self.connect(self.chanNoquirks, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('noquirksChan(bool)'))
- self.chanHide = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memohidden"], self)
+ self.chanNoquirks.toggled[bool].connect(self.noquirksChan)
+ self.chanHide = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memohidden"], self)
self.chanHide.setCheckable(True)
- self.connect(self.chanHide, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('hideChan(bool)'))
- self.chanInvite = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memoinvite"], self)
+ self.chanHide.toggled[bool].connect(self.hideChan)
+ self.chanInvite = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memoinvite"], self)
self.chanInvite.setCheckable(True)
- self.connect(self.chanInvite, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('inviteChan(bool)'))
- self.chanMod = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memomute"], self)
+ self.chanInvite.toggled[bool].connect(self.inviteChan)
+ self.chanMod = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/memomute"], self)
self.chanMod.setCheckable(True)
- self.connect(self.chanMod, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('modChan(bool)'))
+ self.chanMod.toggled[bool].connect(self.modChan)
self.chanModeMenu.addAction(self.chanNoquirks)
self.chanModeMenu.addAction(self.chanHide)
self.chanModeMenu.addAction(self.chanInvite)
@@ -464,33 +448,28 @@ class PesterMemo(PesterConvo):
self.timeinput = TimeInput(self.timeslider, self)
self.timeinput.setText(timestr)
self.timeinput.setSlider()
- self.timetravel = QtGui.QPushButton("GO", self)
- self.timeclose = QtGui.QPushButton("CLOSE", self)
- self.timeswitchl = QtGui.QPushButton(self)
- self.timeswitchr = QtGui.QPushButton(self)
+ self.timetravel = QtWidgets.QPushButton("GO", self)
+ self.timeclose = QtWidgets.QPushButton("CLOSE", self)
+ self.timeswitchl = QtWidgets.QPushButton(self)
+ self.timeswitchr = QtWidgets.QPushButton(self)
- self.connect(self.timetravel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('sendtime()'))
- self.connect(self.timeclose, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('smashclock()'))
- self.connect(self.timeswitchl, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('prevtime()'))
- self.connect(self.timeswitchr, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('nexttime()'))
+ self.timetravel.clicked.connect(self.sendtime)
+ self.timeclose.clicked.connect(self.smashclock)
+ self.timeswitchl.clicked.connect(self.prevtime)
+ self.timeswitchr.clicked.connect(self.nexttime)
self.times = {}
self.initTheme(self.mainwindow.theme)
# connect
- self.connect(self.textInput, QtCore.SIGNAL('returnPressed()'),
- self, QtCore.SLOT('sentMessage()'))
+ self.textInput.returnPressed.connect(self.sentMessage)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.textArea)
layout_0.addWidget(self.textInput)
- layout_1 = QtGui.QHBoxLayout()
+ layout_1 = QtWidgets.QHBoxLayout()
layout_1.addLayout(layout_0)
layout_1.addWidget(self.miniUserlist)
layout_1.addWidget(self.userlist)
@@ -498,14 +477,14 @@ class PesterMemo(PesterConvo):
# layout_1 = QtGui.QGridLayout()
# layout_1.addWidget(self.timeslider, 0, 1, QtCore.Qt.AlignHCenter)
# layout_1.addWidget(self.timeinput, 1, 0, 1, 3)
- layout_2 = QtGui.QHBoxLayout()
+ layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.timeslider)
layout_2.addWidget(self.timeinput)
layout_2.addWidget(self.timetravel)
layout_2.addWidget(self.timeclose)
layout_2.addWidget(self.timeswitchl)
layout_2.addWidget(self.timeswitchr)
- self.layout = QtGui.QVBoxLayout()
+ self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.channelLabel)
self.layout.addLayout(layout_1)
@@ -595,9 +574,9 @@ class PesterMemo(PesterConvo):
self.userlist.optionsMenu.setStyleSheet(theme["main/defaultwindow/style"])
scrolls = "width: 12px; height: 12px; border: 0; padding: 0;"
- if theme.has_key("main/chums/scrollbar"):
+ if "main/chums/scrollbar" in theme:
self.userlist.setStyleSheet("QListWidget { %s } QScrollBar { %s } QScrollBar::handle { %s } QScrollBar::add-line { %s } QScrollBar::sub-line { %s } QScrollBar:up-arrow { %s } QScrollBar:down-arrow { %s }" % (theme["memos/userlist/style"], theme["main/chums/scrollbar/style"] + scrolls, theme["main/chums/scrollbar/handle"], theme["main/chums/scrollbar/downarrow"], theme["main/chums/scrollbar/uparrow"], theme["main/chums/scrollbar/uarrowstyle"], theme["main/chums/scrollbar/darrowstyle"] ))
- elif theme.has_key("convo/scrollbar"):
+ elif "convo/scrollbar" in theme:
self.userlist.setStyleSheet("QListWidget { %s } QScrollBar { %s } QScrollBar::handle { %s } QScrollBar::add-line { %s } QScrollBar::sub-line { %s } QScrollBar:up-arrow { %s } QScrollBar:down-arrow { %s }" % (theme["memos/userlist/style"], theme["convo/scrollbar/style"] + scrolls, theme["convo/scrollbar/handle"], "display:none;", "display:none;", "display:none;", "display:none;" ))
else:
self.userlist.setStyleSheet("QListWidget { %s } QScrollBar { %s } QScrollBar::handle { %s }" % (theme["memos/userlist/style"], scrolls, "background-color: black;"))
@@ -684,7 +663,7 @@ class PesterMemo(PesterConvo):
elif handle[0] == '&':
admin = True
handle = handle[1:]
- item = QtGui.QListWidgetItem(handle)
+ item = QtWidgets.QListWidgetItem(handle)
if handle == self.mainwindow.profile().handle:
color = self.mainwindow.profile().color
else:
@@ -720,7 +699,7 @@ class PesterMemo(PesterConvo):
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
chum = self.mainwindow.profile()
opchum = PesterProfile(op)
- if self.times.has_key(op):
+ if op in self.times:
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
@@ -815,7 +794,7 @@ class PesterMemo(PesterConvo):
else:
timed = timeProtocol(cmd)
- if self.times.has_key(handle):
+ if handle in self.times:
if close is not None:
if close in self.times[handle]:
self.times[handle].setCurrent(close)
@@ -835,13 +814,13 @@ class PesterMemo(PesterConvo):
@QtCore.pyqtSlot()
def sentMessage(self):
- text = unicode(self.textInput.text())
+ text = str(self.textInput.text())
return parsetools.kxhandleInput(self, text, flavor="memos")
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def namesUpdated(self, channel):
- c = unicode(channel)
+ c = str(channel)
if c.lower() != self.channel.lower(): return
# get namesdb
namesdb = self.mainwindow.namesdb
@@ -849,28 +828,27 @@ class PesterMemo(PesterConvo):
self.userlist.clear()
for n in self.mainwindow.namesdb[self.channel]:
self.addUser(n)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def modesUpdated(self, channel, modes):
- c = unicode(channel)
+ c = str(channel)
if c.lower() == self.channel.lower():
self.updateChanModes(modes, None)
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def closeInviteOnly(self, channel):
- c = unicode(channel)
+ c = str(channel)
if c.lower() == self.channel.lower():
- self.disconnect(self.mainwindow, QtCore.SIGNAL('inviteOnlyChan(QString)'),
- self, QtCore.SLOT('closeInviteOnly(QString)'))
+ self.mainwindow.inviteOnlyChan['QString'].disconnect(self.closeInviteOnly)
if self.parent():
- print self.channel
+ print(self.channel)
i = self.parent().tabIndices[self.channel]
self.parent().tabClose(i)
else:
self.close()
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setText("%s: Invites only!" % (c))
msgbox.setInformativeText("This channel is invite-only. You must get an invitation from someone on the inside before entering.")
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
ret = msgbox.exec_()
def quirkDisable(self, op, msg):
@@ -883,7 +861,7 @@ class PesterMemo(PesterConvo):
systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"])
chum = self.mainwindow.profile()
opchum = PesterProfile(op)
- if self.times.has_key(op):
+ if op in self.times:
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
@@ -899,12 +877,12 @@ class PesterMemo(PesterConvo):
chum = self.mainwindow.profile()
ttracker = self.time
curtime = self.time.getTime()
- elif self.times.has_key(h):
+ elif h in self.times:
ttracker = self.times[h]
else:
ttracker = TimeTracker(timedelta(0))
opchum = PesterProfile(op)
- if self.times.has_key(op):
+ if op in self.times:
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
@@ -933,11 +911,11 @@ class PesterMemo(PesterConvo):
self.mainwindow.chatlog.log(self.channel, msg)
del self.netsplit
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString, QString)
def userPresentChange(self, handle, channel, update):
- h = unicode(handle)
- c = unicode(channel)
- update = unicode(update)
+ h = str(handle)
+ c = str(channel)
+ update = str(update)
if update[0:4] == "kick": # yeah, i'm lazy.
l = update.split(":")
update = l[0]
@@ -968,7 +946,7 @@ class PesterMemo(PesterConvo):
for c in chums:
chum = PesterProfile(h)
self.userlist.takeItem(self.userlist.row(c))
- if not self.times.has_key(h):
+ if h not in self.times:
self.times[h] = TimeTracker(timedelta(0))
allinitials = []
while self.times[h].getTime() is not None:
@@ -1002,13 +980,13 @@ class PesterMemo(PesterConvo):
chum = self.mainwindow.profile()
ttracker = self.time
curtime = self.time.getTime()
- elif self.times.has_key(h):
+ elif h in self.times:
ttracker = self.times[h]
else:
ttracker = TimeTracker(timedelta(0))
allinitials = []
opchum = PesterProfile(op)
- if self.times.has_key(op):
+ if op in self.times:
opgrammar = self.times[op].getGrammar()
elif op == self.mainwindow.profile().handle:
opgrammar = self.time.getGrammar()
@@ -1024,13 +1002,13 @@ class PesterMemo(PesterConvo):
if chum is self.mainwindow.profile():
# are you next?
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setText(self.mainwindow.theme["convo/text/kickedmemo"])
msgbox.setInformativeText("press 0k to rec0nnect or cancel to absc0nd")
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
# Find the OK button and make it default
for b in msgbox.buttons():
- if msgbox.buttonRole(b) == QtGui.QMessageBox.AcceptRole:
+ if msgbox.buttonRole(b) == QtWidgets.QMessageBox.AcceptRole:
# We found the 'OK' button, set it as the default
b.setDefault(True)
b.setAutoDefault(True)
@@ -1039,7 +1017,7 @@ class PesterMemo(PesterConvo):
b.setFocus()
break
ret = msgbox.exec_()
- if ret == QtGui.QMessageBox.Ok:
+ if ret == QtWidgets.QMessageBox.Ok:
self.userlist.clear()
self.time = TimeTracker(curtime)
self.resetSlider(curtime)
@@ -1049,7 +1027,7 @@ class PesterMemo(PesterConvo):
msg = me.memoopenmsg(systemColor, self.time.getTime(), self.time.getGrammar(), self.mainwindow.theme["convo/text/openmemo"], self.channel)
self.textArea.append(convertTags(msg))
self.mainwindow.chatlog.log(self.channel, msg)
- elif ret == QtGui.QMessageBox.Cancel:
+ elif ret == QtWidgets.QMessageBox.Cancel:
if self.parent():
i = self.parent().tabIndices[self.channel]
self.parent().tabClose(i)
@@ -1082,7 +1060,7 @@ class PesterMemo(PesterConvo):
for c in chums:
c.op = True
self.iconCrap(c)
- if unicode(c.text()) == self.mainwindow.profile().handle:
+ if str(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.addAction(self.opAction)
self.userlist.optionsMenu.addAction(self.voiceAction)
self.userlist.optionsMenu.addAction(self.banuserAction)
@@ -1099,7 +1077,7 @@ class PesterMemo(PesterConvo):
for c in chums:
c.op = False
self.iconCrap(c)
- if unicode(c.text()) == self.mainwindow.profile().handle:
+ if str(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.removeAction(self.opAction)
self.userlist.optionsMenu.removeAction(self.voiceAction)
self.userlist.optionsMenu.removeAction(self.banuserAction)
@@ -1115,7 +1093,7 @@ class PesterMemo(PesterConvo):
for c in chums:
c.halfop = True
self.iconCrap(c)
- if unicode(c.text()) == self.mainwindow.profile().handle:
+ if str(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.addAction(self.opAction)
self.userlist.optionsMenu.addAction(self.voiceAction)
self.userlist.optionsMenu.addAction(self.banuserAction)
@@ -1132,7 +1110,7 @@ class PesterMemo(PesterConvo):
for c in chums:
c.halfop = False
self.iconCrap(c)
- if unicode(c.text()) == self.mainwindow.profile().handle:
+ if str(c.text()) == self.mainwindow.profile().handle:
self.userlist.optionsMenu.removeAction(self.opAction)
self.userlist.optionsMenu.removeAction(self.voiceAction)
self.userlist.optionsMenu.removeAction(self.banuserAction)
@@ -1180,40 +1158,40 @@ class PesterMemo(PesterConvo):
user = self.userlist.currentItem()
if not user:
return
- user = unicode(user.text())
+ user = str(user.text())
self.mainwindow.newConversation(user)
@QtCore.pyqtSlot()
def addChumSlot(self):
if not self.userlist.currentItem():
return
- currentChum = PesterProfile(unicode(self.userlist.currentItem().text()))
+ currentChum = PesterProfile(str(self.userlist.currentItem().text()))
self.mainwindow.addChum(currentChum)
@QtCore.pyqtSlot()
def banSelectedUser(self):
if not self.userlist.currentItem():
return
- currentHandle = unicode(self.userlist.currentItem().text())
- (reason, ok) = QtGui.QInputDialog.getText(self, "Ban User", "Enter the reason you are banning this user (optional):")
+ currentHandle = str(self.userlist.currentItem().text())
+ (reason, ok) = QtWidgets.QInputDialog.getText(self, "Ban User", "Enter the reason you are banning this user (optional):")
if ok:
self.mainwindow.kickUser.emit("%s:%s" % (currentHandle, reason), self.channel)
@QtCore.pyqtSlot()
def opSelectedUser(self):
if not self.userlist.currentItem():
return
- currentHandle = unicode(self.userlist.currentItem().text())
+ currentHandle = str(self.userlist.currentItem().text())
self.mainwindow.setChannelMode.emit(self.channel, "+o", currentHandle)
@QtCore.pyqtSlot()
def voiceSelectedUser(self):
if not self.userlist.currentItem():
return
- currentHandle = unicode(self.userlist.currentItem().text())
+ currentHandle = str(self.userlist.currentItem().text())
self.mainwindow.setChannelMode.emit(self.channel, "+v", currentHandle)
@QtCore.pyqtSlot()
def killQuirkUser(self):
if not self.userlist.currentItem():
return
- currentHandle = unicode(self.userlist.currentItem().text())
+ currentHandle = str(self.userlist.currentItem().text())
self.mainwindow.killSomeQuirks.emit(self.channel, currentHandle)
def resetSlider(self, time, send=True):
@@ -1226,8 +1204,7 @@ class PesterMemo(PesterConvo):
def openChumLogs(self):
currentChum = self.channel
self.mainwindow.chumList.pesterlogviewer = PesterLogViewer(currentChum, self.mainwindow.config, self.mainwindow.theme, self.mainwindow)
- self.connect(self.mainwindow.chumList.pesterlogviewer, QtCore.SIGNAL('rejected()'),
- self.mainwindow.chumList, QtCore.SLOT('closeActiveLog()'))
+ self.mainwindow.chumList.pesterlogviewer.rejected.connect(self.mainwindow.chumList.closeActiveLog)
self.mainwindow.chumList.pesterlogviewer.show()
self.mainwindow.chumList.pesterlogviewer.raise_()
self.mainwindow.chumList.pesterlogviewer.activateWindow()
@@ -1237,9 +1214,9 @@ class PesterMemo(PesterConvo):
if not hasattr(self, 'invitechums'):
self.invitechums = None
if not self.invitechums:
- (chum, ok) = QtGui.QInputDialog.getText(self, "Invite to Chat", "Enter the chumhandle of the user you'd like to invite:")
+ (chum, ok) = QtWidgets.QInputDialog.getText(self, "Invite to Chat", "Enter the chumhandle of the user you'd like to invite:")
if ok:
- chum = unicode(chum)
+ chum = str(chum)
self.mainwindow.inviteChum.emit(chum, self.channel)
self.invitechums = None
@@ -1303,7 +1280,7 @@ class PesterMemo(PesterConvo):
self.mainwindow.waitingMessages.messageAnswered(self.channel)
self.windowClosed.emit(self.title())
- windowClosed = QtCore.pyqtSignal(QtCore.QString)
+ windowClosed = QtCore.pyqtSignal('QString')
timelist = ["0:00", "0:01", "0:02", "0:04", "0:06", "0:10", "0:14", "0:22", "0:30", "0:41", "1:00", "1:34", "2:16", "3:14", "4:13", "4:20", "5:25", "6:12", "7:30", "8:44", "10:25", "11:34", "14:13", "16:12", "17:44", "22:22", "25:10", "33:33", "42:00", "43:14", "50:00", "62:12", "75:00", "88:44", "100", "133", "143", "188", "200", "222", "250", "314", "333", "413", "420", "500", "600", "612", "888", "1000", "1025"]
diff --git a/menus.py b/menus.py
index b5fcd92..78250b7 100644
--- a/menus.py
+++ b/menus.py
@@ -1,4 +1,4 @@
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
import re, ostools
from os import remove
@@ -7,17 +7,23 @@ from dataobjs import pesterQuirk, PesterProfile
from memos import TimeSlider, TimeInput
from version import _pcVersion
+try:
+ QString = unicode
+except NameError:
+ # Python 3
+ QString = str
+
_datadir = ostools.getDataDir()
-class PesterQuirkItem(QtGui.QTreeWidgetItem):
+class PesterQuirkItem(QtWidgets.QTreeWidgetItem):
def __init__(self, quirk):
parent = None
- QtGui.QTreeWidgetItem.__init__(self, parent)
+ QtWidgets.QTreeWidgetItem.__init__(self, parent)
self.quirk = quirk
- self.setText(0, unicode(quirk))
+ self.setText(0, str(quirk))
def update(self, quirk):
self.quirk = quirk
- self.setText(0, unicode(quirk))
+ self.setText(0, str(quirk))
def __lt__(self, quirkitem):
"""Sets the order of quirks if auto-sorted by Qt. Obsolete now."""
if self.quirk.type == "prefix":
@@ -27,16 +33,15 @@ class PesterQuirkItem(QtGui.QTreeWidgetItem):
return True
else:
return False
-class PesterQuirkList(QtGui.QTreeWidget):
+class PesterQuirkList(QtWidgets.QTreeWidget):
def __init__(self, mainwindow, parent):
- QtGui.QTreeWidget.__init__(self, parent)
+ QtWidgets.QTreeWidget.__init__(self, parent)
self.resize(400, 200)
# make sure we have access to mainwindow info like profiles
self.mainwindow = mainwindow
self.setStyleSheet("background:black; color:white;")
- self.connect(self, QtCore.SIGNAL('itemChanged(QTreeWidgetItem *, int)'),
- self, QtCore.SLOT('changeCheckState()'))
+ self.itemChanged[QTreeWidgetItem, int].connect(self.changeCheckState)
for q in mainwindow.userprofile.quirks:
item = PesterQuirkItem(q)
@@ -64,10 +69,10 @@ class PesterQuirkList(QtGui.QTreeWidget):
if len(found) > 0:
found[0].addChild(item)
else:
- child_1 = QtGui.QTreeWidgetItem([item.quirk.group])
+ child_1 = QtWidgets.QTreeWidgetItem([item.quirk.group])
self.addTopLevelItem(child_1)
child_1.setFlags(child_1.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
- child_1.setChildIndicatorPolicy(QtGui.QTreeWidgetItem.DontShowIndicatorWhenChildless)
+ child_1.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.DontShowIndicatorWhenChildless)
child_1.setCheckState(0,0)
child_1.setExpanded(True)
child_1.addChild(item)
@@ -145,15 +150,15 @@ class PesterQuirkList(QtGui.QTreeWidget):
for f in found:
if not f.isSelected(): continue
if not f.parent(): # group
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
msgbox.setObjectName("delquirkwarning")
msgbox.setWindowTitle("WARNING!")
msgbox.setInformativeText("Are you sure you want to delete the quirk group: %s" % (f.text(0)))
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
# Find the Cancel button and make it default
for b in msgbox.buttons():
- if msgbox.buttonRole(b) == QtGui.QMessageBox.RejectRole:
+ if msgbox.buttonRole(b) == QtWidgets.QMessageBox.RejectRole:
# We found the 'OK' button, set it as the default
b.setDefault(True)
b.setAutoDefault(True)
@@ -162,7 +167,7 @@ class PesterQuirkList(QtGui.QTreeWidget):
b.setFocus()
break
ret = msgbox.exec_()
- if ret == QtGui.QMessageBox.Ok:
+ if ret == QtWidgets.QMessageBox.Ok:
self.takeTopLevelItem(self.indexOfTopLevelItem(f))
else:
f.parent().takeChild(f.parent().indexOfChild(f))
@@ -173,27 +178,27 @@ class PesterQuirkList(QtGui.QTreeWidget):
if not hasattr(self, 'addgroupdialog'):
self.addgroupdialog = None
if not self.addgroupdialog:
- (gname, ok) = QtGui.QInputDialog.getText(self, "Add Group", "Enter a name for the new quirk group:")
+ (gname, ok) = QtWidgets.QInputDialog.getText(self, "Add Group", "Enter a name for the new quirk group:")
if ok:
- gname = unicode(gname)
+ gname = str(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None:
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
ret = msgbox.exec_()
self.addgroupdialog = None
return
found = self.findItems(gname, QtCore.Qt.MatchExactly)
if found:
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS QUIRK GROUP ALREADY EXISTS")
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
ret = msgbox.exec_()
return
- child_1 = QtGui.QTreeWidgetItem([gname])
+ child_1 = QtWidgets.QTreeWidgetItem([gname])
self.addTopLevelItem(child_1)
child_1.setFlags(child_1.flags() | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
- child_1.setChildIndicatorPolicy(QtGui.QTreeWidgetItem.DontShowIndicatorWhenChildless)
+ child_1.setChildIndicatorPolicy(QtWidgets.QTreeWidgetItem.DontShowIndicatorWhenChildless)
child_1.setCheckState(0,0)
child_1.setExpanded(True)
@@ -224,9 +229,9 @@ from convo import PesterInput, PesterText
from parsetools import convertTags, lexMessage, splitMessage, mecmd, colorBegin, colorEnd, img2smiley, smiledict
import parsetools
from dataobjs import pesterQuirks, PesterHistory
-class QuirkTesterWindow(QtGui.QDialog):
+class QuirkTesterWindow(QtWidgets.QDialog):
def __init__(self, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.prnt = parent
self.mainwindow = parent.mainwindow
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
@@ -237,14 +242,13 @@ class QuirkTesterWindow(QtGui.QDialog):
self.textInput = PesterInput(self.mainwindow.theme, self)
self.textInput.setFocus()
- self.connect(self.textInput, QtCore.SIGNAL('returnPressed()'),
- self, QtCore.SLOT('sentMessage()'))
+ self.textInput.returnPressed.connect(self.sentMessage)
self.chumopen = True
self.chum = self.mainwindow.profile()
self.history = PesterHistory()
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.textArea)
layout_0.addWidget(self.textInput)
self.setLayout(layout_0)
@@ -256,12 +260,12 @@ class QuirkTesterWindow(QtGui.QDialog):
pass
@QtCore.pyqtSlot()
def sentMessage(self):
- text = unicode(self.textInput.text())
+ text = str(self.textInput.text())
return parsetools.kxhandleInput(self, text, "menus")
def addMessage(self, msg, me=True):
- if type(msg) in [str, unicode]:
+ if type(msg) in [str, str]:
lexmsg = lexMessage(msg)
else:
lexmsg = msg
@@ -274,174 +278,167 @@ class QuirkTesterWindow(QtGui.QDialog):
def closeEvent(self, event):
self.parent().quirktester = None
-class PesterQuirkTypes(QtGui.QDialog):
+class PesterQuirkTypes(QtWidgets.QDialog):
def __init__(self, parent, quirk=None):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.mainwindow = parent.mainwindow
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Quirk Wizard")
self.resize(500,310)
self.quirk = quirk
- self.pages = QtGui.QStackedWidget(self)
+ self.pages = QtWidgets.QStackedWidget(self)
- self.next = QtGui.QPushButton("Next", self)
+ self.next = QtWidgets.QPushButton("Next", self)
self.next.setDefault(True)
- self.connect(self.next, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('nextPage()'))
- self.back = QtGui.QPushButton("Back", self)
+ self.__next__.clicked.connect(self.nextPage)
+ self.back = QtWidgets.QPushButton("Back", self)
self.back.setEnabled(False)
- self.connect(self.back, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('backPage()'))
- self.cancel = QtGui.QPushButton("Cancel", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_2 = QtGui.QHBoxLayout()
+ self.back.clicked.connect(self.backPage)
+ self.cancel = QtWidgets.QPushButton("Cancel", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_2 = QtWidgets.QHBoxLayout()
layout_2.setAlignment(QtCore.Qt.AlignRight)
layout_2.addWidget(self.back)
- layout_2.addWidget(self.next)
+ layout_2.addWidget(self.__next__)
layout_2.addSpacing(5)
layout_2.addWidget(self.cancel)
- vr = QtGui.QFrame()
- vr.setFrameShape(QtGui.QFrame.VLine)
- vr.setFrameShadow(QtGui.QFrame.Sunken)
- vr2 = QtGui.QFrame()
- vr2.setFrameShape(QtGui.QFrame.VLine)
- vr2.setFrameShadow(QtGui.QFrame.Sunken)
+ vr = QtWidgets.QFrame()
+ vr.setFrameShape(QtWidgets.QFrame.VLine)
+ vr.setFrameShadow(QtWidgets.QFrame.Sunken)
+ vr2 = QtWidgets.QFrame()
+ vr2.setFrameShape(QtWidgets.QFrame.VLine)
+ vr2.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.funclist = QtGui.QListWidget(self)
+ self.funclist = QtWidgets.QListWidget(self)
self.funclist.setStyleSheet("color: #000000; background-color: #FFFFFF;")
- self.funclist2 = QtGui.QListWidget(self)
+ self.funclist2 = QtWidgets.QListWidget(self)
self.funclist2.setStyleSheet("color: #000000; background-color: #FFFFFF;")
from parsetools import quirkloader
- funcs = [q+"()" for q in quirkloader.quirks.keys()]
+ funcs = [q+"()" for q in list(quirkloader.quirks.keys())]
funcs.sort()
self.funclist.addItems(funcs)
self.funclist2.addItems(funcs)
- self.reloadQuirkFuncButton = QtGui.QPushButton("RELOAD FUNCTIONS", self)
- self.connect(self.reloadQuirkFuncButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reloadQuirkFuncSlot()'))
- self.reloadQuirkFuncButton2 = QtGui.QPushButton("RELOAD FUNCTIONS", self)
- self.connect(self.reloadQuirkFuncButton2, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reloadQuirkFuncSlot()'))
+ self.reloadQuirkFuncButton = QtWidgets.QPushButton("RELOAD FUNCTIONS", self)
+ self.reloadQuirkFuncButton.clicked.connect(self.reloadQuirkFuncSlot)
+ self.reloadQuirkFuncButton2 = QtWidgets.QPushButton("RELOAD FUNCTIONS", self)
+ self.reloadQuirkFuncButton2.clicked.connect(self.reloadQuirkFuncSlot)
self.funclist.setMaximumWidth(160)
self.funclist.resize(160,50)
self.funclist2.setMaximumWidth(160)
self.funclist2.resize(160,50)
- layout_f = QtGui.QVBoxLayout()
- layout_f.addWidget(QtGui.QLabel("Available Regexp\nFunctions"))
+ layout_f = QtWidgets.QVBoxLayout()
+ layout_f.addWidget(QtWidgets.QLabel("Available Regexp\nFunctions"))
layout_f.addWidget(self.funclist)
layout_f.addWidget(self.reloadQuirkFuncButton)
- layout_g = QtGui.QVBoxLayout()
- layout_g.addWidget(QtGui.QLabel("Available Regexp\nFunctions"))
+ layout_g = QtWidgets.QVBoxLayout()
+ layout_g.addWidget(QtWidgets.QLabel("Available Regexp\nFunctions"))
layout_g.addWidget(self.funclist2)
layout_g.addWidget(self.reloadQuirkFuncButton2)
# Pages
# Type select
- widget = QtGui.QWidget()
+ widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
- layout_select = QtGui.QVBoxLayout(widget)
+ layout_select = QtWidgets.QVBoxLayout(widget)
layout_select.setAlignment(QtCore.Qt.AlignTop)
self.radios = []
- self.radios.append(QtGui.QRadioButton("Prefix", self))
- self.radios.append(QtGui.QRadioButton("Suffix", self))
- self.radios.append(QtGui.QRadioButton("Simple Replace", self))
- self.radios.append(QtGui.QRadioButton("Regexp Replace", self))
- self.radios.append(QtGui.QRadioButton("Random Replace", self))
- self.radios.append(QtGui.QRadioButton("Mispeller", self))
+ self.radios.append(QtWidgets.QRadioButton("Prefix", self))
+ self.radios.append(QtWidgets.QRadioButton("Suffix", self))
+ self.radios.append(QtWidgets.QRadioButton("Simple Replace", self))
+ self.radios.append(QtWidgets.QRadioButton("Regexp Replace", self))
+ self.radios.append(QtWidgets.QRadioButton("Random Replace", self))
+ self.radios.append(QtWidgets.QRadioButton("Mispeller", self))
- layout_select.addWidget(QtGui.QLabel("Select Quirk Type:"))
+ layout_select.addWidget(QtWidgets.QLabel("Select Quirk Type:"))
for r in self.radios:
layout_select.addWidget(r)
# Prefix
- widget = QtGui.QWidget()
+ widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
- layout_prefix = QtGui.QVBoxLayout(widget)
+ layout_prefix = QtWidgets.QVBoxLayout(widget)
layout_prefix.setAlignment(QtCore.Qt.AlignTop)
- layout_prefix.addWidget(QtGui.QLabel("Prefix"))
- layout_3 = QtGui.QHBoxLayout()
- layout_3.addWidget(QtGui.QLabel("Value:"))
- layout_3.addWidget(QtGui.QLineEdit())
+ layout_prefix.addWidget(QtWidgets.QLabel("Prefix"))
+ layout_3 = QtWidgets.QHBoxLayout()
+ layout_3.addWidget(QtWidgets.QLabel("Value:"))
+ layout_3.addWidget(QtWidgets.QLineEdit())
layout_prefix.addLayout(layout_3)
# Suffix
- widget = QtGui.QWidget()
+ widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
- layout_suffix = QtGui.QVBoxLayout(widget)
+ layout_suffix = QtWidgets.QVBoxLayout(widget)
layout_suffix.setAlignment(QtCore.Qt.AlignTop)
- layout_suffix.addWidget(QtGui.QLabel("Suffix"))
- layout_3 = QtGui.QHBoxLayout()
- layout_3.addWidget(QtGui.QLabel("Value:"))
- layout_3.addWidget(QtGui.QLineEdit())
+ layout_suffix.addWidget(QtWidgets.QLabel("Suffix"))
+ layout_3 = QtWidgets.QHBoxLayout()
+ layout_3.addWidget(QtWidgets.QLabel("Value:"))
+ layout_3.addWidget(QtWidgets.QLineEdit())
layout_suffix.addLayout(layout_3)
# Simple Replace
- widget = QtGui.QWidget()
+ widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
- layout_replace = QtGui.QVBoxLayout(widget)
+ layout_replace = QtWidgets.QVBoxLayout(widget)
layout_replace.setAlignment(QtCore.Qt.AlignTop)
- layout_replace.addWidget(QtGui.QLabel("Simple Replace"))
- layout_3 = QtGui.QHBoxLayout()
- layout_3.addWidget(QtGui.QLabel("Replace:"))
- layout_3.addWidget(QtGui.QLineEdit())
+ layout_replace.addWidget(QtWidgets.QLabel("Simple Replace"))
+ layout_3 = QtWidgets.QHBoxLayout()
+ layout_3.addWidget(QtWidgets.QLabel("Replace:"))
+ layout_3.addWidget(QtWidgets.QLineEdit())
layout_replace.addLayout(layout_3)
- layout_3 = QtGui.QHBoxLayout()
- layout_3.addWidget(QtGui.QLabel("With:"))
- layout_3.addWidget(QtGui.QLineEdit())
+ layout_3 = QtWidgets.QHBoxLayout()
+ layout_3.addWidget(QtWidgets.QLabel("With:"))
+ layout_3.addWidget(QtWidgets.QLineEdit())
layout_replace.addLayout(layout_3)
# Regexp Replace
- widget = QtGui.QWidget()
+ widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
- layout_all = QtGui.QHBoxLayout(widget)
- layout_regexp = QtGui.QVBoxLayout()
+ layout_all = QtWidgets.QHBoxLayout(widget)
+ layout_regexp = QtWidgets.QVBoxLayout()
layout_regexp.setAlignment(QtCore.Qt.AlignTop)
- layout_regexp.addWidget(QtGui.QLabel("Regexp Replace"))
- layout_3 = QtGui.QHBoxLayout()
- layout_3.addWidget(QtGui.QLabel("Regexp:"))
- layout_3.addWidget(QtGui.QLineEdit())
+ layout_regexp.addWidget(QtWidgets.QLabel("Regexp Replace"))
+ layout_3 = QtWidgets.QHBoxLayout()
+ layout_3.addWidget(QtWidgets.QLabel("Regexp:"))
+ layout_3.addWidget(QtWidgets.QLineEdit())
layout_regexp.addLayout(layout_3)
- layout_3 = QtGui.QHBoxLayout()
- layout_3.addWidget(QtGui.QLabel("Replace With:"))
- layout_3.addWidget(QtGui.QLineEdit())
+ layout_3 = QtWidgets.QHBoxLayout()
+ layout_3.addWidget(QtWidgets.QLabel("Replace With:"))
+ layout_3.addWidget(QtWidgets.QLineEdit())
layout_regexp.addLayout(layout_3)
layout_all.addLayout(layout_f)
layout_all.addWidget(vr)
layout_all.addLayout(layout_regexp)
# Random Replace
- widget = QtGui.QWidget()
+ widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
- layout_all = QtGui.QHBoxLayout(widget)
- layout_random = QtGui.QVBoxLayout()
+ layout_all = QtWidgets.QHBoxLayout(widget)
+ layout_random = QtWidgets.QVBoxLayout()
layout_random.setAlignment(QtCore.Qt.AlignTop)
- layout_random.addWidget(QtGui.QLabel("Random Replace"))
- layout_5 = QtGui.QHBoxLayout()
- regexpl = QtGui.QLabel("Regexp:", self)
- self.regexp = QtGui.QLineEdit("", self)
+ layout_random.addWidget(QtWidgets.QLabel("Random Replace"))
+ layout_5 = QtWidgets.QHBoxLayout()
+ regexpl = QtWidgets.QLabel("Regexp:", self)
+ self.regexp = QtWidgets.QLineEdit("", self)
layout_5.addWidget(regexpl)
layout_5.addWidget(self.regexp)
- replacewithl = QtGui.QLabel("Replace With:", self)
+ replacewithl = QtWidgets.QLabel("Replace With:", self)
layout_all.addLayout(layout_g)
layout_all.addWidget(vr2)
layout_all.addLayout(layout_random)
- layout_6 = QtGui.QVBoxLayout()
- layout_7 = QtGui.QHBoxLayout()
- self.replacelist = QtGui.QListWidget(self)
- self.replaceinput = QtGui.QLineEdit(self)
- addbutton = QtGui.QPushButton("ADD", self)
- self.connect(addbutton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('addRandomString()'))
- removebutton = QtGui.QPushButton("REMOVE", self)
- self.connect(removebutton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('removeRandomString()'))
+ layout_6 = QtWidgets.QVBoxLayout()
+ layout_7 = QtWidgets.QHBoxLayout()
+ self.replacelist = QtWidgets.QListWidget(self)
+ self.replaceinput = QtWidgets.QLineEdit(self)
+ addbutton = QtWidgets.QPushButton("ADD", self)
+ addbutton.clicked.connect(self.addRandomString)
+ removebutton = QtWidgets.QPushButton("REMOVE", self)
+ removebutton.clicked.connect(self.removeRandomString)
layout_7.addWidget(addbutton)
layout_7.addWidget(removebutton)
layout_6.addLayout(layout_5)
@@ -452,29 +449,28 @@ class PesterQuirkTypes(QtGui.QDialog):
layout_random.addLayout(layout_6)
# Misspeller
- widget = QtGui.QWidget()
+ widget = QtWidgets.QWidget()
self.pages.addWidget(widget)
- layout_mispeller = QtGui.QVBoxLayout(widget)
+ layout_mispeller = QtWidgets.QVBoxLayout(widget)
layout_mispeller.setAlignment(QtCore.Qt.AlignTop)
- layout_mispeller.addWidget(QtGui.QLabel("Mispeller"))
- layout_1 = QtGui.QHBoxLayout()
- zero = QtGui.QLabel("1%", self)
- hund = QtGui.QLabel("100%", self)
- self.current = QtGui.QLabel("50%", self)
+ layout_mispeller.addWidget(QtWidgets.QLabel("Mispeller"))
+ layout_1 = QtWidgets.QHBoxLayout()
+ zero = QtWidgets.QLabel("1%", self)
+ hund = QtWidgets.QLabel("100%", self)
+ self.current = QtWidgets.QLabel("50%", self)
self.current.setAlignment(QtCore.Qt.AlignHCenter)
- self.slider = QtGui.QSlider(QtCore.Qt.Horizontal, self)
+ self.slider = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
self.slider.setMinimum(1)
self.slider.setMaximum(100)
self.slider.setValue(50)
- self.connect(self.slider, QtCore.SIGNAL('valueChanged(int)'),
- self, QtCore.SLOT('printValue(int)'))
+ self.slider.valueChanged[int].connect(self.printValue)
layout_1.addWidget(zero)
layout_1.addWidget(self.slider)
layout_1.addWidget(hund)
layout_mispeller.addLayout(layout_1)
layout_mispeller.addWidget(self.current)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.pages)
layout_0.addLayout(layout_2)
@@ -497,7 +493,7 @@ class PesterQuirkTypes(QtGui.QDialog):
elif q["type"] == "random":
self.regexp.setText(q["from"])
for v in q["randomlist"]:
- item = QtGui.QListWidgetItem(v, self.replacelist)
+ item = QtWidgets.QListWidgetItem(v, self.replacelist)
elif q["type"] == "spelling":
self.slider.setValue(q["percentage"])
@@ -538,8 +534,8 @@ class PesterQuirkTypes(QtGui.QDialog):
self.current.setText(str(value)+"%")
@QtCore.pyqtSlot()
def addRandomString(self):
- text = unicode(self.replaceinput.text())
- item = QtGui.QListWidgetItem(text, self.replacelist)
+ text = str(self.replaceinput.text())
+ item = QtWidgets.QListWidgetItem(text, self.replacelist)
self.replaceinput.setText("")
self.replaceinput.setFocus()
@QtCore.pyqtSlot()
@@ -554,16 +550,16 @@ class PesterQuirkTypes(QtGui.QDialog):
def reloadQuirkFuncSlot(self):
from parsetools import reloadQuirkFunctions, quirkloader
reloadQuirkFunctions()
- funcs = [q+"()" for q in quirkloader.quirks.keys()]
+ funcs = [q+"()" for q in list(quirkloader.quirks.keys())]
funcs.sort()
self.funclist.clear()
self.funclist.addItems(funcs)
self.funclist2.clear()
self.funclist2.addItems(funcs)
-class PesterChooseQuirks(QtGui.QDialog):
+class PesterChooseQuirks(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.config = config
self.theme = theme
@@ -573,61 +569,52 @@ class PesterChooseQuirks(QtGui.QDialog):
self.quirkList = PesterQuirkList(self.mainwindow, self)
- self.addQuirkButton = QtGui.QPushButton("ADD QUIRK", self)
- self.connect(self.addQuirkButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('addQuirkDialog()'))
+ self.addQuirkButton = QtWidgets.QPushButton("ADD QUIRK", self)
+ self.addQuirkButton.clicked.connect(self.addQuirkDialog)
- self.upShiftButton = QtGui.QPushButton("^", self)
- self.downShiftButton = QtGui.QPushButton("v", self)
+ self.upShiftButton = QtWidgets.QPushButton("^", self)
+ self.downShiftButton = QtWidgets.QPushButton("v", self)
self.upShiftButton.setToolTip("Move quirk up one")
self.downShiftButton.setToolTip("Move quirk down one")
- self.connect(self.upShiftButton, QtCore.SIGNAL('clicked()'),
- self.quirkList, QtCore.SLOT('upShiftQuirk()'))
- self.connect(self.downShiftButton, QtCore.SIGNAL('clicked()'),
- self.quirkList, QtCore.SLOT('downShiftQuirk()'))
+ self.upShiftButton.clicked.connect(self.quirkList.upShiftQuirk)
+ self.downShiftButton.clicked.connect(self.quirkList.downShiftQuirk)
- self.newGroupButton = QtGui.QPushButton("*", self)
+ self.newGroupButton = QtWidgets.QPushButton("*", self)
self.newGroupButton.setToolTip("New Quirk Group")
- self.connect(self.newGroupButton, QtCore.SIGNAL('clicked()'),
- self.quirkList, QtCore.SLOT('addQuirkGroup()'))
+ self.newGroupButton.clicked.connect(self.quirkList.addQuirkGroup)
- layout_quirklist = QtGui.QHBoxLayout() #the nude layout quirklist
- layout_shiftbuttons = QtGui.QVBoxLayout() #the shift button layout
+ layout_quirklist = QtWidgets.QHBoxLayout() #the nude layout quirklist
+ layout_shiftbuttons = QtWidgets.QVBoxLayout() #the shift button layout
layout_shiftbuttons.addWidget(self.upShiftButton)
layout_shiftbuttons.addWidget(self.newGroupButton)
layout_shiftbuttons.addWidget(self.downShiftButton)
layout_quirklist.addWidget(self.quirkList)
layout_quirklist.addLayout(layout_shiftbuttons)
- layout_1 = QtGui.QHBoxLayout()
+ layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.addQuirkButton)
- self.editSelectedButton = QtGui.QPushButton("EDIT", self)
- self.connect(self.editSelectedButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('editSelected()'))
- self.removeSelectedButton = QtGui.QPushButton("REMOVE", self)
- self.connect(self.removeSelectedButton, QtCore.SIGNAL('clicked()'),
- self.quirkList, QtCore.SLOT('removeCurrent()'))
- layout_3 = QtGui.QHBoxLayout()
+ self.editSelectedButton = QtWidgets.QPushButton("EDIT", self)
+ self.editSelectedButton.clicked.connect(self.editSelected)
+ self.removeSelectedButton = QtWidgets.QPushButton("REMOVE", self)
+ self.removeSelectedButton.clicked.connect(self.quirkList.removeCurrent)
+ layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(self.editSelectedButton)
layout_3.addWidget(self.removeSelectedButton)
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
- self.test = QtGui.QPushButton("TEST QUIRKS", self)
- self.connect(self.test, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('testQuirks()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.accept)
+ self.test = QtWidgets.QPushButton("TEST QUIRKS", self)
+ self.test.clicked.connect(self.testQuirks)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.test)
layout_ok.addWidget(self.ok)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addLayout(layout_quirklist)
layout_0.addLayout(layout_1)
#layout_0.addLayout(layout_2)
@@ -675,10 +662,8 @@ class PesterChooseQuirks(QtGui.QDialog):
if self.quirkadd:
return
self.quirkadd = PesterQuirkTypes(self, quirk)
- self.connect(self.quirkadd, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('addQuirk()'))
- self.connect(self.quirkadd, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('closeQuirk()'))
+ self.quirkadd.accepted.connect(self.addQuirk)
+ self.quirkadd.rejected.connect(self.closeQuirk)
self.quirkadd.show()
@QtCore.pyqtSlot()
def addQuirk(self):
@@ -687,16 +672,16 @@ class PesterChooseQuirks(QtGui.QDialog):
vdict["type"] = types[self.quirkadd.pages.currentIndex()-1]
page = self.quirkadd.pages.currentWidget().layout()
if vdict["type"] in ("prefix","suffix"):
- vdict["value"] = unicode(page.itemAt(1).layout().itemAt(1).widget().text())
+ vdict["value"] = str(page.itemAt(1).layout().itemAt(1).widget().text())
elif vdict["type"] == "replace":
- vdict["from"] = unicode(page.itemAt(1).layout().itemAt(1).widget().text())
- vdict["to"] = unicode(page.itemAt(2).layout().itemAt(1).widget().text())
+ vdict["from"] = str(page.itemAt(1).layout().itemAt(1).widget().text())
+ vdict["to"] = str(page.itemAt(2).layout().itemAt(1).widget().text())
elif vdict["type"] == "regexp":
- vdict["from"] = unicode(page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().text())
- vdict["to"] = unicode(page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().text())
+ vdict["from"] = str(page.itemAt(2).layout().itemAt(1).layout().itemAt(1).widget().text())
+ vdict["to"] = str(page.itemAt(2).layout().itemAt(2).layout().itemAt(1).widget().text())
elif vdict["type"] == "random":
- vdict["from"] = unicode(self.quirkadd.regexp.text())
- randomlist = [unicode(self.quirkadd.replacelist.item(i).text())
+ vdict["from"] = str(self.quirkadd.regexp.text())
+ randomlist = [str(self.quirkadd.replacelist.item(i).text())
for i in range(0,self.quirkadd.replacelist.count())]
vdict["randomlist"] = randomlist
elif vdict["type"] == "spelling":
@@ -705,8 +690,8 @@ class PesterChooseQuirks(QtGui.QDialog):
if vdict["type"] in ("regexp", "random"):
try:
re.compile(vdict["from"])
- except re.error, e:
- quirkWarning = QtGui.QMessageBox(self)
+ except re.error as e:
+ quirkWarning = QtWidgets.QMessageBox(self)
quirkWarning.setText("Not a valid regular expression!")
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
quirkWarning.exec_()
@@ -724,69 +709,64 @@ class PesterChooseQuirks(QtGui.QDialog):
def closeQuirk(self):
self.quirkadd = None
-class PesterChooseTheme(QtGui.QDialog):
+class PesterChooseTheme(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.config = config
self.theme = theme
self.parent = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.setWindowTitle("Pick a theme")
- instructions = QtGui.QLabel("Pick a theme:")
+ instructions = QtWidgets.QLabel("Pick a theme:")
avail_themes = config.availableThemes()
- self.themeBox = QtGui.QComboBox(self)
+ self.themeBox = QtWidgets.QComboBox(self)
for (i, t) in enumerate(avail_themes):
self.themeBox.addItem(t)
if t == theme.name:
self.themeBox.setCurrentIndex(i)
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.accept)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.ok)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(instructions)
layout_0.addWidget(self.themeBox)
layout_0.addLayout(layout_ok)
self.setLayout(layout_0)
- self.connect(self, QtCore.SIGNAL('accepted()'),
- parent, QtCore.SLOT('themeSelected()'))
- self.connect(self, QtCore.SIGNAL('rejected()'),
- parent, QtCore.SLOT('closeTheme()'))
+ self.accepted.connect(parent.themeSelected)
+ self.rejected.connect(parent.closeTheme)
-class PesterChooseProfile(QtGui.QDialog):
+class PesterChooseProfile(QtWidgets.QDialog):
def __init__(self, userprofile, config, theme, parent, collision=None):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.userprofile = userprofile
self.theme = theme
self.config = config
self.parent = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
- self.currentHandle = QtGui.QLabel("CHANGING FROM %s" % userprofile.chat.handle)
- self.chumHandle = QtGui.QLineEdit(self)
+ self.currentHandle = QtWidgets.QLabel("CHANGING FROM %s" % userprofile.chat.handle)
+ self.chumHandle = QtWidgets.QLineEdit(self)
self.chumHandle.setMinimumWidth(200)
self.chumHandle.setObjectName("setprofilehandle")
- self.chumHandleLabel = QtGui.QLabel(self.theme["main/mychumhandle/label/text"], self)
- self.chumColorButton = QtGui.QPushButton(self)
+ self.chumHandleLabel = QtWidgets.QLabel(self.theme["main/mychumhandle/label/text"], self)
+ self.chumColorButton = QtWidgets.QPushButton(self)
self.chumColorButton.setObjectName("setprofilecolor")
self.chumColorButton.resize(50, 20)
self.chumColorButton.setStyleSheet("background: %s" % (userprofile.chat.colorhtml()))
self.chumcolor = userprofile.chat.color
- self.connect(self.chumColorButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('openColorDialog()'))
- layout_1 = QtGui.QHBoxLayout()
+ self.chumColorButton.clicked.connect(self.openColorDialog)
+ layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.chumHandleLabel)
layout_1.addWidget(self.chumHandle)
layout_1.addWidget(self.chumColorButton)
@@ -794,63 +774,58 @@ class PesterChooseProfile(QtGui.QDialog):
# available profiles?
avail_profiles = self.config.availableProfiles()
if avail_profiles:
- self.profileBox = QtGui.QComboBox(self)
+ self.profileBox = QtWidgets.QComboBox(self)
self.profileBox.addItem("Choose a profile...")
for p in avail_profiles:
self.profileBox.addItem(p.chat.handle)
else:
self.profileBox = None
- self.defaultcheck = QtGui.QCheckBox(self)
- self.defaultlabel = QtGui.QLabel("Set This Profile As Default", self)
- layout_2 = QtGui.QHBoxLayout()
+ self.defaultcheck = QtWidgets.QCheckBox(self)
+ self.defaultlabel = QtWidgets.QLabel("Set This Profile As Default", self)
+ layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.defaultlabel)
layout_2.addWidget(self.defaultcheck)
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('validateProfile()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
+ self.ok.clicked.connect(self.validateProfile)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
if not collision and avail_profiles:
- self.delete = QtGui.QPushButton("DELETE", self)
- self.connect(self.delete, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('deleteProfile()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.delete = QtWidgets.QPushButton("DELETE", self)
+ self.delete.clicked.connect(self.deleteProfile)
+ layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.ok)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
if collision:
- collision_warning = QtGui.QLabel("%s is taken already! Pick a new profile." % (collision))
+ collision_warning = QtWidgets.QLabel("%s is taken already! Pick a new profile." % (collision))
layout_0.addWidget(collision_warning)
else:
layout_0.addWidget(self.currentHandle, alignment=QtCore.Qt.AlignHCenter)
layout_0.addLayout(layout_1)
if avail_profiles:
- profileLabel = QtGui.QLabel("Or choose an existing profile:", self)
+ profileLabel = QtWidgets.QLabel("Or choose an existing profile:", self)
layout_0.addWidget(profileLabel)
layout_0.addWidget(self.profileBox)
layout_0.addLayout(layout_ok)
if not collision and avail_profiles:
layout_0.addWidget(self.delete)
layout_0.addLayout(layout_2)
- self.errorMsg = QtGui.QLabel(self)
+ self.errorMsg = QtWidgets.QLabel(self)
self.errorMsg.setObjectName("errormsg")
self.errorMsg.setStyleSheet("color:red;")
layout_0.addWidget(self.errorMsg)
self.setLayout(layout_0)
- self.connect(self, QtCore.SIGNAL('accepted()'),
- parent, QtCore.SLOT('profileSelected()'))
- self.connect(self, QtCore.SIGNAL('rejected()'),
- parent, QtCore.SLOT('closeProfile()'))
+ self.accepted.connect(parent.profileSelected)
+ self.rejected.connect(parent.closeProfile)
@QtCore.pyqtSlot()
def openColorDialog(self):
- self.colorDialog = QtGui.QColorDialog(self)
+ self.colorDialog = QtWidgets.QColorDialog(self)
color = self.colorDialog.getColor(initial=self.userprofile.chat.color)
self.chumColorButton.setStyleSheet("background: %s" % color.name())
self.chumcolor = color
@@ -859,7 +834,7 @@ class PesterChooseProfile(QtGui.QDialog):
@QtCore.pyqtSlot()
def validateProfile(self):
if not self.profileBox or self.profileBox.currentIndex() == 0:
- handle = unicode(self.chumHandle.text())
+ handle = str(self.chumHandle.text())
if not PesterProfile.checkLength(handle):
self.errorMsg.setText("PROFILE HANDLE IS TOO LONG")
return
@@ -871,74 +846,69 @@ class PesterChooseProfile(QtGui.QDialog):
@QtCore.pyqtSlot()
def deleteProfile(self):
if self.profileBox and self.profileBox.currentIndex() > 0:
- handle = unicode(self.profileBox.currentText())
+ handle = str(self.profileBox.currentText())
if handle == self.parent.profile().handle:
- problem = QtGui.QMessageBox()
+ problem = QtWidgets.QMessageBox()
# karxi Will probably change this to its own name later.
problem.setObjectName("errmsg")
problem.setStyleSheet(self.theme["main/defaultwindow/style"])
problem.setWindowTitle("Problem!")
problem.setInformativeText("You can't delete the profile you're currently using!")
- problem.setStandardButtons(QtGui.QMessageBox.Ok)
+ problem.setStandardButtons(QtWidgets.QMessageBox.Ok)
problem.exec_()
return
# TODO: Make this select 'no' as the default, as usual.
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setStyleSheet(self.theme["main/defaultwindow/style"])
msgbox.setWindowTitle("WARNING!")
msgbox.setInformativeText("Are you sure you want to delete the profile: %s" % (handle))
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
ret = msgbox.exec_()
- if ret == QtGui.QMessageBox.Ok:
+ if ret == QtWidgets.QMessageBox.Ok:
try:
remove(_datadir+"profiles/%s.js" % (handle))
except OSError:
- problem = QtGui.QMessageBox()
+ problem = QtWidgets.QMessageBox()
problem.setObjectName("errmsg")
problem.setStyleSheet(self.theme["main/defaultwindow/style"])
problem.setWindowTitle("Problem!")
problem.setInformativeText("There was a problem deleting the profile: %s" % (handle))
- problem.setStandardButtons(QtGui.QMessageBox.Ok)
+ problem.setStandardButtons(QtWidgets.QMessageBox.Ok)
problem.exec_()
-class PesterMentions(QtGui.QDialog):
+class PesterMentions(QtWidgets.QDialog):
def __init__(self, window, theme, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.setWindowTitle("Mentions")
self.setModal(True)
self.mainwindow = window
self.theme = theme
self.setStyleSheet(self.theme["main/defaultwindow/style"])
- self.mentionlist = QtGui.QListWidget(self)
+ self.mentionlist = QtWidgets.QListWidget(self)
self.mentionlist.addItems(self.mainwindow.userprofile.getMentions())
- self.addBtn = QtGui.QPushButton("ADD MENTION", self)
- self.connect(self.addBtn, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('addMention()'))
+ self.addBtn = QtWidgets.QPushButton("ADD MENTION", self)
+ self.addBtn.clicked.connect(self.addMention)
- self.editBtn = QtGui.QPushButton("EDIT", self)
- self.connect(self.editBtn, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('editSelected()'))
- self.rmBtn = QtGui.QPushButton("REMOVE", self)
- self.connect(self.rmBtn, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('removeCurrent()'))
- layout_1 = QtGui.QHBoxLayout()
+ self.editBtn = QtWidgets.QPushButton("EDIT", self)
+ self.editBtn.clicked.connect(self.editSelected)
+ self.rmBtn = QtWidgets.QPushButton("REMOVE", self)
+ self.rmBtn.clicked.connect(self.removeCurrent)
+ layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.editBtn)
layout_1.addWidget(self.rmBtn)
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_2 = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.accept)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.mentionlist)
layout_0.addWidget(self.addBtn)
layout_0.addLayout(layout_1)
@@ -963,8 +933,8 @@ class PesterMentions(QtGui.QDialog):
return
try:
re.compile(pdict["value"])
- except re.error, e:
- quirkWarning = QtGui.QMessageBox(self)
+ except re.error as e:
+ quirkWarning = QtWidgets.QMessageBox(self)
quirkWarning.setText("Not a valid regular expression!")
quirkWarning.setInformativeText("H3R3S WHY DUMP4SS: %s" % (e))
quirkWarning.exec_()
@@ -980,86 +950,80 @@ class PesterMentions(QtGui.QDialog):
if i >= 0:
self.mentionlist.takeItem(i)
-class PesterOptions(QtGui.QDialog):
+class PesterOptions(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.setWindowTitle("Options")
self.setModal(False)
self.config = config
self.theme = theme
self.setStyleSheet(self.theme["main/defaultwindow/style"])
- layout_4 = QtGui.QVBoxLayout()
+ layout_4 = QtWidgets.QVBoxLayout()
- hr = QtGui.QFrame()
- hr.setFrameShape(QtGui.QFrame.HLine)
- hr.setFrameShadow(QtGui.QFrame.Sunken)
- vr = QtGui.QFrame()
- vr.setFrameShape(QtGui.QFrame.VLine)
- vr.setFrameShadow(QtGui.QFrame.Sunken)
+ hr = QtWidgets.QFrame()
+ hr.setFrameShape(QtWidgets.QFrame.HLine)
+ hr.setFrameShadow(QtWidgets.QFrame.Sunken)
+ vr = QtWidgets.QFrame()
+ vr.setFrameShape(QtWidgets.QFrame.VLine)
+ vr.setFrameShadow(QtWidgets.QFrame.Sunken)
- self.tabs = QtGui.QButtonGroup(self)
- self.connect(self.tabs, QtCore.SIGNAL('buttonClicked(int)'),
- self, QtCore.SLOT('changePage(int)'))
+ self.tabs = QtWidgets.QButtonGroup(self)
+ self.tabs.buttonClicked[int].connect(self.changePage)
tabNames = ["Chum List", "Conversations", "Interface", "Sound", "Notifications", "Logging", "Idle/Updates", "Theme", "Connection"]
if parent.advanced: tabNames.append("Advanced")
for t in tabNames:
- button = QtGui.QPushButton(t)
+ button = QtWidgets.QPushButton(t)
self.tabs.addButton(button)
layout_4.addWidget(button)
button.setCheckable(True)
self.tabs.button(-2).setChecked(True)
- self.pages = QtGui.QStackedWidget(self)
+ self.pages = QtWidgets.QStackedWidget(self)
- self.bandwidthcheck = QtGui.QCheckBox("Low Bandwidth", self)
+ self.bandwidthcheck = QtWidgets.QCheckBox("Low Bandwidth", self)
if self.config.lowBandwidth():
self.bandwidthcheck.setChecked(True)
- bandwidthLabel = QtGui.QLabel("(Stops you for receiving the flood of MOODS,\n"
+ bandwidthLabel = QtWidgets.QLabel("(Stops you for receiving the flood of MOODS,\n"
" though stops chumlist from working properly)")
font = bandwidthLabel.font()
font.setPointSize(8)
bandwidthLabel.setFont(font)
- self.autonickserv = QtGui.QCheckBox("Auto-Identify with NickServ", self)
+ self.autonickserv = QtWidgets.QCheckBox("Auto-Identify with NickServ", self)
self.autonickserv.setChecked(parent.userprofile.getAutoIdentify())
- self.connect(self.autonickserv, QtCore.SIGNAL('stateChanged(int)'),
- self, QtCore.SLOT('autoNickServChange(int)'))
- self.nickservpass = QtGui.QLineEdit(self)
+ self.autonickserv.stateChanged[int].connect(self.autoNickServChange)
+ self.nickservpass = QtWidgets.QLineEdit(self)
self.nickservpass.setPlaceholderText("NickServ Password")
- self.nickservpass.setEchoMode(QtGui.QLineEdit.PasswordEchoOnEdit)
+ self.nickservpass.setEchoMode(QtWidgets.QLineEdit.PasswordEchoOnEdit)
self.nickservpass.setText(parent.userprofile.getNickServPass())
- self.autojoinlist = QtGui.QListWidget(self)
+ self.autojoinlist = QtWidgets.QListWidget(self)
self.autojoinlist.addItems(parent.userprofile.getAutoJoins())
- self.addAutoJoinBtn = QtGui.QPushButton("Add", self)
- self.connect(self.addAutoJoinBtn, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('addAutoJoin()'))
- self.delAutoJoinBtn = QtGui.QPushButton("Remove", self)
- self.connect(self.delAutoJoinBtn, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('delAutoJoin()'))
+ self.addAutoJoinBtn = QtWidgets.QPushButton("Add", self)
+ self.addAutoJoinBtn.clicked.connect(self.addAutoJoin)
+ self.delAutoJoinBtn = QtWidgets.QPushButton("Remove", self)
+ self.delAutoJoinBtn.clicked.connect(self.delAutoJoin)
- self.tabcheck = QtGui.QCheckBox("Tabbed Conversations", self)
+ self.tabcheck = QtWidgets.QCheckBox("Tabbed Conversations", self)
if self.config.tabs():
self.tabcheck.setChecked(True)
- self.tabmemocheck = QtGui.QCheckBox("Tabbed Memos", self)
+ self.tabmemocheck = QtWidgets.QCheckBox("Tabbed Memos", self)
if self.config.tabMemos():
self.tabmemocheck.setChecked(True)
- self.hideOffline = QtGui.QCheckBox("Hide Offline Chums", self)
+ self.hideOffline = QtWidgets.QCheckBox("Hide Offline Chums", self)
if self.config.hideOfflineChums():
self.hideOffline.setChecked(True)
- self.soundcheck = QtGui.QCheckBox("Sounds On", self)
- self.connect(self.soundcheck, QtCore.SIGNAL('stateChanged(int)'),
- self, QtCore.SLOT('soundChange(int)'))
- self.chatsoundcheck = QtGui.QCheckBox("Pester Sounds", self)
+ self.soundcheck = QtWidgets.QCheckBox("Sounds On", self)
+ self.soundcheck.stateChanged[int].connect(self.soundChange)
+ self.chatsoundcheck = QtWidgets.QCheckBox("Pester Sounds", self)
self.chatsoundcheck.setChecked(self.config.chatSound())
- self.memosoundcheck = QtGui.QCheckBox("Memo Sounds", self)
+ self.memosoundcheck = QtWidgets.QCheckBox("Memo Sounds", self)
self.memosoundcheck.setChecked(self.config.memoSound())
- self.connect(self.memosoundcheck, QtCore.SIGNAL('stateChanged(int)'),
- self, QtCore.SLOT('memoSoundChange(int)'))
- self.memopingcheck = QtGui.QCheckBox("Memo Ping", self)
+ self.memosoundcheck.stateChanged[int].connect(self.memoSoundChange)
+ self.memopingcheck = QtWidgets.QCheckBox("Memo Ping", self)
self.memopingcheck.setChecked(self.config.memoPing())
- self.namesoundcheck = QtGui.QCheckBox("Memo Mention (initials)", self)
+ self.namesoundcheck = QtWidgets.QCheckBox("Memo Mention (initials)", self)
self.namesoundcheck.setChecked(self.config.nameSound())
if self.config.soundOn():
self.soundcheck.setChecked(True)
@@ -1070,63 +1034,60 @@ class PesterOptions(QtGui.QDialog):
self.memosoundcheck.setEnabled(False)
self.memoSoundChange(0)
- self.editMentions = QtGui.QPushButton("Edit Mentions", self)
- self.connect(self.editMentions, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('openMentions()'))
- self.editMentions2 = QtGui.QPushButton("Edit Mentions", self)
- self.connect(self.editMentions2, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('openMentions()'))
+ self.editMentions = QtWidgets.QPushButton("Edit Mentions", self)
+ self.editMentions.clicked.connect(self.openMentions)
+ self.editMentions2 = QtWidgets.QPushButton("Edit Mentions", self)
+ self.editMentions2.clicked.connect(self.openMentions)
- self.volume = QtGui.QSlider(QtCore.Qt.Horizontal, self)
+ self.volume = QtWidgets.QSlider(QtCore.Qt.Horizontal, self)
self.volume.setMinimum(0)
self.volume.setMaximum(100)
self.volume.setValue(self.config.volume())
- self.connect(self.volume, QtCore.SIGNAL('valueChanged(int)'),
- self, QtCore.SLOT('printValue(int)'))
+ self.volume.valueChanged[int].connect(self.printValue)
# Disable the volume slider if we can't actually use it.
if parent.canSetVolume():
- self.currentVol = QtGui.QLabel(
+ self.currentVol = QtWidgets.QLabel(
"{0!s}%".format(self.config.volume()), self)
# We don't need to explicitly set this, but it helps drive the
# point home
self.volume.setEnabled(True)
else:
# We can't set the volume....
- self.currentVol = QtGui.QLabel(
+ self.currentVol = QtWidgets.QLabel(
"(Disabled: Sound Mixer Error)", self)
self.volume.setEnabled(False)
self.currentVol.setAlignment(QtCore.Qt.AlignHCenter)
- self.timestampcheck = QtGui.QCheckBox("Time Stamps", self)
+ self.timestampcheck = QtWidgets.QCheckBox("Time Stamps", self)
if self.config.showTimeStamps():
self.timestampcheck.setChecked(True)
- self.timestampBox = QtGui.QComboBox(self)
+ self.timestampBox = QtWidgets.QComboBox(self)
self.timestampBox.addItem("12 hour")
self.timestampBox.addItem("24 hour")
if self.config.time12Format():
self.timestampBox.setCurrentIndex(0)
else:
self.timestampBox.setCurrentIndex(1)
- self.secondscheck = QtGui.QCheckBox("Show Seconds", self)
+ self.secondscheck = QtWidgets.QCheckBox("Show Seconds", self)
if self.config.showSeconds():
self.secondscheck.setChecked(True)
- self.memomessagecheck = QtGui.QCheckBox("Show OP and Voice Messages in Memos", self)
+ self.memomessagecheck = QtWidgets.QCheckBox("Show OP and Voice Messages in Memos", self)
if self.config.opvoiceMessages():
self.memomessagecheck.setChecked(True)
if not ostools.isOSXBundle():
- self.animationscheck = QtGui.QCheckBox("Use animated smilies", self)
+ self.animationscheck = QtWidgets.QCheckBox("Use animated smilies", self)
if self.config.animations():
self.animationscheck.setChecked(True)
- animateLabel = QtGui.QLabel("(Disable if you leave chats open for LOOOONG periods of time)")
+ animateLabel = QtWidgets.QLabel("(Disable if you leave chats open for LOOOONG periods of time)")
font = animateLabel.font()
font.setPointSize(8)
animateLabel.setFont(font)
- self.userlinkscheck = QtGui.QCheckBox("Disable #Memo and @User Links", self)
+ self.userlinkscheck = QtWidgets.QCheckBox("Disable #Memo and @User Links", self)
self.userlinkscheck.setChecked(self.config.disableUserLinks())
self.userlinkscheck.setVisible(False)
@@ -1134,45 +1095,45 @@ class PesterOptions(QtGui.QDialog):
# Will add ability to turn off groups later
#self.groupscheck = QtGui.QCheckBox("Use Groups", self)
#self.groupscheck.setChecked(self.config.useGroups())
- self.showemptycheck = QtGui.QCheckBox("Show Empty Groups", self)
+ self.showemptycheck = QtWidgets.QCheckBox("Show Empty Groups", self)
self.showemptycheck.setChecked(self.config.showEmptyGroups())
- self.showonlinenumbers = QtGui.QCheckBox("Show Number of Online Chums", self)
+ self.showonlinenumbers = QtWidgets.QCheckBox("Show Number of Online Chums", self)
self.showonlinenumbers.setChecked(self.config.showOnlineNumbers())
- sortLabel = QtGui.QLabel("Sort Chums")
- self.sortBox = QtGui.QComboBox(self)
+ sortLabel = QtWidgets.QLabel("Sort Chums")
+ self.sortBox = QtWidgets.QComboBox(self)
self.sortBox.addItem("Alphabetically")
self.sortBox.addItem("By Mood")
self.sortBox.addItem("Manually")
method = self.config.sortMethod()
if method >= 0 and method < self.sortBox.count():
self.sortBox.setCurrentIndex(method)
- layout_3 = QtGui.QHBoxLayout()
+ layout_3 = QtWidgets.QHBoxLayout()
layout_3.addWidget(sortLabel)
layout_3.addWidget(self.sortBox, 10)
- self.logpesterscheck = QtGui.QCheckBox("Log all Pesters", self)
+ self.logpesterscheck = QtWidgets.QCheckBox("Log all Pesters", self)
if self.config.logPesters() & self.config.LOG:
self.logpesterscheck.setChecked(True)
- self.logmemoscheck = QtGui.QCheckBox("Log all Memos", self)
+ self.logmemoscheck = QtWidgets.QCheckBox("Log all Memos", self)
if self.config.logMemos() & self.config.LOG:
self.logmemoscheck.setChecked(True)
- self.stamppestercheck = QtGui.QCheckBox("Log Time Stamps for Pesters", self)
+ self.stamppestercheck = QtWidgets.QCheckBox("Log Time Stamps for Pesters", self)
if self.config.logPesters() & self.config.STAMP:
self.stamppestercheck.setChecked(True)
- self.stampmemocheck = QtGui.QCheckBox("Log Time Stamps for Memos", self)
+ self.stampmemocheck = QtWidgets.QCheckBox("Log Time Stamps for Memos", self)
if self.config.logMemos() & self.config.STAMP:
self.stampmemocheck.setChecked(True)
- self.idleBox = QtGui.QSpinBox(self)
+ self.idleBox = QtWidgets.QSpinBox(self)
self.idleBox.setStyleSheet("background:#FFFFFF")
self.idleBox.setRange(1, 1440)
self.idleBox.setValue(self.config.idleTime())
- layout_5 = QtGui.QHBoxLayout()
- layout_5.addWidget(QtGui.QLabel("Minutes before Idle:"))
+ layout_5 = QtWidgets.QHBoxLayout()
+ layout_5.addWidget(QtWidgets.QLabel("Minutes before Idle:"))
layout_5.addWidget(self.idleBox)
- self.updateBox = QtGui.QComboBox(self)
+ self.updateBox = QtWidgets.QComboBox(self)
self.updateBox.addItem("Once a Day")
self.updateBox.addItem("Once a Week")
self.updateBox.addItem("Only on Start")
@@ -1180,59 +1141,57 @@ class PesterOptions(QtGui.QDialog):
check = self.config.checkForUpdates()
if check >= 0 and check < self.updateBox.count():
self.updateBox.setCurrentIndex(check)
- layout_6 = QtGui.QHBoxLayout()
- layout_6.addWidget(QtGui.QLabel("Check for\nPesterchum Updates:"))
+ layout_6 = QtWidgets.QHBoxLayout()
+ layout_6.addWidget(QtWidgets.QLabel("Check for\nPesterchum Updates:"))
layout_6.addWidget(self.updateBox)
if not ostools.isOSXLeopard():
- self.mspaCheck = QtGui.QCheckBox("Check for MSPA Updates", self)
+ self.mspaCheck = QtWidgets.QCheckBox("Check for MSPA Updates", self)
self.mspaCheck.setChecked(self.config.checkMSPA())
- self.randomscheck = QtGui.QCheckBox("Receive Random Encounters")
+ self.randomscheck = QtWidgets.QCheckBox("Receive Random Encounters")
self.randomscheck.setChecked(parent.userprofile.randoms)
if not parent.randhandler.running:
self.randomscheck.setEnabled(False)
avail_themes = self.config.availableThemes()
- self.themeBox = QtGui.QComboBox(self)
+ self.themeBox = QtWidgets.QComboBox(self)
notheme = (theme.name not in avail_themes)
for (i, t) in enumerate(avail_themes):
self.themeBox.addItem(t)
if (not notheme and t == theme.name) or (notheme and t == "pesterchum"):
self.themeBox.setCurrentIndex(i)
- self.refreshtheme = QtGui.QPushButton("Refresh current theme", self)
- self.connect(self.refreshtheme, QtCore.SIGNAL('clicked()'),
- parent, QtCore.SLOT('themeSelectOverride()'))
- self.ghostchum = QtGui.QCheckBox("Pesterdunk Ghostchum!!", self)
+ self.refreshtheme = QtWidgets.QPushButton("Refresh current theme", self)
+ self.refreshtheme.clicked.connect(parent.themeSelectOverride)
+ self.ghostchum = QtWidgets.QCheckBox("Pesterdunk Ghostchum!!", self)
self.ghostchum.setChecked(self.config.ghostchum())
self.buttonOptions = ["Minimize to Taskbar", "Minimize to Tray", "Quit"]
- self.miniBox = QtGui.QComboBox(self)
+ self.miniBox = QtWidgets.QComboBox(self)
self.miniBox.addItems(self.buttonOptions)
self.miniBox.setCurrentIndex(self.config.minimizeAction())
- self.closeBox = QtGui.QComboBox(self)
+ self.closeBox = QtWidgets.QComboBox(self)
self.closeBox.addItems(self.buttonOptions)
self.closeBox.setCurrentIndex(self.config.closeAction())
- layout_mini = QtGui.QHBoxLayout()
- layout_mini.addWidget(QtGui.QLabel("Minimize"))
+ layout_mini = QtWidgets.QHBoxLayout()
+ layout_mini.addWidget(QtWidgets.QLabel("Minimize"))
layout_mini.addWidget(self.miniBox)
- layout_close = QtGui.QHBoxLayout()
- layout_close.addWidget(QtGui.QLabel("Close"))
+ layout_close = QtWidgets.QHBoxLayout()
+ layout_close.addWidget(QtWidgets.QLabel("Close"))
layout_close.addWidget(self.closeBox)
- self.pesterBlink = QtGui.QCheckBox("Blink Taskbar on Pesters", self)
+ self.pesterBlink = QtWidgets.QCheckBox("Blink Taskbar on Pesters", self)
if self.config.blink() & self.config.PBLINK:
self.pesterBlink.setChecked(True)
- self.memoBlink = QtGui.QCheckBox("Blink Taskbar on Memos", self)
+ self.memoBlink = QtWidgets.QCheckBox("Blink Taskbar on Memos", self)
if self.config.blink() & self.config.MBLINK:
self.memoBlink.setChecked(True)
- self.notifycheck = QtGui.QCheckBox("Toast Notifications", self)
+ self.notifycheck = QtWidgets.QCheckBox("Toast Notifications", self)
if self.config.notify():
self.notifycheck.setChecked(True)
- self.connect(self.notifycheck, QtCore.SIGNAL('stateChanged(int)'),
- self, QtCore.SLOT('notifyChange(int)'))
- self.notifyOptions = QtGui.QComboBox(self)
+ self.notifycheck.stateChanged[int].connect(self.notifyChange)
+ self.notifyOptions = QtWidgets.QComboBox(self)
types = self.parent().tm.availableTypes()
cur = self.parent().tm.currentType()
self.notifyOptions.addItems(types)
@@ -1240,49 +1199,47 @@ class PesterOptions(QtGui.QDialog):
if t == cur:
self.notifyOptions.setCurrentIndex(i)
break
- self.notifyTypeLabel = QtGui.QLabel("Type", self)
- layout_type = QtGui.QHBoxLayout()
+ self.notifyTypeLabel = QtWidgets.QLabel("Type", self)
+ layout_type = QtWidgets.QHBoxLayout()
layout_type.addWidget(self.notifyTypeLabel)
layout_type.addWidget(self.notifyOptions)
- self.notifySigninCheck = QtGui.QCheckBox("Chum signs in", self)
+ self.notifySigninCheck = QtWidgets.QCheckBox("Chum signs in", self)
if self.config.notifyOptions() & self.config.SIGNIN:
self.notifySigninCheck.setChecked(True)
- self.notifySignoutCheck = QtGui.QCheckBox("Chum signs out", self)
+ self.notifySignoutCheck = QtWidgets.QCheckBox("Chum signs out", self)
if self.config.notifyOptions() & self.config.SIGNOUT:
self.notifySignoutCheck.setChecked(True)
- self.notifyNewMsgCheck = QtGui.QCheckBox("New messages", self)
+ self.notifyNewMsgCheck = QtWidgets.QCheckBox("New messages", self)
if self.config.notifyOptions() & self.config.NEWMSG:
self.notifyNewMsgCheck.setChecked(True)
- self.notifyNewConvoCheck = QtGui.QCheckBox("Only new conversations", self)
+ self.notifyNewConvoCheck = QtWidgets.QCheckBox("Only new conversations", self)
if self.config.notifyOptions() & self.config.NEWCONVO:
self.notifyNewConvoCheck.setChecked(True)
- self.notifyMentionsCheck = QtGui.QCheckBox("Memo Mentions (initials)", self)
+ self.notifyMentionsCheck = QtWidgets.QCheckBox("Memo Mentions (initials)", self)
if self.config.notifyOptions() & self.config.INITIALS:
self.notifyMentionsCheck.setChecked(True)
self.notifyChange(self.notifycheck.checkState())
if parent.advanced:
# NOTE: This doesn't do anything right now - so change it!
- self.modechange = QtGui.QLineEdit(self)
- layout_change = QtGui.QHBoxLayout()
- layout_change.addWidget(QtGui.QLabel("Change:"))
+ self.modechange = QtWidgets.QLineEdit(self)
+ layout_change = QtWidgets.QHBoxLayout()
+ layout_change.addWidget(QtWidgets.QLabel("Change:"))
layout_change.addWidget(self.modechange)
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_2 = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.accept)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
# Tab layouts
# Chum List
- widget = QtGui.QWidget()
- layout_chumlist = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_chumlist = QtWidgets.QVBoxLayout(widget)
layout_chumlist.setAlignment(QtCore.Qt.AlignTop)
layout_chumlist.addWidget(self.hideOffline)
#layout_chumlist.addWidget(self.groupscheck)
@@ -1292,8 +1249,8 @@ class PesterOptions(QtGui.QDialog):
self.pages.addWidget(widget)
# Conversations
- widget = QtGui.QWidget()
- layout_chat = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_chat = QtWidgets.QVBoxLayout(widget)
layout_chat.setAlignment(QtCore.Qt.AlignTop)
layout_chat.addWidget(self.timestampcheck)
layout_chat.addWidget(self.timestampBox)
@@ -1310,8 +1267,8 @@ class PesterOptions(QtGui.QDialog):
self.pages.addWidget(widget)
# Interface
- widget = QtGui.QWidget()
- layout_interface = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_interface = QtWidgets.QVBoxLayout(widget)
layout_interface.setAlignment(QtCore.Qt.AlignTop)
layout_interface.addWidget(self.tabcheck)
layout_interface.addWidget(self.tabmemocheck)
@@ -1322,14 +1279,14 @@ class PesterOptions(QtGui.QDialog):
self.pages.addWidget(widget)
# Sound
- widget = QtGui.QWidget()
- layout_sound = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_sound = QtWidgets.QVBoxLayout(widget)
layout_sound.setAlignment(QtCore.Qt.AlignTop)
layout_sound.addWidget(self.soundcheck)
- layout_indent = QtGui.QVBoxLayout()
+ layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addWidget(self.chatsoundcheck)
layout_indent.addWidget(self.memosoundcheck)
- layout_doubleindent = QtGui.QVBoxLayout()
+ layout_doubleindent = QtWidgets.QVBoxLayout()
layout_doubleindent.addWidget(self.memopingcheck)
layout_doubleindent.addWidget(self.namesoundcheck)
layout_doubleindent.addWidget(self.editMentions)
@@ -1338,7 +1295,7 @@ class PesterOptions(QtGui.QDialog):
layout_indent.setContentsMargins(22,0,0,0)
layout_sound.addLayout(layout_indent)
layout_sound.addSpacing(15)
- mvol = QtGui.QLabel("Master Volume:", self)
+ mvol = QtWidgets.QLabel("Master Volume:", self)
# If we can't set the volume, grey this out as well
#~mvol.setEnabled(parent.canSetVolume())
# Normally we'd grey this out, but that presently makes things
@@ -1350,17 +1307,17 @@ class PesterOptions(QtGui.QDialog):
self.pages.addWidget(widget)
# Notifications
- widget = QtGui.QWidget()
- layout_notify = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_notify = QtWidgets.QVBoxLayout(widget)
layout_notify.setAlignment(QtCore.Qt.AlignTop)
layout_notify.addWidget(self.notifycheck)
- layout_indent = QtGui.QVBoxLayout()
+ layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addLayout(layout_type)
layout_indent.setContentsMargins(22,0,0,0)
layout_indent.addWidget(self.notifySigninCheck)
layout_indent.addWidget(self.notifySignoutCheck)
layout_indent.addWidget(self.notifyNewMsgCheck)
- layout_doubleindent = QtGui.QVBoxLayout()
+ layout_doubleindent = QtWidgets.QVBoxLayout()
layout_doubleindent.addWidget(self.notifyNewConvoCheck)
layout_doubleindent.setContentsMargins(22,0,0,0)
layout_indent.addLayout(layout_doubleindent)
@@ -1370,8 +1327,8 @@ class PesterOptions(QtGui.QDialog):
self.pages.addWidget(widget)
# Logging
- widget = QtGui.QWidget()
- layout_logs = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_logs = QtWidgets.QVBoxLayout(widget)
layout_logs.setAlignment(QtCore.Qt.AlignTop)
layout_logs.addWidget(self.logpesterscheck)
layout_logs.addWidget(self.logmemoscheck)
@@ -1380,8 +1337,8 @@ class PesterOptions(QtGui.QDialog):
self.pages.addWidget(widget)
# Idle/Updates
- widget = QtGui.QWidget()
- layout_idle = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_idle = QtWidgets.QVBoxLayout(widget)
layout_idle.setAlignment(QtCore.Qt.AlignTop)
layout_idle.addLayout(layout_5)
layout_idle.addLayout(layout_6)
@@ -1390,29 +1347,29 @@ class PesterOptions(QtGui.QDialog):
self.pages.addWidget(widget)
# Theme
- widget = QtGui.QWidget()
- layout_theme = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_theme = QtWidgets.QVBoxLayout(widget)
layout_theme.setAlignment(QtCore.Qt.AlignTop)
- layout_theme.addWidget(QtGui.QLabel("Pick a Theme:"))
+ layout_theme.addWidget(QtWidgets.QLabel("Pick a Theme:"))
layout_theme.addWidget(self.themeBox)
layout_theme.addWidget(self.refreshtheme)
layout_theme.addWidget(self.ghostchum)
self.pages.addWidget(widget)
# Connection
- widget = QtGui.QWidget()
- layout_connect = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_connect = QtWidgets.QVBoxLayout(widget)
layout_connect.setAlignment(QtCore.Qt.AlignTop)
layout_connect.addWidget(self.bandwidthcheck)
layout_connect.addWidget(bandwidthLabel)
layout_connect.addWidget(self.autonickserv)
- layout_indent = QtGui.QVBoxLayout()
+ layout_indent = QtWidgets.QVBoxLayout()
layout_indent.addWidget(self.nickservpass)
layout_indent.setContentsMargins(22,0,0,0)
layout_connect.addLayout(layout_indent)
- layout_connect.addWidget(QtGui.QLabel("Auto-Join Memos:"))
+ layout_connect.addWidget(QtWidgets.QLabel("Auto-Join Memos:"))
layout_connect.addWidget(self.autojoinlist)
- layout_8 = QtGui.QHBoxLayout()
+ layout_8 = QtWidgets.QHBoxLayout()
layout_8.addWidget(self.addAutoJoinBtn)
layout_8.addWidget(self.delAutoJoinBtn)
layout_connect.addLayout(layout_8)
@@ -1420,15 +1377,15 @@ class PesterOptions(QtGui.QDialog):
# Advanced
if parent.advanced:
- widget = QtGui.QWidget()
- layout_advanced = QtGui.QVBoxLayout(widget)
+ widget = QtWidgets.QWidget()
+ layout_advanced = QtWidgets.QVBoxLayout(widget)
layout_advanced.setAlignment(QtCore.Qt.AlignTop)
- layout_advanced.addWidget(QtGui.QLabel("Current User Mode: %s" % parent.modes))
+ layout_advanced.addWidget(QtWidgets.QLabel("Current User Mode: %s" % parent.modes))
layout_advanced.addLayout(layout_change)
self.pages.addWidget(widget)
- layout_0 = QtGui.QVBoxLayout()
- layout_1 = QtGui.QHBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
+ layout_1 = QtWidgets.QHBoxLayout()
layout_1.addLayout(layout_4)
layout_1.addWidget(vr)
layout_1.addWidget(self.pages)
@@ -1519,10 +1476,8 @@ class PesterOptions(QtGui.QDialog):
self.mentionmenu = None
if not self.mentionmenu:
self.mentionmenu = PesterMentions(self.parent(), self.theme, self)
- self.connect(self.mentionmenu, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('updateMentions()'))
- self.connect(self.mentionmenu, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('closeMentions()'))
+ self.mentionmenu.accepted.connect(self.updateMentions)
+ self.mentionmenu.rejected.connect(self.closeMentions)
self.mentionmenu.show()
self.mentionmenu.raise_()
self.mentionmenu.activateWindow()
@@ -1538,9 +1493,9 @@ class PesterOptions(QtGui.QDialog):
self.parent().userprofile.setMentions(m)
self.mentionmenu = None
-class PesterUserlist(QtGui.QDialog):
+class PesterUserlist(QtWidgets.QDialog):
def __init__(self, config, theme, parent):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.config = config
self.theme = theme
@@ -1548,31 +1503,28 @@ class PesterUserlist(QtGui.QDialog):
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.resize(200, 600)
- self.searchbox = QtGui.QLineEdit(self)
+ self.searchbox = QtWidgets.QLineEdit(self)
#self.searchbox.setStyleSheet(theme["convo/input/style"]) # which style is better?
self.searchbox.setPlaceholderText("Search")
- self.connect(self.searchbox, QtCore.SIGNAL("textChanged(QString)"), self, QtCore.SLOT("updateUsers()"))
+ self.searchbox.textChanged['QString'].connect(self.updateUsers)
- self.label = QtGui.QLabel("USERLIST")
+ self.label = QtWidgets.QLabel("USERLIST")
self.userarea = RightClickList(self)
self.userarea.setStyleSheet(self.theme["main/chums/style"])
- self.userarea.optionsMenu = QtGui.QMenu(self)
+ self.userarea.optionsMenu = QtWidgets.QMenu(self)
- self.addChumAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
- self.connect(self.addChumAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('addChumSlot()'))
- self.pesterChumAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
- self.connect(self.pesterChumAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('pesterChumSlot()'))
+ self.addChumAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/addchum"], self)
+ self.addChumAction.triggered.connect(self.addChumSlot)
+ self.pesterChumAction = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
+ self.pesterChumAction.triggered.connect(self.pesterChumSlot)
self.userarea.optionsMenu.addAction(self.addChumAction)
self.userarea.optionsMenu.addAction(self.pesterChumAction)
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
+ self.ok.clicked.connect(self.accept)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.label)
layout_0.addWidget(self.userarea)
layout_0.addWidget(self.searchbox)
@@ -1580,13 +1532,9 @@ class PesterUserlist(QtGui.QDialog):
self.setLayout(layout_0)
- self.connect(self.mainwindow, QtCore.SIGNAL('namesUpdated()'),
- self, QtCore.SLOT('updateUsers()'))
+ self.mainwindow.namesUpdated.connect(self.updateUsers)
- self.connect(self.mainwindow,
- QtCore.SIGNAL('userPresentSignal(QString, QString, QString)'),
- self,
- QtCore.SLOT('updateUserPresent(QString, QString, QString)'))
+ self.mainwindow.userPresentSignal['QString', 'QString', 'QString'].connect(self.updateUserPresent)
self.updateUsers()
self.searchbox.setFocus()
@@ -1596,14 +1544,14 @@ class PesterUserlist(QtGui.QDialog):
self.userarea.clear()
for n in names:
if str(self.searchbox.text()) == "" or n.lower().find(str(self.searchbox.text()).lower()) != -1:
- item = QtGui.QListWidgetItem(n)
+ item = QtWidgets.QListWidgetItem(n)
item.setTextColor(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
self.userarea.addItem(item)
self.userarea.sortItems()
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString, QString)
def updateUserPresent(self, handle, channel, update):
- h = unicode(handle)
- c = unicode(channel)
+ h = str(handle)
+ c = str(channel)
if update == "quit":
self.delUser(h)
elif update == "left" and c == "#pesterchum":
@@ -1612,7 +1560,7 @@ class PesterUserlist(QtGui.QDialog):
if str(self.searchbox.text()) == "" or h.lower().find(str(self.searchbox.text()).lower()) != -1:
self.addUser(h)
def addUser(self, name):
- item = QtGui.QListWidgetItem(name)
+ item = QtWidgets.QListWidgetItem(name)
item.setTextColor(QtGui.QColor(self.theme["main/chums/userlistcolor"]))
self.userarea.addItem(item)
self.userarea.sortItems()
@@ -1642,13 +1590,13 @@ class PesterUserlist(QtGui.QDialog):
return
self.pesterChum.emit(cur.text())
- addChum = QtCore.pyqtSignal(QtCore.QString)
- pesterChum = QtCore.pyqtSignal(QtCore.QString)
+ addChum = QtCore.pyqtSignal('QString')
+ pesterChum = QtCore.pyqtSignal('QString')
-class MemoListItem(QtGui.QTreeWidgetItem):
+class MemoListItem(QtWidgets.QTreeWidgetItem):
def __init__(self, channel, usercount):
- QtGui.QTreeWidgetItem.__init__(self, [channel, str(usercount)])
+ QtWidgets.QTreeWidgetItem.__init__(self, [channel, str(usercount)])
self.target = channel
def __lt__(self, other):
column = self.treeWidget().sortColumn()
@@ -1656,20 +1604,20 @@ class MemoListItem(QtGui.QTreeWidgetItem):
return int(self.text(column)) < int(other.text(column))
return self.text(column) < other.text(column)
-class PesterMemoList(QtGui.QDialog):
+class PesterMemoList(QtWidgets.QDialog):
def __init__(self, parent, channel=""):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.setModal(False)
self.theme = parent.theme
self.mainwindow = parent
self.setStyleSheet(self.theme["main/defaultwindow/style"])
self.resize(460, 300)
- self.label = QtGui.QLabel("MEMOS")
+ self.label = QtWidgets.QLabel("MEMOS")
self.channelarea = RightClickTree(self)
- self.channelarea.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
+ self.channelarea.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.channelarea.setStyleSheet(self.theme["main/chums/style"])
- self.channelarea.optionsMenu = QtGui.QMenu(self)
+ self.channelarea.optionsMenu = QtWidgets.QMenu(self)
self.channelarea.setColumnCount(2)
self.channelarea.setHeaderLabels(["Memo", "Users"])
self.channelarea.setIndentation(0)
@@ -1677,35 +1625,31 @@ class PesterMemoList(QtGui.QDialog):
self.channelarea.setColumnWidth(1,10)
self.channelarea.setSortingEnabled(True)
self.channelarea.sortByColumn(0, QtCore.Qt.AscendingOrder)
- self.connect(self.channelarea,
- QtCore.SIGNAL('itemDoubleClicked(QTreeWidgetItem *, int)'),
- self, QtCore.SLOT('AcceptSelection()'))
+ self.channelarea.itemDoubleClicked[QTreeWidgetItem, int].connect(self.AcceptSelection)
- self.orjoinlabel = QtGui.QLabel("OR MAKE A NEW MEMO:")
- self.newmemo = QtGui.QLineEdit(channel, self)
- self.secretChannel = QtGui.QCheckBox("HIDDEN CHANNEL?", self)
- self.inviteChannel = QtGui.QCheckBox("INVITATION ONLY?", self)
+ self.orjoinlabel = QtWidgets.QLabel("OR MAKE A NEW MEMO:")
+ self.newmemo = QtWidgets.QLineEdit(channel, self)
+ self.secretChannel = QtWidgets.QCheckBox("HIDDEN CHANNEL?", self)
+ self.inviteChannel = QtWidgets.QCheckBox("INVITATION ONLY?", self)
- self.timelabel = QtGui.QLabel("TIMEFRAME:")
+ self.timelabel = QtWidgets.QLabel("TIMEFRAME:")
self.timeslider = TimeSlider(QtCore.Qt.Horizontal, self)
self.timeinput = TimeInput(self.timeslider, self)
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- self.join = QtGui.QPushButton("JOIN", self)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ self.join = QtWidgets.QPushButton("JOIN", self)
self.join.setDefault(True)
- self.connect(self.join, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('AcceptIfSelectionMade()'))
- layout_ok = QtGui.QHBoxLayout()
+ self.join.clicked.connect(self.AcceptIfSelectionMade)
+ layout_ok = QtWidgets.QHBoxLayout()
layout_ok.addWidget(self.cancel)
layout_ok.addWidget(self.join)
- layout_left = QtGui.QVBoxLayout()
- layout_right = QtGui.QVBoxLayout()
+ layout_left = QtWidgets.QVBoxLayout()
+ layout_right = QtWidgets.QVBoxLayout()
layout_right.setAlignment(QtCore.Qt.AlignTop)
- layout_0 = QtGui.QVBoxLayout()
- layout_1 = QtGui.QHBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
+ layout_1 = QtWidgets.QHBoxLayout()
layout_left.addWidget(self.label)
layout_left.addWidget(self.channelarea)
layout_right.addWidget(self.orjoinlabel)
@@ -1756,27 +1700,27 @@ class PesterMemoList(QtGui.QDialog):
self.accept()
-class LoadingScreen(QtGui.QDialog):
+class LoadingScreen(QtWidgets.QDialog):
+ tryAgain = QtCore.pyqtSignal()
+
def __init__(self, parent=None):
- QtGui.QDialog.__init__(self, parent, (QtCore.Qt.CustomizeWindowHint |
+ QtWidgets.QDialog.__init__(self, parent, (QtCore.Qt.CustomizeWindowHint |
QtCore.Qt.FramelessWindowHint))
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
- self.loadinglabel = QtGui.QLabel("CONN3CT1NG", self)
- self.cancel = QtGui.QPushButton("QU1T >:?", self)
- self.ok = QtGui.QPushButton("R3CONN3CT >:]", self)
+ self.loadinglabel = QtWidgets.QLabel("CONN3CT1NG", self)
+ self.cancel = QtWidgets.QPushButton("QU1T >:?", self)
+ self.ok = QtWidgets.QPushButton("R3CONN3CT >:]", self)
# Help reduce the number of accidental Pesterchum closures... :|
self.cancel.setAutoDefault(False)
self.ok.setAutoDefault(True)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SIGNAL('tryAgain()'))
+ self.cancel.clicked.connect(self.reject)
+ self.ok.clicked.connect(self.tryAgain)
- self.layout = QtGui.QVBoxLayout()
+ self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.loadinglabel)
- layout_1 = QtGui.QHBoxLayout()
+ layout_1 = QtWidgets.QHBoxLayout()
layout_1.addWidget(self.cancel)
layout_1.addWidget(self.ok)
self.layout.addLayout(layout_1)
@@ -1807,14 +1751,14 @@ class LoadingScreen(QtGui.QDialog):
tryAgain = QtCore.pyqtSignal()
-class AboutPesterchum(QtGui.QDialog):
+class AboutPesterchum(QtWidgets.QDialog):
def __init__(self, parent=None):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
- self.title = QtGui.QLabel("P3ST3RCHUM V. %s" % (_pcVersion))
- self.credits = QtGui.QLabel("Programming by:\n\
+ self.title = QtWidgets.QLabel("P3ST3RCHUM V. %s" % (_pcVersion))
+ self.credits = QtWidgets.QLabel("Programming by:\n\
illuminatedwax (ghostDunk)\n\
Kiooeht (evacipatedBox)\n\
Lexi (lexicalNuance)\n\
@@ -1833,39 +1777,36 @@ Special Thanks:\n\
gamblingGenocider\n\
Eco-Mono")
- self.ok = QtGui.QPushButton("OK", self)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
+ self.ok = QtWidgets.QPushButton("OK", self)
+ self.ok.clicked.connect(self.reject)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.title)
layout_0.addWidget(self.credits)
layout_0.addWidget(self.ok)
self.setLayout(layout_0)
-class UpdatePesterchum(QtGui.QDialog):
+class UpdatePesterchum(QtWidgets.QDialog):
def __init__(self, ver, url, parent=None):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.url = url
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Pesterchum v%s Update" % (ver))
self.setModal(False)
- self.title = QtGui.QLabel("An update to Pesterchum is available!")
+ self.title = QtWidgets.QLabel("An update to Pesterchum is available!")
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.title)
- self.ok = QtGui.QPushButton("D0WNL04D 4ND 1NST4LL N0W", self)
+ self.ok = QtWidgets.QPushButton("D0WNL04D 4ND 1NST4LL N0W", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_2 = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.accept)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
@@ -1873,41 +1814,39 @@ class UpdatePesterchum(QtGui.QDialog):
self.setLayout(layout_0)
-class AddChumDialog(QtGui.QDialog):
+class AddChumDialog(QtWidgets.QDialog):
def __init__(self, avail_groups, parent=None):
- QtGui.QDialog.__init__(self, parent)
+ QtWidgets.QDialog.__init__(self, parent)
self.mainwindow = parent
self.setStyleSheet(self.mainwindow.theme["main/defaultwindow/style"])
self.setWindowTitle("Enter Chum Handle")
self.setModal(True)
- self.title = QtGui.QLabel("Enter Chum Handle")
- self.chumBox = QtGui.QLineEdit(self)
- self.groupBox = QtGui.QComboBox(self)
+ self.title = QtWidgets.QLabel("Enter Chum Handle")
+ self.chumBox = QtWidgets.QLineEdit(self)
+ self.groupBox = QtWidgets.QComboBox(self)
avail_groups.sort()
avail_groups.pop(avail_groups.index("Chums"))
avail_groups.insert(0, "Chums")
for g in avail_groups:
self.groupBox.addItem(g)
- self.newgrouplabel = QtGui.QLabel("Or make a new group:")
- self.newgroup = QtGui.QLineEdit(self)
+ self.newgrouplabel = QtWidgets.QLabel("Or make a new group:")
+ self.newgroup = QtWidgets.QLineEdit(self)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.title)
layout_0.addWidget(self.chumBox)
layout_0.addWidget(self.groupBox)
layout_0.addWidget(self.newgrouplabel)
layout_0.addWidget(self.newgroup)
- self.ok = QtGui.QPushButton("OK", self)
+ self.ok = QtWidgets.QPushButton("OK", self)
self.ok.setDefault(True)
- self.connect(self.ok, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('accept()'))
- self.cancel = QtGui.QPushButton("CANCEL", self)
- self.connect(self.cancel, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('reject()'))
- layout_2 = QtGui.QHBoxLayout()
+ self.ok.clicked.connect(self.accept)
+ self.cancel = QtWidgets.QPushButton("CANCEL", self)
+ self.cancel.clicked.connect(self.reject)
+ layout_2 = QtWidgets.QHBoxLayout()
layout_2.addWidget(self.cancel)
layout_2.addWidget(self.ok)
diff --git a/mispeller.py b/mispeller.py
index b8240e3..5b1cb28 100644
--- a/mispeller.py
+++ b/mispeller.py
@@ -21,12 +21,12 @@ def mispeller(word):
num = 1
else:
num = random.choice([1,2])
- wordseq = range(0, len(word))
+ wordseq = list(range(0, len(word)))
random.shuffle(wordseq)
letters = wordseq[0:num]
def mistype(string, i):
l = string[i]
- if not kbdict.has_key(l):
+ if l not in kbdict:
return string
lpos = kbdict[l]
newpos = lpos
diff --git a/mood.py b/mood.py
index 8c71f6d..993a7dc 100644
--- a/mood.py
+++ b/mood.py
@@ -1,4 +1,4 @@
-from PyQt4 import QtCore, QtGui
+from PyQt5 import QtCore, QtGui, QtWidgets
from generic import PesterIcon
@@ -49,15 +49,13 @@ class PesterMoodHandler(QtCore.QObject):
self.buttons[b.mood.value()] = b
if b.mood.value() == self.mainwindow.profile().mood.value():
b.setSelected(True)
- self.connect(b, QtCore.SIGNAL('clicked()'),
- b, QtCore.SLOT('updateMood()'))
- self.connect(b, QtCore.SIGNAL('moodUpdated(int)'),
- self, QtCore.SLOT('updateMood(int)'))
+ b.clicked.connect(b.updateMood)
+ b.moodUpdated[int].connect(self.updateMood)
def removeButtons(self):
- for b in self.buttons.values():
+ for b in list(self.buttons.values()):
b.close()
def showButtons(self):
- for b in self.buttons.values():
+ for b in list(self.buttons.values()):
b.show()
b.raise_()
@QtCore.pyqtSlot(int)
@@ -81,14 +79,14 @@ class PesterMoodHandler(QtCore.QObject):
moodicon = newmood.icon(self.mainwindow.theme)
self.mainwindow.currentMoodIcon.setPixmap(moodicon.pixmap(moodicon.realsize()))
if oldmood.name() != newmood.name():
- for c in self.mainwindow.convos.values():
+ for c in list(self.mainwindow.convos.values()):
c.myUpdateMood(newmood)
self.mainwindow.moodUpdated.emit()
-class PesterMoodButton(QtGui.QPushButton):
+class PesterMoodButton(QtWidgets.QPushButton):
def __init__(self, parent, **options):
icon = PesterIcon(options["icon"])
- QtGui.QPushButton.__init__(self, icon, options["text"], parent)
+ QtWidgets.QPushButton.__init__(self, icon, options["text"], parent)
self.setIconSize(icon.realsize())
self.setFlat(True)
self.resize(*options["size"])
diff --git a/ostools.py b/ostools.py
index 3ee17ee..2602745 100644
--- a/ostools.py
+++ b/ostools.py
@@ -1,6 +1,7 @@
import os, sys
import platform
-from PyQt4.QtGui import QDesktopServices
+from PyQt5.QtGui import QDesktopServices
+from PyQt5.QtCore import QStandardPaths
def isOSX():
return sys.platform == "darwin"
@@ -32,10 +33,10 @@ def getDataDir():
# in the Pesterchum install directory (like before)
try:
if isOSX():
- return os.path.join(unicode(QDesktopServices.storageLocation(QDesktopServices.DataLocation)), "Pesterchum/")
+ return os.path.join(str(QStandardPaths.writableLocation(QStandardPaths.DataLocation)), "Pesterchum/")
elif isLinux():
- return os.path.join(unicode(QDesktopServices.storageLocation(QDesktopServices.HomeLocation)), ".pesterchum/")
+ return os.path.join(str(QStandardPaths.writableLocation(QStandardPaths.HomeLocation)), ".pesterchum/")
else:
- return os.path.join(unicode(QDesktopServices.storageLocation(QDesktopServices.DataLocation)), "pesterchum/")
+ return os.path.join(str(QStandardPaths.writableLocation(QStandardPaths.DataLocation)), "pesterchum/")
except UnicodeDecodeError:
return ''
diff --git a/oyoyo/client.py b/oyoyo/client.py
index 41f0ae1..b5c819a 100644
--- a/oyoyo/client.py
+++ b/oyoyo/client.py
@@ -127,7 +127,7 @@ class IRCClient:
logging.info('---> send "%s"' % msg)
try:
self.socket.send(msg + bytes("\r\n", "ascii"))
- except socket.error, se:
+ except socket.error as se:
try: # a little dance of compatibility to get the errno
errno = se.errno
except AttributeError:
@@ -160,12 +160,12 @@ class IRCClient:
while not self._end:
try:
buffer += self.socket.recv(1024)
- except socket.timeout, e:
+ except socket.timeout as e:
if self._end:
break
logging.debug("timeout in client.py")
raise e
- except socket.error, e:
+ except socket.error as e:
if self._end:
break
logging.debug("error %s" % e)
@@ -195,10 +195,10 @@ class IRCClient:
pass
yield True
- except socket.timeout, se:
+ except socket.timeout as se:
logging.debug("passing timeout")
raise se
- except socket.error, se:
+ except socket.error as se:
logging.debug("problem: %s" % (se))
if self.socket:
logging.info('error: closing socket')
@@ -264,12 +264,12 @@ class IRCApp:
while self.running:
found_one_alive = False
- for client, clientdesc in self._clients.iteritems():
+ for client, clientdesc in self._clients.items():
if clientdesc.con is None:
clientdesc.con = client.connect()
try:
- clientdesc.con.next()
+ next(clientdesc.con)
except Exception as e:
logging.error('client error %s' % e)
logging.error(traceback.format_exc())
diff --git a/oyoyo/examplebot.py b/oyoyo/examplebot.py
index 81aac02..dfd1885 100644
--- a/oyoyo/examplebot.py
+++ b/oyoyo/examplebot.py
@@ -21,7 +21,7 @@ class MyHandler(DefaultCommandHandler):
match = re.match('\!say (.*)', msg)
if match:
to_say = match.group(1).strip()
- print('Saying, "%s"' % to_say)
+ print(('Saying, "%s"' % to_say))
helpers.msg(self.client, chan, to_say)
@@ -37,7 +37,7 @@ def main():
conn = cli.connect()
while True:
- conn.next() ## python 2
+ next(conn) ## python 2
# next(conn) ## python 3
diff --git a/oyoyo/helpers.py b/oyoyo/helpers.py
index c82ec9c..5c25b59 100644
--- a/oyoyo/helpers.py
+++ b/oyoyo/helpers.py
@@ -111,7 +111,7 @@ def _addNumerics():
cli.send(cmd_num, *args)
return f
m = sys.modules[__name__]
- for num, name in ircevents.numeric_events.iteritems():
+ for num, name in ircevents.numeric_events.items():
setattr(m, name, numericcmd(num, name))
_addNumerics()
diff --git a/oyoyo/ircevents.py b/oyoyo/ircevents.py
index 6d8969b..11a8583 100644
--- a/oyoyo/ircevents.py
+++ b/oyoyo/ircevents.py
@@ -206,5 +206,5 @@ protocol_events = [
"pong",
]
-all_events = generated_events + protocol_events + numeric_events.values()
+all_events = generated_events + protocol_events + list(numeric_events.values())
diff --git a/oyoyo/services.py b/oyoyo/services.py
index 9183beb..751a787 100644
--- a/oyoyo/services.py
+++ b/oyoyo/services.py
@@ -1,5 +1,5 @@
import sys
-from helpers import msg
+from .helpers import msg
# NickServ basic functions
_nickservfuncs = (
@@ -103,7 +103,7 @@ def _addServ(serv, funcs, prefix=""):
if prefix:
cmd_name = prefix.upper() + " " + cmd_name
def f(cli, *args):
- print cmd_name, " ".join(args)
+ print(cmd_name, " ".join(args))
#cli.send(cmd_name, serv.name, *args)
return f
for t in funcs:
diff --git a/parsetools.py b/parsetools.py
index 25bf3f9..509dedb 100644
--- a/parsetools.py
+++ b/parsetools.py
@@ -4,7 +4,7 @@ import ostools
import collections
from copy import copy
from datetime import timedelta
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
from generic import mysteryTime
from quirks import ScriptQuirks
@@ -17,6 +17,12 @@ import pnc.lexercon as lexercon
# I'll clean up the things that are no longer needed once the transition is
# actually finished.
+try:
+ QString = unicode
+except NameError:
+ # Python 3
+ QString = str
+
_ctag_begin = re.compile(r'(?i)')
_gtag_begin = re.compile(r'(?i)')
_ctag_end = re.compile(r'(?i)')
@@ -36,7 +42,7 @@ quirkloader = ScriptQuirks()
quirkloader.add(PythonQuirks())
quirkloader.add(LuaQuirks())
quirkloader.loadAll()
-print quirkloader.funcre()
+print(quirkloader.funcre())
_functionre = re.compile(r"%s" % quirkloader.funcre())
_groupre = re.compile(r"\\([0-9]+)")
@@ -51,7 +57,7 @@ def lexer(string, objlist):
for (oType, regexp) in objlist:
newstringlist = []
for (stri, s) in enumerate(stringlist):
- if type(s) not in [str, unicode]:
+ if type(s) not in [str, str]:
newstringlist.append(s)
continue
lasti = 0
@@ -220,7 +226,7 @@ kxpclexer = lexercon.Pesterchum()
def kxlexMsg(string):
# Do a bit of sanitization.
- msg = unicode(string)
+ msg = str(string)
# TODO: Let people paste line-by-line normally. Maybe have a mass-paste
# right-click option?
msg = msg.replace('\n', ' ').replace('\r', ' ')
@@ -247,9 +253,9 @@ def lexMessage(string):
(smiley, _smilere),
(honker, _honk)]
- string = unicode(string)
+ string = str(string)
string = string.replace("\n", " ").replace("\r", " ")
- lexed = lexer(unicode(string), lexlist)
+ lexed = lexer(str(string), lexlist)
balanced = []
beginc = 0
@@ -271,7 +277,7 @@ def lexMessage(string):
balanced.append(colorEnd(""))
if len(balanced) == 0:
balanced.append("")
- if type(balanced[len(balanced)-1]) not in [str, unicode]:
+ if type(balanced[len(balanced)-1]) not in [str, str]:
balanced.append("")
return balanced
@@ -279,12 +285,12 @@ def convertTags(lexed, format="html"):
if format not in ["html", "bbcode", "ctag", "text"]:
raise ValueError("Color format not recognized")
- if type(lexed) in [str, unicode]:
+ if type(lexed) in [str, str]:
lexed = lexMessage(lexed)
escaped = ""
firststr = True
for (i, o) in enumerate(lexed):
- if type(o) in [str, unicode]:
+ if type(o) in [str, str]:
if format == "html":
escaped += o.replace("&", "&").replace(">", ">").replace("<","<")
else:
@@ -392,7 +398,7 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False):
while len(lexed) > 0:
rounds += 1
if debug:
- print "[Starting round {}...]".format(rounds)
+ print("[Starting round {}...]".format(rounds))
msg = lexed.popleft()
msglen = 0
is_text = False
@@ -433,9 +439,9 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False):
# instead?
subround += 1
if debug:
- print "[Splitting round {}-{}...]".format(
+ print("[Splitting round {}-{}...]".format(
rounds, subround
- )
+ ))
point = msg.rfind(' ', 0, lenl)
if point < 0:
# No spaces to break on...ugh. Break at the last space
@@ -448,12 +454,12 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False):
# Remove what we just added.
msg = msg[point:]
if debug:
- print "msg = {!r}".format(msg)
+ print("msg = {!r}".format(msg))
else:
# Catch the remainder.
stack.append(msg)
if debug:
- print "msg caught; stack = {!r}".format(stack)
+ print("msg caught; stack = {!r}".format(stack))
# Done processing. Pluck out the first portion so we can
# continue processing, clean it up a bit, then add the rest to
# our waiting list.
@@ -494,16 +500,16 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False):
cte = lexercon.CTagEnd("", fmt, None)
working.extend([cte] * len(open_ctags))
if debug:
- print "\tRound {0} linebreak: Added {1} closing ctags".format(
+ print("\tRound {0} linebreak: Added {1} closing ctags".format(
rounds, len(open_ctags)
- )
+ ))
# Run it through the lexer again to render it.
- working = u''.join(kxpclexer.list_convert(working))
+ working = ''.join(kxpclexer.list_convert(working))
if debug:
- print "\tRound {0} add: len == {1} (of {2})".format(
+ print("\tRound {0} add: len == {1} (of {2})".format(
rounds, len(working), maxlen
- )
+ ))
# Now that it's done the work for us, append and resume.
output.append(working)
@@ -518,7 +524,7 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False):
# We have more to go.
# Reset working, starting it with the unclosed ctags.
if debug:
- print "\tRound {0}: More to lex".format(rounds)
+ print("\tRound {0}: More to lex".format(rounds))
working = open_ctags[:]
# Calculate the length of the starting tags, add it before
# anything else.
@@ -533,7 +539,7 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False):
if debug or True:
# This probably shouldn't happen, and if it does, I want to
# know if it *works* properly.
- print "\tRound {0}: No more to lex".format(rounds)
+ print("\tRound {0}: No more to lex".format(rounds))
# Clean up, just in case.
working = []
open_ctags = []
@@ -582,8 +588,8 @@ def kxsplitMsg(lexed, fmt="pchum", maxlen=None, debug=False):
working = kxpclexer.list_convert(working)
if len(working) > 0:
if debug:
- print "Adding end trails: {!r}".format(working)
- working = u''.join(working)
+ print("Adding end trails: {!r}".format(working))
+ working = ''.join(working)
output.append(working)
# We're...done?
@@ -596,7 +602,7 @@ def splitMessage(msg, format="ctag"):
# split long text lines
buf = []
for o in msg:
- if type(o) in [str, unicode] and len(o) > 200:
+ if type(o) in [str, str] and len(o) > 200:
# Split with a step of 200. I.e., cut long segments into chunks of
# 200 characters.
# I'm...not sure why this is done. I'll probably factor it out
@@ -614,7 +620,7 @@ def splitMessage(msg, format="ctag"):
cbegintags = []
# This is the final result.
output = []
- print repr(msg)
+ print(repr(msg))
for o in msg:
oldctag = None
# Add to the working segment.
@@ -687,9 +693,7 @@ def _is_ooc(msg, strict=True):
# We have a match....
ooc1, ooc2 = oocDetected.group(1, 2)
# Make sure the appropriate braces are used.
- mbraces = map(
- lambda br: ooc1 == br[0] and ooc2 == br[1],
- braces)
+ mbraces = [ooc1 == br[0] and ooc2 == br[1] for br in braces]
if any(mbraces):
# If any of those passes matched, we're good to go; it's OOC.
return True
@@ -711,7 +715,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
if text is None:
# Fetch the raw text from the input box.
text = ctx.textInput.text()
- text = unicode(ctx.textInput.text())
+ text = str(ctx.textInput.text())
# Preprocessing stuff.
msg = text.strip()
@@ -731,7 +735,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
# Determine if the line actually *is* OOC.
if is_ooc and not oocDetected:
# If we're supposed to be OOC, apply it artificially.
- msg = u"(( {} ))".format(msg)
+ msg = "(( {} ))".format(msg)
# Also, quirk stuff.
should_quirk = ctx.applyquirks
else:
@@ -764,7 +768,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
except Exception as err:
# Tell the user we couldn't do quirk things.
# TODO: Include the actual error...and the quirk it came from?
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setText("Whoa there! There seems to be a problem.")
err_info = "A quirk seems to be having a problem. (Error: {!s})"
err_info = err_info.format(err)
@@ -776,9 +780,9 @@ def kxhandleInput(ctx, text=None, flavor=None):
try:
# Turns out that Windows consoles can't handle unicode, heh...who'da
# thunk. We have to repr() this, as such.
- print repr(msg)
+ print(repr(msg))
except Exception as err:
- print "(Couldn't print processed message: {!s})".format(err)
+ print("(Couldn't print processed message: {!s})".format(err))
# karxi: We have a list...but I'm not sure if we ever get anything else, so
# best to play it safe. I may remove this during later refactoring.
@@ -790,26 +794,23 @@ def kxhandleInput(ctx, text=None, flavor=None):
# an object type I provided - just so I could pluck them out
# later.
msg[i] = m.convert(format="ctag")
- msg = u''.join(msg)
+ msg = ''.join(msg)
# Quirks have been applied. Lex the messages (finally).
msg = kxlexMsg(msg)
# Debug output.
try:
- print repr(msg)
+ print(repr(msg))
except Exception as err:
- print "(Couldn't print lexed message: {!s})".format(err)
+ print("(Couldn't print lexed message: {!s})".format(err))
# Remove coloring if this is a /me!
if is_action:
# Filter out formatting specifiers (just ctags, at the moment).
- msg = filter(
- lambda m: not isinstance(m,
+ msg = [m for m in msg if not isinstance(m,
(lexercon.CTag, lexercon.CTagEnd)
- ),
- msg
- )
+ )]
# We'll also add /me to the beginning of any new messages, later.
# Put what's necessary in before splitting.
@@ -850,7 +851,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
# if ceased, rebegin
if hasattr(ctx, 'chumopen') and not ctx.chumopen:
ctx.mainwindow.newConvoStarted.emit(
- QtCore.QString(ctx.title()), True
+ QString(ctx.title()), True
)
ctx.setChumOpen(True)
@@ -859,7 +860,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
# If we're working with an action and we split, it should have /mes.
if is_action and i > 0:
# Add them post-split.
- lm = u"/me " + lm
+ lm = "/me " + lm
# NOTE: No reason to reassign for now, but...why not?
lexmsgs[i] = lm
@@ -876,11 +877,11 @@ def kxhandleInput(ctx, text=None, flavor=None):
# We fetched the information outside of the loop, so just
# construct the messages.
- clientMsg = u"{2}{3}{4}: {0}".format(
+ clientMsg = "{2}{3}{4}: {0}".format(
clientMsg, colorcmd, grammar.pcf, initials, grammar.number
)
# Not sure if this needs a space at the end...?
- serverMsg = u"{2}: {0}".format(
+ serverMsg = "{2}: {0}".format(
serverMsg, colorcmd, initials)
ctx.addMessage(clientMsg, True)
@@ -984,7 +985,7 @@ def parseRegexpFunctions(to):
backr = _groupre.search(mo.group())
if backr is not None:
current.append(backreference(backr.group(1)))
- elif mo.group()[:-1] in functiondict.keys():
+ elif mo.group()[:-1] in list(functiondict.keys()):
p = parseLeaf(functiondict[mo.group()[:-1]], current)
current.append(p)
current = p
@@ -1001,7 +1002,7 @@ def parseRegexpFunctions(to):
def img2smiley(string):
- string = unicode(string)
+ string = str(string)
def imagerep(mo):
return reverse_smiley[mo.group(1)]
string = re.sub(r'', imagerep, string)
@@ -1082,8 +1083,8 @@ if ostools.isOSXBundle():
-reverse_smiley = dict((v,k) for k, v in smiledict.iteritems())
-_smilere = re.compile("|".join(smiledict.keys()))
+reverse_smiley = dict((v,k) for k, v in smiledict.items())
+_smilere = re.compile("|".join(list(smiledict.keys())))
class ThemeException(Exception):
def __init__(self, value):
diff --git a/pesterchum b/pesterchum
deleted file mode 100755
index a206116..0000000
--- a/pesterchum
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-cd `dirname $0`
-python2 pesterchum.py $@
diff --git a/pesterchum-update-from3.14.nsi b/pesterchum-update-from3.14.nsi
deleted file mode 100644
index 1dac4b0..0000000
--- a/pesterchum-update-from3.14.nsi
+++ /dev/null
@@ -1,104 +0,0 @@
-
-; The name of the installer
-Name "PESTERCHUM3.14 to 3.41"
-
-; The file to write
-OutFile "pesterchum3.14to3.41.exe"
-
-RequestExecutionLevel admin
-
-Page components
-Page instfiles
-
-UninstPage uninstConfirm
-UninstPage instfiles
-
-; The stuff to install
-Section "Pesterchum"
-
- SectionIn RO
-
- ReadRegStr $INSTDIR HKLM "SOFTWARE\Pesterchum" "Install_Dir"
-
- StrCmp $INSTDIR "" error
-
- ; Set output path to the installation directory.
- SetOutPath $INSTDIR
-
- ; Check and see if this is really 3.14
- IfFileExists library.zip 0 error
-
- ClearErrors
- CreateDirectory $TEMP\pesterchum_backup
- IfErrors backuperror 0
- CopyFiles $INSTDIR\pesterchum.js $TEMP\pesterchum_backup
- CopyFiles $INSTDIR\profiles $TEMP\pesterchum_backup
- CopyFiles $INSTDIR\logs $TEMP\pesterchum_backup
- IfErrors cantcopy 0
-
- Delete $INSTDIR\uninstall.exe
-
- ; Remove shortcuts, if any
- Delete "$SMPROGRAMS\Pesterchum\*.*"
-
- ; Remove directories used
- RMDir "$SMPROGRAMS\Pesterchum"
- RMDir /r "$INSTDIR"
-
- ; Put file there
- File /r *.*
- Rename $INSTDIR\README.mkdn $INSTDIR\readme.txt
- Rename $INSTDIR\CHANGELOG.mkdn $INSTDIR\changelog.txt
-
- ; Copy backup files
- ClearErrors
- CopyFiles $TEMP\pesterchum_backup\*.* $INSTDIR
- IfErrors brokeinstall 0
- RMDIR /r "$TEMP\pesterchum_backup"
-
- WriteUninstaller "uninstall.exe"
-
- CreateDirectory "$SMPROGRAMS\Pesterchum"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Pesterchum.lnk" "$INSTDIR\pesterchum.exe"
- CreateShortcut "$DESKTOP\Pesterchum.lnk" "$INSTDIR\pesterchum.exe"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Readme.lnk" "$INSTDIR\readme.txt"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Uninstall.lnk" "$INSTDIR\uninstall.exe"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Logs.lnk" "$LOCALAPPDATA\pesterchum\logs"
-
- Goto done
-
- error:
- MessageBox MB_OK "Pesterchum 3.14 (or 3.41 beta) not found on this machine!"
- Goto done
- backuperror:
- IfFileExists $TEMP\pesterchum_backup brokeinstall cantmaketmp
- cantmaketmp:
- MessageBox MB_OK "Error! Can't make temporary directory (to save your files) for some raisin. Check your privileges?? i dunno tbqh, soryr *sorry"
- Goto done
- brokeinstall:
- MessageBox MB_OK "Broken install detected. Please copy the files in $TEMP\pesterchum_backup to some place safe and then delete that folder."
- Goto done
- cantcopy:
- MessageBox MB_OK "Can't seem to copy Pesterchum backup files to temp directory."
- Goto done
- done:
-
-SectionEnd
-
-Section "Uninstall"
-
- ; Remove registry keys
- DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pesterchum"
- DeleteRegKey HKLM SOFTWARE\Pesterchum
-
- ; Remove files and uninstaller
- Delete $INSTDIR\uninstall.exe
-
- ; Remove shortcuts, if any
- Delete "$SMPROGRAMS\Pesterchum\*.*"
-
- ; Remove directories used
- RMDir "$SMPROGRAMS\Pesterchum"
- RMDir /r "$INSTDIR"
-
-SectionEnd
\ No newline at end of file
diff --git a/pesterchum-update.nsi b/pesterchum-update.nsi
deleted file mode 100644
index 39a8294..0000000
--- a/pesterchum-update.nsi
+++ /dev/null
@@ -1,47 +0,0 @@
-
-; The name of the installer
-Name "PESTERCHUM3.41"
-
-; The file to write
-OutFile "pesterchum3.41.update.exe"
-
-RequestExecutionLevel admin
-
-Page components
-Page instfiles
-
-; The stuff to install
-Section "Pesterchum"
-
- SectionIn RO
-
- ReadRegStr $INSTDIR HKLM "SOFTWARE\Pesterchum" "Install_Dir"
-
- StrCmp $INSTDIR "" error
-
- ; Set output path to the installation directory.
- SetOutPath $INSTDIR
-
- ; Put file there
- File /r themes
- File /r smilies
- File /r quirks
- File README.mkdn
- File CHANGELOG.mkdn
- File version.py
- File pesterchum.exe
- File pesterchum.exe.manifest
-
-
- Rename $INSTDIR\README.mkdn $INSTDIR\readme.txt
- Rename $INSTDIR\CHANGELOG.mkdn $INSTDIR\changelog.txt
-
- Delete "$SMPROGRAMS\Pesterchum\Pesterchum.lnk"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Pesterchum.lnk" "$INSTDIR\pesterchum.exe"
-
- Goto done
- error:
- MessageBox MB_OK "Pesterchum not found on this machine!"
- done:
-
-SectionEnd
diff --git a/pesterchum.cfg b/pesterchum.cfg
deleted file mode 100644
index 7763cfe..0000000
--- a/pesterchum.cfg
+++ /dev/null
@@ -1,32 +0,0 @@
-#PESTERCHUM CONFIG V2.5
-debug: false
-notify: false
-tray: true
-claf: false
-handle: elegantDiversion
-mood: 0
-color: -15420406
-skin: trollian
-#CHUMROLL BEGIN
-handle: adiosToreador
-color: -5614336
-handle: arachnidsGrip
-color: -6206085
-#CHUMROLL END
-#QUIRKS BEGIN
-search: [p|P]
-replace: 9
-search: [Z|z]
-replace: 2
-search: [S|s]
-replace: 5
-search: [O|o]
-replace: 0
-search: [L|l]
-replace: |
-prefix: ==>
-suffix:
-#QUIRKS END
-#TROLLS BEGIN
-#TROLLS END
-#EOF
diff --git a/pesterchum.ico b/pesterchum.ico
deleted file mode 100644
index 5b8fa1c..0000000
Binary files a/pesterchum.ico and /dev/null differ
diff --git a/pesterchum.nsi b/pesterchum.nsi
deleted file mode 100644
index d8992a9..0000000
--- a/pesterchum.nsi
+++ /dev/null
@@ -1,69 +0,0 @@
-
-; The name of the installer
-Name "PESTERCHUM3.41"
-
-; The file to write
-OutFile "pesterchum3.41.exe"
-
-InstallDir C:\Pesterchum
-
-InstallDirRegKey HKLM "Software\Pesterchum" "Install_Dir"
-RequestExecutionLevel admin
-
-Page components
-Page directory
-Page instfiles
-
-UninstPage uninstConfirm
-UninstPage instfiles
-
-
-; The stuff to install
-Section "Pesterchum"
-
- SectionIn RO
-
- ; Set output path to the installation directory.
- SetOutPath $INSTDIR
-
- ; Put file there
- File /r *.*
- Rename $INSTDIR\README.mkdn $INSTDIR\readme.txt
- Rename $INSTDIR\CHANGELOG.mkdn $INSTDIR\changelog.txt
-
- ; Write the installation path into the registry
- WriteRegStr HKLM SOFTWARE\Pesterchum "Install_Dir" "$INSTDIR"
-
- ; Write the uninstall keys for Windows
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pesterchum" "DisplayName" "PESTERCHUM"
- WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pesterchum" "UninstallString" '"$INSTDIR\uninstall.exe"'
- WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pesterchum" "NoModify" 1
- WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pesterchum" "NoRepair" 1
- WriteUninstaller "uninstall.exe"
-
- CreateDirectory "$SMPROGRAMS\Pesterchum"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Pesterchum.lnk" "$INSTDIR\pesterchum.exe"
- CreateShortcut "$DESKTOP\Pesterchum.lnk" "$INSTDIR\pesterchum.exe"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Readme.lnk" "$INSTDIR\readme.txt"
- CreateShortcut "$SMPROGRAMS\Pesterchum\Uninstall.lnk" "$INSTDIR\uninstall.exe"
-
- CreateShortcut "$SMPROGRAMS\Pesterchum\Logs.lnk" "$LOCALAPPDATA\pesterchum\logs"
-SectionEnd
-
-Section "Uninstall"
-
- ; Remove registry keys
- DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Pesterchum"
- DeleteRegKey HKLM SOFTWARE\Pesterchum
-
- ; Remove files and uninstaller
- Delete $INSTDIR\uninstall.exe
-
- ; Remove shortcuts, if any
- Delete "$SMPROGRAMS\Pesterchum\*.*"
-
- ; Remove directories used
- RMDir "$SMPROGRAMS\Pesterchum"
- RMDir /r "$INSTDIR"
-
-SectionEnd
diff --git a/pesterchum.py b/pesterchum.py
index e1d709a..36bf868 100644
--- a/pesterchum.py
+++ b/pesterchum.py
@@ -1,5 +1,11 @@
# pesterchum
import os, shutil, sys, getopt
+try:
+ QString = unicode
+except NameError:
+ # Python 3
+ QString = str
+
if os.path.dirname(sys.argv[0]):
os.chdir(os.path.dirname(sys.argv[0]))
import logging
@@ -12,7 +18,7 @@ from datetime import *
import random
import re
from time import time
-import threading, Queue
+import threading, queue
try:
import json
except:
@@ -39,13 +45,13 @@ else:
reqmissing = []
optmissing = []
try:
- from PyQt4 import QtGui, QtCore
+ from PyQt5 import QtCore, QtGui, QtMultimedia, QtWidgets
except ImportError as e:
module = str(e)
if module.startswith("No module named ") or \
module.startswith("cannot import name "):
reqmissing.append(module[module.rfind(" ")+1:])
- else: print e
+ else: print(e)
del module
try:
import pygame
@@ -53,12 +59,13 @@ except ImportError as e:
pygame = None
module = str(e)
if module[:16] == "No module named ": optmissing.append(module[16:])
- else: print e
+ else: print(e)
del module
if reqmissing:
- print "ERROR: The following modules are required for Pesterchum to run and are missing on your system:"
- for m in reqmissing: print "* "+m
- exit()
+ print("ERROR: The following modules are required for Pesterchum to run and are missing on your system:")
+ for m in reqmissing: print("* "+m)
+ # False flag for some reason.
+ #exit()
vnum = QtCore.qVersion()
major = int(vnum[:vnum.find(".")])
if vnum.find(".", vnum.find(".")+1) != -1:
@@ -66,8 +73,8 @@ if vnum.find(".", vnum.find(".")+1) != -1:
else:
minor = int(vnum[vnum.find(".")+1:])
if not ((major > 4) or (major == 4 and minor >= 6)):
- print "ERROR: Pesterchum requires Qt version >= 4.6"
- print "You currently have version " + vnum + ". Please upgrade Qt."
+ print("ERROR: Pesterchum requires Qt version >= 4.6")
+ print("You currently have version " + vnum + ". Please upgrade Qt.")
exit()
import ostools
@@ -143,7 +150,7 @@ class waitingMessageHolder(object):
def __init__(self, mainwindow, **msgfuncs):
self.mainwindow = mainwindow
self.funcs = msgfuncs
- self.queue = msgfuncs.keys()
+ self.queue = list(msgfuncs.keys())
if len(self.queue) > 0:
self.mainwindow.updateSystemTray()
def waitingHandles(self):
@@ -159,7 +166,7 @@ class waitingMessageHolder(object):
if len(self.queue) == 0:
self.mainwindow.updateSystemTray()
def addMessage(self, handle, func):
- if not self.funcs.has_key(handle):
+ if handle not in self.funcs:
self.queue.append(handle)
self.funcs[handle] = func
if len(self.queue) > 0:
@@ -167,7 +174,7 @@ class waitingMessageHolder(object):
def __len__(self):
return len(self.queue)
-class chumListing(QtGui.QTreeWidgetItem):
+class chumListing(QtWidgets.QTreeWidgetItem):
def __init__(self, chum, window):
super(chumListing, self).__init__([chum.handle])
self.mainwindow = window
@@ -264,43 +271,34 @@ class chumArea(RightClickTree):
self.showAllChums()
if not self.mainwindow.config.showEmptyGroups():
self.hideEmptyGroups()
- self.groupMenu = QtGui.QMenu(self)
- self.canonMenu = QtGui.QMenu(self)
- self.optionsMenu = QtGui.QMenu(self)
- self.pester = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
- self.connect(self.pester, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('activateChum()'))
- self.removechum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/removechum"], self)
- self.connect(self.removechum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('removeChum()'))
- self.blockchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self)
- self.connect(self.blockchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('blockChum()'))
- self.logchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
- self.connect(self.logchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('openChumLogs()'))
- self.reportchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/report"], self)
- self.connect(self.reportchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('reportChum()'))
- self.findalts = QtGui.QAction("Find Alts", self)
- self.connect(self.findalts, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('findAlts()'))
- self.removegroup = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/removegroup"], self)
- self.connect(self.removegroup, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('removeGroup()'))
- self.renamegroup = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/renamegroup"], self)
- self.connect(self.renamegroup, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('renameGroup()'))
- self.notes = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/notes"], self)
- self.connect(self.notes, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('editNotes()'))
+ self.groupMenu = QtWidgets.QMenu(self)
+ self.canonMenu = QtWidgets.QMenu(self)
+ self.optionsMenu = QtWidgets.QMenu(self)
+ self.pester = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self)
+ self.pester.triggered.connect(self.activateChum)
+ self.removechum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/removechum"], self)
+ self.removechum.triggered.connect(self.removeChum)
+ self.blockchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self)
+ self.blockchum.triggered.connect(self.blockChum)
+ self.logchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/viewlog"], self)
+ self.logchum.triggered.connect(self.openChumLogs)
+ self.reportchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/report"], self)
+ self.reportchum.triggered.connect(self.reportChum)
+ self.findalts = QtWidgets.QAction("Find Alts", self)
+ self.findalts.triggered.connect(self.findAlts)
+ self.removegroup = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/removegroup"], self)
+ self.removegroup.triggered.connect(self.removeGroup)
+ self.renamegroup = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/renamegroup"], self)
+ self.renamegroup.triggered.connect(self.renameGroup)
+ self.notes = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/notes"], self)
+ self.notes.triggered.connect(self.editNotes)
self.optionsMenu.addAction(self.pester)
self.optionsMenu.addAction(self.logchum)
self.optionsMenu.addAction(self.notes)
self.optionsMenu.addAction(self.blockchum)
self.optionsMenu.addAction(self.removechum)
- self.moveMenu = QtGui.QMenu(self.mainwindow.theme["main/menus/rclickchumlist/movechum"], self)
+ self.moveMenu = QtWidgets.QMenu(self.mainwindow.theme["main/menus/rclickchumlist/movechum"], self)
self.optionsMenu.addMenu(self.moveMenu)
self.optionsMenu.addAction(self.reportchum)
self.moveGroupMenu()
@@ -324,22 +322,21 @@ class chumArea(RightClickTree):
self.setDropIndicatorShown(True)
self.setIndentation(4)
self.setDragEnabled(True)
- self.setDragDropMode(QtGui.QAbstractItemView.InternalMove)
+ self.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove)
self.setAnimated(True)
self.setRootIsDecorated(False)
- self.connect(self, QtCore.SIGNAL('itemDoubleClicked(QTreeWidgetItem *, int)'),
- self, QtCore.SLOT('expandGroup()'))
+ self.itemDoubleClicked[QTreeWidgetItem, int].connect(self.expandGroup)
@QtCore.pyqtSlot()
def beginNotify(self):
- print "BEGIN NOTIFY"
+ print("BEGIN NOTIFY")
self.notify = True
def getOptionsMenu(self):
if not self.currentItem():
return None
- text = unicode(self.currentItem().text(0))
+ text = str(self.currentItem().text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
if text == "Chums":
@@ -385,13 +382,13 @@ class chumArea(RightClickTree):
if thisitem.rfind(" (") != -1:
thisitem = thisitem[0:thisitem.rfind(" (")]
# Drop item is a group
- thisitem = unicode(event.source().currentItem().text(0))
+ thisitem = str(event.source().currentItem().text(0))
if thisitem.rfind(" (") != -1:
thisitem = thisitem[0:thisitem.rfind(" (")]
if thisitem == "Chums" or thisitem in self.groups:
droppos = self.itemAt(event.pos())
if not droppos: return
- droppos = unicode(droppos.text(0))
+ droppos = str(droppos.text(0))
if droppos.rfind(" ") != -1:
droppos = droppos[0:droppos.rfind(" ")]
if droppos == "Chums" or droppos in self.groups:
@@ -404,16 +401,16 @@ class chumArea(RightClickTree):
gTemp = []
for i in range(self.topLevelItemCount()):
- text = unicode(self.topLevelItem(i).text(0))
+ text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
- gTemp.append([unicode(text), self.topLevelItem(i).isExpanded()])
+ gTemp.append([str(text), self.topLevelItem(i).isExpanded()])
self.mainwindow.config.saveGroups(gTemp)
# Drop item is a chum
else:
item = self.itemAt(event.pos())
if item:
- text = unicode(item.text(0))
+ text = str(item.text(0))
# Figure out which group to drop into
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
@@ -421,7 +418,7 @@ class chumArea(RightClickTree):
group = text
gitem = item
else:
- ptext = unicode(item.parent().text(0))
+ ptext = str(item.parent().text(0))
if ptext.rfind(" ") != -1:
ptext = ptext[0:ptext.rfind(" ")]
group = ptext
@@ -444,7 +441,7 @@ class chumArea(RightClickTree):
if chums.index(thisitem) < inPos:
inPos -= 1
chums.remove(thisitem)
- chums.insert(inPos, unicode(thisitem))
+ chums.insert(inPos, str(thisitem))
self.mainwindow.config.setChums(chums)
else:
@@ -456,14 +453,14 @@ class chumArea(RightClickTree):
currentGroup = self.currentItem()
if currentGroup:
if currentGroup.parent():
- text = unicode(currentGroup.parent().text(0))
+ text = str(currentGroup.parent().text(0))
else:
- text = unicode(currentGroup.text(0))
+ text = str(currentGroup.text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
currentGroup = text
self.moveMenu.clear()
- actGroup = QtGui.QActionGroup(self)
+ actGroup = QtWidgets.QActionGroup(self)
groups = self.groups[:]
for gtext in groups:
@@ -471,8 +468,7 @@ class chumArea(RightClickTree):
continue
movegroup = self.moveMenu.addAction(gtext)
actGroup.addAction(movegroup)
- self.connect(actGroup, QtCore.SIGNAL('triggered(QAction *)'),
- self, QtCore.SLOT('moveToGroup(QAction *)'))
+ actGroup.triggered[QAction].connect(self.moveToGroup)
def addChum(self, chum):
if len([c for c in self.chums if c.handle == chum.handle]) != 0:
@@ -510,20 +506,20 @@ class chumArea(RightClickTree):
def showAllGroups(self, first=False):
if first:
for i,g in enumerate(self.groups):
- child_1 = QtGui.QTreeWidgetItem(["%s" % (g)])
+ child_1 = QtWidgets.QTreeWidgetItem(["%s" % (g)])
self.addTopLevelItem(child_1)
if self.openGroups[i]:
child_1.setExpanded(True)
return
curgroups = []
for i in range(self.topLevelItemCount()):
- text = unicode(self.topLevelItem(i).text(0))
+ text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
curgroups.append(text)
for i,g in enumerate(self.groups):
if g not in curgroups:
- child_1 = QtGui.QTreeWidgetItem(["%s" % (g)])
+ child_1 = QtWidgets.QTreeWidgetItem(["%s" % (g)])
j = 0
for h in self.groups:
if h == g:
@@ -541,31 +537,31 @@ class chumArea(RightClickTree):
totals = {'Chums': 0}
online = {'Chums': 0}
for g in self.groups:
- totals[unicode(g)] = 0
- online[unicode(g)] = 0
+ totals[str(g)] = 0
+ online[str(g)] = 0
for c in self.chums:
yes = c.mood.name() != "offline"
if c.group == "Chums":
- totals[unicode(c.group)] = totals[unicode(c.group)]+1
+ totals[str(c.group)] = totals[str(c.group)]+1
if yes:
- online[unicode(c.group)] = online[unicode(c.group)]+1
+ online[str(c.group)] = online[str(c.group)]+1
elif c.group in totals:
- totals[unicode(c.group)] = totals[unicode(c.group)]+1
+ totals[str(c.group)] = totals[str(c.group)]+1
if yes:
- online[unicode(c.group)] = online[unicode(c.group)]+1
+ online[str(c.group)] = online[str(c.group)]+1
else:
totals["Chums"] = totals["Chums"]+1
if yes:
online["Chums"] = online["Chums"]+1
for i in range(self.topLevelItemCount()):
- text = unicode(self.topLevelItem(i).text(0))
+ text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
if text in online:
self.topLevelItem(i).setText(0, "%s (%i/%i)" % (text, online[text], totals[text]))
def hideOnlineNumbers(self):
for i in range(self.topLevelItemCount()):
- text = unicode(self.topLevelItem(i).text(0))
+ text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
self.topLevelItem(i).setText(0, "%s" % (text))
@@ -581,7 +577,7 @@ class chumArea(RightClickTree):
@QtCore.pyqtSlot()
def expandGroup(self):
item = self.currentItem()
- text = unicode(item.text(0))
+ text = str(item.text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
@@ -596,13 +592,13 @@ class chumArea(RightClickTree):
self.mainwindow.config.addGroup("Chums")
curgroups = []
for i in range(self.topLevelItemCount()):
- text = unicode(self.topLevelItem(i).text(0))
+ text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
curgroups.append(text)
if not self.findItems(chumLabel.handle, QtCore.Qt.MatchContains | QtCore.Qt.MatchRecursive):
if chumLabel.chum.group not in curgroups:
- child_1 = QtGui.QTreeWidgetItem(["%s" % (chumLabel.chum.group)])
+ child_1 = QtWidgets.QTreeWidgetItem(["%s" % (chumLabel.chum.group)])
i = 0
for g in self.groups:
if g == chumLabel.chum.group:
@@ -613,7 +609,7 @@ class chumArea(RightClickTree):
if self.openGroups[self.groups.index("%s" % (chumLabel.chum.group))]:
child_1.setExpanded(True)
for i in range(self.topLevelItemCount()):
- text = unicode(self.topLevelItem(i).text(0))
+ text = str(self.topLevelItem(i).text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
if text == chumLabel.chum.group:
@@ -632,7 +628,7 @@ class chumArea(RightClickTree):
bestname = ""
if fi > 0:
while not bestj:
- for j in xrange(self.topLevelItem(i).childCount()):
+ for j in range(self.topLevelItem(i).childCount()):
if chums[fi-c] == str(self.topLevelItem(i).child(j).text(0)):
bestj = j
bestname = chums[fi-c]
@@ -707,7 +703,7 @@ class chumArea(RightClickTree):
def initTheme(self, theme):
self.resize(*theme["main/chums/size"])
self.move(*theme["main/chums/loc"])
- if theme.has_key("main/chums/scrollbar"):
+ if "main/chums/scrollbar" in theme:
self.setStyleSheet("QListWidget { %s } QScrollBar { %s } QScrollBar::handle { %s } QScrollBar::add-line { %s } QScrollBar::sub-line { %s } QScrollBar:up-arrow { %s } QScrollBar:down-arrow { %s }" % (theme["main/chums/style"], theme["main/chums/scrollbar/style"], theme["main/chums/scrollbar/handle"], theme["main/chums/scrollbar/downarrow"], theme["main/chums/scrollbar/uparrow"], theme["main/chums/scrollbar/uarrowstyle"], theme["main/chums/scrollbar/darrowstyle"] ))
else:
self.setStyleSheet(theme["main/chums/style"])
@@ -799,8 +795,7 @@ class chumArea(RightClickTree):
return
currentChum = currentChum.text(0)
self.pesterlogviewer = PesterLogViewer(currentChum, self.mainwindow.config, self.mainwindow.theme, self.mainwindow)
- self.connect(self.pesterlogviewer, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('closeActiveLog()'))
+ self.pesterlogviewer.rejected.connect(self.closeActiveLog)
self.pesterlogviewer.show()
self.pesterlogviewer.raise_()
self.pesterlogviewer.activateWindow()
@@ -813,9 +808,9 @@ class chumArea(RightClickTree):
currentChum = self.currentItem()
if not currentChum:
return
- (notes, ok) = QtGui.QInputDialog.getText(self, "Notes", "Enter your notes...")
+ (notes, ok) = QtWidgets.QInputDialog.getText(self, "Notes", "Enter your notes...")
if ok:
- notes = unicode(notes)
+ notes = str(notes)
self.mainwindow.chumdb.setNotes(currentChum.handle, notes)
currentChum.setToolTip(0, "%s: %s" % (currentChum.handle, notes))
@QtCore.pyqtSlot()
@@ -823,13 +818,13 @@ class chumArea(RightClickTree):
if not hasattr(self, 'renamegroupdialog'):
self.renamegroupdialog = None
if not self.renamegroupdialog:
- (gname, ok) = QtGui.QInputDialog.getText(self, "Rename Group", "Enter a new name for the group:")
+ (gname, ok) = QtWidgets.QInputDialog.getText(self, "Rename Group", "Enter a new name for the group:")
if ok:
- gname = unicode(gname)
+ gname = str(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None:
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
ret = msgbox.exec_()
self.addgroupdialog = None
return
@@ -839,7 +834,7 @@ class chumArea(RightClickTree):
index = self.indexOfTopLevelItem(currentGroup)
if index != -1:
expanded = currentGroup.isExpanded()
- text = unicode(currentGroup.text(0))
+ text = str(currentGroup.text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
self.mainwindow.config.delGroup(text)
@@ -859,7 +854,7 @@ class chumArea(RightClickTree):
currentGroup = self.currentItem()
if not currentGroup:
return
- text = unicode(currentGroup.text(0))
+ text = str(currentGroup.text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
self.mainwindow.config.delGroup(text)
@@ -878,11 +873,11 @@ class chumArea(RightClickTree):
self.takeItem(chumLabel)
self.addItem(chumLabel)
self.takeTopLevelItem(i)
- @QtCore.pyqtSlot(QtGui.QAction)
+ @QtCore.pyqtSlot(QtWidgets.QAction)
def moveToGroup(self, item):
if not item:
return
- group = unicode(item.text())
+ group = str(item.text())
chumLabel = self.currentItem()
if not chumLabel:
return
@@ -891,19 +886,21 @@ class chumArea(RightClickTree):
self.takeItem(chumLabel)
self.addItem(chumLabel)
- removeChumSignal = QtCore.pyqtSignal(QtCore.QString)
- blockChumSignal = QtCore.pyqtSignal(QtCore.QString)
+ removeChumSignal = QtCore.pyqtSignal('QString')
+ blockChumSignal = QtCore.pyqtSignal('QString')
class trollSlum(chumArea):
+ unblockChumSignal = QtCore.pyqtSignal()
+
def __init__(self, trolls, mainwindow, parent=None):
#~super(trollSlum, self).__init__(parent)
# TODO: Rework inheritance here.
- QtGui.QTreeWidgetItem.__init__(self, parent)
+ QtWidgets.QTreeWidgetItem.__init__(self, parent)
self.mainwindow = mainwindow
theme = self.mainwindow.theme
self.setStyleSheet(theme["main/trollslum/chumroll/style"])
self.chums = trolls
- child_1 = QtGui.QTreeWidgetItem([""])
+ child_1 = QtWidgets.QTreeWidgetItem([""])
self.addTopLevelItem(child_1)
child_1.setExpanded(True)
for c in self.chums:
@@ -917,10 +914,9 @@ class trollSlum(chumArea):
self.setDropIndicatorShown(False)
self.setIndentation(0)
- self.optionsMenu = QtGui.QMenu(self)
- self.unblockchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self)
- self.connect(self.unblockchum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SIGNAL('unblockChumSignal()'))
+ self.optionsMenu = QtWidgets.QMenu(self)
+ self.unblockchum = QtWidgets.QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self)
+ self.unblockchum.triggered.connect(self.unblockChumSignal)
self.optionsMenu.addAction(self.unblockchum)
#self.sortItems()
@@ -940,30 +936,27 @@ class trollSlum(chumArea):
for c in chumlistings:
c.changeTheme(theme)
- unblockChumSignal = QtCore.pyqtSignal(QtCore.QString)
+ unblockChumSignal = QtCore.pyqtSignal('QString')
-class TrollSlumWindow(QtGui.QFrame):
+class TrollSlumWindow(QtWidgets.QFrame):
def __init__(self, trolls, mainwindow, parent=None):
super(TrollSlumWindow, self).__init__(parent)
self.mainwindow = mainwindow
theme = self.mainwindow.theme
- self.slumlabel = QtGui.QLabel(self)
+ self.slumlabel = QtWidgets.QLabel(self)
self.initTheme(theme)
self.trollslum = trollSlum(trolls, self.mainwindow, self)
- self.connect(self.trollslum, QtCore.SIGNAL('unblockChumSignal()'),
- self, QtCore.SLOT('removeCurrentTroll()'))
- layout_1 = QtGui.QHBoxLayout()
- self.addButton = QtGui.QPushButton("ADD", self)
- self.connect(self.addButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('addTrollWindow()'))
- self.removeButton = QtGui.QPushButton("REMOVE", self)
- self.connect(self.removeButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('removeCurrentTroll()'))
+ self.trollslum.unblockChumSignal.connect(self.removeCurrentTroll)
+ layout_1 = QtWidgets.QHBoxLayout()
+ self.addButton = QtWidgets.QPushButton("ADD", self)
+ self.addButton.clicked.connect(self.addTrollWindow)
+ self.removeButton = QtWidgets.QPushButton("REMOVE", self)
+ self.removeButton.clicked.connect(self.removeCurrentTroll)
layout_1.addWidget(self.addButton)
layout_1.addWidget(self.removeButton)
- layout_0 = QtGui.QVBoxLayout()
+ layout_0 = QtWidgets.QVBoxLayout()
layout_0.addWidget(self.slumlabel)
layout_0.addWidget(self.trollslum)
layout_0.addLayout(layout_1)
@@ -1002,13 +995,13 @@ class TrollSlumWindow(QtGui.QFrame):
self.addtrolldialog = None
if self.addtrolldialog:
return
- self.addtrolldialog = QtGui.QInputDialog(self)
+ self.addtrolldialog = QtWidgets.QInputDialog(self)
(handle, ok) = self.addtrolldialog.getText(self, "Add Troll", "Enter Troll Handle:")
if ok:
- handle = unicode(handle)
+ handle = str(handle)
if not (PesterProfile.checkLength(handle) and
PesterProfile.checkValid(handle)[0]):
- errormsg = QtGui.QErrorMessage(self)
+ errormsg = QtWidgets.QErrorMessage(self)
errormsg.showMessage("THIS IS NOT A VALID CHUMTAG!")
self.addchumdialog = None
return
@@ -1016,10 +1009,13 @@ class TrollSlumWindow(QtGui.QFrame):
self.blockChumSignal.emit(handle)
self.addtrolldialog = None
- blockChumSignal = QtCore.pyqtSignal(QtCore.QString)
- unblockChumSignal = QtCore.pyqtSignal(QtCore.QString)
+ blockChumSignal = QtCore.pyqtSignal('QString')
+ unblockChumSignal = QtCore.pyqtSignal('QString')
class PesterWindow(MovingWindow):
+ reconnectIRC = QtCore.pyqtSignal()
+ sendMessage = QtCore.pyqtSignal('QString', 'QString')
+
def __init__(self, options, parent=None, app=None):
super(PesterWindow, self).__init__(parent,
(QtCore.Qt.CustomizeWindowHint |
@@ -1091,7 +1087,7 @@ class PesterWindow(MovingWindow):
themeChecker(self.theme)
except ThemeException as inst:
logging.error("Caught: " + inst.parameter)
- themeWarning = QtGui.QMessageBox(self)
+ themeWarning = QtWidgets.QMessageBox(self)
themeWarning.setText("Theme Error: %s" % inst)
themeWarning.exec_()
self.theme = pesterTheme("pesterchum")
@@ -1107,70 +1103,57 @@ class PesterWindow(MovingWindow):
self.move(100, 100)
- talk = QtGui.QAction(self.theme["main/menus/client/talk"], self)
+ talk = QtWidgets.QAction(self.theme["main/menus/client/talk"], self)
self.talk = talk
- self.connect(talk, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('openChat()'))
- logv = QtGui.QAction(self.theme["main/menus/client/logviewer"], self)
+ talk.triggered.connect(self.openChat)
+ logv = QtWidgets.QAction(self.theme["main/menus/client/logviewer"], self)
self.logv = logv
- self.connect(logv, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('openLogv()'))
- grps = QtGui.QAction(self.theme["main/menus/client/addgroup"], self)
+ logv.triggered.connect(self.openLogv)
+ grps = QtWidgets.QAction(self.theme["main/menus/client/addgroup"], self)
self.grps = grps
- self.connect(grps, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('addGroupWindow()'))
- self.rand = QtGui.QAction(self.theme["main/menus/client/randen"], self)
- self.connect(self.rand, QtCore.SIGNAL('triggered()'),
- self.randhandler, QtCore.SLOT('getEncounter()'))
- opts = QtGui.QAction(self.theme["main/menus/client/options"], self)
+ grps.triggered.connect(self.addGroupWindow)
+ self.rand = QtWidgets.QAction(self.theme["main/menus/client/randen"], self)
+ self.rand.triggered.connect(self.randhandler.getEncounter)
+ opts = QtWidgets.QAction(self.theme["main/menus/client/options"], self)
self.opts = opts
- self.connect(opts, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('openOpts()'))
- exitaction = QtGui.QAction(self.theme["main/menus/client/exit"], self)
+ opts.triggered.connect(self.openOpts)
+ exitaction = QtWidgets.QAction(self.theme["main/menus/client/exit"], self)
self.exitaction = exitaction
- self.connect(exitaction, QtCore.SIGNAL('triggered()'),
- self.app, QtCore.SLOT('quit()'))
- userlistaction = QtGui.QAction(self.theme["main/menus/client/userlist"], self)
+ exitaction.triggered.connect(self.app.quit)
+ userlistaction = QtWidgets.QAction(self.theme["main/menus/client/userlist"], self)
self.userlistaction = userlistaction
- self.connect(userlistaction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('showAllUsers()'))
- memoaction = QtGui.QAction(self.theme["main/menus/client/memos"], self)
+ userlistaction.triggered.connect(self.showAllUsers)
+ memoaction = QtWidgets.QAction(self.theme["main/menus/client/memos"], self)
self.memoaction = memoaction
- self.connect(memoaction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('showMemos()'))
- self.importaction = QtGui.QAction(self.theme["main/menus/client/import"], self)
- self.connect(self.importaction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('importExternalConfig()'))
- self.idleaction = QtGui.QAction(self.theme["main/menus/client/idle"], self)
+ memoaction.triggered.connect(self.showMemos)
+ self.importaction = QtWidgets.QAction(self.theme["main/menus/client/import"], self)
+ self.importaction.triggered.connect(self.importExternalConfig)
+ self.idleaction = QtWidgets.QAction(self.theme["main/menus/client/idle"], self)
self.idleaction.setCheckable(True)
- self.connect(self.idleaction, QtCore.SIGNAL('toggled(bool)'),
- self, QtCore.SLOT('toggleIdle(bool)'))
- self.reconnectAction = QtGui.QAction(self.theme["main/menus/client/reconnect"], self)
- self.connect(self.reconnectAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SIGNAL('reconnectIRC()'))
+ self.idleaction.toggled[bool].connect(self.toggleIdle)
+ self.reconnectAction = QtWidgets.QAction(self.theme["main/menus/client/reconnect"], self)
+ self.reconnectAction.triggered.connect(self.reconnectIRC)
- self.menu = QtGui.QMenuBar(self)
+ self.menu = QtWidgets.QMenuBar(self)
self.menu.setNativeMenuBar(False)
self.menu.setObjectName("mainmenu")
self.console = AttrDict(dict(
window = None,
- action = QtGui.QAction("Console", self),
+ action = QtWidgets.QAction("Console", self),
is_open = False
))
self.console.shortcuts = AttrDict(dict(
- conkey = QtGui.QShortcut(QtGui.QKeySequence("Ctrl+`"), self,
+ conkey = QtWidgets.QShortcut(QtGui.QKeySequence("Ctrl+`"), self,
context=QtCore.Qt.ApplicationShortcut),
- curwgt = QtGui.QShortcut(QtGui.QKeySequence("Ctrl+Alt+w"), self,
+ curwgt = QtWidgets.QShortcut(QtGui.QKeySequence("Ctrl+Alt+w"), self,
context=QtCore.Qt.ApplicationShortcut)
))
- self.connect(self.console.action, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('toggleConsole()'))
+ self.console.action.triggered.connect(self.toggleConsole)
# Make sure the shortcut works anywhere.
# karxi: There's something wrong with the inheritance scheme here.
#~self.console.shortcuts.conkey.setContext(QtCore.Qt.ApplicationShortcut)
- self.connect(self.console.shortcuts.conkey,
- QtCore.SIGNAL('activated()'), self, QtCore.SLOT('toggleConsole()'))
+ self.console.shortcuts.conkey.activated.connect(self.toggleConsole)
#~# Use new-style connections
#~self.console.shortcut.activated.connect(self.toggleConsole)
# Apparently those can crash sometimes...c'est la vie. Can't use 'em.
@@ -1196,24 +1179,20 @@ class PesterWindow(MovingWindow):
filemenu.addAction(self.reconnectAction)
filemenu.addAction(exitaction)
- changequirks = QtGui.QAction(self.theme["main/menus/profile/quirks"], self)
+ changequirks = QtWidgets.QAction(self.theme["main/menus/profile/quirks"], self)
self.changequirks = changequirks
- self.connect(changequirks, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('openQuirks()'))
- loadslum = QtGui.QAction(self.theme["main/menus/profile/block"], self)
+ changequirks.triggered.connect(self.openQuirks)
+ loadslum = QtWidgets.QAction(self.theme["main/menus/profile/block"], self)
self.loadslum = loadslum
- self.connect(loadslum, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('showTrollSlum()'))
+ loadslum.triggered.connect(self.showTrollSlum)
- changecoloraction = QtGui.QAction(self.theme["main/menus/profile/color"], self)
+ changecoloraction = QtWidgets.QAction(self.theme["main/menus/profile/color"], self)
self.changecoloraction = changecoloraction
- self.connect(changecoloraction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('changeMyColor()'))
+ changecoloraction.triggered.connect(self.changeMyColor)
- switch = QtGui.QAction(self.theme["main/menus/profile/switch"], self)
+ switch = QtWidgets.QAction(self.theme["main/menus/profile/switch"], self)
self.switch = switch
- self.connect(switch, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('switchProfile()'))
+ switch.triggered.connect(self.switchProfile)
profilemenu = self.menu.addMenu(self.theme["main/menus/profile/_name"])
self.profilemenu = profilemenu
@@ -1222,24 +1201,18 @@ class PesterWindow(MovingWindow):
profilemenu.addAction(changecoloraction)
profilemenu.addAction(switch)
- self.helpAction = QtGui.QAction(self.theme["main/menus/help/help"], self)
- self.connect(self.helpAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('launchHelp()'))
- self.botAction = QtGui.QAction(self.theme["main/menus/help/calsprite"], self)
- self.connect(self.botAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('loadCalsprite()'))
- self.nickServAction = QtGui.QAction(self.theme["main/menus/help/nickserv"], self)
- self.connect(self.nickServAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('loadNickServ()'))
- self.chanServAction = QtGui.QAction(self.theme["main/menus/help/chanserv"], self)
- self.connect(self.chanServAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('loadChanServ()'))
- self.aboutAction = QtGui.QAction(self.theme["main/menus/help/about"], self)
- self.connect(self.aboutAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('aboutPesterchum()'))
- self.reportBugAction = QtGui.QAction("REPORT BUG", self)
- self.connect(self.reportBugAction, QtCore.SIGNAL('triggered()'),
- self, QtCore.SLOT('reportBug()'))
+ self.helpAction = QtWidgets.QAction(self.theme["main/menus/help/help"], self)
+ self.helpAction.triggered.connect(self.launchHelp)
+ self.botAction = QtWidgets.QAction(self.theme["main/menus/help/calsprite"], self)
+ self.botAction.triggered.connect(self.loadCalsprite)
+ self.nickServAction = QtWidgets.QAction(self.theme["main/menus/help/nickserv"], self)
+ self.nickServAction.triggered.connect(self.loadNickServ)
+ self.chanServAction = QtWidgets.QAction(self.theme["main/menus/help/chanserv"], self)
+ self.chanServAction.triggered.connect(self.loadChanServ)
+ self.aboutAction = QtWidgets.QAction(self.theme["main/menus/help/about"], self)
+ self.aboutAction.triggered.connect(self.aboutPesterchum)
+ self.reportBugAction = QtWidgets.QAction("REPORT BUG", self)
+ self.reportBugAction.triggered.connect(self.reportBug)
helpmenu = self.menu.addMenu(self.theme["main/menus/help/_name"])
self.helpmenu = helpmenu
self.helpmenu.addAction(self.helpAction)
@@ -1259,45 +1232,31 @@ class PesterWindow(MovingWindow):
chums = [PesterProfile(c, chumdb=self.chumdb) for c in set(self.config.chums())]
self.chumList = chumArea(chums, self)
- self.connect(self.chumList,
- QtCore.SIGNAL('itemActivated(QTreeWidgetItem *, int)'),
- self,
- QtCore.SLOT('pesterSelectedChum()'))
- self.connect(self.chumList,
- QtCore.SIGNAL('removeChumSignal(QString)'),
- self,
- QtCore.SLOT('removeChum(QString)'))
- self.connect(self.chumList,
- QtCore.SIGNAL('blockChumSignal(QString)'),
- self,
- QtCore.SLOT('blockChum(QString)'))
+ self.chumList.itemActivated[QTreeWidgetItem, int].connect(self.pesterSelectedChum)
+ self.chumList.removeChumSignal['QString'].connect(self.removeChum)
+ self.chumList.blockChumSignal['QString'].connect(self.blockChum)
- self.addChumButton = QtGui.QPushButton(self.theme["main/addchum/text"], self)
+ self.addChumButton = QtWidgets.QPushButton(self.theme["main/addchum/text"], self)
self.addChumButton.setObjectName("addchumbtn")
- self.connect(self.addChumButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('addChumWindow()'))
- self.pesterButton = QtGui.QPushButton(self.theme["main/pester/text"], self)
+ self.addChumButton.clicked.connect(self.addChumWindow)
+ self.pesterButton = QtWidgets.QPushButton(self.theme["main/pester/text"], self)
self.pesterButton.setObjectName("newpesterbtn")
- self.connect(self.pesterButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('pesterSelectedChum()'))
- self.blockButton = QtGui.QPushButton(self.theme["main/block/text"], self)
+ self.pesterButton.clicked.connect(self.pesterSelectedChum)
+ self.blockButton = QtWidgets.QPushButton(self.theme["main/block/text"], self)
self.blockButton.setObjectName("blockbtn")
- self.connect(self.blockButton, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('blockSelectedChum()'))
+ self.blockButton.clicked.connect(self.blockSelectedChum)
- self.moodsLabel = QtGui.QLabel(self.theme["main/moodlabel/text"], self)
+ self.moodsLabel = QtWidgets.QLabel(self.theme["main/moodlabel/text"], self)
self.moodsLabel.setObjectName("moodlabel")
- self.mychumhandleLabel = QtGui.QLabel(self.theme["main/mychumhandle/label/text"], self)
+ self.mychumhandleLabel = QtWidgets.QLabel(self.theme["main/mychumhandle/label/text"], self)
self.mychumhandleLabel.setObjectName("myhandlelabel")
- self.mychumhandle = QtGui.QPushButton(self.profile().handle, self)
+ self.mychumhandle = QtWidgets.QPushButton(self.profile().handle, self)
self.mychumhandle.setFlat(True)
- self.connect(self.mychumhandle, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('switchProfile()'))
+ self.mychumhandle.clicked.connect(self.switchProfile)
- self.mychumcolor = QtGui.QPushButton(self)
- self.connect(self.mychumcolor, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('changeMyColor()'))
+ self.mychumcolor = QtWidgets.QPushButton(self)
+ self.mychumcolor.clicked.connect(self.changeMyColor)
self.initTheme(self.theme)
@@ -1319,8 +1278,7 @@ class PesterWindow(MovingWindow):
# idletime
time = 0
))
- self.connect(self.idler.timer, QtCore.SIGNAL('timeout()'),
- self, QtCore.SLOT('checkIdle()'))
+ self.idler.timer.timeout.connect(self.checkIdle)
self.idler.timer.start(1000)
if not self.config.defaultprofile():
@@ -1330,12 +1288,10 @@ class PesterWindow(MovingWindow):
if not ostools.isOSXLeopard():
QtCore.QTimer.singleShot(1000, self, QtCore.SLOT('mspacheck()'))
- self.connect(self, QtCore.SIGNAL('pcUpdate(QString, QString)'),
- self, QtCore.SLOT('updateMsg(QString, QString)'))
+ self.pcUpdate['QString', 'QString'].connect(self.updateMsg)
self.pingtimer = QtCore.QTimer()
- self.connect(self.pingtimer, QtCore.SIGNAL('timeout()'),
- self, QtCore.SLOT('checkPing()'))
+ self.pingtimer.timeout.connect(self.checkPing)
self.lastping = int(time())
self.pingtimer.start(1000*90)
@@ -1345,23 +1301,21 @@ class PesterWindow(MovingWindow):
if not ostools.isOSXLeopard():
checker = MSPAChecker(self)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def updateMsg(self, ver, url):
if not hasattr(self, 'updatemenu'):
self.updatemenu = None
if not self.updatemenu:
self.updatemenu = UpdatePesterchum(ver, url, self)
- self.connect(self.updatemenu, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('updatePC()'))
- self.connect(self.updatemenu, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('noUpdatePC()'))
+ self.updatemenu.accepted.connect(self.updatePC)
+ self.updatemenu.rejected.connect(self.noUpdatePC)
self.updatemenu.show()
self.updatemenu.raise_()
self.updatemenu.activateWindow()
@QtCore.pyqtSlot()
def updatePC(self):
- version.updateDownload(unicode(self.updatemenu.url))
+ version.updateDownload(str(self.updatemenu.url))
self.updatemenu = None
@QtCore.pyqtSlot()
def noUpdatePC(self):
@@ -1381,7 +1335,7 @@ class PesterWindow(MovingWindow):
if self.tabconvo:
self.tabconvo.close()
else:
- for c in self.convos.values():
+ for c in list(self.convos.values()):
c.close()
if self.tabmemo:
if not switch:
@@ -1390,7 +1344,7 @@ class PesterWindow(MovingWindow):
for m in self.tabmemo.convos:
self.tabmemo.convos[m].sendtime()
else:
- for m in self.memos.values():
+ for m in list(self.memos.values()):
if not switch:
m.close()
else:
@@ -1417,7 +1371,7 @@ class PesterWindow(MovingWindow):
return
# notify
if self.config.notifyOptions() & self.config.NEWMSG:
- if not self.convos.has_key(handle):
+ if handle not in self.convos:
t = self.tm.Toast("New Conversation", "From: %s" % handle)
t.show()
elif not self.config.notifyOptions() & self.config.NEWCONVO:
@@ -1435,7 +1389,7 @@ class PesterWindow(MovingWindow):
elif msg == "PESTERCHUM:UNBLOCK":
t = self.tm.Toast("Unblocked", handle)
t.show()
- if not self.convos.has_key(handle):
+ if handle not in self.convos:
if msg == "PESTERCHUM:CEASE": # ignore cease after we hang up
return
matchingChums = [c for c in self.chumList.chums if c.handle == handle]
@@ -1457,13 +1411,13 @@ class PesterWindow(MovingWindow):
else:
self.alarm.play()
def newMemoMsg(self, chan, handle, msg):
- if not self.memos.has_key(chan):
+ if chan not in self.memos:
# silently ignore in case we forgot to /part
# TODO: This is really bad practice. Fix it later.
return
memo = self.memos[chan]
- msg = unicode(msg)
- if not memo.times.has_key(handle):
+ msg = str(msg)
+ if handle not in memo.times:
# new chum! time current
newtime = timedelta(0)
time = TimeTracker(newtime)
@@ -1503,19 +1457,19 @@ class PesterWindow(MovingWindow):
def changeColor(self, handle, color):
# pesterconvo and chumlist
self.chumList.updateColor(handle, color)
- if self.convos.has_key(handle):
+ if handle in self.convos:
self.convos[handle].updateColor(color)
self.chumdb.setColor(handle, color)
def updateMood(self, handle, mood):
# updates OTHER chums' moods
oldmood = self.chumList.updateMood(handle, mood)
- if self.convos.has_key(handle):
+ if handle in self.convos:
self.convos[handle].updateMood(mood, old=oldmood)
if hasattr(self, 'trollslum') and self.trollslum:
self.trollslum.updateMood(handle, mood)
def newConversation(self, chum, initiated=True):
- if type(chum) in [str, unicode]:
+ if type(chum) in [str, str]:
matchingChums = [c for c in self.chumList.chums if c.handle == chum]
if len(matchingChums) > 0:
mood = matchingChums[0].mood
@@ -1525,7 +1479,7 @@ class PesterWindow(MovingWindow):
if len(matchingChums) == 0:
self.moodRequest.emit(chum)
- if self.convos.has_key(chum.handle):
+ if chum.handle in self.convos:
self.convos[chum.handle].showChat()
return
if self.config.tabs():
@@ -1535,28 +1489,24 @@ class PesterWindow(MovingWindow):
self.tabconvo.show()
else:
convoWindow = PesterConvo(chum, initiated, self)
- self.connect(convoWindow, QtCore.SIGNAL('messageSent(QString, QString)'),
- self, QtCore.SIGNAL('sendMessage(QString, QString)'))
- self.connect(convoWindow, QtCore.SIGNAL('windowClosed(QString)'),
- self, QtCore.SLOT('closeConvo(QString)'))
+ convoWindow.messageSent['QString', 'QString'].connect(self.sendMessage['QString', 'QString'])
+ convoWindow.windowClosed['QString'].connect(self.closeConvo)
self.convos[chum.handle] = convoWindow
- if unicode(chum.handle).upper() in BOTNAMES:
+ if str(chum.handle).upper() in BOTNAMES:
convoWindow.toggleQuirks(True)
convoWindow.quirksOff.setChecked(True)
- if unicode(chum.handle).upper() in CUSTOMBOTS:
- self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated)
+ if str(chum.handle).upper() in CUSTOMBOTS:
+ self.newConvoStarted.emit(QString(chum.handle), initiated)
else:
- self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated)
+ self.newConvoStarted.emit(QString(chum.handle), initiated)
convoWindow.show()
def createTabWindow(self):
self.tabconvo = PesterTabWindow(self)
- self.connect(self.tabconvo, QtCore.SIGNAL('windowClosed()'),
- self, QtCore.SLOT('tabsClosed()'))
+ self.tabconvo.windowClosed.connect(self.tabsClosed)
def createMemoTabWindow(self):
self.tabmemo = MemoTabWindow(self)
- self.connect(self.tabmemo, QtCore.SIGNAL('windowClosed()'),
- self, QtCore.SLOT('memoTabsClosed()'))
+ self.tabmemo.windowClosed.connect(self.memoTabsClosed)
@QtCore.pyqtSlot()
def toggleConsole(self):
@@ -1569,14 +1519,11 @@ class PesterWindow(MovingWindow):
logging.warning("Making a console....")
self.console.window = win = console.ConsoleWindow(parent=self)
logging.warning("Console made.")
- self.connect(win, QtCore.SIGNAL('windowClosed()'),
- self, QtCore.SLOT('consoleWindowClosed()'))
- self.connect(self.console.shortcuts.curwgt,
- QtCore.SIGNAL('activated()'),
- win, QtCore.SLOT('designateCurrentWidget()'))
+ win.windowClosed.connect(self.consoleWindowClosed)
+ self.console.shortcuts.curwgt.activated.connect(win.designateCurrentWidget)
if self.console.is_open:
- for wgt in win.findChildren(QtGui.QWidget):
+ for wgt in win.findChildren(QtWidgets.QWidget):
try:
focused = wgt.hasFocus()
except AttributeError:
@@ -1630,7 +1577,7 @@ class PesterWindow(MovingWindow):
def newMemo(self, channel, timestr, secret=False, invite=False):
if channel == "#pesterchum":
return
- if self.memos.has_key(channel):
+ if channel in self.memos:
self.memos[channel].showChat()
return
# do slider dialog then set
@@ -1642,19 +1589,12 @@ class PesterWindow(MovingWindow):
else:
memoWindow = PesterMemo(channel, timestr, self, None)
# connect signals
- self.connect(self, QtCore.SIGNAL('inviteOnlyChan(QString)'),
- memoWindow, QtCore.SLOT('closeInviteOnly(QString)'))
- self.connect(memoWindow, QtCore.SIGNAL('messageSent(QString, QString)'),
- self, QtCore.SIGNAL('sendMessage(QString, QString)'))
- self.connect(memoWindow, QtCore.SIGNAL('windowClosed(QString)'),
- self, QtCore.SLOT('closeMemo(QString)'))
- self.connect(self, QtCore.SIGNAL('namesUpdated(QString)'),
- memoWindow, QtCore.SLOT('namesUpdated(QString)'))
- self.connect(self, QtCore.SIGNAL('modesUpdated(QString, QString)'),
- memoWindow, QtCore.SLOT('modesUpdated(QString, QString)'))
- self.connect(self,
- QtCore.SIGNAL('userPresentSignal(QString, QString, QString)'),
- memoWindow, QtCore.SLOT('userPresentChange(QString, QString, QString)'))
+ self.inviteOnlyChan['QString'].connect(memoWindow.closeInviteOnly)
+ memoWindow.messageSent['QString', 'QString'].connect(self.sendMessage['QString', 'QString'])
+ memoWindow.windowClosed['QString'].connect(self.closeMemo)
+ self.namesUpdated['QString'].connect(memoWindow.namesUpdated)
+ self.modesUpdated['QString', 'QString'].connect(memoWindow.modesUpdated)
+ self.userPresentSignal['QString', 'QString', 'QString'].connect(memoWindow.userPresentChange)
# chat client send memo open
self.memos[channel] = memoWindow
self.joinChannel.emit(channel) # race condition?
@@ -1751,19 +1691,19 @@ class PesterWindow(MovingWindow):
if hasattr(self, 'moods'):
self.moods.removeButtons()
mood_list = theme["main/moods"]
- mood_list = [dict([(str(k),v) for (k,v) in d.iteritems()])
+ mood_list = [dict([(str(k),v) for (k,v) in d.items()])
for d in mood_list]
self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in mood_list])
self.moods.showButtons()
# chum
addChumStyle = "QPushButton { %s }" % (theme["main/addchum/style"])
- if theme.has_key("main/addchum/pressed"):
+ if "main/addchum/pressed" in theme:
addChumStyle += "QPushButton:pressed { %s }" % (theme["main/addchum/pressed"])
pesterButtonStyle = "QPushButton { %s }" % (theme["main/pester/style"])
- if theme.has_key("main/pester/pressed"):
+ if "main/pester/pressed" in theme:
pesterButtonStyle += "QPushButton:pressed { %s }" % (theme["main/pester/pressed"])
blockButtonStyle = "QPushButton { %s }" % (theme["main/block/style"])
- if theme.has_key("main/block/pressed"):
+ if "main/block/pressed" in theme:
pesterButtonStyle += "QPushButton:pressed { %s }" % (theme["main/block/pressed"])
self.addChumButton.setText(theme["main/addchum/text"])
self.addChumButton.resize(*theme["main/addchum/size"])
@@ -1788,12 +1728,12 @@ class PesterWindow(MovingWindow):
self.mychumcolor.resize(*theme["main/mychumhandle/colorswatch/size"])
self.mychumcolor.move(*theme["main/mychumhandle/colorswatch/loc"])
self.mychumcolor.setStyleSheet("background: %s" % (self.profile().colorhtml()))
- if self.theme.has_key("main/mychumhandle/currentMood"):
+ if "main/mychumhandle/currentMood" in self.theme:
moodicon = self.profile().mood.icon(theme)
if hasattr(self, 'currentMoodIcon') and self.currentMoodIcon:
self.currentMoodIcon.hide()
self.currentMoodIcon = None
- self.currentMoodIcon = QtGui.QLabel(self)
+ self.currentMoodIcon = QtWidgets.QLabel(self)
self.currentMoodIcon.setPixmap(moodicon.pixmap(moodicon.realsize()))
self.currentMoodIcon.move(*theme["main/mychumhandle/currentMood"])
self.currentMoodIcon.show()
@@ -1825,9 +1765,9 @@ class PesterWindow(MovingWindow):
if (pygame and pygame.mixer):
# We have pygame, so we may as well use it.
soundclass = pygame.mixer.Sound
- elif QtGui.QSound.isAvailable():
+ elif QtMultimedia.QSound.isAvailable():
# We don't have pygame; try to use QSound.
- soundclass = QtGui.QSound
+ soundclass = QtMultimedia.QSound
else:
# We don't have any options...just use fillers.
soundclass = NoneSound
@@ -1866,7 +1806,7 @@ class PesterWindow(MovingWindow):
if pygame and pygame.mixer and \
isinstance(sound, pygame.mixer.sound):
sound.set_volume(vol)
- elif not isinstance(sound, QtGui.QSound):
+ elif not isinstance(sound, QtMultimedia.QSound):
# We can't set a volume on those....
sound.setVolume(vol)
except Exception as err:
@@ -1889,7 +1829,7 @@ class PesterWindow(MovingWindow):
try:
themeChecker(theme)
except ThemeException as inst:
- themeWarning = QtGui.QMessageBox(self)
+ themeWarning = QtWidgets.QMessageBox(self)
themeWarning.setText("Theme Error: %s" % inst)
themeWarning.exec_()
theme = pesterTheme("pesterchum")
@@ -1906,9 +1846,9 @@ class PesterWindow(MovingWindow):
self.tabconvo.changeTheme(theme)
if self.tabmemo:
self.tabmemo.changeTheme(theme)
- for c in self.convos.values():
+ for c in list(self.convos.values()):
c.changeTheme(theme)
- for m in self.memos.values():
+ for m in list(self.memos.values()):
m.changeTheme(theme)
if hasattr(self, 'trollslum') and self.trollslum:
self.trollslum.changeTheme(theme)
@@ -1955,7 +1895,7 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def connected(self):
if self.loadingscreen:
- self.loadingscreen.done(QtGui.QDialog.Accepted)
+ self.loadingscreen.done(QtWidgets.QDialog.Accepted)
self.loadingscreen = None
self.doAutoIdentify()
@@ -1971,13 +1911,13 @@ class PesterWindow(MovingWindow):
def pesterSelectedChum(self):
curChum = self.chumList.currentItem()
if curChum:
- text = unicode(curChum.text(0))
+ text = str(curChum.text(0))
if text.rfind(" (") != -1:
text = text[0:text.rfind(" (")]
if text not in self.chumList.groups and \
text != "Chums":
self.newConversationWindow(curChum)
- @QtCore.pyqtSlot(QtGui.QListWidgetItem)
+ @QtCore.pyqtSlot(QtWidgets.QListWidgetItem)
def newConversationWindow(self, chumlisting):
# check chumdb
chum = chumlisting.chum
@@ -1985,9 +1925,9 @@ class PesterWindow(MovingWindow):
if color:
chum.color = color
self.newConversation(chum)
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def closeConvo(self, handle):
- h = unicode(handle)
+ h = str(handle)
try:
chum = self.convos[h].chum
except KeyError:
@@ -2001,9 +1941,9 @@ class PesterWindow(MovingWindow):
self.convoClosed.emit(handle)
self.chatlog.finish(h)
del self.convos[h]
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def closeMemo(self, channel):
- c = unicode(channel)
+ c = str(channel)
self.chatlog.finish(c)
self.leftChannel.emit(channel)
try:
@@ -2019,54 +1959,54 @@ class PesterWindow(MovingWindow):
del self.tabmemo
self.tabmemo = None
- @QtCore.pyqtSlot(QtCore.QString, Mood)
+ @QtCore.pyqtSlot(QString, Mood)
def updateMoodSlot(self, handle, mood):
- h = unicode(handle)
+ h = str(handle)
self.updateMood(h, mood)
- @QtCore.pyqtSlot(QtCore.QString, QtGui.QColor)
+ @QtCore.pyqtSlot(QString, QtGui.QColor)
def updateColorSlot(self, handle, color):
- h = unicode(handle)
+ h = str(handle)
self.changeColor(h, color)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def deliverMessage(self, handle, msg):
- h = unicode(handle)
- m = unicode(msg)
+ h = str(handle)
+ m = str(msg)
self.newMessage(h, m)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString, QString)
def deliverMemo(self, chan, handle, msg):
- (c, h, m) = (unicode(chan), unicode(handle), unicode(msg))
+ (c, h, m) = (str(chan), str(handle), str(msg))
self.newMemoMsg(c,h,m)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def deliverNotice(self, handle, msg):
- h = unicode(handle)
- m = unicode(msg)
+ h = str(handle)
+ m = str(msg)
if h.upper() == "NICKSERV" and m.startswith("Your nickname is now being changed to"):
changedto = m[39:-1]
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setText("This chumhandle has been registered; you may not use it.")
msgbox.setInformativeText("Your handle is now being changed to %s." % (changedto))
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
ret = msgbox.exec_()
elif h == self.randhandler.randNick:
self.randhandler.incoming(msg)
- elif self.convos.has_key(h):
+ elif h in self.convos:
self.newMessage(h, m)
elif h.upper() == "NICKSERV" and "PESTERCHUM:" not in m:
m = nickservmsgs.translate(m)
if m:
t = self.tm.Toast("NickServ:", m)
t.show()
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def deliverInvite(self, handle, channel):
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setText("You're invited!")
msgbox.setInformativeText("%s has invited you to the memo: %s\nWould you like to join them?" % (handle, channel))
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok | QtGui.QMessageBox.Cancel)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
# Find the Cancel button and make it default
for b in msgbox.buttons():
- if msgbox.buttonRole(b) == QtGui.QMessageBox.RejectRole:
+ if msgbox.buttonRole(b) == QtWidgets.QMessageBox.RejectRole:
# We found the 'OK' button, set it as the default
b.setDefault(True)
b.setAutoDefault(True)
@@ -2075,48 +2015,48 @@ class PesterWindow(MovingWindow):
b.setFocus()
break
ret = msgbox.exec_()
- if ret == QtGui.QMessageBox.Ok:
- self.newMemo(unicode(channel), "+0:00")
- @QtCore.pyqtSlot(QtCore.QString)
+ if ret == QtWidgets.QMessageBox.Ok:
+ self.newMemo(str(channel), "+0:00")
+ @QtCore.pyqtSlot(QString)
def chanInviteOnly(self, channel):
self.inviteOnlyChan.emit(channel)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def cannotSendToChan(self, channel, msg):
self.deliverMemo(channel, "ChanServ", msg)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def modesUpdated(self, channel, modes):
self.modesUpdated.emit(channel, modes)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString, QString)
def timeCommand(self, chan, handle, command):
- (c, h, cmd) = (unicode(chan), unicode(handle), unicode(command))
+ (c, h, cmd) = (str(chan), str(handle), str(command))
if self.memos[c]:
self.memos[c].timeUpdate(h, cmd)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString, QString)
def quirkDisable(self, channel, msg, op):
- (c, msg, op) = (unicode(channel), unicode(msg), unicode(op))
- if not self.memos.has_key(c):
+ (c, msg, op) = (str(channel), str(msg), str(op))
+ if c not in self.memos:
return
memo = self.memos[c]
memo.quirkDisable(op, msg)
- @QtCore.pyqtSlot(QtCore.QString, PesterList)
+ @QtCore.pyqtSlot(QString, PesterList)
def updateNames(self, channel, names):
- c = unicode(channel)
+ c = str(channel)
# update name DB
self.namesdb[c] = names
# warn interested party of names
self.namesUpdated.emit(c)
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString, QString)
def userPresentUpdate(self, handle, channel, update):
- c = unicode(channel)
- n = unicode(handle)
+ c = str(channel)
+ n = str(handle)
if update == "nick":
l = n.split(":")
oldnick = l[0]
newnick = l[1]
if update in ("quit", "netsplit"):
- for c in self.namesdb.keys():
+ for c in list(self.namesdb.keys()):
try:
i = self.namesdb[c].index(n)
self.namesdb[c].pop(i)
@@ -2133,7 +2073,7 @@ class PesterWindow(MovingWindow):
except KeyError:
self.namesdb[c] = []
elif update == "nick":
- for c in self.namesdb.keys():
+ for c in list(self.namesdb.keys()):
try:
i = self.namesdb[c].index(oldnick)
self.namesdb[c].pop(i)
@@ -2160,23 +2100,23 @@ class PesterWindow(MovingWindow):
available_groups = [g[0] for g in self.config.getGroups()]
self.addchumdialog = AddChumDialog(available_groups, self)
ok = self.addchumdialog.exec_()
- handle = unicode(self.addchumdialog.chumBox.text()).strip()
- newgroup = unicode(self.addchumdialog.newgroup.text()).strip()
+ handle = str(self.addchumdialog.chumBox.text()).strip()
+ newgroup = str(self.addchumdialog.newgroup.text()).strip()
selectedGroup = self.addchumdialog.groupBox.currentText()
group = newgroup if newgroup else selectedGroup
if ok:
- handle = unicode(handle)
+ handle = str(handle)
if handle in [h.handle for h in self.chumList.chums]:
self.addchumdialog = None
return
if not (PesterProfile.checkLength(handle) and
PesterProfile.checkValid(handle)[0]):
- errormsg = QtGui.QErrorMessage(self)
+ errormsg = QtWidgets.QErrorMessage(self)
errormsg.showMessage("THIS IS NOT A VALID CHUMTAG!")
self.addchumdialog = None
return
if re.search("[^A-Za-z0-9_\s]", group) is not None:
- errormsg = QtGui.QErrorMessage(self)
+ errormsg = QtWidgets.QErrorMessage(self)
errormsg.showMessage("THIS IS NOT A VALID GROUP NAME")
self.addchumdialog = None
return
@@ -2187,20 +2127,20 @@ class PesterWindow(MovingWindow):
self.chumdb.setGroup(handle, group)
self.addChum(chum)
self.addchumdialog = None
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def removeChum(self, chumlisting):
self.config.removeChum(chumlisting)
def reportChum(self, handle):
- (reason, ok) = QtGui.QInputDialog.getText(self, "Report User", "Enter the reason you are reporting this user (optional):")
+ (reason, ok) = QtWidgets.QInputDialog.getText(self, "Report User", "Enter the reason you are reporting this user (optional):")
if ok:
self.sendMessage.emit("REPORT %s %s" % (handle, reason) , "calSprite")
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def blockChum(self, handle):
- h = unicode(handle)
+ h = str(handle)
self.config.addBlocklist(h)
self.config.removeChum(h)
- if self.convos.has_key(h):
+ if h in self.convos:
convo = self.convos[h]
msg = self.profile().pestermsg(convo.chum, QtGui.QColor(self.theme["convo/systemMsgColor"]), self.theme["convo/text/blocked"])
convo.textArea.append(convertTags(msg))
@@ -2213,11 +2153,11 @@ class PesterWindow(MovingWindow):
self.moodRequest.emit(newtroll)
self.blockedChum.emit(handle)
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def unblockChum(self, handle):
- h = unicode(handle)
+ h = str(handle)
self.config.delBlocklist(h)
- if self.convos.has_key(h):
+ if h in self.convos:
convo = self.convos[h]
msg = self.profile().pestermsg(convo.chum, QtGui.QColor(self.theme["convo/systemMsgColor"]), self.theme["convo/text/unblocked"])
convo.textArea.append(convertTags(msg))
@@ -2286,7 +2226,7 @@ class PesterWindow(MovingWindow):
# Tell everyone we're in a chat with that we just went idle.
sysColor = QtGui.QColor(self.theme["convo/systemMsgColor"])
verb = self.theme["convo/text/idle"]
- for (h, convo) in self.convos.iteritems():
+ for (h, convo) in self.convos.items():
# karxi: There's an irritating issue here involving a lack of
# consideration for case-sensitivity.
# This fix is a little sloppy, and I need to look into what it
@@ -2310,12 +2250,12 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def importExternalConfig(self):
- f = QtGui.QFileDialog.getOpenFileName(self)
+ f = QtWidgets.QFileDialog.getOpenFileName(self)[0]
if f == "":
return
fp = open(f, 'r')
regexp_state = None
- for l in fp.xreadlines():
+ for l in fp:
# import chumlist
l = l.rstrip()
chum_mo = re.match("handle: ([A-Za-z0-9]+)", l)
@@ -2329,7 +2269,7 @@ class PesterWindow(MovingWindow):
replace = replace_mo.group(1)
try:
re.compile(regexp_state)
- except re.error, e:
+ except re.error as e:
continue
newquirk = pesterQuirk({"type": "regexp",
"from": regexp_state,
@@ -2358,32 +2298,30 @@ class PesterWindow(MovingWindow):
if self.memochooser:
return
self.memochooser = PesterMemoList(self, channel)
- self.connect(self.memochooser, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('joinSelectedMemo()'))
- self.connect(self.memochooser, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('memoChooserClose()'))
+ self.memochooser.accepted.connect(self.joinSelectedMemo)
+ self.memochooser.rejected.connect(self.memoChooserClose)
self.requestChannelList.emit()
self.memochooser.show()
@QtCore.pyqtSlot()
def joinSelectedMemo(self):
- time = unicode(self.memochooser.timeinput.text())
+ time = str(self.memochooser.timeinput.text())
secret = self.memochooser.secretChannel.isChecked()
invite = self.memochooser.inviteChannel.isChecked()
# Join the ones on the list first
for SelectedMemo in self.memochooser.SelectedMemos():
- channel = "#"+unicode(SelectedMemo.target)
+ channel = "#"+str(SelectedMemo.target)
self.newMemo(channel, time)
if self.memochooser.newmemoname():
newmemo = self.memochooser.newmemoname()
- channel = unicode(newmemo).replace(" ", "_")
+ channel = str(newmemo).replace(" ", "_")
channel = re.sub(r"[^A-Za-z0-9#_\,]", "", channel)
# Allow us to join more than one with this.
chans = channel.split(',')
# Filter out empty entries.
- chans = filter(None, chans)
+ chans = [_f for _f in chans if _f]
for c in chans:
c = '#' + c
# We should really change this code to only make the memo once
@@ -2405,25 +2343,21 @@ class PesterWindow(MovingWindow):
self.allusers = None
if not self.allusers:
self.allusers = PesterUserlist(self.config, self.theme, self)
- self.connect(self.allusers, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('userListClose()'))
- self.connect(self.allusers, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('userListClose()'))
- self.connect(self.allusers, QtCore.SIGNAL('addChum(QString)'),
- self, QtCore.SLOT('userListAdd(QString)'))
- self.connect(self.allusers, QtCore.SIGNAL('pesterChum(QString)'),
- self, QtCore.SLOT('userListPester(QString)'))
+ self.allusers.accepted.connect(self.userListClose)
+ self.allusers.rejected.connect(self.userListClose)
+ self.allusers.addChum['QString'].connect(self.userListAdd)
+ self.allusers.pesterChum['QString'].connect(self.userListPester)
self.requestNames.emit("#pesterchum")
self.allusers.show()
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def userListAdd(self, handle):
- h = unicode(handle)
+ h = str(handle)
chum = PesterProfile(h, chumdb=self.chumdb)
self.addChum(chum)
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def userListPester(self, handle):
- h = unicode(handle)
+ h = str(handle)
self.newConversation(h)
@QtCore.pyqtSlot()
def userListClose(self):
@@ -2435,17 +2369,15 @@ class PesterWindow(MovingWindow):
self.quirkmenu = None
if not self.quirkmenu:
self.quirkmenu = PesterChooseQuirks(self.config, self.theme, self)
- self.connect(self.quirkmenu, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('updateQuirks()'))
- self.connect(self.quirkmenu, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('closeQuirks()'))
+ self.quirkmenu.accepted.connect(self.updateQuirks)
+ self.quirkmenu.rejected.connect(self.closeQuirks)
self.quirkmenu.show()
self.quirkmenu.raise_()
self.quirkmenu.activateWindow()
@QtCore.pyqtSlot()
def updateQuirks(self):
for i in range(self.quirkmenu.quirkList.topLevelItemCount()):
- curgroup = unicode(self.quirkmenu.quirkList.topLevelItem(i).text(0))
+ curgroup = str(self.quirkmenu.quirkList.topLevelItem(i).text(0))
for j in range(self.quirkmenu.quirkList.topLevelItem(i).childCount()):
item = self.quirkmenu.quirkList.topLevelItem(i).child(j)
item.quirk.quirk["on"] = item.quirk.on = (item.checkState(0) == QtCore.Qt.Checked)
@@ -2465,10 +2397,10 @@ class PesterWindow(MovingWindow):
if not hasattr(self, "openchatdialog"):
self.openchatdialog = None
if not self.openchatdialog:
- (chum, ok) = QtGui.QInputDialog.getText(self, "Pester Chum", "Enter a handle to pester:")
+ (chum, ok) = QtWidgets.QInputDialog.getText(self, "Pester Chum", "Enter a handle to pester:")
try:
if ok:
- self.newConversation(unicode(chum))
+ self.newConversation(str(chum))
except:
pass
finally:
@@ -2479,10 +2411,8 @@ class PesterWindow(MovingWindow):
self.logusermenu = None
if not self.logusermenu:
self.logusermenu = PesterLogUserSelect(self.config, self.theme, self)
- self.connect(self.logusermenu, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('closeLogUsers()'))
- self.connect(self.logusermenu, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('closeLogUsers()'))
+ self.logusermenu.accepted.connect(self.closeLogUsers)
+ self.logusermenu.rejected.connect(self.closeLogUsers)
self.logusermenu.show()
self.logusermenu.raise_()
self.logusermenu.activateWindow()
@@ -2496,13 +2426,13 @@ class PesterWindow(MovingWindow):
if not hasattr(self, 'addgroupdialog'):
self.addgroupdialog = None
if not self.addgroupdialog:
- (gname, ok) = QtGui.QInputDialog.getText(self, "Add Group", "Enter a name for the new group:")
+ (gname, ok) = QtWidgets.QInputDialog.getText(self, "Add Group", "Enter a name for the new group:")
if ok:
- gname = unicode(gname)
+ gname = str(gname)
if re.search("[^A-Za-z0-9_\s]", gname) is not None:
- msgbox = QtGui.QMessageBox()
+ msgbox = QtWidgets.QMessageBox()
msgbox.setInformativeText("THIS IS NOT A VALID GROUP NAME")
- msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
+ msgbox.setStandardButtons(QtWidgets.QMessageBox.Ok)
ret = msgbox.exec_()
self.addgroupdialog = None
return
@@ -2515,10 +2445,8 @@ class PesterWindow(MovingWindow):
self.optionmenu = None
if not self.optionmenu:
self.optionmenu = PesterOptions(self.config, self.theme, self)
- self.connect(self.optionmenu, QtCore.SIGNAL('accepted()'),
- self, QtCore.SLOT('updateOptions()'))
- self.connect(self.optionmenu, QtCore.SIGNAL('rejected()'),
- self, QtCore.SLOT('closeOptions()'))
+ self.optionmenu.accepted.connect(self.updateOptions)
+ self.optionmenu.rejected.connect(self.closeOptions)
self.optionmenu.show()
self.optionmenu.raise_()
self.optionmenu.activateWindow()
@@ -2550,7 +2478,7 @@ class PesterWindow(MovingWindow):
# combine
self.createTabWindow()
newconvos = {}
- for (h,c) in self.convos.iteritems():
+ for (h,c) in self.convos.items():
c.setParent(self.tabconvo)
self.tabconvo.addChat(c)
self.tabconvo.show()
@@ -2580,7 +2508,7 @@ class PesterWindow(MovingWindow):
# combine
newmemos = {}
self.createMemoTabWindow()
- for (h,m) in self.memos.iteritems():
+ for (h,m) in self.memos.items():
m.setParent(self.tabmemo)
self.tabmemo.addChat(m)
self.tabmemo.show()
@@ -2629,7 +2557,7 @@ class PesterWindow(MovingWindow):
# timestamps
timestampsetting = self.optionmenu.timestampcheck.isChecked()
self.config.set("showTimeStamps", timestampsetting)
- timeformatsetting = unicode(self.optionmenu.timestampBox.currentText())
+ timeformatsetting = str(self.optionmenu.timestampBox.currentText())
if timeformatsetting == "12 hour":
self.config.set("time12Format", True)
else:
@@ -2739,7 +2667,7 @@ class PesterWindow(MovingWindow):
self.config.set('blink', blinksetting)
# toast notifications
self.tm.setEnabled(self.optionmenu.notifycheck.isChecked())
- self.tm.setCurrentType(unicode(self.optionmenu.notifyOptions.currentText()))
+ self.tm.setCurrentType(str(self.optionmenu.notifyOptions.currentText()))
notifysetting = 0
if self.optionmenu.notifySigninCheck.isChecked():
notifysetting |= self.config.SIGNIN
@@ -2786,24 +2714,18 @@ class PesterWindow(MovingWindow):
def setButtonAction(self, button, setting, old):
if old == 0: # minimize to taskbar
- self.disconnect(button, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('showMinimized()'));
+ button.clicked.disconnect(self.showMinimized)
elif old == 1: # minimize to tray
- self.disconnect(button, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('closeToTray()'));
+ button.clicked.disconnect(self.closeToTray)
elif old == 2: # quit
- self.disconnect(button, QtCore.SIGNAL('clicked()'),
- self.app, QtCore.SLOT('quit()'));
+ button.clicked.disconnect(self.app.quit)
if setting == 0: # minimize to taskbar
- self.connect(button, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('showMinimized()'));
+ button.clicked.connect(self.showMinimized)
elif setting == 1: # minimize to tray
- self.connect(button, QtCore.SIGNAL('clicked()'),
- self, QtCore.SLOT('closeToTray()'));
+ button.clicked.connect(self.closeToTray)
elif setting == 2: # quit
- self.connect(button, QtCore.SIGNAL('clicked()'),
- self.app, QtCore.SLOT('quit()'));
+ button.clicked.connect(self.app.quit)
@QtCore.pyqtSlot()
def themeSelectOverride(self):
@@ -2812,14 +2734,14 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def themeSelected(self, override=False):
if not override:
- themename = unicode(self.optionmenu.themeBox.currentText())
+ themename = str(self.optionmenu.themeBox.currentText())
else:
themename = override
if override or themename != self.theme.name:
try:
self.changeTheme(pesterTheme(themename))
except ValueError as e:
- themeWarning = QtGui.QMessageBox(self)
+ themeWarning = QtWidgets.QMessageBox(self)
themeWarning.setText("Theme Error: %s" % (e))
themeWarning.exec_()
self.choosetheme = None
@@ -2834,14 +2756,14 @@ class PesterWindow(MovingWindow):
def profileSelected(self):
if self.chooseprofile.profileBox and \
self.chooseprofile.profileBox.currentIndex() > 0:
- handle = unicode(self.chooseprofile.profileBox.currentText())
+ handle = str(self.chooseprofile.profileBox.currentText())
if handle == self.profile().handle:
self.chooseprofile = None
return
self.userprofile = userProfile(handle)
self.changeTheme(self.userprofile.getTheme())
else:
- handle = unicode(self.chooseprofile.chumHandle.text())
+ handle = str(self.chooseprofile.chumHandle.text())
if handle == self.profile().handle:
self.chooseprofile = None
return
@@ -2868,11 +2790,8 @@ class PesterWindow(MovingWindow):
return
trolls = [PesterProfile(h) for h in self.config.getBlocklist()]
self.trollslum = TrollSlumWindow(trolls, self)
- self.connect(self.trollslum, QtCore.SIGNAL('blockChumSignal(QString)'),
- self, QtCore.SLOT('blockChum(QString)'))
- self.connect(self.trollslum,
- QtCore.SIGNAL('unblockChumSignal(QString)'),
- self, QtCore.SLOT('unblockChum(QString)'))
+ self.trollslum.blockChumSignal['QString'].connect(self.blockChum)
+ self.trollslum.unblockChumSignal['QString'].connect(self.unblockChum)
self.moodsRequest.emit(PesterList(trolls))
self.trollslum.show()
@QtCore.pyqtSlot()
@@ -2884,7 +2803,7 @@ class PesterWindow(MovingWindow):
self.colorDialog = None
if self.colorDialog:
return
- self.colorDialog = QtGui.QColorDialog(self)
+ self.colorDialog = QtWidgets.QColorDialog(self)
color = self.colorDialog.getColor(initial=self.profile().color)
if not color.isValid():
color = self.profile().color
@@ -2898,13 +2817,13 @@ class PesterWindow(MovingWindow):
@QtCore.pyqtSlot()
def switchProfile(self):
if self.convos:
- closeWarning = QtGui.QMessageBox()
+ closeWarning = QtWidgets.QMessageBox()
closeWarning.setText("WARNING: CHANGING PROFILES WILL CLOSE ALL CONVERSATION WINDOWS!")
closeWarning.setInformativeText("i warned you about windows bro!!!! i told you dog!")
- closeWarning.setStandardButtons(QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Ok)
- closeWarning.setDefaultButton(QtGui.QMessageBox.Ok)
+ closeWarning.setStandardButtons(QtWidgets.QMessageBox.Cancel | QtWidgets.QMessageBox.Ok)
+ closeWarning.setDefaultButton(QtWidgets.QMessageBox.Ok)
ret = closeWarning.exec_()
- if ret == QtGui.QMessageBox.Cancel:
+ if ret == QtWidgets.QMessageBox.Cancel:
return
self.changeProfile()
@QtCore.pyqtSlot()
@@ -2931,7 +2850,7 @@ class PesterWindow(MovingWindow):
QtGui.QDesktopServices.openUrl(QtCore.QUrl("https://github.com/Dpeta/pesterchum-alt-servers/issues", QtCore.QUrl.TolerantMode))
return
- @QtCore.pyqtSlot(QtCore.QString, QtCore.QString)
+ @QtCore.pyqtSlot(QString, QString)
def nickCollision(self, handle, tmphandle):
self.mychumhandle.setText(tmphandle)
self.userprofile = userProfile(PesterProfile("pesterClient%d" % (random.randint(100,999)), QtGui.QColor("black"), Mood(0)))
@@ -2940,9 +2859,9 @@ class PesterWindow(MovingWindow):
if not hasattr(self, 'chooseprofile'):
self.chooseprofile = None
if not self.chooseprofile:
- h = unicode(handle)
+ h = str(handle)
self.changeProfile(collision=h)
- @QtCore.pyqtSlot(QtCore.QString)
+ @QtCore.pyqtSlot(QString)
def myHandleChanged(self, handle):
if self.profile().handle == handle:
self.doAutoIdentify()
@@ -2954,57 +2873,57 @@ class PesterWindow(MovingWindow):
def pickTheme(self):
self.themePicker()
- @QtCore.pyqtSlot(QtGui.QSystemTrayIcon.ActivationReason)
+ @QtCore.pyqtSlot(QtWidgets.QSystemTrayIcon.ActivationReason)
def systemTrayActivated(self, reason):
- if reason == QtGui.QSystemTrayIcon.Trigger:
+ if reason == QtWidgets.QSystemTrayIcon.Trigger:
self.systemTrayFunction()
- elif reason == QtGui.QSystemTrayIcon.Context:
+ elif reason == QtWidgets.QSystemTrayIcon.Context:
pass
# show context menu i guess
#self.showTrayContext.emit()
@QtCore.pyqtSlot()
def tooManyPeeps(self):
- msg = QtGui.QMessageBox(self)
+ msg = QtWidgets.QMessageBox(self)
msg.setText("D: TOO MANY PEOPLE!!!")
msg.setInformativeText("The server has hit max capacity. Please try again later.")
msg.show()
- pcUpdate = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
+ pcUpdate = QtCore.pyqtSignal('QString', 'QString')
closeToTraySignal = QtCore.pyqtSignal()
- newConvoStarted = QtCore.pyqtSignal(QtCore.QString, bool, name="newConvoStarted")
- sendMessage = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- sendNotice = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- convoClosed = QtCore.pyqtSignal(QtCore.QString)
+ newConvoStarted = QtCore.pyqtSignal('QString', bool, name="newConvoStarted")
+ sendMessage = QtCore.pyqtSignal('QString', 'QString')
+ sendNotice = QtCore.pyqtSignal('QString', 'QString')
+ convoClosed = QtCore.pyqtSignal('QString')
profileChanged = QtCore.pyqtSignal()
animationSetting = QtCore.pyqtSignal(bool)
moodRequest = QtCore.pyqtSignal(PesterProfile)
moodsRequest = QtCore.pyqtSignal(PesterList)
moodUpdated = QtCore.pyqtSignal()
requestChannelList = QtCore.pyqtSignal()
- requestNames = QtCore.pyqtSignal(QtCore.QString)
- namesUpdated = QtCore.pyqtSignal(QtCore.QString)
- modesUpdated = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- userPresentSignal = QtCore.pyqtSignal(QtCore.QString,QtCore.QString,QtCore.QString)
+ requestNames = QtCore.pyqtSignal('QString')
+ namesUpdated = QtCore.pyqtSignal('QString')
+ modesUpdated = QtCore.pyqtSignal('QString', 'QString')
+ userPresentSignal = QtCore.pyqtSignal('QString','QString','QString')
mycolorUpdated = QtCore.pyqtSignal()
trayIconSignal = QtCore.pyqtSignal(int)
- blockedChum = QtCore.pyqtSignal(QtCore.QString)
- unblockedChum = QtCore.pyqtSignal(QtCore.QString)
- kickUser = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- joinChannel = QtCore.pyqtSignal(QtCore.QString)
- leftChannel = QtCore.pyqtSignal(QtCore.QString)
- setChannelMode = QtCore.pyqtSignal(QtCore.QString, QtCore.QString, QtCore.QString)
- channelNames = QtCore.pyqtSignal(QtCore.QString)
- inviteChum = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
- inviteOnlyChan = QtCore.pyqtSignal(QtCore.QString)
+ blockedChum = QtCore.pyqtSignal('QString')
+ unblockedChum = QtCore.pyqtSignal('QString')
+ kickUser = QtCore.pyqtSignal('QString', 'QString')
+ joinChannel = QtCore.pyqtSignal('QString')
+ leftChannel = QtCore.pyqtSignal('QString')
+ setChannelMode = QtCore.pyqtSignal('QString', 'QString', 'QString')
+ channelNames = QtCore.pyqtSignal('QString')
+ inviteChum = QtCore.pyqtSignal('QString', 'QString')
+ inviteOnlyChan = QtCore.pyqtSignal('QString')
closeSignal = QtCore.pyqtSignal()
reconnectIRC = QtCore.pyqtSignal()
- gainAttention = QtCore.pyqtSignal(QtGui.QWidget)
+ gainAttention = QtCore.pyqtSignal(QtWidgets.QWidget)
pingServer = QtCore.pyqtSignal()
setAway = QtCore.pyqtSignal(bool)
- killSomeQuirks = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
+ killSomeQuirks = QtCore.pyqtSignal('QString', 'QString')
-class PesterTray(QtGui.QSystemTrayIcon):
+class PesterTray(QtWidgets.QSystemTrayIcon):
def __init__(self, icon, mainwindow, parent):
super(PesterTray, self).__init__(icon, parent)
self.mainwindow = mainwindow
@@ -3031,7 +2950,7 @@ class MainProgram(QtCore.QObject):
# See http://stackoverflow.com/a/1552105 for more details.
from ctypes import windll
# Note that this has to be unicode.
- wid = u"mspa.homestuck.pesterchum.314"
+ wid = "mspa.homestuck.pesterchum.314"
# Designate this as a separate process - i.e., tell Windows that
# Python is just hosting Pesterchum.
# TODO: Eventually we should get this changed so it checks and
@@ -3045,7 +2964,7 @@ class MainProgram(QtCore.QObject):
logging.error("Attempted to set as {0!r}.".format(wid))
# Back to our scheduled program.
- self.app = QtGui.QApplication(sys.argv)
+ self.app = QtWidgets.QApplication(sys.argv)
self.app.setApplicationName("Pesterchum 3.14")
self.app.setQuitOnLastWindowClosed(False)
@@ -3071,7 +2990,7 @@ class MainProgram(QtCore.QObject):
except:
pass
self.server = "irc.pesterchum.xyz"
- print("Server is: " + self.server)
+ print(("Server is: " + self.server))
def doSoundInit():
# TODO: Make this more uniform, adapt it into a general function.
@@ -3081,7 +3000,7 @@ class MainProgram(QtCore.QObject):
pygame.mixer.init()
pygame.mixer.init()
except pygame.error as err:
- print "Warning: No sound! (pygame error: %s)" % err
+ print("Warning: No sound! (pygame error: %s)" % err)
else:
# Sound works, we're done.
return
@@ -3089,61 +3008,43 @@ class MainProgram(QtCore.QObject):
# ... Other alternatives here. ...
# Last resort. (Always 'works' on Windows, no volume control.)
- if QtGui.QSound.isAvailable():
+ if QtMultimedia.QSound.isAvailable():
# Sound works, we're done.
return
else:
- print "Warning: No sound! (No pygame/QSound)"
+ print("Warning: No sound! (No pygame/QSound)")
doSoundInit()
self.widget = PesterWindow(options, app=self.app)
self.widget.show()
self.trayicon = PesterTray(PesterIcon(self.widget.theme["main/icon"]), self.widget, self.app)
- self.traymenu = QtGui.QMenu()
+ self.traymenu = QtWidgets.QMenu()
moodMenu = self.traymenu.addMenu("SET MOOD")
moodCategories = {}
for k in Mood.moodcats:
moodCategories[k] = moodMenu.addMenu(k.upper())
self.moodactions = {}
for (i,m) in enumerate(Mood.moods):
- maction = QtGui.QAction(m.upper(), self)
+ maction = QtWidgets.QAction(m.upper(), self)
mobj = PesterMoodAction(i, self.widget.moods.updateMood)
- self.trayicon.connect(maction, QtCore.SIGNAL('triggered()'),
- mobj, QtCore.SLOT('updateMood()'))
+ maction.triggered.connect(mobj.updateMood)
self.moodactions[i] = mobj
moodCategories[Mood.revmoodcats[m]].addAction(maction)
- miniAction = QtGui.QAction("MINIMIZE", self)
- self.trayicon.connect(miniAction, QtCore.SIGNAL('triggered()'),
- self.widget, QtCore.SLOT('showMinimized()'))
- exitAction = QtGui.QAction("EXIT", self)
- self.trayicon.connect(exitAction, QtCore.SIGNAL('triggered()'),
- self.app, QtCore.SLOT('quit()'))
+ miniAction = QtWidgets.QAction("MINIMIZE", self)
+ miniAction.triggered.connect(self.widget.showMinimized)
+ exitAction = QtWidgets.QAction("EXIT", self)
+ exitAction.triggered.connect(self.app.quit)
self.traymenu.addAction(miniAction)
self.traymenu.addAction(exitAction)
self.trayicon.setContextMenu(self.traymenu)
self.trayicon.show()
- self.trayicon.connect(self.trayicon,
- QtCore.SIGNAL('activated(QSystemTrayIcon::ActivationReason)'),
- self.widget,
- QtCore.SLOT('systemTrayActivated(QSystemTrayIcon::ActivationReason)'))
- self.trayicon.connect(self.widget,
- QtCore.SIGNAL('trayIconSignal(int)'),
- self.trayicon,
- QtCore.SLOT('changeTrayIcon(int)'))
- self.trayicon.connect(self.widget,
- QtCore.SIGNAL('closeToTraySignal()'),
- self,
- QtCore.SLOT('trayiconShow()'))
- self.trayicon.connect(self.widget,
- QtCore.SIGNAL('closeSignal()'),
- self.trayicon,
- QtCore.SLOT('mainWindowClosed()'))
- self.connect(self.trayicon,
- QtCore.SIGNAL('messageClicked()'),
- self,
- QtCore.SLOT('trayMessageClick()'))
+ self.trayicon.activated[QSystemTrayIcon.ActivationReason].connect(self.widget.systemTrayActivated)
+ self.widget.trayIconSignal[int].connect(self.trayicon.changeTrayIcon)
+ self.widget.closeToTraySignal.connect(self.trayiconShow)
+ self.widget.closeSignal.connect(self.trayicon.mainWindowClosed)
+ self.trayicon.messageClicked.connect(self.trayMessageClick)
self.attempts = 0
@@ -3152,8 +3053,7 @@ class MainProgram(QtCore.QObject):
self.irc = PesterIRC(self.widget.config, self.widget, self.server)
self.connectWidgets(self.irc, self.widget)
- self.connect(self.widget, QtCore.SIGNAL('gainAttention(QWidget*)'),
- self, QtCore.SLOT('alertWindow(QWidget*)'))
+ self.widget.gainAttention[QWidget].connect(self.alertWindow)
# This doesn't know as far as I'm aware, so it's commented out for now.
@@ -3180,7 +3080,7 @@ class MainProgram(QtCore.QObject):
@QtCore.pyqtSlot()
def runUpdateSlot(self):
- q = Queue.Queue(1)
+ q = queue.Queue(1)
s = threading.Thread(target=version.updateCheck, args=(q,))
w = threading.Thread(target=self.showUpdate, args=(q,))
w.start()
@@ -3195,7 +3095,7 @@ class MainProgram(QtCore.QObject):
return
QtCore.QTimer.singleShot(1000*seconds, self, QtCore.SLOT('runUpdateSlot()'))
- @QtCore.pyqtSlot(QtGui.QWidget)
+ @QtCore.pyqtSlot(QtWidgets.QWidget)
def alertWindow(self, widget):
self.app.alert(widget)
@@ -3285,27 +3185,19 @@ Click this message to never see this again.")
'quirkDisable(QString, QString, QString)')
]
def connectWidgets(self, irc, widget):
- self.connect(irc, QtCore.SIGNAL('finished()'),
- self, QtCore.SLOT('restartIRC()'))
- self.connect(irc, QtCore.SIGNAL('connected()'),
- self, QtCore.SLOT('connected()'))
+ irc.finished.connect(self.restartIRC)
+ irc.connected.connect(self.connected)
for c in self.widget2irc:
- self.connect(widget, QtCore.SIGNAL(c[0]),
- irc, QtCore.SLOT(c[1]))
+ widget.c[0].connect(irc.c[1])
for c in self.irc2widget:
- self.connect(irc, QtCore.SIGNAL(c[0]),
- widget, QtCore.SLOT(c[1]))
+ irc.c[0].connect(widget.c[1])
def disconnectWidgets(self, irc, widget):
for c in self.widget2irc:
- self.disconnect(widget, QtCore.SIGNAL(c[0]),
- irc, QtCore.SLOT(c[1]))
+ widget.c[0].disconnect(irc.c[1])
for c in self.irc2widget:
- self.disconnect(irc, QtCore.SIGNAL(c[0]),
- widget, QtCore.SLOT(c[1]))
- self.disconnect(irc, QtCore.SIGNAL('connected()'),
- self, QtCore.SLOT('connected()'))
- self.disconnect(self.irc, QtCore.SIGNAL('finished()'),
- self, QtCore.SLOT('restartIRC()'))
+ irc.c[0].disconnect(widget.c[1])
+ irc.connected.disconnect(self.connected)
+ self.irc.finished.disconnect(self.restartIRC)
def showUpdate(self, q):
new_url = q.get()
@@ -3335,10 +3227,8 @@ Click this message to never see this again.")
else:
widget.loadingscreen = LoadingScreen(widget)
widget.loadingscreen.loadinglabel.setText(msg)
- self.connect(widget.loadingscreen, QtCore.SIGNAL('rejected()'),
- widget.app, QtCore.SLOT('quit()'))
- self.connect(self.widget.loadingscreen, QtCore.SIGNAL('tryAgain()'),
- self, QtCore.SLOT('tryAgain()'))
+ widget.loadingscreen.rejected.connect(widget.app.quit)
+ self.widget.loadingscreen.tryAgain.connect(self.tryAgain)
if hasattr(self, 'irc') and self.irc.registeredIRC:
return
if self.reconnectok:
@@ -3346,14 +3236,14 @@ Click this message to never see this again.")
else:
widget.loadingscreen.hideReconnect()
status = widget.loadingscreen.exec_()
- if status == QtGui.QDialog.Rejected:
+ if status == QtWidgets.QDialog.Rejected:
sys.exit(0)
else:
if self.widget.tabmemo:
for c in self.widget.tabmemo.convos:
self.irc.joinChannel(c)
else:
- for c in self.widget.memos.values():
+ for c in list(self.widget.memos.values()):
self.irc.joinChannel(c.channel)
return True
@@ -3365,7 +3255,7 @@ Click this message to never see this again.")
if not self.reconnectok:
return
if self.widget.loadingscreen:
- self.widget.loadingscreen.done(QtGui.QDialog.Accepted)
+ self.widget.loadingscreen.done(QtWidgets.QDialog.Accepted)
self.widget.loadingscreen = None
self.attempts += 1
if hasattr(self, 'irc') and self.irc:
diff --git a/pnc/dep/attrdict.py b/pnc/dep/attrdict.py
index fc0b9bb..c8a1bb4 100644
--- a/pnc/dep/attrdict.py
+++ b/pnc/dep/attrdict.py
@@ -13,7 +13,7 @@ class AttrDict(dict):
super(AttrDict, self).__init__(init)
def __getstate__(self):
- return self.__dict__.items()
+ return list(self.__dict__.items())
def __setstate__(self, items):
for key, val in items: self.__dict__[key] = val
diff --git a/pnc/lexercon.py b/pnc/lexercon.py
index 81891c9..0b979b0 100644
--- a/pnc/lexercon.py
+++ b/pnc/lexercon.py
@@ -1,5 +1,5 @@
# -*- coding=UTF-8; tab-width: 4 -*-
-from __future__ import division
+
from .unicolor import Color
@@ -8,7 +8,7 @@ import re
global basestr
basestr = str
try:
- basestr = basestring
+ basestr = str
except NameError:
# We're running Python 3. Leave it be.
pass
@@ -160,7 +160,7 @@ class CTag(Specifier):
cmatch = Pesterchum._ctag_rgb.match(text)
if cmatch:
working = cmatch.groups()
- working = map(int, working)
+ working = list(map(int, working))
inst.color = Color(*working)
else:
try:
diff --git a/pnc/unicolor.py b/pnc/unicolor.py
index af50120..e7ee0e7 100644
--- a/pnc/unicolor.py
+++ b/pnc/unicolor.py
@@ -1,5 +1,5 @@
# -*- coding=UTF-8; tab-width: 4 -*-
-from __future__ import division
+
__all__ = ["Color"]
@@ -16,7 +16,7 @@ import sys
# Python 3 checking
if sys.version_info[0] == 2:
- basestr = basestring
+ basestr = str
else:
basestr = str
@@ -119,7 +119,7 @@ class Color(object):
## self.red, self.green, self.blue
## ])
# 2012-12-08T13:34-07:00: This should improve accuracy
- result = map(hash, self.cielab)
+ result = list(map(hash, self.cielab))
result = functools.reduce(lambda x, y: x ^ y, result)
return result
@@ -201,7 +201,7 @@ class Color(object):
closest, cldist = None, None
targs = _irc_colors
- for code, other in targs.items():
+ for code, other in list(targs.items()):
dist = self - other
##if (not strict and dist > self.jnd) or dist == 0:
if dist == 0:
@@ -217,7 +217,7 @@ class Color(object):
closest, cldist = None, None
targs = _svg_colors
- for name, other in targs.items():
+ for name, other in list(targs.items()):
dist = self - other
if (not strict and dist > self.jnd) or dist == 0:
# The difference is below the Just-Noticeable Difference
@@ -236,7 +236,7 @@ class Color(object):
# http://en.wikipedia.org/wiki/Color_difference
slab, olab = self.to_cielab_tuple(), other.to_cielab_tuple()
# Calculate the distance between the points for each
- dist = map(lambda p1, p2: (p2 - p1)**2, slab, olab)
+ dist = list(map(lambda p1, p2: (p2 - p1)**2, slab, olab))
# Add the results up, and sqrt to compensate for earlier squaring
dist = sum(dist) ** .5
return dist
@@ -252,7 +252,7 @@ class Color(object):
### Square the results from the above
##dist = [x**2 for x in dist]
# Do what we WOULD have done in those two lines with a single one
- dist = map(lambda x1, x2: (x1 - x2)**2, srgb, orgb)
+ dist = list(map(lambda x1, x2: (x1 - x2)**2, srgb, orgb))
# Add the results up
dist = sum(dist)
# Fetch the square root to compensate for the earlier squaring
@@ -284,7 +284,7 @@ class Color(object):
@staticmethod
def rgb_to_hexstr(red, green, blue, compress=False):
rgb = [red, green, blue]
- rgb = map(abs, rgb)
+ rgb = list(map(abs, rgb))
result = []
for c in rgb:
c = "%02X" % c
@@ -547,7 +547,7 @@ _svg_colors.update({
"yellow": Color(255, 255, 0),
"yellowgreen": Color(154, 205, 50)
})
-for k, v in _svg_colors.items():
+for k, v in list(_svg_colors.items()):
v.closest_name = v.name = k
# 2012-12-08T14:29-07:00: Copied over from Colors.hexstr_for_ccodes in the main
@@ -594,7 +594,7 @@ _irc_colors.update({
99: Color(0x999999) # Until I think of a better solution to this
})
-for k, v in _irc_colors.items():
+for k, v in list(_irc_colors.items()):
v.ccode = "%02d" % k
del k, v
diff --git a/profile.py b/profile.py
index d9498db..32cf576 100644
--- a/profile.py
+++ b/profile.py
@@ -7,7 +7,7 @@ import codecs
import platform
from datetime import *
from time import strftime, time
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
import ostools
from mood import Mood
@@ -48,22 +48,22 @@ class PesterLog(object):
html = time + convertTags(msg, "html")+" "
msg = time +convertTags(msg, "text")
modes = {"bbcode": bbcodemsg, "html": html, "text": msg}
- if not self.convos.has_key(handle):
+ if handle not in self.convos:
time = datetime.now().strftime("%Y-%m-%d.%H.%M")
self.convos[handle] = {}
- for (format, t) in modes.iteritems():
+ for (format, t) in modes.items():
if not os.path.exists("%s/%s/%s/%s" % (self.logpath, self.handle, handle, format)):
os.makedirs("%s/%s/%s/%s" % (self.logpath, self.handle, handle, format))
try:
fp = codecs.open("%s/%s/%s/%s/%s.%s.txt" % (self.logpath, self.handle, handle, format, handle, time), encoding='utf-8', mode='a')
except IOError:
- errmsg = QtGui.QMessageBox(self)
+ errmsg = QtWidgets.QMessageBox(self)
errmsg.setText("Warning: Pesterchum could not open the log file for %s!" % (handle))
errmsg.setInformativeText("Your log for %s will not be saved because something went wrong. We suggest restarting Pesterchum. Sorry :(" % (handle))
errmsg.show()
continue
self.convos[handle][format] = fp
- for (format, t) in modes.iteritems():
+ for (format, t) in modes.items():
f = self.convos[handle][format]
if platform.system() == "Windows":
f.write(t+"\r\n")
@@ -71,14 +71,14 @@ class PesterLog(object):
f.write(t+"\r\n")
f.flush()
def finish(self, handle):
- if not self.convos.has_key(handle):
+ if handle not in self.convos:
return
- for f in self.convos[handle].values():
+ for f in list(self.convos[handle].values()):
f.close()
del self.convos[handle]
def close(self):
- for h in self.convos.keys():
- for f in self.convos[h].values():
+ for h in list(self.convos.keys()):
+ for f in list(self.convos[h].values()):
f.close()
class userConfig(object):
@@ -104,7 +104,7 @@ class userConfig(object):
# No such file or directory:
# u'XXX\\AppData\\Local\\pesterchum/profiles/XXX.js'
# Part 2 :(
- if self.config.has_key("defaultprofile"):
+ if "defaultprofile" in self.config:
try:
self.userprofile = userProfile(self.config["defaultprofile"])
except:
@@ -125,7 +125,7 @@ class userConfig(object):
json.dump(self.groups, fp)
def chums(self):
- if not self.config.has_key('chums'):
+ if 'chums' not in self.config:
self.set("chums", [])
return self.config.get('chums', [])
def setChums(self, newchums):
@@ -148,19 +148,19 @@ class userConfig(object):
def tabs(self):
return self.config.get("tabs", True)
def tabMemos(self):
- if not self.config.has_key('tabmemos'):
+ if 'tabmemos' not in self.config:
self.set("tabmemos", self.tabs())
return self.config.get("tabmemos", True)
def showTimeStamps(self):
- if not self.config.has_key('showTimeStamps'):
+ if 'showTimeStamps' not in self.config:
self.set("showTimeStamps", True)
return self.config.get('showTimeStamps', True)
def time12Format(self):
- if not self.config.has_key('time12Format'):
+ if 'time12Format' not in self.config:
self.set("time12Format", True)
return self.config.get('time12Format', True)
def showSeconds(self):
- if not self.config.has_key('showSeconds'):
+ if 'showSeconds' not in self.config:
self.set("showSeconds", False)
return self.config.get('showSeconds', False)
def sortMethod(self):
@@ -174,11 +174,11 @@ class userConfig(object):
return g[1]
return True
def showEmptyGroups(self):
- if not self.config.has_key('emptyGroups'):
+ if 'emptyGroups' not in self.config:
self.set("emptyGroups", False)
return self.config.get('emptyGroups', False)
def showOnlineNumbers(self):
- if not self.config.has_key('onlineNumbers'):
+ if 'onlineNumbers' not in self.config:
self.set("onlineNumbers", False)
return self.config.get('onlineNumbers', False)
def logPesters(self):
@@ -238,7 +238,7 @@ class userConfig(object):
newchums = [c for c in self.config['chums'] if c != handle]
self.set("chums", newchums)
def getBlocklist(self):
- if not self.config.has_key('block'):
+ if 'block' not in self.config:
self.set('block', [])
return self.config['block']
def addBlocklist(self, handle):
@@ -251,7 +251,7 @@ class userConfig(object):
l.pop(l.index(handle))
self.set('block', l)
def getGroups(self):
- if not self.groups.has_key('groups'):
+ if 'groups' not in self.groups:
self.saveGroups([["Chums", True]])
return self.groups.get('groups', [["Chums", True]])
def addGroup(self, group, open=True):
@@ -301,7 +301,7 @@ class userConfig(object):
return self.parent.portOverride
return self.config.get('port', '6667')
def soundOn(self):
- if not self.config.has_key('soundon'):
+ if 'soundon' not in self.config:
self.set('soundon', True)
return self.config['soundon']
def chatSound(self):
@@ -356,7 +356,7 @@ class userProfile(object):
if type(user) is PesterProfile:
self.chat = user
self.userprofile = {"handle":user.handle,
- "color": unicode(user.color.name()),
+ "color": str(user.color.name()),
"quirks": [],
"theme": "pesterchum"}
self.theme = pesterTheme("pesterchum")
@@ -382,8 +382,8 @@ class userProfile(object):
self.userprofile = json.load(fp)
except:
- msgBox = QtGui.QMessageBox()
- msgBox.setIcon(QtGui.QMessageBox.Information)
+ msgBox = QtWidgets.QMessageBox()
+ msgBox.setIcon(QtWidgets.QMessageBox.Information)
msgBox.setWindowTitle(":(")
self.filename = _datadir+"pesterchum.js"
msgBox.setText("Failed to open \"" + \
@@ -449,7 +449,7 @@ class userProfile(object):
self.save()
def setColor(self, color):
self.chat.color = color
- self.userprofile["color"] = unicode(color.name())
+ self.userprofile["color"] = str(color.name())
self.save()
def setQuirks(self, quirks):
self.quirks = quirks
@@ -467,7 +467,7 @@ class userProfile(object):
try:
for (i,m) in enumerate(mentions):
re.compile(m)
- except re.error, e:
+ except re.error as e:
logging.error("#%s Not a valid regular expression: %s" % (i, e))
else:
self.mentions = mentions
@@ -516,7 +516,7 @@ class userProfile(object):
fp.write(jsonoutput)
def saveNickServPass(self):
# remove profiles with no passwords
- for h,t in self.passwd.items():
+ for h,t in list(self.passwd.items()):
if "auto" not in t and ("pw" not in t or t["pw"] == ""):
del self.passwd[h]
try:
@@ -550,7 +550,7 @@ class PesterProfileDB(dict):
json.dump(chumdict, fp)
u = []
- for (handle, c) in chumdict.iteritems():
+ for (handle, c) in chumdict.items():
options = dict()
if 'group' in c:
options['group'] = c['group']
@@ -567,38 +567,38 @@ class PesterProfileDB(dict):
def save(self):
try:
with open("%s/chums.js" % (self.logpath), 'w') as fp:
- chumdict = dict([p.plaindict() for p in self.itervalues()])
+ chumdict = dict([p.plaindict() for p in self.values()])
json.dump(chumdict, fp)
except Exception as e:
raise e
def getColor(self, handle, default=None):
- if not self.has_key(handle):
+ if handle not in self:
return default
else:
return self[handle].color
def setColor(self, handle, color):
- if self.has_key(handle):
+ if handle in self:
self[handle].color = color
else:
self[handle] = PesterProfile(handle, color)
def getGroup(self, handle, default="Chums"):
- if not self.has_key(handle):
+ if handle not in self:
return default
else:
return self[handle].group
def setGroup(self, handle, theGroup):
- if self.has_key(handle):
+ if handle in self:
self[handle].group = theGroup
else:
self[handle] = PesterProfile(handle, group=theGroup)
self.save()
def getNotes(self, handle, default=""):
- if not self.has_key(handle):
+ if handle not in self:
return default
else:
return self[handle].notes
def setNotes(self, handle, notes):
- if self.has_key(handle):
+ if handle in self:
self[handle].notes = notes
else:
self[handle] = PesterProfile(handle, notes=notes)
@@ -626,7 +626,7 @@ class pesterTheme(dict):
except IOError:
theme = json.loads("{}")
self.update(theme)
- if self.has_key("inherits"):
+ if "inherits" in self:
self.inheritedTheme = pesterTheme(self["inherits"])
if not default:
self.defaultTheme = pesterTheme("pesterchum", default=True)
@@ -653,8 +653,8 @@ class pesterTheme(dict):
raise e
return v
def pathHook(self, d):
- for (k, v) in d.iteritems():
- if isinstance(v, unicode):
+ for (k, v) in d.items():
+ if isinstance(v, str):
s = Template(v)
d[k] = s.safe_substitute(path=self.path)
return d
@@ -680,6 +680,6 @@ class pesterTheme(dict):
return (v is not None)
except KeyError:
if hasattr(self, 'inheritedTheme'):
- return self.inheritedTheme.has_key(key)
+ return key in self.inheritedTheme
else:
return False
diff --git a/py2app.sh b/py2app.sh
deleted file mode 100755
index bb413a4..0000000
--- a/py2app.sh
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/bin/bash
-
-## Cleanup
-rm -rf build/ dist/
-rm -f Pesterchum.dmg
-
-### Force build with custom installed frameworky python not system python
-/Library/Frameworks/Python.framework/Versions/2.6/bin/python setup-py2app.py py2app
-#python setup-py2app.py py2app
-#
-### Do some .app tings
-touch dist/Pesterchum.app/Contents/Resources/qt.conf
-find dist/Pesterchum.app -iname "*_debug" -exec rm -f '{}' \;
-
-## Create a dmg file to hold everything
-VERSION=$(python version.py) #"3.41.2 Beta 5"
-SIZE=2000
-name="Pesterchum"
-title="${name} ${VERSION}"
-CHANGELOG="Changelog.rtf"
-PYQUIRKS="Python Quirks.rtf"
-TODO="To Do.rtf"
-README="Read Me!.rtf"
-## Make a proper installer dmg not just effectively a zip file.
-#
-# Most of this is from http://stackoverflow.com/questions/96882/
-# I've fiddled with it a little
-
-# Store the background picture (in PNG format) in a folder called ".background"
-# in the DMG, and store its name in the "backgroundPictureName" variable.
-
-mkdir dist/.background
-cp MacBuild/dmg_background.png dist/.background/display.png
-
-# Convert markdown files to rich text files
-convert=~/Library/Haskell/bin/pandoc
-if ! test -e "${convert}"
-then
- echo "Please install pandoc from http://johnmacfarlane.net/pandoc/" 1>&2
- exit 1
-fi
-
-echo "Converting CHANGELOG . . . "
-$convert --standalone --smart --from=markdown --to=rtf --output="dist/${CHANGELOG}" CHANGELOG.mkdn
-echo "Converting PYQUIRKS . . ."
-$convert --standalone --smart --from=markdown --to=rtf --output="dist/${PYQUIRKS}" PYQUIRKS.mkdn
-echo "Converting TODO . . ."
-$convert --standalone --smart --from=markdown --to=rtf --output="dist/${TODO}" TODO.mkdn
-echo "Converting README . . ."
-$convert --standalone --smart --from=markdown --to=rtf --output="dist/${README}" README.mkdn
-
-# Create a R/W DMG. It must be larger than the result will be.
-# In this example, the bash variable "size" contains the size
-# in Kb and the contents of the folder in the "source" bash
-# variable will be copied into the DMG:
-# Note: I've removed the size argument
-
-echo "Creating initial DMG file . . ."
-hdiutil create -srcfolder "./dist" -volname "${title}" -fs HFS+ \
- -fsargs "-c c=64,a=16,e=16" -format UDRW pack.temp.dmg
-
-# Mount the disk image, and store the device name
-# (you might want to use sleep for a few seconds after this operation):
-
-echo "Mounting initial DMG file . . ."
-device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \
- egrep '^/dev/' | sed 1q | awk '{print $1}')
-sleep 2
-
-
-
-# Use AppleScript to set the visual styles (name of .app must be in bash variable
-# "applicationName", use variables for the other properties as needed):
-base=100
-iconsize=72
-padding=18
-echo "Making DMG file pretty with Applescript . . ."
-echo '
- tell application "Finder"
- tell disk "'${title}'"
- open
- set current view of container window to icon view
- set toolbar visible of container window to false
- set statusbar visible of container window to false
- set the bounds of container window to {400, 100, 885, 430}
- set theViewOptions to the icon view options of container window
- set arrangement of theViewOptions to not arranged
- set icon size of theViewOptions to 72
- set background picture of theViewOptions to file ".background:display.png"
- make new alias file at container window to POSIX file "/Applications" with properties {name:"Applications"}
- -- Positions
- set position of item "'${name}'.app" of container window to {100, 100}
- set position of item "Applications" of container window to {375, 100}
- set position of item "'${README}'" of container window to {'${base}+${iconsize}*0+${padding}*0', 244}
- set position of item "'${CHANGELOG}'" of container window to {'${base}+${iconsize}*1+${padding}*1', 244}
- set position of item "'${PYQUIRKS}'" of container window to {'${base}+${iconsize}*2+${padding}*2', 244}
- set position of item "'${TODO}'" of container window to {'${base}+${iconsize}*3+${padding}*3', 244}
- -- Visibility
- set extension hidden of item "'${CHANGELOG}'" of container window to true
- set extension hidden of item "'${PYQUIRKS}'" of container window to true
- set extension hidden of item "'${TODO}'" of container window to true
- set extension hidden of item "'${README}'" of container window to true
- close
- open
- update without registering applications
- delay 5
- eject
- end tell
- end tell
-' | osascript
-
-# This took so long to work out how to do ._.
-# Stolen from http://lists.apple.com/archives/darwin-userlevel/2007/Oct/msg00000.html
-# Set the SLA to read only (dunno why)
-echo "Converting initial DMG file to a UDRO one . . ."
-hdiutil convert -ov -format UDRO -o "sla.temp.dmg" "pack.temp.dmg"
-# Inflate the dmg
-echo "Inflating UDRO DMG file . . ."
-hdiutil unflatten "sla.temp.dmg"
-# Attach the GPL
-echo "Attaching GPL licence . . ."
-Rez -a MacBuild/GPL.res -o "sla.temp.dmg"
-# Steamroller again
-echo "Deflating UDRO DMG file . . ."
-hdiutil flatten "sla.temp.dmg"
-
-# Finialize the DMG by setting permissions properly, compressing and releasing it:
-
-#chmod -Rf go-w /Volumes/"${title}"
-sync
-#hdiutil detach ${device}
-echo "Compressing UDRO DMG file to UDZO for release . . ."
-hdiutil convert "sla.temp.dmg" -format UDZO -imagekey zlib-level=6 -o "${name}.dmg"
-
-# Get rid of the bits
-echo "Cleaning up . . ."
-rm -f pack.temp.dmg
-rm -f sla.temp.dmg
-rm -rf build/ dist/
diff --git a/pyquirks.py b/pyquirks.py
index 8ecf999..19f256e 100644
--- a/pyquirks.py
+++ b/pyquirks.py
@@ -1,6 +1,6 @@
import os, sys, imp, re, ostools
from quirks import ScriptQuirks
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
class PythonQuirks(ScriptQuirks):
def loadModule(self, name, filename):
@@ -12,21 +12,21 @@ class PythonQuirks(ScriptQuirks):
def modHas(self, module, attr):
if attr == 'commands':
variables = vars(module)
- for name, obj in variables.iteritems():
+ for name, obj in variables.items():
if self.modHas(obj, 'command'):
return True
return hasattr(module, attr)
def register(self, module):
variables = vars(module)
- for name, obj in variables.iteritems():
+ for name, obj in variables.items():
if self.modHas(obj, 'command'):
try:
- if not isinstance(obj("test"), basestring):
+ if not isinstance(obj("test"), str):
raise Exception
except:
- print "Quirk malformed: %s" % (obj.command)
- msgbox = QtGui.QMessageBox()
+ print("Quirk malformed: %s" % (obj.command))
+ msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Error!")
msgbox.setText("Quirk malformed: %s" % (obj.command))
msgbox.exec_()
diff --git a/quirks.py b/quirks.py
index 48e3b85..9f32246 100644
--- a/quirks.py
+++ b/quirks.py
@@ -1,5 +1,5 @@
import os, sys, re, ostools
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
class ScriptQuirks(object):
def __init__(self):
@@ -20,7 +20,7 @@ class ScriptQuirks(object):
self.last = self.quirks.copy()
self.quirks.clear()
for script in self.scripts:
- print script.getExtension()
+ print(script.getExtension())
script.load()
#print script.quirks
for q in script.quirks:
@@ -31,9 +31,9 @@ class ScriptQuirks(object):
del self.quirks[k]
#print self.quirks
if self.quirks:
- print 'Registered quirks:', '(), '.join(self.quirks) + "()"
+ print('Registered quirks:', '(), '.join(self.quirks) + "()")
else:
- print "Warning: Couldn't find any script quirks"
+ print("Warning: Couldn't find any script quirks")
def add(self, script):
self.scripts.append(script)
@@ -65,8 +65,8 @@ class ScriptQuirks(object):
if module is None:
continue
except Exception as e:
- print "Error loading %s: %s (in quirks.py)" % (os.path.basename(name), e)
- msgbox = QtGui.QMessageBox()
+ print("Error loading %s: %s (in quirks.py)" % (os.path.basename(name), e))
+ msgbox = QtWidgets.QMessageBox()
msgbox.setWindowTitle("Error!")
msgbox.setText("Error loading %s: %s (in quirks.py)" % (os.path.basename(filename), e))
msgbox.exec_()
diff --git a/quirks/example.lua b/quirks/example.lua
deleted file mode 100644
index 82f8045..0000000
--- a/quirks/example.lua
+++ /dev/null
@@ -1,18 +0,0 @@
-module(..., package.seeall)
-commands = {}
-
-local function upper(text)
- return string.upper(text)
-end
-commands.luaupper = upper
-
-local function lower(text)
- return string.lower(text)
-end
-commands.lualower = lower
-
-local function utf8reverse(text)
- return text:gsub("([\194-\244][\128-\191]+)", string.reverse):reverse()
-end
-commands.luareverse = utf8reverse
-
diff --git a/randomer.py b/randomer.py
index ff62399..511128e 100644
--- a/randomer.py
+++ b/randomer.py
@@ -1,4 +1,4 @@
-from PyQt4 import QtGui, QtCore
+from PyQt5 import QtCore, QtGui, QtWidgets
RANDNICK = "randomEncounter"
@@ -58,12 +58,12 @@ class RandomHandler(QtCore.QObject):
pass
elif code == "!":
if l[1] == "x":
- from PyQt4 import QtGui
- msgbox = QtGui.QMessageBox()
+ from PyQt5 import QtGui, QtWidgets
+ msgbox = QtWidgets.QMessageBox()
msgbox.setText("Unable to fetch you a random encounter!")
msgbox.setInformativeText("Try again later :(")
msgbox.exec_()
return
- name = unicode(l[1])
- print name
+ name = str(l[1])
+ print(name)
self.mainwindow.newConversation(name)
diff --git a/server.json b/server.json
deleted file mode 100644
index fce98d0..0000000
--- a/server.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "server": "pesterchum.xyz"
-}
\ No newline at end of file
diff --git a/smilies/Suckers.gif b/smilies/Suckers.gif
deleted file mode 100644
index ff5a89f..0000000
Binary files a/smilies/Suckers.gif and /dev/null differ
diff --git a/smilies/acceptant.png b/smilies/acceptant.png
deleted file mode 100644
index 163ee04..0000000
Binary files a/smilies/acceptant.png and /dev/null differ
diff --git a/smilies/apple.png b/smilies/apple.png
deleted file mode 100644
index b1462d9..0000000
Binary files a/smilies/apple.png and /dev/null differ
diff --git a/smilies/bathearst.png b/smilies/bathearst.png
deleted file mode 100644
index e47162f..0000000
Binary files a/smilies/bathearst.png and /dev/null differ
diff --git a/smilies/blacktear.png b/smilies/blacktear.png
deleted file mode 100644
index 8c91ad8..0000000
Binary files a/smilies/blacktear.png and /dev/null differ
diff --git a/smilies/blueslimer.gif b/smilies/blueslimer.gif
deleted file mode 100644
index 7a2f8eb..0000000
Binary files a/smilies/blueslimer.gif and /dev/null differ
diff --git a/smilies/blueslimer.png b/smilies/blueslimer.png
deleted file mode 100644
index 4db51ec..0000000
Binary files a/smilies/blueslimer.png and /dev/null differ
diff --git a/smilies/box.png b/smilies/box.png
deleted file mode 100644
index 8443c23..0000000
Binary files a/smilies/box.png and /dev/null differ
diff --git a/smilies/candycorn.png b/smilies/candycorn.png
deleted file mode 100644
index 6ca85c5..0000000
Binary files a/smilies/candycorn.png and /dev/null differ
diff --git a/smilies/cathearst.png b/smilies/cathearst.png
deleted file mode 100644
index 82fca88..0000000
Binary files a/smilies/cathearst.png and /dev/null differ
diff --git a/smilies/cheer.gif b/smilies/cheer.gif
deleted file mode 100644
index 8d2c8cd..0000000
Binary files a/smilies/cheer.gif and /dev/null differ
diff --git a/smilies/cheer.png b/smilies/cheer.png
deleted file mode 100644
index 16d3b8f..0000000
Binary files a/smilies/cheer.png and /dev/null differ
diff --git a/smilies/confusedjohn.gif b/smilies/confusedjohn.gif
deleted file mode 100644
index 9298353..0000000
Binary files a/smilies/confusedjohn.gif and /dev/null differ
diff --git a/smilies/confusedjohn.png b/smilies/confusedjohn.png
deleted file mode 100644
index 2bc5e43..0000000
Binary files a/smilies/confusedjohn.png and /dev/null differ
diff --git a/smilies/datrump.png b/smilies/datrump.png
deleted file mode 100644
index af259b4..0000000
Binary files a/smilies/datrump.png and /dev/null differ
diff --git a/smilies/detestful.png b/smilies/detestful.png
deleted file mode 100644
index dc573df..0000000
Binary files a/smilies/detestful.png and /dev/null differ
diff --git a/smilies/devious.png b/smilies/devious.png
deleted file mode 100644
index eae4799..0000000
Binary files a/smilies/devious.png and /dev/null differ
diff --git a/smilies/discontent.png b/smilies/discontent.png
deleted file mode 100644
index 546a2eb..0000000
Binary files a/smilies/discontent.png and /dev/null differ
diff --git a/smilies/distraught.png b/smilies/distraught.png
deleted file mode 100644
index c923891..0000000
Binary files a/smilies/distraught.png and /dev/null differ
diff --git a/smilies/ecstatic.png b/smilies/ecstatic.png
deleted file mode 100644
index edb062e..0000000
Binary files a/smilies/ecstatic.png and /dev/null differ
diff --git a/smilies/facepalm.png b/smilies/facepalm.png
deleted file mode 100644
index e5bc561..0000000
Binary files a/smilies/facepalm.png and /dev/null differ
diff --git a/smilies/headbonk.gif b/smilies/headbonk.gif
deleted file mode 100644
index 8767d0f..0000000
Binary files a/smilies/headbonk.gif and /dev/null differ
diff --git a/smilies/headbonk.png b/smilies/headbonk.png
deleted file mode 100644
index ac67711..0000000
Binary files a/smilies/headbonk.png and /dev/null differ
diff --git a/smilies/honk.png b/smilies/honk.png
deleted file mode 100644
index e22e8ca..0000000
Binary files a/smilies/honk.png and /dev/null differ
diff --git a/smilies/jadespritehead.gif b/smilies/jadespritehead.gif
deleted file mode 100644
index bb28391..0000000
Binary files a/smilies/jadespritehead.gif and /dev/null differ
diff --git a/smilies/jadespritehead.png b/smilies/jadespritehead.png
deleted file mode 100644
index c4a5fce..0000000
Binary files a/smilies/jadespritehead.png and /dev/null differ
diff --git a/smilies/lilcal.png b/smilies/lilcal.png
deleted file mode 100644
index c418532..0000000
Binary files a/smilies/lilcal.png and /dev/null differ
diff --git a/smilies/manipulative.png b/smilies/manipulative.png
deleted file mode 100644
index d686bbc..0000000
Binary files a/smilies/manipulative.png and /dev/null differ
diff --git a/smilies/mirthful.png b/smilies/mirthful.png
deleted file mode 100644
index e7d54fe..0000000
Binary files a/smilies/mirthful.png and /dev/null differ
diff --git a/smilies/mspa_face.png b/smilies/mspa_face.png
deleted file mode 100644
index 1629678..0000000
Binary files a/smilies/mspa_face.png and /dev/null differ
diff --git a/smilies/mspa_reader.gif b/smilies/mspa_reader.gif
deleted file mode 100644
index 217fb43..0000000
Binary files a/smilies/mspa_reader.gif and /dev/null differ
diff --git a/smilies/mspa_reader.png b/smilies/mspa_reader.png
deleted file mode 100644
index 86730e2..0000000
Binary files a/smilies/mspa_reader.png and /dev/null differ
diff --git a/smilies/olliesouty.gif b/smilies/olliesouty.gif
deleted file mode 100644
index 44ad0ed..0000000
Binary files a/smilies/olliesouty.gif and /dev/null differ
diff --git a/smilies/pc_amazed.png b/smilies/pc_amazed.png
deleted file mode 100644
index 96563ae..0000000
Binary files a/smilies/pc_amazed.png and /dev/null differ
diff --git a/smilies/pc_amazedfirman.png b/smilies/pc_amazedfirman.png
deleted file mode 100644
index 4286405..0000000
Binary files a/smilies/pc_amazedfirman.png and /dev/null differ
diff --git a/smilies/pc_bemused.png b/smilies/pc_bemused.png
deleted file mode 100644
index 68d63e5..0000000
Binary files a/smilies/pc_bemused.png and /dev/null differ
diff --git a/smilies/pc_chummy.png b/smilies/pc_chummy.png
deleted file mode 100644
index 1f2724f..0000000
Binary files a/smilies/pc_chummy.png and /dev/null differ
diff --git a/smilies/pc_distraught.png b/smilies/pc_distraught.png
deleted file mode 100644
index f9126bc..0000000
Binary files a/smilies/pc_distraught.png and /dev/null differ
diff --git a/smilies/pc_distraughtfirman.png b/smilies/pc_distraughtfirman.png
deleted file mode 100644
index 409b308..0000000
Binary files a/smilies/pc_distraughtfirman.png and /dev/null differ
diff --git a/smilies/pc_insolent.png b/smilies/pc_insolent.png
deleted file mode 100644
index 0785670..0000000
Binary files a/smilies/pc_insolent.png and /dev/null differ
diff --git a/smilies/pc_mystified.png b/smilies/pc_mystified.png
deleted file mode 100644
index af0b859..0000000
Binary files a/smilies/pc_mystified.png and /dev/null differ
diff --git a/smilies/pc_pleasant.png b/smilies/pc_pleasant.png
deleted file mode 100644
index 7f41490..0000000
Binary files a/smilies/pc_pleasant.png and /dev/null differ
diff --git a/smilies/pc_pranky.png b/smilies/pc_pranky.png
deleted file mode 100644
index bf26cd1..0000000
Binary files a/smilies/pc_pranky.png and /dev/null differ
diff --git a/smilies/pc_rancorous.png b/smilies/pc_rancorous.png
deleted file mode 100644
index 9da5b9f..0000000
Binary files a/smilies/pc_rancorous.png and /dev/null differ
diff --git a/smilies/pc_tense.png b/smilies/pc_tense.png
deleted file mode 100644
index 63b34e8..0000000
Binary files a/smilies/pc_tense.png and /dev/null differ
diff --git a/smilies/pccool.png b/smilies/pccool.png
deleted file mode 100644
index b4a15b3..0000000
Binary files a/smilies/pccool.png and /dev/null differ
diff --git a/smilies/pckitty.png b/smilies/pckitty.png
deleted file mode 100644
index 6663bbe..0000000
Binary files a/smilies/pckitty.png and /dev/null differ
diff --git a/smilies/pcstrider.png b/smilies/pcstrider.png
deleted file mode 100644
index 72d9f8f..0000000
Binary files a/smilies/pcstrider.png and /dev/null differ
diff --git a/smilies/perky.png b/smilies/perky.png
deleted file mode 100644
index 608ec74..0000000
Binary files a/smilies/perky.png and /dev/null differ
diff --git a/smilies/poolballL.gif b/smilies/poolballL.gif
deleted file mode 100644
index 1c7be73..0000000
Binary files a/smilies/poolballL.gif and /dev/null differ
diff --git a/smilies/poolballS.gif b/smilies/poolballS.gif
deleted file mode 100644
index 6db6ad7..0000000
Binary files a/smilies/poolballS.gif and /dev/null differ
diff --git a/smilies/record.gif b/smilies/record.gif
deleted file mode 100644
index b32c29d..0000000
Binary files a/smilies/record.gif and /dev/null differ
diff --git a/smilies/record.png b/smilies/record.png
deleted file mode 100644
index d668c3e..0000000
Binary files a/smilies/record.png and /dev/null differ
diff --git a/smilies/relaxed.png b/smilies/relaxed.png
deleted file mode 100644
index caf9e6f..0000000
Binary files a/smilies/relaxed.png and /dev/null differ
diff --git a/smilies/saw.gif b/smilies/saw.gif
deleted file mode 100644
index a538325..0000000
Binary files a/smilies/saw.gif and /dev/null differ
diff --git a/smilies/scorpio.gif b/smilies/scorpio.gif
deleted file mode 100644
index e6bf7c6..0000000
Binary files a/smilies/scorpio.gif and /dev/null differ
diff --git a/smilies/shades.png b/smilies/shades.png
deleted file mode 100644
index 6441cee..0000000
Binary files a/smilies/shades.png and /dev/null differ
diff --git a/smilies/sleek.png b/smilies/sleek.png
deleted file mode 100644
index fa4311f..0000000
Binary files a/smilies/sleek.png and /dev/null differ
diff --git a/smilies/slimer.gif b/smilies/slimer.gif
deleted file mode 100644
index 1b9b48d..0000000
Binary files a/smilies/slimer.gif and /dev/null differ
diff --git a/smilies/slimer.png b/smilies/slimer.png
deleted file mode 100644
index aedb2ba..0000000
Binary files a/smilies/slimer.png and /dev/null differ
diff --git a/smilies/squiddle.gif b/smilies/squiddle.gif
deleted file mode 100644
index 2a9c1c3..0000000
Binary files a/smilies/squiddle.gif and /dev/null differ
diff --git a/smilies/squiddle.png b/smilies/squiddle.png
deleted file mode 100644
index 9f16866..0000000
Binary files a/smilies/squiddle.png and /dev/null differ
diff --git a/smilies/tab.gif b/smilies/tab.gif
deleted file mode 100644
index d2e729b..0000000
Binary files a/smilies/tab.gif and /dev/null differ
diff --git a/smilies/tab.png b/smilies/tab.png
deleted file mode 100644
index 6f5fa7a..0000000
Binary files a/smilies/tab.png and /dev/null differ
diff --git a/smilies/theprofessor.png b/smilies/theprofessor.png
deleted file mode 100644
index 9a7b6ed..0000000
Binary files a/smilies/theprofessor.png and /dev/null differ
diff --git a/smilies/trollbro.png b/smilies/trollbro.png
deleted file mode 100644
index 75b6b21..0000000
Binary files a/smilies/trollbro.png and /dev/null differ
diff --git a/smilies/trollc00l.gif b/smilies/trollc00l.gif
deleted file mode 100644
index 39e1674..0000000
Binary files a/smilies/trollc00l.gif and /dev/null differ
diff --git a/smilies/trollcool.png b/smilies/trollcool.png
deleted file mode 100644
index 76dc247..0000000
Binary files a/smilies/trollcool.png and /dev/null differ
diff --git a/smilies/vigorous.png b/smilies/vigorous.png
deleted file mode 100644
index 382e23a..0000000
Binary files a/smilies/vigorous.png and /dev/null differ
diff --git a/smilies/weasel.gif b/smilies/weasel.gif
deleted file mode 100644
index 203157a..0000000
Binary files a/smilies/weasel.gif and /dev/null differ
diff --git a/smilies/weasel.png b/smilies/weasel.png
deleted file mode 100644
index aec489d..0000000
Binary files a/smilies/weasel.png and /dev/null differ
diff --git a/smilies/what.png b/smilies/what.png
deleted file mode 100644
index f632afd..0000000
Binary files a/smilies/what.png and /dev/null differ
diff --git a/smilies/whatdidyoudo.gif b/smilies/whatdidyoudo.gif
deleted file mode 100644
index 7fac68a..0000000
Binary files a/smilies/whatdidyoudo.gif and /dev/null differ
diff --git a/smilies/whatpumpkin.png b/smilies/whatpumpkin.png
deleted file mode 100644
index 57d1275..0000000
Binary files a/smilies/whatpumpkin.png and /dev/null differ
diff --git a/themes.txt b/themes.txt
deleted file mode 100644
index 376ed97..0000000
--- a/themes.txt
+++ /dev/null
@@ -1,474 +0,0 @@
-HOW TO MAKE YOUR OWN THEMES:
-
-Pesterchum 3.14 themes are very flexible and allow you to create
-almost any kind of main window you can imagine (notable exception
-being animation). This document should help you make your own themes
-or make adjustments to existing themes!
-
-Try following along with existing themes -- it'll make this document
-much less confusing!
-
-A note on editing existing themes: Don't edit current themes! If you
-make changes in the existing themes directory, they *will* be
-overwritten when you install any updates.
-
-CREATING A THEME
-----------------
-Every theme is just a separate directory in the "themes"
-directory. That directory contains all the images used in that theme
-as well as a "style.js" file which is the configuration file for the
-theme.
-
-FORMAT
-------
-The theme file is unlike most configuration files. It uses a format
-called JSON, which at its core looks like this:
-
-{"option": "value", "option2": 5, "category": {"option1": [10, 50] } }
-
-The idea is that it's basically a list of: "name": "value"
-separated by commas, inside brackets. So to give another example:
-
-{"color": "red", "size": 50 }
-
-means "color" is "red, and "size" is 50. Note that strings should have
-quotes around them and numbers should not. You can also make certain
-values into categories by making the value a bracketed list, like so:
-
-{"memos": {"color": "red", "size": 50}, "convos": {"color": "green", "size": 50 } }
-
-This creates two categories: memos and convos, each with their own
-color and size value. Also note that spaces don't really matter. It
-helps to indent each category:
-
-{"memos": {"color": "red", "size": 50"},
- "convos": {"color": "green", "size": 50" }
-}
-
-or even
-
-{"memos": {"color": "red",
- "size": 50" },
- "convos": {"color": "green",
- "size": 50" }
-}
-
-SETTINGS
---------
-
-INHERITS: You can make writing themes easier on yourself by using the
-"inherits" setting. This sets all the settings to be the same as the
-inherited theme unless you change it. So you only need to set the
-settings you want to change!
-
-When specifying file locations, you use the term "$path" to represent
-the path to the current theme. The program will automatically
-subtitute the correct location.
-
-A note about styles:
-
-PC3.14 uses Qt's Stylesheets. That means that there are several
-options in the style file that use CSS-like options. Most CSS options
-are actually available in these settings. See this page for details
-about Qt's stylesheets:
-
-http://doc.qt.nokia.com/latest/stylesheet.html
-
-and here for how CSS works:
-
-http://www.w3schools.com/css/default.asp
-
-If you know CSS, note that there is no cascading or need to type in
-tag names. The program does this for you.
-
-CSS values are like this:
-
-background:#000000; font: bold;
-
-with name:value; separated by ";".
-
-NOTE that if you change a style from a theme you inherited, you MUST
-put in all the options the old style had if you want to keep them!
-
-I'll go over some of the most commonly used options in styles:
-
-background-color: Self-explanatory. A note, though: colors can be
-color names ("black"), standard HTML colors ("#000000") or rgba
-(red, green, blue, alpha) values ("rgba(0, 34, 151, 75%)").
-
-background-image: Sets the background image to be this image. You
-specify the location of the image by using "url(location)". So it
-could be: "url($path/background.png)".
-
-background-repeat: Sets how the background should repeat if the area
-is larger than the image. Values are repeat-x, repeat-y, repeat, and
-no-repeat.
-
-border: Sets the border of the item. Should be in the form "Xpx style
-color". Example: "border: 2px solid black;" See reference for styles.
-
-border-top/right/left/bottom: You can specify values for individual
-borders the same way by using these. Example: "border-right: 1px solid
-#ffff00;"
-
-border-image: This one is complicated. Basically it's a good way of
-having a resizable image with borders. See this page for a good
-tutorial: http://www.lrbabe.com/sdoms/borderImage/
-
-border-radius: Set this to a certain pixel length to get a rounded
-border. Example: "border-radius: 4px;"
-
-color: The color to make text. Example: "color: #ff0000;"
-
-font: A shortcut. You can specify most different font properties from
-this setting. Read on...
-
-font-family: A string representing the font name. Be careful as
-everyone's computer may not have the same fonts! Popular fonts like
-"Arial" are fine. Example: "font-family: 'Arial';" Don't forget the
-quotes!
-
-font-size: A font's size in pixels. Example: "font-size: 12px;"
-
-font-style: Basically italic or not. Example: "font-style: italic;"
-
-font-weight: Basically bold or not. Example: "font-weight: bold;"
-
-margin: Sets the amount of space between this object and other
-objects. This is really only useful in memo and conversation
-settings. You can set individual margins for right/left/top/bottom
-by margin-top/left/right/bottom. Examples: "margin-top: 15px;" "margin:
-5px;"
-
-max/min-height/width: Sets the maximum/minimum height/width for something.
-
-padding: Same thing as margin, kinda... basically this sets the space
-between the outside of the box and the stuff inside it. See
-http://doc.qt.nokia.com/latest/stylesheet-customizing.html#the-box-model
-for more detail.
-
-selection-color: The color of the text when an item is
-selected. Example: "selection-color: black;"
-
-selection-background-color: The color of the background of an item
-when it is selected. Example: "selection-background-color: white;"
-
-text-align: Centers, left-justifies, and right-justifies
-text. Example: "text-align: center;"
-
---------
-
-A note about sizes and coordinates:
-
-Wherever it says "size", Pesterchum expects a value of the form [width,
-height], where width and height are NUMBERS. No quotes should be
-involved. Example:
-
-"size": [232,280]
-
-Same with coordinates, and with coordinates, they are always the
-distance away from the top left corner. So [50, 60] would be 50 pixels
-to the right and 60 pixels down.
-
-
-OK, onto the main event:
-
-MAIN
-----
-
-"main": { .... }
-
-This is the section that controls the main chum window.
-
-"style": Sets the style of the main window (as above). This value will
-affect other parts of the window. DO NOT put a background image
-here. You must set that separately; this is necessary to support
-themes that are not square (e.g. gold xl).
-
-"background-image": Sets the background image. This will define the
-shape of your pesterchum! This is your canvas! See the included themes
-for examples of what background images look like.
-
-"size": The size of the window. Usually this is the same as the size
-of your background image.
-
-"icon": The file name of the image you want to appear in the tray and
-your taskbar. Example: "icon": "$path/trayicon.png"
-
-"newmsgicon": The file name of the image that will appear in the tray
-when you have a new message.
-
-"windowtitle": The title of the window.
-
-"close": Category:
- "image": Location of the image of the "X" button.
- "loc": The coordinates of the "X" button.
-Example:
-"close": {"image": "$path/x.png", "loc": [210,2]}
-
-"minimize": Category. Same as "close" but for the minimize button.
-
-"menubar": Category. Contains one element:
- "style": Style of the main menubar.
-
-"menu": Category.
- "style": Style of each individual menu.
- "menuitem": Affects each menu item on the main menu. Usually used
- for spacing.
- "selected": Style information for when you hover over a menu option.
- "loc": Location of the main menubar.
-
-"sounds": Category.
- "alertsound": Path to the alert sound. Should be a wav.
- "ceasesound": Path to the sound when people cease pestering.
-
-"menus": Category. This is where you change the text of the menus.
- "client": Category. The client menu.
- "_name": The text for the client menu header.
- (These are self explanatory:)
- "options"
- "memos"
- "userlist"
- "import"
- "reconnect"
- "idle"
- "exit"
- "profile": Category. Profile menu.
- "_name": Text of the profile menu header.
- "switch"
- "color"
- "theme"
- "block"
- "quirks"
- "help": Category. Help menu.
- "_name": Text of the help menu header
- "about"
- "rclickchumlist": Category. Text for right click menus.
- "pester"
- "removechum"
- "blockchum"
- "addchum"
- "unblockchum"
- "banuser"
- "opuser"
- "quirksoff"
-
-"chums": Category. Creates your chumroll, where all the users are. All
-of them.
-
- "style": Style for the chumroll
- "loc": Location of the chumroll
- "size": Size of the chumroll
- "userlistcolor": Default text color of the users
- "moods": Category. Contains a list of mood icons and colors; when a
- user has that mood, their handle will appear with that icon and text
- color. Basically follows the form "mood": { "icon": "$path/file.png", "color": "colorname" }
- Moods are:
- "chummy", "rancorous", "offline", "pleasant", "distraught",
- "pranky", "smooth", "mystified", "amazed", "insolent", "bemused",
- "ecstatic", "relaxed", "discontent", "devious", "sleek",
- "detestful", "mirthful", "manipulative", "vigorous", "perky",
- "acceptant", "protective", "blocked"
- (Note: blocked is not technically a "mood", but the icon is used
- when you block someone.)
-
- "trollslum": Category. The settings for the trollslum.
- "style": Style for the trollslum.
- "size": Size of the window.
- "label": Category. Sets the label of the trollslum.
- "style": Style of the label.
- "text": The text displayed.
- "chumroll": Category.
- "style": Sets the style for the list of users.
-
- "mychumhandle": Category. Settings for the text label, the user's
- current handle, and color swatch.
- "label": Category.
- "text": Text of label indicating chumhandle.
- "loc": Location of label.
- "style": Style of label.
- "handle": Category. User's current handle.
- "style": Style of handle.
- "loc": Location of handle.
- "size": Size of handle.
- "colorswatch": Category. Color swatch.
- "loc": Location of swatch.
- "size": Size of swatch.
- "text": Text displayed inside swatch.
- "currentmood": Location of icon of user's current mood.
-
- "defaultwindow": Category.
- "style": Style of the default window. (Quirks, profile changer,
- etc)
-
- "addchum": Category. Add chum button.
- "style": Style of button.
- "pressed": Style of button when pressed down.
- "loc": Location of button.
- "size": Size of button.
- "text": Text of button.
- The same attributes apply for these categories:
- "pester": Button to pester selected user.
- "block": Button to block selected user.
-
- "defaultmood": Default mood of this theme.
- "moodlabel": Category. Text label indicating mood buttons.
- "style": Style of label.
- "loc": Location of label.
- "text": Text of label.
-
- "moods": OK this can get complicated. Basically this is a list of
- categories, one for each mood button present in the interface. You
- make a list like this example:
-
-"moods": [{"style": "", "option": "value"}, {"style": "", "option": "value"}]
-
- The square brackets are important!
- Anyway, for each mood, here are the possible settings:
- "style": Style of the mood button.
- "selected": Style of the mood button when selected.
- "loc": Location of the mood button.
- "size": Size of the mood button.
- "text": Text displayed on the mood button.
- "icon": Path to icon displayed on the mood button.
- "mood": Mood # of the button. See mood numbers -> mood names index
- at the end of this document.
-
-CONVO SECTION
--------------
-
-{"main": { ... },
- "convo": { ... }
-
-This controls the conversation windows.
-
- "style": Style of the conversation window. Only affects the main
- window; does not cascade to the other parts.
- "scrollbar": Category. This item is OPTIONAL. It can be a little
- complicated: if you add this item, you MUST specify ALL of the
- settings yourself. If you don't add this item, it will use default
- system scrollbars. If you are inheriting a theme that does have
- scrollbar customization and you want to remove it, enter "scrollbar: null".
-
- Anyway, onto the scrollbar options:
- "style": General style of whole scrollbar.
- "handle": Style for the handle of the scrollbar.
- "downarrow": Style for the down arrow.
- "darrowstyle": Generally this is where you set the image of the
- down arrow with "image:url($path/downarrow.png)".
- "uparrow": Same as down arrow.
- "uarrowstyle": Same as darrowstyle but for up arrow.
-
- "margins": Category. Sets the margins around the contents of the
- conversation window.
- "top": Top margin
- "bottom", "left", "right"
-
- "size": Initial size of the conversation window.
- "chumlabel": Category. The part that says who youre chatting with.
- "style": Style for the chumlabel.
- "align": Category.
- "h": Horizontal alignment
- "v": Vertical alignment
- "minheight": The minimum height the chum label can be.
- "maxheight": The tallest the chum label can be.
- "text": The text of the label. Use $handle to represent the name
- of the person you're talking to. Example: ":: $handle ::"
-
- "textarea": Category. The window with the pesterlog in it.
- "style": Style of the window.
-
- "input": Category. The place where you type.
- "style": Style of the input area.
-
- "tabwindow": Category. The window that holds the tabs.
- "style": Style of the window.
-
- "tabs": Category. Style of the tabs in tabbed conversation.
- "style": Style of the tabs.
- "selectedstyle": Style of the currently selected tabs.
- "newmsgcolor": The color the text should turn when you get a new
- msg.
- "tabstyle": Usually 0. See the Qt Stylesheets for more
- information.
-
- "text": Category. Flavor text for system messages. In the following
- examples, the text in all caps will be replaced with these values:
- "beganpester": " BEGAN PESTERING at