openfetion-2.2.1/0000755000175000017500000000000011561721144012344 5ustar aronaronopenfetion-2.2.1/AUTHORS0000644000175000017500000000004711561721144013415 0ustar aronaronliwenpeng(levin), openfetion-2.2.1/COPYING0000644000175000017500000000271711561721144013406 0ustar aronaron Copyright (C) 2010 levin This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but is provided AS IS, WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and NON-INFRINGEMENT. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. In addition, as a special exception, the copyright holders give permission to link the code of portions of this program with the OpenSSL library under certain conditions as described in each individual source file, and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than OpenSSL. If you modify file(s) with this exception, you may extend this exception to your version of the file(s), but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. If you delete this exception statement from all source files in the program, then also delete it here. openfetion-2.2.1/ChangeLog0000644000175000017500000001123711561721144014122 0ustar aronaron2010-12-26 YunQiang Su * 优化了 API * GTK 版增加了命令行功能,添加了一个纯命令行版 * 迁移到 cmake * 一些界面修改(新关于对话框,对话框不再相互覆盖) 2010-11-27 YunQiang Su * 修复 aes 密码产生函数的安全问题。 2010-11-25 YunQiang Su * 在编译系统中去掉了 fx_share.c,避免 make check 失败。 2010-11-24 YunQiang Su * 修复了多个内存泄露的问题 * 修复了对话框使界面锁死的问题 * libofetion 不输出内部符号,加了版本号 * 去掉了 AC_CHECK_LIB(notify),避免 libofetion 依赖 libnotify * 将 nm 的依赖从 dbus-1 改为 dbus-glib-1,修复了禁用 notify 的时候编译失败 2010-10-24 levin * 修复了登录和运行时的崩溃问题 * 修复了群发短信时的崩溃问题 * 修复了添加好友时的崩溃问题 * 添加了数据本地化,实现了离线登录功能 * 添加了断线自动重连功能 * 添加了空闲时间自动离开功能 * 添加了关闭上线提示的功能 * 优化了登录过程,登录速度更快 * 更换了新版图标,更美观 2010-09-25 levin * 修复了旧版本登录过程中出现的各种崩溃的问题 * 修复了查看聊天记录崩溃的问题 * 修复了查看群功能使用中的崩溃问题 * 更换了图标及提示音,解决了资源文件的版权问题 * 去掉了之前的自绘主题 * 添加了离线不接收飞信信息的功能 * 添加了发送失败提示功能 * 添加了断线提示功能 * 添加了多种常用快捷键 * 对界面做了一些优化,使更美观 2010-08-14 gettextize * configure.ac (AC_CONFIG_FILES): Add po/Makefile.in. 2010-08-14 gettextize * Makefile.am (EXTRA_DIST): Add config.rpath. 2010-07-31 gettextize * Makefile.am (ACLOCAL_AMFLAGS): New variable. (EXTRA_DIST): Add m4/ChangeLog. * configure.ac (AC_CONFIG_FILES): Add po/Makefile.in. 2010-7-20 levin * 添加了联系人搜索功能 * 添加了聊天记录导出功能 * 修复了系统消息导致程序崩溃的bug * 可选择窗体不隐藏到托盘图标 * 增加了聊天窗口关闭快捷键CTRL+Q * 修复了表情提示框的bug * 更换了主题图标 * 优化了代码 2010-6-7 levin * 添加了上线提示和消息提示功能(需要libnotify支持) * 添加了不在线用户头像暗色显示功能 * 修复了头像加载时的内存泄漏,降低内存使用量 * 重写了部分重要的数据结构,加快了运行速度 * 修复了添加好友时的段错误 2010-5-24 levin * 添加了邮箱注册飞信号登录功能 * 添加了直接短信功能 * 完善了用户状态显示 * 完善了停机用户功能限制 * 优化了用户界面 * 修复了崩溃及自动退出的bug 2010-5-7 levin * 修复了因协议变动造成的登录时异常退出的bug * 添加了声音提示功能(需要gstreamer库的支持) * 添加了飞信表情功能 * 修复了用户心情短语过长时界面太宽的bug * 添加了识别用户设备功能,能识别出手机登录的用户 * 增加了窗体位置记忆功能 2010-4-15 levin * 修复了1.2中不能真正删除好友的bug * 设置用户可调整界面大小,解决了上网本界面太大不能正常使用的问题 * 修改了输入设置,解决了ibus,scim等输入发不能发送消息的问题 * 增加了HTTP代理功能 * 增加了聊天界面查看用户信息的功能 2010-4-6 levin * 修复了登录过程中出现断错误的bug * 修复了用户不能真正修改个人设置的bug * 添加了用户设置关闭按钮动作的功能 2010-3-30 levin * 将通信协议更改为飞信v4版本 * 修复了初次创建时需要手动创建.openfetion的bug * 修复了收到系统消息时的bug,屏蔽了系统消息 * 修复了将好友移动分组后好友变成未验证及分组用户数量不变的bug * 限制每次发送消息为180个字,修复了发送大信息时程序崩溃的bug * 修复了添加好友时默认名字的bug * 修改了登录认证算法,登录过程速度提高 * 修改了头像下载过程算法,头像加载速度提高 * 添加了查看任意手机号或飞信号相关信息的功能 * 添加了陌生人聊天的功能 * 添加了短信群发的功能,不限制一次发送数据 * 添加了简单的个性化设置功能 2010-2-25 levin * 程序第一次发布 openfetion-2.2.1/INSTALL0000644000175000017500000000254011561721144013376 0ustar aronaronThis file tells how to build openfetion on your system. PREPARE ======= You need the following things pre-installed on your system: a) pkg-config, the package config system; b) cmake, the make system; c) gettext, GNU locale utilities, if you want to enable Native language support; and d) required libraries: libofetion, glib-2, gtk+-2, gdk-pixbuf-2, gstreamer, if you want to enable sound support, libnotify, if you want to enable notification support, libXScrnSaver, if you want to enable auto-leaving support, NetworkManager and dbus-glib, if you want to enable network monitor support via dbus. CONFIGURE ========= The following options can be turned on/off in cmake: -DNLS=ON|OFF -DGSTREAMER=ON|OFF -DLIBNOTIFY=ON|OFF -DLIBXSS=ON|OFF -DNETWORKMANAGER=ON|OFF Other options can be set via the following macros: BIN_INSTALL_DIR DATA_INSTALL_DIR MAN_INSTALL_DIR RESOURCE_INSTALL_DIR SKIN_INATALL_DIR LOCALE_INSTALL_DIR BUILD ===== Build from /path/to/your/openfetion, execute: $ mkdir build $ cd build/ $ cmake \ -DCMAKE_INSTALL_PREFIX=/path/to/dest \ -DCMAKE_BUILD_TYPE=release \ -DNLS=ON \ -DGSTREAMER=ON \ -DLIBNOTIFY=ON \ -DLIBXSS=ON \ -DNETWORKMANAGER=ON \ .. $ make $ sudo make install DEBUG ===== UNINSTALL ========= To uninstall, run # xargs rm < install_manifest.txt openfetion-2.2.1/INSTALL.standalone0000644000175000017500000000267711561721144015540 0ustar aronaronThis file tells how to build openfetion on your system. This package is a standalone version. PREPARE ======= You need the following things pre-installed on your system: a) pkg-config, the package config system; b) cmake, the make system; c) gettext, GNU locale utilities, if you want to enable Native language support; and d) required libraries: libxml2, sqlite3, openssl, glib-2, gtk+-2, gdk-pixbuf-2, gstreamer, if you want to enable sound support, libnotify, if you want to enable notification support, libXScrnSaver, if you want to enable auto-leaving support, NetworkManager and dbus-glib, if you want to enable network monitor support via dbus. CONFIGURE ========= The following options can be turned on/off in cmake: -DNLS=ON|OFF -DGSTREAMER=ON|OFF -DLIBNOTIFY=ON|OFF -DLIBXSS=ON|OFF -DNETWORKMANAGER=ON|OFF Other options can be set via the following macros: BIN_INSTALL_DIR LIB_INSTALL_DIR DATA_INSTALL_DIR MAN_INSTALL_DIR INCLUDE_INSTALL_DIR RESOURCE_INSTALL_DIR SKIN_INATALL_DIR LOCALE_INSTALL_DIR BUILD ===== Build from /path/to/your/openfetion, execute $ mkdir build $ cd build/ $ cmake \ -DCMAKE_INSTALL_PREFIX=/path/to/dest \ -DCMAKE_BUILD_TYPE=release \ -DNLS=ON \ -DGSTREAMER=ON \ -DLIBNOTIFY=ON \ -DLIBXSS=ON \ -DNETWORKMANAGER=ON \ .. $ make $ sudo make install DEBUG ===== UNINSTALL ========= To uninstall, run # xargs rm < install_manifest.txt openfetion-2.2.1/LICENSE0000644000175000017500000004311011561721144013350 0ustar aronaron GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. 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 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. openfetion-2.2.1/License.OpenSSL0000644000175000017500000000104311561721144015131 0ustar aronaronOpenSSL linking exception -------------------------- If you modify this Program, or any covered work, by linking or combining it with the OpenSSL project's "OpenSSL" library (or a modified version of that library), containing parts covered by the terms of OpenSSL/SSLeay license, the licensors of this Program grant you additional permission to convey the resulting work. Corresponding Source for a non-source form of such a combination shall include the source code for the parts of the OpenSSL library used as well as that of the covered work. openfetion-2.2.1/NEWS0000644000175000017500000000000011561721144013031 0ustar aronaronopenfetion-2.2.1/README0000644000175000017500000000110511561721144013221 0ustar aronaronREADME ====== OpenFetion a IM client based on GTK+2.0, using CHINA MOBILE's Fetion Protocol Version 4. CONTACT ======= If you have problems, questions, ideas or suggestions, please contact me by sending email to levin108@gmail.com, or join the discussion in our mailling list: ofetion@googlegroups.com WEBSITE ======= Visit libofetion code site: http://ofetion.googlecode.com/ for the latest news and downloads, also you can find useful information via the author's blog: http://basiccoder.com/openfetion/ INSTALLATION ============ Please see INSTALL file for more details. openfetion-2.2.1/config-ofetion.h.cmake0000644000175000017500000000035111561721144016501 0ustar aronaron#ifndef _CONFIG_H_ #define _CONFIG_H_ #cmakedefine USE_LIBNOTIFY 1 #cmakedefine USE_GSTREAMER 1 #cmakedefine USE_LIBXSS 1 #cmakedefine USE_NETWORKMANAGER 1 #cmakedefine LIBNOTIFY_OLD 1 #cmakedefine USE_INDICATE 1 #endif //_CONFIG_H_ openfetion-2.2.1/openfetion.10000644000175000017500000000305711561721144014601 0ustar aronaron.TH "OPENFETION" 1 "2010-12-26" "" "" .SH NAME openfetion \- open source implementation of fetion protocol client .SH SYNOPSIS .B openfetion \-f SOURCE \-t DEST \-d MESSAGE .br .B openfetion \-f SOURCE \-m \-d MESSAGE .br .B openfetion \-f SOURCE \-p \-t DEST \-d MESSAGE .br .B openfetion \-f SOURCE \-g NUM .br .SH DESCRIPTION .PP openfetion is a fetion client for Linux based on GTK+2.0, using Fetion Protocol Version 4. .PP It supports most useful functions of China Mobile Fetion, more important, it's small and fast, and is better in look. .TP \fB\-f\fR specify which number you will use to send a message .TP \fB\-t\fR specify which number you will send a message to .TP \fB\-d\fR message you will send .TP \fB\-m\fR send a message to myself .TP \fB\-p\fR send a message to the phone .TP \fB\-g\fR get information of specific mobile number .TP \fB\-h\fR, \fB\-H\fR display this help and exit .SH EXAMPLES .PP send "hello world" to 18788888888: .TP openfetion \-f 15288888888 \-t 1878888888 \-d "hello world" .PP send "hello world" to yourself: .TP openfetion \-m \-f 15288888888 \-d "hello world" .PP get information of 18788888888: .TP openfetion \-f 15288888888 \-g 1878888888 .SH AUTHOR Written by Aron Xu . .RE .PP .SH RESOURCES openfetion home page: http://code.google.com/p/ofetion .RE .PP .SH COPYING Copyright \(co 2009 Aron Xu. License GPLv3+: GNU GPL version 3 or later . .PP This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. .PP openfetion-2.2.1/po/0000755000175000017500000000000011561721144012762 5ustar aronaronopenfetion-2.2.1/po/openfetion.pot0000644000175000017500000007332611561721144015667 0ustar aronaron# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: OpenFetion\n" "Report-Msgid-Bugs-To: http://code.google.com/p/ofetion/issues/list\n" "POT-Creation-Date: 2010-12-13 15:11+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: src/fx_about.c:140 msgid "Openfetion " msgstr "" #: src/fx_about.c:141 msgid "" "OpenFetion is a Fetion client for linux based on GTK+2.0, implementing " "Fetion Protocol Version 4.\n" "It supports most features of Fetion. \n" "What's more, it's lightweight and efficient with intuitive interface.\n" "\n" "Project homepage: " msgstr "" #: src/fx_about.c:176 msgid "" "\n" "Bug report: " msgstr "" #: src/fx_about.c:180 msgid "" "\n" "\n" "Page on author's blog: " msgstr "" #: src/fx_about.c:190 msgid "" "Graduate student at Beijing University of Post & Telecommunication.Love " "Linux,Love OpenSource.Started this project in order to help linux users " "including myself to get a better way to use fetion.\n" "\n" "Blog:" msgstr "" #: src/fx_about.c:234 msgid "" "This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " "Software Foundation; either version 2 of the License, or (at your option) " "any later version.\n" "\n" msgstr "" #: src/fx_about.c:238 msgid "" "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.\n" "\n" msgstr "" #: src/fx_about.c:242 msgid "" "You should have received a copy of the GNU General Public License along with " "this program; if not, see \n" msgstr "" #: src/fx_about.c:271 msgid "" "The Main Contributors\n" "\n" msgstr "" #: src/fx_about.c:307 msgid "" "Make deb package for debian/ubuntu users,maintainer of the PPA of " "openfetion.\n" "Blog:" msgstr "" #: src/fx_about.c:316 msgid "" "Main translater of openfetion,accomplish the internationalisation(i18n) of " "openfetion" msgstr "" #: src/fx_about.c:323 msgid "" "Contributed to the UI development,and fixed some bugs of the UI.\n" "Follow him:" msgstr "" #: src/fx_about.c:331 msgid "" "A good designer,designed a logo and some icons for openfetion,and also " "contributed to the UI design.\n" "Follow him:" msgstr "" #: src/fx_about.c:366 src/fx_main.c:1233 msgid "About OpenFetion" msgstr "" #: src/fx_about.c:379 msgid "Introduction" msgstr "" #: src/fx_about.c:390 msgid "About the author" msgstr "" #: src/fx_about.c:401 msgid "Contributor" msgstr "" #: src/fx_about.c:412 msgid "License" msgstr "" #: src/fx_about.c:425 src/fx_chat.c:563 src/fx_dsms.c:670 src/fx_history.c:146 #: src/fx_many.c:477 src/fx_myself.c:184 src/fx_pggroup.c:206 #: src/fx_sysmsg.c:76 msgid "Close" msgstr "" #: src/fx_add_group.c:73 msgid "Add a buddy group" msgstr "" #: src/fx_add_group.c:76 msgid "Input the name of the new group:" msgstr "" #: src/fx_add_group.c:84 src/fx_addbuddy.c:113 src/fx_app.c:116 #: src/fx_close.c:79 src/fx_code.c:100 src/fx_dsms.c:81 src/fx_edit.c:57 #: src/fx_gedit.c:59 src/fx_lookupres.c:203 src/fx_proxy.c:121 #: src/fx_set.c:207 src/fx_share.c:96 src/fx_smsstat.c:97 msgid "OK" msgstr "" #: src/fx_add_group.c:88 src/fx_addbuddy.c:117 src/fx_app.c:119 #: src/fx_close.c:81 src/fx_code.c:106 src/fx_dsms.c:82 src/fx_edit.c:61 #: src/fx_gedit.c:63 src/fx_head.c:508 src/fx_lookup.c:62 #: src/fx_lookupres.c:206 src/fx_proxy.c:124 src/fx_set.c:211 #: src/fx_share.c:100 src/fx_smsstat.c:101 msgid "Cancel" msgstr "" #: src/fx_addbuddy.c:44 src/fx_bottom.c:93 msgid "Add Buddy" msgstr "" #: src/fx_addbuddy.c:53 src/fx_lookupres.c:141 src/fx_profile.c:80 #: src/fx_set.c:339 msgid "Cell Phone Number:" msgstr "" #: src/fx_addbuddy.c:56 src/fx_lookupres.c:125 src/fx_profile.c:64 #: src/fx_set.c:319 msgid "Fetion Number:" msgstr "" #: src/fx_addbuddy.c:72 msgid "Contact's Information" msgstr "" #: src/fx_addbuddy.c:78 msgid "Group: " msgstr "" #: src/fx_addbuddy.c:81 msgid "Name: " msgstr "" #: src/fx_addbuddy.c:99 msgid "Send Message:" msgstr "" #: src/fx_addbuddy.c:102 msgid "Hello ,I am " msgstr "" #: src/fx_addbuddy.c:194 src/fx_addbuddy.c:204 msgid "You can not add yourself as a friend" msgstr "" #: src/fx_addbuddy.c:223 msgid "" "The contact you want to add has already been in your contact list, please " "don't add him(her) repeatedly!" msgstr "" #: src/fx_addbuddy.c:229 msgid "You have reached the daily limit of adding buddies, please retry later" msgstr "" #: src/fx_addbuddy.c:233 msgid "Add buddy failed. Unknown reason!" msgstr "" #: src/fx_app.c:57 msgid "Receive an Add Buddy request" msgstr "" #: src/fx_app.c:74 #, c-format msgid "Hello ,I am %s , %s" msgstr "" #: src/fx_app.c:83 msgid "Accept and add him(her) to your contact list" msgstr "" #: src/fx_app.c:87 src/fx_profile.c:109 msgid "Note name:" msgstr "" #: src/fx_app.c:95 src/fx_sysmsg.c:74 msgid "View details" msgstr "" #: src/fx_app.c:100 msgid "Add to group:" msgstr "" #: src/fx_app.c:111 msgid "Decline his(her) add buddy request" msgstr "" #: src/fx_app.c:301 msgid "Lookup failed, unknown identity, unknown reason" msgstr "" #: src/fx_bottom.c:85 src/fx_main.c:1299 src/fx_set.c:195 msgid "Personal Settings" msgstr "" #: src/fx_bottom.c:101 msgid "Send a message to myself" msgstr "" #: src/fx_bottom.c:108 src/fx_main.c:1288 msgid "SMS to many" msgstr "" #: src/fx_bottom.c:115 src/fx_dsms.c:540 src/fx_main.c:1290 msgid "SMS directly" msgstr "" #: src/fx_bottom.c:124 msgid "Fetion Group" msgstr "" #: src/fx_bottom.c:129 src/fx_lookup.c:41 msgid "View information of any user (attribution etc)" msgstr "" #: src/fx_bottom.c:136 msgid "Show OpenFetion About dialog" msgstr "" #: src/fx_chat.c:79 #, c-format msgid "The message \"%s\" sent at [%s] send failed,please resend it" msgstr "" #: src/fx_chat.c:91 src/fx_chat.c:96 src/fx_pggroup.c:447 src/fx_pggroup.c:449 #, c-format msgid "%s says: (%s):\n" msgstr "" #: src/fx_chat.c:506 msgid "Emotion" msgstr "" #: src/fx_chat.c:515 msgid "Contact's cell phone" msgstr "" #: src/fx_chat.c:516 msgid "Mesage will be send to Contact's cell phone in long SMS format" msgstr "" #: src/fx_chat.c:526 msgid "Chat logs" msgstr "" #: src/fx_chat.c:526 src/fx_tree.c:643 msgid "View chat logs" msgstr "" #: src/fx_chat.c:532 msgid "Screen jitter" msgstr "" #: src/fx_chat.c:532 msgid "Send a screen jitter" msgstr "" #: src/fx_chat.c:537 msgid "total 180 character left" msgstr "" #: src/fx_chat.c:539 msgid "[180] characters" msgstr "" #: src/fx_chat.c:568 src/fx_dsms.c:666 src/fx_many.c:482 src/fx_myself.c:189 #: src/fx_pggroup.c:211 msgid "Send" msgstr "" #: src/fx_chat.c:665 src/fx_chat.c:744 msgid "Empty messages are not allowed." msgstr "" #: src/fx_chat.c:692 msgid "Message send failed,Unknown Error" msgstr "" #: src/fx_chat.c:754 msgid "" "Sorry, you have reached the quota of free SMS today, SMS messages cannot be " "sent any more today." msgstr "" #: src/fx_chat.c:759 #, c-format msgid "" "%d free SMS messages can be sent(include this one). Free SMS messages: %d " "per month" msgstr "" #: src/fx_chat.c:764 #, c-format msgid "" "tips:if you wnat to send more free sms,please bound your mobileno\n" "at once ,no authentication code needed any more." msgstr "" #: src/fx_chat.c:799 #, c-format msgid "Message sent successfully. You have sent %d SMS, and %d left." msgstr "" #: src/fx_chat.c:879 msgid "Contact is not online. Cannot send screen jitter" msgstr "" #: src/fx_chat.c:958 msgid "" "Run out of your quota, you can still send IM mesages. If want to send more " "free SMS, bind you cell phone number." msgstr "" #: src/fx_chat.c:964 #, c-format msgid "" "Mesage will be sent to contact's cell phone. You have %d free SMS left. If " "want to send more free SMS, bind your cell phone,please." msgstr "" #: src/fx_chat.c:972 #, c-format msgid "" "Messages will be sent to you phone as long SMS messages. You have sent %d, " "and %d left." msgstr "" #: src/fx_chat.c:980 msgid "Message will be sent to contact's fetion" msgstr "" #: src/fx_chat.c:1057 #, c-format msgid "[%d] character" msgstr "" #: src/fx_chat.c:1079 #, c-format msgid "(%d)unread [%s]" msgstr "" #: src/fx_chat.c:1083 #, c-format msgid "Chatting with [%s]" msgstr "" #: src/fx_close.c:55 msgid "Notification" msgstr "" #: src/fx_close.c:67 msgid "Are you sure you want to exit OpenFetion?" msgstr "" #: src/fx_close.c:70 msgid "Exit OpenFetion" msgstr "" #: src/fx_close.c:72 src/fx_set.c:460 msgid "Minimize to Tray" msgstr "" #: src/fx_close.c:73 msgid "Don't notify again" msgstr "" #: src/fx_code.c:48 msgid "Please entry your verification code" msgstr "" #: src/fx_code.c:76 msgid "Click here getting new verification code" msgstr "" #: src/fx_conn.c:131 #, c-format msgid "" "Public IP: %s\n" "IP of last login: %s\n" "Time of last login: %s\n" msgstr "" #: src/fx_conn.c:139 msgid "Getting portrait..." msgstr "" #: src/fx_conn.c:151 msgid "Login successful" msgstr "" #: src/fx_conn.c:220 src/fx_conn.c:878 msgid "Preparing for login" msgstr "" #: src/fx_conn.c:224 src/fx_conn.c:236 src/fx_conn.c:366 src/fx_conn.c:388 #: src/fx_conn.c:675 src/fx_conn.c:690 src/fx_conn.c:718 src/fx_conn.c:882 msgid "Login failed" msgstr "" #: src/fx_conn.c:245 src/fx_conn.c:410 msgid "Getting code picture,please wait..." msgstr "" #: src/fx_conn.c:275 msgid "" "Login failed. \n" "Incorrect cell phone number or password" msgstr "" #: src/fx_conn.c:280 msgid "Loading local user information" msgstr "" #: src/fx_conn.c:318 msgid "" "Detected that this is the first time you login\n" "Downloading configuration file..." msgstr "" #: src/fx_conn.c:322 msgid "Downloading configuration files" msgstr "" #: src/fx_conn.c:325 msgid "Connection has been shutdown by the server" msgstr "" #: src/fx_conn.c:340 msgid "Connecting to proxy server" msgstr "" #: src/fx_conn.c:347 msgid "Connecting to registration server" msgstr "" #: src/fx_conn.c:362 msgid "Registering to SIPC Server" msgstr "" #. start sipc authentication using the response created just now #: src/fx_conn.c:384 msgid "SIPC Indentify" msgstr "" #: src/fx_conn.c:395 src/fx_conn.c:402 src/fx_conn.c:727 src/fx_conn.c:740 #: src/fx_conn.c:870 msgid "Authenticate failed." msgstr "" #: src/fx_conn.c:471 src/fx_conn.c:496 msgid "Initializing main panel" msgstr "" #: src/fx_conn.c:477 msgid "Login sucessful" msgstr "" #: src/fx_conn.c:485 msgid "Ungrouped" msgstr "" #: src/fx_conn.c:493 msgid "Strangers" msgstr "" #: src/fx_conn.c:612 msgid "" "\n" "Connection has been shutdown\n" msgstr "" #: src/fx_conn.c:864 msgid "No local information stored" msgstr "" #: src/fx_conn.c:959 msgid "The action can't be performed in offline state" msgstr "" #: src/fx_dsms.c:68 msgid "" "Fetion has sent the verification code as SMS to your cell phone. Please " "input it." msgstr "" #: src/fx_dsms.c:69 msgid "Verification code" msgstr "" #: src/fx_dsms.c:74 msgid "" "NOTE:A little timelag because of some network reason," "Please Wait......" msgstr "" #: src/fx_dsms.c:206 msgid "Delete this contact" msgstr "" #: src/fx_dsms.c:243 #, c-format msgid "%d/180, will split to %d" msgstr "" #: src/fx_dsms.c:332 #, c-format msgid "Mesage has been send to %s successfully." msgstr "" #: src/fx_dsms.c:338 #, c-format msgid "Mesage didn't send to %s. Please check the phone number of the contact." msgstr "" #: src/fx_dsms.c:352 msgid "Send message failed" msgstr "" #: src/fx_dsms.c:376 msgid "Message sent failed" msgstr "" #: src/fx_dsms.c:429 msgid "Please input a contact" msgstr "" #: src/fx_dsms.c:452 #, c-format msgid "%s said (%s):\n" msgstr "" #: src/fx_dsms.c:546 msgid "" " You will send SMS to contact directly, cost 0.1 RMB/SMS." msgstr "" #: src/fx_dsms.c:635 msgid "" "No Contact\n" "\n" "Please input Phone Number\n" "in the input box above\n" "3 contacts allowed at most" msgstr "" #: src/fx_dsms.c:652 msgid "0/180, will split to 0" msgstr "" #: src/fx_dsms.c:656 msgid "Sign" msgstr "" #: src/fx_edit.c:41 src/fx_tree.c:651 msgid "Edit note name" msgstr "" #: src/fx_edit.c:49 msgid "Please input note name:" msgstr "" #: src/fx_emotion.c:5 msgid "Smile" msgstr "" #: src/fx_emotion.c:6 msgid "Laugh" msgstr "" #: src/fx_emotion.c:7 msgid "Wink" msgstr "" #: src/fx_emotion.c:8 msgid "Surprised" msgstr "" #: src/fx_emotion.c:9 msgid "Tongue smile" msgstr "" #: src/fx_emotion.c:10 msgid "Warm smile" msgstr "" #: src/fx_emotion.c:11 msgid "Angry" msgstr "" #: src/fx_emotion.c:12 msgid "Sad" msgstr "" #: src/fx_emotion.c:13 msgid "Cry" msgstr "" #: src/fx_emotion.c:14 msgid "Awkward" msgstr "" #: src/fx_emotion.c:15 msgid "Irony" msgstr "" #: src/fx_emotion.c:16 msgid "Illed" msgstr "" #: src/fx_emotion.c:17 msgid "Gritting my teeth" msgstr "" #: src/fx_emotion.c:18 msgid "Tired" msgstr "" #: src/fx_emotion.c:19 src/fx_lookupres.c:48 src/fx_profile.c:174 #: src/fx_set.c:421 src/fx_set.c:422 src/fx_set.c:532 msgid "Secrecy" msgstr "" #: src/fx_emotion.c:20 msgid "Googly eyes" msgstr "" #: src/fx_emotion.c:21 msgid "Sleeping Moon" msgstr "" #: src/fx_emotion.c:22 msgid "Rain" msgstr "" #: src/fx_emotion.c:23 msgid "Clock" msgstr "" #: src/fx_emotion.c:24 msgid "Red Heart" msgstr "" #: src/fx_emotion.c:25 msgid "Broken Heart" msgstr "" #: src/fx_emotion.c:26 msgid "Face of Cat" msgstr "" #: src/fx_emotion.c:27 msgid "Face of Dog" msgstr "" #: src/fx_emotion.c:28 msgid "Snail" msgstr "" #: src/fx_emotion.c:29 msgid "Star" msgstr "" #: src/fx_emotion.c:30 msgid "Sun" msgstr "" #: src/fx_emotion.c:31 msgid "Rainbow" msgstr "" #: src/fx_emotion.c:32 msgid "Hug left" msgstr "" #: src/fx_emotion.c:33 msgid "Hug right" msgstr "" #: src/fx_emotion.c:34 msgid "Red Lips" msgstr "" #: src/fx_emotion.c:35 msgid "Red Rose" msgstr "" #: src/fx_emotion.c:36 msgid "Withered Rose" msgstr "" #: src/fx_emotion.c:37 msgid "Gift Box" msgstr "" #: src/fx_emotion.c:38 msgid "Birthday Cake" msgstr "" #: src/fx_emotion.c:39 msgid "Music" msgstr "" #: src/fx_emotion.c:40 msgid "Bulb" msgstr "" #: src/fx_emotion.c:41 msgid "Idea" msgstr "" #: src/fx_emotion.c:42 msgid "Coffee" msgstr "" #: src/fx_emotion.c:43 msgid "Umbrella" msgstr "" #: src/fx_emotion.c:44 msgid "Mobile Phone" msgstr "" #: src/fx_emotion.c:45 msgid "Computer" msgstr "" #: src/fx_emotion.c:46 msgid "Disappointed" msgstr "" #: src/fx_emotion.c:47 msgid "Confused" msgstr "" #: src/fx_emotion.c:48 msgid "Worried" msgstr "" #: src/fx_emotion.c:49 msgid "Drinks" msgstr "" #: src/fx_emotion.c:50 msgid "Goblet" msgstr "" #: src/fx_emotion.c:51 msgid "Angel" msgstr "" #: src/fx_emotion.c:52 msgid "Thinking" msgstr "" #: src/fx_emotion.c:53 msgid "Great" msgstr "" #: src/fx_emotion.c:54 msgid "Naughty" msgstr "" #: src/fx_emotion.c:55 msgid "Idiot" msgstr "" #: src/fx_emotion.c:56 msgid "Sunglasses" msgstr "" #: src/fx_gedit.c:43 src/fx_tree.c:711 msgid "Edit name of a group" msgstr "" #: src/fx_gedit.c:51 msgid "Please entry new name of the group:" msgstr "" #: src/fx_head.c:190 src/fx_set.c:133 src/fx_set.c:138 msgid "Click here to input signature" msgstr "" #: src/fx_head.c:276 src/fx_login.c:320 src/fx_main.c:1220 msgid "Online" msgstr "" #: src/fx_head.c:277 src/fx_login.c:321 src/fx_main.c:1221 msgid "Leave" msgstr "" #: src/fx_head.c:278 src/fx_login.c:322 src/fx_main.c:1222 msgid "Busy" msgstr "" #: src/fx_head.c:279 src/fx_login.c:323 src/fx_main.c:1223 msgid "Hide" msgstr "" #: src/fx_head.c:280 src/fx_login.c:324 msgid "Offline" msgstr "" #: src/fx_head.c:285 src/fx_login.c:325 src/fx_main.c:1224 msgid "Eating out" msgstr "" #: src/fx_head.c:286 src/fx_login.c:326 src/fx_main.c:1225 msgid "Do Not Disturb" msgstr "" #: src/fx_head.c:287 src/fx_login.c:328 src/fx_main.c:1227 msgid "Meeting" msgstr "" #: src/fx_head.c:288 src/fx_login.c:329 src/fx_main.c:1228 msgid "Calling" msgstr "" #: src/fx_head.c:293 src/fx_main.c:1253 msgid "Receive SMS" msgstr "" #: src/fx_head.c:302 msgid "Modify Profile" msgstr "" #: src/fx_head.c:308 src/fx_main.c:1305 msgid "Exit OpenFetion " msgstr "" #: src/fx_head.c:506 msgid "Choose the avatar file to upload" msgstr "" #: src/fx_head.c:508 msgid "Upload" msgstr "" #: src/fx_head.c:564 msgid "" "Upload avatar failed. Note: This appliaction doesn't support auto-" "compression of image. Please be sure that the avater is in 150px × 150px." msgstr "" #: src/fx_history.c:58 #, c-format msgid "View logs with [%s]" msgstr "" #: src/fx_history.c:69 msgid "Show the most recent" msgstr "" #: src/fx_history.c:76 msgid "mesage" msgstr "" #: src/fx_history.c:82 msgid "Refresh" msgstr "" #: src/fx_history.c:89 msgid "Today" msgstr "" #: src/fx_history.c:97 msgid "This Week" msgstr "" #: src/fx_history.c:104 msgid "This Month" msgstr "" #: src/fx_history.c:111 msgid "All" msgstr "" #: src/fx_history.c:119 msgid "Export" msgstr "" #: src/fx_history.c:126 msgid "Cleanup" msgstr "" #: src/fx_history.c:269 msgid "Export File" msgstr "" #: src/fx_history.c:278 #, c-format msgid "logs with %s.txt" msgstr "" #: src/fx_history.c:307 msgid "" "The action can not be undone.\n" "Are you sure you want to continue?" msgstr "" #: src/fx_login.c:63 #, c-format msgid " Proxy[%s]" msgstr "" #: src/fx_login.c:64 src/fx_login.c:69 src/fx_login.c:243 msgid "Off" msgstr "" #: src/fx_login.c:64 src/fx_login.c:69 src/fx_login.c:243 msgid "On" msgstr "" #: src/fx_login.c:68 src/fx_login.c:242 #, c-format msgid " Proxy[%s]" msgstr "" #: src/fx_login.c:118 msgid "Welcome to OpenFetion" msgstr "" #: src/fx_login.c:124 msgid "" "OpenFetion a fetion client for linux based on GTK+2.0, using Fetion " "Protocol Version 4.\n" "OpenFetion is a non-profit software, aiming at making linux users convenient " "to use fetion." msgstr "" #: src/fx_login.c:190 msgid "Cell number or fetion number:" msgstr "" #: src/fx_login.c:202 msgid "Please input password:" msgstr "" #: src/fx_login.c:209 msgid "Status:" msgstr "" #: src/fx_login.c:210 msgid "Login" msgstr "" #: src/fx_login.c:236 msgid "Remember password" msgstr "" #: src/fx_login.c:327 src/fx_main.c:1226 msgid "Back Soon" msgstr "" #: src/fx_lookup.c:49 msgid "Please input the user's phone number or fetion number:" msgstr "" #: src/fx_lookup.c:58 msgid "Find" msgstr "" #: src/fx_lookup.c:90 msgid "Query failed, please input vaild phone number of China Mobile" msgstr "" #: src/fx_lookupres.c:48 src/fx_profile.c:174 src/fx_set.c:531 msgid "Female" msgstr "" #: src/fx_lookupres.c:48 src/fx_profile.c:174 src/fx_set.c:530 msgid "Male" msgstr "" #: src/fx_lookupres.c:60 src/fx_profile.c:186 msgid "China" msgstr "" #: src/fx_lookupres.c:65 src/fx_lookupres.c:72 src/fx_profile.c:191 #: src/fx_profile.c:198 src/fx_tree.c:1220 src/fx_tree.c:1224 msgid "Unknown" msgstr "" #: src/fx_lookupres.c:133 src/fx_profile.c:72 src/fx_set.c:327 msgid "Sex:" msgstr "" #: src/fx_lookupres.c:150 src/fx_profile.c:88 src/fx_set.c:347 msgid "Nickname:" msgstr "" #: src/fx_lookupres.c:158 src/fx_lookupres.c:171 src/fx_profile.c:96 #: src/fx_set.c:354 msgid "Personal Signature:" msgstr "" #: src/fx_lookupres.c:179 src/fx_profile.c:117 msgid "Country:" msgstr "" #: src/fx_lookupres.c:187 src/fx_profile.c:125 src/fx_set.c:362 msgid "Province:" msgstr "" #: src/fx_lookupres.c:195 src/fx_profile.c:133 src/fx_set.c:371 msgid "City:" msgstr "" #: src/fx_main.c:317 #, c-format msgid "%s , now ONLINE" msgstr "" #: src/fx_main.c:319 #, c-format msgid "" "Phone Number: %s\n" "Fetion Number: %s\n" "Signature: %s" msgstr "" #: src/fx_main.c:324 msgid "unknown" msgstr "" #: src/fx_main.c:548 #, c-format msgid "%s(%s) said:" msgstr "" #: src/fx_main.c:825 msgid "Receive a window jitter" msgstr "" #: src/fx_main.c:931 msgid "Your fetion login elsewhere. You are forced quit." msgstr "" #: src/fx_main.c:1240 msgid "Close sound" msgstr "" #: src/fx_main.c:1265 msgid "Information query" msgstr "" #: src/fx_main.c:1269 msgid "Edit statement" msgstr "" #: src/fx_main.c:1285 msgid "Message Function" msgstr "" #: src/fx_main.c:1293 msgid "SMS myself" msgstr "" #: src/fx_main.c:1297 msgid "Add contact" msgstr "" #: src/fx_main.c:1301 src/fx_set.c:201 msgid "System Settings" msgstr "" #: src/fx_many.c:231 #, c-format msgid "" "Choosed [%d] contacts, [%d] more available" msgstr "" #: src/fx_many.c:376 msgid "SMS To Many" msgstr "" #. left top area #: src/fx_many.c:389 msgid "Choose Contacts" msgstr "" #: src/fx_many.c:425 msgid "Contacts Selected" msgstr "" #: src/fx_many.c:432 msgid "" "Choosed [0] contacts, [10000] more available" msgstr "" #: src/fx_many.c:504 msgid "You have not selected contacts" msgstr "" #: src/fx_many.c:533 msgid "Please input the contents of message" msgstr "" #: src/fx_many.c:552 #, c-format msgid "" "Mesage \"%s\" has been sent to \"%s\". You have sent %d today and %d this " "month\n" msgstr "" #: src/fx_many.c:558 #, c-format msgid "Mesage \"%s\" did not send to \"%s\"\n" msgstr "" #: src/fx_myself.c:54 msgid "Sending sms to myself" msgstr "" #: src/fx_pggroup.c:90 msgid "no notice!" msgstr "" #: src/fx_pggroup.c:97 #, c-format msgid "Fetion Group [%s]" msgstr "" #: src/fx_pggroup.c:171 src/fx_tree.c:1792 msgid "Send group message" msgstr "" #: src/fx_pggroup.c:181 msgid "Access group space" msgstr "" #. notice #: src/fx_pggroup.c:223 msgid "Group Notice" msgstr "" #. contact list #: src/fx_pggroup.c:250 msgid "Group Members" msgstr "" #: src/fx_pggroup.c:397 msgid "[Administrator]" msgstr "" #: src/fx_pggroup.c:398 msgid "[Super Administrator]" msgstr "" #: src/fx_pggroup.c:546 msgid "" "Group member who didn't bind fetion number to mobile number can't receive " "the group sms you send" msgstr "" #: src/fx_pggroup.c:653 #, c-format msgid "" "NickName : %s\t\n" "FetionNumber : %s\t\n" msgstr "" #: src/fx_pgprofile.c:54 msgid "Group Details" msgstr "" #: src/fx_pgprofile.c:64 msgid "Basic Information" msgstr "" #: src/fx_pgprofile.c:68 msgid "Group Number:" msgstr "" #: src/fx_pgprofile.c:71 msgid "Group Name:" msgstr "" #: src/fx_pgprofile.c:74 msgid "Administrator:" msgstr "" #: src/fx_pgprofile.c:77 msgid "Create Time:" msgstr "" #: src/fx_pgprofile.c:108 msgid "Group Bulletin:" msgstr "" #: src/fx_pgprofile.c:113 msgid "" "Only visible to group members,less than 256 " "characters" msgstr "" #: src/fx_pgprofile.c:130 msgid "Group Summary:" msgstr "" #: src/fx_pgprofile.c:135 msgid "Visible to anyone,less than 256 characters" msgstr "" #: src/fx_pgprofile.c:187 src/fx_tree.c:208 src/fx_tree.c:936 msgid "%Y-%m-%d" msgstr "" #: src/fx_profile.c:41 src/fx_tree.c:634 msgid "view contact's information" msgstr "" #: src/fx_profile.c:141 msgid "Finish" msgstr "" #: src/fx_proxy.c:71 msgid "Set HTTP Proxy" msgstr "" #: src/fx_proxy.c:80 msgid "Trun on HTTP proxy" msgstr "" #: src/fx_proxy.c:89 msgid "Proxy host" msgstr "" #: src/fx_proxy.c:93 msgid "Port" msgstr "" #: src/fx_proxy.c:105 msgid "Uesrname" msgstr "" #: src/fx_proxy.c:109 msgid "Password" msgstr "" #: src/fx_proxy.c:171 msgid "Please input hostname" msgstr "" #: src/fx_proxy.c:181 msgid "Please input port number" msgstr "" #: src/fx_proxy.c:193 msgid " Proxy [on]" msgstr "" #: src/fx_proxy.c:204 msgid " Proxy [off]" msgstr "" #: src/fx_search.c:58 msgid "" "You can not send messages to him(her), because he(she) is not in your " "contact list" msgstr "" #: src/fx_search.c:66 msgid "User has shut his fetion service, so you can not send a message to him" msgstr "" #: src/fx_set.c:110 msgid "Nick can not be empty!" msgstr "" #: src/fx_set.c:185 msgid "OpenFetion Preference" msgstr "" #: src/fx_set.c:286 msgid "Sorry, I am not in now, and will reply to you soon" msgstr "" #: src/fx_set.c:380 msgid "Job occupation:" msgstr "" #: src/fx_set.c:389 msgid "Email:" msgstr "" #: src/fx_set.c:457 msgid "Appearance" msgstr "" #: src/fx_set.c:463 msgid "Close to Tray" msgstr "" #: src/fx_set.c:466 msgid "Auto popup message" msgstr "" #: src/fx_set.c:469 msgid "Disable Message Notification" msgstr "" #: src/fx_set.c:472 msgid "Mute" msgstr "" #: src/fx_set.c:475 msgid "Auto away when idle" msgstr "" #: src/fx_set.c:478 msgid "Online notification enabled" msgstr "" #: src/fx_set.c:481 msgid "Disable System Message" msgstr "" #: src/fx_set.c:484 msgid "Disable Fetion Show" msgstr "" #: src/fx_set.c:488 msgid "Auto Reply" msgstr "" #: src/fx_set.c:491 msgid "Enable" msgstr "" #: src/fx_set.c:508 msgid "Send Message" msgstr "" #: src/fx_set.c:511 msgid "Press Enter to Send" msgstr "" #: src/fx_set.c:514 msgid "Press CTRL + Enter to Send" msgstr "" #: src/fx_share.c:66 msgid "Transport files by Fetion" msgstr "" #: src/fx_share.c:76 #, c-format msgid "Transporting files OS Revolution.mkv to %s..." msgstr "" #: src/fx_share.c:83 msgid "Progress: " msgstr "" #: src/fx_share.c:93 msgid "Establishing Connection..." msgstr "" #: src/fx_share.c:141 msgid "" "Contact acccept your request of transporting files. " "Transporting..." msgstr "" #: src/fx_smsstat.c:52 msgid "Settings Of Receving Message" msgstr "" #: src/fx_smsstat.c:62 msgid "" "You can set not to receive sms here , even\n" "for a period,in whitch you won`t receive the \n" "sms sent from fetion,but you can still receive \n" "the message from fetion client, the period will be:" msgstr "" #: src/fx_smsstat.c:70 msgid "24 hours" msgstr "" #: src/fx_smsstat.c:77 msgid "3 days" msgstr "" #: src/fx_smsstat.c:84 msgid "1 week" msgstr "" #: src/fx_smsstat.c:91 msgid "forever" msgstr "" #: src/fx_sysmsg.c:62 msgid "System mesage" msgstr "" #: src/fx_tree.c:106 msgid "Only English words are allowed here!" msgstr "" #: src/fx_tree.c:212 #, c-format msgid "" "\n" "Group Name:%s\t\n" "Current Member Count: %d\t\n" "Limit Member Count: %d\t\n" "Group Rank: %d/%d\t\n" "Create Time: %s\t\n" msgstr "" #: src/fx_tree.c:380 msgid "No Group!" msgstr "" #: src/fx_tree.c:627 msgid "Send IM mesages" msgstr "" #: src/fx_tree.c:647 msgid "Refresh information" msgstr "" #: src/fx_tree.c:654 msgid "Hightlight all contacts" msgstr "" #: src/fx_tree.c:654 msgid "Hightlight online contacts" msgstr "" #: src/fx_tree.c:657 msgid "Use big icon" msgstr "" #: src/fx_tree.c:657 msgid "Use small icon" msgstr "" #: src/fx_tree.c:661 msgid "Remove this contact" msgstr "" #: src/fx_tree.c:669 msgid "Move this contact to" msgstr "" #: src/fx_tree.c:709 msgid "Add a new group" msgstr "" #: src/fx_tree.c:714 msgid "Remove this group" msgstr "" #: src/fx_tree.c:845 #, c-format msgid "[Unverified]" msgstr "" #: src/fx_tree.c:849 src/fx_tree.c:856 src/fx_tree.c:860 #, c-format msgid "[Has shut fetion service]" msgstr "" #: src/fx_tree.c:853 #, c-format msgid "[Online with SMS]" msgstr "" #: src/fx_tree.c:866 #, c-format msgid "[Out of service]" msgstr "" #: src/fx_tree.c:885 msgid "[Login with cell phone]" msgstr "" #: src/fx_tree.c:938 #, c-format msgid "" "%s\n" "Create Time: %s" msgstr "" #: src/fx_tree.c:1138 msgid "" "You can not send a message to anyone who has not been in your contact list" msgstr "" #: src/fx_tree.c:1145 msgid "This user have shut fetion service,so you cannot send mesage to him/her" msgstr "" #: src/fx_tree.c:1320 msgid "Remove this contact?" msgstr "" #: src/fx_tree.c:1321 msgid "Remove contact" msgstr "" #: src/fx_tree.c:1488 msgid "Remove this group?" msgstr "" #: src/fx_tree.c:1489 msgid "Remove group" msgstr "" #: src/fx_tree.c:1685 #, c-format msgid "Not bind to a phone number." msgstr "" #: src/fx_tree.c:1688 #, c-format msgid "%s(Out of service)" msgstr "" #: src/fx_tree.c:1689 src/fx_tree.c:1695 msgid "Phone number not be published." msgstr "" #: src/fx_tree.c:1694 msgid "Not bind to a phone number." msgstr "" #: src/fx_tree.c:1698 #, c-format msgid "" " Nickname: %s\n" " Phone Number: %s\n" " Fetion Number: %s\n" " Signature: %s" msgstr "" #: src/fx_tree.c:1794 msgid "Send group sms" msgstr "" #: src/fx_tree.c:1800 msgid "View group details" msgstr "" #: src/fx_util.c:30 src/fx_util.c:61 msgid "[Online]" msgstr "" #: src/fx_util.c:33 msgid "[Busy]" msgstr "" #: src/fx_util.c:36 msgid "[Leave]" msgstr "" #: src/fx_util.c:39 msgid "[Hide]" msgstr "" #: src/fx_util.c:42 msgid "[Eating out]" msgstr "" #: src/fx_util.c:45 msgid "[Do Not Disturb]" msgstr "" #: src/fx_util.c:48 msgid "[Be Back Soon]" msgstr "" #: src/fx_util.c:51 msgid "[Meeting]" msgstr "" #: src/fx_util.c:54 msgid "[Calling]" msgstr "" #: src/fx_util.c:57 msgid "[Offline]" msgstr "" #: src/fx_util.c:63 msgid "[Unknown Statement]" msgstr "" #: src/fx_tree.c:717 msgid "Remove from group" msgstr "" #: src/fx_tree.c:752 msgid "Copy this contact to" msgstr "" #: src/fx_set.c:505 msgid "Don't Use Status Icon(restart)" msgstr "" openfetion-2.2.1/po/zh_CN.po0000644000175000017500000012146411561721144014333 0ustar aronaron# English translations for OpenFetion package. # Copyright (C) 2010 THE OpenFetion'S COPYRIGHT HOLDER # This file is distributed under the same license as the OpenFetion package. # syq , 2010. # levin108 , 2010. # Xhacker Liu , 2010. # xuhdev , 2010. # YunQiang Su , 2010. # msgid "" msgstr "" "Project-Id-Version: openfetion 2.2.0\n" "Report-Msgid-Bugs-To: http://code.google.com/p/ofetion/issues/list\n" "POT-Creation-Date: 2010-12-13 15:11+0800\n" "PO-Revision-Date: 2011-05-03 17:52+0800\n" "Last-Translator: YunQiang Su \n" "Language-Team: Chinese (simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Language: \n" "Plural-Forms: nplurals=1; plural=0;\n" #: src/fx_about.c:180 msgid "" "\n" "\n" "Page on author's blog: " msgstr "" "\n" "\n" "作者的博客:" #: src/fx_tree.c:212 #, c-format msgid "" "\n" "Group Name:%s\t\n" "Current Member Count: %d\t\n" "Limit Member Count: %d\t\n" "Group Rank: %d/%d\t\n" "Create Time: %s\t\n" msgstr "" "\n" "群名称:%s\t\n" "当前群内人数:%d人\t\n" "允许人数上限:%d人\t\n" "群热度:%d/%d\t\n" "创建时间:%s\t\n" #: src/fx_about.c:176 msgid "" "\n" "Bug report: " msgstr "" "\n" "报告 bug:" #: src/fx_conn.c:612 msgid "" "\n" "Connection has been shutdown\n" msgstr "" "\n" "连接已断开\n" #: src/fx_tree.c:1698 #, c-format msgid "" " Nickname: %s\n" " Phone Number: %s\n" " Fetion Number: %s\n" " Signature: %s" msgstr "" " 昵称: %s\n" " 手机: %s\n" " 飞信: %s\n" " 心情: %s" #: src/fx_dsms.c:546 msgid "" " You will send SMS to contact directly, cost 0.1 RMB/SMS." msgstr " 您将发送直接短信直接联系人,资费0.1元/条。" #: src/fx_pgprofile.c:187 src/fx_tree.c:208 src/fx_tree.c:936 msgid "%Y-%m-%d" msgstr "%Y年%m月%d日" #: src/fx_chat.c:759 #, c-format msgid "" "%d free SMS messages can be sent(include this one). Free SMS messages: %d " "per month" msgstr "您还可以发送 %d 条免费短信(含本条),免费短信限额:每月 %d 条" #: src/fx_dsms.c:243 #, c-format msgid "%d/180, will split to %d" msgstr "%d/180,分为%d条短信" #: src/fx_tree.c:938 #, c-format msgid "" "%s\n" "Create Time: %s" msgstr "" "%s\n" "创建时间:%s" #: src/fx_main.c:317 #, c-format msgid "%s , now ONLINE" msgstr "%s , 上线啦" #: src/fx_dsms.c:452 #, c-format msgid "%s said (%s):\n" msgstr "%s 说: (%s):\n" #: src/fx_chat.c:91 src/fx_chat.c:96 src/fx_pggroup.c:447 src/fx_pggroup.c:449 #, c-format msgid "%s says: (%s):\n" msgstr "%s 说: (%s):\n" #: src/fx_main.c:548 #, c-format msgid "%s(%s) said:" msgstr "%s(%s) 说:" #: src/fx_chat.c:1079 #, c-format msgid "(%d)unread [%s]" msgstr "(%d)未读 [%s]" #: src/fx_dsms.c:652 msgid "0/180, will split to 0" msgstr "0/180,分为0条短信" #: src/fx_smsstat.c:84 msgid "1 week" msgstr "1星期" #: src/fx_smsstat.c:70 msgid "24 hours" msgstr "24小时" #: src/fx_smsstat.c:77 msgid "3 days" msgstr "3天" #: src/fx_set.c:457 msgid "Appearance" msgstr "外观" #: src/fx_set.c:488 msgid "Auto Reply" msgstr "自动回复" #: src/fx_dsms.c:635 msgid "" "No Contact\n" "\n" "Please input Phone Number\n" "in the input box above\n" "3 contacts allowed at most" msgstr "" "暂无联系人\n" "\n" "请在上方输入框中输入收信\n" "人手机号\n" "\n" "最多一次添加3个收信人" #: src/fx_tree.c:380 msgid "No Group!" msgstr "您没有加入任何群" #: src/fx_proxy.c:109 msgid "Password" msgstr "密码" #: src/fx_proxy.c:93 msgid "Port" msgstr "端口" #: src/fx_share.c:83 msgid "Progress: " msgstr "进度:" #: src/fx_proxy.c:89 msgid "Proxy host" msgstr "代理主机" #: src/fx_set.c:508 msgid "Send Message" msgstr "发送消息" #: src/fx_proxy.c:105 msgid "Uesrname" msgstr "用户名" #: src/fx_login.c:118 msgid "Welcome to OpenFetion" msgstr "欢迎使用 OpenFetion" #: src/fx_login.c:124 msgid "" "OpenFetion a fetion client for linux based on GTK+2.0, using Fetion " "Protocol Version 4.\n" "OpenFetion is a non-profit software, aiming at making linux users convenient " "to use fetion." msgstr "" "OpenFetion 是一个使用 GTK+2 编写,实现了第四版飞信协议的 Linux 飞信客" "户端。\n" "OpenFetion 是非营利软件,主要目标是方便 Linux 用户使用飞信。" #: src/fx_tree.c:1688 #, c-format msgid "%s(Out of service)" msgstr "%s(停机)" #: src/fx_tree.c:1685 #, c-format msgid "Not bind to a phone number." msgstr "未绑定手机号" #: src/fx_proxy.c:204 msgid " Proxy [off]" msgstr " 网络代理[关闭]" #: src/fx_proxy.c:193 msgid " Proxy [on]" msgstr " 网络代理[开启]" #: src/fx_pggroup.c:397 msgid "[Administrator]" msgstr "[管理员]" #: src/fx_pggroup.c:398 msgid "[Super Administrator]" msgstr "[超级管理员]" #: src/fx_login.c:68 src/fx_login.c:242 #, c-format msgid " Proxy[%s]" msgstr " 网络代理[%s]" #: src/fx_login.c:63 #, c-format msgid " Proxy[%s]" msgstr " 网络代理[%s]" #: src/fx_dsms.c:74 msgid "" "NOTE:A little timelag because of some network reason," "Please Wait......" msgstr "" "注意:短信可能由于网络等原因有一些延迟,请稍候..." #: src/fx_pggroup.c:653 #, c-format msgid "" "NickName : %s\t\n" "FetionNumber : %s\t\n" msgstr "" " 昵称: %s\t\n" " 飞信号: %s\t\n" #: src/fx_pgprofile.c:113 msgid "" "Only visible to group members,less than 256 " "characters" msgstr "仅群成员可见,不超过256个字符" #: src/fx_pgprofile.c:135 msgid "Visible to anyone,less than 256 characters" msgstr "所有人可见,不超过256个字符" #: src/fx_share.c:141 msgid "" "Contact acccept your request of transporting files. " "Transporting..." msgstr "好友接受了传送文件的请求。正在传输..." #: src/fx_share.c:93 msgid "Establishing Connection..." msgstr "正在建立连接..." #: src/fx_tree.c:849 src/fx_tree.c:856 src/fx_tree.c:860 #, c-format msgid "[Has shut fetion service]" msgstr "[已关闭飞信服务]" #: src/fx_tree.c:853 #, c-format msgid "[Online with SMS]" msgstr "[短信在线]" #: src/fx_tree.c:866 #, c-format msgid "[Out of service]" msgstr "[停机]" #: src/fx_tree.c:845 #, c-format msgid "[Unverified]" msgstr "[等待验证]" #: src/fx_proxy.c:171 msgid "Please input hostname" msgstr "请输入主机名" #: src/fx_proxy.c:181 msgid "Please input port number" msgstr "请输入端口号" #: src/fx_about.c:331 msgid "" "A good designer,designed a logo and some icons for openfetion,and also " "contributed to the UI design.\n" "Follow him:" msgstr "" "一位优秀的设计师,为 OpenFetion 设计了 logo 和一些图标,也对界面设计有贡" "献。\n" "关注他:" #: src/fx_about.c:366 src/fx_main.c:1233 msgid "About OpenFetion" msgstr "关于 OpenFetion" #: src/fx_about.c:390 msgid "About the author" msgstr "关于作者" #: src/fx_app.c:83 msgid "Accept and add him(her) to your contact list" msgstr "同意并添加对方为好友" #: src/fx_pggroup.c:181 msgid "Access group space" msgstr "访问群空间" #: src/fx_addbuddy.c:44 src/fx_bottom.c:93 msgid "Add Buddy" msgstr "添加好友" #: src/fx_add_group.c:73 msgid "Add a buddy group" msgstr "添加一个好友分组" #: src/fx_tree.c:709 msgid "Add a new group" msgstr "添加新分组" #: src/fx_addbuddy.c:233 msgid "Add buddy failed. Unknown reason!" msgstr "添加好友失败,原因不详" #: src/fx_main.c:1297 msgid "Add contact" msgstr "添加好友" #: src/fx_app.c:100 msgid "Add to group:" msgstr "添加到组:" #: src/fx_pgprofile.c:74 msgid "Administrator:" msgstr "超级管理员:" #: src/fx_history.c:111 msgid "All" msgstr "全部" #: src/fx_emotion.c:51 msgid "Angel" msgstr "天使" #: src/fx_emotion.c:11 msgid "Angry" msgstr "生气" #: src/fx_close.c:67 msgid "Are you sure you want to exit OpenFetion?" msgstr "确定要退出 OpenFetion 吗?" #: src/fx_conn.c:395 src/fx_conn.c:402 src/fx_conn.c:727 src/fx_conn.c:740 #: src/fx_conn.c:870 msgid "Authenticate failed." msgstr "身份验证失败,手机号或密码错误" #: src/fx_set.c:475 msgid "Auto away when idle" msgstr "空闲时自动离开" #: src/fx_set.c:466 msgid "Auto popup message" msgstr "自动弹出消息窗口" #: src/fx_emotion.c:14 msgid "Awkward" msgstr "尴尬" #: src/fx_login.c:327 src/fx_main.c:1226 msgid "Back Soon" msgstr "马上回来" #: src/fx_pgprofile.c:64 msgid "Basic Information" msgstr "基本资料" #: src/fx_emotion.c:38 msgid "Birthday Cake" msgstr "生日蛋糕" #: src/fx_emotion.c:25 msgid "Broken Heart" msgstr "破碎的心" #: src/fx_emotion.c:40 msgid "Bulb" msgstr "灯泡" #: src/fx_head.c:278 src/fx_login.c:322 src/fx_main.c:1222 msgid "Busy" msgstr "忙碌" #: src/fx_head.c:288 src/fx_login.c:329 src/fx_main.c:1228 msgid "Calling" msgstr "电话中" #: src/fx_add_group.c:88 src/fx_addbuddy.c:117 src/fx_app.c:119 #: src/fx_close.c:81 src/fx_code.c:106 src/fx_dsms.c:82 src/fx_edit.c:61 #: src/fx_gedit.c:63 src/fx_head.c:508 src/fx_lookup.c:62 #: src/fx_lookupres.c:206 src/fx_proxy.c:124 src/fx_set.c:211 #: src/fx_share.c:100 src/fx_smsstat.c:101 msgid "Cancel" msgstr "取消" #: src/fx_addbuddy.c:53 src/fx_lookupres.c:141 src/fx_profile.c:80 #: src/fx_set.c:339 msgid "Cell Phone Number:" msgstr "手机号:" #: src/fx_login.c:190 msgid "Cell number or fetion number:" msgstr "请输入手机号或飞信号:" #: src/fx_chat.c:526 msgid "Chat logs" msgstr " 聊天记录" #: src/fx_chat.c:1083 #, c-format msgid "Chatting with [%s]" msgstr "和[%s]聊天中" #: src/fx_lookupres.c:60 src/fx_profile.c:186 msgid "China" msgstr "中国" #. left top area #: src/fx_many.c:389 msgid "Choose Contacts" msgstr "请选择好友" #: src/fx_head.c:506 msgid "Choose the avatar file to upload" msgstr "请选择要上传的头像文件" #: src/fx_many.c:231 #, c-format msgid "" "Choosed [%d] contacts, [%d] more available" msgstr "" "已选择好友[%d]人,还可选择[%" "d]人" #: src/fx_many.c:432 msgid "" "Choosed [0] contacts, [10000] more available" msgstr "" "已选择好友[0]人,还可选择[10000]人" #: src/fx_lookupres.c:195 src/fx_profile.c:133 src/fx_set.c:371 msgid "City:" msgstr "城市:" #: src/fx_history.c:126 msgid "Cleanup" msgstr "清空" #: src/fx_code.c:76 msgid "Click here getting new verification code" msgstr "点此重新获取验证码" #: src/fx_head.c:190 src/fx_set.c:133 src/fx_set.c:138 msgid "Click here to input signature" msgstr "点此输入心情短语" #: src/fx_emotion.c:23 msgid "Clock" msgstr "时钟" #: src/fx_about.c:425 src/fx_chat.c:563 src/fx_dsms.c:670 src/fx_history.c:146 #: src/fx_many.c:477 src/fx_myself.c:184 src/fx_pggroup.c:206 #: src/fx_sysmsg.c:76 msgid "Close" msgstr "关闭" #: src/fx_main.c:1240 msgid "Close sound" msgstr "关闭声音" #: src/fx_set.c:463 msgid "Close to Tray" msgstr "关闭到托盘" #: src/fx_emotion.c:42 msgid "Coffee" msgstr "咖啡" #: src/fx_emotion.c:45 msgid "Computer" msgstr "计算机" #: src/fx_emotion.c:47 msgid "Confused" msgstr "困惑" #: src/fx_conn.c:340 msgid "Connecting to proxy server" msgstr "正在连接到代理服务器" #: src/fx_conn.c:347 msgid "Connecting to registration server" msgstr "正在连接到注册服务器" #: src/fx_conn.c:325 msgid "Connection has been shutdown by the server" msgstr "连接已断开" #: src/fx_chat.c:879 msgid "Contact is not online. Cannot send screen jitter" msgstr "对方不在线,不能发送窗口抖动" #: src/fx_addbuddy.c:72 msgid "Contact's Information" msgstr "好友信息" #: src/fx_chat.c:515 msgid "Contact's cell phone" msgstr "对方手机" #: src/fx_many.c:425 msgid "Contacts Selected" msgstr "已选择的好友" #: src/fx_about.c:323 msgid "" "Contributed to the UI development,and fixed some bugs of the UI.\n" "Follow him:" msgstr "" "为界面开发做出了贡献,修改了界面的很多问题。\n" "关注他:" #: src/fx_about.c:401 msgid "Contributor" msgstr "贡献者" #: src/fx_tree.c:752 msgid "Copy this contact to" msgstr "将好友复制到" #: src/fx_lookupres.c:179 src/fx_profile.c:117 msgid "Country:" msgstr "国家:" #: src/fx_pgprofile.c:77 msgid "Create Time:" msgstr "创建时间:" #: src/fx_emotion.c:13 msgid "Cry" msgstr "哭泣" #: src/fx_app.c:111 msgid "Decline his(her) add buddy request" msgstr "拒绝对方的添加好友请求" #: src/fx_dsms.c:206 msgid "Delete this contact" msgstr "删除这个联系人" #: src/fx_conn.c:318 msgid "" "Detected that this is the first time you login\n" "Downloading configuration file..." msgstr "" "系统检测到这是您初次登录飞信\n" "正在下载配置文件..." #: src/fx_set.c:484 msgid "Disable Fetion Show" msgstr "关闭飞信秀" #: src/fx_set.c:469 msgid "Disable Message Notification" msgstr "关闭消息提示" #: src/fx_set.c:481 msgid "Disable System Message" msgstr "关闭系统消息" #: src/fx_emotion.c:46 msgid "Disappointed" msgstr "失望" #: src/fx_head.c:286 src/fx_login.c:326 src/fx_main.c:1225 msgid "Do Not Disturb" msgstr "请勿打扰" #: src/fx_set.c:505 msgid "Don't Use Status Icon(restart)" msgstr "不使用托盘图标(需要重启程序)" #: src/fx_close.c:73 msgid "Don't notify again" msgstr "不再提示" #: src/fx_conn.c:322 msgid "Downloading configuration files" msgstr "正在下载配置文件" #: src/fx_emotion.c:49 msgid "Drinks" msgstr "饮料" #: src/fx_head.c:285 src/fx_login.c:325 src/fx_main.c:1224 msgid "Eating out" msgstr "外出就餐" #: src/fx_gedit.c:43 src/fx_tree.c:711 msgid "Edit name of a group" msgstr "修改分组名称" #: src/fx_edit.c:41 src/fx_tree.c:651 msgid "Edit note name" msgstr "修改备注名称" #: src/fx_main.c:1269 msgid "Edit statement" msgstr "修改状态" #: src/fx_set.c:389 msgid "Email:" msgstr "电子邮箱:" #: src/fx_chat.c:506 msgid "Emotion" msgstr "表情" #: src/fx_chat.c:665 src/fx_chat.c:744 msgid "Empty messages are not allowed." msgstr "不允许发送空信息" #: src/fx_set.c:491 msgid "Enable" msgstr "启用" #: src/fx_close.c:70 msgid "Exit OpenFetion" msgstr "退出 OpenFetion" #: src/fx_head.c:308 src/fx_main.c:1305 msgid "Exit OpenFetion " msgstr "退出 OpenFetion " #: src/fx_history.c:119 msgid "Export" msgstr "导出" #: src/fx_history.c:269 msgid "Export File" msgstr "导出文件" #: src/fx_emotion.c:26 msgid "Face of Cat" msgstr "猫脸" #: src/fx_emotion.c:27 msgid "Face of Dog" msgstr "狗脸" #: src/fx_lookupres.c:48 src/fx_profile.c:174 src/fx_set.c:531 msgid "Female" msgstr "女" #: src/fx_bottom.c:124 msgid "Fetion Group" msgstr "飞信群" #: src/fx_pggroup.c:97 #, c-format msgid "Fetion Group [%s]" msgstr "飞信群 [%s]" #: src/fx_addbuddy.c:56 src/fx_lookupres.c:125 src/fx_profile.c:64 #: src/fx_set.c:319 msgid "Fetion Number:" msgstr "飞信号:" #: src/fx_dsms.c:68 msgid "" "Fetion has sent the verification code as SMS to your cell phone. Please " "input it." msgstr "飞信已经将短信验证码发送到您好的手机,请输入短信验证码" #: src/fx_lookup.c:58 msgid "Find" msgstr "查询" #: src/fx_profile.c:141 msgid "Finish" msgstr "完成" #: src/fx_conn.c:245 src/fx_conn.c:410 msgid "Getting code picture,please wait..." msgstr "正在获取验证码,请稍候..." #: src/fx_conn.c:139 msgid "Getting portrait..." msgstr "正在获取头像" #: src/fx_emotion.c:37 msgid "Gift Box" msgstr "礼品盒" #: src/fx_emotion.c:50 msgid "Goblet" msgstr "高脚杯" #: src/fx_emotion.c:20 msgid "Googly eyes" msgstr "转动的眼睛" #: src/fx_about.c:190 msgid "" "Graduate student at Beijing University of Post & Telecommunication.Love " "Linux,Love OpenSource.Started this project in order to help linux users " "including myself to get a better way to use fetion.\n" "\n" "Blog:" msgstr "" "北京邮电大学研究生。喜爱 Linux,热爱开源。启动这个项目是为了帮助包括自己在内" "的 Linux 用户获得更好的飞信使用体验。\n" "\n" "博客:" #: src/fx_emotion.c:53 msgid "Great" msgstr "太棒了" #: src/fx_emotion.c:17 msgid "Gritting my teeth" msgstr "咬牙切齿" #: src/fx_pgprofile.c:108 msgid "Group Bulletin:" msgstr "群公告:" #: src/fx_pgprofile.c:54 msgid "Group Details" msgstr "群资料" #. contact list #: src/fx_pggroup.c:250 msgid "Group Members" msgstr "群成员" #: src/fx_pgprofile.c:71 msgid "Group Name:" msgstr "群名称:" #. notice #: src/fx_pggroup.c:223 msgid "Group Notice" msgstr "群公告" #: src/fx_pgprofile.c:68 msgid "Group Number:" msgstr "群号码:" #: src/fx_pgprofile.c:130 msgid "Group Summary:" msgstr "群简介:" #: src/fx_pggroup.c:546 msgid "" "Group member who didn't bind fetion number to mobile number can't receive " "the group sms you send" msgstr "未绑定手机号的群成员将无法接收到您发送的群短信" #: src/fx_addbuddy.c:78 msgid "Group: " msgstr "分组:" #: src/fx_addbuddy.c:102 msgid "Hello ,I am " msgstr "您好,我是" #: src/fx_app.c:74 #, c-format msgid "Hello ,I am %s , %s" msgstr "您好,我是%s,%s" #: src/fx_head.c:279 src/fx_login.c:323 src/fx_main.c:1223 msgid "Hide" msgstr "隐身" #: src/fx_tree.c:654 msgid "Hightlight all contacts" msgstr "所有好友高亮" #: src/fx_tree.c:654 msgid "Hightlight online contacts" msgstr "在线好友高亮" #: src/fx_emotion.c:32 msgid "Hug left" msgstr "左侧拥抱" #: src/fx_emotion.c:33 msgid "Hug right" msgstr "右侧拥抱" #: src/fx_emotion.c:41 msgid "Idea" msgstr "想法" #: src/fx_emotion.c:55 msgid "Idiot" msgstr "笨蛋,呆子" #: src/fx_emotion.c:16 msgid "Illed" msgstr "生病" #: src/fx_main.c:1265 msgid "Information query" msgstr "信息查询" #: src/fx_conn.c:471 src/fx_conn.c:496 msgid "Initializing main panel" msgstr "正在初始化主界面" #: src/fx_add_group.c:76 msgid "Input the name of the new group:" msgstr "请输入新建分组名称:" #: src/fx_about.c:379 msgid "Introduction" msgstr "软件介绍" #: src/fx_emotion.c:15 msgid "Irony" msgstr "讽刺" #: src/fx_set.c:380 msgid "Job occupation:" msgstr "职业:" #: src/fx_emotion.c:6 msgid "Laugh" msgstr "大笑" #: src/fx_head.c:277 src/fx_login.c:321 src/fx_main.c:1221 msgid "Leave" msgstr "离开" #: src/fx_about.c:412 msgid "License" msgstr "许可协议" #: src/fx_conn.c:280 msgid "Loading local user information" msgstr "正在加载本地用户信息" #: src/fx_login.c:210 msgid "Login" msgstr "登录" #: src/fx_conn.c:224 src/fx_conn.c:236 src/fx_conn.c:366 src/fx_conn.c:388 #: src/fx_conn.c:675 src/fx_conn.c:690 src/fx_conn.c:718 src/fx_conn.c:882 msgid "Login failed" msgstr "登录失败" #: src/fx_conn.c:275 msgid "" "Login failed. \n" "Incorrect cell phone number or password" msgstr "登录失败,手机号或密码错误" #: src/fx_conn.c:151 msgid "Login successful" msgstr "登录成功" #: src/fx_conn.c:477 msgid "Login sucessful" msgstr "登录成功" #: src/fx_app.c:301 msgid "Lookup failed, unknown identity, unknown reason" msgstr "查询失败,对方身份不明,原因未知" #: src/fx_about.c:316 msgid "" "Main translater of openfetion,accomplish the internationalisation(i18n) of " "openfetion" msgstr "Openfetion 的主要翻译者,完成了 openfetion 的国际化。" #: src/fx_about.c:307 msgid "" "Make deb package for debian/ubuntu users,maintainer of the PPA of " "openfetion.\n" "Blog:" msgstr "" "为 Debian/Ubuntu 打包,维护 openfetion 的 PPA。\n" "博客:" #: src/fx_lookupres.c:48 src/fx_profile.c:174 src/fx_set.c:530 msgid "Male" msgstr "男" #: src/fx_head.c:287 src/fx_login.c:328 src/fx_main.c:1227 msgid "Meeting" msgstr "会议中" #: src/fx_many.c:558 #, c-format msgid "Mesage \"%s\" did not send to \"%s\"\n" msgstr "消息“%s”未发送至“%s”\n" #: src/fx_many.c:552 #, c-format msgid "" "Mesage \"%s\" has been sent to \"%s\". You have sent %d today and %d this " "month\n" msgstr "消息“%s”成功发送至“%s”,今天已发送短信息%d条,本月已发送%d条\n" #: src/fx_dsms.c:338 #, c-format msgid "Mesage didn't send to %s. Please check the phone number of the contact." msgstr "消息未发送至 %s,请确认联系人手机号是否正确。" #: src/fx_dsms.c:332 #, c-format msgid "Mesage has been send to %s successfully." msgstr "消息已成功发送至 %s。" #: src/fx_chat.c:516 msgid "Mesage will be send to Contact's cell phone in long SMS format" msgstr "消息将以长短信的方式发送到对方手机" #: src/fx_chat.c:964 #, c-format msgid "" "Mesage will be sent to contact's cell phone. You have %d free SMS left. If " "want to send more free SMS, bind your cell phone,please." msgstr "" "消息将直接发送到对方手机。您还可以发送%d条免费短信。如果您还想发送更多免费短" "信,请绑定手机号,成为飞信移动用户。" #: src/fx_main.c:1285 msgid "Message Function" msgstr "短信功能" #: src/fx_chat.c:692 msgid "Message send failed,Unknown Error" msgstr "消息发送失败,未知错误" #: src/fx_dsms.c:376 msgid "Message sent failed" msgstr "消息发送失败" #: src/fx_chat.c:799 #, c-format msgid "Message sent successfully. You have sent %d SMS, and %d left." msgstr "发送成功,今天已发送%d条短信息,还可以发送%d条。" #: src/fx_chat.c:980 msgid "Message will be sent to contact's fetion" msgstr "消息将直接发送到对方飞信" #: src/fx_chat.c:972 #, c-format msgid "" "Messages will be sent to you phone as long SMS messages. You have sent %d, " "and %d left." msgstr "" "信息将以长短信的方式发送到对方的手机上,您已经发送了%d条,还可以发送%d条" #: src/fx_close.c:72 src/fx_set.c:460 msgid "Minimize to Tray" msgstr "最小化到托盘" #: src/fx_emotion.c:44 msgid "Mobile Phone" msgstr "手机" #: src/fx_head.c:302 msgid "Modify Profile" msgstr "修改资料" #: src/fx_tree.c:669 msgid "Move this contact to" msgstr "将好友移动到" #: src/fx_emotion.c:39 msgid "Music" msgstr "音乐" #: src/fx_set.c:472 msgid "Mute" msgstr "静音" #: src/fx_addbuddy.c:81 msgid "Name: " msgstr "名字:" #: src/fx_emotion.c:54 msgid "Naughty" msgstr "淘气" #: src/fx_set.c:110 msgid "Nick can not be empty!" msgstr "昵称不能为空!" #: src/fx_lookupres.c:150 src/fx_profile.c:88 src/fx_set.c:347 msgid "Nickname:" msgstr "昵称:" #: src/fx_conn.c:864 msgid "No local information stored" msgstr "没有本地信息" #: src/fx_tree.c:1694 msgid "Not bind to a phone number." msgstr "未绑定手机号" #: src/fx_app.c:87 src/fx_profile.c:109 msgid "Note name:" msgstr "备注名:" #: src/fx_close.c:55 msgid "Notification" msgstr "提示信息" #: src/fx_add_group.c:84 src/fx_addbuddy.c:113 src/fx_app.c:116 #: src/fx_close.c:79 src/fx_code.c:100 src/fx_dsms.c:81 src/fx_edit.c:57 #: src/fx_gedit.c:59 src/fx_lookupres.c:203 src/fx_proxy.c:121 #: src/fx_set.c:207 src/fx_share.c:96 src/fx_smsstat.c:97 msgid "OK" msgstr "确定" #: src/fx_login.c:64 src/fx_login.c:69 src/fx_login.c:243 msgid "Off" msgstr "关闭" #: src/fx_head.c:280 src/fx_login.c:324 msgid "Offline" msgstr "离线" #: src/fx_login.c:64 src/fx_login.c:69 src/fx_login.c:243 msgid "On" msgstr "开启" #: src/fx_head.c:276 src/fx_login.c:320 src/fx_main.c:1220 msgid "Online" msgstr "上线" #: src/fx_set.c:478 msgid "Online notification enabled" msgstr "开启上线提示" #: src/fx_tree.c:106 msgid "Only English words are allowed here!" msgstr "此处只能输入英文,搜索中文请输入拼音首字母组合" #: src/fx_set.c:185 msgid "OpenFetion Preference" msgstr "OpenFetion 首选项" #: src/fx_about.c:141 msgid "" "OpenFetion is a Fetion client for linux based on GTK+2.0, implementing " "Fetion Protocol Version 4.\n" "It supports most features of Fetion. \n" "What's more, it's lightweight and efficient with intuitive interface.\n" "\n" "Project homepage: " msgstr "" "OpenFetion 是一个使用 GTK+2 编写,实现了第四版飞信协议的 Linux 飞信客户端。\n" "支持飞信的大多数功能。\n" "更重要的是,很轻量、高效,界面直观。\n" "\n" "项目主页:" #: src/fx_about.c:140 msgid "Openfetion " msgstr "OpenFetion " #: src/fx_bottom.c:85 src/fx_main.c:1299 src/fx_set.c:195 msgid "Personal Settings" msgstr "个人设置" #: src/fx_lookupres.c:158 src/fx_lookupres.c:171 src/fx_profile.c:96 #: src/fx_set.c:354 msgid "Personal Signature:" msgstr "个性签名:" #: src/fx_main.c:319 #, c-format msgid "" "Phone Number: %s\n" "Fetion Number: %s\n" "Signature: %s" msgstr "" "手机号 : %s \n" "飞信号 : %s\n" "个性签名:%s" #: src/fx_tree.c:1689 src/fx_tree.c:1695 msgid "Phone number not be published." msgstr "未公开手机号" #: src/fx_gedit.c:51 msgid "Please entry new name of the group:" msgstr "请输入新的分组名称:" #: src/fx_code.c:48 msgid "Please entry your verification code" msgstr "请输入验证码" #: src/fx_dsms.c:429 msgid "Please input a contact" msgstr "请输入联系人" #: src/fx_edit.c:49 msgid "Please input note name:" msgstr "请输入备注名称:" #: src/fx_login.c:202 msgid "Please input password:" msgstr "请输入密码:" #: src/fx_many.c:533 msgid "Please input the contents of message" msgstr "请输入消息内容" #: src/fx_lookup.c:49 msgid "Please input the user's phone number or fetion number:" msgstr "请输入用户的手机号或飞信号:" #: src/fx_conn.c:220 src/fx_conn.c:878 msgid "Preparing for login" msgstr "正在准备登录" #: src/fx_set.c:514 msgid "Press CTRL + Enter to Send" msgstr "CTRL + Enter 发送消息" #: src/fx_set.c:511 msgid "Press Enter to Send" msgstr "Enter 发送消息" #: src/fx_lookupres.c:187 src/fx_profile.c:125 src/fx_set.c:362 msgid "Province:" msgstr "省份:" #: src/fx_conn.c:131 #, c-format msgid "" "Public IP: %s\n" "IP of last login: %s\n" "Time of last login: %s\n" msgstr "" "公网IP地址:%s\n" "上次登录IP地址:%s\n" "上次登录时间%s\n" #: src/fx_lookup.c:90 msgid "Query failed, please input vaild phone number of China Mobile" msgstr "查询失败,请输入正确的移动手机号码" #: src/fx_emotion.c:22 msgid "Rain" msgstr "下雨" #: src/fx_emotion.c:31 msgid "Rainbow" msgstr "彩虹" #: src/fx_head.c:293 src/fx_main.c:1253 msgid "Receive SMS" msgstr "接收短信息" #: src/fx_main.c:825 msgid "Receive a window jitter" msgstr "收到一个窗口抖动" #: src/fx_app.c:57 msgid "Receive an Add Buddy request" msgstr "收到一个添加好友请求" #: src/fx_emotion.c:24 msgid "Red Heart" msgstr "红心" #: src/fx_emotion.c:34 msgid "Red Lips" msgstr "红唇" #: src/fx_emotion.c:35 msgid "Red Rose" msgstr "红玫瑰" #: src/fx_history.c:82 msgid "Refresh" msgstr "刷新" #: src/fx_tree.c:647 msgid "Refresh information" msgstr "刷新好友信息" #: src/fx_conn.c:362 msgid "Registering to SIPC Server" msgstr "正在注册到 SIPC 服务器" #: src/fx_login.c:236 msgid "Remember password" msgstr "记住密码" #: src/fx_tree.c:1321 msgid "Remove contact" msgstr "删除好友" #: src/fx_tree.c:717 msgid "Remove from group" msgstr "从该分组删除" #: src/fx_tree.c:1489 msgid "Remove group" msgstr "删除分组" #: src/fx_tree.c:661 msgid "Remove this contact" msgstr "删除该好友" #: src/fx_tree.c:1320 msgid "Remove this contact?" msgstr "确定要删除这个好友吗?" #: src/fx_tree.c:714 msgid "Remove this group" msgstr "删除该分组" #: src/fx_tree.c:1488 msgid "Remove this group?" msgstr "确定要删除这个分组吗?" #: src/fx_chat.c:958 msgid "" "Run out of your quota, you can still send IM mesages. If want to send more " "free SMS, bind you cell phone number." msgstr "" "您的短信限额已用完,你可以给对方发送消息。如果您想发送更多免费短信,请绑定手" "机号,成为飞信移动用户" #. start sipc authentication using the response created just now #: src/fx_conn.c:384 msgid "SIPC Indentify" msgstr "正在进行 SIPC 身份验证" #: src/fx_many.c:376 msgid "SMS To Many" msgstr "短信群发" #: src/fx_bottom.c:115 src/fx_dsms.c:540 src/fx_main.c:1290 msgid "SMS directly" msgstr "直接短信" #: src/fx_main.c:1293 msgid "SMS myself" msgstr "短信自己" #: src/fx_bottom.c:108 src/fx_main.c:1288 msgid "SMS to many" msgstr "短信群发" #: src/fx_emotion.c:12 msgid "Sad" msgstr "悲伤" #: src/fx_chat.c:532 msgid "Screen jitter" msgstr " 屏幕抖动" #: src/fx_emotion.c:19 src/fx_lookupres.c:48 src/fx_profile.c:174 #: src/fx_set.c:421 src/fx_set.c:422 src/fx_set.c:532 msgid "Secrecy" msgstr "保密" #: src/fx_chat.c:568 src/fx_dsms.c:666 src/fx_many.c:482 src/fx_myself.c:189 #: src/fx_pggroup.c:211 msgid "Send" msgstr "发送" #: src/fx_tree.c:627 msgid "Send IM mesages" msgstr "发送即时消息" #: src/fx_addbuddy.c:99 msgid "Send Message:" msgstr "发送消息" #: src/fx_bottom.c:101 msgid "Send a message to myself" msgstr "给自己发短信" #: src/fx_chat.c:532 msgid "Send a screen jitter" msgstr "发送一个屏幕抖动" #: src/fx_pggroup.c:171 src/fx_tree.c:1792 msgid "Send group message" msgstr "发送群消息" #: src/fx_tree.c:1794 msgid "Send group sms" msgstr "发送群短信" #: src/fx_dsms.c:352 msgid "Send message failed" msgstr "消息发送失败" #: src/fx_myself.c:54 msgid "Sending sms to myself" msgstr "正在给自己发短信" #: src/fx_proxy.c:71 msgid "Set HTTP Proxy" msgstr "设置 HTTP 代理" #: src/fx_smsstat.c:52 msgid "Settings Of Receving Message" msgstr "接收短信设置" #: src/fx_lookupres.c:133 src/fx_profile.c:72 src/fx_set.c:327 msgid "Sex:" msgstr "性别:" #: src/fx_bottom.c:136 msgid "Show OpenFetion About dialog" msgstr "显示关于对话框" #: src/fx_history.c:69 msgid "Show the most recent" msgstr "显示最新的" #: src/fx_dsms.c:656 msgid "Sign" msgstr "签名" #: src/fx_emotion.c:21 msgid "Sleeping Moon" msgstr "沉睡的月亮" #: src/fx_emotion.c:5 msgid "Smile" msgstr "微笑" #: src/fx_emotion.c:28 msgid "Snail" msgstr "蜗牛" #: src/fx_set.c:286 msgid "Sorry, I am not in now, and will reply to you soon" msgstr "对不起,我现在不在,稍后给您回复" #: src/fx_chat.c:754 msgid "" "Sorry, you have reached the quota of free SMS today, SMS messages cannot be " "sent any more today." msgstr "对不起,你今天的免费短信限额已经用完,不能再发送短信" #: src/fx_emotion.c:29 msgid "Star" msgstr "星星" #: src/fx_login.c:209 msgid "Status:" msgstr "状态:" #: src/fx_conn.c:493 msgid "Strangers" msgstr "陌生人" #: src/fx_emotion.c:30 msgid "Sun" msgstr "太阳" #: src/fx_emotion.c:56 msgid "Sunglasses" msgstr "戴着太阳镜" #: src/fx_emotion.c:8 msgid "Surprised" msgstr "惊讶" #: src/fx_main.c:1301 src/fx_set.c:201 msgid "System Settings" msgstr "系统设置" #: src/fx_sysmsg.c:62 msgid "System mesage" msgstr "系统消息" #: src/fx_about.c:271 msgid "" "The Main Contributors\n" "\n" msgstr "" "主要贡献者\n" "\n" #: src/fx_history.c:307 msgid "" "The action can not be undone.\n" "Are you sure you want to continue?" msgstr "该操作不可恢复,确定删除?" #: src/fx_conn.c:959 msgid "The action can't be performed in offline state" msgstr "离线状态下该操作不能执行" #: src/fx_addbuddy.c:223 msgid "" "The contact you want to add has already been in your contact list, please " "don't add him(her) repeatedly!" msgstr "您添加的好友已经在您的好友列表中,请不要重复添加" #: src/fx_chat.c:79 #, c-format msgid "The message \"%s\" sent at [%s] send failed,please resend it" msgstr "您于[%s]发送的消息“%s”发送失败,请重新发送" #: src/fx_emotion.c:52 msgid "Thinking" msgstr "深思" #: src/fx_history.c:104 msgid "This Month" msgstr "本月" #: src/fx_history.c:97 msgid "This Week" msgstr "本周" #: src/fx_about.c:238 msgid "" "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.\n" "\n" msgstr "" "发布这一程序的目的是希望它有用,但没有任何担保,甚至没有适合特定目的的隐含的" "担保。更详细的情况请参阅 GNU 通用公共许可证。\n" "\n" #: src/fx_about.c:234 msgid "" "This program is free software; you can redistribute it and/or modify it " "under the terms of the GNU General Public License as published by the Free " "Software Foundation; either version 2 of the License, or (at your option) " "any later version.\n" "\n" msgstr "" "这一程序是自由软件;你可以遵照自由软件基金会出版的 GNU 通用公共许可证条款来修" "改和重新发布这一程序;可采用该许可证的第二版,或者(根据您的选择)用任何更新的" "版本。\n" "\n" #: src/fx_tree.c:1145 msgid "This user have shut fetion service,so you cannot send mesage to him/her" msgstr "该用户已关闭飞信服务,不能给他发消息" #: src/fx_emotion.c:18 msgid "Tired" msgstr "困" #: src/fx_history.c:89 msgid "Today" msgstr "今天" #: src/fx_emotion.c:9 msgid "Tongue smile" msgstr "吐舌笑脸" #: src/fx_share.c:66 msgid "Transport files by Fetion" msgstr "使用飞信传输文件" #: src/fx_share.c:76 #, c-format msgid "Transporting files OS Revolution.mkv to %s..." msgstr "正在向 %s 传输 OS Revolution.mkv ..." #: src/fx_proxy.c:80 msgid "Trun on HTTP proxy" msgstr "开启 HTTP 代理" #: src/fx_emotion.c:43 msgid "Umbrella" msgstr "雨伞" #: src/fx_conn.c:485 msgid "Ungrouped" msgstr "未分组" #: src/fx_lookupres.c:65 src/fx_lookupres.c:72 src/fx_profile.c:191 #: src/fx_profile.c:198 src/fx_tree.c:1220 src/fx_tree.c:1224 msgid "Unknown" msgstr "未知" #: src/fx_head.c:508 msgid "Upload" msgstr "上传" #: src/fx_head.c:564 msgid "" "Upload avatar failed. Note: This appliaction doesn't support auto-" "compression of image. Please be sure that the avater is in 150px × 150px." msgstr "" "上传头像失败,友情提示:本程序暂不提供图片自动压缩功能,上传头像尺寸请控制在 " "150px × 150px 以内" #: src/fx_tree.c:657 msgid "Use big icon" msgstr "使用大图标" #: src/fx_tree.c:657 msgid "Use small icon" msgstr "使用小图标" #: src/fx_search.c:66 msgid "User has shut his fetion service, so you can not send a message to him" msgstr "该用户已关闭飞信服务,不能给他发消息" #: src/fx_dsms.c:69 msgid "Verification code" msgstr "短信验证码:" #: src/fx_chat.c:526 src/fx_tree.c:643 msgid "View chat logs" msgstr "查看聊天记录" #: src/fx_app.c:95 src/fx_sysmsg.c:74 msgid "View details" msgstr "查看详情" #: src/fx_tree.c:1800 msgid "View group details" msgstr "查看群资料" #: src/fx_bottom.c:129 src/fx_lookup.c:41 msgid "View information of any user (attribution etc)" msgstr "查看任意用户信息(归属地等)" #: src/fx_history.c:58 #, c-format msgid "View logs with [%s]" msgstr "查看与[%s]的聊天记录" #: src/fx_emotion.c:10 msgid "Warm smile" msgstr "热烈的笑脸" #: src/fx_emotion.c:7 msgid "Wink" msgstr "眨眼" #: src/fx_emotion.c:36 msgid "Withered Rose" msgstr "凋谢的玫瑰" #: src/fx_emotion.c:48 msgid "Worried" msgstr "担心" #: src/fx_addbuddy.c:194 src/fx_addbuddy.c:204 msgid "You can not add yourself as a friend" msgstr "您不能添加自己为好友" #: src/fx_tree.c:1138 msgid "" "You can not send a message to anyone who has not been in your contact list" msgstr "由于对方尚未成为你的飞信好友,您不能给对方发送消息" #: src/fx_search.c:58 msgid "" "You can not send messages to him(her), because he(she) is not in your " "contact list" msgstr "由于对方未成为您的飞信好友,您不能给对方发送消息" #: src/fx_smsstat.c:62 msgid "" "You can set not to receive sms here , even\n" "for a period,in whitch you won`t receive the \n" "sms sent from fetion,but you can still receive \n" "the message from fetion client, the period will be:" msgstr "" "您在这里可以设置不接收短信/彩信,并且能够定制一\n" "个时间期限。在这期间,您不会收到来自飞信的短信/\n" "彩信,但不影响您登录飞信的客户端接收消息。您希\n" "望这段时间是:" #: src/fx_many.c:504 msgid "You have not selected contacts" msgstr "您还没有选择好友" #: src/fx_addbuddy.c:229 msgid "You have reached the daily limit of adding buddies, please retry later" msgstr "您已经达到添加好友的上限,请改日再试" #: src/fx_about.c:242 msgid "" "You should have received a copy of the GNU General Public License along with " "this program; if not, see \n" msgstr "您应该已经随本程序得到了 GNU 通用公共许可证的副本;如果没有,请参看\n" #: src/fx_main.c:931 msgid "Your fetion login elsewhere. You are forced quit." msgstr "您的飞信已经在别处登录,您被强制退出" #: src/fx_chat.c:1057 #, c-format msgid "[%d] character" msgstr "[%d]个字" #: src/fx_chat.c:539 msgid "[180] characters" msgstr "[180]个字" #: src/fx_util.c:48 msgid "[Be Back Soon]" msgstr "[马上回来]" #: src/fx_util.c:33 msgid "[Busy]" msgstr "[忙碌]" #: src/fx_util.c:54 msgid "[Calling]" msgstr "[电话中]" #: src/fx_util.c:45 msgid "[Do Not Disturb]" msgstr "[请勿打扰]" #: src/fx_util.c:42 msgid "[Eating out]" msgstr "[外出就餐]" #: src/fx_util.c:39 msgid "[Hide]" msgstr "[隐身]" #: src/fx_util.c:36 msgid "[Leave]" msgstr "[离开]" #: src/fx_tree.c:885 msgid "[Login with cell phone]" msgstr "[手机登录]" #: src/fx_util.c:51 msgid "[Meeting]" msgstr "[会议中]" #: src/fx_util.c:57 msgid "[Offline]" msgstr "[离线]" #: src/fx_util.c:30 src/fx_util.c:61 msgid "[Online]" msgstr "[在线]" #: src/fx_util.c:63 msgid "[Unknown Statement]" msgstr "[未知状态]" #: src/fx_smsstat.c:91 msgid "forever" msgstr "永远" #: src/fx_history.c:278 #, c-format msgid "logs with %s.txt" msgstr "与 %s 的聊天记录.txt" #: src/fx_history.c:76 msgid "mesage" msgstr "条聊天记录" #: src/fx_pggroup.c:90 msgid "no notice!" msgstr "暂无群公告!" #: src/fx_chat.c:764 #, c-format msgid "" "tips:if you wnat to send more free sms,please bound your mobileno\n" "at once ,no authentication code needed any more." msgstr "温馨提示:发送更多免费短信,请立即绑定手机号,无需输入验证码" #: src/fx_chat.c:537 msgid "total 180 character left" msgstr "共可输入180个字,还可输入" #: src/fx_main.c:324 msgid "unknown" msgstr "未知" #: src/fx_profile.c:41 src/fx_tree.c:634 msgid "view contact's information" msgstr "查看好友信息" #~ msgid "" #~ "Choosed [0] buddy\n" #~ " and up to [10000] left." #~ msgstr "" #~ "已选择好友 [%d]人\n" #~ "还可选择 [%d]人" #~ msgid "Get help or give advice at Open Fetion homepage" #~ msgstr "到 Open Fetion 页面获取帮助或者反馈意见" openfetion-2.2.1/resource/0000755000175000017500000000000011561721144014173 5ustar aronaronopenfetion-2.2.1/resource/newmessage.wav0000644000175000017500000006011011561721144017046 0ustar aronaronRIFF@`WAVEfmt Ddata`A="P47 =-[fh{|mVdLc]^ k o9>qK=0Q /bkSoY|~*VD rOO M;wam-m=] o $~?V[=\FkT5Dg=||,N{#MRQ)+Sy?b=p.|[y=OfGu 8@,+VQ6PQSA Y<1 UmQ7Q"+ 3]-ctV:@ 'p+s$d7O'oi[\s~zL @[:qO iJ2O]@:@X ; #Y Y75b ?vv?BN ?w 03^vi Sl@_'L<1`Phrw+MJEyF!4Rwg;bojfyMO1D  zo: ixt%*W\C^DIXiPS"(F@/^\^$?@ZOOo#[RIN4k7td%M|!Oikw zNshk=k1CJ}|;,"5VDpt>)^}WSl5 mFk/+oc==G-~~QFI7zLatcHa<aWEHcC<i5`U+*^I `r}}g LOR{h?OEAaC#02mG% 'w0|+Wt]~@% \WY|*7%|A*V>ZeR^FN9+;!!n^C>J4r.\Q](YbA Mi@o: E#ox|{Be>Mn)uJX$6pT$<*zo<Y!XQ.al5F.~DS,|)qY.~,c)ksr]ks22y5&a'oy }6+oh\!@ 5`W~' |bCjW 9g%{t<-H(Gq IO=,Atl# B1[BQ\CFxWDp# a}'pLD+fyH;#9+/M;8/ d}S%|n(=Tx3^6bcL OHQ-U[rnZo4ABt(ߣ~ORڐۤ&Y߮ \R (8h< k7 5 !kpzP% K!m! !!l"B"#K$/!i$#-#b g"D  KY5} >  #18K6p,oދzqd!/U]6Ui @ q u  2HD@   Vr i0VS\= [xj7^x@}rwNUvm,gj*$|Gk={W o N ~ ]N`]e9P|"t!zjy.3 A td7 O M%Xldb&vs;GdIv !|`fTn2pjiLkV} ~ V,!x>A8!Vu@ 6jR%]HdjicI [ l}P=y8>rRJ0|?: UU K  kV*ZB8bxR<U(g@%11j"s.C0 C    6Y",~g&+x  f [6@=xT|@*-a+\Qh}qz(R|#\J  k* {  5n3qY qrN Xi V q NzZ+&7=]-6m)K8vpU  Q Y o !RtF}!k= m  ] )Qh,X-*_ 4%!UiPOA/S'BwD  r  i*ds\U G [ W Z \ . M  ,ewpzo7 FL+ #\m    ] Co 4^1A]z - . Q SZb--S[PVEJkN?'6smLH'6nqJ%|r G j m FBQ+6A5'n)w#B A M 7oh 4vKp[==dxXQ ht>HRPwfX  @ G X {8IQdO 81 M  R g 2 { Tl5Z//wLKfj:qTVo=hh']jn# 1 p  Z x |8v E J i  c& O QfFw8L28uYu)6)g7K}tqD+T$I  G 5 \ $I S  ~{ M %} ~ Xi  F ? JJy#b OEaY:RRFq@VX=+O0)GR]Q = k Q H 7 m. __ mn ^W bx  yHu T\*[It8u5 {!epLC2z FQPGw  n S c uvl#     ) 0 3Z' " IvtHC0Ogb\bo?Y$mad=Na F  mw v ( i Y  ^ # A] 3% g.Sfx*r^!^C7em~z`x>)Th7 p d D } $?\ka ) 7  " 1 /,T+am\xd)cc8 kb1x|%YY :t   w9E%   t 5 @DP7 1 q &8,F-^ \4R?z?N9S \ IRY Z x   n n }g Vs@V!$k)L|o$)n\-+h X;j}=J B  B f <a y+  e  c=' kAZ +E67PF[]/\1/ VD  9   K   9d M a m#* " oMhMf <:j0bA@3 vQ\k:j  h + 0B &OHn }    ;B88 )}p!T dz RX?F _ i  & \n  k^   cw O?T?ynw lK2Ek&.zjdURXIoVAR C!HN<VOj1[9cqa !P"#>Z n'(H^); % V ]  usQ].U=p%"nu9^st[ *7iG!PH2 G%b}'Cc d L}`R~Som+]bEZ[C*Y~_    w~ L v )~ f3:1`Z-YWI4^0.8 >    ~ U  i $ ' !U S<23SZ\\; XgZ L  _ + #{'/Cm9c k +^ cQ  ~ite }  7 ]&s!m6!~)4u"l"n39b $]  {[ : ' S[U(S:)SQm&5jVy&fz  v  j9Yv-lO`?qZMm 3 f L  ?  g{$:8[<?W1bcLF|bfH>  a [ / 9 ` q ` #r:4- f} s[bTQ` Fu    9j2O)6>"  aO E` x y 1Aj+$1jvAWTol>Ht2z0? x( 3 W k  ~ BoQ$kp7yQVeT= \~f,y.c= Xfe_f&}h`3Z#>gY$LTHte.Jg7 GSdB6S  V d Q{bKP2JHpgpnAn'4.pqGh`[k|{J'!i    j  s=7FOg1NrYfW*r ;    ]2ExG1.:aYHB`h U hZW ` ` _HZSC]QZ:O \ d"n!#B] XmOl2x@lއߍB`x$ 5*Cp =N@MQ 9,8.G.!kg"LiY '`8bnbLdS Q  !f] { B&v*tߎrܣj+eO HpG `^! w 6Ou*6_)Y#U%" 0e [; gZ   ,Cb@qrJM, 5F g ! \ ' jj, r- X QG[k4 } .<< 'W Q E&* 8 #a?=S (h+Pyq Z K# Z P{;#niy.U~  uf> up7( 0 ^|S,~ *]A). p G 0tQx f pC XL{ 4 oN ,t 1z7ީfJۗ߼i b#F %m#5: }  9 JV=ݨHqE{ l\  %() hD JyI `N^5< {U!csH& 8<i]W`kpu5A A^IX oo<O, H^- I }C @u M ^?_s@$Q%.*TrZY9 > # # | o h\ *p/".  F Q :ydV*Z{WbA6dx4C+2 {3  :^.Jj^%Tjp5>lJ t N sGT6@1Jt\Fcj*E0rK~` o j5q"H$w{_;B  TvgX3lN d?vl]spg&nx 5 *3 < ; .nsy Y< fu4. V Fd!7,9KtFKne#>Oo=[!f0,!yg %>=CvrG1]|~J?@k9Ezh uOhT?g#QG#i@h,9^*'M[K&r>YR) Wb)6  P $ f {g2' klF nw lZ]c{qo(,<lbg0C!v=EY@N`McLw"D0&sn?/{CDuKvdc-d|,!"SyB%tFrZ u   zx = aZqp, w4Ms&}pGKir1oVbmpcAscLl<]j%U;0<+320RFZ:cXLnKf2:]%~1X4U8\\y"7_\N|sZb[[=J[{XW\xqGe]3AGrklC $qY\^prU(r 1zfxmz.!nk3Ol| gK_\>84 yn ;{C y3-Lxmwq1!'nH{,teDA9KXM9I.%d 1$QfTHv[b%4ix8cgq,^9 ?iM}ue's+SA<5}Bdu}abJAalj{wUYsg3=| 7 wf=qE*x/ 92R*vLTg wn qsCK[FjA/xg!a4(0rz_rftI 6.9gy5v~w=|87 [t4X 0.l4tm8<4@/N-W*Tyh%Hg>8 j7eit 9y`zwb3C^|SHD #a,#e#,7p@Kkh`v7(ar._)*xGzn3Svi67t-s{e-iy? DjNV\]4FicJ'3wO 7FgRdldmHw. se*aFREe>f;[0  /7iyHtly$O0~qSrwmC.v&SGJ%o ;>`$RM "^Bb$ly.Q;1>S5 7v\Dd lX"Uw j5?<%>vgbexi6:^u>xs'alRKLPL^AGmSu9cOQp1:hnHsD, Df%"  .;6IuW`Z<! {Br[cfd[sl$X'M|uU\, fh_Rj`|v W!AH4' [vD/e$+@UGrHF:b7 ru%6Yq-jQauS/c? }w`D3.EoB#7Na_2m`JD_'D!Ft&N&nBMLOjDGe.#@n9zGucb[^x.3NO`WiUfRDE 1#wP'&; X*:#KgL<1cB063TtxjX>%  (   $'+)'('<&G*X2X6V;KC:@30!* %  +>EJRSSTOB5'/@F EF;( , ? N OG>* +>JRXQ?0!   &+(/94A0<&=9'   !1 57#7!3%,&   #*.12 54* !)4=:9 5+"%(,(!!    !.5::3'  #%(-*'   %$$%%   *8&D&I E<- $+/,!(&    "#$%     !   "#%($     $-06 ;8 /!                 ! % %       ""  ""!                 openfetion-2.2.1/resource/openfetion.desktop0000644000175000017500000000041311561721144017732 0ustar aronaron[Desktop Entry] Icon=fetion Name=OpenFetion Name[en_GB]=OpenFetion Name[zh_CN]=OpenFetion(飞信) Comment=Fetion For Linux Comment[zh_CN]=Linux 版飞信客户端 Exec=openfetion StartupNotify=true Terminal=false Type=Application Categories=Network;InstantMessaging; openfetion-2.2.1/skin/0000755000175000017500000000000011561721144013310 5ustar aronaronopenfetion-2.2.1/skin/LoadingImage.gif0000644000175000017500000000646511561721144016332 0ustar aronaronGIF89a+$δ`όׄõjX)qgo%r霂6ÿji ٩AճydښշtHcMXMM/k j M-Xpd}ŦxTK,|$+& TXi[ux־xSscys{:4XΣ{ĵĵН|ixvޚv&j! NETSCAPE2.0! ,+$3}5~3~}F5a}|{ Yh0ZB0@x`܍ @7H@ V! , VMQQc?'PQ'>xJQxx~nKr%|QivR\{@&RƌverΌRK8@XIKG@IłݬH8#8I|,ڟuI|ib,Y" +8Ь4pTc4Ks\hĚ#I.HpD РO2 E?!2`8V[k*e=tdH:AAK\ۃ(g)! ,v!JJkG'PGID'>xJ?xx4`!v`#?p=†Rr`8Gpς-r@r#oGR? K~@4#K@@^X BJh e{vcHKEǤ\ I$K8 >;pa͟ ArCEyX3r<%17iɁ:H9KHpo?>8 4{ {q! , oXGp?cpXoH?KK[o#id?f_p4_-J_jF^`'PpeF-84'>xJho8Kkpxxmkkʪ(`gɁ8~9BK 7K|P'Eh5p(#R-ARfIArD ,r$$H`b :-PT$'1Ar$qYld! , 7cciRT[o#Moo[#`:?:P[[PX`hnnp%P+I:[ejc4j[jO2lXT4(=`p^_.YeH@Kp!RJ@@K0\4 (y)cȟx 8A$r_%KZ љ䈔r*Bu@w?@8JOP #8F! , D%r/q;THOj;O4:iTOO9##Rd^^9TM8+#8'^m%ii@XGj9&Xp+fڜ#X+@ =_ mNNn=PIlj #IA>FIX1`~0XbJΒ%R>cK.A~"Hh>p 7|pts8,i,ّ!0\8eT)T<p%EIzieQD! , M%%(9 89;q9dll))9T@pHrd=&(TK8:IkHlmds02pK'd`s(4'V`d9]%ȄK?9 h +X#R!0A/4pp@AN r]h `iLj> 2`H?H `YJ@@J!0\8%D$=p%4]$<AA tۢBhP!@! , 0&@)D/"(D(/(8VV(E((K h8=&(D%RRV$=22~lr>0%+:/G:k_)gpJJ4dZ8Hrp'P4Y$Gz4rxPPC<|88p'xϒz՜gĈRv*gBX3hDM1!,2@D,5 (Ѓ?H `Y MgZ Z1,MJ;openfetion-2.2.1/skin/add.png0000644000175000017500000000050311561721144014544 0ustar aronaronPNG  IHDRabKGDC pHYs B(xtIME DxIDAT8͑``rҺ`6[;tqDdZ &g7Z,Vi1v`9=0+n/\ϵUR>.009xrbD["[-$mx\9XwV2@@PiAkeRjt&Rȿ&ROXNOӅ43kgO=TrK wIENDB`openfetion-2.2.1/skin/away.svg0000644000175000017500000020102411561721144014771 0ustar aronaron image/svg+xml openfetion-2.2.1/skin/bigimage.png0000644000175000017500000000121211561721144015556 0ustar aronaronPNG  IHDRabKGD pHYs  tIME 5wߚ5tEXtComment(c) 2004 Jakub Steiner Created with The GIMPًoIDAT8˝;hQ5i%Hq *v*_P*AppH`APVQtPq -%-EjMSMLuؼrsϹȉEo4g Xm֜XԵ%'ýHp".qSK$~QM :yCυoePO9/hYk>H0=@{g<wdvBV))` image/svg+xml openfetion-2.2.1/skin/delete.png0000644000175000017500000000036711561721144015266 0ustar aronaronPNG  IHDRabKGDC pHYs B(xtIME ;"\IDAT8푱 Pi:+#mF stԶ"DO!ʳ3w&H6暺`?S-FIENDB`openfetion-2.2.1/skin/directsms.png0000644000175000017500000000103411561721144016011 0ustar aronaronPNG  IHDRabKGD pHYs B(xtIME -\IDAT8˭O(a?ARRCjFea`ns8pfAN&$dm9a1K"y"j^f<~#05q[}lFH'`k&Ӝ1c-o#<<\IB(@ i5ĠVھd[+@0U âckhĨC*@0ؘr:.qy^?W~_dV?ao5+b62+5P~p)&ݭȐWרV[aqc*J(S3Ӿ|dۻw'(7K=F#p.|K[HY_.sVQ)fH_udj|>N 0CI]vBMIENDB`openfetion-2.2.1/skin/edit.png0000644000175000017500000000107611561721144014747 0ustar aronaronPNG  IHDRabKGD pHYs  tIME 7);RHIDAT8˥MhA3ݣH"-)X+xEж'< "~1[M\bӍLlZx0Cmj+ ofރ a]VzxG/fw؎XM9WOJݬ;-T@YXݓ zV_LKNJ7qĉ?}MeM}'O2t3@zz}KAI{|-Mu=۶m;R>n&X^Q@dct| UsEΟ0 M ҽ \y7}7FdY~C;>Yz=iv4nK!?y%;nL&q]7\OPV<G;+H%H`YeExA,CkMVCk5Bl:ud})0oZy IENDB`openfetion-2.2.1/skin/emotion.png0000644000175000017500000000173211561721144015473 0ustar aronaronPNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<WIDAT8]Oe..Э0X)`-VmxT/Qkp2x Lch"-XY6-Yvavv^FS>bbbgɪ) ͘Ɣf }GrF_4?ۋFFn;^uj+FC&\*nG~R/ssf&##y8r+ɔ* b?iNjwXݮ_p~W[O(M'Jk&;ۑmJ!o.镃z.TOVM-2uDg*5# DIvl 'Kx<55r)^89#,|Kh9<\aT( {ϗ "P6ύaLJ2.E.%:©"C EĔ@dlgBLY\k=D('o稨*D,Ns&r=TV6i>݉A#l}=2MvQLGpW{Z^XDh^hiuu7),lN2@x|-(z`ڢGbQpEK[dd6ai֢\ $5'ptG R[ɇ5Ҹ7~m[M1^$ ."GOaV9td5]oZu+V>SSZO5v7.Ac0}KߔًVv`#> {!;5miES{c{]4m)vdT8?Rͭj޺677&FuԥBEJh"z*1D+?cעIENDB`openfetion-2.2.1/skin/exit.png0000644000175000017500000000172611561721144014775 0ustar aronaronPNG  IHDRasRGBbKGD pHYs  tIME ~,VIDAT8MMhw@?36ѤEM-^$oH֖ iiiQ J)mDB)MBPR4&ۉ1~C+.q,;H55}1'(jZm_*ApŅac*c160ɾ}~8p;2TDiiǹ{72Z 8S,vv]0,hm\N~q¯v A_I_,nn;&O_Iɟ=+2ĄL'2uKDZwޓ'{zmfuua67i"q7pUf2葫D?::NA<<^zr.R < ҒElBNjGd)y΁1M6ΟudA{6eT[[$Tu~xQR,/cg؎Ě1Zo3J5 m^ǔJZ N$PAvDV6!X[w~6v];r'""LTY+kߘo3g{=rkp2J,K(5MY_$EAY~T*EHtak-/00K!,3F^/EL&T,7A mM@GJ )6 cBLGvau 6Oy{B& N~~N gfwH-~~r C3P)P`~ 5FOP?Jo9^G[Z4/Vd#C Zb KpPR%=һ2;,.Ͽ:D0ܿI)/'S ? G~)@s;39Lɋ׻x%om?iÈ*B)c.3.֨,ئ'׵6ޮ,C>/@ܤ*KKԻ)1.7)8&>Eư;*Ӻ/G]5_/O!,^>>Ov}}_o:!>}I PCGxh z\~~+ KR~}~xZ8vJåt& w~~+29~ic-TnLTq̉,B`B@CEAĸC#OH$NK/9dQ"XS9iY/Y[d]^fzo3vu2v2{CHQ M=@FKGE<=d9K k=?3;T%d"/1-/*6%#ª"ī"Ŭ${̰Ǯ+ϳҵҶԷõm׹ӹ/˹\ۼؽ.6\ js^ĝ  =k9 #Йrrҏ { Pl׋ &جk&)(+),٪.022598;ۻ<|==@CADHߗIHIKq=*OOPwVQYXJ[G]a_fPb`g[gi`aYeh`josthi~r!Created with GIMP! , HAbق*)2VLS"=t0Ѳhդ=SF (Glrlfq#E{4ᡄpER"J.M Ię֌ _)# h}82΀'/h֍Y.y+Y j֐UBŬW)J8( DڥPI3D / LpM @@)CycF $T;k6"%Ȍbp`Õ'L    Q D *@5xP@;openfetion-2.2.1/skin/face_images/12.gif0000644000175000017500000000133311561721144016444 0ustar aronaronGIF89a§&žHF<׹ 82s$Ç>!EVQ6DJS#}';&$Ź#!շ="WW D.*$ĮG$25$@D,/ŹD֓Iκ*IEF۾MFCM/ Z(? Bړݛ7-=ǰ'k%LP~0SN*=(3L8H=Җˆ1Е"#A0?33Ϲe ='4v:#J0G-w$x'!,1G4#81@ CC _y?SCHXz2Bjl4vH_Ce"">>0F;qW~~zB0N *7x"~!)19z΂U Ga9< Tdef,".БC+Y Ecy;: %xNBkHtEi!,  %pg BAQb|Ϛ!, ; Tde 54@G~Fkҕ %TZEruHA!, B 4M8R ˸#<"+)8F\9JX\p x,s!, !, ? $d*()E[[0/l/p,*pˆl&2Uc\4\ v-!, &`h2H"m;6 * !1'ZC!, A @dٜB6 %M< H@p8A!@#2l !, !, !, !, ;openfetion-2.2.1/skin/face_images/15.gif0000644000175000017500000000125011561721144016445 0ustar aronaronGIF89a݊<ԻL,ӪBAܭ,'>"۴28JٓEQPLOI11%ܩ'ã[V֧LGLGiė(R#HۦǘJŔzֳZ&˜0TXW@>?SDRXDU(ƥ\Ͱ6=]־HR?Ư{?+Ң%s(kϬ@ͱsҲAI8߳13%"3"5E^LSKأ?4%GٙSճTPע$ͣ24O7(ި\KLRbE)K!,E&:B>r/deD286;&pvy~~q*oG4~UH)w~\%c~%0hb9I,f~:{.iK[" " `#~'ll^ ]V5 _'<>TWmt P~J#@ D?Qc+& ?>fj8cCKuѧ!R C\@ (n@3Hd+@)!Y;openfetion-2.2.1/skin/face_images/16.gif0000644000175000017500000000172211561721144016452 0ustar aronaronGIF89a"GN)#-?B&7G@RJئ&%V1A(;CLKǦDF=x:ѫw'Q(UzWSɫlBSܽzUW8'Oс@Т>Ͻ\7:>-&ܭ+٦nIE3H/ot"C=Gf@a>z !C> },Xr >plpͅ%b&p' dC,X H H;:ѢŘ AX~ᢠUk (>LS=v /Fv8U< b @z}$t@!, ${|{~H~K J!, {{~!,  ~{{!, ~~{{!,&~GG{OLROKKNSPL;openfetion-2.2.1/skin/face_images/17.gif0000644000175000017500000000127111561721144016452 0ustar aronaronGIF89aff{ݾҚef򒒨﫬olghro™镕㹹蘗iipqow霜͡\\퍋ooq՗||ggt°!,-~~\}!):H$o~%x8fcJ~g2d 7E# hk~>P|~?yRdž}%/ ,Y.Z|~ /#O, ]J|`cA 2$ʞ+4"8G499zza@h``API!>+xC !/㠠  SΎ0F0aC@ }#= бC +'ihBD@35@?A>,/FC@DEGG>-NKHFAHJLLMK=6- EOI8APRSUVS0FPQN?;%!4E47A3&>"Jy5C46L>?( C03 Bf)ZLaȋ#`ÇCPFYP K&$(Y"͂w|P O <8H&8PP'+H1hHp@2\8bË⠊ <MJdnψ :,C[~aʔ5GWMX!K H0@?5ڠd(xzɎ;openfetion-2.2.1/skin/face_images/2.gif0000644000175000017500000000136211561721144016365 0ustar aronaronGIF89aUK֫Vݿ^ٻsyڇmݪ֫C›Aiǜf=ĩksn|w'Z۷VرRO^-R iȦLͼξ۱Rhw邻hkUikcaOeׯQPk?ذQKtw͊۰Ciجy|zwpюtuֿjnllwo|]ԽaF޿`bdݼZqx(x'!,9k?;51 .cW U!6,F .) .b[1Fn)EI*.''.*|' Vo mq}(("~}\J D)*A"}A)|C~"\9lE|**)7Y<Tz2 @|PG/e ~4L OChĎ/XgH gL?@!@G 5g=zBxϒf?-P}1'+F. Omѥ'tl0#(Ȑ!O3+t\qdЁV4h&i7Ȉś p?DC&zQ ;openfetion-2.2.1/skin/face_images/20.gif0000644000175000017500000000126111561721144016443 0ustar aronaronGIF89aX[6$4,D!Z\b918&(kdwUͯI!P"‘_5.!6!A!nJTCX*L!U%=!2!d=b6)!Z.d9!]2jN H!\FO-f@T#mMάhW03cbB wyF tx=&aс}޳HD܀kN*Y-K3C*R3԰ݹކp弾kGO&c98zxkeeg[XG@? fil|{iknA::ۓ갰G?=poqE<:edf71.RHF>>=urrB<<732qpnjjjMIHilnono\WU[ZXb`bbbdskhеpprsrtxwv𧥥B@ADCDEDEOFDXMK:::>;<!,~z# :{/X}~We0gS6y( ;qPGys45n+4IBs;"Ii#)+29MO7>K<0^ A[ku|t"w.+]~b 8-xZu# =-\1I$ !3ȏ IA'  1C%FP"HVp hBQ'mЧ ab>` M4 5,YipcOQ>|" m`24GHЌ'xO ;openfetion-2.2.1/skin/face_images/23.gif0000644000175000017500000000130411561721144016444 0ustar aronaronGIF89ae3حؒ|(z˔)ɳt(6T˛ڕ+x.cadgZvY¿I"TW[8!t0ͻ=ɤÆ*sDilpƫ2۸")ަ"ˇ$ֽ.(IڸAC!rc*WOB(%/*ƍ#'8=>/ן71Ȫfdm-Ѿm }sfK!$=ػUsjah@ б1ܿ,GA0ŮYϰHѠJ[CHZOĂ !,~ 99~~V $T'|7CV*$%dw 'hg95Y(17G%x=}~R "[.4zN'LOrg *B(41k2Z]uJ53F% WNb+ ln85_L)Na90c, J(-8RĊ6'D)0H`I2dx3?^ :x 7ϠC5ك!B~<4Q,ܰ"J@ X y!LX0%,(y!3!xP^KqzTA etoMāeM!,edSedcdGWcdM;bb=bc8bc-b 'eAbIU1%^ 0$)T:6Be\, C29+"Q#Z 4]D*!@7>5  _[aY.`⃄ P<)CH:(1Ȅ J@b),,!ɓ(S& ;openfetion-2.2.1/skin/face_images/25.gif0000644000175000017500000000127711561721144016457 0ustar aronaronGIF89a|ݳYI󅬫|oq,u[£wtCyt1|QͲ, l,v;}Dh  o2i%Ȼ+nɘxJҊWӽ|ꉵQ+l`hV;t(UBW̖߆n8@\Ƞ"ݵ555Рp9sn1ɝ$־lšv'ӱ-͟Θ蝗k6l8. ֩i%!,E /$`9$Sk,ec}/0~d %!bh O Î-S*P!@՟S\0͊4aBbJPA4&@E.zD@#F"41G;&$Hb!#0S`=#H(ЀІtTpx'\ S;openfetion-2.2.1/skin/face_images/26.gif0000644000175000017500000000132111561721144016446 0ustar aronaronGIF89aӖnkrﺎ9Ƽ# r{̤'"k&#R$$$;,:-'Wa.(! ­#߁{зXb}̦'P'$`٣&&`gtc̷͖$t{LU¨"㞇"pY貶G4ţ׼íU᫅U#$֟Й䭲ܔ~\f_עܥͥ'Ғ ahϦ' !,fq }."  (gy!.,8bM@a*W^ B ",ZtItm5 %}Rl~ ]d|Q\'G9~~ N)~{ (#r onD ~1~vI7k[\#+=ċ' x0 c0J B T!It80\P"@!`#C;openfetion-2.2.1/skin/face_images/27.gif0000644000175000017500000000117511561721144016456 0ustar aronaronGIF89adu å:X-#fظ+)Z %sss/ξ66֭) ]}}==ٓIgewn @<d  4+ n !z KcA- 73kIN$Lb?"tq)"\~'Qv,( ]STW[@*Eu$o ; V0dȑ[)0Þ7`T侢iճm{*/.ϺՓ'Ǚ-quϺ}/ix\O&ˮǺumȚxØHcbTϤO?mbWTBsH!,@pH,$: 8xtXxV0͆8q6ci>Yqga $+,+$$D+* ((+%%+'C(*#**+s,B))!$$)D+*+'֥sF $GpDA;openfetion-2.2.1/skin/face_images/29.gif0000644000175000017500000000121511561721144016453 0ustar aronaronGIF89a%MwC.J${$聧$M[?D_t́aT]p{$#)+B_Վbfq _&S\_u$/sz'=<=xyz278F<5g&=`%i5p bv`1&tvmop>ABS$~[M%W~//0\k~[L#\Clt2hP_]}xIM&0WB4=Yrd'?7(9-%6A)v,!@1 g8uF:UG `0f8 5  {,q = :!=0a츄Y#=V9 Osa4Q@̧JbIuRLyjJ(;openfetion-2.2.1/skin/face_images/3.gif0000644000175000017500000000232011561721144016361 0ustar aronaronGIF89a~>BF?$1IRUXLM8)ܣ5IPئ&Р(XS9@-(^,ܽKAW97(&''C3ܭ+=&"J1;ϴ~VJڞ¬xEnQPՅy&C ̓хܤ.V"GɱzGט%7.֙0ָ6M92K)$͉'+B֦(Т(ΩLKٶF̺JƟ,ӳ;S_$ˣ./B,i֗+•}"ؙ&|KTݺl^ӣغrBԒ'uK=?VK3֨,)GJVS Nx'! NETSCAPE2.0!~,}}59bzzS{1'i_} z{*+8'yy{xw+hZ yww||mf x||8yW >R PN3F>x$|..|&D5{4  |!= (XX`aert<*A&"Fwn܉Jh 88 `T P@L" 7Xd:l1`"(cG1)"ԇ!a*ADz@AQ !~,~~/\/jgz ~Uz~zXz~xwp~k} X3Akyy||ujgr}}{QBz|{{<~Ѓ ~aw4x||<}\~s~ Fq^A%AvR }F>x$~..D5~{  zz=~{ ,V[r w *05ܸ3,0,Aep0`ȇ".AqR! ~>q# 0v 8C?6v0@Fͩ~#@;openfetion-2.2.1/skin/face_images/30.gif0000644000175000017500000000123311561721144016443 0ustar aronaronGIF89a:$Y:b5<&V=]6P.m[[D?&G)E(Ux`  >ˆ! y 1p" %&ؓHP*0Сٳ];openfetion-2.2.1/skin/face_images/31.gif0000644000175000017500000000116111561721144016444 0ustar aronaronGIF89a=pIktmvpN8+E.mLL2O9Ͽ`=pxh?k^G2T+ޓxbSH7kKL6tDG)K+R8F6F3Q7F(xBwIT+fX\:F1n_F)jrF"-oNuEG5uD=)nw|qY==oH,$3L]de H 7C;O/5[8A MTVWN'`-DK:#E.@6U c a_cdcaםdQa4ߑ*^baBbb?a <c)9b(B1 YpHza@ 2$` P3D%Ę%  AZȔ & ;openfetion-2.2.1/skin/face_images/32.gif0000644000175000017500000000123411561721144016446 0ustar aronaronGIF89alu%]e& /F)!AZeLROSe($;T[8aH\e1PKM-`4W:԰ž2 ,#Iǽ2b,@& ˅ l$L``Z @a)L2>,` qECb(]:AR2!T`28Jȋ,<;openfetion-2.2.1/skin/face_images/33.gif0000644000175000017500000000130311561721144016444 0ustar aronaronGIF89aᢎpIeY8&i"g"f"g͵髖!fgvhCuՐُ㭰𲝠vժc+kbg㤏hk؄nnDyݕX7cX|p㥐ߋp7 :osV^K:ϑ㊎i{i߉owջaadvvf誕cl1ndBvҖfi8!8 8!!,|~"~ |~D~~ | |ef}|}~>~/(ojk1~~~Z`Xv s*IF@Jw #4NKl=!UT!;;Q0@1m+}ġ@1N8` ,svb1%a ѐ[XK7%"B˟9G LXDc A ч`xD (MP6 c"-Ѐ)?B^D ;openfetion-2.2.1/skin/face_images/34.gif0000644000175000017500000000177111561721144016456 0ustar aronaronGIF89azwG7WĔl6ƱsM.[WĨmgFҦŽӫÝ4}H+Wcr=)`h&ʵe홈`٪g/Ρ֩򤸛Yqo4C_eϲMnOڍjzp͚p.ϟćx4AauifYlԿ¡MɾQͰYbubh)½g%̻gҹxРےԟ~<ه؁j('̡P"P1Ƣ2s!У XhQ0F8( WHdj<FYB"4hi1-0@ A*%V@v F RXO ,)RHQ"W!,r / .*!,~!, ~r/ +*.*!,~*~ &N/" %&!,  ~/ *++*!, ~* ~ &,.!,/*+;openfetion-2.2.1/skin/face_images/35.gif0000644000175000017500000000120611561721144016450 0ustar aronaronGIF89ast}}JIu-+iKMVX_]baIfy<FXrD*?TwH\r,/vs81kSNG-)%)(Qg!U{O'~}jt5\A}ϕn4P2BAbG,wt qC lP5Ė6M,` %(`2"@;openfetion-2.2.1/skin/face_images/36.gif0000644000175000017500000000132411561721144016452 0ustar aronaronGIF89avũz̾QUPflnj'ŞUPзb[ѵ􂭬؟νei%7DGHZ`ѸޝJ`dbeltiдͅġԢjeTyq҄ߪGþzvظail}}ӶXxt@fƲw\ZsxϛqgͰnÆ!,)'~.4W72)}')-~/:IYA /)|~-|bHcCcR}|-.~}tsS<5( kE }~W>,`D yj ˆ9w(,$30) B#**))|0{@ Ya̅*|&L(`$`OL0Pݶ? i#h2ihI <-'F %.l $ BHyQ 'BP6ҟZfͰQGP1 (z gW/|x _`3adP 8"b;openfetion-2.2.1/skin/face_images/37.gif0000644000175000017500000000124211561721144016452 0ustar aronaronGIF89a f3̙3fff3f33f3! NETSCAPE2.0 !  ,pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s}=^W{|NNjj(s1t! \1 ]]!  ,pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s} ^d^j|\jN(s1#!]!]!  ,}pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s}]]^j|{j(^#j1!!^!  ,pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s} ^d^j|\jN(s1#!]!];openfetion-2.2.1/skin/face_images/38.gif0000644000175000017500000000125011561721144016452 0ustar aronaronGIF89aqzꕤݢۍsڌrz}brʚ䌐z۴ȼwؖs}hvv⛨ӷసŤev즾窿jyfp𡦨LJ_octeuȠş﴾nx!,?Q~t!} h+} WX ~}0~63V/21kOc12/\3bJ)-,#""#,-**^ }M*)G&%|=Z%Nnp}LsYo nTœ0.aI:F.Hd1G3q iAȉ.2p S@; @c |Ȃy`Vadq@O9 y@  PXV2j4;V (Ւ-;openfetion-2.2.1/skin/face_images/39.gif0000644000175000017500000000110211561721144016447 0ustar aronaronGIF89a HFP ($"3~[>   #85I %"!($7"0""OM^SPa;5D"30@86F !;9H,*):+)%$"-$"20.QGEV(&3JBU)'8*(7*(2 up  <5Kd;B?P 98K" 0QO`!,\+8F;7\Z*G M 4ZZDZ ZRP &ZLW,Z%\Q9B=ZEZ/\C2SN03TH #.[< 51J(>6IX!$?V"O)YΟ@<)، 4b;openfetion-2.2.1/skin/face_images/4.gif0000644000175000017500000000135511561721144016371 0ustar aronaronGIF89a,څM.޻<]4TKJXV2hFBS֫6GͲR:w',νN`[ݪ1<3dbej^PwǜUګ.EA1Ĩkb^-qeYhԽ0hͽ2R VNڹif٭2D0ͯNϮVӮVն\711A8P;RAtf\ը.i`/4Z:X`DcTV>ֿq4xϮnզ,^OS Kx'!,$+-+ IU667rCHw|O ]|azW7<2|'|9 JC<1;(;%%b9` Rs:H2((}}9}Ppv9d}kj}JD$_%';; }8cKKy 68} XYPD~%O"Bh!E\A~0rd4 GXo/ @PGȋ IDpH\ dC```@ψ jCpJh@APNCBESAz̄:#o ItQL!5 "X8d;openfetion-2.2.1/skin/face_images/40.gif0000644000175000017500000000110311561721144016440 0ustar aronaronGIF89a75:33:& !   @  D% 4+__b²:=:7=A69>tw(4,#F mm/?/8X?DNB&<#|xr`f5X<* ܄L=D>#1'%OcMVVW`dz}qzs*P)y|KDE+9&,S34Y5𜛽/$ $[sW"7$"'''@aU.$&az^;P8)E*{fe+G*/>30.14b4DVM99!,t;I Zt89tQt OGMt'edC6p"(?2a&/sXPb5-gEm.WfiN8с@B0 bA.& ;openfetion-2.2.1/skin/face_images/41.gif0000644000175000017500000000132711561721144016451 0ustar aronaronGIF89aÖȤȎ[{v䵷纺۬QGxCwwhxWL|L²ەT~}8uibb+źؕl]?{륥TaX~nn{4ʾqTFoqs֑ںܭtfŘn곳Ѫԝf`idrl݂vWL½杕baоɡק酇挓ѓ걲}ND}ƏȊ!, #0+#CCbU"DbJJ`-dK-II&xE[4 vf:%}$A1OyR7*%E%*e Bgg L:*:L u \)2قS878G4\@sY= {T` e#aF,*`$>d胳c 00tPP< ACPQ#(@!`@?(2JBYP. }a ,0OO4%a ,K? 8LJ5cA|r ;openfetion-2.2.1/skin/face_images/42.gif0000644000175000017500000000135211561721144016450 0ustar aronaronGIF89a֪4`F5T_/]BKj>PSèjӲQު:B٪.νeӺY?3;0``1ZYNK,=qU0_^YWUzOUǜ,2bX02ξcظh2N\fԽhNZwVi2EU4=[RQѷۮ0Q0;3L67^G1DDIHNtwcAզ,ը.9ӭJ89/id1ҪK!, )I'nJ KL0[@+.j`&*7pq\KT ovLrzOzAo- ]Q 0H2~2A{b~`u=C)r~}} <~tPl<~~,~Rf$q93  vf"F/H`q ME$L#( hY`B,(E&h2158  ~'~>@~Iv0O|((2h p0c5XG.X0 F܀'A&# 0Uc8 ɖ !B8SNm0$Hr8hEMzPà v8dA4yRhq/= aCЏ) VpYIQDʠFt1!o,QDˣ1,ԙa)vpH8\8ZG;openfetion-2.2.1/skin/face_images/44.gif0000644000175000017500000000171611561721144016456 0ustar aronaronGIF89a3f3?NR?*?ff̙33f333! NETSCAPE2.0!<,n$diP(pzB%<ȃ#B(< )0 gQ{x^b$z cypK:";>=sAQRk R/C?/- 2,\*#!!, `R iA!-, HR)@!, `HR JiA!, PR`!, `PH  !!-, `B !, `PD)!!(, `HRPA! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn;openfetion-2.2.1/skin/face_images/45.gif0000644000175000017500000000122411561721144016451 0ustar aronaronGIF89af8˾pqtﮬآІDŽcbjLeeeת{*.Ϯϼ汲ȗ{\pt͆tkϺ颫?b^䈈mO}~ޝ>!,N ?  0 2:N B 68,<1 !3)>'LL.JD"C";!HL&LJMKKM4ILGM#NL% ޑ ;tԻ7HA@#I ,6؄F^T`4A $(Ir x0$50ǃ92d DlX` A EdB  ;openfetion-2.2.1/skin/face_images/46.gif0000644000175000017500000000111711561721144016453 0ustar aronaronGIF89aϢ򎑔n:pqt~}~湹V1ǹI(ˉϺI.īϺ潻pdfcd鱶pt׆!,@ +(  ,=1)$:;>8#->7*24 >? %?>0@' > Ԃ5  &"3~4 σ]Aq@̘4@ 6,XaS ;openfetion-2.2.1/skin/face_images/47.gif0000644000175000017500000000134511561721144016457 0ustar aronaronGIF89aĮ*uwݩ&9ֽʶd[ٺRεXٴBf)*кd"ܵ3%JFOApwb')/>O;R]?MBL"y./žBK2~Οn,fwWQQ,)0ʰ]Lj,HC΢3׏64=*G)٫/G׼Pon+ŋ0Њa߾zҷ'fnͥOq7ǯ8˲AO!,R66l<c7*? oOx; O %u!";z.'~~..I% " 'pk e=`{ < *.'s 1$CK!>\'i00P@BQ~9dMk #&&8J]}| 2?t`$̉}RUbAJ rpBA 1J8h㑉?Cb-840!А2+h؂A!‹v@A@w"3΋5f13B2hJuK$HPИ1 rAB*YPl؀ xA'A`E?Yf@@V a;openfetion-2.2.1/skin/face_images/48.gif0000644000175000017500000000220311561721144016452 0ustar aronaronGIF89aVЧ|>=ڸl-ɫl8k;޿zNEÍ8ԥ(0kJ"ܭ+7'ʷ%3ڝ[Т(vG:AîB)R@C껐((IKI>'-M%}`}ZIh(P}E>E}P[} $bJ)G}}Cy'H#):Y`ɀcxX$20qKA\Nhˊ^$xe/VƋ `䂌n,0 HPzA'~Y!L>@v W0P5X+22D2,n<!!al"Cg #:`u!,"&&ihju"ih>~%>l .}:Hɘʂp"t ,z^^ ==oiw"1jopڌ!,hJ rk&X%hE>Eby}~}}ȟ Ɍ# ̃7=@Nx ||*nns*b#ٌ!,]! qXm"J!~>l~{}_qvv=-mA=ƛ1șҗNj;openfetion-2.2.1/skin/face_images/49.gif0000644000175000017500000000062611561721144016462 0ustar aronaronGIF89axޝ>iɵιzڐ?Ƒдõm԰Rˮʪճmh}˦cØHl/cOZ!,pH,k`tl`1.bFX١ @+*{ d0ZҜ02//)Cx43!C1 01023/B1x443B2/*B$1433C%3y11C"1331 D'+E- (.a  RA;openfetion-2.2.1/skin/face_images/5.gif0000644000175000017500000000135611561721144016373 0ustar aronaronGIF89a6On ׬1Ri:h&EچHة.ͽ4e]Gۜ5T11[FSWT4g;IOW"dF@̯ͣ\޿AhTxLa$Y$Bw[jLf8ZXP@z8v(s$23J12t4fE7UA?x'x(K!,()!J`?I'302B#GE'(Cj,N-B/q'C* H&&.53X~~ , kFR0~~ H<<$9D)2~=,&<[7"!M4;=~O}<d_"1l[@lϝ7A<`hO LlIs&a0!=fȉC4/\Pc<"Xp %VrPX`2Ñ  a>%Lp!B?E R>:K)@1\X >(#G q `:YG'(:th1؈ +;openfetion-2.2.1/skin/face_images/50.gif0000644000175000017500000006671511561721144016465 0ustar aronaronGIF89a @0@4aLePy ޲}aiU ΙiLyi<֡]HޮmL]@qye8YDuڥ qa0ue8m‘ ua4q]0iPy}Ҳ־mUΝ}ڪ yi@q ڶ Ϊ]HY<aLҙ}@eơڮm}e, Y8Ҫ֝־ ֶU@Y<mY(e ye|qcÃ(5Pƈ0*t8P@! ,   % pXC1d ';TP S(P*01PJ@@t`A h  B.4 `M50A‰ $*@ U*T0 & XIV(*80 j߿B,Аx1MU)bĊMƍ,/n'`mp!@@X‡J)q8/$X8I"M Ԃ hd#PLj(Z ȍ 8v֠C#Fب! ,   % pXC1d ';TP S(P*01PJ@@t`A h  B.4 `M50A‰ $*@ U*T0 & XIV(*80 j߿B,Аx1MU)bĊMƍ,/n'`mp!@@X‡J)q8/$X8I"M Ԃ hd#PLj(Z ȍ 8v֠C#Fب! ,   % pXC1d ';TP S(P*01PJ@@t`A h  B.4 `M50A‰ $*@ U*T0 & XIV(*80 j߿B,Аx1MU)bĊMƍ,/n'`mp!@@X‡J)q8/$X8I"M Ԃ hd#PLj(Z ȍ 8v֠C#Fب! , | H$L AS" 0@/@i$ BF& i Lp,D3h_i@I 98P(0yZFm 2@HP 8l@h -tvxpp"v8X &,p@C DC‚ Hp8%4Pʏ#<02=nl418*1F !,  k cȂN*\0 @ 2 8PX46I@0@UH@EQeȓ'D ԤP._\XdS?N4b@! ,  ~ vC 4d@hXQZi9 6# ȔHQ1e( 2uL8@Р6&@`=00t @ P@ %,XiaAĀ!, 9I1d 'bA@ 10:FDŽ*bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 !(, 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! ,  `   h`…( @*"!A eK8`IE|# . AZ [Dрp(>A! , 1IX(P9 x# ipt  i\ (j! , 1!H)[ <R)TpѤ-gh@! , 1IX(P9 x# ipt  i\ (j! , 1!H)[ <R)TpѤ-gh@! ,M H*\ȰÇ#JHbB)[Hhe%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 !(, 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! ,  `   h`…( @*"!A eK8`IE|# . AZ [Dрp(>A! , 1IX(P9 x# ipt  i\ (j! , 1!H)[ <R)TpѤ-gh@! , 1IX(P9 x# ipt  i\ (j! ,g H*\ȰÇ Q0F0'9681D /~) e$I)t$̄:3 pĝ :1իX! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! (, 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , H0DJ G Fǐ/P!BD&|L@TYRG"0da` 0@C\`AӦћrAF&`@U&HвDDq@6h`` i)80Q@,F$`4I1HA=ȁlR nrU.60@mیr@Xws!BpLaJԩ $u@E)0r8bhȁv4H@!D^J+a 42QBZ @x1^сS! , L!`+(a#8@*D&&,@@ ,a"EHixp〈`p1SR@)~'  aS9 3Di: lRak&PqM/4r,y B"0">@:^8q#H( F { ) lpAd hV  1b )$G#<9@(D߽A^FlQt! ,   % pX#*1d ';6TP S PU01P,  1g !t02AP&Hв54`80Qurp8` =ȁ jpƐ u =`<`˗s F  @ȀD | -J#r b@O&jlF+?Jt=nx4 B! ,  H `@X@`C 81<@ @qGL #FvI&ɆSjX! ,  P   h`…,8 @8(&T00c"ر8K~VCZJ De@! ,  H `@X@`C 81<@ @qGL #FvI&ɆSjX! ,  P   h`…,8 @8(&T00c"ر8K~VCZJ De@!,  e 6 @X8@`  x )4cdž#JCJ @+[^hCUZ6RJT ,gV%G[Ai! ,  } `XH B. bEi2bAŇ,&phC Nieɇ-{|8Pi/&@`4)(@b ,H@4Xa@! ,  T \@J@) J[PE/& !Hp%iiHӣ+C )0ɖ*R6at'> )@SZ*@F+?J <@@ D{cCD!T tQZ|@{)o! ,   % pX#* @b*Dx(̈́)+’&e/ `\``@@@ : p ,I 4x#\-  rnݵg9pMa UC65uWcEp` -0Ã`)!I:w8XB0 @$p@C ҈aA‚ $X8IMD (pG l76<ȑ`76FAÀ! ,  U @@0B @"ChB0 4yrE <2g<@N%)C6! ,  Q \@J@) J[PE/& !Hp%;(pʐl hΕ#[F#р! ,  U @@0B @"ChB0 4yrE <2g<@N%)C6! ,  Q \@J@) J[PE/& !Hp%;(pʐl hΕ#[F#р! 2, c ` ! p(0E2&cnj H ` @C WQ2Y400Μ+.@  RLMJJ*Հ! ,   % pXC*0@*Dx(̈́)">L $R0 CDâb@0 H )i$%@BϦM `0yӭ Xငe # HW 4d8a X k  El< YZAƃFbxPp9 B5 b Z &‎$4Y@ 2D .I,H@F+?JpaFdz`#Gi :T1b 7< !d,   % pX#*1d ';6TP S PU01P,  1g !tThfB AX 5̨,0&   XٺVh[G`/TjpF HU =`< bƠ" ʌ-D$\x*r P"4"0#`!$z ,Q#qm($pGhÇ76g^ՐrCg@@k^6 B 8VƃÖi ->>SgFH#rk |@R h'2wUҔPCzIdp% $&,Ƙ@@B͇=nlx*1FM !d,   % pX#*1d ';6TP S PU01P,  1g !tThfB AX 5̨,0&   XٺVh[G`/TjpF HU =`< bƠ" ʌ-D$\x*r P"4"0#`!$z ,Q#qm($pGhÇ76j Ag~A "F,(D;iN$h( Y$(t y tg2'hDɵ(HT ?Y𢼄& *ŒCA UeD@G((t@1'#`% ! ,  / (0XHiJKCi @(Џ47 @ȁ! ,  85#@A `ihPZi*Rȱ;Nxѣɓ\)bIi! ,  =bAA2( @Cpbi ^h ď ?: !$SDqQD2 ! ,  :@101( @E)j(>ȱɍHq!/(! , H*\ȰÇBѠ@!HB"҄M((JRG/ @E2r@|.,Bgt9@aG~pcB.o̰H,2Pà7RPXe! , "M;DSYDX@PO&Kx(E(,Zr *?xhDU/U(( @`@B3%P/B} A j-tjS@ .LH"q҄1 ԓbG`犝D0jP 0xA2!00@㧝!LaׁĜ<  \JNaRUɰdR($EQqA݀u^X K !^H" -`F\[)J{ .x!!REHNI#gPA!xRGNt@G(T!x'#x#&H4Q@! ,  &B8" <)⅓*D8Ɇ &,O1 <8ЁA)l*\hС$F=) 0A $crP 4xRPB `\ت8r09!2AZR N=F ҌdĀ<R*Pb#T0  1N|@R)TpĂ hd@[f7BqcC8#lTЀ`@! ,  H 0S !%V(af F C$hǔAb\ib Y)&"4U, BF& Ԧ $ @@@jC@E6J$s.: $2Dfa ! B$@`@$AEFbxNH @ @0Ą(|haT&x!H X$,p"I+?J `ÌB!:T1b  ! ,  ( 0S a%d#I!F Ǐ2*D@hGGR\@4H DH q(UHBȅLHM '6x3@S0&8 rp8 !xVő @޾@@@C6LxG$P 8 AH!f D$\`-J#r@G JA MD NpG lÇ76t(FبС! ,  D0S Ci2Qb+p@(Ǐ2^8ٱB=Z`‚*KjXM2 0@j\*\h &΢$h@"Ǖ` 3pH R$+X 0`Ԫ8rKW+21dt#sJ< 0k4Z!a$͜vy"  .p`H‡K8Â/^XIMD NpG lÇ7JL#FبС! , D0S Ã2Q@J*rX#BBfHNvla Ȑc"PU0!ȟ@B:f̦"! XBHP 0 $  E $fD>ࠈ:,H<Z>4 )\h`A(0ƒ 3r| ʖIB06TAu! , D%V()P !J,`*D(M=21  LXPeI eS4vB0DɰiPB$P!BP`W$h@Φ vO 4x`6+kծݩ 0E6 UqRFv A t^w!B$Hh:"IFbx@vl'2 AL@`(ia4"t0< A N8|@R@uijpI hdl74}с60 tЀD! , 80DJ GFǐ/P!BD&|L@TYRDҠ 0D ,l\AB.4&èU) l UFA0@8 XaLqxR ,)l #E8f B26BIͥƠ"DFbx[P @ DJ>9&/!ƉHX$,XА=Õ%>J|aFdpGWP00TT! , HPZ+(a#P! ^8ٱBM &, E`` "@ͣ8$P!BL@H!Le X  `7 Xa-;M , gWőZ] f@5Be!l< Ai -Hr(bxHZmP%M0q\`P‡N,<^@:LH@^B*(MRf$,X`=Õ% _`,4̐dpCGdmЁ60 t@! ,  % pX##TcȂNvl@>`A@ ,a Y <8ЁA ,dZAB.4Ȅ@ Z6 Jf<!ذoTB ;/YtU9 @a˅m`JPW)G3g`4A"У< (_`@‡J$p@ Kq>`L .I4/Xx+?J ^If@ǍBBZ00TR!,   % pX#*1d ';6TP S PU01P,  1g !t02a@ 0A $ @WOg@@ÌtVL ,P`]wȁz`SRd h -t@CfcsȀD:;,`'P"4"t8'> 9S\h`A W~9>qC#ǎ;1b < ! ,  &L0 @ZQ` +3F!<,  )I@ZYH `C XpE`G ;openfetion-2.2.1/skin/face_images/51.gif0000644000175000017500000000116211561721144016447 0ustar aronaronGIF89aG'}z1߶N`0ګ5K@(N! NETSCAPE2.0!,#1(M1芇84(>`Ph|4 F1Ad meָ F4[$EЌ^(&B`ih iKi({xg w l|L`36\| 65K72(} 66ZZ  Z7-b|G Ư. F.;#%v؁"!!,P  bN[B;8 1,TL4,ȅaDI*}Ij }%d B# YnہxV"EC!, L $baPr@B8JݎC: (-A$!1XEV5}/Am߁xF Q!, O $p$ BTCn "tDTU@%ArhA(In.ָ`|0 ;openfetion-2.2.1/skin/face_images/52.gif0000644000175000017500000000134011561721144016446 0ustar aronaronGIF89aԐV .C8)`KB;=R"ƼC'%3JN(թ,ξG=9֫ӥ(~s&p3b8, (ŵ(ű'ʧ:@ܿ;:һ  2}}}@@@ԻجE333ئ&LA4PPP&x+O&յg1W*"v(v_"Р'A<ְ0H7%MI5$#ޯ,Loi\Hĵ"/ppm-Gyj CE.I+KxJ4ϟ)x&T\\\D>?-/)x'!,Y#d`7Ro,jn8>0Y9,= H679II  {U^~~)Vu)DOtb'c~v;33A~ EC~22 qATrXa *~W .g@@m-ML'F FV,.00bM& 0 :*4}z2mC?>@*6e@ 6=P0 c `Bȃ4DEJPQ ;openfetion-2.2.1/skin/face_images/6.gif0000644000175000017500000000215511561721144016372 0ustar aronaronGIF89a %%!#!)%<* M-=3%MG'OH$[N=YUEa[BwX&a[Tc]DgbFcb^md9wdBph?|jng\{knzo3|o/snVvscu0rTv2w?}{q}AgۼǺvٽ.¼οo 1 )Ŀ3ɀ ˇ ̷Ѫ  Dl Hو&)(,+ڙ02259k8;<=+=@"@80ݷqTa4'~TXyObEVT2f=jLa9[mCZSkAfedׅ]jMoDhKX^I{ =7C"X}`;L; #) }~O}hk+%Q;f>~E~wh!~;.`dž ?v*8б G}0ʇ>~\ha%4|؃KS! #H0PgFH`F1R >pB>bLl#!LW_XD WLXer:Ō=da٧>g2H#P ,w]N_O)_Ӗ0VtI߰2Xֵ:kګ+ԟ8IԽHտԛ4Ԟ7aթ֫Ο)N!,-SHOMB5m`Z$:0>DaLk*FMDYdLo "v {B!!L \p X15)!??!o $J-LL==6~~AK&No~~[ rVL)ÀF?~H;@10BD ~,I"ŏ #4X` !P8(@!B*nĜi )&&b8s!& %NVeσ;openfetion-2.2.1/skin/face_images/9.gif0000644000175000017500000000665411561721144016405 0ustar aronaronGIF89aӳKyY>нb0Zs2⯷yս7ƚMFҥ)Dç;EA-۬-\#5kVJQgզ+4]8jg?Nh`/U.BRWU>2<8DA9M7ܨ?*xٹkWFTPTGئ&ǩg'.Ϡ'U<(&'ȅ4ٔ.LO;>1zV+vm^ܿwߥ:hi޼?l\Yڙ1νF~:wb)ˡ:Eyk56lP%;St,萐ϊ:j8FIĐ@RŠ1tHa!'ztA9-[VPx%'< J8c LK @H!ЊڳAKS)ۥR!yA'Gg *I:8(!,I I=.2=31&332_,}K43zzDz}>%Ӈ[)0` s++JId%苿KJ<7(!,O @P@=O~^/#qS~(~ -E-(|E$9M^|CzCZz0'Az ~ zz7&M ~.(z; @/ۣ!0HP|(ϖiAh B8? yA".;lt) > AFˆ =xD#Iȴx2 d@&̊s`i A +$a#A7 hGXo@i#jM` ͨ &AL0b%}$J`vP !,I @  I v},y0=I@.2,,}@y.3.15L. 44341&I}4_2_uK2D}0N@:2zzz}0H,DD}>566DI]S|A :$<(!lQR1$â6pRBA!+BBC?$@P9z0)VO `B AxXȰM8KJFDR 89BD'?ph$Q(@!,O @P@=O~H{/#qS~ |{C(|# z~ o--C{ZEi{C|{FM^|<{A~OaB-9&rj/$'n@/BbBFAA#BaN}X/ǍA@"B>|^0…ˎA=, XafG56 }$ ;CG 6 Bb }?%tA"[RRǃ$C2Ɗ?+rPϜ?=9`E `<?xSp%LO2Ry)%~>A#T@Tq ~ud(tpxvP !,~O @P@=O^/#qS~.(. .-E-(|E$9M^|CzCZz0'Az ~ zz7&M ~.~ڤz; @/٣!0HP|(ZP|Y!Á|^`]JxG/0cB!QEH0) a@s"iHPŠ) r15 h0GXo0i#jM` ͨ `&AL0b%唡$J`vP !,~K=@ =K~=v},y0I@..442,,}A33,15.A~=31&~K}4_z2zue 24z3D,:0N@:43Х}:''0H,DD>56lP%;St,萐ϊ:j8FIĐ@RŠ1tHa!'ztA9-[VPx%'< J8c LK @H!ЊڳAKS)ۥR!yA'Gg *I:8(;openfetion-2.2.1/skin/face_images/big_1.gif0000644000175000017500000000135411561721144017206 0ustar aronaronGIF89awh8Nԥ(5%-ܭ+'3KֶgТ(;G:ט&B"v=BKUx'ުR@νV(9=?(ξ(Tՙ0IKIڡ6U*'ĩkSNOǝΉ'?3ܤ.S ^-E֫տئ&L#wQS2EH)@۹9K&Mٟ4wР'QW$1+JenoC&H֮1o34`D/Pϟ)VW֨,?>-/00K!,3F^/EL&T,7A mM@GJ )6 cBLGvau 6Oy{B& N~~N gfwH-~~r C3P)P`~ 5FOP?Jo9^G[Z4/Vd#C Zb KpPR%=һ2;,.Ͽ:D0ܿI)/'S ? G~)@s;39Lɋ׻x%om?iÈ*B)c.3.֨,ئ'׵6ޮ,C>/@ܤ*KKԻ)1.7)8&>Eư;*Ӻ/G]5_/O!,^>>Ov}}_o:!>}I PCGxh z\~~+ KR~}~xZ8vJåt& w~~+29~ic-TnLTq̉,B`B@CEAĸC#OH$NK/9dQ"XS9iY/Y[d]^fzo3vu2v2{CHQ M=@FKGE<=d9K k=?3;T%d"/1-/*6%#ª"ī"Ŭ${̰Ǯ+ϳҵҶԷõm׹ӹ/˹\ۼؽ.6\ js^ĝ  =k9 #Йrrҏ { Pl׋ &جk&)(+),٪.022598;ۻ<|==@CADHߗIHIKq=*OOPwVQYXJ[G]a_fPb`g[gi`aYeh`josthi~r!Created with GIMP! , HAbق*)2VLS"=t0Ѳhդ=SF (Glrlfq#E{4ᡄpER"J.M Ię֌ _)# h}82΀'/h֍Y.y+Y j֐UBŬW)J8( DڥPI3D / LpM @@)CycF $T;k6"%Ȍbp`Õ'L    Q D *@5xP@;openfetion-2.2.1/skin/face_images/big_12.gif0000644000175000017500000000133311561721144017265 0ustar aronaronGIF89a§&žHF<׹ 82s$Ç>!EVQ6DJS#}';&$Ź#!շ="WW D.*$ĮG$25$@D,/ŹD֓Iκ*IEF۾MFCM/ Z(? Bړݛ7-=ǰ'k%LP~0SN*=(3L8H=Җˆ1Е"#A0?33Ϲe ='4v:#J0G-w$x'!,1G4#81@ CC _y?SCHXz2Bjl4vH_Ce"">>0F;qW~~zB0N *7x"~!)19z΂U Ga9< Tdef,".БC+Y Ecy;: %xNBkHtEi!,  %pg BAQb|Ϛ!, ; Tde 54@G~Fkҕ %TZEruHA!, B 4M8R ˸#<"+)8F\9JX\p x,s!, !, ? $d*()E[[0/l/p,*pˆl&2Uc\4\ v-!, &`h2H"m;6 * !1'ZC!, A @dٜB6 %M< H@p8A!@#2l !, !, !, !, ;openfetion-2.2.1/skin/face_images/big_15.gif0000644000175000017500000000125011561721144017266 0ustar aronaronGIF89a݊<ԻL,ӪBAܭ,'>"۴28JٓEQPLOI11%ܩ'ã[V֧LGLGiė(R#HۦǘJŔzֳZ&˜0TXW@>?SDRXDU(ƥ\Ͱ6=]־HR?Ư{?+Ң%s(kϬ@ͱsҲAI8߳13%"3"5E^LSKأ?4%GٙSճTPע$ͣ24O7(ި\KLRbE)K!,E&:B>r/deD286;&pvy~~q*oG4~UH)w~\%c~%0hb9I,f~:{.iK[" " `#~'ll^ ]V5 _'<>TWmt P~J#@ D?Qc+& ?>fj8cCKuѧ!R C\@ (n@3Hd+@)!Y;openfetion-2.2.1/skin/face_images/big_16.gif0000644000175000017500000000172211561721144017273 0ustar aronaronGIF89a"GN)#-?B&7G@RJئ&%V1A(;CLKǦDF=x:ѫw'Q(UzWSɫlBSܽzUW8'Oс@Т>Ͻ\7:>-&ܭ+٦nIE3H/ot"C=Gf@a>z !C> },Xr >plpͅ%b&p' dC,X H H;:ѢŘ AX~ᢠUk (>LS=v /Fv8U< b @z}$t@!, ${|{~H~K J!, {{~!,  ~{{!, ~~{{!,&~GG{OLROKKNSPL;openfetion-2.2.1/skin/face_images/big_17.gif0000644000175000017500000000127111561721144017273 0ustar aronaronGIF89aff{ݾҚef򒒨﫬olghro™镕㹹蘗iipqow霜͡\\퍋ooq՗||ggt°!,-~~\}!):H$o~%x8fcJ~g2d 7E# hk~>P|~?yRdž}%/ ,Y.Z|~ /#O, ]J|`cA 2$ʞ+4"8G499zza@h``API!>+xC !/㠠  SΎ0F0aC@ }#= бC +'ihBD@35@?A>,/FC@DEGG>-NKHFAHJLLMK=6- EOI8APRSUVS0FPQN?;%!4E47A3&>"Jy5C46L>?( C03 Bf)ZLaȋ#`ÇCPFYP K&$(Y"͂w|P O <8H&8PP'+H1hHp@2\8bË⠊ <MJdnψ :,C[~aʔ5GWMX!K H0@?5ڠd(xzɎ;openfetion-2.2.1/skin/face_images/big_2.gif0000644000175000017500000000136211561721144017206 0ustar aronaronGIF89aUK֫Vݿ^ٻsyڇmݪ֫C›Aiǜf=ĩksn|w'Z۷VرRO^-R iȦLͼξ۱Rhw邻hkUikcaOeׯQPk?ذQKtw͊۰Ciجy|zwpюtuֿjnllwo|]ԽaF޿`bdݼZqx(x'!,9k?;51 .cW U!6,F .) .b[1Fn)EI*.''.*|' Vo mq}(("~}\J D)*A"}A)|C~"\9lE|**)7Y<Tz2 @|PG/e ~4L OChĎ/XgH gL?@!@G 5g=zBxϒf?-P}1'+F. Omѥ'tl0#(Ȑ!O3+t\qdЁV4h&i7Ȉś p?DC&zQ ;openfetion-2.2.1/skin/face_images/big_20.gif0000644000175000017500000000126111561721144017264 0ustar aronaronGIF89aX[6$4,D!Z\b918&(kdwUͯI!P"‘_5.!6!A!nJTCX*L!U%=!2!d=b6)!Z.d9!]2jN H!\FO-f@T#mMάhW03cbB wyF tx=&aс}޳HD܀kN*Y-K3C*R3԰ݹކp弾kGO&c98zxkeeg[XG@? fil|{iknA::ۓ갰G?=poqE<:edf71.RHF>>=urrB<<732qpnjjjMIHilnono\WU[ZXb`bbbdskhеpprsrtxwv𧥥B@ADCDEDEOFDXMK:::>;<!,~z# :{/X}~We0gS6y( ;qPGys45n+4IBs;"Ii#)+29MO7>K<0^ A[ku|t"w.+]~b 8-xZu# =-\1I$ !3ȏ IA'  1C%FP"HVp hBQ'mЧ ab>` M4 5,YipcOQ>|" m`24GHЌ'xO ;openfetion-2.2.1/skin/face_images/big_23.gif0000644000175000017500000000130411561721144017265 0ustar aronaronGIF89ae3حؒ|(z˔)ɳt(6T˛ڕ+x.cadgZvY¿I"TW[8!t0ͻ=ɤÆ*sDilpƫ2۸")ަ"ˇ$ֽ.(IڸAC!rc*WOB(%/*ƍ#'8=>/ן71Ȫfdm-Ѿm }sfK!$=ػUsjah@ б1ܿ,GA0ŮYϰHѠJ[CHZOĂ !,~ 99~~V $T'|7CV*$%dw 'hg95Y(17G%x=}~R "[.4zN'LOrg *B(41k2Z]uJ53F% WNb+ ln85_L)Na90c, J(-8RĊ6'D)0H`I2dx3?^ :x 7ϠC5ك!B~<4Q,ܰ"J@ X y!LX0%,(y!3!xP^KqzTA etoMāeM!,edSedcdGWcdM;bb=bc8bc-b 'eAbIU1%^ 0$)T:6Be\, C29+"Q#Z 4]D*!@7>5  _[aY.`⃄ P<)CH:(1Ȅ J@b),,!ɓ(S& ;openfetion-2.2.1/skin/face_images/big_25.gif0000644000175000017500000000127711561721144017300 0ustar aronaronGIF89a|ݳYI󅬫|oq,u[£wtCyt1|QͲ, l,v;}Dh  o2i%Ȼ+nɘxJҊWӽ|ꉵQ+l`hV;t(UBW̖߆n8@\Ƞ"ݵ555Рp9sn1ɝ$־lšv'ӱ-͟Θ蝗k6l8. ֩i%!,E /$`9$Sk,ec}/0~d %!bh O Î-S*P!@՟S\0͊4aBbJPA4&@E.zD@#F"41G;&$Hb!#0S`=#H(ЀІtTpx'\ S;openfetion-2.2.1/skin/face_images/big_26.gif0000644000175000017500000000132111561721144017267 0ustar aronaronGIF89aӖnkrﺎ9Ƽ# r{̤'"k&#R$$$;,:-'Wa.(! ­#߁{зXb}̦'P'$`٣&&`gtc̷͖$t{LU¨"㞇"pY貶G4ţ׼íU᫅U#$֟Й䭲ܔ~\f_עܥͥ'Ғ ahϦ' !,fq }."  (gy!.,8bM@a*W^ B ",ZtItm5 %}Rl~ ]d|Q\'G9~~ N)~{ (#r onD ~1~vI7k[\#+=ċ' x0 c0J B T!It80\P"@!`#C;openfetion-2.2.1/skin/face_images/big_27.gif0000644000175000017500000000117511561721144017277 0ustar aronaronGIF89adu å:X-#fظ+)Z %sss/ξ66֭) ]}}==ٓIgewn @<d  4+ n !z KcA- 73kIN$Lb?"tq)"\~'Qv,( ]STW[@*Eu$o ; V0dȑ[)0Þ7`T侢iճm{*/.ϺՓ'Ǚ-quϺ}/ix\O&ˮǺumȚxØHcbTϤO?mbWTBsH!,@pH,$: 8xtXxV0͆8q6ci>Yqga $+,+$$D+* ((+%%+'C(*#**+s,B))!$$)D+*+'֥sF $GpDA;openfetion-2.2.1/skin/face_images/big_29.gif0000644000175000017500000000121511561721144017274 0ustar aronaronGIF89a%MwC.J${$聧$M[?D_t́aT]p{$#)+B_Վbfq _&S\_u$/sz'=<=xyz278F<5g&=`%i5p bv`1&tvmop>ABS$~[M%W~//0\k~[L#\Clt2hP_]}xIM&0WB4=Yrd'?7(9-%6A)v,!@1 g8uF:UG `0f8 5  {,q = :!=0a츄Y#=V9 Osa4Q@̧JbIuRLyjJ(;openfetion-2.2.1/skin/face_images/big_3.gif0000644000175000017500000000232011561721144017202 0ustar aronaronGIF89a~>BF?$1IRUXLM8)ܣ5IPئ&Р(XS9@-(^,ܽKAW97(&''C3ܭ+=&"J1;ϴ~VJڞ¬xEnQPՅy&C ̓хܤ.V"GɱzGט%7.֙0ָ6M92K)$͉'+B֦(Т(ΩLKٶF̺JƟ,ӳ;S_$ˣ./B,i֗+•}"ؙ&|KTݺl^ӣغrBԒ'uK=?VK3֨,)GJVS Nx'! NETSCAPE2.0!~,}}59bzzS{1'i_} z{*+8'yy{xw+hZ yww||mf x||8yW >R PN3F>x$|..|&D5{4  |!= (XX`aert<*A&"Fwn܉Jh 88 `T P@L" 7Xd:l1`"(cG1)"ԇ!a*ADz@AQ !~,~~/\/jgz ~Uz~zXz~xwp~k} X3Akyy||ujgr}}{QBz|{{<~Ѓ ~aw4x||<}\~s~ Fq^A%AvR }F>x$~..D5~{  zz=~{ ,V[r w *05ܸ3,0,Aep0`ȇ".AqR! ~>q# 0v 8C?6v0@Fͩ~#@;openfetion-2.2.1/skin/face_images/big_30.gif0000644000175000017500000000123311561721144017264 0ustar aronaronGIF89a:$Y:b5<&V=]6P.m[[D?&G)E(Ux`  >ˆ! y 1p" %&ؓHP*0Сٳ];openfetion-2.2.1/skin/face_images/big_31.gif0000644000175000017500000000116111561721144017265 0ustar aronaronGIF89a=pIktmvpN8+E.mLL2O9Ͽ`=pxh?k^G2T+ޓxbSH7kKL6tDG)K+R8F6F3Q7F(xBwIT+fX\:F1n_F)jrF"-oNuEG5uD=)nw|qY==oH,$3L]de H 7C;O/5[8A MTVWN'`-DK:#E.@6U c a_cdcaםdQa4ߑ*^baBbb?a <c)9b(B1 YpHza@ 2$` P3D%Ę%  AZȔ & ;openfetion-2.2.1/skin/face_images/big_32.gif0000644000175000017500000000123411561721144017267 0ustar aronaronGIF89alu%]e& /F)!AZeLROSe($;T[8aH\e1PKM-`4W:԰ž2 ,#Iǽ2b,@& ˅ l$L``Z @a)L2>,` qECb(]:AR2!T`28Jȋ,<;openfetion-2.2.1/skin/face_images/big_33.gif0000644000175000017500000000130311561721144017265 0ustar aronaronGIF89aᢎpIeY8&i"g"f"g͵髖!fgvhCuՐُ㭰𲝠vժc+kbg㤏hk؄nnDyݕX7cX|p㥐ߋp7 :osV^K:ϑ㊎i{i߉owջaadvvf誕cl1ndBvҖfi8!8 8!!,|~"~ |~D~~ | |ef}|}~>~/(ojk1~~~Z`Xv s*IF@Jw #4NKl=!UT!;;Q0@1m+}ġ@1N8` ,svb1%a ѐ[XK7%"B˟9G LXDc A ч`xD (MP6 c"-Ѐ)?B^D ;openfetion-2.2.1/skin/face_images/big_34.gif0000644000175000017500000000177111561721144017277 0ustar aronaronGIF89azwG7WĔl6ƱsM.[WĨmgFҦŽӫÝ4}H+Wcr=)`h&ʵe홈`٪g/Ρ֩򤸛Yqo4C_eϲMnOڍjzp͚p.ϟćx4AauifYlԿ¡MɾQͰYbubh)½g%̻gҹxРےԟ~<ه؁j('̡P"P1Ƣ2s!У XhQ0F8( WHdj<FYB"4hi1-0@ A*%V@v F RXO ,)RHQ"W!,r / .*!,~!, ~r/ +*.*!,~*~ &N/" %&!,  ~/ *++*!, ~* ~ &,.!,/*+;openfetion-2.2.1/skin/face_images/big_35.gif0000644000175000017500000000120611561721144017271 0ustar aronaronGIF89ast}}JIu-+iKMVX_]baIfy<FXrD*?TwH\r,/vs81kSNG-)%)(Qg!U{O'~}jt5\A}ϕn4P2BAbG,wt qC lP5Ė6M,` %(`2"@;openfetion-2.2.1/skin/face_images/big_36.gif0000644000175000017500000000132411561721144017273 0ustar aronaronGIF89avũz̾QUPflnj'ŞUPзb[ѵ􂭬؟νei%7DGHZ`ѸޝJ`dbeltiдͅġԢjeTyq҄ߪGþzvظail}}ӶXxt@fƲw\ZsxϛqgͰnÆ!,)'~.4W72)}')-~/:IYA /)|~-|bHcCcR}|-.~}tsS<5( kE }~W>,`D yj ˆ9w(,$30) B#**))|0{@ Ya̅*|&L(`$`OL0Pݶ? i#h2ihI <-'F %.l $ BHyQ 'BP6ҟZfͰQGP1 (z gW/|x _`3adP 8"b;openfetion-2.2.1/skin/face_images/big_37.gif0000644000175000017500000000124211561721144017273 0ustar aronaronGIF89a f3̙3fff3f33f3! NETSCAPE2.0 !  ,pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s}=^W{|NNjj(s1t! \1 ]]!  ,pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s} ^d^j|\jN(s1#!]!]!  ,}pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s}]]^j|{j(^#j1!!^!  ,pIx֤zup^dX&)yjQ 6"+*ϫ5@$J8Βb "Q(FBpҖm!a8PWlzLR{s} ^d^j|\jN(s1#!]!];openfetion-2.2.1/skin/face_images/big_38.gif0000644000175000017500000000125011561721144017273 0ustar aronaronGIF89aqzꕤݢۍsڌrz}brʚ䌐z۴ȼwؖs}hvv⛨ӷసŤev즾窿jyfp𡦨LJ_octeuȠş﴾nx!,?Q~t!} h+} WX ~}0~63V/21kOc12/\3bJ)-,#""#,-**^ }M*)G&%|=Z%Nnp}LsYo nTœ0.aI:F.Hd1G3q iAȉ.2p S@; @c |Ȃy`Vadq@O9 y@  PXV2j4;V (Ւ-;openfetion-2.2.1/skin/face_images/big_39.gif0000644000175000017500000000110211561721144017270 0ustar aronaronGIF89a HFP ($"3~[>   #85I %"!($7"0""OM^SPa;5D"30@86F !;9H,*):+)%$"-$"20.QGEV(&3JBU)'8*(7*(2 up  <5Kd;B?P 98K" 0QO`!,\+8F;7\Z*G M 4ZZDZ ZRP &ZLW,Z%\Q9B=ZEZ/\C2SN03TH #.[< 51J(>6IX!$?V"O)YΟ@<)، 4b;openfetion-2.2.1/skin/face_images/big_4.gif0000644000175000017500000000135511561721144017212 0ustar aronaronGIF89a,څM.޻<]4TKJXV2hFBS֫6GͲR:w',νN`[ݪ1<3dbej^PwǜUګ.EA1Ĩkb^-qeYhԽ0hͽ2R VNڹif٭2D0ͯNϮVӮVն\711A8P;RAtf\ը.i`/4Z:X`DcTV>ֿq4xϮnզ,^OS Kx'!,$+-+ IU667rCHw|O ]|azW7<2|'|9 JC<1;(;%%b9` Rs:H2((}}9}Ppv9d}kj}JD$_%';; }8cKKy 68} XYPD~%O"Bh!E\A~0rd4 GXo/ @PGȋ IDpH\ dC```@ψ jCpJh@APNCBESAz̄:#o ItQL!5 "X8d;openfetion-2.2.1/skin/face_images/big_40.gif0000644000175000017500000000110311561721144017261 0ustar aronaronGIF89a75:33:& !   @  D% 4+__b²:=:7=A69>tw(4,#F mm/?/8X?DNB&<#|xr`f5X<* ܄L=D>#1'%OcMVVW`dz}qzs*P)y|KDE+9&,S34Y5𜛽/$ $[sW"7$"'''@aU.$&az^;P8)E*{fe+G*/>30.14b4DVM99!,t;I Zt89tQt OGMt'edC6p"(?2a&/sXPb5-gEm.WfiN8с@B0 bA.& ;openfetion-2.2.1/skin/face_images/big_41.gif0000644000175000017500000000132711561721144017272 0ustar aronaronGIF89aÖȤȎ[{v䵷纺۬QGxCwwhxWL|L²ەT~}8uibb+źؕl]?{륥TaX~nn{4ʾqTFoqs֑ںܭtfŘn곳Ѫԝf`idrl݂vWL½杕baоɡק酇挓ѓ걲}ND}ƏȊ!, #0+#CCbU"DbJJ`-dK-II&xE[4 vf:%}$A1OyR7*%E%*e Bgg L:*:L u \)2قS878G4\@sY= {T` e#aF,*`$>d胳c 00tPP< ACPQ#(@!`@?(2JBYP. }a ,0OO4%a ,K? 8LJ5cA|r ;openfetion-2.2.1/skin/face_images/big_42.gif0000644000175000017500000000135211561721144017271 0ustar aronaronGIF89a֪4`F5T_/]BKj>PSèjӲQު:B٪.νeӺY?3;0``1ZYNK,=qU0_^YWUzOUǜ,2bX02ξcظh2N\fԽhNZwVi2EU4=[RQѷۮ0Q0;3L67^G1DDIHNtwcAզ,ը.9ӭJ89/id1ҪK!, )I'nJ KL0[@+.j`&*7pq\KT ovLrzOzAo- ]Q 0H2~2A{b~`u=C)r~}} <~tPl<~~,~Rf$q93  vf"F/H`q ME$L#( hY`B,(E&h2158  ~'~>@~Iv0O|((2h p0c5XG.X0 F܀'A&# 0Uc8 ɖ !B8SNm0$Hr8hEMzPà v8dA4yRhq/= aCЏ) VpYIQDʠFt1!o,QDˣ1,ԙa)vpH8\8ZG;openfetion-2.2.1/skin/face_images/big_44.gif0000644000175000017500000000171611561721144017277 0ustar aronaronGIF89a3f3?NR?*?ff̙33f333! NETSCAPE2.0!<,n$diP(pzB%<ȃ#B(< )0 gQ{x^b$z cypK:";>=sAQRk R/C?/- 2,\*#!!, `R iA!-, HR)@!, `HR JiA!, PR`!, `PH  !!-, `B !, `PD)!!(, `HRPA! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn! ,  `$ICJ! ,  $JD"Z3! , $>D蜥hFn;openfetion-2.2.1/skin/face_images/big_45.gif0000644000175000017500000000122411561721144017272 0ustar aronaronGIF89af8˾pqtﮬآІDŽcbjLeeeת{*.Ϯϼ汲ȗ{\pt͆tkϺ颫?b^䈈mO}~ޝ>!,N ?  0 2:N B 68,<1 !3)>'LL.JD"C";!HL&LJMKKM4ILGM#NL% ޑ ;tԻ7HA@#I ,6؄F^T`4A $(Ir x0$50ǃ92d DlX` A EdB  ;openfetion-2.2.1/skin/face_images/big_46.gif0000644000175000017500000000111711561721144017274 0ustar aronaronGIF89aϢ򎑔n:pqt~}~湹V1ǹI(ˉϺI.īϺ潻pdfcd鱶pt׆!,@ +(  ,=1)$:;>8#->7*24 >? %?>0@' > Ԃ5  &"3~4 σ]Aq@̘4@ 6,XaS ;openfetion-2.2.1/skin/face_images/big_47.gif0000644000175000017500000000134511561721144017300 0ustar aronaronGIF89aĮ*uwݩ&9ֽʶd[ٺRεXٴBf)*кd"ܵ3%JFOApwb')/>O;R]?MBL"y./žBK2~Οn,fwWQQ,)0ʰ]Lj,HC΢3׏64=*G)٫/G׼Pon+ŋ0Њa߾zҷ'fnͥOq7ǯ8˲AO!,R66l<c7*? oOx; O %u!";z.'~~..I% " 'pk e=`{ < *.'s 1$CK!>\'i00P@BQ~9dMk #&&8J]}| 2?t`$̉}RUbAJ rpBA 1J8h㑉?Cb-840!А2+h؂A!‹v@A@w"3΋5f13B2hJuK$HPИ1 rAB*YPl؀ xA'A`E?Yf@@V a;openfetion-2.2.1/skin/face_images/big_48.gif0000644000175000017500000000220311561721144017273 0ustar aronaronGIF89aVЧ|>=ڸl-ɫl8k;޿zNEÍ8ԥ(0kJ"ܭ+7'ʷ%3ڝ[Т(vG:AîB)R@C껐((IKI>'-M%}`}ZIh(P}E>E}P[} $bJ)G}}Cy'H#):Y`ɀcxX$20qKA\Nhˊ^$xe/VƋ `䂌n,0 HPzA'~Y!L>@v W0P5X+22D2,n<!!al"Cg #:`u!,"&&ihju"ih>~%>l .}:Hɘʂp"t ,z^^ ==oiw"1jopڌ!,hJ rk&X%hE>Eby}~}}ȟ Ɍ# ̃7=@Nx ||*nns*b#ٌ!,]! qXm"J!~>l~{}_qvv=-mA=ƛ1șҗNj;openfetion-2.2.1/skin/face_images/big_49.gif0000644000175000017500000000062611561721144017303 0ustar aronaronGIF89axޝ>iɵιzڐ?Ƒдõm԰Rˮʪճmh}˦cØHl/cOZ!,pH,k`tl`1.bFX١ @+*{ d0ZҜ02//)Cx43!C1 01023/B1x443B2/*B$1433C%3y11C"1331 D'+E- (.a  RA;openfetion-2.2.1/skin/face_images/big_5.gif0000644000175000017500000000135611561721144017214 0ustar aronaronGIF89a6On ׬1Ri:h&EچHة.ͽ4e]Gۜ5T11[FSWT4g;IOW"dF@̯ͣ\޿AhTxLa$Y$Bw[jLf8ZXP@z8v(s$23J12t4fE7UA?x'x(K!,()!J`?I'302B#GE'(Cj,N-B/q'C* H&&.53X~~ , kFR0~~ H<<$9D)2~=,&<[7"!M4;=~O}<d_"1l[@lϝ7A<`hO LlIs&a0!=fȉC4/\Pc<"Xp %VrPX`2Ñ  a>%Lp!B?E R>:K)@1\X >(#G q `:YG'(:th1؈ +;openfetion-2.2.1/skin/face_images/big_50.gif0000644000175000017500000006671511561721144017306 0ustar aronaronGIF89a @0@4aLePy ޲}aiU ΙiLyi<֡]HޮmL]@qye8YDuڥ qa0ue8m‘ ua4q]0iPy}Ҳ־mUΝ}ڪ yi@q ڶ Ϊ]HY<aLҙ}@eơڮm}e, Y8Ҫ֝־ ֶU@Y<mY(e ye|qcÃ(5Pƈ0*t8P@! ,   % pXC1d ';TP S(P*01PJ@@t`A h  B.4 `M50A‰ $*@ U*T0 & XIV(*80 j߿B,Аx1MU)bĊMƍ,/n'`mp!@@X‡J)q8/$X8I"M Ԃ hd#PLj(Z ȍ 8v֠C#Fب! ,   % pXC1d ';TP S(P*01PJ@@t`A h  B.4 `M50A‰ $*@ U*T0 & XIV(*80 j߿B,Аx1MU)bĊMƍ,/n'`mp!@@X‡J)q8/$X8I"M Ԃ hd#PLj(Z ȍ 8v֠C#Fب! ,   % pXC1d ';TP S(P*01PJ@@t`A h  B.4 `M50A‰ $*@ U*T0 & XIV(*80 j߿B,Аx1MU)bĊMƍ,/n'`mp!@@X‡J)q8/$X8I"M Ԃ hd#PLj(Z ȍ 8v֠C#Fب! , | H$L AS" 0@/@i$ BF& i Lp,D3h_i@I 98P(0yZFm 2@HP 8l@h -tvxpp"v8X &,p@C DC‚ Hp8%4Pʏ#<02=nl418*1F !,  k cȂN*\0 @ 2 8PX46I@0@UH@EQeȓ'D ԤP._\XdS?N4b@! ,  ~ vC 4d@hXQZi9 6# ȔHQ1e( 2uL8@Р6&@`=00t @ P@ %,XiaAĀ!, 9I1d 'bA@ 10:FDŽ*bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01bCȗߥ ct A|qtw@A`A! , HPZ+(a#P!P!Ă&| @@ ,a@F4iA:0 `@AB.4@ I2I @ 3HDհ  6$▨ЩT8r@d (&J  G1bAHP$W bjA4Z)01he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 !(, 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! ,  `   h`…( @*"!A eK8`IE|# . AZ [Dрp(>A! , 1IX(P9 x# ipt  i\ (j! , 1!H)[ <R)TpѤ-gh@! , 1IX(P9 x# ipt  i\ (j! , 1!H)[ <R)TpѤ-gh@! ,M H*\ȰÇ#JHbB)[Hhe%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 !(, 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! ,  `   h`…( @*"!A eK8`IE|# . AZ [Dрp(>A! , 1IX(P9 x# ipt  i\ (j! , 1!H)[ <R)TpѤ-gh@! , 1IX(P9 x# ipt  i\ (j! ,g H*\ȰÇ Q0F0'9681D /~) e$I)t$̄:3 pĝ :1իX! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h"'( | (@#F4n9A n4mt#`B$]ai 42 QZ6Ɔ5tp:0 ! (, 80DJ GFǐ/P!BD&|L@TYRGi"0da` 0@C\`AӦћrF&`@U&HвDq@6h"& %;rpx6{V|X*af@LØsB0h`O<W .0nܘs>he%XI"/KX-MF?JV,@O6ˈ^tpJ ]+^7~ (P@! , H0DJ G Fǐ/P!BD&|L@TYRG"0da` 0@C\`AӦћrAF&`@U&HвDDq@6h`` i)80Q@,F$`4I1HA=ȁlR nrU.60@mیr@Xws!BpLaJԩ $u@E)0r8bhȁv4H@!D^J+a 42QBZ @x1^сS! , L!`+(a#8@*D&&,@@ ,a"EHixp〈`p1SR@)~'  aS9 3Di: lRak&PqM/4r,y B"0">@:^8q#H( F { ) lpAd hV  1b )$G#<9@(D߽A^FlQt! ,   % pX#*1d ';6TP S PU01P,  1g !t02AP&Hв54`80Qurp8` =ȁ jpƐ u =`<`˗s F  @ȀD | -J#r b@O&jlF+?Jt=nx4 B! ,  H `@X@`C 81<@ @qGL #FvI&ɆSjX! ,  P   h`…,8 @8(&T00c"ر8K~VCZJ De@! ,  H `@X@`C 81<@ @qGL #FvI&ɆSjX! ,  P   h`…,8 @8(&T00c"ر8K~VCZJ De@!,  e 6 @X8@`  x )4cdž#JCJ @+[^hCUZ6RJT ,gV%G[Ai! ,  } `XH B. bEi2bAŇ,&phC Nieɇ-{|8Pi/&@`4)(@b ,H@4Xa@! ,  T \@J@) J[PE/& !Hp%iiHӣ+C )0ɖ*R6at'> )@SZ*@F+?J <@@ D{cCD!T tQZ|@{)o! ,   % pX#* @b*Dx(̈́)+’&e/ `\``@@@ : p ,I 4x#\-  rnݵg9pMa UC65uWcEp` -0Ã`)!I:w8XB0 @$p@C ҈aA‚ $X8IMD (pG l76<ȑ`76FAÀ! ,  U @@0B @"ChB0 4yrE <2g<@N%)C6! ,  Q \@J@) J[PE/& !Hp%;(pʐl hΕ#[F#р! ,  U @@0B @"ChB0 4yrE <2g<@N%)C6! ,  Q \@J@) J[PE/& !Hp%;(pʐl hΕ#[F#р! 2, c ` ! p(0E2&cnj H ` @C WQ2Y400Μ+.@  RLMJJ*Հ! ,   % pXC*0@*Dx(̈́)">L $R0 CDâb@0 H )i$%@BϦM `0yӭ Xငe # HW 4d8a X k  El< YZAƃFbxPp9 B5 b Z &‎$4Y@ 2D .I,H@F+?JpaFdz`#Gi :T1b 7< !d,   % pX#*1d ';6TP S PU01P,  1g !tThfB AX 5̨,0&   XٺVh[G`/TjpF HU =`< bƠ" ʌ-D$\x*r P"4"0#`!$z ,Q#qm($pGhÇ76g^ՐrCg@@k^6 B 8VƃÖi ->>SgFH#rk |@R h'2wUҔPCzIdp% $&,Ƙ@@B͇=nlx*1FM !d,   % pX#*1d ';6TP S PU01P,  1g !tThfB AX 5̨,0&   XٺVh[G`/TjpF HU =`< bƠ" ʌ-D$\x*r P"4"0#`!$z ,Q#qm($pGhÇ76j Ag~A "F,(D;iN$h( Y$(t y tg2'hDɵ(HT ?Y𢼄& *ŒCA UeD@G((t@1'#`% ! ,  / (0XHiJKCi @(Џ47 @ȁ! ,  85#@A `ihPZi*Rȱ;Nxѣɓ\)bIi! ,  =bAA2( @Cpbi ^h ď ?: !$SDqQD2 ! ,  :@101( @E)j(>ȱɍHq!/(! , H*\ȰÇBѠ@!HB"҄M((JRG/ @E2r@|.,Bgt9@aG~pcB.o̰H,2Pà7RPXe! , "M;DSYDX@PO&Kx(E(,Zr *?xhDU/U(( @`@B3%P/B} A j-tjS@ .LH"q҄1 ԓbG`犝D0jP 0xA2!00@㧝!LaׁĜ<  \JNaRUɰdR($EQqA݀u^X K !^H" -`F\[)J{ .x!!REHNI#gPA!xRGNt@G(T!x'#x#&H4Q@! ,  &B8" <)⅓*D8Ɇ &,O1 <8ЁA)l*\hС$F=) 0A $crP 4xRPB `\ت8r09!2AZR N=F ҌdĀ<R*Pb#T0  1N|@R)TpĂ hd@[f7BqcC8#lTЀ`@! ,  H 0S !%V(af F C$hǔAb\ib Y)&"4U, BF& Ԧ $ @@@jC@E6J$s.: $2Dfa ! B$@`@$AEFbxNH @ @0Ą(|haT&x!H X$,p"I+?J `ÌB!:T1b  ! ,  ( 0S a%d#I!F Ǐ2*D@hGGR\@4H DH q(UHBȅLHM '6x3@S0&8 rp8 !xVő @޾@@@C6LxG$P 8 AH!f D$\`-J#r@G JA MD NpG lÇ76t(FبС! ,  D0S Ci2Qb+p@(Ǐ2^8ٱB=Z`‚*KjXM2 0@j\*\h &΢$h@"Ǖ` 3pH R$+X 0`Ԫ8rKW+21dt#sJ< 0k4Z!a$͜vy"  .p`H‡K8Â/^XIMD NpG lÇ7JL#FبС! , D0S Ã2Q@J*rX#BBfHNvla Ȑc"PU0!ȟ@B:f̦"! XBHP 0 $  E $fD>ࠈ:,H<Z>4 )\h`A(0ƒ 3r| ʖIB06TAu! , D%V()P !J,`*D(M=21  LXPeI eS4vB0DɰiPB$P!BP`W$h@Φ vO 4x`6+kծݩ 0E6 UqRFv A t^w!B$Hh:"IFbx@vl'2 AL@`(ia4"t0< A N8|@R@uijpI hdl74}с60 tЀD! , 80DJ GFǐ/P!BD&|L@TYRDҠ 0D ,l\AB.4&èU) l UFA0@8 XaLqxR ,)l #E8f B26BIͥƠ"DFbx[P @ DJ>9&/!ƉHX$,XА=Õ%>J|aFdpGWP00TT! , HPZ+(a#P! ^8ٱBM &, E`` "@ͣ8$P!BL@H!Le X  `7 Xa-;M , gWőZ] f@5Be!l< Ai -Hr(bxHZmP%M0q\`P‡N,<^@:LH@^B*(MRf$,X`=Õ% _`,4̐dpCGdmЁ60 t@! ,  % pX##TcȂNvl@>`A@ ,a Y <8ЁA ,dZAB.4Ȅ@ Z6 Jf<!ذoTB ;/YtU9 @a˅m`JPW)G3g`4A"У< (_`@‡J$p@ Kq>`L .I4/Xx+?J ^If@ǍBBZ00TR!,   % pX#*1d ';6TP S PU01P,  1g !t02a@ 0A $ @WOg@@ÌtVL ,P`]wȁz`SRd h -t@CfcsȀD:;,`'P"4"t8'> 9S\h`A W~9>qC#ǎ;1b < ! ,  &L0 @ZQ` +3F!<,  )I@ZYH `C XpE`G ;openfetion-2.2.1/skin/face_images/big_51.gif0000644000175000017500000000116211561721144017270 0ustar aronaronGIF89aG'}z1߶N`0ګ5K@(N! NETSCAPE2.0!,#1(M1芇84(>`Ph|4 F1Ad meָ F4[$EЌ^(&B`ih iKi({xg w l|L`36\| 65K72(} 66ZZ  Z7-b|G Ư. F.;#%v؁"!!,P  bN[B;8 1,TL4,ȅaDI*}Ij }%d B# YnہxV"EC!, L $baPr@B8JݎC: (-A$!1XEV5}/Am߁xF Q!, O $p$ BTCn "tDTU@%ArhA(In.ָ`|0 ;openfetion-2.2.1/skin/face_images/big_52.gif0000644000175000017500000000134011561721144017267 0ustar aronaronGIF89aԐV .C8)`KB;=R"ƼC'%3JN(թ,ξG=9֫ӥ(~s&p3b8, (ŵ(ű'ʧ:@ܿ;:һ  2}}}@@@ԻجE333ئ&LA4PPP&x+O&յg1W*"v(v_"Р'A<ְ0H7%MI5$#ޯ,Loi\Hĵ"/ppm-Gyj CE.I+KxJ4ϟ)x&T\\\D>?-/)x'!,Y#d`7Ro,jn8>0Y9,= H679II  {U^~~)Vu)DOtb'c~v;33A~ EC~22 qATrXa *~W .g@@m-ML'F FV,.00bM& 0 :*4}z2mC?>@*6e@ 6=P0 c `Bȃ4DEJPQ ;openfetion-2.2.1/skin/face_images/big_6.gif0000644000175000017500000000215511561721144017213 0ustar aronaronGIF89a %%!#!)%<* M-=3%MG'OH$[N=YUEa[BwX&a[Tc]DgbFcb^md9wdBph?|jng\{knzo3|o/snVvscu0rTv2w?}{q}AgۼǺvٽ.¼οo 1 )Ŀ3ɀ ˇ ̷Ѫ  Dl Hو&)(,+ڙ02259k8;<=+=@"@80ݷqTa4'~TXyObEVT2f=jLa9[mCZSkAfedׅ]jMoDhKX^I{ =7C"X}`;L; #) }~O}hk+%Q;f>~E~wh!~;.`dž ?v*8б G}0ʇ>~\ha%4|؃KS! #H0PgFH`F1R >pB>bLl#!LW_XD WLXer:Ō=da٧>g2H#P ,w]N_O)_Ӗ0VtI߰2Xֵ:kګ+ԟ8IԽHտԛ4Ԟ7aթ֫Ο)N!,-SHOMB5m`Z$:0>DaLk*FMDYdLo "v {B!!L \p X15)!??!o $J-LL==6~~AK&No~~[ rVL)ÀF?~H;@10BD ~,I"ŏ #4X` !P8(@!B*nĜi )&&b8s!& %NVeσ;openfetion-2.2.1/skin/face_images/big_9.gif0000644000175000017500000000665411561721144017226 0ustar aronaronGIF89aӳKyY>нb0Zs2⯷yս7ƚMFҥ)Dç;EA-۬-\#5kVJQgզ+4]8jg?Nh`/U.BRWU>2<8DA9M7ܨ?*xٹkWFTPTGئ&ǩg'.Ϡ'U<(&'ȅ4ٔ.LO;>1zV+vm^ܿwߥ:hi޼?l\Yڙ1νF~:wb)ˡ:Eyk56lP%;St,萐ϊ:j8FIĐ@RŠ1tHa!'ztA9-[VPx%'< J8c LK @H!ЊڳAKS)ۥR!yA'Gg *I:8(!,I I=.2=31&332_,}K43zzDz}>%Ӈ[)0` s++JId%苿KJ<7(!,O @P@=O~^/#qS~(~ -E-(|E$9M^|CzCZz0'Az ~ zz7&M ~.(z; @/ۣ!0HP|(ϖiAh B8? yA".;lt) > AFˆ =xD#Iȴx2 d@&̊s`i A +$a#A7 hGXo@i#jM` ͨ &AL0b%}$J`vP !,I @  I v},y0=I@.2,,}@y.3.15L. 44341&I}4_2_uK2D}0N@:2zzz}0H,DD}>566DI]S|A :$<(!lQR1$â6pRBA!+BBC?$@P9z0)VO `B AxXȰM8KJFDR 89BD'?ph$Q(@!,O @P@=O~H{/#qS~ |{C(|# z~ o--C{ZEi{C|{FM^|<{A~OaB-9&rj/$'n@/BbBFAA#BaN}X/ǍA@"B>|^0…ˎA=, XafG56 }$ ;CG 6 Bb }?%tA"[RRǃ$C2Ɗ?+rPϜ?=9`E `<?xSp%LO2Ry)%~>A#T@Tq ~ud(tpxvP !,~O @P@=O^/#qS~.(. .-E-(|E$9M^|CzCZz0'Az ~ zz7&M ~.~ڤz; @/٣!0HP|(ZP|Y!Á|^`]JxG/0cB!QEH0) a@s"iHPŠ) r15 h0GXo0i#jM` ͨ `&AL0b%唡$J`vP !,~K=@ =K~=v},y0I@..442,,}A33,15.A~=31&~K}4_z2zue 24z3D,:0N@:43Х}:''0H,DD>56lP%;St,萐ϊ:j8FIĐ@RŠ1tHa!'ztA9-[VPx%'< J8c LK @H!ЊڳAKS)ۥR!yA'Gg *I:8(;openfetion-2.2.1/skin/fetion.svg0000644000175000017500000010122511561721144015316 0ustar aronaron image/svg+xml openfetion-2.2.1/skin/find.png0000644000175000017500000000164711561721144014746 0ustar aronaronPNG  IHDRabKGD pHYs B(xtIMElx4IDAT8˥[hTwgn646>|P4B5M5TZ4DThk&/}/Hh@[d޷=9%Z 3Ïo>W~7ߊ*qBfyxE |ͲQE&NgRg2{v[c ;֦[aHR,(ĥ\6J>iTw=6DrQcJK6 hDčآŃCro::毫<MqIʥ"3d"rIP\fU[,X6n0y}V34ݑApw־D$I v(x/7br]Hė4ʀ+m$yZ$QO&ژ LhbN80@D<ޙw2>s79(" q0ȭXt}rL&zee` DQJx+V5`rGArPpylxo#Eԉ} 6.@o{`rO^Z&`lZ[[[TCz ;fhOIENDB`openfetion-2.2.1/skin/groupsend.png0000644000175000017500000000154411561721144016030 0ustar aronaronPNG  IHDRabKGDC pHYs B(xtIME IDAT8u]h[u,9i햴̬PYub+ZԢ^):@M*R./2^P cz-ې5XQ)LC]|8^4]^x]<<pO+PJ"B+y4J5aIkK)})yﺮ];ԕ͌y8yBH)Zc&cBRd3AhVh1 ۶fFBqhM&ikoY!Խmی}lpVmm۶#Oft_`NHhwo #Ƨ`7Ұ{}Sak Qk~զ^@O,: D{E"ġ%ԤlbpaE1EM%It&JJ͊4Lqtwo5~s~s8T\L)%) 1ek^v}STޔ0bmeZqU7S{z?\!&,zIW׈%ooߓc,RFg}ZUYEӣm%Y{[n=v_0kEI珖D N Jhs;u&%srm'$=Wn/@ ,C-f PPn(.*rraB+YWUH43 sW߽%::6ilZN̾24PU}z YXXx(7VL6^|IENDB`openfetion-2.2.1/skin/history.png0000644000175000017500000000106111561721144015515 0ustar aronaronPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<IDAT8A?34F,\#("Vbg(XɝXX\\an2"w!'/3Ã=6o3V?Et0F,/-yx0!O"^SyZk&3úӲ,L0K;t~ 0 R"Ē`So/:"Z$c`(.Ns5Cq.KMB~8pA$mpg,+:bwVգIENDB`openfetion-2.2.1/skin/invisible.svg0000644000175000017500000023137111561721144016024 0ustar aronaron image/svg+xml openfetion-2.2.1/skin/login.png0000644000175000017500000000124411561721144015127 0ustar aronaronPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<6IDAT8KHTaFR^D hFh"[FBr6B+7(rEb>p-f)7",3x_3ԁ1|tSSRƣqwp5Xb55G"w CIef8@30c|7/ɳHo32Qѣ1e#uPʩ8X4m/VRÊH Z4%vK3ܪ[qč[1ېu%a{kjҎV8 il\Šz31dETwv<(J CA=yÎ4YgɎyz~ ͹'`?Fcp bK.VS8p%|ER&deD;|0O8ҀNcL %)0 )`9DP74i 4o|2C!lb_ٴ0)A;t=e8\2CsF Y49hVk <VN>cj?/08p?"44iF.%!4*y$~ I2 +\fb!(ZN 8kuEQPBބ R`!xq эb@CRɁr;P$.CBhuEEU=hPC/hY&A ^#@2dbS\W;NsG8"pkc5$%p:a<`(|q Rh@>Ahaq810԰qd tNM$Az@R{Ed"Hɼ "▐@ӎN:H)V"@Ol@!phр|CqC@ NBQTp| Dp i՟jM5lh )& L#=[Lp4>@ щS1)+mP8A<Ƕ4q+pnd BQyDl4HƊQhc {@ + mwD @o c X/Q D^0KdTp^Hő HPAߝ)<0W`ĜX UŠ +}l(8l8^+ L E&a'(QńP(4X,fB8' E'(}1sd ~P.6+2GeX(]!_t(dA7=pqMd'3!Bo֔~Md0ԙ0T ꮶZ&ĵH.j)s6P XPA fJ|f4TU!y>z酫 \q]OKD`ra׵]:_`/UWA(̲\^B%8cX4A]Wt`+ꖺܣ`a=2TeCW[yP3`ƕ xvXnc__HVP0MpMᓏ=0/]y*R-gӡd9o/^ `4EԠ5 Gs/l7sg#:џQQﹱ'y7wg`Z6m]f}%}ڷA29sFgswwbw G Aj@\PaɗQ7DZjo>tFP"0Qf2 zr&RP* e6MWj@po=A afpb -]v" |c|tpqpHP 0: ;@ @ 8 @rwbqFA #0X Ӑ E[Pň 8WqH Π8Șh` ۸`u8 8` 0r h0Xh ` Hh h 7  gЁ ` #0 ɋȍ* 0b bp(*% . 036y0 HY `Fp@3PY,9, hpb.`BPfyhjkI BptIBlzB9 [Yʠ v0 B$` yٙ P90 %ca-@ P@ JFi9 `Vg#9` Ey ` `` dT#I P @)Yyٟ9Ӏcq ؘ cI ` ڡ "*p0`#/ ~);0`Y>@B:DZFz c闯ЍҐ )Gb:dJA`P.`k! o(@J0Zz P ):oP|0{:D` ZzڪJA@P@Lo*Yj  ڬjU Īh ɕ -6*J@ڮꮱ*4 L嚫Āܘ &cp ٗ檢0  а;[Ku.)Y`P0 Z { 4[6{8:<۳8 A@ ݉+!H9,vH: $l^` J0 F[ =6p S[{<@ l;[{ pi K5=0jx)[{+2 @Z{ L  @ oйK ! 2p p| n нPu𦴛 P+p' G˲+ۜһۿ{PE\S u 3T`S 00$\$4^6.e=Gfn@FvAG` `9&uPx.7^N{@vhnfNg}>~ni` xzr @U.jP_G_>7 ͰGDdI ~Fwn⊠)0VP^2n Z i譮  ~^cb.㤾 ` GPgڞܾ do| PNP(V~|@S Nii`Si  ?3ES3vPbpRpN^:; 0  "O@S]0SG` 0/2G 0&EJ1@ p7tW 욠 $G a ?Y/ ^?_SyPYe? !h |uN? G$pO<_EMrYi>` R _ rO_XE_@MԴ9L XpeC%EhIND$Y2Ɂ8qZ"E%Ed`%0 ٳ罛+0S$IMdqx%1b\^ lڕ&Ei聘^lNq! S.'?:A U'N2cPWѤֱ8tjbf͚0CAPѳ4kC2"=8P2\2vC4 ;!(т )HzHT"ŀ1 (!qCAbs! F<ƒ$cXG0_ƓZB8Q.lx;B<(G R 91P1F@dĂ*yIhx G LiQ|\JjP8rQ\"e q`Ô"4y@҇@$FDHl]f42( P$'< ZҘ N@ | V _ <5@"%'J@Qs!2, H*\ȰÇ#JHŋ3jȱǏ CIɓ(S\ɲ׶rl^.RazpIXJU\TЕJ&EYz=Xk/oeנ9W%=x#SV :$]م5@R@K8 ph Ghv΁g MC(}QhsNd25֊ac\(P]B9v75g(3J3$OMd(:i+bLy3zy`< |lS8+xу/Ay|Bz. <ېSE(dl(ZRBȑ͊DgT.fVP)|Yj#BkQg\uYU(ahqV=I&W4$[ 4HU8|SU$C%TbCBgk~L.F n !O HW|eC% w=CnNRB*.<7?&l :$St3 )T(k?K27ܐM2ȳK>gt܄  l#7-J K!#DX-|B̀nRU| +Gی*7plʄ ؐ^ 4PLa7x1Dqd p8܀Bx-3@"2CL(t yCЂОςPч [2!20fD2Xc d|$Cްt,Pd҃/2dB>cQ!LӋ 8c-qQ TP)lVN|0!'b2ʑON=䮡&NƀC.CNwU2ɧ϶Ҵ~LD/TmqR 9Z0^pF9 ^8 4,'4Zu G,iﳝ+haU/($4%6T <FkT//  S99QūB>Cz_C!pB`c 0 W,YT.z1!`% 1g` P.ˆTB R \<  c|AQ g5\jXJlcTT/S 8q Bpc)c wX'NM9فRB40J;Q pa"5H7V\AXIQ/3#G#ZNĠAׄQ"8(M @tA4#M0sW@q 0 c7L N-K%4caK?AX#HFQϏI< 9Dsc7weH^ Pd& $E[PO"|`c&s"-[`/!%TA b(vс|3 -DP6%S5kN*QH- :%E(k:(n#rg Ac2Q\i/AbE1 'o /yǰ!y = DxBYjQ|8)+Hp kSKK +I$s|WuHE7q|kح?l3 a "H >Q_Σ[8r𣤔ni+pTLC&JQOkE 豃,Y^Bb185ɢ& 0%`ii< 43'I9שo}04a*nS1Y6C l`\@ R1$ȉ8`G$W=xp b8V4v.2 #o\• ;/ +TGA\@BSxh`t^OKTT=_zkS‰?d`gP3y P!t\ba#hP "uD ~82wn5B0R0 A+l]=*zĤ ;Zk%J] 8AXltjz.m RŠ1^t# pW + uF nH$h>Aē`S\'JbMS1}^ ĩwqXC h,m:wp"*Q`O΃z$ocܜwct(u s/T !h-HCᤁ%/гyNľEbp4b~& 1 |%50az5D챗w$祆٩{n  Jvz~z6x@PMBL~'iP~Ѥ`+AB6!@uHqlwÐ}t{{|9 CP ʰL"` s$t/Lh `ސJ@ x5g6}qg7 %p,h$w~0EzPK8:tx h@g@gj8{a@fxaWjdG P)0 iv88 (` Ȁ -0ӀAq`3a(8\XxЌ8h p^paxPo`  X[#،ƨh0@x0 0؏HHà ; x )؏(h -> 8%p.'29'`6y86)g^tU:9Dy4y.VATpx &H AȀ`#" xb9dYdYIdjlG3TK l EҐ YSPiiG6Vư ZҐ h0@45}Z9YyKs Ǡ^p` 1X)0϶z10yK0Yyșʹ̉, T0(tP =c T y虞깞ٞIC0 # w}s I TZ, nMY0 Ӑ cZ@ r0 TpyF -@ ' n02:4Z6z83 0M_@ z"j @ZЀgg/XZS 'f! 'B7 ' ( vzxz|ڧ~vK@K j0q G + r8 A0 0TP{ک~0 ÀGW6T PQ0גpH?%poId:zn0Q)aO4)G zn@ <ث Z:^My! p 骧 KBEگ' @ =|';|jIgPA K?Ki @ ; 5Kp jH:<' "g|Zj0 h0$)p ! 5d PtJ԰ ڵ^`b;b{`7 d0:ssO%` s0VqUP핣J;`d_c԰mp 0 pZ A x9e [`LgP{k' p !P \ м\0 `M:2 Юx0:D껾۾g𻭀:_   0T31g@$+@ =  =Sп<(L9 - 61 0 ,@ӜK$%pKD\F|HJ4:yP;lXY|y0 hp' V%?Iנ YkD+Pv|xzvL 9U|Y|ZV_ fN  p 55PT; *||ʨ m0 0˲<˴, @ @ Ȑ ^xn\n:PMt؜ڼ\r@ 0\|ΰ# fpuU P\MP`|Ϳp| \ѳP1/P0  dVK  02=4]6}3myG`P@,@-`@  ,T]VM' '2}8`wptE@Clnp\ "!b7A_ K0xՀ^`q wpCp؊،،Cx@`pٜ٘ٚ$p 1Eő8 xW=LaP`pkCp۸ۺ۸LTji}ܝι}28`t`8m҂4fZ%k0k=G@] 0 @S qhp5`;cp jPZeZRa ek]P~` W%E&ې "ߜy z% ^6^Za@`@BD>F^@Q ݣi.2݀6p +"4T=Gpr7~ Re@>t^N  100u"pe.]Gxf0f>R0^N&N۫\uꢎ`¸66Ed"MV`=g1>1.C P=~sJ .o)=,."aLw.f CCq@Epip`s 9 "Wܾ L[ #qw 0 $_%ON@  9 אe}2?" Kp<93/"p h^>>p&RY q8ɀ M`^폞Fa0#q09_qp =xa؇55?\`Sq - `gvCah\*3L a4}[ ipYpWWY0 ҐeenjOccxf@ {&0_e?E#!`OdB TSAbWLfB<2G!?TfI)U^9?1eGR24B1>'XXxQI{q! QhRDEnݚ劊+a(PPl.8 i"qc",I)𲢉cWFwP!!:x2e˙101YAY<Nɕ˪dh 6C!N-=j&ܻ2=x"FJڳgQS6Qzg55Mo`e#1kPp{Ϸ#BO(p@ 4P@;<%h=2Ԑ=D@K$X@CA9ƆsqG{d0E4 FVdF7ipJ, L+K0sL23A%,"Mm8$P8'Xf!F3AQHmtRJ+I,ƂS>@*`3KgeVZg!VruWozWevXe= PvYfuYh sIB hR8d[n[puB\peŁv]xazWB7~!ph 6Z820ZxbqZ4FxCcPBK6dA8 ` J]2jj0h]Q@aAAfKNYY K90lV;mvB0YBUQmQH}vb]stcAi(nxs7V2 >s髧z|PAnܓ{`Ͼ砌?eD(}Rɏ~Dx >@FA-hAzB|0 (X 4 #0Q"Ѐ ! 2, H&qG!c>G"w CIef8@30c|7/ɳHo32Qѣ1e#uPʩ8X4m/VRÊH Z4%vK3ܪ[qč[1ېu%a{kjҎV8 il\Šz31dETwv<(J CA=yÎ4YgɎyz~ ͹'`?Fcp bK.VS8p%|ER&deD;|0O8ҀNcL %)0 )`9DP74i 4o|2C!lb_ٴ0)A;t=e8\2CsF Y49hVk <VN>cj?/08p?"44iF.%!4*y$~ I2 +\fb!(ZN 8kuEQPBބ R`!xֽ3Ѓ/X KmLFp S ˀJH&ܸ\r  d7h$d,gZ0` aqJ;T 18[EFBBw@ r!8AaNJmc0oѓJ ׎TQ!`((C@,"\-EIǫ:E![cчЀ6"0@$L 4x<" RP#AA1 @?0 "0"A]`l<2!^%T7a UHAF 9PB.@1|<`ʠ@G 2r:!Le1Bv PCI&A 4)@2d”@sG8"pkc5$%"$i' _T$oZݶƺ :9jԠu#&;hVXfp©5D(&AB V $d nLA ?ʹuvB"}bz =!Jځl4GF@?@$A7ckC8;2s:Sh.,{P'G*|@?ˆ)L 4q uDg{:V P`,6EEA^:Xܐ+1~W*/<`b/ P:` l=r+aBa].,֢VڥV/آT+BG+E""8gEZ`ՖKb"t48D! cc\M6rLC(,pӴcͶY 2"XDq !z7~}Q6s>R\2b1:RtI}73|xEoc ;>HVP1MG$x{5G9xao}S -\!-p~ZgWj@ Fj0@}hWky VCvvϗ F)Ue h|§wV`ggx #D}qr0 89.Fgu46wH]Qxp+vQ9.K8nOw4hsQpdgˆggvkg. %U6+ }7~P* fNVj@pPr=A aghd -^" tU|w8s'`sHP : ;@ @ 8P @ҊaF"p0긎 0  p\ ȏh {X7 Ȏ# i 8   L0 "` 1i 49p`s&O8#0 G95I)0- 6r@  #  `b9dph lɖp9 0o pmɖh^YY0 Uyb).`BЙ9I BɚB9B9 Yʠ v0 B$`ʙ 9Yyi Pȹ0 @%caę Ā.PfE*t(9`ڐ h zEp9<P P`.P1:Zt ` ``  dT #I P @ɩ2:4Z6z8:;/ڡ9cp 9 RAPVzXZ\ڥ^_jA  iv0H ȀФ);0`0ښz|ڧ~: i@Ґ )@ک A`P.`Pm! (@0J:YP f꠫`D` :Zz蚮 A@P@L XYj  뚰 +U @ {h I P ztp $а()ۮRPIJ (0`2wpg0 HJL۴NPO \PI)-rV(@[9ppr;t[v{x; L)@ Đ.p\dX 1ahP a< 8:<>  Р1٤ ^u  ;@0@=d=<uC]$q 072 uz|. b]ֆ]֏0iG  dZ((j}l P 8]ڪڬڮڰڪ] f ۺۼ`E!016e /1p }e cAi@ԓU([qEP0@B>D^F~C^B^hM`N` >`97uPx>nH>dn{@jplnpQntq [.jPG e^G i ",a7~ t `>֠0!`{|9`^EC>^p`đ>^qi @"@ uNZ^s >^W` d_""i`Ti (j ?CETCvspRpN&@N@Z0 qm0 ˊ D] Au|֠|p `rY0dPY XL@03` pr W rQ00t_v_Q@Eiz2]EqZ;N e,̚5a܃"c0x:8F_IϞAl1Ж%Y ,%WwpQ̆$^mvS|//ZwS;C`W+$Qo/g BoM\!kd(^]w]71~ _g{Pp +CD* ±02: 8Xcv.Xa`̃fE0h(@, M% 20!kH@$nY/-ıK0sQ(=@#R,D3H!Kk2)M`K 5.u K 8T#|XQ>P5F`-RjTQ[eUW[-F3r=U- $ 8TMc,ӱ Tj3cG|v[nv[QB[q"RG55J8c6'N "VFhuC[u .tA`a}C8X8XC*k[EKVd@Ԕ nӤbcޱeZx`Md>L)H(0KI"PP⇕{ou Fvmن":'&I}[D* ,\%)@D|AdÃ4 (JNs@4$2|?Wk("7B@$7xWxMo~k~zꫧ^e8{9`%xAe]Ft@#$!  #E ]i@)hh ҃(СyC1@ " xm$bІ\ 9qPw E0# c p`#eF8m4Zh/Zh@!.'XȝTFAJ<@Kȣ(> Lbr$5(A e.tT28D+]iDXiхww[`")ILayE HhF$-I iA DMpAA9+V/G[ PflZ JsIZ1PCf \`I &5Μ<ǃ+=(;&Hu _6cpe˖oQbmA `I*iRтޡItk˹&eT$+2!3 %5Lt"EJ LG-FYTS I8>J͑& \.-*33m&g\. ʊx8:Lz25`0T 8BgQC 6< ' ;8S9@:/r \N eBʼ@D:hpU)%TLUм@ڏ)YI']-JGU8C+xF'=` '`I2Zt[x} f^U NR8';3]j'2؉t @MkDJeN6PBrQ'tYI:"8HjCdZ^P?&l%LcUR5@!5(km䀃$#W"WSE8Tk̐!C2 ad `șqȥUr WI5B#MdbC,H(D((8#X^.tL Ss@qLb}U=/c`7{^?̢?Dh4rVx-k8>tyH%/pOa-c{ =*4^B Yp0 x9῔xtQ )Ezk@%! '>ԚA%3:1Ca "-l` hB%FH56ta>A0ve" <;bǰPCTr h9*pA%$!kG 2d4c!A*5ax 3p"18X zpШo(+<>a43.gH5pt߹DЊHW'@I#@7a/Y@M:Z stVDU>7*m}/0e'@!| Y"XN <DFMJqN̓x ?2(8P7BBFl! @ؑNy7DpiL g:i@"ɬh:F'6 AzL*aH ~Qd赯_55R0Bp۔Sc*$݈9̖L@טQ|L< |1~bTHh檡HE(/)Y DM[~6͉;f qqzZńyC Y2[6J"`$tp?qfd'] }bpL` x?`Q#4¹Kn <B*?gt=> Ph=ͬ;Fcp*Luq:p?N<<]ߔx!8Qc1_XP|?@ֳ8 7*ʉdTMP(0 nХ^`b:dZf=08@)d?=xBiM@Uk ( Zzڨn@a (0 0_TM9m) h0 a^P1p V0 *d+hpA )PGj/+@ g`D:Zz )I[@  0PK@$zVG Q[j^ a @ljh0 5Zcp|۱ +p^G S-px0 '@ CB"B;[j @ [` gAh0YW@@'0d[f{hj+8`L{5h`'paʩ = +۸gPA T0T 𹫰 =0}@ 64ʐ";)Fprp${dy@ m@EțEP00 \ #1@`b4ӣ;pD[{蛾껾+ ' r ` _S -ۀ Ə-5up/ľ A, | 0 *, 0 UT{"|Pa :I= jLNPR 4i%@ 0'+<.` +4 " Af; @bHT 8t<ǂ H~ǀȂ<ȄȁW@"-Ŏ.<ƒ`: U # P+@|$u\ǂk@ fTȲ<˅,%  0 0 p) z Cd؜ؼw :p c˴<γlˣ090]< 9, q 1P wڜ͂P+0p ǜP\_@8" 5jh#@|~FM7w C]6+ 0 P@- @ a ` @ :Ԁ6 C`=pXaZn5b=d]f}c vy A׿  0΂"|#`Ð I2 /Z]ث,Y cpْؐ=ُPG \`מ=ڠ=ڢ]um1 QAP[Q dr@mJC0ۓC! ϝS* Sw9}7֜ ]=3 E 0 U^x\0k>\9i@iM/ F` .^} Y5K8:<NHJLM^ԭm(@ "/{Ej,Q4==m`ps^t~vx~i0 A zΡ'sId_!_t߁*VQGp lT^ͰF>ꤞA 5W` ]jp p dp?} '*(&+Ѓ$ ȞʾQO/ 90N~K^ 9Q`~]>^On I~ ʙ"`11dTwy^Qn >ؾ0\*,.0!n}:]kp@E;"DŽI9M0!&VXNנ-PbTpȾ/o#9t_r1=d i?*`Xq 9 +Yi8Kɕn\~oNE0U.J 3`ixPnwp>n@քkpc eďYp՟ ee߯_YPoPh)]l+ЌSq aL ,V,dpů= HH4G!=*qI(c3(%CS"Łf9qF8=f-I*]Elqb2 'lk+)Ŋ] ,Ki,%$Aq(Jco۷(3, Lx -x*,#;Be̗DgYU@ -)񲥉 [3 yA&l X|jFȍ,Ih֕bމMNc|M*x⑉'Oğ/߷&V(8b+^pB + 00/i/>CqDK)Lc ͠"0FsqG{1L0*D",_fdZx|J,q /sL1$'Ii`B2|2K<Ա6,O@tPB  d%If9=cy<ɦ|ǃ= A|97?}0" }`7?O dxDA!&h ^_Q5P L@P RP+Ă ",#aJ -y8A, EH kxD`T(FQ(&=;openfetion-2.2.1/skin/move.png0000644000175000017500000000124411561721144014765 0ustar aronaronPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<6IDAT8KHTaFR^D hFh"[FBr6B+7(rEb>p-f)7",3x_3ԁ1|tSSRƣqwp5Xb55^H Ο/q@k]mg).hkmwfLϯ*u2)d$nOpˏ_QWWϡr>-..^(}q)Dp&rF_d ~,AI[m^^LOw&ycB.99EY('ysLm ^ zlAd$@Ζ.(jDBdI- k*X ;0$& f 3PVo̺I֔#j"sE,t4w,,bI{/l@åNyfJ. FiQ2 EUuuSENr!t)-"G'(mH-mǯy1uS&.~ER%2)"+H+2g|SqM}'^a$~env4 d#lXGƧPwc/}.G]z`ꢐ!"h`ٻ;)5+zc-*ÅNt?WZs`*ewIENDB`openfetion-2.2.1/skin/offline.svg0000644000175000017500000012615611561721144015466 0ustar aronaron image/svg+xml openfetion-2.2.1/skin/online.svg0000644000175000017500000010123611561721144015320 0ustar aronaron image/svg+xml openfetion-2.2.1/skin/openfetion.png0000644000175000017500000000471711561721144016175 0ustar aronaronPNG  IHDR#*sRGBbKGD pHYs  tIME  *DtEXtCommentCreated with GIMPW *IDATxyE_y1 F@% IʀAp)+R슠Ą0))aQ  D,l*@ ;(r!Lߗ~w$|USu^OOOOṣD%JOLm+>*̖W9$V˕p=MԖ\8C4]$WwH>$~.(cqQE[`hɼ g| lxVfiG+C2Oeo3&,LWZa'] X}pPws/ȣ}30K;{8)$p3&W}Lt[қ=ev0_簥,8©]qIw$d[e^.AڪeVy~v\IR888U< 0EVg"{C&paF~8\EK0\]#܇*"~/ŷcU<#?-58?õ ~ԐQ HNH#niNVCFH y_MakP˯߄|}JY&[0Jڹ 5!=|7%cɳ=(vڽԼ8gnl3M>J"O`ף>"^o[bd0FaZ8 y.}fXp=ZSjjY=LǢg10TMx d@lj.#ް=? Sgt̏o ]%؍熭?00p;<)5=]x_F ä-|eo\1*bnK = q,2W%m JTqnMy'oĹ*iz}=,gTo/pxiԐkCN?Lھgun,TOl51%J}-8҂vg &E%֢sx kPVqDw |7LDrOnވz+!Ydzׄ`ltw e| Ay { cĿUtEl{yjr*fg`g@$U]2˚ss$##!كC:jSgM]߾$kEt ת2t-HS:t=4ԼQ!5aXvb{pHIR'4ig$ySnZ c^m[w%P`FUaA4#S5 NxʭW#9 طzZbuJ4#=56tOO$Z1èiGxE(JEJxM%=ӤGjm9Zx>!5Jf^ߒ/2-^R?7@k ZlMY>PL\aydDQ?:h4o/J.lr'UL5!(➑h`$54\uW$VZ15?#y.qum)wXZ{Q"]Z7RM\;Πő4!}_98bͳY%Q% iD%~[0`M/3>0#1AuhMٌD%JѩRWD{.kO v <X(s0^'<<5Q ~9GHl%__K Ԡx<_brϿ↨% Hkè0j^~V xL$i#Ԅ0GuX0toF|j#3!8g'E&/=y%'[gD, 'L@,ĻگxynTGsy8,T%~Nn[ɓI#TNd SB"5#R,Ө:L`EyB׋RI \ȱǶ\L}bՅ|Ӄ|I4@9;Y8sbeoj6yd'l/o%#AΒ5p2o΃C<0NnnbbR^vRqG*4 4◨]B\C 8,eAQDJC_MYdq@6gޙ!Pyfݿ`fH2+ҿՑ߃5W }3(RN%K(_DI%Z@VX9rJJ(QDVNĤ]IENDB`openfetion-2.2.1/skin/options.png0000644000175000017500000000111411561721144015506 0ustar aronaronPNG  IHDRabKGD pHYs  tIME q_ZtEXtCommentCreated with The GIMPd%nIDAT8œJQXNm%0Ţ@2:O(y!:\&8&-3(-vtbM7.zVs9?߅[FbT0n>M2M}s>>eް@hSmwcS=$Xf\tA6MlӒՑDxal |?["!6Z$^/GNMTQdtX:Ql(lœ4m0Cu(=Fh;٩t.7׭Ffu^kaz k':>>|k K}kX RMC&3q zu8aP))CQ TJcx1jU8_vӇ3ѭ|w\)a27^I3*|sAR?} O=sP2a]^xG Z7M3;?N?l}קPwⷵ:22/2yK!!2X):w؟JOEI0@[5g*2 PKhۇBD . <:j%x%{d~[m7E,qWw_=뙫m{͞{DYFϤZ`IENDB`openfetion-2.2.1/skin/phone.png0000644000175000017500000000121211561721144015123 0ustar aronaronPNG  IHDRabKGD pHYs B(xtIME  ?IDAT8˅ϋRQ?/7o3 0**$~ChݢM 4E(D~@ЁQg@͓g}~=G M?3XB0 lZV*e'͆vlZ.3ٴkD Vi۶)Vwm˲q}(lz XZ\bfE Pۍ]EJ5.bh9D 0ԯQ!@pl9Deg @vz iCw\4q@BAn޺9oGwRW֝8(˲X]9GL6"6p ,.,p)VWb6^G!YERF FDд,^O*1)?DPEJ.v:!NEh4Ɗ8.M:G|>/ggQUˏ^$HIjU|Dh^*<<@z` gH"K*0W,p)K~5ő#|IENDB`openfetion-2.2.1/skin/portrait.png0000644000175000017500000002673211561721144015674 0ustar aronaronPNG  IHDRxx9d6sRGBbKGD pHYs B(xtIME  }O IDATxy|]es]'4mI7@W@V,0*: *f (3 8,ⰶ@oiڤٚ&w8ޞ$7ihys=9}'@i@S'k&:> D~:;GS@8?';oVʸ m@'>w c/Ko[::AZYn~\ Sp_>lvd TթJ5L[) ,~W0a*++ )%@7fr ΀_`Y^0{lONee%ZZZ ~3^x\?_ṯυNnrѩ'T"޽P(㡢~?eee\/P(D{{;T*)USp)#oO"ٳgs5pL& 466_-[ٶ< \LzSH%LΫK/Dyy9>4R`hjjavEwNjeOvmnvgժUYBPPPԩS 罋)/s]hnjjb͚5twwSQQA<Cwww m] ty晜s9eѢEL>B([[{{̛7 p0w\LBEEE---ܹz-[ebؠ̞=2bmmm\N뀧NA}. l2~z U%{NUUU _ڽ{eT*D"Um޼YqJӴAu]UTTܟM#uhmmz衇t^}7MjIIԧ>D^MR*p8 CuuuÇ}sx9':vxmXʽ馛T{{:Rg_ڼys4ML&U4UGuuuvҢ<:^|Er|AVIQ%?|ޗ<@ò,eJ$VU:tH8p@ݻWܹSm۶MyJ|3'=LA^zBߵ^ٳgOfϞ/?mijYֈcΜ9ۄBawX0ԗ7of…nv,~<^{ʼې4M 0ǩT*p[n p "~)->ݻwp#pyG'^,^[RYY9*BB)eYuiRAUU{/SN&_7osq)%= 4(~".BVZȱ4`@ӟץMӤ{w9sFT~8.xX47|3OƷsN*++8qe an6ͺȑ#|_gXw`Iɺ}K.G=n 7VrN`^u\ly<zx0dMM =壒yͪs}VnƐ`: l0())իWOr sKߞ7L}} w `_}F۶mg%O0^x+V/~qDJINNR[[ pMW؁ʢkna\:}PWWZvA[[\r ̚5?h4J" LꫯV^M2+ /I&e(0 ZZZؾ^0\I}C҉'˗תH$?O$!j*8x<{rfx "lڴd2I<ԨݶhŠ 1)6Ǫdf͚xJB< ׯVL$Lfɓ6.}6H/zHR$ RTd2Ɍ32lpe鮚w 0䪫 : H={ښ4BVX1c(eè  ?"`s===DQmF0T*E,cŊ  2jܞ!JʼnxC rJ D"8Dh4RJHѿ 3t-fW1;?ꫯfܹAh9DH$Bmm-_җD u;ht\=K7@0n&OCr+Pb?2 ,?be}"{1*"HY===\pL2)听8;5< xn c2az.r^z%ӧOgΜ9nO+:f3y -w,<?[Yf HS]]iͥPe%Rtvv83\wup+#iG+$f&~b>Ke %Y:Vo3rɏ<,X,Fuu5W^yeFZE**ё+MuGD@s,RAf /J8+~^ތQF| G"McMMMý~D<`Ƚ[3 +vfm ;YaTg@dGMPġ4+& &!-xT(07` @ 6Vax7E[QfK4ŎGRt  HML 'zwj( o!*-mtV K%AXilS c܀ֳ 2\\R.%x|H=Ιyu\0WvgR8@Bhobd?6(JC,GVAƁpvLikk ( RT;(Տrx0`:.1Ҳ[heQ2ߟ=VmpŌ}!60dZZ MrQ>v!z! pzPVnj$e,[FlݺuP;.8 BǏ)6R/aOfU5f\CJAm@aiJd+gD"1N$A@ wcS};#oqLM+Zb ,RD} CCYAssH}3%|x0Wz\w= PRqFEӱ-2: DX "ZvN x8PrX1Tvr߱3^ 7cJcpVQ_[sJ&֖S 0$"%cHICDZIX!.#Mvhz pBڵkG2J?e'.\Ȗ-[XdIRDR )ںue-VR>(_~PkalQP(*LJU *!vUqiNhP1 iH3}ԉ}s.;ނ30ʈc݋KC Z D/I<I)_9s' =iF6oZtxf͚Yh)}JӄZ>,V)U`f)e1iҤ!).t Ak;e2!L Dl kD9@ . )h-Y,zD3^H[226;9׹KI)5M(5,B(T7nŋٴi dɒw#g໏3*StW} ̕RUP46*&I-|$nO [j7Hi6AYZV'/N;7mE/YdRѶ H7M{[m)7{c; RJIRaF4LI2 ׂ~?ީ!x5lORGȊa@JSesڟ=R C ПMB7} P(j+))Ɍ^]HL&N,{>kéT!7qX/Xo}M(LI)\)PNF|yU~WѴV8<Ȝmn%K2zW߮c6~k)*aY*ݰ#: J WXLP *Be\<JK+'ԽoXomB:RoDOO%̩@Seܙ C~G~uR)oy-.lx7Q '{;NC1R/pw>½?|[k1kfT$r "^)펧YӴ+Xe)4!ud_ !mP(F2iفu_H$?G> eY#R A<7xt>pgc&]WW7`CQ)F*eڅ@j[#)OO5{Z9UTREgy=)|`m H& BѲ4,h N2e ʦmO~bLSsLa% `SRxNH,7|Ʀ]\5'2xX)޿H&Mrr_!Wyo~[>+.i@YQe]r#]¾|`b>ɋHAk"asn 'CU566f-K)>TVC |3 qpBkK+tv.d>7~2W$T*E(MǬM!D( `)eR)jbX"31"Q+x7_mD)9E5Utt/G5λ`6_G&R&}Ѵ7W)̵d$ FA{[/N ~uol>-ͫWx".28 ~?^7mDرc֭c׮]h] M<sN֭[Gmm-RJ9B("H84mGs2mF);G M;Ҷ= &%& ~-B U<+͖ͣornئןOӞn &8nM{՝[a .c=ws,L_(mtL9+_7V= t8j+ ꈠ{t~MB/ŵ$f!uBex3QOQf4*H&- t]@)Fy~{"k}BǦ>tEBcIY4TN˱ \#pD΁j/u,?Miyɨ& 2yD/m(TTxm:}3]VS\Y[Ϩ#ec] \&u`ˋg(o=G.g̟?Y?` >-K!=MI:Q#E Q4lYYkz|h-4Mq(@(Wcw1~=PS["؈q-5ćK)5MVt]:핆/~.Sw6 qCbD:">ۋ2XR:ر>N[E{61hEJAg[ׯE~pƍ֧;x8&ZL;񌁞IM]t .g LU20lg¼s1S#̬=H!8 5K$\)M ꩅ4,ʴgi%WNb-{BXbuw6M+3UY$f8R*3wX !L9-]޸#1taɅ:WPQLYvg.fۚD楷Ta*k:E>q;"dLym Qˇbb}!sέ KW˾AZb]4] +k;",!eɑYB$<*e{E&@RUWPZ4rA/w3oYC )v`'R$> o۶@If,-cNpA)"mlfBQbD&aYq)-J36WY'[Oͱ;C]CHFhdm ,RG^] p%5:g^1M1 Kuv'h\~QQQӭH_\@ e;Ou9hݙ@%B &QTͨ?ZB%ӖѼ9F"bei.[˥NҙtY(>i)=(iyKN%GYu`&v((B)7%J//UL9 ٢Ey{wй7Ejy6 Il;qwɧ dTѱ@ ZɄGJ;E>-&vkx.ᴵ4ӂk5  'ht01P1MC#?K(8r˖--iM,@k`G8B]97 4L!)i4IeS %̼sS +bΝa1akJOW0?g_T{v}rRIA`튬 rۇ|gS ET`<+o=-OHz xJ9L._RWlXxqvNH/@ MW(Spf ,4VKU=^E P>݂޽٦cnG*iq-=FKp\owȉ* KA_Dhvʾx!ڣET!~tTŢǏ|F``؞X_̴Sedb6ZpAG[j"}v`fY# !D#qRioa'&?) S9 G%FWNayl=J=ɔI$u;:ƏE2ᘓQ<]&I:joXP2ӿ--t4RCR08oV0@8R)E)B$zqQcDB1aOCzrEO󹝮sͲ/i V*Bs@iր{Ry ޝ~H/w>]2gN ι^ӥ+2g.5&3\nI)2mpI<} BO䔐te:No4 |{fAzo7DٷbS6MIӴW)Sq k {BwٟsgdiC+\p!̵dzB,̾n5SӴ7Ӗ,YR|O)!DadDx>Sg_=oBBHjZ2#|^|۝=p0t#M6׸dL/^\*`ݚRHZ%%EB)%TWs3)eRJs:EEBd +|Yܪ0T)UN]R{:ۧڬ+ ޽,KreqB!}O4Hʹǹg7n 'ܖuIENDB`openfetion-2.2.1/skin/profile.png0000644000175000017500000000116411561721144015460 0ustar aronaronPNG  IHDRabKGD pHYs B(xtIME  ©KIDAT8˥OHTQSތfcfNJDhڴLTUڷ hem]B֢Dڴ) 2a ɱ f^9-}s;kLG㽦IěQ-8TN=VlԄolmLMdV:k\'qR1M!79dVF;YL) 4cR3#V2;>3ޝmjGUu(1soÜ;JnrGIR8bv7EpoNa-}_:R?a!|FDf$IOCؤ=dii U@D ^%'ui+>;/fn1FTm;(x&&(rC~9EmmmPwW{ﳱ- jQ,FUD"j1A`6uDXV`a"U* "> 3"TIENDB`openfetion-2.2.1/skin/proxy.png0000644000175000017500000000211111561721144015172 0ustar aronaronPNG  IHDRasBIT|d pHYs B(xtEXtSoftwarewww.inkscape.org<tEXtTitleInternet&stEXtAuthorJakub Steiner/!tEXtSourcehttp://jimmac.musichall.czif^_IDAT8UKh\eF;wbyq/ ._vKGʊn\-:ZduE; kA61k~iSGuXo_<9t|>~&V4^򐶆2j=ݝ.Lgw۶(Xo VV֐DNE 4LJK,!o؋hoՄziM:+JJk &p9t#/WPJq:XZFy pVOeL#$PpS8IgszWZPJGsE -[nF^=N$s`rh8~3knNsk=N9i`MI/5Vda?Abv&+#ou[[`4f?eg V~oTMLX8]B!)~!D)K!-c̝c9tpIENDB`openfetion-2.2.1/skin/reconnecting.gif0000644000175000017500000002004411561721144016455 0ustar aronaronGIF89a00trt<:<ČTVTԜdfd,.,|z|\^\ܤlnl464TRT̔ܤljl424|~|dbd! NETSCAPE2.0! ,00pH4ǨThVb :b)۩p]E4^nxL_ ijyE!!ckL`_mW|UMCr_z]wE^mp U H]qqsCm`~x\ KڏtҐȣOY!qeF~ᤃ!4)JN@\C%İWB7l]4n؍Z c%|<0e*3V8' 2qXAfg Tɦ#ӧex!nQP6`@A8.㣦 dbQ8K$r=_d8kn 6c1m <@.]&u)Pi,aX ^XLfM\:ib$1Z&VSNoF߈^H}^ e I2. ފs 6"2Np:@3 LMjxf+k"PA0LR%%Fehzf@@VD `ˮ \R|ty-d}"h@xW! ,00trt464Č\^\,*,ԄDFD |z|dfd424LNLtvtDBD̔dbd,.,܌LJL  pH<ǨThVQPb~MZb) .p]E4^~xL_ijyE &&ckL`_mW|U MCr_z]wE^mpUH]qqsCm` ~% x\ KڏtҐȣOY&qeF~ᤃ&4)ʃN>\CİWL7l]4n؍Z c%|‘<0e*3V8' 2qX%f烠 Tɦ#ӧe!6w6@РpӅe p ۷"AiT;x^_ hCUXdmz"%bz sho L^U>pq]c{#by|9eW;tSP}/ke8)Fb # NoqpeA:EgC=uV5f쀱)T0 ܸ#ѧ&.\7θgkڻ `͹q B|f͹;x $^9D?/!!=f@ng)8&lF`΢^RE.I8҄R2͗Qz=TeHQ1u!ZjUAԢ"t#[^H loThJKH7xc)q(0 BA6`md؆r|`FJeG' t(`d9f=8Ji IUޘdv -DN@Y:<}PDc(@驀V*'T"jL- L$P@X Uy ƖBŤ$ hb dr$,>:Kf1H׊V HJ@akm@eTioY%`e{k"!sê `s5%(` (0.ØM! ,00trt464Č\^\,*,ԄDFD |z|dfd424LNLtvtDBD̔dbd,.,܌LJL  pH̤q`6Ǩth4VBkaxJΚH|߀EM/׋11ihxE && X~oD&!&y{y Z _ j&" &zG  F"xUɌ&ŭgVnsŲ㠅{ŏ Bd5XyBڳ)<\I*P PZQTug f<Y3RzGqwj! R"1CӇȢI X, A'l0e\qW8fi!WaTXQOb9#z[@=E\K E,KT5n@7V{2S2H&Tlb'^A BZ+EAc8C7cՇ_Q "`3Z! ,00pHr1Ǩth4NBkq9"giz5nޯCذg|]_sq kj{D!#!w_[ dXXh$$V`sF!$$yDFrn̴v{qWտۃ ciV۔Nu3R:,.a!3!=Z=t?6 HA ^ =`G.06 @Q^s h1h OjzH H=`4*>!lBPQ>4}C慫L>ېC  %*;Â\W6,M@fukF )wF ~Ԡ6GC9[ / Aٷa9bBPrh'JUq!`*,5iĎ֯XQG(Rzܟyu0!V mqj"mAJb-~ Ԉ pz2ǔQL*kdf▚W`;gc lFq#C! ,00trt464Č\^\,*,ԄDFD |z|dfd424LNLtvtDBD̔dbd,.,܌LJL  pHӁLǨth4VBk2x!JΚhR| ⡮E~y_q#ZhQW! zod  XXf & &Vz  TQB& !!! P{lPo Y~ wӻ8\rN1BHR@W+zU0$B{rNZ5^ځZ =FJv)#QYs b ΂B X@gI5&Dh@#[|(R(]U7(]zʂl ; Lh` (@װ-89 N> @{a .hd+W!nb0 CژM~\ԇ{M;4u㒕ס=s}B}^{'Y` A}FAyyaDn ~`i@dm&AgDPgAe`xYUhFUh$e"ޢ$be X&<edQjQmw顝^i }u%r0ȠVUA"5&WY-^w' 䘀nljgՙsDeyVSꝑqܪtjch`f¬~2ڭ[/٩s51i*oMe駪ZhMk_K"%Eu Bk|! TCe٧ae!vc]7%ga0C!dUA! ,00trt<:<ČTVTԜdfd,.,|z|\^\ܤ464TRT̔ܤlnl424|~|dbdpHEbS`Ǩth4NBk!(0 iz5(a/xg|]_^__ kj{EPV ^_` e |~U ##vF| zG Ws W ͷZhn rM϶XD   P8)$'; [D46 8` h+8g\KݩW,iE|`zhƊ^NcGOPb2d. ~1P  9#4:3 **`&Rg R=h :< ךC%c!d2[>e]@`׷66+ahCظXMBQe4!6G|dw |ORAj zk=â&C汻2jq<,}t0^X&\"Ta8blűŞ[}UxI][T\ChP@e@HUamF5PwԢ"z8 ]iqVWE\ "X-]@֋-љc6O` "x\ ptPc̐_ 4F E^BG fmTQ9*jiy&ntLuP0AbCAYL.fЌX"gC`XdHdH@@ՌR2@o `Fu=SA t. Ak\1Ę>DSN#aWP;p\]O}w x E;FWF[ux)F4fhie&8 LY0Mh T 0"@K'+QLpBz %Պ)Kއ LLy@&޵\~QUYSNFŤ{dT4"݈EeZY!4hf&TlZ𧁣 $M ߅)czp&jo25K;NBih@zIph TA:@NBu}@ @DTYK W6 IN @87eVPiHrLEXjA,W\ G;openfetion-2.2.1/skin/refresh.png0000644000175000017500000000162011561721144015453 0ustar aronaronPNG  IHDRasBIT|dtEXtSoftwarewww.inkscape.org<"IDAT8mRMlTe={3m[ 3јF7`XDa M ta1L%47!«qВF;̴Yp=''\bfHe4jՄ'¸.ؖp|t&E@O*}]gQ(V02v|g'-lzW6ÌĈdǂЉ  3EW Ŋ 5>.W f43=gOk40ĭCձž _M^l8l?3]X1/23ǕgƧg^hڷuS( wD-HU/<A2e^ۏ^,}?,az  ,Hc$UgnSui&vn{'v>Eq4Akw_?߼''k'W%߼[0j>AX-/?ԩT=eYcJ奎Go@W!'$_ԓSln\{&?3 DV%r=?JeFmXv@x\qqah=Ѿ2;}З|9r-k5tT2>hMA҄ǡ̖MD, z=*];[x 8wyIuI1MN<-I7, #?[FՕD(̗ˣRmcer-0{ W1oR ]!PՑl.UvjeIENDB`openfetion-2.2.1/skin/warning.svg0000644000175000017500000000410411561721144015475 0ustar aronaron openfetion-2.2.1/src/0000755000175000017500000000000011561721144013133 5ustar aronaronopenfetion-2.2.1/src/fx_about.c0000644000175000017500000004100111561721144015102 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include #define BUFLEN 4096 static void follow_if_link (GtkWidget *UNUSED(text_view), GtkTextIter *iter) { GSList *tags = NULL, *tagp = NULL; tags = gtk_text_iter_get_tags (iter); for (tagp = tags; tagp != NULL; tagp = tagp->next) { GtkTextTag *tag = tagp->data; gchar *url = (gchar*)(g_object_get_data (G_OBJECT (tag), "url")); if (url) { if(fork() == 0) execlp("xdg-open" , "xdg-open" , url , (char**)NULL); break; } } if (tags) g_slist_free (tags); } static gboolean event_after (GtkWidget *text_view, GdkEvent *ev) { GtkTextIter start, end, iter; GtkTextBuffer *buffer; GdkEventButton *event; gint x, y; if (ev->type != GDK_BUTTON_RELEASE) return FALSE; event = (GdkEventButton *)ev; if (event->button != 1) return FALSE; buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)); gtk_text_buffer_get_selection_bounds (buffer, &start, &end); if (gtk_text_iter_get_offset (&start) != gtk_text_iter_get_offset (&end)) return FALSE; gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, event->x, event->y, &x, &y); gtk_text_view_get_iter_at_location (GTK_TEXT_VIEW (text_view), &iter, x, y); follow_if_link (text_view, &iter); return FALSE; } static void insert_link (GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text) { GtkTextTag *tag; tag = gtk_text_buffer_create_tag (buffer, NULL, "foreground", "blue", "underline", PANGO_UNDERLINE_SINGLE, NULL); g_object_set_data (G_OBJECT (tag), "url", text); gtk_text_buffer_insert_with_tags (buffer, iter, text, -1, tag, NULL); } static gboolean hovering_over_link = FALSE; static GdkCursor *hand_cursor = NULL; static GdkCursor *regular_cursor = NULL; static void set_cursor_if_appropriate (GtkTextView *text_view, gint x, gint y) { GSList *tags = NULL, *tagp = NULL; GtkTextIter iter; gboolean hovering = FALSE; gtk_text_view_get_iter_at_location (text_view, &iter, x, y); tags = gtk_text_iter_get_tags (&iter); for (tagp = tags; tagp != NULL; tagp = tagp->next) { GtkTextTag *tag = tagp->data; gchar *url = (gchar*)(g_object_get_data (G_OBJECT (tag), "url")); if (url) { hovering = TRUE; break; } } if (hovering != hovering_over_link) { hovering_over_link = hovering; if (hovering_over_link) gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), hand_cursor); else gdk_window_set_cursor (gtk_text_view_get_window (text_view, GTK_TEXT_WINDOW_TEXT), regular_cursor); } if (tags) g_slist_free (tags); } static gboolean motion_notify_event (GtkWidget *text_view, GdkEventMotion *event) { gint x, y; gtk_text_view_window_to_buffer_coords (GTK_TEXT_VIEW (text_view), GTK_TEXT_WINDOW_WIDGET, event->x, event->y, &x, &y); set_cursor_if_appropriate (GTK_TEXT_VIEW (text_view), x, y); gdk_window_get_pointer (text_view->window, NULL, NULL, NULL); return FALSE; } static void create_intro(GtkTextView *view) { GtkTextTag *tag; GtkTextTag *tag1; GtkTextIter iter; const char title[] = N_("Openfetion "OPENFETION_VERSION"\n\n"); const char intro[] = N_("OpenFetion is a Fetion client for linux based on GTK+2.0, " "implementing Fetion Protocol Version 4.\n" "It supports most features of Fetion. \n" "What's more, it's lightweight and efficient with intuitive interface.\n\n" "Project homepage: "); gtk_text_view_set_editable(view,FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD_CHAR); g_signal_connect (view, "motion-notify-event", G_CALLBACK (motion_notify_event), NULL); g_signal_connect(view, "event-after", G_CALLBACK (event_after), NULL); GtkTextBuffer *buffer = gtk_text_view_get_buffer(view); tag = gtk_text_buffer_create_tag (buffer, NULL, "size", 15 * PANGO_SCALE, "justification", GTK_JUSTIFY_CENTER, "weight", PANGO_WEIGHT_BOLD, NULL); tag1 = gtk_text_buffer_create_tag (buffer, NULL, "left-margin", 25, "right-margin", 25, NULL); gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, title, -1, tag, NULL); gtk_text_buffer_insert_with_tags(buffer, &iter, _(intro), -1, tag1, NULL); insert_link(buffer, &iter, "http://code.google.com/p/ofetion/"); gtk_text_buffer_insert_with_tags(buffer, &iter, _("\nBug report: "), -1, tag1, NULL); insert_link(buffer, &iter, "http://code.google.com/p/ofetion/issues/"); gtk_text_buffer_insert_with_tags(buffer, &iter, _("\n\nPage on author's blog: "), -1, tag1, NULL); insert_link(buffer, &iter, "http://basiccoder.com/openfetion"); } static void create_author(GtkTextView *view) { GtkTextTag *tag; GtkTextTag *tag1; GtkTextIter iter; const char title[] = "Levin\n\n"; const char *intro = _("Graduate student at Beijing University of Post & Telecommunication." "Love Linux,Love OpenSource.Started this project in order to help " "linux users including myself to get a better way to use fetion.\n\n" "Blog:"); gtk_text_view_set_editable(view,FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD_CHAR); g_signal_connect (view, "motion-notify-event", G_CALLBACK (motion_notify_event), NULL); g_signal_connect(view, "event-after", G_CALLBACK (event_after), NULL); GtkTextBuffer *buffer = gtk_text_view_get_buffer(view); tag = gtk_text_buffer_create_tag (buffer, NULL, "size", 15 * PANGO_SCALE, "justification", GTK_JUSTIFY_CENTER, "weight", PANGO_WEIGHT_BOLD, NULL); tag1 = gtk_text_buffer_create_tag (buffer, NULL, "left-margin", 25, "right-margin", 25, NULL); gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, title, -1, tag, NULL); gtk_text_buffer_insert_with_tags(buffer, &iter, intro, -1, tag1, NULL); insert_link(buffer, &iter, "http://basiccoder.com"); gtk_text_buffer_insert_with_tags(buffer, &iter, "\nE-mail: levin108@gmail.com\n", -1, tag1, NULL); gtk_text_buffer_insert_with_tags(buffer, &iter, "Twitter: ", -1, tag1, NULL); insert_link(buffer, &iter, "http://twitter.com/levin108"); } static void create_gpl(GtkTextView *view) { GtkTextTag *tag; GtkTextIter iter; char *buf1 = N_("This program is free software; you can redistribute it and/or modify " "it under the terms of the GNU General Public License as published by " "the Free Software Foundation; either version 2 of the License, or " "(at your option) any later version.\n\n"); char *buf2 = N_("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.\n\n"); char *buf3 = N_("You should have received a copy of the GNU General Public License " "along with this program; if not, see \n"); gtk_text_view_set_editable(view, FALSE); gtk_text_view_set_wrap_mode(view, GTK_WRAP_WORD); g_signal_connect (view, "motion-notify-event", G_CALLBACK (motion_notify_event), NULL); GtkTextBuffer *buffer = gtk_text_view_get_buffer(view); tag = gtk_text_buffer_create_tag (buffer, NULL, "left-margin", 5, "right-margin", 5, NULL); gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, _(buf1), -1, tag, NULL); gtk_text_buffer_insert_with_tags(buffer, &iter, _(buf2), -1, tag, NULL); gtk_text_buffer_insert_with_tags(buffer, &iter, _(buf3), -1, tag, NULL); insert_link(buffer, &iter, "http://www.gnu.org/licenses/gpl-2.0.txt"); } static void create_contri(GtkTextView *view) { GtkTextTag *tag; GtkTextTag *tag1; GtkTextTag *tag2; GtkTextIter iter; const char title[] = N_("The Main Contributors\n\n"); const char *intro; gtk_text_view_set_editable(view,FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD_CHAR); g_signal_connect (view, "motion-notify-event", G_CALLBACK (motion_notify_event), NULL); g_signal_connect(view, "event-after", G_CALLBACK (event_after), NULL); GtkTextBuffer *buffer = gtk_text_view_get_buffer(view); tag = gtk_text_buffer_create_tag (buffer, NULL, "size", 15 * PANGO_SCALE, "justification", GTK_JUSTIFY_CENTER, "weight", PANGO_WEIGHT_BOLD, NULL); tag1 = gtk_text_buffer_create_tag (buffer, NULL, "left-margin", 25, "right-margin", 25, NULL); tag2 = gtk_text_buffer_create_tag (buffer, NULL, "left-margin", 25, "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_get_start_iter(buffer, &iter); gtk_text_buffer_insert_with_tags(buffer, &iter, title, -1, tag, NULL); gtk_text_buffer_insert_with_tags(buffer, &iter, "happyaron: ", -1, tag2, NULL); intro = N_("Make deb package for debian/ubuntu users," "maintainer of the PPA of openfetion.\nBlog:"); gtk_text_buffer_insert_with_tags(buffer, &iter, _(intro), -1, tag1, NULL); insert_link(buffer, &iter, "http://blogs.gnome.org/happyaron/"); gtk_text_buffer_insert_with_tags(buffer, &iter, "\n\nwzssyqa: ", -1, tag2, NULL); intro = N_("Main translater of openfetion,accomplish" " the internationalisation(i18n) of openfetion"); gtk_text_buffer_insert_with_tags(buffer, &iter, _(intro), -1, tag1, NULL); gtk_text_buffer_insert_with_tags(buffer, &iter, "\n\nxhacker: ", -1, tag2, NULL); intro = N_("Contributed to the UI development,and fixed some " "bugs of the UI.\nFollow him:"); gtk_text_buffer_insert_with_tags(buffer, &iter, _(intro), -1, tag1, NULL); insert_link(buffer, &iter, "http://twitter.com/xhacker"); gtk_text_buffer_insert_with_tags(buffer, &iter, "\n\nriku: ", -1, tag2, NULL); intro = N_("A good designer,designed a logo and some icons for " "openfetion,and also contributed to the UI design.\nFollow him:"); gtk_text_buffer_insert_with_tags(buffer, &iter, _(intro), -1, tag1, NULL); insert_link(buffer, &iter, "http://twitter.com/riku"); } void close_about(GtkWidget *UNUSED(widget), gpointer data) { GtkWidget *window = GTK_WIDGET(data); gtk_widget_destroy(window); } void show_about() { GtkWidget *window; GtkWidget *image; GdkPixbuf *pixbuf; GtkWidget *vbox; GtkWidget *notebook; GtkWidget *scroll; GtkWidget *textview; GtkWidget *tablabel; GtkWidget *action_area; GtkWidget *button; hand_cursor = gdk_cursor_new (GDK_HAND2); regular_cursor = gdk_cursor_new (GDK_XTERM); pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg", 40, 40, NULL); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_icon(GTK_WINDOW(window), pixbuf); g_object_unref(pixbuf); gtk_window_set_title(GTK_WINDOW(window), _("About OpenFetion")); gtk_widget_set_usize(window, 500, 400); vbox = gtk_vbox_new(FALSE, 5); pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg", 98, 98, NULL); image = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(pixbuf); gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0); notebook = gtk_notebook_new(); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook), GTK_POS_LEFT); gtk_box_pack_start(GTK_BOX(vbox), notebook, TRUE, TRUE, 5); tablabel = gtk_label_new(_("Introduction")); scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); textview = gtk_text_view_new(); create_intro(GTK_TEXT_VIEW(textview)); gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, tablabel); tablabel = gtk_label_new(_("About the author")); scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); textview = gtk_text_view_new(); create_author(GTK_TEXT_VIEW(textview)); gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, tablabel); tablabel = gtk_label_new(_("Contributor")); scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); textview = gtk_text_view_new(); create_contri(GTK_TEXT_VIEW(textview)); gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, tablabel); tablabel = gtk_label_new(_("License")); scroll = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); textview = gtk_text_view_new(); create_gpl(GTK_TEXT_VIEW(textview)); gtk_container_add(GTK_CONTAINER(scroll), textview); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll, tablabel); action_area = gtk_hbox_new(FALSE, 10); gtk_box_pack_start(GTK_BOX(vbox), action_area, FALSE, FALSE, 5); button = gtk_button_new_with_label(_("Close")); gtk_widget_set_usize(button, 90, 0); gtk_box_pack_end(GTK_BOX(action_area), button, FALSE, FALSE, 5); g_signal_connect(button, "clicked", G_CALLBACK(close_about), window); gtk_container_add(GTK_CONTAINER(window), vbox); gtk_widget_show_all(window); } openfetion-2.2.1/src/fx_add_group.c0000644000175000017500000001237111561721144015744 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static void fx_add_group_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxAddGroup* fxaddgroup = (FxAddGroup*)data; User* user = fxaddgroup->fxmain->user; const char* text = gtk_entry_get_text(GTK_ENTRY(fxaddgroup->add_entry)); GtkTreeView* tree = GTK_TREE_VIEW(fxaddgroup->fxmain->mainPanel->treeView); GtkTreeModel* model = gtk_tree_view_get_model(tree); GtkTreeIter iter; int groupid; groupid = fetion_buddylist_create(user , text); if(groupid > 0 ) { gtk_tree_store_append(GTK_TREE_STORE(model) , &iter , NULL); gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , G_NAME_COL , text , G_ID_COL , groupid , G_ALL_COUNT_COL , 0 , G_ONLINE_COUNT_COL , 0 , -1); gtk_tree_view_set_model(tree , model); } gtk_dialog_response(GTK_DIALOG(fxaddgroup->dialog) , GTK_RESPONSE_CANCEL); } static void fx_add_group_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_CANCEL); } FxAddGroup* fx_add_group_new(FxMain* fxmain) { FxAddGroup* fxaddgroup = (FxAddGroup*)malloc(sizeof(FxAddGroup)); memset(fxaddgroup , 0 , sizeof(FxAddGroup)); fxaddgroup->fxmain = fxmain; return fxaddgroup; } void fx_add_group_initialize(FxAddGroup* fxaddgroup) { GdkPixbuf* pb; fxaddgroup->dialog = gtk_dialog_new(); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , 22 , 22 , NULL); gtk_dialog_set_has_separator(GTK_DIALOG(fxaddgroup->dialog) , FALSE); gtk_window_set_resizable(GTK_WINDOW(fxaddgroup->dialog) , FALSE); gtk_widget_set_usize(fxaddgroup->dialog , 300 , 150); gtk_window_set_icon(GTK_WINDOW(fxaddgroup->dialog) , pb); g_object_unref(pb); gtk_window_set_title(GTK_WINDOW(fxaddgroup->dialog) , _("Add a buddy group")); gtk_container_set_border_width(GTK_CONTAINER(fxaddgroup->dialog) , 20); fxaddgroup->add_label = gtk_label_new(_("Input the name of the new group:")); gtk_misc_set_alignment(GTK_MISC(fxaddgroup->add_label) , 0 , 0 ); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddgroup->dialog)->vbox) , fxaddgroup->add_label); fxaddgroup->add_entry = gtk_entry_new(); g_signal_connect(fxaddgroup->add_entry , "activate" , G_CALLBACK(fx_add_group_on_ok_clicked) , fxaddgroup); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddgroup->dialog)->vbox) , fxaddgroup->add_entry); fxaddgroup->ok_button = gtk_button_new_with_label(_("OK")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddgroup->dialog)->action_area) , fxaddgroup->ok_button); g_signal_connect(fxaddgroup->ok_button , "clicked" , G_CALLBACK(fx_add_group_on_ok_clicked) , fxaddgroup); fxaddgroup->cancel_button = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddgroup->dialog)->action_area) , fxaddgroup->cancel_button); g_signal_connect(fxaddgroup->cancel_button , "clicked" , G_CALLBACK(fx_add_group_on_cancel_clicked) , fxaddgroup->dialog); gtk_widget_show_all(fxaddgroup->dialog); } void fx_add_group_free(FxAddGroup* fxaddgroup) { free(fxaddgroup); } openfetion-2.2.1/src/fx_add_group.h0000644000175000017500000000475211561721144015755 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_ADD_GROUP_H #define FX_ADD_GROUP_H extern FxAddGroup* fx_add_group_new(FxMain* fxmain); extern void fx_add_group_initialize(FxAddGroup* fxaddgroup); extern void fx_add_group_free(FxAddGroup* fxaddgroup); #endif openfetion-2.2.1/src/fx_addbuddy.c0000644000175000017500000003305711561721144015564 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxAddbuddy* fx_addbuddy_new(FxMain* fxmain) { FxAddbuddy* fxaddbuddy = (FxAddbuddy*)malloc(sizeof(FxAddbuddy)); memset(fxaddbuddy , 0 , sizeof(FxAddbuddy)); fxaddbuddy->fxmain = fxmain; fxaddbuddy->phraselist = fetion_config_get_phrase(fxmain->user->config); return fxaddbuddy; } void fx_addbuddy_initialize(FxAddbuddy* fxaddbuddy) { GdkPixbuf *icon; GtkWidget *group_text , *info_frame , *info_box , *ok_button; GtkWidget *cancel_button , *name_text , *msg_frame , *msglabel; GtkWidget *group_entry , *name_hbox , *name_alignment; GtkTreeModel* model; fxaddbuddy->dialog = gtk_dialog_new(); icon = gdk_pixbuf_new_from_file(SKIN_DIR"add.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxaddbuddy->dialog) , icon); gtk_window_set_title(GTK_WINDOW(fxaddbuddy->dialog) , _("Add Buddy")); gtk_dialog_set_has_separator(GTK_DIALOG(fxaddbuddy->dialog) , FALSE); gtk_window_set_resizable(GTK_WINDOW(fxaddbuddy->dialog) , FALSE); gtk_window_set_modal(GTK_WINDOW(fxaddbuddy->dialog) , TRUE); gtk_widget_set_usize(fxaddbuddy->dialog , 350 , 420); gtk_container_set_border_width(GTK_CONTAINER(fxaddbuddy->dialog) , 20); fxaddbuddy->tablebox = gtk_table_new(2 , 2 , FALSE); fxaddbuddy->mobile_button = gtk_radio_button_new_with_label(NULL , _("Cell Phone Number:")); fxaddbuddy->group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(fxaddbuddy->mobile_button)); fxaddbuddy->fetion_button = gtk_radio_button_new_with_label(fxaddbuddy->group , _("Fetion Number:")); g_signal_connect(fxaddbuddy->fetion_button , "toggled" , G_CALLBACK(fx_addbuddy_no_type_change) , fxaddbuddy); gtk_table_attach_defaults(GTK_TABLE(fxaddbuddy->tablebox) , fxaddbuddy->fetion_button , 0 , 1 , 1 , 2); gtk_table_attach_defaults(GTK_TABLE(fxaddbuddy->tablebox) , fxaddbuddy->mobile_button , 0 , 1 , 0 , 1); fxaddbuddy->fetion_entry = gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE(fxaddbuddy->tablebox) , fxaddbuddy->fetion_entry , 1 , 2 , 1 , 2); gtk_widget_set_sensitive(fxaddbuddy->fetion_entry , FALSE); fxaddbuddy->mobile_entry = gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE(fxaddbuddy->tablebox) , fxaddbuddy->mobile_entry , 1 , 2 , 0 , 1); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddbuddy->dialog)->vbox) , fxaddbuddy->tablebox); info_frame = gtk_frame_new(_("Contact's Information")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddbuddy->dialog)->vbox) , info_frame); info_box = gtk_table_new(2 , 3 , FALSE); gtk_container_add(GTK_CONTAINER(info_frame) , info_box); group_text = gtk_label_new(_("Group: ")); gtk_table_attach_defaults(GTK_TABLE(info_box) , group_text , 0 , 1 , 0 , 1); name_text = gtk_label_new(_("Name: ")); gtk_table_attach_defaults(GTK_TABLE(info_box) , name_text , 0 , 1 , 1 , 2 ); model = fx_addbuddy_create_group_model(fxaddbuddy); fxaddbuddy->group_combo = gtk_combo_box_entry_new_with_model(model , GROUP_NAME_COL); group_entry = gtk_bin_get_child(GTK_BIN(fxaddbuddy->group_combo)); gtk_entry_set_editable(GTK_ENTRY(group_entry) , FALSE); gtk_widget_set_usize(fxaddbuddy->group_combo , 130 , 25); gtk_table_attach_defaults(GTK_TABLE(info_box) , fxaddbuddy->group_combo , 1 , 2 , 0 , 1 ); fxaddbuddy->name_entry = gtk_entry_new(); gtk_widget_set_usize(fxaddbuddy->name_entry , 130 , 25); gtk_table_attach_defaults(GTK_TABLE(info_box) , fxaddbuddy->name_entry , 1 , 2 , 1 , 2); msg_frame = gtk_frame_new(_("Send Message:")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddbuddy->dialog)->vbox) , msg_frame); fxaddbuddy->msgbox = gtk_vbox_new(FALSE , 3); msglabel = gtk_label_new(_("Hello ,I am ")); fxaddbuddy->myname_entry = gtk_entry_new(); gtk_widget_set_usize(fxaddbuddy->myname_entry , 70 , 30); name_hbox = gtk_hbox_new(FALSE , 3); name_alignment = gtk_alignment_new(0 ,0 , 0 , 0); gtk_container_add(GTK_CONTAINER(name_alignment) , name_hbox); gtk_box_pack_start_defaults(GTK_BOX(name_hbox) , msglabel); gtk_box_pack_start_defaults(GTK_BOX(name_hbox) , fxaddbuddy->myname_entry); gtk_box_pack_start_defaults(GTK_BOX(fxaddbuddy->msgbox) , name_alignment); gtk_container_add(GTK_CONTAINER(msg_frame) , fxaddbuddy->msgbox); ok_button = gtk_button_new_with_label(_("OK")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddbuddy->dialog)->action_area) , ok_button); g_signal_connect(G_OBJECT(ok_button) , "clicked" , G_CALLBACK(fx_addbuddy_on_ok_clicked) , fxaddbuddy); cancel_button = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxaddbuddy->dialog)->action_area) , cancel_button); g_signal_connect(G_OBJECT(cancel_button) , "clicked" , G_CALLBACK(fx_addbuddy_on_cancel_clicked) , fxaddbuddy->dialog); fx_addbuddy_bind(fxaddbuddy); gtk_widget_show_all(fxaddbuddy->dialog); } GtkTreeModel* fx_addbuddy_create_group_model(FxAddbuddy* fxaddbuddy) { FxMain* fxmain = fxaddbuddy->fxmain; GtkTreeView* tree = GTK_TREE_VIEW(fxmain->mainPanel->treeView); GtkTreeModel* model = gtk_tree_view_get_model(tree); GtkTreeStore* store; GtkTreeIter iter , cIter; char* groupname; int groupid; store = gtk_tree_store_new(GROUP_COL_NUMS , G_TYPE_STRING , G_TYPE_INT); gtk_tree_model_get_iter_root(model , &iter); do { gtk_tree_model_get(model , &iter , G_NAME_COL , &groupname , G_ID_COL , &groupid , -1); gtk_tree_store_append(store , &cIter , NULL); gtk_tree_store_set(store , &cIter , GROUP_NAME_COL , groupname , GROUP_ID_COL , groupid , -1); } while(gtk_tree_model_iter_next(model , &iter)); return GTK_TREE_MODEL(store); } void fx_addbuddy_bind(FxAddbuddy* fxaddbuddy) { GtkWidget *button; GSList *msglist = NULL; FxList *pos; Phrase *phrase; User *user = fxaddbuddy->fxmain->user; foreach_list(fxaddbuddy->phraselist , pos){ phrase = (Phrase*)(pos->data); button = gtk_radio_button_new_with_label(msglist , phrase->content); msglist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(button)); g_signal_connect(G_OBJECT(button) , "toggled" , G_CALLBACK(fx_addbuddy_on_phrase_change) , fxaddbuddy); gtk_box_pack_start(GTK_BOX(fxaddbuddy->msgbox) , button , FALSE , FALSE , 1); } gtk_combo_box_set_active (GTK_COMBO_BOX(fxaddbuddy->group_combo), 0); gtk_entry_set_text(GTK_ENTRY(fxaddbuddy->myname_entry) , user->nickname); } void fx_addbuddy_on_ok_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxAddbuddy* fxadd = (FxAddbuddy*)data; const char *no = NULL; const char *desc = NULL; const char *localname = NULL; int buddylist; GtkTreeIter iter , newIter; GtkTreeModel *model = NULL; GtkTreeModel *mainModel = NULL; Contact* contact = NULL; Config* config = NULL; GdkPixbuf *pb = NULL; FxCode* fxcode = NULL; int ret = 0; char code[24]; User* user = fxadd->fxmain->user; config = user->config; if(fxadd->notype == FETION_NO) { no = gtk_entry_get_text(GTK_ENTRY(fxadd->fetion_entry)); if(strcmp(no , user->sId) == 0) { fx_util_popup_warning(fxadd->fxmain , _("You can not add yourself as a friend")); gtk_dialog_response(GTK_DIALOG(fxadd->dialog) , GTK_RESPONSE_OK); return; } } else { no = gtk_entry_get_text(GTK_ENTRY(fxadd->mobile_entry)); if(strcmp(no , user->mobileno) == 0) { fx_util_popup_warning(fxadd->fxmain , _("You can not add yourself as a friend")); gtk_dialog_response(GTK_DIALOG(fxadd->dialog) , GTK_RESPONSE_OK); return; } } if(*no == '\0') return; desc = gtk_entry_get_text(GTK_ENTRY(fxadd->myname_entry)); model = gtk_combo_box_get_model(GTK_COMBO_BOX(fxadd->group_combo)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(fxadd->group_combo) , &iter); gtk_tree_model_get(model , &iter , GROUP_ID_COL , &buddylist , -1); localname = gtk_entry_get_text(GTK_ENTRY(fxadd->name_entry)); addbuddy: contact = fetion_contact_add_buddy(user, no, fxadd->notype, buddylist, localname, desc, fxadd->phraseid, &ret); switch(ret) { case BUDDY_USER_EXIST : fx_util_popup_warning(fxadd->fxmain, _("The contact you want to add has already been in your contact list, please don't add him(her) repeatedly!")); gtk_dialog_response(GTK_DIALOG(fxadd->dialog), GTK_RESPONSE_OK); return; case BUDDY_SAME_USER_DAILY_LIMIT : fx_util_popup_warning(fxadd->fxmain, _("You have reached the daily limit of adding buddies, please retry later")); gtk_dialog_response(GTK_DIALOG(fxadd->dialog) , GTK_RESPONSE_OK); return; case BUDDY_BAD_REQUEST : fx_util_popup_warning(fxadd->fxmain , _("Add buddy failed. Unknown reason!")); gtk_dialog_response(GTK_DIALOG(fxadd->dialog) , GTK_RESPONSE_OK); return; default: break; } if(contact != NULL) { mainModel = gtk_tree_view_get_model(GTK_TREE_VIEW(fxadd->fxmain->mainPanel->treeView)); gtk_tree_model_get_iter_root(mainModel , &iter); do { gtk_tree_model_get(mainModel , &iter , G_ID_COL , &buddylist , -1); if(buddylist == contact->groupid) { pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 25 , 25 , NULL); gtk_tree_store_append(GTK_TREE_STORE(mainModel) , &newIter , &iter); gtk_tree_store_set(GTK_TREE_STORE(mainModel) , &newIter , B_PIXBUF_COL , pb , B_SIPURI_COL , contact->sipuri , B_USERID_COL , contact->userId , B_NAME_COL , contact->localname , B_CARRIER_COL , "CMCC" , B_STATE_COL , 0 , B_SERVICESTATUS_COL , contact->serviceStatus , B_CARRIERSTATUS_COL , CARRIER_STATUS_NORMAL , B_RELATIONSTATUS_COL , RELATION_STATUS_UNAUTHENTICATED , B_IMAGE_CHANGED_COL , -1 , B_SIZE_COL , config->iconSize , -1); break; } } while(gtk_tree_model_iter_next(mainModel , &iter)); } else { if(user->verification != NULL) { generate_pic_code(user); fxcode = fx_code_new(fxadd->fxmain , user->verification->text , user->verification->tips , CODE_NOT_ERROR); fx_code_initialize(fxcode); ret = gtk_dialog_run(GTK_DIALOG(fxcode->dialog)); if(ret == GTK_RESPONSE_OK) { memset(code, 0, sizeof(code)); strcpy(code , gtk_entry_get_text(GTK_ENTRY(fxcode->codeentry))); fetion_user_set_verification_code(user , code); gtk_widget_destroy(fxcode->dialog); goto addbuddy; gdk_threads_leave(); } else { gtk_widget_destroy(fxcode->dialog); gdk_threads_leave(); } } } gtk_dialog_response(GTK_DIALOG(fxadd->dialog) , GTK_RESPONSE_OK); } void fx_addbuddy_on_cancel_clicked(GtkWidget *UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_CANCEL); } void fx_addbuddy_on_phrase_change(GtkWidget* widget , gpointer data) { FxAddbuddy *fxaddbuddy = (FxAddbuddy*)data; const char *label; FxList *pos; Phrase *phrase; if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) return; label = gtk_button_get_label(GTK_BUTTON(widget)); pos = fxaddbuddy->phraselist; foreach_list(fxaddbuddy->phraselist , pos){ phrase = (Phrase*)(pos->data); if(strcmp(phrase->content , label) == 0){ fxaddbuddy->phraseid = phrase->phraseid; break; } } } void fx_addbuddy_no_type_change(GtkWidget *UNUSED(widget) , gpointer data) { FxAddbuddy* fxaddbuddy = (FxAddbuddy*)data; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxaddbuddy->fetion_button))) { fxaddbuddy->notype = FETION_NO; gtk_widget_set_sensitive(fxaddbuddy->fetion_entry , TRUE); gtk_widget_set_sensitive(fxaddbuddy->mobile_entry , FALSE); } else { fxaddbuddy->notype = MOBILE_NO; gtk_widget_set_sensitive(fxaddbuddy->fetion_entry , FALSE); gtk_widget_set_sensitive(fxaddbuddy->mobile_entry , TRUE); } } openfetion-2.2.1/src/fx_addbuddy.h0000644000175000017500000000572111561721144015566 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_ADDBUDDY_H #define FX_ADDBUDDY_H enum groupcolumn { GROUP_NAME_COL = 0, GROUP_ID_COL = 1, GROUP_COL_NUMS = 2 }; extern FxAddbuddy* fx_addbuddy_new(FxMain* fxmain); extern void fx_addbuddy_initialize(FxAddbuddy* fxaddbuddy); extern GtkTreeModel* fx_addbuddy_create_group_model(FxAddbuddy* fxaddnuddy); extern void fx_addbuddy_bind(FxAddbuddy* fxaddbuddy); extern void fx_addbuddy_on_ok_clicked(GtkWidget *UNUSED(widget) , gpointer data); extern void fx_addbuddy_on_cancel_clicked(GtkWidget *UNUSED(widget) , gpointer data); extern void fx_addbuddy_on_phrase_change(GtkWidget *widget , gpointer data); extern void fx_addbuddy_no_type_change(GtkWidget *UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_app.c0000644000175000017500000002705611561721144014566 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxApp* fx_app_new(FxMain* fxmain , const char* sipuri , const char* userid , const char* desc , int phrase) { FxApp *fxapp = (FxApp*)malloc(sizeof(FxApp)); memset(fxapp , 0 , sizeof(FxApp)); fxapp->fxmain = fxmain; fxapp->phraseid = phrase; strcpy(fxapp->sipuri , sipuri); strcpy(fxapp->userid , userid); strcpy(fxapp->desc , desc); return fxapp; } void fx_app_initialize(FxApp* fxapp) { GtkWidget *fixed = NULL; GdkPixbuf *pb = NULL; GtkWidget *okButton = NULL; GtkWidget *cancelButton = NULL; GtkWidget *lnLabel = NULL; GtkWidget *agLabel = NULL; GtkWidget *ifoButton = NULL; GtkTreeModel *model = NULL; GtkWidget *ifoEntry = NULL; FxMain *fxmain = fxapp->fxmain; Config *config = fxmain->user->config; FxList *phraseList , *pl_cur; Phrase *phrase = NULL; char text[1024]; fxapp->dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(fxapp->dialog) , _("Receive an Add Buddy request")); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 24 , 24 , NULL); gtk_window_set_modal(GTK_WINDOW(fxapp->dialog) , FALSE); gtk_window_set_transient_for(GTK_WINDOW(fxapp->dialog) , GTK_WINDOW(fxmain->window)); gtk_window_set_icon(GTK_WINDOW(fxapp->dialog) , pb); g_object_unref(pb); gtk_window_set_resizable(GTK_WINDOW(fxapp->dialog) , FALSE); gtk_widget_set_usize(fxapp->dialog , 440 , 280); fixed = gtk_fixed_new(); fxapp->msgLabel = gtk_label_new(""); phraseList = fetion_config_get_phrase(config); foreach_list(phraseList , pl_cur){ phrase = (Phrase*)pl_cur->data; if(fxapp->phraseid == phrase->phraseid){ memset(text, 0, sizeof(text)); sprintf(text , _("Hello ,I am %s , %s") , fxapp->desc , phrase->content); } fetion_phrase_free(phrase); } gtk_label_set_markup(GTK_LABEL(fxapp->msgLabel) , text); gtk_label_set_line_wrap(GTK_LABEL(fxapp->msgLabel) , TRUE); gtk_widget_set_usize(fxapp->msgLabel , 400 , 30); gtk_fixed_put(GTK_FIXED(fixed) , fxapp->msgLabel , 20 , 20); fxapp->aptButton = gtk_radio_button_new_with_label(NULL , _("Accept and add him(her) to your contact list")); fxapp->rdoList = gtk_radio_button_get_group(GTK_RADIO_BUTTON(fxapp->aptButton)); gtk_fixed_put(GTK_FIXED(fixed) , fxapp->aptButton , 20 , 50); lnLabel = gtk_label_new(_("Note name:")); gtk_fixed_put(GTK_FIXED(fixed) , lnLabel , 40 , 85); fxapp->lnEntry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(fxapp->lnEntry) , fxapp->desc); gtk_widget_set_usize(fxapp->lnEntry , 200 , 28); gtk_fixed_put(GTK_FIXED(fixed) , fxapp->lnEntry , 120 , 80); ifoButton = gtk_button_new_with_label(_("View details")); g_signal_connect(ifoButton , "clicked" , G_CALLBACK(fx_app_on_check_clicked) , fxapp); gtk_widget_set_usize(ifoButton , 80 , 65); gtk_fixed_put(GTK_FIXED(fixed) , ifoButton , 340 , 80); agLabel = gtk_label_new(_("Add to group:")); gtk_fixed_put(GTK_FIXED(fixed) , agLabel , 40 , 120); model = fx_app_create_group_model(fxmain); fxapp->agCombo = gtk_combo_box_entry_new_with_model(model , APP_G_NAME_COL); ifoEntry = gtk_bin_get_child(GTK_BIN(fxapp->agCombo)); gtk_entry_set_editable(GTK_ENTRY(ifoEntry) , FALSE); gtk_combo_box_set_active(GTK_COMBO_BOX(fxapp->agCombo) , 0); gtk_widget_set_usize(fxapp->agCombo , 200 , 30); gtk_fixed_put(GTK_FIXED(fixed) , fxapp->agCombo , 120 , 115); fxapp->rjtButton = gtk_radio_button_new_with_label(fxapp->rdoList , _("Decline his(her) add buddy request")); gtk_fixed_put(GTK_FIXED(fixed) , fxapp->rjtButton , 20 , 150); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxapp->dialog)->vbox) , fixed); okButton = gtk_button_new_with_label(_("OK")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxapp->dialog)->action_area) , okButton); g_signal_connect(okButton , "clicked" , G_CALLBACK(fx_app_on_ok_clicked) , fxapp); cancelButton = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxapp->dialog)->action_area) , cancelButton); g_signal_connect(cancelButton , "clicked" , G_CALLBACK(fx_app_on_cancel_clicked) , fxapp); gtk_widget_show_all(fxapp->dialog); } GtkTreeModel* fx_app_create_group_model(FxMain* fxmain) { GtkTreeStore *store = NULL; GtkTreeModel *model = NULL; GtkTreeView *tree = NULL; GtkTreeIter oIter; GtkTreeIter nIter; gchar *groupname = NULL; gint groupid; tree = GTK_TREE_VIEW(fxmain->mainPanel->treeView); model = gtk_tree_view_get_model(tree); store = gtk_tree_store_new(APP_G_COL_NUM , G_TYPE_STRING , G_TYPE_INT); gtk_tree_model_get_iter_root(model , &oIter); do{ gtk_tree_model_get(model , &oIter , G_NAME_COL , &groupname , G_ID_COL , &groupid , -1); gtk_tree_store_append(store , &nIter , NULL); gtk_tree_store_set(store , &nIter , APP_G_NAME_COL , groupname , APP_G_ID_COL , groupid , -1); }while(gtk_tree_model_iter_next(model , &oIter)); return GTK_TREE_MODEL(store); } void* fx_app_ok_thread(void* data) { FxApp *fxapp = (FxApp*)data; const gchar *localname = NULL; gint buddylist; gint groupid; gint result; gint allCount; gint onlineCount; FxMain *fxmain = fxapp->fxmain; GtkTreeView *tree = GTK_TREE_VIEW(fxmain->mainPanel->treeView); GtkTreeModel *model = gtk_tree_view_get_model(tree); GtkTreeModel *gmodel = NULL; GtkTreeIter iter; GtkTreeIter iter1; GtkTreeIter piter; Contact *contact = NULL; GdkPixbuf *pb = NULL; Config *config = NULL; gchar portraitPath[512]; gchar *sid = NULL; gmodel = gtk_combo_box_get_model(GTK_COMBO_BOX(fxapp->agCombo)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(fxapp->agCombo) , &iter); gtk_tree_model_get(gmodel , &iter , APP_G_ID_COL , &buddylist , -1); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxapp->aptButton))) result = APP_ACCEPT; else result = APP_REJECT; localname = gtk_entry_get_text(GTK_ENTRY(fxapp->lnEntry)); localname = ""; if(result == APP_REJECT){ contact = fetion_contact_handle_contact_request(fxmain->user , fxapp->sipuri , fxapp->userid , localname , buddylist , result); return NULL; } gtk_tree_model_get_iter_root(model , &piter); do { gtk_tree_model_get(model , &piter , G_ID_COL , &groupid , G_ALL_COUNT_COL , &allCount , G_ONLINE_COUNT_COL , &onlineCount , -1); if(groupid == buddylist) { allCount ++; gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model) , &piter , G_ALL_COUNT_COL , allCount , G_ONLINE_COUNT_COL , onlineCount , -1); gdk_threads_leave(); break; } } while(gtk_tree_model_iter_next(model , &piter)); gdk_threads_enter(); gtk_tree_store_append(GTK_TREE_STORE(model) , &iter1 , &piter); gdk_threads_leave(); fetion_user_download_portrait(fxmain->user , fxapp->sipuri); config = fxmain->user->config; sid = fetion_sip_get_sid_by_sipuri(fxapp->sipuri); sprintf(portraitPath , "%s/%s.jpg" , config->iconPath , sid); g_free(sid); pb = gdk_pixbuf_new_from_file_at_size(portraitPath , config->iconSize , config->iconSize , NULL); if(pb == NULL) pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , config->iconSize , config->iconSize , NULL); gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model) , &iter1 , B_PIXBUF_COL , pb , B_SIPURI_COL , fxapp->sipuri , -1); gdk_threads_leave(); contact = fetion_contact_handle_contact_request(fxmain->user , fxapp->sipuri , fxapp->userid , localname , buddylist , result); if(contact == NULL){ gdk_threads_enter(); gtk_tree_store_remove(GTK_TREE_STORE(model) , &iter1); gdk_threads_leave(); return NULL; } gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model) , &iter1 , B_USERID_COL , contact->userId , B_NAME_COL , contact->nickname ? contact->nickname : "" , B_SERVICESTATUS_COL , BASIC_SERVICE_NORMAL , B_RELATIONSTATUS_COL , contact->relationStatus , B_CARRIER_COL , "CMCC" , B_CARRIERSTATUS_COL , CARRIER_STATUS_NORMAL , B_DEVICE_COL , "PC" , -1); gdk_threads_leave(); return NULL; } void fx_app_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxApp *fxapp = (FxApp*)data; g_thread_create(fx_app_ok_thread , data , TRUE , NULL); gtk_dialog_response(GTK_DIALOG(fxapp->dialog) , GTK_RESPONSE_OK); } void fx_app_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxApp *fxapp = (FxApp*)data; gtk_dialog_response(GTK_DIALOG(fxapp->dialog) , GTK_RESPONSE_CANCEL); } void* fx_app_check_thread(void* data) { FxApp *fxapp = (FxApp*)data; User *user = fxapp->fxmain->user; gchar *sid = NULL; Contact *contact = NULL; FxLookupres *fxlookupres = NULL; sid = fetion_sip_get_sid_by_sipuri(fxapp->sipuri); contact = fetion_contact_get_contact_info_by_no(user , sid , FETION_NO); g_free(sid); if(contact == NULL){ gdk_threads_enter(); fx_util_popup_warning(fxapp->fxmain, _("Lookup failed, unknown identity, unknown reason")); gdk_threads_leave(); return NULL; } gdk_threads_enter(); fxlookupres = fx_lookupres_new(fxapp->fxmain , contact); fx_lookupres_initialize(fxlookupres); gtk_dialog_run(GTK_DIALOG(fxlookupres->dialog)); g_free(contact); gtk_widget_destroy(fxlookupres->dialog); gdk_threads_leave(); return NULL; } void fx_app_on_check_clicked(GtkWidget* UNUSED(widget) , gpointer data) { g_thread_create(fx_app_check_thread , data , FALSE , NULL); } openfetion-2.2.1/src/fx_app.h0000644000175000017500000000553011561721144014564 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_APP_H #define FX_APP_H enum { APP_G_NAME_COL , APP_G_ID_COL , APP_G_COL_NUM }; enum { APP_ACCEPT = 1, APP_REJECT = 0 }; extern FxApp* fx_app_new(FxMain* fxmain , const char* sipuri , const char* userid , const char* desc , int phrase); extern void fx_app_initialize(FxApp* fxapp); extern GtkTreeModel* fx_app_create_group_model(FxMain* fxmain); extern void fx_app_on_ok_clicked(GtkWidget* widget , gpointer data); extern void fx_app_on_cancel_clicked(GtkWidget* widget , gpointer data); extern void fx_app_on_check_clicked(GtkWidget* widget , gpointer data); #endif openfetion-2.2.1/src/fx_bottom.c0000644000175000017500000001766711561721144015321 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxBottom* fx_bottom_new() { FxBottom* fxbottom = (FxBottom*)malloc(sizeof(FxBottom)); memset(fxbottom , 0 , sizeof(FxBottom)); return fxbottom; } static void fx_bottom_on_directsms_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxMain *fxmain = (FxMain*)data; FxDSMS *fxdsms = fx_dsms_new(fxmain); if(fxmain->user->carrierStatus == CARRIER_STATUS_DOWN){ fx_util_popup_warning(fxmain , SERVICE_DOWN_MESSAGE); return; } if(fx_conn_check_action(fxmain)) fx_dsms_initialize(fxdsms); } static void fx_bottom_on_pggroup_clicked(GtkWidget *widget , gpointer data) { FxMain *fxmain = (FxMain*)data; PGGroup *pg = fxmain->user->pggroup; FxTree *fxtree = fxmain->mainPanel; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))){ if(pg) gtk_widget_show(fxtree->pgScrollWindow); else gtk_widget_show(fxtree->noLabelScrollWindow); gtk_widget_hide(fxtree->scrollWindow); }else{ gtk_widget_hide(fxtree->pgScrollWindow); gtk_widget_hide(fxtree->noLabelScrollWindow); gtk_widget_show(fxtree->scrollWindow); } } static void fx_bottom_on_help_clicked(GtkWidget* UNUSED(widget) , gpointer UNUSED(data)) { show_about(); } void fx_bottom_initialize(FxMain* fxmain) { FxBottom *fxbottom = fx_bottom_new(); GtkWidget *icon; GdkPixbuf *pb; fxmain->bottomPanel = fxbottom; User *user = fxmain->user; GtkWidget *mainbox = fxmain->mainbox; fxbottom->toolbar = gtk_toolbar_new(); gtk_box_pack_start(GTK_BOX(mainbox) , fxbottom->toolbar , FALSE , FALSE , 0); icon = gtk_image_new_from_file(SKIN_DIR"options.png"); gtk_toolbar_append_item(GTK_TOOLBAR(fxbottom->toolbar) , NULL , _("Personal Settings") , NULL , icon , G_CALLBACK(fx_bottom_on_setting_clicked) , fxmain ); gtk_toolbar_set_style(GTK_TOOLBAR(fxbottom->toolbar) , GTK_TOOLBAR_ICONS); icon = gtk_image_new_from_file(SKIN_DIR"add.png"); gtk_toolbar_append_item(GTK_TOOLBAR(fxbottom->toolbar) , NULL , _("Add Buddy") , NULL , icon , G_CALLBACK(fx_bottom_on_addfriend_clicked) , fxmain); if(user->boundToMobile == BOUND_MOBILE_ENABLE){ pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"myselfsms.png" , 16 , 16 , NULL); icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxbottom->toolbar) , NULL , _("Send a message to myself") , NULL , icon , G_CALLBACK(fx_bottom_on_sendtome_clicked) , fxmain); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"groupsend.png" , 16 , 16 , NULL); icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxbottom->toolbar) , NULL , _("SMS to many") , NULL , icon , G_CALLBACK(fx_bottom_on_sendtomany_clicked) , fxmain); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"directsms.png" , 16 , 16 , NULL); icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxbottom->toolbar) , NULL , _("SMS directly") , NULL , icon , G_CALLBACK(fx_bottom_on_directsms_clicked) , fxmain); } pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"pggroup.png" , 16 , 16 , NULL); icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_element(GTK_TOOLBAR(fxbottom->toolbar) , GTK_TOOLBAR_CHILD_TOGGLEBUTTON , NULL , NULL , _("Fetion Group") , NULL , icon , G_CALLBACK(fx_bottom_on_pggroup_clicked) , fxmain); icon = gtk_image_new_from_file(SKIN_DIR"find.png"); gtk_toolbar_append_item(GTK_TOOLBAR(fxbottom->toolbar) , NULL , _("View information of any user (attribution etc)") , NULL , icon , G_CALLBACK(fx_bottom_on_lookup_clicked) , fxmain); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"home.png" , 16 , 16 , NULL); icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxbottom->toolbar) , NULL , _("Show OpenFetion About dialog") , NULL , icon , G_CALLBACK(fx_bottom_on_help_clicked) , NULL); } void fx_bottom_show(FxMain *fxmain) { FxBottom *fxbottom = fxmain->bottomPanel; gtk_widget_show_all(fxbottom->toolbar); } void fx_bottom_free(FxBottom* fxbottom) { free(fxbottom); } void fx_bottom_on_setting_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain *fxmain = (FxMain*)data; FxSet *fxset = fx_set_new(fxmain); fx_set_initialize(fxset); } void fx_bottom_on_sendtome_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain* fxmain = (FxMain*)data; FxMyself* fxmyself = fx_myself_new(fxmain); if(fxmain->user->carrierStatus == CARRIER_STATUS_DOWN){ fx_util_popup_warning(fxmain , SERVICE_DOWN_MESSAGE); return; } if(fx_conn_check_action(fxmain)){ fx_myself_initialize(fxmyself); } } void fx_bottom_on_sendtomany_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain* fxmain = (FxMain*)data; FxMany* fxmany = fx_many_new(fxmain); if(fxmain->user->carrierStatus == CARRIER_STATUS_DOWN){ fx_util_popup_warning(fxmain , SERVICE_DOWN_MESSAGE); return; } if(fx_conn_check_action(fxmain)){ fx_many_initialize(fxmany); } } void fx_bottom_on_addfriend_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain* fxmain = (FxMain*)data; FxAddbuddy *fxaddbuddy = fx_addbuddy_new(fxmain); if(fx_conn_check_action(fxmain)){ fx_addbuddy_initialize(fxaddbuddy); gtk_dialog_run(GTK_DIALOG(fxaddbuddy->dialog)); gtk_widget_destroy(fxaddbuddy->dialog); free(fxaddbuddy); } } void fx_bottom_on_lookup_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain* fxmain = (FxMain*)data; FxLookup* fxlookup = fx_lookup_new(fxmain); if(fx_conn_check_action(fxmain)){ fx_lookup_initialize(fxlookup); gtk_dialog_run(GTK_DIALOG(fxlookup->dialog)); gtk_widget_destroy(fxlookup->dialog); free(fxlookup); } } openfetion-2.2.1/src/fx_bottom.h0000644000175000017500000000563611561721144015317 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_BOTTOM_H #define FX_BOTTOM_H extern FxBottom* fx_bottom_new(); extern void fx_bottom_initialize(FxMain* fxmain); extern void fx_bottom_show(FxMain *fxmain); extern void fx_bottom_free(FxBottom* fxbottom); extern void fx_bottom_on_setting_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_bottom_on_sendtome_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_bottom_on_sendtomany_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_bottom_on_addfriend_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_bottom_on_lookup_clicked(GtkWidget* UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_chat.c0000644000175000017500000011035711561721144014722 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" #ifdef USE_INDICATE #include #include #include #endif static GStaticMutex mutex; static void fx_chat_on_tophone_clicked(GtkWidget* widget , gpointer data); static void fx_chat_on_close_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_chat_on_send_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_chat_on_history_clicked(GtkWidget* UNUSED(widget) , gpointer data); static gboolean fx_chat_on_key_pressed(GtkWidget* UNUSED(widget) , GdkEventKey* event , gpointer data); static void fx_chat_on_nudge_clicked(GtkWidget* UNUSED(widget) , gpointer data); static gboolean fx_chat_on_text_buffer_changed(GtkTextBuffer* buffer , gpointer data); FxChat* fx_chat_new(FxMain* fxmain , Conversation* conv) { FxChat* fxchat = (FxChat*)malloc(sizeof(FxChat)); memset(fxchat, 0, sizeof(FxChat)); fxchat->fxmain = fxmain; fxchat->conv = conv; fxchat->sendtophone = FALSE; return fxchat; } void fx_chat_add_message(FxChat* fxchat , const char* msg , const struct tm* datetime , int issendmsg, int issysback) { GtkTextChildAnchor *anchor; GtkTextIter iter; GtkWidget *pb; GtkTextBuffer *buffer; FxMain *fxmain; User *user; Contact *contact; gchar *usid; gchar text[4096]; gchar color[10]; gchar time[30]; gchar path[1024]; struct tm *now; unsigned int i = 0 , p = 0 , n = 0; fxmain = fxchat->fxmain; user = fxmain->user; contact = fxchat->conv->currentContact; if(issendmsg == 1) strcpy(color , "blue"); else strcpy(color , "red"); buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(fxchat->recv_text)); /* timeout alert msg */ if(issysback) { strftime(time, sizeof(time), "%H:%M:%S", datetime); snprintf(text ,sizeof(text) - 1, _("The message \"%s\" sent" " at [%s] send failed,please resend it"), time , msg); fx_chat_add_information(fxchat , text); return; } usid = fetion_sip_get_sid_by_sipuri(contact->sipuri); if(issendmsg == 0){ strftime(time, sizeof(time), "%H:%M:%S", datetime); snprintf(text, sizeof(text) - 1, _("%s says: (%s):\n"), contact->nickname, time); }else{ now = get_currenttime(); strftime(time, sizeof(time), "%H:%M:%S", now); snprintf(text, sizeof(text) - 1, _("%s says: (%s):\n"), user->nickname, time); fx_main_add_history(fxmain, user->nickname, contact->userId, msg, issendmsg); } g_free(usid); gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter , text , -1 , color , NULL); gchar *msgE = fx_util_replace_emotion((char*)msg); gchar *pos , num[4]; while(msgE[i] != '\0'){ if(msgE[i] == '#'){ pos = msgE + i + 1; if(strstr(pos , "#") != NULL){ n = strlen(pos) - strlen(strstr(pos , "#")); if(n == 1 || n == 2 ){ memset(num, 0, sizeof(num)); strncpy(num , pos , n); if(atoi(num) > 0 && atoi(num) < 53){ gtk_text_buffer_insert_with_tags_by_name(buffer , &iter, msgE + p , i - p , "lm10" , NULL); sprintf(path , SKIN_DIR"face_images/big_%s.gif" , num); pb = gtk_image_new_from_file(path); gtk_widget_show(pb); anchor = gtk_text_buffer_create_child_anchor(buffer , &iter); gtk_text_view_add_child_at_anchor(GTK_TEXT_VIEW(fxchat->recv_text) , pb , anchor); i += n + 2; p = i; continue; } } } } i ++; } if( p < strlen(msgE)){ gtk_text_buffer_insert_with_tags_by_name(buffer , &iter, msgE + p , strlen(msgE) - p , "lm10" , NULL); } gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); fxchat->mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark (buffer, fxchat->mark, &iter); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(fxchat->recv_text), fxchat->mark); } void fx_chat_add_information(FxChat* fxchat , const char* msg) { GtkTextIter iter; GtkTextBuffer *buffer; buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(fxchat->recv_text)); gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert(buffer , &iter , "" , -1); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, msg , -1 , "grey", "lm10" , "small" , NULL); gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); fxchat->mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark(buffer, fxchat->mark, &iter); gtk_text_view_scroll_mark_onscreen( GTK_TEXT_VIEW(fxchat->recv_text), fxchat->mark); } gboolean fx_chat_focus_in_func(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data) { FxChat *fxchat; FxMain *fxmain; FxList *ctlist; Config *config; Message *message; GdkPixbuf *pb; gchar *sipuri; gchar *sid; gchar path[128]; fxchat = (FxChat*)data; fxmain = fxchat->fxmain; ctlist = fxmain->mlist; config = fxmain->user->config; fxchat->hasFocus = CHAT_DIALOG_FOCUSED; if(fxchat->unreadMsgCount > 0){ fxchat->unreadMsgCount = 0; fx_chat_update_window(fxchat); #ifdef USE_INDICATE GSList *iterator = NULL; IndicateIndicator *indicator = NULL; gint count = 0; const gchar *id; gchar *sid; extern GSList *indicators; sid = fetion_sip_get_sid_by_sipuri(fxchat->conv->currentContact->sipuri); for (iterator = indicators; iterator; iterator = iterator->next, count ++) { indicator = (IndicateIndicator*)iterator->data; /* clear attention */ id = indicate_indicator_get_property(indicator, "sid"); if (strcmp(sid, id) == 0) { indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, ""); /* remove the indicators from the indicate server */ indicate_server_remove_indicator(fxmain->indserver, indicator); indicators = g_slist_remove(indicators, indicator); break; } } g_free(sid); #endif } if(!USE_STATUS_ICON(config)) return FALSE; if(list_empty(ctlist)){ /* if the message queue is empty,and the status icon is not blinking * and there`s no unread mesasge for the current chat window,do nothing */ if(!gtk_status_icon_get_blinking( GTK_STATUS_ICON(fxmain->trayIcon)) && fxchat->unreadMsgCount == 0) return FALSE; gtk_status_icon_set_blinking( GTK_STATUS_ICON(fxmain->trayIcon) , FALSE); g_signal_handler_disconnect(fxmain->trayIcon, fxmain->iconConnectId); fxmain->iconConnectId = g_signal_connect( G_OBJECT(fxmain->trayIcon) , "activate" , GTK_SIGNAL_FUNC(fx_main_tray_activate_func) , fxmain); fx_head_set_state_image(fxmain, fxmain->user->state); }else{ message = (Message*)(ctlist->next->data); sipuri = message->sipuri; sid = fetion_sip_get_sid_by_sipuri(sipuri); sprintf(path , "%s/%s.jpg" , config->iconPath , sid); g_free(sid); pb = gdk_pixbuf_new_from_file(path , NULL); if(!pb) pb = gdk_pixbuf_new_from_file(SKIN_DIR"online.svg" , NULL); gtk_status_icon_set_blinking( GTK_STATUS_ICON(fxmain->trayIcon) , TRUE); gtk_status_icon_set_from_pixbuf( GTK_STATUS_ICON(fxmain->trayIcon) , pb); g_signal_handler_disconnect(fxmain->trayIcon, fxmain->iconConnectId); fxmain->iconConnectId = g_signal_connect( G_OBJECT(fxmain->trayIcon) , "activate" , GTK_SIGNAL_FUNC(fx_main_message_func) , fxmain); g_object_unref(pb); } return FALSE; } gboolean fx_chat_focus_out_func(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data) { FxChat* fxchat = (FxChat*)data; fxchat->hasFocus = CHAT_DIALOG_NOT_FOCUSED; return FALSE; } void fx_chat_bind(FxChat* fxchat) { FxMain *fxmain; Config *config; gchar text[128]; GdkPixbuf *pixbuf; fxmain = fxchat->fxmain; config = fxmain->user->config; sprintf(text , "%s/%s.jpg", config->iconPath, fxchat->conv->currentContact->sId); pixbuf = gdk_pixbuf_new_from_file_at_size( text , 30 , 30 , NULL); if(pixbuf){ gtk_image_set_from_pixbuf( GTK_IMAGE(fxchat->headimage), pixbuf); gtk_window_set_icon( GTK_WINDOW(fxchat->dialog), pixbuf); g_object_unref(pixbuf); } } static void *get_contact_info(void *data) { FxChat *fxchat = (FxChat*)data; FxProfile *fxprofile; Contact *contact; fxprofile = fx_profile_new(fxchat->fxmain, fxchat->conv->currentContact->userId); gdk_threads_enter(); fx_profile_initialize(fxprofile); gdk_threads_leave(); contact = fx_profile_fetch(fxprofile); if(!contact || strlen(contact->province) == 0) contact = fetion_contact_get_contact_info( fxchat->fxmain->user, fxchat->conv->currentContact->userId); gdk_threads_enter(); fx_profile_bind(fxprofile, contact); gtk_dialog_run(GTK_DIALOG(fxprofile->dialog)); gtk_widget_destroy(fxprofile->dialog); gdk_threads_leave(); free(fxprofile); return NULL; } static void fx_chat_name_box_func(GtkWidget *UNUSED(widget) , GdkEventButton *event , gpointer data) { FxChat *fxchat; gchar *name; gchar *sid; gchar nametext[1024]; Contact *contact; fxchat = (FxChat*)data; contact = fxchat->conv->currentContact; name = (contact->localname == NULL || strlen(contact->localname) == 0) ? contact->nickname : contact->localname; sid = fetion_sip_get_sid_by_sipuri(contact->sipuri); switch(event->type){ case GDK_ENTER_NOTIFY : snprintf(nametext, 1023, "%s(%s)", g_markup_escape_text(name, -1), sid); g_free(sid); gtk_label_set_markup(GTK_LABEL(fxchat->name_label) , nametext); break; case GDK_LEAVE_NOTIFY : snprintf(nametext, 1023, "%s(%s)", g_markup_escape_text(name, -1), sid); g_free(sid); gtk_label_set_markup(GTK_LABEL(fxchat->name_label) , nametext); break; case GDK_BUTTON_PRESS : g_thread_create(get_contact_info, fxchat, FALSE, NULL); break; default: break; } } void fx_chat_on_emotion_clicked(GtkWidget *widget , gpointer data) { FxChat *fxchat = (FxChat*)data; FxEmotion *fxemotion = NULL; int x , y , ex , ey , root_x , root_y; gtk_widget_translate_coordinates(widget , fxchat->dialog , 0 , 0 , &ex , &ey ); gtk_window_get_position(GTK_WINDOW(fxchat->dialog) , &root_x , &root_y); x = root_x + ex + 3; y = root_y + ey + 46; fxemotion = fx_emotion_new(fxchat); fx_emotion_initialize(fxemotion , x , y); } static gboolean key_press_func(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data) { FxChat *fxchat; if(event->keyval == GDK_w){ fxchat = (FxChat*)data; if(event->state & GDK_CONTROL_MASK){ gtk_widget_destroy(fxchat->dialog); return TRUE; }else{ return FALSE; } } return FALSE; } void fx_chat_initialize(FxChat* fxchat) { GtkWidget *vbox; GtkWidget *halign; GtkWidget *halign1; GtkWidget *tophone_icon; GtkWidget *hbox; GtkWidget *lvbox; GtkWidget *rvbox; GtkWidget *history_icon; GtkWidget *nouge_icon; GtkWidget *label; GtkWidget *action_area; GtkWidget *send_button; GtkWidget *close_button; GtkWidget *frame; GtkWidget *img; GdkPixbuf *pb; gchar nametext[512]; gchar portraitPath[512]; gchar *sid; gchar *name; Contact *contact; contact = fxchat->conv->currentContact; FxMain *fxmain = fxchat->fxmain; User *user = fxmain->user; Config *config = user->config; fxchat->dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_modal(GTK_WINDOW(fxchat->dialog) , FALSE); if(config->closeFetionShow == CLOSE_FETION_SHOW_DISABLE) gtk_window_set_default_size(GTK_WINDOW(fxchat->dialog) , 600 , 430); else gtk_window_set_default_size(GTK_WINDOW(fxchat->dialog) , 550 , 430); gtk_widget_set_size_request(fxchat->dialog, 550, 430); gtk_container_set_border_width(GTK_CONTAINER(fxchat->dialog) , 10); fx_chat_update_window(fxchat); g_signal_connect(fxchat->dialog , "destroy" , G_CALLBACK(fx_chat_destroy) , fxchat); vbox = gtk_vbox_new(FALSE , 2); hbox = gtk_hbox_new(FALSE , 6); gtk_container_add(GTK_CONTAINER(fxchat->dialog) , vbox); action_area = gtk_hbox_new(FALSE , 0); fxchat->headbox = gtk_hbox_new(FALSE, 5); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 40 , 40 , NULL); gtk_window_set_icon(GTK_WINDOW(fxchat->dialog), pb); fxchat->headimage = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_box_pack_start(GTK_BOX(fxchat->headbox), fxchat->headimage, FALSE, FALSE, 0); fxchat->name_label = gtk_label_new(NULL); sid = fetion_sip_get_sid_by_sipuri(contact->sipuri); name = (contact->localname == NULL || strlen(contact->localname) == 0) ? contact->nickname : contact->localname; sprintf(nametext , "%s(%s)" , g_markup_escape_text(name, -1) , sid); free(sid); gtk_label_set_markup(GTK_LABEL(fxchat->name_label) , nametext); gtk_label_set_justify(GTK_LABEL(fxchat->name_label) , GTK_JUSTIFY_LEFT); fxchat->name_box = gtk_event_box_new(); g_signal_connect(fxchat->name_box , "enter-notify-event" , GTK_SIGNAL_FUNC(fx_chat_name_box_func) , fxchat); g_signal_connect(fxchat->name_box , "leave-notify-event" , GTK_SIGNAL_FUNC(fx_chat_name_box_func) , fxchat); g_signal_connect(fxchat->name_box , "button-press-event" , GTK_SIGNAL_FUNC(fx_chat_name_box_func) , fxchat); gtk_container_add(GTK_CONTAINER(fxchat->name_box) , fxchat->name_label); GtkWidget *vbox1 = gtk_vbox_new(TRUE, 0); GtkWidget *hbox1 = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(fxchat->headbox), vbox1, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(vbox1), hbox1, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox1), fxchat->name_box, FALSE, FALSE, 0); fxchat->input_label = gtk_label_new(NULL); gtk_box_pack_start(GTK_BOX(hbox1), fxchat->input_label, FALSE, FALSE, 10); snprintf(nametext , sizeof(nametext) - 1 , "%s" , contact->impression); escape_impression(nametext); fxchat->impre_label = gtk_label_new(nametext); gtk_widget_set_size_request(fxchat->impre_label, 450, 20); gtk_misc_set_alignment(GTK_MISC(fxchat->impre_label), 0, 0); gtk_label_set_justify(GTK_LABEL(fxchat->impre_label) , GTK_JUSTIFY_LEFT); gtk_box_pack_start(GTK_BOX(vbox1), fxchat->impre_label, FALSE, FALSE, 0); halign = gtk_alignment_new( 0 , 0 , 0 , 0); gtk_container_add(GTK_CONTAINER(halign) , fxchat->headbox); gtk_box_pack_start(GTK_BOX(vbox) , halign , FALSE , FALSE , 5); gtk_box_pack_start(GTK_BOX(vbox) , hbox , TRUE , TRUE , 0); lvbox = gtk_vbox_new(FALSE , 0); rvbox = gtk_vbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(hbox) , lvbox , TRUE , TRUE , 0); gtk_box_pack_start(GTK_BOX(hbox) , rvbox , FALSE , FALSE , 0); fxchat->recv_scroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(lvbox) , fxchat->recv_scroll , TRUE , TRUE , 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxchat->recv_scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(fxchat->recv_scroll) , GTK_SHADOW_ETCHED_IN); fxchat->recv_text = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxchat->recv_text) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxchat->recv_text) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxchat->recv_text) , FALSE); gtk_container_add(GTK_CONTAINER(fxchat->recv_scroll) , fxchat->recv_text); fxchat->recv_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxchat->recv_text)); gtk_text_buffer_create_tag(fxchat->recv_buffer , "blue" , "foreground" , "#639900" , NULL); gtk_text_buffer_create_tag(fxchat->recv_buffer , "grey" , "foreground" , "#808080" , NULL); gtk_text_buffer_create_tag(fxchat->recv_buffer , "green" , "foreground" , "green" , NULL); gtk_text_buffer_create_tag(fxchat->recv_buffer , "red" , "foreground" , "#0088bf" , NULL); gtk_text_buffer_create_tag(fxchat->recv_buffer , "lm10" , "left_margin" , 10 , NULL); gtk_text_buffer_create_tag(fxchat->recv_buffer , "small" , "left_margin" , 5 , NULL); gtk_text_buffer_get_end_iter(fxchat->recv_buffer , &(fxchat->recv_iter)); gtk_text_buffer_create_mark(fxchat->recv_buffer , "scroll" , &(fxchat->recv_iter) , FALSE); /*toolbar begin*/ fxchat->toolbar = gtk_toolbar_new(); gtk_toolbar_set_style(GTK_TOOLBAR(fxchat->toolbar) , GTK_TOOLBAR_ICONS); gtk_box_pack_start(GTK_BOX(lvbox) , fxchat->toolbar , FALSE , FALSE , 0); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"emotion.png" , 16 , 16 , NULL); nouge_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); fxchat->nouge = gtk_toolbar_append_item(GTK_TOOLBAR(fxchat->toolbar) , _("Emotion") , "" , NULL , nouge_icon , G_CALLBACK(fx_chat_on_emotion_clicked) , fxchat ); gtk_toolbar_append_space(GTK_TOOLBAR(fxchat->toolbar)); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"phone.png" , 16 , 16 , NULL); tophone_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); fxchat->tophone = gtk_toolbar_append_element(GTK_TOOLBAR(fxchat->toolbar) , GTK_TOOLBAR_CHILD_TOGGLEBUTTON , NULL , _("Contact's cell phone") , _("Mesage will be send to Contact's cell phone in long SMS format") , NULL , tophone_icon , G_CALLBACK(fx_chat_on_tophone_clicked) , fxchat ); gtk_toolbar_append_space(GTK_TOOLBAR(fxchat->toolbar)); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"history.png" , 16 , 16 , NULL); history_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); fxchat->historybutton = gtk_toolbar_append_item(GTK_TOOLBAR(fxchat->toolbar) , _("Chat logs") , _("View chat logs") , NULL , history_icon , G_CALLBACK(fx_chat_on_history_clicked) ,fxchat ); gtk_toolbar_append_space(GTK_TOOLBAR(fxchat->toolbar)); nouge_icon = gtk_image_new_from_file(SKIN_DIR"nudge.png"); fxchat->nouge = gtk_toolbar_append_item(GTK_TOOLBAR(fxchat->toolbar) , _("Screen jitter") , _("Send a screen jitter") , NULL , nouge_icon , G_CALLBACK(fx_chat_on_nudge_clicked) , fxchat ); gtk_toolbar_append_space(GTK_TOOLBAR(fxchat->toolbar)); label = gtk_label_new(_("total 180 character left")); fxchat->countLabel = gtk_label_new(""); gtk_label_set_markup(GTK_LABEL(fxchat->countLabel) , _("[180] characters")); gtk_container_add(GTK_CONTAINER(fxchat->toolbar) , label); gtk_container_add(GTK_CONTAINER(fxchat->toolbar) , fxchat->countLabel); /*toolbar end*/ fxchat->send_scroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(lvbox) , fxchat->send_scroll , FALSE , FALSE , 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxchat->send_scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(fxchat->send_scroll) , GTK_SHADOW_ETCHED_IN); fxchat->send_text = gtk_text_view_new(); gtk_widget_set_usize(fxchat->send_text , 0 , 100); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxchat->send_text) , GTK_WRAP_WORD_CHAR); g_signal_connect(fxchat->send_text , "key_press_event" , G_CALLBACK(fx_chat_on_key_pressed) , fxchat); gtk_container_add(GTK_CONTAINER(fxchat->send_scroll) , fxchat->send_text); fxchat->send_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxchat->send_text)); gtk_text_buffer_get_iter_at_offset(fxchat->send_buffer , &(fxchat->send_iter) , 0); halign1 = gtk_alignment_new( 1 , 0 , 0 , 0); gtk_container_add(GTK_CONTAINER(halign1) , action_area); gtk_box_pack_start(GTK_BOX(vbox) , halign1 , FALSE , FALSE , 0); close_button = gtk_button_new_with_label(_("Close")); gtk_widget_set_usize(close_button , 100 , 30); gtk_box_pack_start(GTK_BOX(action_area) , close_button , FALSE , TRUE , 2); g_signal_connect(close_button , "clicked" , G_CALLBACK(fx_chat_on_close_clicked) , fxchat); send_button = gtk_button_new_with_label(_("Send")); gtk_widget_set_usize(send_button , 100 , 30); gtk_box_pack_start(GTK_BOX(action_area) , send_button , FALSE , TRUE , 2); g_signal_connect(send_button , "clicked" , G_CALLBACK(fx_chat_on_send_clicked) , fxchat); gtk_window_set_position(GTK_WINDOW(fxchat->dialog) , GTK_WIN_POS_CENTER); gint x,y; gtk_window_get_position(GTK_WINDOW(fxchat->dialog), &x, &y); gtk_window_move(GTK_WINDOW(fxchat->dialog), x + rand()%100, y + rand()%100); //gtk_window_set_opacity(GTK_WINDOW(fxchat->dialog) , 0.9); fx_chat_bind(fxchat); g_signal_connect(fxchat->dialog , "focus-in-event" , GTK_SIGNAL_FUNC(fx_chat_focus_in_func) , fxchat ); g_signal_connect(fxchat->dialog , "focus-out-event" , GTK_SIGNAL_FUNC(fx_chat_focus_out_func) , fxchat ); g_signal_connect(fxchat->send_buffer , "changed" , G_CALLBACK(fx_chat_on_text_buffer_changed) , fxchat); g_signal_connect(fxchat->dialog , "key-press-event" , G_CALLBACK(key_press_func) , fxchat); /*right box */ if(config->closeFetionShow == CLOSE_FETION_SHOW_DISABLE){ frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame) , GTK_SHADOW_ETCHED_IN); gtk_widget_set_usize(frame , 160 , 160); sprintf(portraitPath , "%s/%s.jpg" , config->iconPath , contact->sId); pb = gdk_pixbuf_new_from_file_at_size(portraitPath , 140 , 140 , NULL); if(!pb) pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 140 , 140 , NULL); img = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_container_add(GTK_CONTAINER(frame) , img); gtk_box_pack_start(GTK_BOX(rvbox) , frame , FALSE , FALSE , 0); GtkWidget *spliter = gtk_label_new(NULL); gtk_box_pack_start(GTK_BOX(rvbox) , spliter , TRUE , TRUE , 0); frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame) , GTK_SHADOW_ETCHED_IN); gtk_widget_set_usize(frame , 160 , 160); sprintf(portraitPath , "%s/%s.jpg" , config->iconPath , user->sId); pb = gdk_pixbuf_new_from_file_at_size(portraitPath , 140 , 140 , NULL); if(!pb) pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 140 , 140 , NULL); img = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_container_add(GTK_CONTAINER(frame) , img); gtk_box_pack_start(GTK_BOX(rvbox) , frame , FALSE , FALSE , 0); } GTK_WIDGET_SET_FLAGS(fxchat->send_text, GTK_CAN_FOCUS); gtk_widget_grab_focus(fxchat->send_text); gtk_widget_show_all (vbox); gtk_widget_show(fxchat->dialog); } void fx_chat_free(FxChat* fxchat) { if(fxchat) free(fxchat->conv); free(fxchat); } void fx_chat_destroy(GtkWidget* UNUSED(widget) , gpointer data) { FxChat* fxchat = (FxChat*)data; fx_list_remove_chat_by_sipuri(fxchat->fxmain->clist , fxchat->conv->currentContact->sipuri); fx_chat_free(fxchat); } void* fx_chat_send_message_thread(void *data) { FxChat *fxchat; Conversation *conv; GtkTextIter begin; GtkTextIter end; gchar *text = NULL; struct tm *now = NULL; ThreadArgs *args = NULL; FxList *fxlist = NULL; fxchat = (FxChat*)data; conv = fxchat->conv; gtk_text_buffer_get_start_iter(fxchat->send_buffer , &begin); gtk_text_buffer_get_end_iter(fxchat->send_buffer , &end); text = gtk_text_buffer_get_text(fxchat->send_buffer , &begin , &end , TRUE); if(*text == '\0'){ fx_chat_add_information(fxchat, _("Empty messages are not allowed.")); return NULL; } now = get_currenttime(); gdk_threads_enter(); fx_chat_add_message(fxchat , text , now , 1 , 0); gtk_text_buffer_delete(fxchat->send_buffer , &begin , &end); gdk_threads_leave(); if(fetion_conversation_invite_friend(conv) > 0){ fx_conn_append(conv->currentSip->tcp); args = (ThreadArgs*)malloc(sizeof(ThreadArgs)); args->fxmain = fxchat->fxmain; args->sip = conv->currentSip; fxlist = fx_list_new(conv->currentSip); fx_list_append(fxchat->fxmain->slist , fxlist); g_thread_create(fx_main_listen_thread_func , args , FALSE , NULL); fetion_conversation_send_sms(conv , text); }else{ fx_chat_add_information(fxchat, _("Message send failed,Unknown Error")); } return NULL; } void fx_chat_send_message(FxChat* fxchat) { Conversation *conv; Contact *contact; User *user; GtkTextIter begin; GtkTextIter end; gchar *text; FxCode *fxcode; gchar reason[512]; gchar tips[512]; const gchar *code = NULL; gint ret; gint daycount; gint monthcount; if(!fx_conn_check_action(fxchat->fxmain)) return; conv = fxchat->conv; contact = conv->currentContact; user = fxchat->fxmain->user; gtk_text_buffer_get_start_iter(fxchat->send_buffer , &begin); gtk_text_buffer_get_end_iter(fxchat->send_buffer , &end); if(!contact) return; text = gtk_text_buffer_get_text(fxchat->send_buffer, &begin, &end, TRUE); if(*text == '\0') return; /* check whether 'send to phone' button is clicked , * if true , just send to phone and return */ if(fxchat->sendtophone) { /* show message sent,and truncate the send text area */ text = gtk_text_buffer_get_text(fxchat->send_buffer, &begin, &end, TRUE); if(*text == '\0'){ fx_chat_add_information(fxchat, _("Empty messages are not allowed.")); return; } if(user->boundToMobile == BOUND_MOBILE_DISABLE){ user->verification = fetion_verification_new(); send: generate_pic_code(user); if(user->smsDayLimit == user->smsDayCount){ fx_chat_add_information(fxchat, _("Sorry, you have reached" " the quota of free SMS today, SMS" " messages cannot be sent any more today.")); return; } sprintf(reason , _("%d free SMS messages can be sent(include this " "one). Free SMS messages: %d per month") , user->smsDayLimit - user->smsMonthCount , user->smsMonthLimit ); sprintf(tips, _("tips:if you wnat to send more" " free sms,please bound your mobileno\n" "at once ,no authentication code needed any more.")); fxcode = fx_code_new(fxchat->fxmain , reason , tips , CODE_NOT_ERROR); fx_code_initialize(fxcode); ret = gtk_dialog_run(GTK_DIALOG(fxcode->dialog)); if(ret == GTK_RESPONSE_OK){ code = gtk_entry_get_text(GTK_ENTRY(fxcode->codeentry)); user->verification->code = (char*)malloc(strlen(code) + 1); memset(user->verification->code, 0, strlen(code) + 1); strcpy(user->verification->code , code); gtk_widget_destroy(fxcode->dialog); }else{ gtk_widget_destroy(fxcode->dialog); return; } if(fetion_conversation_send_sms_to_phone_with_reply(conv , text , &daycount , &monthcount) == -1){ goto send; }else{ fetion_verification_free(user->verification); user->verification = NULL; } }else{ fetion_conversation_send_sms_to_phone_with_reply(conv , text , &daycount , &monthcount); } fx_chat_add_message(fxchat , text , NULL , 1 , 0); sprintf(tips , _("Message sent successfully." " You have sent %d SMS, and %d left.") , daycount , user->smsDayLimit - daycount); fx_chat_add_information(fxchat , tips); gtk_text_buffer_delete(fxchat->send_buffer , &begin , &end); return; } /* if user`s online and has not started a thread for chating , * just created a thread for listening ,and send message * throuch the chat channel */ if(contact->state > 0 && conv->currentSip == NULL){ conv->currentSip = fx_list_find_sip_by_sipuri( fxchat->fxmain->slist , contact->sipuri); if(!conv->currentSip){ debug_info("CREATE A NEW MESSAGE THREAD"); g_thread_create(fx_chat_send_message_thread, fxchat, FALSE, NULL); return; } debug_info("MESSAGE THREAD ALREADY EXIST"); } /* show message sent,and truncate the send text area */ fx_chat_add_message(fxchat , text , NULL , 1 , 0); gtk_text_buffer_delete(fxchat->send_buffer , &begin , &end); fetion_conversation_send_sms(conv , text); } void* fx_chat_send_nudge_thread(void* data) { FxChat *fxchat; Conversation *conv; ThreadArgs *args = NULL; FxList *fxlist = NULL; fxchat = (FxChat*)data; conv = fxchat->conv; g_static_mutex_lock(&mutex); if(fetion_conversation_invite_friend(conv) > 0){ fx_conn_append(conv->currentSip->tcp); args = (ThreadArgs*)malloc(sizeof(ThreadArgs)); args->fxmain = fxchat->fxmain; args->sip = conv->currentSip; fxlist = fx_list_new(conv->currentSip); fx_list_append(fxchat->fxmain->slist , fxlist); gdk_threads_enter(); g_thread_create(fx_main_listen_thread_func , args , FALSE , NULL); fetion_conversation_send_nudge(conv); gdk_threads_leave(); } g_static_mutex_unlock(&mutex); return NULL; } static void fx_chat_on_nudge_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxChat *fxchat; Conversation *conv; Contact *contact; fxchat = (FxChat*)data; conv = fxchat->conv; contact = conv->currentContact; if(!fx_conn_check_action(fxchat->fxmain)) return; if(contact->state <= 0){ fx_chat_add_information(fxchat, _("Contact is not online. Cannot send screen jitter")); return; } if(contact->state > 0 && conv->currentSip == NULL){ conv->currentSip = fx_list_find_sip_by_sipuri( fxchat->fxmain->slist , contact->sipuri); if(!conv->currentSip){ debug_info("CREATE A NEW MESSAGE THREAD"); g_thread_create(fx_chat_send_nudge_thread , fxchat , FALSE , NULL); fx_chat_nudge(fxchat); return; } debug_info("MESSAGE THREAD ALREADY EXIST"); } fetion_conversation_send_nudge(conv); fx_chat_nudge(fxchat); } void fx_chat_nudge(FxChat* fxchat) { int x , y , i; gtk_window_get_position(GTK_WINDOW(fxchat->dialog) , &x , &y); for(i = 0 ; i < 4 ; i++){ g_usleep(70000); gtk_window_move(GTK_WINDOW(fxchat->dialog) , x + 7 , y + 7); update(); g_usleep(70000); gtk_window_move(GTK_WINDOW(fxchat->dialog) , x - 7 , y - 7); update(); } } void fx_chat_nudge_in_thread(FxChat* fxchat) { int x , y , i; gdk_threads_enter(); gtk_window_get_position(GTK_WINDOW(fxchat->dialog) , &x , &y); gdk_threads_leave(); for(i = 0 ; i < 4 ; i++){ g_usleep(100000); gdk_threads_enter(); gtk_window_move(GTK_WINDOW(fxchat->dialog) , x + 7 , y + 7); update(); gdk_threads_leave(); g_usleep(100000); gdk_threads_enter(); gtk_window_move(GTK_WINDOW(fxchat->dialog) , x - 7 , y - 7); update(); gdk_threads_leave(); } } static void fx_chat_on_tophone_clicked(GtkWidget* widget , gpointer data) { GtkToggleButton *btn; FxChat *fxchat; User *user; gchar text[1024]; btn = GTK_TOGGLE_BUTTON(widget); fxchat = (FxChat*)data; user = fxchat->fxmain->user; if(gtk_toggle_button_get_active(btn)){ fxchat->sendtophone = TRUE; if(user->boundToMobile == BOUND_MOBILE_DISABLE){ memset(text, 0, sizeof(text)); if(user->smsDayLimit == user->smsDayCount || user->smsMonthLimit == user->smsMonthCount){ strcpy(text , _("Run out of your quota," " you can still send IM mesages." " If want to send more free SMS," " bind you cell phone number.")); gtk_widget_set_sensitive(fxchat->send_text , FALSE); }else{ sprintf(text , _("Mesage will be sent to " "contact's cell phone. You have" " %d free SMS left. If want to send" " more free SMS, bind your cell phone,please.") , user->smsDayLimit - user->smsDayCount); } fx_chat_add_information(fxchat , text); }else{ sprintf(text , _("Messages will be sent to you phone as long SMS " "messages. You have sent %d, and %d left.") , user->smsDayCount , user->smsDayLimit - user->smsDayCount); fx_chat_add_information(fxchat , text); } }else{ fxchat->sendtophone = FALSE; gtk_widget_set_sensitive(fxchat->send_text , TRUE); fx_chat_add_information(fxchat , _("Message will be sent to contact's fetion")); } } static void fx_chat_on_close_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxChat* fxchat = (FxChat*)data; gtk_widget_destroy(fxchat->dialog); } static void fx_chat_on_send_clicked(GtkWidget* UNUSED(widget) , gpointer data) { fx_chat_send_message((FxChat*)data); } static void fx_chat_on_history_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxChat *fxchat; Conversation *conv; Contact *contact; FxHistory *fxhistory; fxchat = (FxChat*)data; conv = fxchat->conv; contact = conv->currentContact; fxhistory = fx_history_new(fxchat->fxmain, contact->userId , contact->nickname); fx_history_initialize(fxhistory); gtk_dialog_run(GTK_DIALOG(fxhistory->dialog)); gtk_widget_destroy(fxhistory->dialog); free(fxhistory); } static gboolean fx_chat_on_key_pressed(GtkWidget* UNUSED(widget) , GdkEventKey* event , gpointer data) { FxChat *fxchat = NULL; Config *config = NULL; if(event->keyval == GDK_Return || event->keyval == GDK_ISO_Enter || event->keyval == GDK_KP_Enter){ fxchat = (FxChat*)data; config = fxchat->fxmain->user->config; if(config->sendMode == SEND_MODE_ENTER){ if(event->state & GDK_CONTROL_MASK || event->state & GDK_SHIFT_MASK){ return FALSE; }else{ if (gtk_im_context_filter_keypress (GTK_TEXT_VIEW(fxchat->send_text)->im_context, event)) { GTK_TEXT_VIEW (fxchat->send_text)->need_im_reset = TRUE; return TRUE; } fx_chat_send_message(fxchat); return TRUE; } }else{ if(event->state & GDK_CONTROL_MASK) { fx_chat_send_message(fxchat); return TRUE; }else{ return FALSE; } } } return FALSE; } static gboolean fx_chat_on_text_buffer_changed(GtkTextBuffer* buffer , gpointer data) { FxChat* fxchat = (FxChat*)data; GtkTextIter startIter; GtkTextIter endIter; gchar text[48]; const gchar *res = NULL; gint count; count = gtk_text_buffer_get_char_count(buffer); if(count <= 180){ sprintf(text , _("[%d] character") , 180 - count); gtk_label_set_markup(GTK_LABEL(fxchat->countLabel) , text); }else{ gtk_text_buffer_get_start_iter(buffer , &startIter); gtk_text_buffer_get_iter_at_offset(buffer , &endIter , 180); res = gtk_text_buffer_get_text(buffer , &startIter , &endIter , 180); gtk_text_buffer_set_text(buffer , res , strlen(res)); } return FALSE; } void fx_chat_update_window(FxChat *fxchat) { Contact *cont; char markup[1024]; char *name; cont = fxchat->conv->currentContact; name = (cont->localname == NULL || strlen(cont->localname) == 0) ? cont->nickname : cont->localname; if(fxchat->unreadMsgCount > 0) sprintf(markup, _("(%d)unread [%s]"), fxchat->unreadMsgCount, name); else snprintf(markup , sizeof(markup) - 1, _("Chatting with [%s]"), name); gtk_window_set_title(GTK_WINDOW(fxchat->dialog), markup); } void fx_chat_set_input(FxChat *fxchat) { gtk_label_set_markup(GTK_LABEL(fxchat->input_label), "正在输入..."); } void fx_chat_clear_input(FxChat *fxchat) { if(GTK_IS_LABEL(fxchat->input_label)) gtk_label_set_text(GTK_LABEL(fxchat->input_label), NULL); } openfetion-2.2.1/src/fx_chat.h0000644000175000017500000000602111561721144014717 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_CHAT_H #define FX_CHAT_H extern FxChat* fx_chat_new(FxMain *fxmain , Conversation *conv); extern void fx_chat_add_message(FxChat *fxchat , const char *msg , const struct tm *datetime , int issendmsg, int issysback); extern void fx_chat_add_information(FxChat *fxchat , const char *msg); extern void fx_chat_initialize(FxChat *fxchat); extern void fx_chat_free(FxChat *fxchat); extern void fx_chat_destroy(GtkWidget *UNUSED(widget) , gpointer data); extern void fx_chat_send_message(FxChat *fxchat); extern void fx_chat_nudge(FxChat *fxchat); extern void fx_chat_nudge_in_thread(FxChat *fxchat); extern void fx_chat_update_window(FxChat *fxchat); extern void fx_chat_set_input(FxChat *fxchat); extern void fx_chat_clear_input(FxChat *fxchat); #endif openfetion-2.2.1/src/fx_cli.c0000644000175000017500000002002311561721144014540 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include #include #define NOLEN 128 #define MOBILENO_LEN 11 int cli_to_myself = 0; int cli_to_other = 0; int cli_to_phone = 0; int cli_get_info = 0; char from_no[NOLEN]; char to_no[NOLEN]; char msg_body[BUFLEN]; static char *generate_body(); static char* convert_xml(xmlChar* in); static int usage() { fprintf(stderr, "%s Copyright: levin108\n", FETION_NAME); fprintf(stderr, "\nWARNING: THERE IS NO WARRANTY FOR Openfetion. USE AT YOUR OWN RISK!!!\n"); fprintf(stderr, "\nGeneric Options:\n"); fprintf(stderr, "-h/-H\t\tShow this message.\n"); fprintf(stderr, "-f from_number\tspecify which number you will use to send a message.\n"); fprintf(stderr, "-t to_nomber\tspecify which number you will send a message to.\n"); fprintf(stderr, "-d msg_body\t\tmessage you will send\n"); fprintf(stderr, "-m\t\tsend a message to myself\n"); fprintf(stderr, "-p\t\tsend a message to the phone\n"); fprintf(stderr, "-g mobile_no\tget information of mobile_no\n"); fprintf(stderr, "\neg.\n"); fprintf(stderr, "send \"hello world\" to 18788888888:\n"); fprintf(stderr, "openfetion -f 15288888888 -t 1878888888 -d \"hello world\"\n\n"); fprintf(stderr, "send \"hello world\" to yourself:\n"); fprintf(stderr, "openfetion -m -f 15288888888 -d \"hello world\"\n\n"); fprintf(stderr, "get information of 18788888888:\n"); fprintf(stderr, "openfetion -f 15288888888 -g 1878888888\n"); fprintf(stderr, "\nhome page:\t http://code.google.com/p/ofetion/\n"); fprintf(stderr, "bug report:\t http://code.google.com/p/ofetion/issues/list\n"); fprintf(stderr, "author's home page: http://basiccoder.com\n\n"); return 1; } int fx_cli_opt(int argc, char **argv) { char ch; memset(from_no, 0, sizeof(from_no)); memset(to_no, 0, sizeof(to_no)); while((ch = getopt(argc, argv, "d:f:g:hHmpt:")) != -1) { switch(ch) { case 'd': strcpy(msg_body, optarg); break; case 'f': strcpy(from_no, optarg); break; case 'g': strcpy(to_no, optarg); cli_get_info = 1; break; case 'h':case 'H': return usage(); case 'm': cli_to_myself = 1; break; case 'p': cli_to_phone = 1; break; case 't': cli_to_other = 1; strcpy(to_no, optarg); break; default: break; } } return 0; } int fx_cli_exec() { int serv_fifo; int cli_fifo; unsigned int n; char *xml_body; struct fifo_resp resp; char client_fifo_file[BUFLEN]; char server_fifo_file[BUFLEN]; char buf[BUFLEN]; struct fifo_mesg *mesg; if(strlen(from_no) != 11) return usage(); if(cli_to_myself && *msg_body == '\0') return usage(); if(cli_to_other && *msg_body == '\0') return usage(); if(!cli_to_other && !cli_to_myself) return usage(); if((cli_to_myself || cli_to_phone) && cli_get_info) { debug_error("couldn't send a message when getting information"); return 1; } if(to_no[0] != '\0' && strlen(to_no) != 11) { debug_error("mobile number error"); return 1; } snprintf(client_fifo_file, sizeof(client_fifo_file) - 1, OPENFETION_CLIENT_FIFO, getpid()); snprintf(server_fifo_file, sizeof(server_fifo_file) - 1, OPENFETION_FIFO_FILE, from_no); if(mkfifo(client_fifo_file, FIFO_FILE_MODE) == -1) { debug_error("create fifo %s:%s", client_fifo_file, strerror(errno)); return 1; } if((serv_fifo = open(server_fifo_file, O_WRONLY, 0)) == -1) { debug_error("open fifo %s:%s", client_fifo_file, server_fifo_file); unlink(client_fifo_file); return 1; } mesg = (struct fifo_mesg*)buf; xml_body = generate_body(); if(cli_get_info) mesg->type = CLI_GET_INFORMATION; else mesg->type = CLI_SEND_MESSAGE; mesg->length = strlen(xml_body); mesg->pid = getpid(); memcpy(buf + sizeof(struct fifo_mesg), xml_body, strlen(xml_body)); free(xml_body); n = write(serv_fifo, buf, mesg->length + FIFO_HEAD_SIZE); if(n != mesg->length + FIFO_HEAD_SIZE) { debug_error("write %d bytes,but %d bytes expected", n, mesg->length + FIFO_HEAD_SIZE); unlink(client_fifo_file); close(serv_fifo); return 1; } if((cli_fifo = open(client_fifo_file, O_RDONLY, 0)) == -1) { debug_error("open fifo %s:%s\n", client_fifo_file, strerror(errno)); unlink(client_fifo_file); close(serv_fifo); return 1; } n = read(cli_fifo, &resp, RESP_HEAD_SIZE); if(n != RESP_HEAD_SIZE) { debug_error("read %d bytes,but %d bytes expected", n, RESP_HEAD_SIZE); unlink(client_fifo_file); close(serv_fifo); close(cli_fifo); return 1; } memset(buf, 0, sizeof(buf)); n = read(cli_fifo, buf, resp.length); if(n != resp.length) { unlink(client_fifo_file); debug_error("read %d bytes,but %d bytes expected", n, resp.length); close(serv_fifo); close(cli_fifo); return 1; } unlink(client_fifo_file); close(serv_fifo); close(cli_fifo); if(resp.code == CLI_EXEC_OK){ printf("[\e[32m\e[1mOK\e[0m] %s\n", buf); return 0; }else{ printf("[\e[31m\e[1mFAIL\e[0m] %s\n", buf); return 1; } return 0; } static char *generate_body() { const char *xml = ""; xmlChar *res; xmlDocPtr doc; xmlNodePtr node; doc = xmlParseMemory(xml, strlen(xml)); node = xmlDocGetRootElement(doc); node = xmlNewChild(node, NULL, BAD_CAST "m", NULL); xmlNewProp(node, BAD_CAST "bd", BAD_CAST msg_body); if(cli_to_myself) xmlNewProp(node, BAD_CAST "no", BAD_CAST from_no); else xmlNewProp(node, BAD_CAST "no", BAD_CAST to_no); if(cli_to_phone) xmlNewProp(node, BAD_CAST "p", BAD_CAST "1"); else xmlNewProp(node, BAD_CAST "p", BAD_CAST "0"); xmlDocDumpMemory(doc , &res , NULL); xmlFreeDoc(doc); return convert_xml(res); } static char* convert_xml(xmlChar* in) { char *res , *pos ; pos = strstr((char*)in , "?>") + 2; res = (char*)malloc(strlen(pos) + 1); memset(res , 0 , strlen(pos) + 1); memcpy(res , pos , strlen(pos)); xmlFree(in); return res; } openfetion-2.2.1/src/fx_close.c0000644000175000017500000001170211561721144015102 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxClose *fx_close_new(FxMain *fxmain) { FxClose *fxclose = (FxClose*)malloc(sizeof(FxClose)); memset(fxclose , 0 , sizeof(FxClose)); fxclose->fxmain = fxmain; return fxclose; } static void fx_close_on_ok_clicked(GtkWidget *UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_OK); } static void fx_close_on_cancel_clicked(GtkWidget *UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_CANCEL); } void fx_close_initialize(FxClose *fxclose) { GSList *group; GtkWidget *okBtn , *cancelBtn , *label; GdkPixbuf *pb; GtkBox *vbox , *action_area; GtkFixed *fixed; fxclose->dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(fxclose->dialog) , _("Notification")); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , 22 , 22 , NULL); gtk_window_set_icon(GTK_WINDOW(fxclose->dialog) , pb); g_object_unref(pb); gtk_widget_set_usize(fxclose->dialog , 280 , 180); gtk_window_set_resizable(GTK_WINDOW(fxclose->dialog) , FALSE); vbox = GTK_BOX(GTK_DIALOG(fxclose->dialog)->vbox); action_area = GTK_BOX(GTK_DIALOG(fxclose->dialog)->action_area); fixed = GTK_FIXED(gtk_fixed_new()); gtk_box_pack_start_defaults(vbox , GTK_WIDGET(fixed)); label = gtk_label_new(_("Are you sure you want to exit OpenFetion?")); gtk_fixed_put(fixed , label , 20 , 20); fxclose->closeBtn = gtk_radio_button_new_with_label(NULL , _("Exit OpenFetion")); group = gtk_radio_button_get_group(GTK_RADIO_BUTTON(fxclose->closeBtn)); fxclose->iconBtn = gtk_radio_button_new_with_label(group , _("Minimize to Tray")); fxclose->notalert = gtk_check_button_new_with_label(_("Don't notify again")); gtk_fixed_put(fixed , fxclose->closeBtn , 40 , 50); gtk_fixed_put(fixed , fxclose->iconBtn , 40 , 70); gtk_fixed_put(fixed , fxclose->notalert , 40 , 100); okBtn = gtk_button_new_with_label(_("OK")); g_signal_connect(okBtn , "clicked" , G_CALLBACK(fx_close_on_ok_clicked) , fxclose->dialog); cancelBtn = gtk_button_new_with_label(_("Cancel")); g_signal_connect(cancelBtn , "clicked" , G_CALLBACK(fx_close_on_cancel_clicked) , fxclose->dialog); gtk_box_pack_start_defaults(action_area , okBtn); gtk_box_pack_start_defaults(action_area , cancelBtn); GTK_WIDGET_SET_FLAGS(okBtn, GTK_CAN_FOCUS); gtk_widget_grab_focus(okBtn); gtk_widget_show_all(fxclose->dialog); } int fx_close_get_action(FxClose *fxclose) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxclose->closeBtn))){ return CLOSE_DESTROY_MODE; }else{ return CLOSE_ICON_MODE; } } int fx_close_alert(FxClose *fxclose) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxclose->notalert))){ return CLOSE_ALERT_DISABLE; }else{ return CLOSE_ALERT_ENABLE; } } openfetion-2.2.1/src/fx_close.h0000644000175000017500000000505711561721144015115 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_CLOSE_H #define FX_CLOSE_H extern FxClose *fx_close_new(FxMain *fxmain); extern void fx_close_initialize(FxClose *fxclose); extern int fx_close_get_action(FxClose *fxclose); /** * whether the "not alert" has been toggled */ extern int fx_close_alert(FxClose *fxclose); #endif openfetion-2.2.1/src/fx_code.c0000644000175000017500000001643311561721144014715 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxCode* fx_code_new(FxMain* fxmain , const char* reason , const char* tips , ErrorType error) { FxCode* fxcode = (FxCode*)malloc(sizeof(FxCode)); memset(fxcode , 0 , sizeof(FxCode)); fxcode->fxmain = fxmain; if(reason != NULL) strcpy(fxcode->reason , reason); if(tips != NULL) strcpy(fxcode->tip , tips); fxcode->error = error; return fxcode; } void fx_code_initialize(FxCode *fxcode) { GtkWidget *fixed , *warningpic; GtkWidget *vbox , *action_area; GtkWidget *ok_button , *cancel_button; GdkPixbuf *pb , *icon; char codePath[256]; fxcode->dialog = gtk_dialog_new(); gtk_window_set_title(GTK_WINDOW(fxcode->dialog) , _("Please entry your verification code")); icon = gdk_pixbuf_new_from_file(SKIN_DIR"warning.svg" , NULL); gtk_window_set_icon(GTK_WINDOW(fxcode->dialog) , icon); vbox = GTK_DIALOG(fxcode->dialog)->vbox; action_area = GTK_DIALOG(fxcode->dialog)->action_area; fixed = gtk_fixed_new(); gtk_widget_set_usize(fxcode->dialog , 460 , 250); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"warning.svg" , 96 , 96 , NULL); warningpic = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_fixed_put(GTK_FIXED(fixed) , warningpic , 20 , 20 ); fxcode->reasonlabel = gtk_label_new(fxcode->reason); gtk_widget_set_usize(fxcode->reasonlabel , 300 , 40); gtk_label_set_line_wrap(GTK_LABEL(fxcode->reasonlabel) , TRUE ); gtk_label_set_justify(GTK_LABEL(fxcode->reasonlabel), GTK_JUSTIFY_FILL); gtk_fixed_put(GTK_FIXED(fixed) , fxcode->reasonlabel , 150 , 20); fxcode->codeentry = gtk_entry_new(); gtk_widget_set_usize(fxcode->codeentry , 300 , 30); gtk_fixed_put(GTK_FIXED(fixed) , fxcode->codeentry , 150 , 70); g_signal_connect(fxcode->codeentry, "key_press_event" , G_CALLBACK(fx_code_on_key_pressed), fxcode); memset(codePath , 0 , sizeof(codePath)); sprintf(codePath , "%s/code.gif" , fxcode->fxmain->user->config->globalPath); pb = gdk_pixbuf_new_from_file_at_size(codePath , 130 , 36 , NULL); fxcode->codepic = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_widget_set_tooltip_markup(fxcode->codepic , _("Click here getting new verification code")); fxcode->codebox = gtk_event_box_new(); g_signal_connect(G_OBJECT(fxcode->codebox) , "button_press_event" , GTK_SIGNAL_FUNC(fx_code_code_event_func) , fxcode); g_signal_connect(G_OBJECT(fxcode->codebox) , "enter_notify_event" , GTK_SIGNAL_FUNC(fx_code_code_event_func) , fxcode); g_signal_connect(G_OBJECT(fxcode->codebox) , "leave_notify_event" , GTK_SIGNAL_FUNC(fx_code_code_event_func) , fxcode); gtk_container_add(GTK_CONTAINER(fxcode->codebox) , fxcode->codepic); gtk_fixed_put(GTK_FIXED(fixed) , fxcode->codebox , 150 , 120); fxcode->tiplabel = gtk_label_new(fxcode->tip); gtk_widget_set_usize(fxcode->tiplabel , 450 , 40); gtk_label_set_line_wrap(GTK_LABEL(fxcode->tiplabel) , TRUE ); gtk_label_set_justify(GTK_LABEL(fxcode->tiplabel), GTK_JUSTIFY_FILL); gtk_fixed_put(GTK_FIXED(fixed) , fxcode->tiplabel , 20 , 160); ok_button = gtk_button_new_with_label(_("OK")); GTK_WIDGET_SET_FLAGS(ok_button , GTK_CAN_FOCUS); gtk_widget_grab_focus(ok_button); g_signal_connect(ok_button , "clicked" , G_CALLBACK(fx_code_on_ok_clicked) , fxcode->dialog); gtk_box_pack_start_defaults(GTK_BOX(action_area) , ok_button); cancel_button = gtk_button_new_with_label(_("Cancel")); g_signal_connect(cancel_button , "clicked" , G_CALLBACK(fx_code_on_cancel_clicked) , fxcode->dialog); gtk_box_pack_start_defaults(GTK_BOX(action_area) , cancel_button); gtk_box_pack_start_defaults(GTK_BOX(vbox) , fixed); gtk_widget_show_all(fxcode->dialog); } void fx_code_code_event_func(GtkWidget* UNUSED(widget) , GdkEventButton* event , gpointer data) { FxCode *fxcode = (FxCode*)data; User *user = fxcode->fxmain->user; GdkCursor* cursor; char codePath[256]; GdkPixbuf *pb; switch(event->type) { case GDK_BUTTON_PRESS : generate_pic_code(user); memset(codePath, 0, sizeof(codePath)); sprintf(codePath , "%s/code.gif" , fxcode->fxmain->user->config->globalPath); pb = gdk_pixbuf_new_from_file_at_size(codePath , 130 , 36 , NULL); gtk_image_set_from_pixbuf(GTK_IMAGE(fxcode->codepic) , pb); g_object_unref(pb); break; case GDK_ENTER_NOTIFY : cursor = gdk_cursor_new (GDK_HAND2); gdk_window_set_cursor(fxcode->dialog->window,cursor); break; case GDK_LEAVE_NOTIFY : cursor = gdk_cursor_new (GDK_LEFT_PTR); gdk_window_set_cursor(fxcode->dialog->window,cursor); break; default: break; }; } void fx_code_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_OK); } void fx_code_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_CANCEL); } gboolean fx_code_on_key_pressed(GtkWidget* UNUSED(widget), GdkEventKey* event, gpointer data) { FxCode *fxcode = (FxCode*)data; if(event->keyval == GDK_Return || event->keyval == GDK_ISO_Enter || event->keyval == GDK_KP_Enter) { fx_code_on_ok_clicked(NULL, fxcode->dialog); return TRUE; } return FALSE; } openfetion-2.2.1/src/fx_code.h0000644000175000017500000000547611561721144014727 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_CODE_H #define FX_CODE_H extern FxCode* fx_code_new(FxMain* fxmain , const char* reason , const char* tips , ErrorType error); extern void fx_code_initialize(FxCode* fxcode); extern void fx_code_code_event_func(GtkWidget* UNUSED(widget) , GdkEventButton* event , gpointer data); extern void fx_code_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_code_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern gboolean fx_code_on_key_pressed(GtkWidget* UNUSED(widget), GdkEventKey* event, gpointer data); #endif openfetion-2.2.1/src/fx_conn.c0000644000175000017500000006771711561721144014753 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include int old_state; extern gint presence_count; extern struct userlist *ul; #define MAX_PASSWORD_LENGTH 16 #ifdef USE_NETWORKMANAGER #include #include static DBusGConnection *nm_conn = NULL; static DBusGProxy *nm_proxy = NULL; static void nm_state_change_cb(DBusGProxy *UNUSED(proxy), NMState state, gpointer data) { FxMain *fxmain = (FxMain*)data; if(!fxmain->user) return; switch(state) { case NM_STATE_CONNECTED: debug_info("network is connected"); fx_conn_reconnect(fxmain, old_state); break; case NM_STATE_ASLEEP: debug_info("network is sleeping..."); fx_conn_offline(fxmain); break; case NM_STATE_CONNECTING: debug_info("network is connecting..."); break; case NM_STATE_DISCONNECTED: debug_info("network is disconnected"); fx_conn_offline(fxmain); break; case NM_STATE_UNKNOWN: debug_info("unknown network state"); default: break; } } #endif void fx_conn_init(FxMain *fxmain) { #ifdef USE_NETWORKMANAGER GError *error = NULL; #endif connlst = (struct conn_list*)malloc(sizeof(struct conn_list)); connlst->conn = NULL; connlst->next = connlst->pre = connlst; #ifdef USE_NETWORKMANAGER nm_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); if (!nm_conn) { debug_error("Error connecting to DBus System service: %s.\n", error->message); } else { nm_proxy = dbus_g_proxy_new_for_name(nm_conn, NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE); dbus_g_proxy_add_signal(nm_proxy, "StateChange", G_TYPE_UINT, G_TYPE_INVALID); dbus_g_proxy_connect_signal(nm_proxy, "StateChange", G_CALLBACK(nm_state_change_cb), fxmain, NULL); } #endif } void fx_conn_append(FetionConnection *conn) { struct conn_list *tmp; tmp = (struct conn_list*)malloc(sizeof(struct conn_list)); tmp->conn = conn; connlst->next->pre = tmp; tmp->next = connlst->next; tmp->pre = connlst; connlst->next = tmp; } static void fx_conn_remove(struct conn_list *conn) { conn->next->pre = conn->pre; conn->pre->next = conn->next; } static void popup_startup_msg(FxMain *fxmain) { #ifdef USE_LIBNOTIFY gchar notifyText[1024]; gchar iconPath[256]; GdkPixbuf *pixbuf; FxLogin *fxlogin = fxmain->loginPanel; User *user = fxmain->user; Config *config = user->config; sprintf(iconPath, "%s/%s.jpg", config->iconPath, user->sId); sprintf(notifyText , _("Public IP: %s\n" "IP of last login: %s\n" "Time of last login: %s\n"), user->publicIp , user->lastLoginIp, user->lastLoginTime); pixbuf = gdk_pixbuf_new_from_file_at_size(iconPath, NOTIFY_IMAGE_SIZE, NOTIFY_IMAGE_SIZE, NULL); if(!pixbuf){ fx_login_show_msg(fxlogin, _("Getting portrait...")); fetion_user_download_portrait(user , user->sipuri); pixbuf = gdk_pixbuf_new_from_file_at_size(iconPath, NOTIFY_IMAGE_SIZE, NOTIFY_IMAGE_SIZE, NULL); if(!pixbuf) pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", NOTIFY_IMAGE_SIZE, NOTIFY_IMAGE_SIZE, NULL); } gdk_threads_enter(); notify_notification_update(fxmain->notify, _("Login successful")// notifySummary , notifyText , NULL); notify_notification_set_icon_from_pixbuf( fxmain->notify , pixbuf); notify_notification_show(fxmain->notify , NULL); gdk_threads_leave(); g_object_unref(pixbuf); #endif } static void *fx_server_func(void *data) { FxMain *fxmain = (FxMain*)data; int fifo; if((fifo = init_server(fxmain)) == -1) { fprintf(stderr, "init openfetion server failed\n"); return (void*)0; } start_server(fxmain, fifo); return (void*)0; } int fx_conn_connect(FxMain *fxmain) { FxLogin *fxlogin = fxmain->loginPanel; FetionConnection *conn = NULL; /* connection for sipc */ const gchar *no; const gchar *password; gchar *pos; gchar *nonce; gchar *key; gchar *aeskey; gchar *response; /* string used for authentication */ Config *config = NULL; /* global user config */ Group *group = NULL; /* buddy list */ User *user = NULL; /* global user information */ gchar code[20]; /* store reply code */ gchar statusTooltip[128]; struct userlist *newul; struct userlist *ul_cur; GtkTreeIter stateIter; GtkTreeModel *stateModel = NULL; gint state; gboolean remember; gint local_buddy_count; gint local_group_count; gint new_buddy_count; gint new_group_count; FxCode *fxcode = NULL; gint ret; /* get login state value */ gtk_combo_box_get_active_iter( GTK_COMBO_BOX(fxlogin->statecombo), &stateIter); stateModel = gtk_combo_box_get_model( GTK_COMBO_BOX(fxlogin->statecombo)); gtk_tree_model_get(stateModel, &stateIter, 2 , &state , -1); old_state = state; /* get login number and password */ no = gtk_combo_box_get_active_text( GTK_COMBO_BOX(fxlogin->username)); password = gtk_entry_get_text( GTK_ENTRY(fxlogin->password)); /* get whether to remember password */ remember = gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON(fxlogin->remember)); user = fetion_user_new(no , password); fx_main_set_user(fxmain , user); gdk_threads_enter(); fx_login_hide(fxlogin); fx_logining_show(fxmain); gdk_threads_leave(); fx_login_show_msg(fxlogin , _("Preparing for login")); config = fetion_config_new(); if(!user){ fx_login_show_err(fxlogin , _("Login failed")); goto failed; } /* set the proxy structure to config */ config->proxy = fxlogin->proxy; /* set the config structure to user */ fetion_user_set_config(user , config); login: newul = fetion_user_list_find_by_no(ul , no); if(newul && strlen(password) == MAX_PASSWORD_LENGTH && strncmp(password, newul->password, MAX_PASSWORD_LENGTH) == 0) fetion_user_set_password(user, newul->password); pos = ssi_auth_action(user); if(!pos){ fx_login_show_err(fxlogin , _("Login failed")); goto failed; } parse_ssi_auth_response(pos , user); g_free(pos); if(USER_AUTH_NEED_CONFIRM(user)){ debug_info(user->verification->text); debug_info(user->verification->tips); fx_login_show_msg(fxlogin, _("Getting code picture,please wait...")); generate_pic_code(user); gdk_threads_enter(); fxcode = fx_code_new(fxmain, user->verification->text, user->verification->tips, CODE_NOT_ERROR); fx_code_initialize(fxcode); ret = gtk_dialog_run(GTK_DIALOG(fxcode->dialog)); if(ret == GTK_RESPONSE_OK){ strcpy(code , gtk_entry_get_text( GTK_ENTRY(fxcode->codeentry))); fetion_user_set_verification_code(user , code); gtk_widget_destroy(fxcode->dialog); g_free(fxcode); gdk_threads_leave(); }else{ gtk_widget_destroy(fxcode->dialog); g_free(fxcode); gdk_threads_leave(); g_thread_exit(0); } debug_info("Input verfication code:%s" , code); goto login; } if(USER_AUTH_ERROR(user)){ debug_error("password ERROR!!!"); fx_login_show_err(fxlogin, _("Login failed. \nIncorrect cell phone number or password")); goto failed; } fx_login_show_err(fxlogin, _("Loading local user information")); if(fetion_user_init_config(user) == -1) { debug_error("initialize config failed"); fx_login_show_err(fxlogin , _("Login failed")); goto failed; } /* initialize history */ fx_main_history_init(fxmain); /* set user list to be stored in local file */ newul = NULL; newul = fetion_user_list_find_by_no(ul , no); if(!newul) { if(remember) { gchar *hashed_password = hash_password(password); newul = fetion_user_list_new(no, hashed_password, user->userId, user->sId, state, 1); g_free(hashed_password); } else newul = fetion_user_list_new(no, NULL, user->userId, user->sId, state, 1); foreach_userlist(ul, ul_cur) ul_cur->islastuser = 0; fetion_user_list_append(ul, newul); } else { if(remember) { if(strlen(password) != MAX_PASSWORD_LENGTH || strncmp(password, newul->password, MAX_PASSWORD_LENGTH)) { /* hash password */ memset(newul->password, 0, sizeof(newul->password)); gchar *hashed_password = hash_password(password); strcpy(newul->password, hashed_password); g_free(hashed_password); } } else { /* clear the password */ memset(newul->password, 0, sizeof(newul->password)); } newul->laststate = state; foreach_userlist(ul , ul_cur) ul_cur->islastuser = 0; newul->islastuser = 1; } fetion_user_list_save(config , ul); fetion_user_list_free(ul); /* download xml configuration file from the server */ fetion_config_load(user); if(config->sipcProxyPort == 0) fx_login_show_msg(fxlogin, _("Detected that this is the first time you login\n" "Downloading configuration file...")); else fx_login_show_msg(fxlogin, _("Downloading configuration files")); if(fetion_config_download_configuration(user) < 0){ fx_login_show_err(fxlogin, _("Connection has been shutdown by the server")); return -1; } fetion_config_save(user); fetion_user_set_st(user , state); /*load local data*/ fetion_user_load(user); fetion_contact_load(user, &local_group_count, &local_buddy_count); /* start a new tcp connection for registering to sipc server */ conn = tcp_connection_new(); if(config->proxy != NULL && config->proxy->proxyEnabled){ fx_login_show_msg(fxlogin, _("Connecting to proxy server")); tcp_connection_connect_with_proxy(conn, config->sipcProxyIP, config->sipcProxyPort, config->proxy); }else{ fx_login_show_msg(fxlogin, _("Connecting to registration server")); int ret = tcp_connection_connect(conn, config->sipcProxyIP, config->sipcProxyPort); if(ret == -1) { config->sipcProxyPort = 443; ret = tcp_connection_connect(conn, config->sipcProxyIP, config->sipcProxyPort); if(ret == -1) { fx_login_show_err(fxlogin , _("Login failed")); goto failed; } } } /* add the connection object into the connection list */ fx_conn_append(conn); /* initialize a sip object */ FetionSip* sip = fetion_sip_new(conn , user->sId); fetion_user_set_sip(user , sip); fx_login_show_msg(fxlogin, _("Registering to SIPC Server")); pos = sipc_reg_action(user); if(!pos){ fx_login_show_err(fxlogin , _("Login failed")); goto failed; } parse_sipc_reg_response(pos , &nonce , &key); g_free(pos); aeskey = generate_aes_key(); if(aeskey == NULL){ goto failed; } response = generate_response(nonce, user->userId, user->password, key, aeskey); g_free(nonce); g_free(key); g_free(aeskey); /* start sipc authentication using the response created just now */ fx_login_show_msg(fxlogin , _("SIPC Indentify")); auth: pos = sipc_aut_action(user , response); if(pos == NULL){ fx_login_show_err(fxlogin , _("Login failed")); goto failed; } if(parse_sipc_auth_response(pos , user, &new_group_count, &new_buddy_count) < 0){ debug_info("Password error , login failed!!!"); fx_login_show_err(fxlogin , _("Authenticate failed.")); goto failed; } g_free(pos); pos = NULL; if(USER_AUTH_ERROR(user)){ debug_info("Password error , login failed!!!"); fx_login_show_err(fxlogin , _("Authenticate failed.")); goto failed; } if(USER_AUTH_NEED_CONFIRM(user)){ debug_info(user->verification->text); debug_info(user->verification->tips); fx_login_show_msg(fxlogin, _("Getting code picture,please wait...")); generate_pic_code(user); gdk_threads_enter(); fxcode = fx_code_new(fxmain, user->verification->text, user->verification->tips, CODE_NOT_ERROR); fx_code_initialize(fxcode); ret = gtk_dialog_run(GTK_DIALOG(fxcode->dialog)); if(ret == GTK_RESPONSE_OK){ strcpy(code , gtk_entry_get_text( GTK_ENTRY(fxcode->codeentry))); fetion_user_set_verification_code(user , code); gtk_widget_destroy(fxcode->dialog); gdk_threads_leave(); goto auth; }else{ gtk_widget_destroy(fxcode->dialog); gdk_threads_leave(); goto failed; } debug_info("Input verfication code:%s" , code); } Contact *c_cur; Contact *c_tmp; Group *g_cur; Group *g_tmp; /* update buddy list */ if(user->groupCount == 0) user->groupCount = local_group_count; else if(user->groupCount != local_group_count){ for(g_cur = user->groupList->next; g_cur != user->groupList;){ g_tmp = g_cur; g_cur = g_cur->next; if(!g_tmp->dirty){ fetion_group_list_remove(g_tmp); g_free(g_tmp); } } } /* update buddy count */ if(user->contactCount == 0) user->contactCount = local_buddy_count; else if(user->contactCount != local_buddy_count){ /* do some clean on the local buddy data */ for(c_cur = user->contactList->next; c_cur != user->contactList;){ c_tmp = c_cur; c_cur = c_cur->next; if(!c_tmp->dirty){ fetion_contact_list_remove(c_tmp); g_free(c_tmp); } } } fx_login_show_msg(fxlogin , _("Initializing main panel")); pg_group_get_list(user); popup_startup_msg(fxmain); fx_login_show_msg(fxlogin , _("Login sucessful")); /*if there is not a buddylist name "Ungrouped" or "Strangers", create one */ if(fetion_group_list_find_by_id(user->groupList, BUDDY_LIST_NOT_GROUPED) == NULL && fetion_contact_has_ungrouped(user->contactList)){ group = fetion_group_new(); group->groupid = BUDDY_LIST_NOT_GROUPED; strcpy(group->groupname , N_("Ungrouped")); fetion_group_list_append(user->groupList , group); } if(fetion_group_list_find_by_id(user->groupList, BUDDY_LIST_STRANGER) == NULL && fetion_contact_has_strangers(user->contactList)){ group = fetion_group_new(); group->groupid = BUDDY_LIST_STRANGER; strcpy(group->groupname , N_("Strangers")); fetion_group_list_prepend(user->groupList , group); } fx_login_show_msg(fxlogin , _("Initializing main panel")); /* initialize head panel */ gdk_threads_enter(); fx_head_initialize(fxmain); gdk_threads_leave(); /* initialize main panel which in fact only contains a treeview*/ gdk_threads_enter(); fxmain->mainPanel = fx_tree_new(); fx_tree_initilize(fxmain); gdk_threads_leave(); /* initialize bottom panel */ gdk_threads_enter(); fx_bottom_initialize(fxmain); gdk_threads_leave(); gdk_threads_enter(); gtk_window_set_resizable(GTK_WINDOW(fxmain->window) , TRUE); fetion_config_load_size(config); if(config->window_width > 0 && config->window_height >0) gtk_window_resize(GTK_WINDOW(fxmain->window), config->window_width, config->window_height); gdk_threads_leave(); /* set tooltip of status icon */ sprintf(statusTooltip, "%s\n%s", user->nickname , user->mobileno); gdk_threads_enter(); if(USE_STATUS_ICON(config)) { gtk_status_icon_set_tooltip( GTK_STATUS_ICON(fxmain->trayIcon), statusTooltip); } /* set title of main window*/ gtk_window_set_title(GTK_WINDOW(fxmain->window), user->nickname ); gdk_threads_leave(); gdk_threads_enter(); fx_login_free(fxlogin); fx_head_show(fxmain); fx_tree_show(fxmain); fx_bottom_show(fxmain); gdk_threads_leave(); /* start sending keep alive request periodically */ g_timeout_add_seconds(70 , (GSourceFunc)fx_main_register_func , user); g_timeout_add_seconds(5 , (GSourceFunc)fx_main_check_func , fxmain); g_thread_create(fx_server_func, fxmain, FALSE, NULL); g_thread_exit(0); failed: gdk_threads_enter(); gtk_widget_destroy(fxlogin->fixed1); gtk_widget_show(fxlogin->fixed); gtk_widget_grab_focus(fxlogin->loginbutton); gdk_threads_leave(); g_thread_exit(0); return -1; } void fx_conn_offline(FxMain *fxmain) { FxTree *fxtree; GtkTreeView *treeview; GtkTreeModel *model; GtkTreeIter rootiter; GtkTreeIter childiter; struct conn_list *cur; struct conn_list *tmp; FxList *cw_cur; FxList *sip_cur; FxList *tmp_cur; FxChat *fxchat; /* set state image to be offline */ fx_head_set_state_image(fxmain, P_OFFLINE); /* set user state to be offline */ fetion_user_set_st(fxmain->user, P_OFFLINE); /* shutdown all the connections */ for(cur = connlst->next;cur != connlst;){ tmp = cur; cur = cur->next; tcp_connection_close(tmp->conn); fx_conn_remove(tmp); g_free(tmp); } /* clear the state of all contacts */ fxtree = fxmain->mainPanel; treeview = GTK_TREE_VIEW(fxtree->treeView); model = gtk_tree_view_get_model(treeview); if(gtk_tree_model_get_iter_root(model, &rootiter)){ do{ /* clear group online numbers */ gtk_tree_store_set(GTK_TREE_STORE(model), &rootiter, G_ONLINE_COUNT_COL, 0, -1); if(gtk_tree_model_iter_children(model, &childiter, &rootiter)) do{ /* clear contacts' online state */ gtk_tree_store_set(GTK_TREE_STORE(model), &childiter, B_STATE_COL, P_HIDDEN, -1); }while(gtk_tree_model_iter_next(model, &childiter)); }while(gtk_tree_model_iter_next(model, &rootiter)); } /* notify all the chat window */ foreach_list(fxmain->clist, cw_cur){ fxchat = (FxChat*)cw_cur->data; fx_chat_add_information(fxchat, _("\nConnection has been shutdown\n")); } /* clear the sip list */ for(sip_cur = fxmain->slist->next; sip_cur != fxmain->slist;){ tmp_cur = sip_cur; sip_cur = sip_cur->next; fx_list_remove(tmp_cur); free(tmp_cur); } } int fx_conn_reconnect(FxMain *fxmain, int state) { User *user; Config *config; FetionSip *sip; FetionConnection *tcp; ThreadArgs *args; FxCode *fxcode; FxHead *fxhead; GdkPixbuf *pixbuf; gchar *res_str; gchar *nonce; gchar *key; gchar *response; gchar *aeskey; gchar code[16]; gchar path[1024]; gint ret; gint group_count; gint buddy_count; user = fxmain->user; sip = user->sip; config = user->config; fxhead = fxmain->headPanel; /* set user state to be not offline */ fetion_user_set_st(user , state); /* create a new connection to the sip server */ tcp = tcp_connection_new(); /* add connection to connlist */ fx_conn_append(tcp); debug_info("Connecting to sipc server"); if(config->proxy && config->proxy->proxyEnabled) ret = tcp_connection_connect_with_proxy(tcp, config->sipcProxyIP, config->sipcProxyPort, config->proxy); else { ret = tcp_connection_connect(tcp, config->sipcProxyIP, config->sipcProxyPort); if(ret == -1 && config->sipcProxyPort != 443) { config->sipcProxyPort = 443; ret = tcp_connection_connect(tcp, config->sipcProxyIP, config->sipcProxyPort); } } if(ret == -1){ gdk_threads_enter(); fx_util_popup_warning(fxmain, _("Login failed")); gdk_threads_leave(); goto failed2; } /* set the connection to the sip obj already exist */ fetion_sip_set_conn(sip, tcp); /* register to sipc server */ debug_info("Registering to sipc server"); res_str = sipc_reg_action(user); if(!res_str){ gdk_threads_enter(); fx_util_popup_warning(fxmain, _("Login failed")); gdk_threads_leave(); goto failed2; } parse_sipc_reg_response(res_str, &nonce, &key); g_free(res_str); /* generate sipc authencation response string */ aeskey = generate_aes_key(); if(aeskey == NULL){ goto failed2; } response = generate_response(nonce, user->userId, user->password, key, aeskey); g_free(nonce); g_free(key); g_free(aeskey); auth: /* start sipc authencation */ debug_info("Starting sipc authencation"); res_str = sipc_aut_action(user, response); if(!res_str){ gdk_threads_enter(); fx_util_popup_warning(fxmain, _("Login failed")); gdk_threads_leave(); goto failed2; } if(parse_sipc_auth_response(res_str, user, &group_count, &buddy_count) < 0){ gdk_threads_enter(); fx_util_popup_warning(fxmain, _("Authenticate failed.")); gdk_threads_leave(); g_free(res_str); goto failed2; } g_free(res_str); /* error code 401 or 400,means passowd error */ if(user->loginStatus == 401 || user->loginStatus == 400){ gdk_threads_enter(); fx_util_popup_warning(fxmain, _("Authenticate failed.")); gdk_threads_leave(); goto failed2; } /* need verification */ if(user->loginStatus == 421 || user->loginStatus == 420){ debug_info(user->verification->text); debug_info(user->verification->tips); debug_info("Getting code picture,please wait..."); generate_pic_code(user); gdk_threads_enter(); fxcode = fx_code_new(fxmain, user->verification->text, user->verification->tips, CODE_NOT_ERROR); fx_code_initialize(fxcode); ret = gtk_dialog_run(GTK_DIALOG(fxcode->dialog)); if(ret == GTK_RESPONSE_OK){ strcpy(code , gtk_entry_get_text( GTK_ENTRY(fxcode->codeentry))); fetion_user_set_verification_code(user , code); gtk_widget_destroy(fxcode->dialog); gdk_threads_leave(); goto auth; }else{ gtk_widget_destroy(fxcode->dialog); gdk_threads_leave(); goto failed2; } debug_info("Input verfication code:%s" , code); } args = (ThreadArgs*)malloc(sizeof(ThreadArgs)); args->fxmain = fxmain; args->sip = NULL; /* start listening thread */ fetion_contact_subscribe_only(user); presence_count = 0; g_thread_create(fx_main_listen_thread_func, args, FALSE, NULL); /* recover the portrait */ sprintf(path, "%s/%s.jpg", config->iconPath, user->sId); pixbuf = gdk_pixbuf_new_from_file_at_size(path, USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, NULL); if(!pixbuf) pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, NULL); gdk_threads_enter(); gtk_image_set_from_pixbuf( GTK_IMAGE(fxhead->portrait), pixbuf); gtk_widget_set_sensitive(fxhead->portrait, TRUE); gdk_threads_leave(); g_object_unref(pixbuf); /* set state image */ gdk_threads_enter(); fx_head_set_state_image(fxmain, state); gdk_threads_leave(); /* start sending keep alive request periodically */ g_timeout_add_seconds(60 , (GSourceFunc)fx_main_register_func , user); g_timeout_add_seconds(3 , (GSourceFunc)fx_main_check_func , fxmain); return 1; failed2: fetion_user_set_st(user, P_OFFLINE); sprintf(path, "%s/%s.jpg", config->iconPath, user->sId); pixbuf = gdk_pixbuf_new_from_file_at_size(path, USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, NULL); if(!pixbuf) pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, NULL); gdk_threads_enter(); gtk_image_set_from_pixbuf( GTK_IMAGE(fxhead->portrait), pixbuf); gdk_threads_leave(); g_object_unref(pixbuf); return -1; } int fx_conn_offline_login(FxMain *fxmain) { FxLogin *fxlogin; FetionConnection *conn; FetionSip *sip; User *user; Config *config; const gchar *no; const gchar *password; gint local_group_count; gint local_buddy_count; struct userlist *ul_cur; fxlogin = fxmain->loginPanel; gdk_threads_enter(); fx_login_hide(fxlogin); fx_logining_show(fxmain); gdk_threads_leave(); /* get login number and password */ no = gtk_combo_box_get_active_text( GTK_COMBO_BOX(fxlogin->username)); password = gtk_entry_get_text( GTK_ENTRY(fxlogin->password)); ul_cur = fetion_user_list_find_by_no(ul, no); if(!ul_cur){ fx_login_show_err(fxlogin, _("No local information stored")); goto failed1; } if(strcmp(ul_cur->password, password) != 0){ fx_login_show_err(fxlogin, _("Authenticate failed.")); goto failed1; } user = fetion_user_new(no , password); fetion_user_set_userid(user, ul_cur->userid); fx_main_set_user(fxmain , user); fx_login_show_msg(fxlogin , _("Preparing for login")); config = fetion_config_new(); if(!user){ fx_login_show_err(fxlogin , _("Login failed")); goto failed1; } /* set the proxy structure to config */ config->proxy = fxlogin->proxy; /* set the config structure to user */ fetion_user_set_config(user , config); if(fetion_user_init_config(user)) { fx_login_show_err(fxlogin , _("Login failed")); debug_error("initialize config failed"); goto failed1; } /* initialize history */ fx_main_history_init(fxmain); fetion_config_load(user); if(config->sipcProxyPort == 0) goto failed1; fetion_user_set_st(user , P_OFFLINE); /*load local data*/ fetion_user_load(user); fetion_contact_load(user, &local_group_count, &local_buddy_count); /* add the connection object into the connection list */ conn = tcp_connection_new(); fx_conn_append(conn); /* initialize a sip object */ sip = fetion_sip_new(conn , user->sId); fetion_user_set_sip(user , sip); /* initialize head panel */ gdk_threads_enter(); fx_head_initialize(fxmain); gdk_threads_leave(); /* initialize main panel which in fact only contains a treeview*/ gdk_threads_enter(); fxmain->mainPanel = fx_tree_new(); fx_tree_initilize(fxmain); gdk_threads_leave(); /* initialize bottom panel */ gdk_threads_enter(); fx_bottom_initialize(fxmain); gdk_threads_leave(); gdk_threads_enter(); /* set title of main window*/ gtk_window_set_title(GTK_WINDOW(fxmain->window), user->nickname ); gdk_threads_leave(); gdk_threads_enter(); fx_login_free(fxlogin); fx_head_show(fxmain); fx_tree_show(fxmain); fx_bottom_show(fxmain); gdk_threads_leave(); return 1; failed1: gdk_threads_enter(); gtk_widget_destroy(fxlogin->fixed1); gtk_widget_show(fxlogin->fixed); gtk_widget_grab_focus(fxlogin->loginbutton); gdk_threads_leave(); g_thread_exit(0); return -1; } int fx_conn_check_action(FxMain *fxmain) { if(fxmain->user->state == P_OFFLINE){ fx_util_popup_warning(fxmain, _("The action can't be performed in offline state")); return 0; } return 1; } openfetion-2.2.1/src/fx_conn.h0000644000175000017500000000555711561721144014752 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_CONN_H #define FX_CONN_H #include struct conn_list { FetionConnection *conn; struct conn_list *next; struct conn_list *pre; }; #define foreach_conn_list(head,cur) \ for(cur=head;(cur=cur->next)!=head;) struct conn_list *connlst; extern void fx_conn_init(FxMain *fxmain); extern void fx_conn_append(FetionConnection *conn); extern void fx_conn_offline(FxMain *fxmain); extern int fx_conn_check_action(FxMain *fxmain); extern int fx_conn_connect(FxMain *fxmain); extern int fx_conn_reconnect(FxMain *fxmain, int state); extern int fx_conn_offline_login(FxMain *fxmain); #endif openfetion-2.2.1/src/fx_dsms.c0000644000175000017500000006141011561721144014744 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static gboolean key_press_func(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data); FxConfirm* fx_confirm_new(FxMain *fxmain) { FxConfirm *fxconfirm ; fxconfirm = (FxConfirm*)malloc(sizeof(FxConfirm)); fxconfirm->fxmain = fxmain; return fxconfirm; } static void fx_confirm_on_ok_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxConfirm *fxconfirm = (FxConfirm*)data; gtk_dialog_response(GTK_DIALOG(fxconfirm->dialog) , GTK_RESPONSE_OK); } static void fx_confirm_on_cancel_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxConfirm *fxconfirm = (FxConfirm*)data; gtk_dialog_response(GTK_DIALOG(fxconfirm->dialog) , GTK_RESPONSE_CANCEL); } void fx_confirm_initialize(FxConfirm *fxconfirm) { GtkWidget *infoLabel , *noteLabel , *codeLabel; GtkWidget *fixed , *okBtn , *cancelBtn; GdkPixbuf *pb; fxconfirm->dialog = gtk_dialog_new(); gtk_widget_set_usize(fxconfirm->dialog , 420 , 220); gtk_window_set_resizable(GTK_WINDOW(fxconfirm->dialog) , FALSE); pb = gdk_pixbuf_new_from_file(SKIN_DIR"online.svg" , NULL); gtk_window_set_icon(GTK_WINDOW(fxconfirm->dialog) , pb); g_object_unref(pb); gtk_window_set_title(GTK_WINDOW(fxconfirm->dialog) , ("SMS directly")); fixed = gtk_fixed_new(); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxconfirm->dialog)->vbox) , fixed); infoLabel = gtk_label_new(_("Fetion has sent the verification code as SMS to your cell phone. Please input it.")); codeLabel = gtk_label_new(_("Verification code")); fxconfirm->codeEntry = gtk_entry_new(); gtk_widget_set_usize(fxconfirm->codeEntry , 240 , 25); noteLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(noteLabel) , _("NOTE:A little timelag because of some network reason" ",Please Wait......")); gtk_fixed_put(GTK_FIXED(fixed) , infoLabel , 40 , 40); gtk_fixed_put(GTK_FIXED(fixed) , codeLabel , 40 , 74); gtk_fixed_put(GTK_FIXED(fixed) , fxconfirm->codeEntry , 120 , 70); gtk_fixed_put(GTK_FIXED(fixed) , noteLabel , 20 , 120); okBtn = gtk_button_new_with_label(_("OK")); cancelBtn = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxconfirm->dialog)->action_area) , okBtn); g_signal_connect(okBtn , "clicked" , G_CALLBACK(fx_confirm_on_ok_clicked) , fxconfirm); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxconfirm->dialog)->action_area) , cancelBtn); g_signal_connect(cancelBtn , "clicked" , G_CALLBACK(fx_confirm_on_cancel_clicked) , fxconfirm); gtk_widget_show_all(fxconfirm->dialog); } FxDSMS* fx_dsms_new(FxMain *fxmain) { FxDSMS *fxdsms = (FxDSMS*)malloc(sizeof(FxDSMS)); fxdsms->fxmain = fxmain; return fxdsms; } static void add_contact(gpointer data) { FxDSMS *fxdsms = (FxDSMS*)data; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxdsms->chooseList)); GdkPixbuf *pb; const char *number; GtkTreeIter iter; gtk_widget_show(fxdsms->chooseList); gtk_widget_hide(fxdsms->msgLabel); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg", 22 , 22 , NULL); number = gtk_entry_get_text(GTK_ENTRY(fxdsms->numberEntry)); if(*number == '\0') return; gtk_tree_store_append(GTK_TREE_STORE(model) , &iter , NULL); gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , PIXBUF_COL , pb , NUMBER_COL , number , -1); gtk_entry_set_text(GTK_ENTRY(fxdsms->numberEntry) , ""); g_object_unref(pb); } static gboolean fx_dsms_number_clicked(GtkWidget *UNUSED(widget) , gpointer data) { add_contact(data); return TRUE; } static void fx_dsms_add_contact(GtkWidget *UNUSED(widget) , GdkEventButton *UNUSED(event) , gpointer data){ add_contact(data); } static GtkTreeModel* create_model() { GtkTreeStore *store; store = gtk_tree_store_new(COL_SIZE , GDK_TYPE_PIXBUF , G_TYPE_STRING); return GTK_TREE_MODEL(store); } static void create_column(GtkWidget* tree) { GtkCellRenderer* renderer; GtkTreeViewColumn *col , *col0; renderer = gtk_cell_renderer_pixbuf_new(); col = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col, renderer , FALSE); gtk_tree_view_column_add_attribute(col, renderer, "pixbuf", PIXBUF_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col); renderer = gtk_cell_renderer_text_new(); col0 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col0, renderer , FALSE); gtk_tree_view_column_add_attribute(col0 , renderer, "text", NUMBER_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col0); } static void fx_dsms_on_delete_clicked(GtkWidget *UNUSED(widget) , gpointer data) { struct deleteargs *args = (struct deleteargs*)data; FxDSMS *fxdsms = args->fxdsms; GtkTreeIter iter = args->iter; GtkWidget *treeView = fxdsms->chooseList; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)); gtk_tree_store_remove(GTK_TREE_STORE(model) , &iter); if(! gtk_tree_model_get_iter_first(model , &iter)){ gtk_widget_hide(treeView); gtk_widget_show(fxdsms->msgLabel); } } static gboolean fx_dsms_on_rightbutton_click(GtkWidget *UNUSED(tree) , GdkEventButton *event , gpointer data) { FxDSMS *fxdsms = (FxDSMS*)data; GtkTreeIter iter; GtkTreePath* path = NULL; GtkTreeModel* model = NULL; GtkWidget *menu , *item , *img; struct deleteargs *args; if(event->type == GDK_BUTTON_PRESS && event->button == 3) { menu = gtk_menu_new(); model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxdsms->chooseList)); gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(fxdsms->chooseList) , (gint)event->x , (gint)event->y , &path , NULL , NULL , NULL); if(path == NULL) return FALSE; gtk_tree_model_get_iter(GTK_TREE_MODEL(model) , &iter , path); gtk_tree_path_free(path); item = gtk_image_menu_item_new_with_label(_("Delete this contact")); img = gtk_image_new_from_file(SKIN_DIR"delete.png"); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img); gtk_menu_shell_append(GTK_MENU_SHELL(menu) , item); args = (struct deleteargs*)malloc(sizeof(struct deleteargs)); args->fxdsms = fxdsms; args->iter = iter; g_signal_connect(item , "activate" , G_CALLBACK(fx_dsms_on_delete_clicked) , args); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu) , NULL , NULL , NULL , NULL , (event != NULL) ? event->button : 0 , gdk_event_get_time((GdkEvent*)event)); return TRUE; } return FALSE; } static gboolean fx_dsms_on_text_buffer_changed(GtkTextBuffer *buffer , gpointer data) { FxDSMS* fxdsms = (FxDSMS*)data; GtkTextIter startIter , endIter; char text[48]; const char *res = NULL; int count = gtk_text_buffer_get_char_count(buffer); int len; res = gtk_entry_get_text(GTK_ENTRY(fxdsms->sigEntry)); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxdsms->checkBtn))){ len = 179 - g_utf8_strlen(res , -1); count += (g_utf8_strlen(res , -1) + 1); }else{ len = 180; } if(count <= 180) { snprintf(text, sizeof(text) - 1 , _("%d/180, will split to %d") , count , (count % 60) ? (count / 60 + 1) : (count / 60 )); gtk_label_set_markup(GTK_LABEL(fxdsms->countLabel) , text); } else { gtk_text_buffer_get_start_iter(buffer , &startIter); gtk_text_buffer_get_iter_at_offset(buffer , &endIter , len); res = gtk_text_buffer_get_text(buffer , &startIter , &endIter , len); gtk_text_buffer_set_text(buffer , res , strlen(res)); } return FALSE; } static void fx_dsms_add_information(FxDSMS* fxdsms , const char* msg) { GtkTextIter iter; GtkTextMark *mark; GtkTextBuffer* buffer; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxdsms->recvText)); gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert(buffer , &iter , "" , -1); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter, msg , -1 , "grey" , "lm10" , NULL); gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark (buffer, mark, &iter); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(fxdsms->recvText), mark); } static void fx_dsms_sig_checked(GtkWidget *UNUSED(widget) , gpointer data) { FxDSMS *fxdsms = (FxDSMS*)data; GtkTextBuffer *buffer; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxdsms->sendText)); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxdsms->checkBtn))){ gtk_widget_set_sensitive(fxdsms->sigEntry , TRUE); }else{ gtk_widget_set_sensitive(fxdsms->sigEntry , FALSE); } fx_dsms_on_text_buffer_changed(buffer , data); } static void* fx_dsms_send_thread(void *data) { FxDSMS *fxdsms = (FxDSMS*)data; FxMain *fxmain = fxdsms->fxmain; User *user = fxmain->user; GtkTreeView *treeView = GTK_TREE_VIEW(fxdsms->chooseList); GtkTreeModel *model = gtk_tree_view_get_model(treeView); GtkTreeIter iter; GtkTextIter begin , end; GtkTextBuffer *buffer; char *to , text[1024] , msg[1024] , *error; const char *message , *code; int ret , ret1 , ret2 , ret3; FxCode *fxcode; FxConfirm *fxconfirm; gtk_tree_model_get_iter_first(model , &iter); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxdsms->sendText)); gtk_text_buffer_get_start_iter(buffer , &begin); gtk_text_buffer_get_end_iter(buffer , &end); message = gtk_text_buffer_get_text(buffer , &begin , &end , TRUE); memset(msg, 0, sizeof(msg)); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxdsms->checkBtn))){ sprintf(msg , "%s:%s" , gtk_entry_get_text(GTK_ENTRY(fxdsms->sigEntry)) , message); }else{ strcpy(msg , message); } gtk_text_buffer_delete(buffer , &begin , &end); do { gtk_tree_model_get(model , &iter , NUMBER_COL , &to , -1); ret = fetion_directsms_send_sms(user , to , msg); if(ret == SEND_SMS_SUCCESS){ memset(text, 0, sizeof(text)); sprintf(text , _("Mesage has been send to %s successfully.") , to); gdk_threads_enter(); fx_dsms_add_information(fxdsms , text); gdk_threads_leave(); }else if(ret == SEND_SMS_OTHER_ERROR){ memset(text, 0, sizeof(text)); sprintf(text , _("Mesage didn't send to %s. Please check the phone number of the contact.") , to); gdk_threads_enter(); fx_dsms_add_information(fxdsms , text); gdk_threads_leave(); }else{ picreload: generate_pic_code(user); fxcode = fx_code_new(fxmain , user->verification->text , user->verification->tips , CODE_NOT_ERROR ); gdk_threads_enter(); fx_code_initialize(fxcode); ret = gtk_dialog_run(GTK_DIALOG(fxcode->dialog)); if(ret == GTK_RESPONSE_CANCEL){ memset(text, 0, sizeof(text)); strcpy(text , _("Send message failed")); fx_dsms_add_information(fxdsms , text); gtk_widget_destroy(fxcode->dialog); gdk_threads_leave(); fetion_verification_free(user->verification); user->verification = NULL; break; } if(ret == GTK_RESPONSE_OK){ code = gtk_entry_get_text(GTK_ENTRY(fxcode->codeentry)); ret1 = fetion_directsms_send_subscribe(user , code , &error); gtk_widget_destroy(fxcode->dialog); if(ret1 == PIC_ERROR){ debug_info("%s" , error); free(error); gdk_threads_leave(); goto picreload; }else{ fxconfirm = fx_confirm_new(fxmain); fx_confirm_initialize(fxconfirm); ret2 = gtk_dialog_run(GTK_DIALOG(fxconfirm->dialog)); if(ret2 == GTK_RESPONSE_CANCEL){ memset(text, 0, sizeof(text)); strcpy(text , _("Message sent failed")); fx_dsms_add_information(fxdsms , text); gtk_widget_destroy(fxconfirm->dialog); gdk_threads_leave(); fetion_verification_free(user->verification); user->verification = NULL; break; }else{ memset(user->verification->guid, 0, strlen(user->verification->guid) + 1); strcpy(user->verification->guid , user->mobileno); code = gtk_entry_get_text(GTK_ENTRY(fxconfirm->codeEntry)); ret3 = fetion_directsms_send_option(user , code); gtk_widget_destroy(fxconfirm->dialog); if(ret3 == DSMS_OPTION_SUCCESS){ gdk_threads_leave(); }else{ gdk_threads_leave(); goto picreload; } } } } } memset(text, 0, sizeof(text)); fx_dsms_add_information(fxdsms , text); free(to); }while(gtk_tree_model_iter_next(model , &iter)); return NULL; } static void fx_dsms_send_message(FxDSMS *fxdsms) { GtkTextIter iter , begin , end; GtkTextBuffer *buffer , *buffer1; GtkTextMark *mark; GtkTreeModel *model; GtkTreeView *treeView; GtkTreeIter posIter; FxMain* fxmain = fxdsms->fxmain; User* user = fxmain->user; char text[200] = { 0 }; char time[30] = { 0 }; const char *message; char msg[1024]; struct tm *datetime; treeView = GTK_TREE_VIEW(fxdsms->chooseList); model = gtk_tree_view_get_model(treeView); if(! gtk_tree_model_get_iter_first(model , &posIter)) { fx_util_popup_warning(fxmain , _("Please input a contact")); return; } datetime = get_currenttime(); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxdsms->recvText)); buffer1 = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxdsms->sendText)); gtk_text_buffer_get_start_iter(buffer1 , &begin); gtk_text_buffer_get_end_iter(buffer1 , &end); message = gtk_text_buffer_get_text(buffer1 , &begin , &end , TRUE); if(*message == '\0') return; memset(msg, 0, sizeof(msg)); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxdsms->checkBtn))){ sprintf(msg , "%s:%s" , gtk_entry_get_text(GTK_ENTRY(fxdsms->sigEntry)) , message); }else{ strcpy(msg , message); } strftime(time , sizeof(time) , "%H:%M:%S" , datetime); sprintf(text , _("%s said (%s):\n") , user->nickname , time); gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter , text , -1 , "blue" , NULL); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter, msg , strlen(msg) , "lm10" , NULL); gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark (buffer, mark, &iter); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(fxdsms->recvText), mark); g_thread_create(fx_dsms_send_thread , fxdsms , FALSE , NULL); } static gboolean fx_dsms_on_key_pressed(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data) { FxDSMS *fxdsms = NULL; Config *config = NULL; if(event->keyval == GDK_Return || event->keyval == GDK_ISO_Enter || event->keyval == GDK_KP_Enter) { fxdsms = (FxDSMS*)data; config = fxdsms->fxmain->user->config; if(config->sendMode == SEND_MODE_ENTER) { if(event->state & GDK_CONTROL_MASK || event->state & GDK_SHIFT_MASK){ return FALSE; }else{ if (gtk_im_context_filter_keypress (GTK_TEXT_VIEW(fxdsms->sendText)->im_context, event)) { GTK_TEXT_VIEW (fxdsms->sendText)->need_im_reset = TRUE; return TRUE; } fx_dsms_send_message(fxdsms); return TRUE; } } else { if(event->state & GDK_CONTROL_MASK) { fx_dsms_send_message(fxdsms); return TRUE; }else{ return FALSE; } } } return FALSE; } static void fx_dsms_on_close_clicked(GtkWidget *UNUSED(widget) , gpointer data) { GtkWidget *dialog = GTK_WIDGET(data); gtk_widget_destroy(dialog); } static void fx_dsms_on_send_clicked(GtkWidget *UNUSED(widget) , gpointer data) { fx_dsms_send_message((FxDSMS*)data); } void fx_dsms_initialize(FxDSMS *fxdsms) { FxMain *fxmain = fxdsms->fxmain; User *user = fxmain->user; Config *config = user->config; char path[256]; GtkWidget *infoLabel; GtkWidget *hbox , *lvbox , *rvbox , *rhbox , *okBtn , *cancelBtn; GtkWidget *recvScroll , *sendScroll; GtkTextBuffer *recvBuffer , *sendBuffer; GtkTextIter recvIter ; GdkPixbuf *pb; GtkWidget *portrait , *portraitFrame; GtkWidget *addImage , *addEventBox; GtkBox *abox; fxdsms->dialog = gtk_dialog_new(); gtk_widget_set_usize(fxdsms->dialog , 650 , 490); gtk_window_set_resizable(GTK_WINDOW(fxdsms->dialog) , FALSE); pb = gdk_pixbuf_new_from_file(SKIN_DIR"directsms.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxdsms->dialog) , pb); g_object_unref(pb); gtk_window_set_title(GTK_WINDOW(fxdsms->dialog) , _("SMS directly")); g_signal_connect(fxdsms->dialog , "key-press-event" , G_CALLBACK(key_press_func) , fxdsms); infoLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(infoLabel) , _(" You will send SMS to contact directly, cost 0.1 RMB/SMS.")); gtk_misc_set_alignment(GTK_MISC(infoLabel) , 0 , 0); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(fxdsms->dialog)->vbox) , infoLabel , FALSE , TRUE , 10); hbox = gtk_hbox_new(FALSE , 0); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxdsms->dialog)->vbox) , hbox); lvbox = gtk_vbox_new(FALSE , 0); rvbox = gtk_vbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(hbox) , lvbox , TRUE , TRUE , 10); gtk_box_pack_start(GTK_BOX(hbox) , rvbox , FALSE , FALSE , 5); /*left box*/ recvScroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(lvbox) , recvScroll , TRUE , TRUE , 5); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(recvScroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(recvScroll) , GTK_SHADOW_ETCHED_IN); fxdsms->recvText = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxdsms->recvText) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxdsms->recvText) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxdsms->recvText) , FALSE); gtk_container_add(GTK_CONTAINER(recvScroll) , fxdsms->recvText); recvBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxdsms->recvText)); gtk_text_buffer_create_tag(recvBuffer , "blue" , "foreground" , "#639900" , NULL); gtk_text_buffer_create_tag(recvBuffer , "grey" , "foreground" , "#808080" , NULL); gtk_text_buffer_create_tag(recvBuffer , "lm10" , "left_margin" , 10 , NULL); gtk_text_buffer_get_end_iter(recvBuffer , &recvIter); gtk_text_buffer_create_mark(recvBuffer , "scroll" , &recvIter , FALSE); sendScroll = gtk_scrolled_window_new(NULL , NULL); gtk_widget_set_usize(sendScroll , 0 , 120); gtk_box_pack_start(GTK_BOX(lvbox) , sendScroll , FALSE , TRUE , 5); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sendScroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sendScroll) , GTK_SHADOW_ETCHED_OUT); fxdsms->sendText = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxdsms->sendText) , GTK_WRAP_CHAR); gtk_container_add(GTK_CONTAINER(sendScroll) , fxdsms->sendText); sendBuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxdsms->sendText)); g_signal_connect(sendBuffer , "changed" , G_CALLBACK(fx_dsms_on_text_buffer_changed) , fxdsms); g_signal_connect(fxdsms->sendText , "key_press_event" , G_CALLBACK(fx_dsms_on_key_pressed) , fxdsms); /*right box*/ rhbox = gtk_hbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(rvbox) , rhbox , FALSE , FALSE , 5); fxdsms->numberEntry = gtk_entry_new(); gtk_widget_set_usize(fxdsms->numberEntry , 140 , 20); gtk_box_pack_start(GTK_BOX(rhbox) , fxdsms->numberEntry , FALSE , FALSE , 0); g_signal_connect(fxdsms->numberEntry , "activate" , G_CALLBACK(fx_dsms_number_clicked) , fxdsms); addEventBox = gtk_event_box_new(); addImage = gtk_image_new_from_file(SKIN_DIR"add.png"); gtk_container_add(GTK_CONTAINER(addEventBox) , addImage); gtk_box_pack_start(GTK_BOX(rhbox) , addEventBox , FALSE , FALSE , 2); gtk_widget_set_events(addEventBox , GDK_MOTION_NOTIFY | GDK_BUTTON_PRESS | GDK_BUTTON_RELEASE | GDK_ENTER_NOTIFY | GDK_LEAVE_NOTIFY); g_signal_connect(G_OBJECT(addEventBox) , "button_press_event" , GTK_SIGNAL_FUNC(fx_dsms_add_contact) , fxdsms); GtkTreeModel *model = create_model(); fxdsms->chooseList = gtk_tree_view_new_with_model(model); create_column(fxdsms->chooseList); gtk_tree_view_set_show_expanders(GTK_TREE_VIEW(fxdsms->chooseList) , FALSE); gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(fxdsms->chooseList) , -30); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(fxdsms->chooseList) , FALSE); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (fxdsms->chooseList), TRUE); gtk_box_pack_start(GTK_BOX(rvbox) , fxdsms->chooseList , TRUE , TRUE , 0); g_signal_connect(fxdsms->chooseList , "button_press_event" , G_CALLBACK(fx_dsms_on_rightbutton_click) , fxdsms); fxdsms->msgLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(fxdsms->msgLabel) , _("No Contact\n\n" "Please input Phone Number\nin the input box above\n" "3 contacts allowed at most")); gtk_box_pack_start(GTK_BOX(rvbox) , fxdsms->msgLabel , TRUE , FALSE , 0); portraitFrame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(portraitFrame) , GTK_SHADOW_ETCHED_IN); gtk_widget_set_usize(portraitFrame , 160 , 160); snprintf(path, sizeof(path) - 1 , "%s/%s.jpg" , config->iconPath , user->sId); pb = gdk_pixbuf_new_from_file_at_size(path , 140 , 140 , NULL); portrait = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_container_add(GTK_CONTAINER(portraitFrame) , portrait); gtk_box_pack_start(GTK_BOX(rvbox) , portraitFrame , FALSE , FALSE , 2); /* bottom box */ abox = GTK_BOX(gtk_hbox_new(FALSE , 2)); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxdsms->dialog)->action_area) , GTK_WIDGET(abox)); fxdsms->countLabel = gtk_label_new(_("0/180, will split to 0")); gtk_misc_set_alignment(GTK_MISC(fxdsms->countLabel) , 0 , 0.5); gtk_box_pack_start(abox , fxdsms->countLabel , TRUE , FALSE , 0); fxdsms->checkBtn = gtk_check_button_new_with_label(_("Sign")); g_signal_connect(fxdsms->checkBtn , "toggled" , G_CALLBACK(fx_dsms_sig_checked) , fxdsms); gtk_box_pack_start(abox , fxdsms->checkBtn , FALSE , FALSE , 0); fxdsms->sigEntry = gtk_entry_new(); gtk_entry_set_text(GTK_ENTRY(fxdsms->sigEntry) , user->nickname); gtk_widget_set_sensitive(fxdsms->sigEntry , FALSE); gtk_widget_set_usize(fxdsms->sigEntry , 100 , 0); gtk_box_pack_start(abox , fxdsms->sigEntry , FALSE , FALSE , 0); okBtn = gtk_button_new_with_label(_("Send")); gtk_widget_set_usize(okBtn , 100 , 0); g_signal_connect(okBtn , "clicked" , G_CALLBACK(fx_dsms_on_send_clicked) , fxdsms); cancelBtn = gtk_button_new_with_label(_("Close")); g_signal_connect(cancelBtn , "clicked" , G_CALLBACK(fx_dsms_on_close_clicked) , fxdsms->dialog); gtk_widget_set_usize(cancelBtn , 100 , 0); gtk_box_pack_start(abox , cancelBtn , FALSE , FALSE , 0); gtk_box_pack_start(abox , okBtn , FALSE , FALSE , 0); GTK_WIDGET_SET_FLAGS(fxdsms->sendText, GTK_CAN_FOCUS); gtk_widget_grab_focus(fxdsms->sendText); gtk_widget_show_all(fxdsms->dialog); gtk_widget_hide(fxdsms->chooseList); } static gboolean key_press_func(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data) { FxDSMS *fxdsms ; if(event->keyval == GDK_w){ if(event->state & GDK_CONTROL_MASK){ fxdsms = (FxDSMS*)data; gtk_widget_destroy(fxdsms->dialog); return TRUE; }else{ return FALSE; } } return FALSE; } openfetion-2.2.1/src/fx_dsms.h0000644000175000017500000000515311561721144014753 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_DSMS_H #define FX_DSMS_H enum{ PIXBUF_COL , NUMBER_COL , COL_SIZE }; struct deleteargs{ FxDSMS *fxdsms; GtkTreeIter iter; }; extern FxConfirm* fx_confirm_new(FxMain *fxmain); extern void fx_confirm_initialize(FxConfirm *fxconfirm); extern FxDSMS* fx_dsms_new(FxMain *fxmain); extern void fx_dsms_initialize(FxDSMS *fxdsms); #endif openfetion-2.2.1/src/fx_edit.c0000644000175000017500000001257011561721144014726 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxEdit* fx_edit_new(FxMain* fxmain , GtkTreeIter iter , const char* userid) { FxEdit* fxedit = (FxEdit*)malloc(sizeof(FxEdit)); memset(fxedit , 0 , sizeof(FxEdit)); fxedit->fxmain = fxmain; fxedit->iter = iter; strcpy(fxedit->userid , userid); return fxedit; } void fx_edit_initialize(FxEdit* fxedit) { GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg", 22 , 22, NULL); fxedit->dialog = gtk_dialog_new(); gtk_window_set_icon(GTK_WINDOW(fxedit->dialog) , pb); gtk_window_set_title(GTK_WINDOW(fxedit->dialog) , _("Edit note name")); gtk_window_set_modal(GTK_WINDOW(fxedit->dialog) , TRUE); gtk_dialog_set_has_separator(GTK_DIALOG(fxedit->dialog) , FALSE); gtk_window_set_resizable(GTK_WINDOW(fxedit->dialog) , FALSE); gtk_widget_set_usize(fxedit->dialog , 300 , 150); gtk_container_set_border_width(GTK_CONTAINER(fxedit->dialog) , 20); fxedit->remark_label = gtk_label_new(_("Please input note name:")); gtk_misc_set_alignment(GTK_MISC(fxedit->remark_label) , 0 , 0 ); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxedit->dialog)->vbox) , fxedit->remark_label); fxedit->remark_entry = gtk_entry_new(); g_signal_connect(fxedit->remark_entry , "activate" , G_CALLBACK(fx_edit_on_ok_clicked) , fxedit); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxedit->dialog)->vbox) , fxedit->remark_entry); fxedit->ok_button = gtk_button_new_with_label(_("OK")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxedit->dialog)->action_area) , fxedit->ok_button); g_signal_connect(fxedit->ok_button , "clicked" , G_CALLBACK(fx_edit_on_ok_clicked) , fxedit); fxedit->cancel_button = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxedit->dialog)->action_area) , fxedit->cancel_button); g_signal_connect(fxedit->cancel_button , "clicked" , G_CALLBACK(fx_edit_on_cancel_clicked) , fxedit->dialog); gtk_widget_show_all(fxedit->dialog); } void fx_edit_free(FxEdit* fxedit) { free(fxedit); } void fx_edit_on_ok_clicked(GtkWidget* UNUSED(widget), gpointer data) { FxEdit* fxedit = (FxEdit*)data; FxMain* fxmain = fxedit->fxmain; User* user = fxmain->user; GtkTreeView* tree = GTK_TREE_VIEW(fxmain->mainPanel->treeView); GtkTreeModel* model = gtk_tree_view_get_model(tree); GtkTreeIter iter; Contact *contact; const char* name = gtk_entry_get_text(GTK_ENTRY(fxedit->remark_entry)); if(*name == '\0') return; if(fetion_contact_set_displayname(user , fxedit->userid , name) == 0) { contact = fetion_contact_list_find_by_userid(user->contactList, fxedit->userid); foreach_groupids(contact->groupids) { if(fx_tree_get_buddy_iter(model, group_id, fxedit->userid, &iter) == -1) continue; gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , B_NAME_COL , name , -1); } end_groupids(contact->groupids) gtk_dialog_response(GTK_DIALOG(fxedit->dialog) , GTK_RESPONSE_OK); } else { gtk_dialog_response(GTK_DIALOG(fxedit->dialog) , GTK_RESPONSE_CANCEL); } } void fx_edit_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data) { GtkWidget* dialog = (GtkWidget*)data; gtk_dialog_response(GTK_DIALOG(dialog) , GTK_RESPONSE_CANCEL); } openfetion-2.2.1/src/fx_edit.h0000644000175000017500000000520711561721144014732 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_EDIT_H #define FX_EDIT_H extern FxEdit* fx_edit_new(FxMain* fxmain , GtkTreeIter iter , const char* userid); extern void fx_edit_initialize(FxEdit* fxedit); extern void fx_edit_free(FxEdit* fxedit); extern void fx_edit_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_edit_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_emotion.c0000644000175000017500000001611611561721144015453 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" struct emotion emotions[] = { { N_("Smile") , ":)", 1 } , { N_("Laugh") , ":-d", 2 } , { N_("Wink") , ";)", 3 } , { N_("Surprised") , ":-o", 4 } , { N_("Tongue smile") , ":-p", 5 } , { N_("Warm smile") , "(h)", 6 } , { N_("Angry") , ":-@", 7 } , { N_("Sad") , ":(", 8 } , { N_("Cry") , ":'(", 9 } , { N_("Awkward") , ":\">", 10 } , { N_("Irony") , "^o)", 11 } , { N_("Illed") , ":&", 12 } , { N_("Gritting my teeth") , "8o|", 13 } , { N_("Tired") , "|-)", 14 } , { N_("Secrecy") , ":-#", 15 } , { N_("Googly eyes") , "8-)", 16 } , { N_("Sleeping Moon") , "(s)", 17 } , { N_("Rain") , "(st)", 18 } , { N_("Clock") , "(o)", 19 } , { N_("Red Heart") , "(l)", 20 } , { N_("Broken Heart") , "(u)", 21 } , { N_("Face of Cat") , "(@)", 22 } , { N_("Face of Dog") , "(&)", 23 } , { N_("Snail") , "(sn)", 24 } , { N_("Star") , "(*)", 25 } , { N_("Sun") , "(#)", 26 } , { N_("Rainbow") , "(r)", 27 } , { N_("Hug left") , "({)", 28 } , { N_("Hug right") , "(})", 29 } , { N_("Red Lips") , "(k)", 30 } , { N_("Red Rose") , "(f)", 31 } , { N_("Withered Rose") , "(w)", 32 } , { N_("Gift Box") , "(g)", 33 } , { N_("Birthday Cake") , "(^)", 34 } , { N_("Music") , "(8)", 35 } , { N_("Bulb") , "(i)", 36 } , { N_("Idea") , "*-:)", 37 } , { N_("Coffee") , "(c)", 38 } , { N_("Umbrella") , "(um)", 39 } , { N_("Mobile Phone") , "(mp)", 40 } , { N_("Computer") , "(co)", 41 } , { N_("Disappointed") , ":-|", 42 } , { N_("Confused") , ":-/", 43 } , { N_("Worried") , ":s", 44 } , { N_("Drinks") , ")-|", 45 } , { N_("Goblet") , "(d)", 46 } , { N_("Angel") , "O:)", 47 } , { N_("Thinking") , ":-?", 48 } , { N_("Great") , "(y)", 49 } , { N_("Naughty") , ">:)", 50 } , { N_("Idiot") , ":-b", 51 } , { N_("Sunglasses") , "b)", 52 } , { "" , "" , 0} }; FxEmotion *fx_emotion_new(FxChat *fxchat) { FxEmotion *fxemotion = (FxEmotion*)malloc(sizeof(FxEmotion)); fxemotion->fxchat = fxchat; return fxemotion; } static gboolean fx_emotion_focus_out(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data) { FxEmotion *fxemotion = (FxEmotion*)data; gtk_widget_destroy(fxemotion->dialog); free(fxemotion); return TRUE; } static gboolean fx_emotion_ok_clicked(GtkWidget *UNUSED(widget) , GdkEventButton *UNUSED(event) , gpointer data) { struct args{ FxEmotion *fxemotion; int id; } *emotionArgs = (struct args *)data; FxEmotion *fxemotion = emotionArgs->fxemotion; FxChat *fxchat = fxemotion->fxchat; GtkTextBuffer* buffer; GtkTextIter iter; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxchat->send_text)); gtk_text_buffer_get_end_iter(buffer , &iter); gtk_text_buffer_insert(buffer , &iter , emotions[emotionArgs->id - 1].symbol , -1); free(emotionArgs); gtk_widget_destroy(fxemotion->dialog); free(fxemotion); return FALSE; } void fx_emotion_initialize(FxEmotion *fxemotion , int x , int y) { GtkWidget *table; GtkWidget *frame , *subframe; GtkWidget *img , *eventbox; int i = 0 , j = 0 , k = 0; char path[1024]; struct args{ FxEmotion *fxemotion; int id; } *emotionArgs; fxemotion->dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_decorated(GTK_WINDOW(fxemotion->dialog) , FALSE); gtk_window_set_type_hint(GTK_WINDOW(fxemotion->dialog), GDK_WINDOW_TYPE_HINT_DIALOG); gtk_widget_set_name(fxemotion->dialog , "mainwindow"); gtk_window_set_default_size(GTK_WINDOW(fxemotion->dialog) , 300 , 180); gtk_window_set_skip_taskbar_hint (GTK_WINDOW(fxemotion->dialog), TRUE); gtk_window_move(GTK_WINDOW(fxemotion->dialog) , x , y); table = gtk_table_new(10 , 6 , FALSE); gtk_widget_set_usize(table , 300 , 180); frame = gtk_frame_new(NULL); gtk_widget_set_events(fxemotion->dialog , GDK_ALL_EVENTS_MASK); g_signal_connect(fxemotion->dialog , "focus-out-event" , GTK_SIGNAL_FUNC(fx_emotion_focus_out) , fxemotion); for( j = 0 ; j < 6 ; j ++){ for( i = 0 ; i < 10 ; i ++){ subframe = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(subframe) , GTK_SHADOW_ETCHED_IN); memset(path, 0, sizeof(path)); if( k < 52 ){ sprintf(path , SKIN_DIR"face_images/%d.gif" , (k++) + 1); img = gtk_image_new_from_file(path); if(!img) continue; eventbox = gtk_event_box_new(); gtk_widget_set_tooltip_markup(eventbox , _(emotions[k - 1].name)); gtk_container_add(GTK_CONTAINER(eventbox) , img); emotionArgs = (struct args *)malloc(sizeof(struct args)); emotionArgs->fxemotion = fxemotion; emotionArgs->id = k; g_signal_connect(eventbox , "button-press-event" , GTK_SIGNAL_FUNC(fx_emotion_ok_clicked) , emotionArgs); gtk_container_add(GTK_CONTAINER(subframe) , eventbox); } gtk_table_attach_defaults(GTK_TABLE(table) , subframe , i , i + 1 , j , j + 1); } } gtk_container_add(GTK_CONTAINER(frame) , table); gtk_container_add(GTK_CONTAINER(fxemotion->dialog) , frame); gtk_widget_show_all(fxemotion->dialog); } openfetion-2.2.1/src/fx_emotion.h0000644000175000017500000000477711561721144015472 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_EMOTION_H #define FX_EMOTION_H struct emotion{ const char* name; const char* symbol; int id; }; extern FxEmotion *fx_emotion_new(FxChat *fxchat); extern void fx_emotion_initialize(FxEmotion *fxemotion , int x , int y); #endif openfetion-2.2.1/src/fx_gedit.c0000644000175000017500000001234611561721144015076 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxGEdit* fx_gedit_new(FxMain* fxmain , GtkTreeIter iter , int groupid) { FxGEdit* fxgedit = (FxGEdit*)malloc(sizeof(FxGEdit)); memset(fxgedit , 0 , sizeof(FxGEdit)); fxgedit->fxmain = fxmain; fxgedit->iter = iter; fxgedit->groupid = groupid; return fxgedit; } void fx_gedit_initialize(FxGEdit* fxgedit) { fxgedit->dialog = gtk_dialog_new(); GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg", 22 ,22,NULL); gtk_window_set_icon(GTK_WINDOW(fxgedit->dialog) , pb); g_object_unref(pb); gtk_window_set_title(GTK_WINDOW(fxgedit->dialog) , _("Edit name of a group")); gtk_window_set_modal(GTK_WINDOW(fxgedit->dialog) , TRUE); gtk_dialog_set_has_separator(GTK_DIALOG(fxgedit->dialog) , FALSE); gtk_window_set_resizable(GTK_WINDOW(fxgedit->dialog) , FALSE); gtk_widget_set_usize(fxgedit->dialog , 300 , 150); gtk_container_set_border_width(GTK_CONTAINER(fxgedit->dialog) , 20); fxgedit->remark_label = gtk_label_new(_("Please entry new name of the group:")); gtk_misc_set_alignment(GTK_MISC(fxgedit->remark_label) , 0 , 0 ); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxgedit->dialog)->vbox) , fxgedit->remark_label); fxgedit->remark_entry = gtk_entry_new(); g_signal_connect(fxgedit->remark_entry , "activate" , G_CALLBACK(fx_gedit_on_ok_clicked) , fxgedit); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxgedit->dialog)->vbox) , fxgedit->remark_entry); fxgedit->ok_button = gtk_button_new_with_label(_("OK")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxgedit->dialog)->action_area) , fxgedit->ok_button); g_signal_connect(fxgedit->ok_button , "clicked" , G_CALLBACK(fx_gedit_on_ok_clicked) , fxgedit); fxgedit->cancel_button = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxgedit->dialog)->action_area) , fxgedit->cancel_button); g_signal_connect(fxgedit->cancel_button , "clicked" , G_CALLBACK(fx_gedit_on_cancel_clicked) , fxgedit->dialog); gtk_widget_show_all(fxgedit->dialog); } void fx_gedit_free(FxGEdit* fxgedit) { free(fxgedit); } void fx_gedit_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxGEdit* fxgedit = (FxGEdit*)data; FxMain* fxmain = fxgedit->fxmain; User* user = fxmain->user; GtkTreeView* tree = GTK_TREE_VIEW(fxmain->mainPanel->treeView); GtkTreeModel* model = gtk_tree_view_get_model(tree); GtkTreeIter iter = fxgedit->iter; int groupid = fxgedit->groupid; const char* name = gtk_entry_get_text(GTK_ENTRY(fxgedit->remark_entry)); if(*name == '\0') return; if(fetion_buddylist_edit(user , groupid , name) > 0) { gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , G_NAME_COL , name , -1); gtk_dialog_response(GTK_DIALOG(fxgedit->dialog) , GTK_RESPONSE_OK); } else { gtk_dialog_response(GTK_DIALOG(fxgedit->dialog) , GTK_RESPONSE_CANCEL); } } void fx_gedit_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data) { GtkWidget* dialog = (GtkWidget*)data; gtk_dialog_response(GTK_DIALOG(dialog) , GTK_RESPONSE_CANCEL); } openfetion-2.2.1/src/fx_gedit.h0000644000175000017500000000521311561721144015076 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_GEDIT_H #define FX_GEDIT_H extern FxGEdit* fx_gedit_new(FxMain* fxmain , GtkTreeIter iter , int groupid); extern void fx_gedit_initialize(FxGEdit* fxgedit); extern void fx_gedit_free(FxGEdit* fxgedit); extern void fx_gedit_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_gedit_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_head.c0000644000175000017500000005175111561721144014706 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" extern int old_state; FxHead* fx_head_new() { FxHead* fxhead = (FxHead*)malloc(sizeof(FxHead)); memset(fxhead , 0 , sizeof(FxHead)); return fxhead; } void fx_head_free(FxHead* fxhead) { if(fxhead != NULL) free(fxhead); } void fx_head_initialize(FxMain* fxmain) { GdkPixbuf* pb; GtkWidget *vbox , *headbox , *alignment , *halign; GtkWidget* hbox = gtk_hbox_new(FALSE , 0); FxHead* fxhead = fx_head_new(); fxmain->headPanel = fxhead; halign = gtk_alignment_new(0, 0 , 0 , 0); gtk_container_add(GTK_CONTAINER(halign) , hbox); pb = gdk_pixbuf_new_from_file_at_scale(SKIN_DIR"fetion.svg", USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, TRUE, NULL); fxhead->portrait = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); GtkWidget *frame; frame = gtk_frame_new(NULL); gtk_widget_set_usize(frame , 55 , 55); fxhead->portraitbox = gtk_event_box_new(); gtk_container_add(GTK_CONTAINER(fxhead->portraitbox) , fxhead->portrait); gtk_container_add(GTK_CONTAINER(frame) , fxhead->portraitbox); gtk_box_pack_start(GTK_BOX(hbox) , frame , FALSE , FALSE , 10 ); g_signal_connect(G_OBJECT(fxhead->portraitbox) , "button_press_event" , GTK_SIGNAL_FUNC(fx_head_change_portrait_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->portraitbox) , "enter_notify_event" , GTK_SIGNAL_FUNC(fx_head_change_portrait_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->portraitbox) , "leave_notify_event" , GTK_SIGNAL_FUNC(fx_head_change_portrait_func) , fxmain); vbox = gtk_vbox_new(TRUE , 0); headbox = gtk_hbox_new(FALSE , 0); fxhead->state_button = gtk_event_box_new(); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , 20 , 20 , FALSE); fxhead->state_img = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_container_add(GTK_CONTAINER(fxhead->state_button) , fxhead->state_img); gtk_widget_set_events(fxhead->state_button , GDK_MOTION_NOTIFY | GDK_BUTTON_PRESS | GDK_BUTTON_RELEASE | GDK_ENTER_NOTIFY | GDK_LEAVE_NOTIFY); g_signal_connect(G_OBJECT(fxhead->state_button) , "button_press_event" , GTK_SIGNAL_FUNC(fx_head_popup_statemenu_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->state_button) , "enter_notify_event" , GTK_SIGNAL_FUNC(fx_head_popup_statemenu_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->state_button) , "leave_notify_event" , GTK_SIGNAL_FUNC(fx_head_popup_statemenu_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->portraitbox) , "leave_notify_event" , GTK_SIGNAL_FUNC(fx_head_change_portrait_func) , fxmain); gtk_box_pack_start(GTK_BOX(headbox) , fxhead->state_button , TRUE , TRUE , 0); fxhead->name_label = gtk_label_new(NULL); fxhead->state_label = gtk_label_new(NULL); gtk_box_pack_start(GTK_BOX(headbox) , fxhead->name_label , TRUE , TRUE , 0); gtk_box_pack_start(GTK_BOX(headbox) , fxhead->state_label , TRUE , TRUE , 0); fxhead->impre_box = gtk_event_box_new(); g_signal_connect(G_OBJECT(fxhead->impre_box) , "button_press_event" , GTK_SIGNAL_FUNC(fx_head_impre_event_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->impre_box) , "button_release_event" , GTK_SIGNAL_FUNC(fx_head_impre_event_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->impre_box) , "enter_notify_event" , GTK_SIGNAL_FUNC(fx_head_impre_event_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->impre_box) , "leave_notify_event" , GTK_SIGNAL_FUNC(fx_head_impre_event_func) , fxmain); fxhead->impre_entry = gtk_entry_new(); g_signal_connect(G_OBJECT(fxhead->impre_entry) , "focus-out-event" , GTK_SIGNAL_FUNC(fx_head_impre_focus_out_func) , fxmain); g_signal_connect(G_OBJECT(fxhead->impre_entry) , "activate" , G_CALLBACK(fx_head_impre_activate_func) , fxmain); fxhead->impre_label = gtk_label_new(NULL); gtk_label_set_width_chars(GTK_LABEL(fxhead->impre_label) , 15); gtk_misc_set_alignment(GTK_MISC(fxhead->impre_label) , 0 , 0); alignment = gtk_alignment_new(0 , 0 , 0 , 0); gtk_container_add(GTK_CONTAINER(alignment) , headbox); gtk_box_pack_start(GTK_BOX(vbox) , alignment , FALSE , TRUE , 0); gtk_container_add(GTK_CONTAINER(fxhead->impre_box) , fxhead->impre_label); gtk_box_pack_start(GTK_BOX(vbox) , fxhead->impre_box , FALSE , FALSE , 0); gtk_box_pack_start(GTK_BOX(vbox) , fxhead->impre_entry , FALSE , FALSE , 0); gtk_box_pack_start(GTK_BOX(hbox) , vbox , FALSE , TRUE , 10); fxhead->topbox = gtk_hbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(fxhead->topbox) , halign , FALSE , FALSE , 0); gtk_box_pack_start(GTK_BOX(fxmain->mainbox) , fxhead->topbox , FALSE , FALSE , 10); fx_head_bind(fxmain); } void fx_head_show(FxMain *fxmain) { FxHead *fxhead = fxmain->headPanel; gtk_widget_show_all(fxhead->topbox); gtk_widget_hide(fxhead->impre_entry); } void fx_head_bind(FxMain* fxmain) { FxHead* fxhead = fxmain->headPanel; User* user = fxmain->user; Config* config = user->config; char name[256]; char tooltip[1024]; char* statename = NULL; GdkPixbuf* portrait_pix = NULL; memset(fxhead->oldimpression, 0, sizeof(fxhead->oldimpression)); snprintf(name, sizeof(name) - 1 , "%s" , user->nickname == NULL ? user->sId : g_markup_escape_text(user->nickname, -1) ); gtk_label_set_markup(GTK_LABEL(fxhead->name_label), name ); strcpy(fxhead->oldimpression , (strlen(user->impression) == 0 || user->impression == NULL) ? _("Click here to input signature") : user->impression); sprintf(tooltip, "%s", g_markup_escape_text(user->impression, strlen(user->impression))); gtk_widget_set_tooltip_markup(fxhead->impre_label, tooltip); escape_impression(fxhead->oldimpression); gtk_label_set_text(GTK_LABEL(fxhead->impre_label), fxhead->oldimpression); sprintf(name , "%s/%s.jpg" , config->iconPath , user->sId); portrait_pix = gdk_pixbuf_new_from_file_at_size(name, USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, NULL); if(! portrait_pix) portrait_pix = gdk_pixbuf_new_from_file_at_size(name, USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, NULL); if(portrait_pix) gtk_image_set_from_pixbuf(GTK_IMAGE(fxhead->portrait) , portrait_pix); statename = fx_util_get_state_name(user->state); gtk_label_set_markup(GTK_LABEL(fxhead->state_label) , statename); fx_head_set_state_image(fxmain , user->state); free(statename); } void fx_head_set_state_image(FxMain* fxmain , StateType type) { FxHead *fxhead = fxmain->headPanel; GdkPixbuf *pixbuf; gchar *statename = fx_util_get_state_name(type); gint use_status_icon = USE_STATUS_ICON(fxmain->user->config); gtk_label_set_markup(GTK_LABEL(fxhead->state_label) , statename); switch(type) { case P_ONLINE : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , 20 , 20 , NULL); if(use_status_icon) gtk_status_icon_set_from_file(fxmain->trayIcon, SKIN_DIR"online.svg"); break; case P_BUSY : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"busy.svg" , 20 , 20 , NULL); if(use_status_icon) gtk_status_icon_set_from_file(fxmain->trayIcon, SKIN_DIR"busy.svg"); break; case P_HIDDEN : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"invisible.svg" , 20 , 20 , NULL); if(use_status_icon) gtk_status_icon_set_from_file(fxmain->trayIcon, SKIN_DIR"invisible.svg"); break; case P_OFFLINE : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"offline.svg" , 20 , 20 , NULL); if(use_status_icon) gtk_status_icon_set_from_file(fxmain->trayIcon, SKIN_DIR"offline.svg"); gtk_widget_set_sensitive(fxhead->portrait, FALSE); break; default : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"away.svg" , 20 , 20 , NULL); if(use_status_icon) gtk_status_icon_set_from_file(fxmain->trayIcon, SKIN_DIR"away.svg"); break; } gtk_image_set_from_pixbuf(GTK_IMAGE(fxhead->state_img) , pixbuf); g_object_unref(pixbuf); free(statename); } void fx_head_popup_statemenu_func(GtkWidget* widget , GdkEventButton* event , gpointer data) { FxMain* fxmain = (FxMain*)data; User *user = fxmain->user; GtkWidget *item; GtkWidget *img; GtkWidget *separator; GdkCursor *cursor; GtkWidget *presence_menu = gtk_menu_new(); if(event->type == GDK_ENTER_NOTIFY) { cursor = gdk_cursor_new (GDK_HAND2); gdk_window_set_cursor(widget->window , cursor); return; } if(event->type == GDK_LEAVE_NOTIFY) { cursor = gdk_cursor_new (GDK_LEFT_PTR); gdk_window_set_cursor(widget->window , cursor); return; } fx_head_create_presence_item(P_ONLINE , _("Online") , presence_menu , fxmain); fx_head_create_presence_item(P_AWAY , _("Leave") , presence_menu , fxmain); fx_head_create_presence_item(P_BUSY , _("Busy") , presence_menu , fxmain); fx_head_create_presence_item(P_HIDDEN , _("Hide") , presence_menu , fxmain); fx_head_create_presence_item(P_OFFLINE , _("Offline") , presence_menu , fxmain); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(presence_menu) , separator); fx_head_create_presence_item(P_OUTFORLUNCH , _("Eating out") , presence_menu , fxmain); fx_head_create_presence_item(P_DONOTDISTURB , _("Do Not Disturb") , presence_menu , fxmain); fx_head_create_presence_item(P_MEETING , _("Meeting") , presence_menu , fxmain); fx_head_create_presence_item(P_ONTHEPHONE , _("Calling") , presence_menu , fxmain); separator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(presence_menu) , separator); item = gtk_check_menu_item_new_with_label(_("Receive SMS")); if(strcmp(user->smsOnLineStatus , "0.00:00:00") && strcmp(user->smsOnLineStatus , "0.0:0:0")) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item) , FALSE); else gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item) , TRUE); gtk_menu_shell_append(GTK_MENU_SHELL(presence_menu) , item); g_signal_connect(item , "activate" , G_CALLBACK(fx_head_set_sms_clicked) , fxmain); item = gtk_image_menu_item_new_with_label(_("Modify Profile")); img = gtk_image_new_from_file(SKIN_DIR"edit.png"); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img); gtk_menu_shell_append(GTK_MENU_SHELL(presence_menu) , item); g_signal_connect(item , "activate" , G_CALLBACK(fx_bottom_on_setting_clicked) , fxmain); item = gtk_image_menu_item_new_with_label(_("Exit OpenFetion ")); img = gtk_image_new_from_file(SKIN_DIR"exit.png"); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img); gtk_menu_shell_append(GTK_MENU_SHELL(presence_menu) , item); g_signal_connect(item , "activate" , G_CALLBACK(fx_main_destroy) , fxmain); gtk_widget_show_all(presence_menu); gtk_menu_popup(GTK_MENU(presence_menu) , NULL , NULL , NULL , NULL , (event != NULL) ? event->button : 0 , gdk_event_get_time((GdkEvent*)event)); } void fx_head_create_presence_item(int type , const char* message , GtkWidget* menu , FxMain* fxmain) { typedef struct { FxMain *fxmain; StateType type; } Args1; GtkWidget* item = gtk_image_menu_item_new_with_label(message); GtkWidget* item_img = NULL; GdkPixbuf *pixbuf; Args1 *args = (Args1*)malloc(sizeof(Args1)); args->fxmain = fxmain; args->type = type; g_signal_connect(item , "activate" , G_CALLBACK(fx_head_change_state_func) , args); switch(type) { case P_ONLINE : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , 20 , 20 , NULL); break; case P_BUSY : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"busy.svg" , 20 , 20 , NULL); break; case P_HIDDEN : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"invisible.svg" , 20 , 20 , NULL); break; case P_OFFLINE : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"offline.svg", 20, 20, NULL); break; default : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"away.svg" , 20 , 20 , NULL); break; } item_img = gtk_image_new_from_pixbuf(pixbuf); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , item_img); g_object_unref(pixbuf); gtk_menu_shell_append(GTK_MENU_SHELL(menu) , item); } void fx_head_impre_event_func(GtkWidget* widget , GdkEventButton* event , gpointer data) { FxMain* fxmain = (FxMain*)data; FxHead* fxhead = fxmain->headPanel; GdkColor color; gdk_color_parse ("white", &color); GdkCursor* cursor = NULL; const char* text = NULL; switch(event->type) { case GDK_BUTTON_PRESS : if(fx_conn_check_action(fxmain)){ gtk_widget_show(fxhead->impre_entry); text = gtk_label_get_text(GTK_LABEL(fxhead->impre_label)); gtk_entry_set_text(GTK_ENTRY(fxhead->impre_entry) , text); gtk_entry_select_region(GTK_ENTRY(fxhead->impre_entry) , 0 , strlen(text)); gtk_widget_grab_focus(fxhead->impre_entry); gtk_widget_hide(widget); } break; case GDK_ENTER_NOTIFY : gtk_widget_modify_bg(fxhead->impre_box, GTK_STATE_NORMAL, &color); cursor = gdk_cursor_new (GDK_HAND2); gdk_window_set_cursor(widget->window , cursor); break; case GDK_LEAVE_NOTIFY : gtk_widget_modify_bg(fxhead->impre_box, GTK_STATE_NORMAL, NULL); cursor = gdk_cursor_new (GDK_LEFT_PTR); gdk_window_set_cursor(widget->window , cursor); break; default: break; }; } gboolean fx_head_impre_focus_out_func(GtkWidget* UNUSED(widget) , GdkEventFocus* UNUSED(event) , gpointer data) { FxMain* fxmain = (FxMain*)data; FxHead* fxhead = fxmain->headPanel; gtk_widget_show(fxhead->impre_box); gtk_widget_hide(fxhead->impre_entry); return FALSE; } gboolean fx_head_impre_activate_func(GtkWidget* widget , gpointer data) { FxMain* fxmain = (FxMain*)data; FxHead* fxhead = fxmain->headPanel; gchar tooltip[1024]; const gchar* impression = gtk_entry_get_text(GTK_ENTRY(widget)); gtk_widget_show(fxhead->impre_box); gtk_widget_hide(widget); if(strcmp(impression , fxhead->oldimpression) == 0) return FALSE; if(fetion_user_set_moodphrase(fxmain->user , impression) > 0) { gtk_label_set_text(GTK_LABEL(fxhead->impre_label) , impression); memset(fxhead->oldimpression, 0, sizeof(fxhead->oldimpression)); strcpy(fxhead->oldimpression , impression); memset(tooltip, 0, sizeof(tooltip)); sprintf(tooltip , "%s" , g_markup_escape_text(impression, -1)); gtk_widget_set_tooltip_markup(fxhead->impre_label , tooltip); } return TRUE; } static void* reconnection_func(void *data) { typedef struct { FxMain *fxmain; StateType type; } Args1; Args1 *args = (Args1*)data; FxMain *fxmain = args->fxmain; FxHead *fxhead = fxmain->headPanel; gdk_threads_enter(); gtk_image_set_from_file(GTK_IMAGE(fxhead->portrait), SKIN_DIR"reconnecting.gif"); gdk_threads_leave(); fx_conn_reconnect(fxmain, args->type); return NULL; } void fx_head_change_state_func(GtkWidget* UNUSED(widget) , gpointer data) { typedef struct { FxMain *fxmain; StateType type; } Args1; Args1 *args = (Args1*)data; FxMain *fxmain = args->fxmain; User *user = fxmain->user; if(args->type == P_OFFLINE){ fx_conn_offline(fxmain); g_free(args); return; } if(user->state == P_OFFLINE){ g_thread_create(reconnection_func, args, FALSE, NULL); return; } if(fetion_user_set_state(user , args->type) > 0){ fx_head_set_state_image(fxmain , args->type); old_state = args->type; } g_free(args); } void fx_head_change_portrait_func(GtkWidget* widget , GdkEventButton* event , gpointer data) { FxMain *fxmain = (FxMain*)data; char *filename = NULL; GdkPixbufAnimation *anim_pixbuf = NULL; GtkWidget* filechooser = NULL; GdkCursor* cursor = NULL; struct Args1{ FxMain* fxmain; char filename[1024]; } *args = (struct Args1*)malloc(sizeof(struct Args1)); int response; if(event->type == GDK_ENTER_NOTIFY) { cursor = gdk_cursor_new (GDK_HAND2); gdk_window_set_cursor(widget->window , cursor); return; } if(event->type == GDK_LEAVE_NOTIFY) { cursor = gdk_cursor_new (GDK_LEFT_PTR); gdk_window_set_cursor(widget->window , cursor); return; } if(!fx_conn_check_action(fxmain)) return; filechooser = gtk_file_chooser_dialog_new(_("Choose the avatar file to upload") , NULL , GTK_FILE_CHOOSER_ACTION_OPEN , _("Upload") , 1 , _("Cancel") , 2 , NULL); response = gtk_dialog_run(GTK_DIALOG(filechooser)); if(response == 1) { filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(filechooser)); if (filename) { anim_pixbuf = gdk_pixbuf_animation_new_from_file(SKIN_DIR"LoadingImage.gif", NULL); gtk_image_set_from_animation(GTK_IMAGE(fxmain->headPanel->portrait) , anim_pixbuf); args->fxmain = fxmain; memset(args->filename, 0, sizeof(args->filename)); strcpy(args->filename , filename); g_thread_create(fx_head_change_portrait_thread , args , FALSE , NULL); } } gtk_widget_destroy(filechooser); } void* fx_head_change_portrait_thread(void* data) { struct Args1 { FxMain* fxmain; char filename[1024]; } *args = (struct Args1*)data; FxMain *fxmain; FxHead *fxhead; Config *config; gchar filepath[128]; GtkWidget *dialog; GdkPixbuf *pb; fxmain = args->fxmain; fxhead = fxmain->headPanel; config = fxmain->user->config; if(fetion_user_upload_portrait(fxmain->user , args->filename) > 0){ fetion_user_download_portrait(fxmain->user , fxmain->user->sipuri); sprintf(filepath , "%s/%s.jpg" , config->iconPath , fxmain->user->sId); pb = gdk_pixbuf_new_from_file_at_size(filepath, USER_PORTRAIT_SIZE , USER_PORTRAIT_SIZE , NULL); if(pb == NULL) pb = gdk_pixbuf_new_from_file_at_size(filepath, USER_PORTRAIT_SIZE, USER_PORTRAIT_SIZE, NULL); gdk_threads_enter(); gtk_image_set_from_pixbuf(GTK_IMAGE(fxhead->portrait) , pb); g_object_unref(pb); gdk_threads_leave(); }else{ gdk_threads_enter(); dialog = gtk_message_dialog_new(GTK_WINDOW(fxmain->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("Upload avatar failed. Note: This appliaction doesn't support auto-compression " "of image. Please be sure that the avater is in 150px × 150px.")); gtk_window_set_title(GTK_WINDOW(dialog), "Warning"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); gdk_threads_leave(); gdk_threads_enter(); sprintf(filepath , "%s/%s.jpg" , config->iconPath , fxmain->user->sId); pb = gdk_pixbuf_new_from_file_at_size(filepath , USER_PORTRAIT_SIZE , USER_PORTRAIT_SIZE , NULL); if(pb == NULL) pb = gdk_pixbuf_new_from_file_at_size(filepath, USER_PORTRAIT_SIZE , USER_PORTRAIT_SIZE , NULL); gtk_image_set_from_pixbuf(GTK_IMAGE(fxhead->portrait) , pb); g_object_unref(pb); gdk_threads_leave(); } free(args); return NULL; } gboolean fx_head_set_sms_clicked(GtkWidget *UNUSED(widget), gpointer data) { FxMain *fxmain = (FxMain*)data; User *user = fxmain->user; FxSmsstat *fxst; if(strcmp(user->smsOnLineStatus , "0.00:00:00") == 0 || strcmp(user->smsOnLineStatus , "0.0:0:0") == 0){ fxst = fx_smsstat_new(fxmain); fx_smsstat_initialize(fxst); gtk_dialog_run(GTK_DIALOG(fxst->dialog)); gtk_widget_destroy(fxst->dialog); free(fxst); }else{ fetion_user_set_sms_status(user , 0); } return FALSE; } openfetion-2.2.1/src/fx_head.h0000644000175000017500000000665211561721144014713 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_HEAD_H #define FX_HEAD_H #define USER_PORTRAIT_SIZE 50 extern FxHead* fx_head_new(); extern void fx_head_free(FxHead* fxhead); extern void fx_head_initialize(FxMain* fxmain); extern void fx_head_show(FxMain *fxmain); extern void fx_head_bind(FxMain* fxmain); void fx_head_set_state_image(FxMain* fxmain , StateType type); extern void fx_head_popup_statemenu_func(GtkWidget* UNUSED(widget), GdkEventButton* event , gpointer data); void fx_head_create_presence_item(int type, const char* message, GtkWidget* menu, FxMain* fxmain); extern void fx_head_impre_event_func(GtkWidget* widget, GdkEventButton* event , gpointer data); extern gboolean fx_head_impre_focus_out_func(GtkWidget* UNUSED(widget), GdkEventFocus* UNUSED(event) , gpointer data); extern gboolean fx_head_impre_activate_func(GtkWidget* widget, gpointer data); extern void fx_head_change_state_func(GtkWidget* UNUSED(widget), gpointer data); extern void fx_head_change_portrait_func(GtkWidget* widget, GdkEventButton* event , gpointer data); extern void* fx_head_change_portrait_thread(void* data); extern gboolean fx_head_set_sms_clicked(GtkWidget *widget, gpointer data); #endif openfetion-2.2.1/src/fx_history.c0000644000175000017500000003354411561721144015506 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static GtkTreeModel* fx_history_create_count_model(); static void fx_history_on_close_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_history_on_refresh_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_history_on_today_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_history_on_yestorday_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_history_on_month_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_history_on_all_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_history_on_export_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_history_on_cleanup_clicked(GtkWidget* UNUSED(widget) , gpointer data); FxHistory* fx_history_new(FxMain* fxmain , const char* userid , const char* name) { FxHistory* fxhistory = (FxHistory*)malloc(sizeof(FxHistory)); memset(fxhistory , 0 , sizeof(FxHistory)); strcpy(fxhistory->userid , userid); strcpy(fxhistory->name , name); fxhistory->fxmain = fxmain; return fxhistory; } void fx_history_initialize(FxHistory* fxhistory) { char title[128]; GdkPixbuf* pb; GtkWidget *label1 , *label2 , *refresh_icon , *today_icon; GtkWidget *yest_icon , *month_icon , *all_icon , *exp_icon; GtkWidget *scrollwindow; GtkTextBuffer* buffer; GtkTreeModel* model; GtkBox* vbox; FxList *list; Config* config = fxhistory->fxmain->user->config; fxhistory->dialog = gtk_dialog_new(); snprintf(title, sizeof(title) - 1 , _("View logs with [%s]") , fxhistory->name ); gtk_window_set_title(GTK_WINDOW(fxhistory->dialog) , title); gtk_widget_set_usize(fxhistory->dialog , 750 , 550); pb = gdk_pixbuf_new_from_file(SKIN_DIR"history.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxhistory->dialog) , pb); g_object_unref(pb); gtk_dialog_set_has_separator(GTK_DIALOG(fxhistory->dialog) , FALSE); vbox = GTK_BOX(GTK_DIALOG(fxhistory->dialog)->vbox); fxhistory->toolbar = gtk_toolbar_new(); gtk_toolbar_set_style(GTK_TOOLBAR(fxhistory->toolbar) , GTK_TOOLBAR_BOTH_HORIZ); gtk_box_pack_start(vbox , fxhistory->toolbar , FALSE , TRUE , 0); label1 = gtk_label_new(_("Show the most recent")); gtk_container_add(GTK_CONTAINER(fxhistory->toolbar) , label1); model = fx_history_create_count_model(); fxhistory->daycombo = gtk_combo_box_entry_new_with_model(model , 0); gtk_combo_box_set_active(GTK_COMBO_BOX(fxhistory->daycombo) , 1); gtk_widget_set_usize(fxhistory->daycombo , 60 , 20); gtk_container_add(GTK_CONTAINER(fxhistory->toolbar) , fxhistory->daycombo); label2 = gtk_label_new(_("mesage")); gtk_container_add(GTK_CONTAINER(fxhistory->toolbar) , label2); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"refresh.png" , 16 , 16 , NULL); refresh_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxhistory->toolbar) , _("Refresh") , NULL , NULL , refresh_icon , G_CALLBACK(fx_history_on_refresh_clicked) , fxhistory); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"login.png" , 16 , 16 , NULL); today_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxhistory->toolbar) , _("Today") , NULL , NULL , today_icon , G_CALLBACK(fx_history_on_today_clicked) , fxhistory); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"login.png" , 16 , 16 , NULL); yest_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxhistory->toolbar) , _("This Week") , NULL , NULL , yest_icon , G_CALLBACK(fx_history_on_yestorday_clicked) , fxhistory); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"login.png" , 16 , 16 , NULL); month_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxhistory->toolbar) , _("This Month") , NULL , NULL , month_icon , G_CALLBACK(fx_history_on_month_clicked) , fxhistory); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"login.png" , 16 , 16 , NULL); all_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxhistory->toolbar) , _("All") , NULL , NULL , all_icon , G_CALLBACK(fx_history_on_all_clicked) , fxhistory); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"login.png" , 16 , 16 , NULL); exp_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxhistory->toolbar) , _("Export") , NULL , NULL , exp_icon , G_CALLBACK(fx_history_on_export_clicked) , fxhistory); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"login.png" , 16 , 16 , NULL); exp_icon = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_toolbar_append_item(GTK_TOOLBAR(fxhistory->toolbar) , _("Cleanup") , NULL , NULL , exp_icon , G_CALLBACK(fx_history_on_cleanup_clicked) , fxhistory); fxhistory->textview = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxhistory->textview) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxhistory->textview) , FALSE); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxhistory->textview)); gtk_text_buffer_create_tag(buffer , "blue" , "foreground" , "blue" , NULL); gtk_text_buffer_create_tag(buffer , "green" , "foreground" , "green" , NULL); gtk_text_buffer_create_tag(buffer , "red" , "foreground" , "red" , NULL); gtk_text_buffer_create_tag(buffer , "lm10" , "left_margin" , 10 , NULL); scrollwindow = gtk_scrolled_window_new(NULL , NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollwindow) , GTK_SHADOW_ETCHED_IN); gtk_container_add(GTK_CONTAINER(scrollwindow) , fxhistory->textview); gtk_box_pack_start(vbox , scrollwindow , TRUE , TRUE , 5); fxhistory->closebtn = gtk_button_new(); gtk_button_set_label(GTK_BUTTON(fxhistory->closebtn) , _("Close")); g_signal_connect(fxhistory->closebtn, "clicked", G_CALLBACK(fx_history_on_close_clicked), fxhistory); gtk_box_pack_start_defaults( GTK_BOX(GTK_DIALOG(fxhistory->dialog)->action_area), fxhistory->closebtn); list = fetion_history_get_list(config , fxhistory->userid , 20); fx_history_bind(fxhistory , list); gtk_widget_show_all(fxhistory->dialog); } void fx_history_bind(FxHistory* fxhistory , FxList *list) { char text[2048]; FxList *cur; History *history; GtkTextBuffer *buffer; GtkTextIter begin , end; buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(fxhistory->textview)); gtk_text_buffer_get_start_iter(buffer , &begin); gtk_text_buffer_get_end_iter(buffer , &end); gtk_text_buffer_delete(buffer , &begin , &end); if(!list) return; foreach_list_back(list , cur){ history = (History*)(cur->data); if(history->issend){ snprintf(text, sizeof(text) -1, "%s(%s) :", history->name, history->sendtime ); gtk_text_buffer_insert_with_tags_by_name(buffer , &end , text , -1 , "blue" , NULL); }else{ snprintf(text, sizeof(text) -1, "%s(%s) :", history->name, history->sendtime ); gtk_text_buffer_insert_with_tags_by_name(buffer , &end , text , -1 , "red" , NULL); } gtk_text_buffer_insert(buffer , &end , "\n" , -1); gtk_text_buffer_insert_with_tags_by_name(buffer , &end , history->message , -1 , "lm10" , NULL); gtk_text_buffer_insert(buffer , &end , "\n" , -1); } } static GtkTreeModel* fx_history_create_count_model() { GtkTreeStore* store = gtk_tree_store_new(1 , G_TYPE_STRING); char count[5]; int i; for(i = 10 ; i != 100 ; i += 10){ GtkTreeIter iter; gtk_tree_store_append(store , &iter , NULL); sprintf(count , "%d" , i); gtk_tree_store_set(store , &iter , 0 , count , -1); } return GTK_TREE_MODEL(store); } static void fx_history_on_close_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxHistory *fxhistory = (FxHistory*)data; gtk_dialog_response(GTK_DIALOG(fxhistory->dialog) , GTK_RESPONSE_OK); } static void fx_history_on_refresh_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxHistory *fxhistory = (FxHistory*)data; FxList *list; GtkWidget* entry = gtk_bin_get_child(GTK_BIN(fxhistory->daycombo)); const char* count = gtk_entry_get_text(GTK_ENTRY(entry)); Config* config = fxhistory->fxmain->user->config; list = fetion_history_get_list(config , fxhistory->userid , atoi(count)); fx_history_bind(fxhistory , list); } static void fx_history_on_today_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxHistory *fxhistory = (FxHistory*)data; Config* config = fxhistory->fxmain->user->config; FxList *list = fetion_history_get_e_list(config , fxhistory->userid , HISTORY_TODAY); fx_history_bind(fxhistory , list); } static void fx_history_on_yestorday_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxHistory *fxhistory = (FxHistory*)data; Config* config = fxhistory->fxmain->user->config; FxList *list = fetion_history_get_e_list(config, fxhistory->userid , HISTORY_WEEK); fx_history_bind(fxhistory , list); } static void fx_history_on_month_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxHistory *fxhistory = (FxHistory*)data; Config* config = fxhistory->fxmain->user->config; FxList *list = fetion_history_get_e_list(config , fxhistory->userid , HISTORY_MONTH); fx_history_bind(fxhistory , list); } static void fx_history_on_all_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxHistory *fxhistory = (FxHistory*)data; Config* config = fxhistory->fxmain->user->config; FxList *list = fetion_history_get_e_list(config , fxhistory->userid , HISTORY_ALL); fx_history_bind(fxhistory , list); } static void fx_history_on_export_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxHistory *fxhistory = (FxHistory*)data; FxMain *fxmain = fxhistory->fxmain; User *user = fxmain->user; Config *config = user->config; GtkWidget *dialog; char text[1024]; dialog = gtk_file_chooser_dialog_new (_("Export File"), GTK_WINDOW(fxhistory->fxmain->window), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER (dialog), TRUE); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), getenv("HOME")); sprintf(text , _("logs with %s.txt") , fxhistory->name); gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), text); if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); fetion_history_export(config , user->sId , fxhistory->userid , filename); g_free (filename); } gtk_widget_destroy (dialog); } static void fx_history_on_cleanup_clicked(GtkWidget *UNUSED(widget), gpointer data) { FxHistory *fxhistory = (FxHistory*)data; FxMain *fxmain = fxhistory->fxmain; User *user = fxmain->user; Config *config = user->config; GtkWidget *dialog; GtkTextBuffer *buffer; GtkTextIter begin , end; int ret; dialog = gtk_message_dialog_new (GTK_WINDOW(fxhistory->dialog), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK_CANCEL, _("The action can not be undone.\n" "Are you sure you want to continue?")); ret = gtk_dialog_run (GTK_DIALOG (dialog)); if(ret == GTK_RESPONSE_OK){ fetion_history_delete(config, fxhistory->userid); buffer = gtk_text_view_get_buffer( GTK_TEXT_VIEW(fxhistory->textview)); gtk_text_buffer_get_start_iter(buffer , &begin); gtk_text_buffer_get_end_iter(buffer , &end); gtk_text_buffer_delete(buffer , &begin , &end); } gtk_widget_destroy (dialog); } openfetion-2.2.1/src/fx_history.h0000644000175000017500000000502211561721144015501 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_HISTORY_H #define FX_HISTORY_H extern FxHistory* fx_history_new(FxMain* fxmain , const char* userid , const char* name); extern void fx_history_initialize(FxHistory* fxhistory); extern void fx_history_bind(FxHistory* fxhistory , FxList *list); #endif openfetion-2.2.1/src/fx_idle.c0000644000175000017500000000715411561721144014720 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include #ifdef USE_LIBXSS #include #include #include #include #endif #define IDLE_TIMEOUT_SEC 180 extern int old_state; gint idle_timesec(void) { #ifdef USE_LIBXSS static XScreenSaverInfo *mit_info = NULL; static gint has_extension = -1; gint event_base, error_base; if (has_extension == -1) has_extension = XScreenSaverQueryExtension( GDK_DISPLAY(), &event_base, &error_base); if(has_extension){ if (mit_info == NULL) mit_info = XScreenSaverAllocInfo(); XScreenSaverQueryInfo(GDK_DISPLAY(), GDK_ROOT_WINDOW(), mit_info); return (mit_info->idle)/1000; } #endif return 0; } void idle_autoaway(FxMain *fxmain) { typedef struct { FxMain* fxmain; StateType type; } Args1; User *user = fxmain->user; Config *config = user->config; Args1 *args; gint os; if(config->autoAway == AUTO_AWAY_ENABLE){ args = (Args1*)malloc(sizeof(Args1)); args->fxmain = fxmain; if(user->state > 0 && user->state != P_AWAY && idle_timesec() > IDLE_TIMEOUT_SEC){ os = user->state; args->type = P_AWAY; fx_head_change_state_func(NULL, args); old_state = os; return; } if(user->state != old_state && idle_timesec() < IDLE_TIMEOUT_SEC){ args->type = old_state; fx_head_change_state_func(NULL, args); return; } free(args); } } openfetion-2.2.1/src/fx_idle.h0000644000175000017500000000455511561721144014727 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include extern gint idle_timesec(void); extern void idle_autoaway(FxMain *fxmain); openfetion-2.2.1/src/fx_include.h0000644000175000017500000000656411561721144015437 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_INCLUDE_H #define FX_INCLUDE_H #include #include #include #include #include #ifdef USE_LIBNOTIFY #include #endif #include #ifdef ENABLE_NLS #include "glib/gi18n.h" #else #define _(String) (String) #define N_(String) (String) #endif #include "fx_types.h" #include "fx_util.h" #include "fx_sound.h" #include "fx_tree.h" #include "fx_head.h" #include "fx_bottom.h" #include "fx_main.h" #include "fx_login.h" #include "fx_proxy.h" #include "fx_add_group.h" #include "fx_profile.h" #include "fx_dsms.h" #include "fx_edit.h" #include "fx_gedit.h" #include "fx_chat.h" #include "fx_myself.h" #include "fx_history.h" #include "fx_many.h" #include "fx_lookup.h" #include "fx_lookupres.h" #include "fx_addbuddy.h" #include "fx_code.h" #include "fx_app.h" #include "fx_set.h" #include "fx_emotion.h" #include "fx_sysmsg.h" #include "fx_close.h" #include "fx_search.h" #include "fx_pggroup.h" #include "fx_pgprofile.h" #include "fx_smsstat.h" #include "fx_idle.h" #include "fx_conn.h" #include "fx_about.h" #endif openfetion-2.2.1/src/fx_login.c0000644000175000017500000005137511561721144015117 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" struct userlist *ul; #define PORTRAIT_SIZE 120 #define LOADING_IMAGE_SIZE 128 #define MAX_PASSWORD_LENGTH 16 static void userlist_remove_clicked(GtkWidget *widget, gpointer data); FxLogin* fx_login_new() { FxLogin* fxlogin = (FxLogin*)malloc(sizeof(FxLogin)); memset(fxlogin , 0 , sizeof(FxLogin)); return fxlogin; } void fx_login_hide(FxLogin *fxlogin) { gtk_widget_hide(fxlogin->fixed); } void fx_login_free(FxLogin* fxlogin) { gtk_widget_destroy(fxlogin->fixed); gtk_widget_destroy(fxlogin->fixed1); free(fxlogin); } gboolean fx_login_proxy_button_func(GtkWidget *UNUSED(widget) , GdkEventButton *event , gpointer data) { FxLogin *fxlogin = (FxLogin*)data; Proxy *proxy = fxlogin->proxy; FxProxy *fxproxy = NULL; gchar text[1024]; memset(text, 0, sizeof(text)); switch(event->type) { case GDK_ENTER_NOTIFY : snprintf(text, sizeof(text) - 1 , _(" Proxy[%s]") , (proxy == NULL || !proxy->proxyEnabled) ? _("Off") : _("On")); gtk_label_set_markup(GTK_LABEL(fxlogin->proxyLabel) , text); break; case GDK_LEAVE_NOTIFY : snprintf(text, sizeof(text) - 1, _(" Proxy[%s]") , (proxy == NULL || !proxy->proxyEnabled) ? _("Off") : _("On")); gtk_label_set_markup(GTK_LABEL(fxlogin->proxyLabel) , text); break; case GDK_BUTTON_PRESS : fxproxy = fx_proxy_new(fxlogin); fx_proxy_initialize(fxproxy); gtk_dialog_run(GTK_DIALOG(fxproxy->dialog)); gtk_widget_destroy(fxproxy->dialog); break; default: break; } return TRUE; } void fx_logining_show(FxMain *fxmain) { GdkPixbuf *pixbuf; GtkWidget *mainbox; GtkWidget *label; FxLogin *fxlogin; mainbox = fxmain->mainbox; fxlogin = fxmain->loginPanel; fxlogin->fixed1 = gtk_fixed_new(); gtk_box_pack_start(GTK_BOX(mainbox), fxlogin->fixed1, TRUE, TRUE, 0); pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"online.svg", LOADING_IMAGE_SIZE, LOADING_IMAGE_SIZE, NULL); fxlogin->image = gtk_image_new_from_file(SKIN_DIR"logining.gif"); gtk_fixed_put(GTK_FIXED(fxlogin->fixed1), fxlogin->image, (WINDOW_WIDTH - 128)/2, 70); g_object_unref(pixbuf); fxlogin->label = gtk_label_new(NULL); // gtk_label_set_line_wrap(GTK_LABEL(fxlogin->label), TRUE); gtk_fixed_put(GTK_FIXED(fxlogin->fixed1), fxlogin->label, 0, 280); gtk_widget_set_usize(fxlogin->label, WINDOW_WIDTH, 0); gtk_label_set_justify(GTK_LABEL(fxlogin->label), GTK_JUSTIFY_CENTER); label = gtk_label_new(NULL); gtk_widget_set_usize(label, WINDOW_WIDTH, 0); gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER); gtk_label_set_markup(GTK_LABEL(label), _("Welcome to OpenFetion")); gtk_fixed_put(GTK_FIXED(fxlogin->fixed1), label, 0, 350); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label), _("OpenFetion a fetion client for linux" " based on GTK+2.0, using Fetion Protocol" " Version 4.\nOpenFetion is a non-profit software," " aiming at making linux users convenient " "to use fetion.")); gtk_widget_set_usize(label, WINDOW_WIDTH - 40, 0); gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); gtk_fixed_put(GTK_FIXED(fxlogin->fixed1), label, 20, 390); gtk_widget_show_all(fxlogin->fixed1); } void fx_login_initialize(FxMain *fxmain) { FxLogin *fxlogin = fxmain->loginPanel; GtkTreeModel *stateModel = NULL; GtkCellRenderer *renderer = NULL; GtkWidget *img = NULL; GtkWidget *frame; Config *config = NULL; GtkTreeModel *model = NULL; GtkWidget *proxyHbox = NULL; GtkWidget *rmBtn = NULL; GdkPixbuf *pixbuf; Proxy *proxy = NULL; GtkWidget *image = NULL; GtkWidget *openfetion; const gchar *no; const gchar *psd; gchar text[1024]; config = fetion_config_new(); /* load proxy information */ proxy = fetion_config_load_proxy(); fxlogin->proxy = proxy; ul = fetion_user_list_load(config); model = fx_login_create_user_model(); pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", PORTRAIT_SIZE, PORTRAIT_SIZE, NULL); fxlogin->portrait = gtk_image_new_from_pixbuf(pixbuf); frame = gtk_frame_new(NULL); gtk_widget_set_usize(frame, PORTRAIT_SIZE + 5, PORTRAIT_SIZE + 5); gtk_container_add(GTK_CONTAINER(frame), fxlogin->portrait); g_object_unref(pixbuf); fxlogin->username = gtk_combo_box_entry_new_with_model(model , 0); gtk_widget_set_size_request(GTK_WIDGET(fxlogin->username) , 207 , 25); g_signal_connect(fxlogin->username, "changed", G_CALLBACK(fx_login_user_change_func) , fxmain); rmBtn = gtk_button_new(); gtk_widget_set_usize(rmBtn, 30, 25); image = gtk_image_new_from_stock(GTK_STOCK_DELETE, GTK_ICON_SIZE_SMALL_TOOLBAR); gtk_button_set_image(GTK_BUTTON(rmBtn), image); g_signal_connect(rmBtn, "clicked", G_CALLBACK(userlist_remove_clicked), fxmain); fxlogin->userlabel = gtk_label_new(gettext("Cell number or fetion number:")); gtk_label_set_justify(GTK_LABEL(fxlogin->userlabel), GTK_JUSTIFY_CENTER); fxlogin->password = gtk_entry_new(); gtk_entry_set_max_length(GTK_ENTRY(fxlogin->password), MAX_PASSWORD_LENGTH); gtk_widget_set_size_request(GTK_WIDGET(fxlogin->password) , 240 , 25); gtk_entry_set_visibility(GTK_ENTRY(fxlogin->password) , FALSE); g_signal_connect(G_OBJECT(fxlogin->password) , "activate" , G_CALLBACK(fx_login_action_func) , fxmain); fxlogin->passlabel = gtk_label_new(_("Please input password:")); gtk_label_set_justify(GTK_LABEL(fxlogin->passlabel) , GTK_JUSTIFY_CENTER); fxlogin->errlabel = gtk_label_new(NULL); gtk_widget_set_usize(GTK_WIDGET(fxlogin->errlabel) , WINDOW_WIDTH - 10 , 0); gtk_label_set_justify(GTK_LABEL(fxlogin->errlabel) , GTK_JUSTIFY_CENTER); fxlogin->statusLabel = gtk_label_new(_("Status:")); fxlogin->loginbutton = gtk_button_new_with_label(_("Login")); img = gtk_image_new_from_file(SKIN_DIR"login.png"); gtk_button_set_image(GTK_BUTTON(fxlogin->loginbutton) , img); fxlogin->loginFuncId = g_signal_connect(G_OBJECT(fxlogin->loginbutton) , "clicked" , G_CALLBACK(fx_login_action_func) , fxmain); gtk_widget_set_size_request(GTK_WIDGET(fxlogin->loginbutton) , 80 , 25); stateModel = fx_login_create_state_model(); fxlogin->statecombo = gtk_combo_box_new_with_model(stateModel); g_object_unref(stateModel); renderer = gtk_cell_renderer_pixbuf_new (); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (fxlogin->statecombo), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (fxlogin->statecombo), renderer, "pixbuf", 0, NULL); renderer = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (fxlogin->statecombo), renderer, FALSE); gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (fxlogin->statecombo), renderer, "text", 1, NULL); gtk_combo_box_set_active (GTK_COMBO_BOX (fxlogin->statecombo), 3); gtk_widget_set_usize(GTK_WIDGET(fxlogin->statecombo) , 240 , 28); fxlogin->remember = gtk_check_button_new_with_label(_("Remember password")); fxlogin->proxyBtn = gtk_event_box_new(); fxlogin->proxyLabel = gtk_label_new(NULL); proxyHbox = gtk_hbox_new(FALSE , FALSE); img = gtk_image_new_from_file(SKIN_DIR"proxy.png"); sprintf(text , _(" Proxy[%s]") , (fxlogin->proxy == NULL || ! fxlogin->proxy->proxyEnabled) ? _("Off") : _("On")); gtk_label_set_markup(GTK_LABEL(fxlogin->proxyLabel) , text); gtk_container_add(GTK_CONTAINER(fxlogin->proxyBtn) , proxyHbox); gtk_box_pack_start_defaults(GTK_BOX(proxyHbox) , img); gtk_box_pack_start_defaults(GTK_BOX(proxyHbox) , fxlogin->proxyLabel); g_signal_connect(G_OBJECT(fxlogin->proxyBtn) , "button_press_event" , GTK_SIGNAL_FUNC(fx_login_proxy_button_func) , fxlogin); g_signal_connect(G_OBJECT(fxlogin->proxyBtn) , "enter_notify_event" , GTK_SIGNAL_FUNC(fx_login_proxy_button_func) , fxlogin); g_signal_connect(G_OBJECT(fxlogin->proxyBtn) , "leave_notify_event" , GTK_SIGNAL_FUNC(fx_login_proxy_button_func) , fxlogin); openfetion = gtk_image_new_from_file(SKIN_DIR"openfetion.png"); fx_login_set_last_login_user(fxlogin); fxlogin->fixed = gtk_fixed_new(); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , frame, (WINDOW_WIDTH - PORTRAIT_SIZE - 10) / 2, 25); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , openfetion, (WINDOW_WIDTH - 190) / 2, 170); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->userlabel , 20 ,225); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->username , 20, 245); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , rmBtn , 230 , 245); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->passlabel , 20 , 275); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->password , 20, 295); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->statusLabel , 20, 325); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->statecombo , 20, 345); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->remember , 20, 387); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->loginbutton , 180, 385); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->errlabel , 5 , 415); gtk_fixed_put(GTK_FIXED(fxlogin->fixed) , fxlogin->proxyBtn , WINDOW_WIDTH - 100 , WINDOW_HEIGHT - 30); gtk_box_pack_start(GTK_BOX(fxmain->mainbox) , fxlogin->fixed , TRUE , TRUE , 0); GtkWidget *entry = gtk_bin_get_child(GTK_BIN(fxlogin->username)); GTK_WIDGET_SET_FLAGS(entry, GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS(fxlogin->password, GTK_CAN_FOCUS); GTK_WIDGET_SET_FLAGS(fxlogin->loginbutton, GTK_CAN_FOCUS); /* get login number and password */ no = gtk_combo_box_get_active_text( GTK_COMBO_BOX(fxlogin->username)); psd = gtk_entry_get_text( GTK_ENTRY(fxlogin->password)); if(!no || *no == '\0') gtk_widget_grab_focus(fxlogin->username); else if(!psd || *psd == '\0') gtk_widget_grab_focus(fxlogin->password); else gtk_widget_grab_focus(fxlogin->loginbutton); gtk_widget_show_all(fxmain->mainbox); g_free(config); } GtkTreeModel* fx_login_create_state_model() { GtkListStore *store = NULL; GtkTreeIter iter; GdkPixbuf *pb = NULL; gint i; struct { const gchar* name; const gchar* icon; int type; } presence[] = { { N_("Online") , SKIN_DIR"online.svg" , P_ONLINE } , { N_("Leave") , SKIN_DIR"away.svg" , P_AWAY } , { N_("Busy") , SKIN_DIR"busy.svg" , P_BUSY } , { N_("Hide") , SKIN_DIR"invisible.svg" , P_HIDDEN } , { N_("Offline") , SKIN_DIR"offline.svg" , P_OFFLINE } , { N_("Eating out") , SKIN_DIR"away.svg" , P_OUTFORLUNCH } , { N_("Do Not Disturb") , SKIN_DIR"away.svg" , P_DONOTDISTURB } , { N_("Back Soon") , SKIN_DIR"away.svg" , P_RIGHTBACK } , { N_("Meeting") , SKIN_DIR"away.svg" , P_MEETING } , { N_("Calling") , SKIN_DIR"away.svg" , P_ONTHEPHONE} , { NULL , NULL , -2} }; enum { PIXBUF_COL , TEXT_COL , INT_COL }; store = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING , G_TYPE_INT); for(i = 0 ; presence[i].type != -2 ; i++){ gtk_list_store_append(store , &iter); pb = gdk_pixbuf_new_from_file_at_size(presence[i].icon, 20, 20, NULL); gtk_list_store_set(store , &iter , PIXBUF_COL , pb , TEXT_COL , _(presence[i].name) , INT_COL , presence[i].type , -1); g_object_unref(pb); } return GTK_TREE_MODEL(store); } void fx_login_show_msg(FxLogin *fxlogin , const char *msg) { char text[1024]; gdk_threads_enter(); sprintf(text, "%s", msg); gtk_label_set_markup(GTK_LABEL(fxlogin->label) , text); update(); gdk_threads_leave(); } void fx_login_show_err(FxLogin *fxlogin , const char *msg) { gdk_threads_enter(); gtk_label_set_text(GTK_LABEL(fxlogin->errlabel) , msg); update(); gdk_threads_leave(); } static void *fx_offline_login_thread_func(void *data) { fx_conn_offline_login((FxMain*)data); return NULL; } static void *fx_login_thread_func(void *data) { fx_conn_connect((FxMain*)data); return NULL; } void fx_login_action_func(GtkWidget* UNUSED(widget) , gpointer data) { FxMain *fxmain = (FxMain*)data; FxLogin *fxlogin = fxmain->loginPanel; GtkTreeIter stateIter; GtkTreeModel *stateModel; gint state; /* get login state value */ gtk_combo_box_get_active_iter( GTK_COMBO_BOX(fxlogin->statecombo), &stateIter); stateModel = gtk_combo_box_get_model( GTK_COMBO_BOX(fxlogin->statecombo)); gtk_tree_model_get(stateModel, &stateIter, 2 , &state , -1); if(state == P_OFFLINE) g_thread_create(fx_offline_login_thread_func, fxmain, FALSE, NULL); else g_thread_create(fx_login_thread_func, fxmain , FALSE , NULL); } GtkTreeModel* fx_login_create_user_model() { GtkTreeStore* model = gtk_tree_store_new(USER_COLS_NUM , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT); struct userlist *ul_cur; GtkTreeIter iter; foreach_userlist(ul , ul_cur){ gtk_tree_store_append(model , &iter , NULL); gtk_tree_store_set(model , &iter , L_NO_COL , ul_cur->no , L_PWD_COL , ul_cur->password , L_STATE_COL, ul_cur->laststate , L_LAST_COL , ul_cur->islastuser , -1); } return GTK_TREE_MODEL(model); } void fx_login_set_last_login_user(FxLogin* fxlogin) { GtkComboBox *combo = GTK_COMBO_BOX(fxlogin->username); GtkTreeModel *model = gtk_combo_box_get_model(combo); GtkTreeIter iter; gchar *no; gchar *pwd; gint state; gint last; gchar truncated[24]; if(!gtk_tree_model_get_iter_root(model , &iter)) return; do{ gtk_tree_model_get(model , &iter , L_NO_COL , &no , L_PWD_COL , &pwd , L_STATE_COL, &state , L_LAST_COL , &last , -1); if(last == 1){ gtk_combo_box_set_active_iter(combo , &iter); if(strlen(pwd) == 40) {/* this is a hashed password */ strncpy(truncated, pwd, MAX_PASSWORD_LENGTH); pwd[MAX_PASSWORD_LENGTH] = '\0'; } else { strncpy(truncated, pwd, strlen(pwd)); truncated[strlen(pwd)] = '\0'; } gtk_entry_set_text(GTK_ENTRY(fxlogin->password), truncated); fx_login_set_last_login_state(fxlogin , state); if(*pwd != '\0') gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(fxlogin->remember) , TRUE); g_free(no); g_free(pwd); break; } } while(gtk_tree_model_iter_next(model , &iter)); } void fx_login_set_last_login_state(FxLogin* fxlogin , StateType state) { GtkTreeModel* model = gtk_combo_box_get_model( GTK_COMBO_BOX(fxlogin->statecombo)); GtkTreeIter iter; int s; gtk_tree_model_get_iter_root(model , &iter); do{ gtk_tree_model_get(model , &iter , 2 , &s , -1); if(s == state) gtk_combo_box_set_active_iter( GTK_COMBO_BOX(fxlogin->statecombo) , &iter); } while(gtk_tree_model_iter_next(model , &iter)); } void fx_login_user_change_func(GtkWidget* widget , gpointer data) { FxMain *fxmain = (FxMain*)data; FxLogin *fxlogin = fxmain->loginPanel; GtkComboBox *combo = GTK_COMBO_BOX(widget); GtkTreeModel *model = gtk_combo_box_get_model(combo); GdkPixbuf *pixbuf; Config *config; gchar *pwd; gchar *no; gchar path[1024]; GtkTreeIter iter; gint state; struct userlist *ul_cur = NULL; const gchar *nno; gchar truncated[24]; GtkWidget *entry = gtk_bin_get_child(GTK_BIN(fxlogin->username)); nno = gtk_entry_get_text(GTK_ENTRY(entry)); if(!nno) return; ul_cur = fetion_user_list_find_by_no(ul, nno); if(!ul_cur) { pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg", 120, 120, NULL); if(pixbuf){ gtk_image_set_from_pixbuf( GTK_IMAGE(fxlogin->portrait), pixbuf); g_object_unref(pixbuf); } gtk_entry_set_text(GTK_ENTRY(fxlogin->password), ""); return; } if(!gtk_combo_box_get_active_iter(combo , &iter)) { config = fetion_config_new(); fetion_config_initialize(config, ul_cur->userid); snprintf(path, sizeof(path) - 1, "%s/%s.jpg", config->iconPath, ul_cur->sid); pixbuf = gdk_pixbuf_new_from_file_at_size(path, 120, 120, NULL); if(pixbuf){ gtk_image_set_from_pixbuf( GTK_IMAGE(fxlogin->portrait), pixbuf); g_object_unref(pixbuf); } gtk_entry_set_text(GTK_ENTRY(fxlogin->password), ul_cur->password); fx_login_set_last_login_state(fxlogin , ul_cur->laststate); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxlogin->remember) , *(ul_cur->password) == '\0' ? FALSE : TRUE); return; } gtk_tree_model_get(model, &iter, L_PWD_COL, &pwd, L_NO_COL, &no, L_STATE_COL, &state, -1); ul_cur = fetion_user_list_find_by_no(ul, no); config = fetion_config_new(); fetion_config_initialize(config, ul_cur->userid); snprintf(path, sizeof(path) - 1, "%s/%s.jpg", config->iconPath, ul_cur->sid); pixbuf = gdk_pixbuf_new_from_file_at_size(path, 120, 120, NULL); if(pixbuf){ gtk_image_set_from_pixbuf( GTK_IMAGE(fxlogin->portrait), pixbuf); g_object_unref(pixbuf); } if(strlen(pwd) == 40) {/* this is a hashed password */ strncpy(truncated, pwd, MAX_PASSWORD_LENGTH); pwd[MAX_PASSWORD_LENGTH] = '\0'; } else { strncpy(truncated, pwd, strlen(pwd)); truncated[strlen(pwd)] = '\0'; } gtk_entry_set_text(GTK_ENTRY(fxlogin->password), truncated); fx_login_set_last_login_state(fxlogin , state); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxlogin->remember) , *pwd == '\0' ? FALSE : TRUE); g_free(pwd); g_free(no); } static void userlist_remove_clicked(GtkWidget *UNUSED(widget), gpointer data) { FxMain *fxmain = (FxMain*)data; FxLogin *fxlogin = fxmain->loginPanel; GtkComboBox *combo; GtkTreeModel *model; GtkWidget *entry; GdkPixbuf *pixbuf; GtkTreeIter iter; gchar *no; Config *config; combo = GTK_COMBO_BOX(fxlogin->username); model = gtk_combo_box_get_model(combo); if(!gtk_combo_box_get_active_iter(combo, &iter)) return; config = fetion_config_new(); gtk_tree_model_get(model, &iter, L_NO_COL, &no, -1); if(fetion_user_list_remove(config, no) == -1){ g_free(config); g_free(no); return; } gtk_tree_store_remove(GTK_TREE_STORE(model), &iter); if(gtk_tree_model_get_iter_root(model, &iter)){ gtk_combo_box_set_active_iter(combo, &iter); }else{ entry = gtk_bin_get_child(GTK_BIN(fxlogin->username)); gtk_entry_set_text(GTK_ENTRY(entry), ""); gtk_entry_set_text(GTK_ENTRY(fxlogin->password), ""); pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", PORTRAIT_SIZE, PORTRAIT_SIZE, NULL); if(pixbuf){ gtk_image_set_from_pixbuf( GTK_IMAGE(fxlogin->portrait), pixbuf); g_object_unref(pixbuf); } } g_free(config); g_free(no); } openfetion-2.2.1/src/fx_login.h0000644000175000017500000000646411561721144015123 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_LOGIN_H #define FX_LOGIN_H enum { L_NO_COL = 0 , L_PWD_COL , L_STATE_COL , L_LAST_COL , USER_COLS_NUM }; extern FxLogin* fx_login_new(); extern void fx_login_free(FxLogin* fxlogin); extern void fx_login_initialize(FxMain* fxmain); extern GtkTreeModel* fx_login_create_state_model(); extern GtkTreeModel* fx_login_create_user_model(); extern void fx_login_set_last_login_user(FxLogin* fxlogin); extern void fx_login_set_last_login_state(FxLogin* fxlogin , StateType state); extern void fx_login_show_msg(FxLogin *fxlogin , const char *msg); extern void fx_login_show_err(FxLogin *fxlogin , const char *msg); extern void fx_login_hide(FxLogin *fxlogin); extern void fx_login_free(FxLogin* fxlogin); extern void fx_logining_show(FxMain *fxmain); /* signal function */ extern void fx_login_action_func(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_login_user_change_func(GtkWidget* widget , gpointer data); extern gboolean fx_login_proxy_button_func(GtkWidget *UNUSED(widget) , GdkEventButton *event , gpointer data); #endif openfetion-2.2.1/src/fx_lookup.c0000644000175000017500000001400411561721144015304 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static void fx_lookup_on_entry_activated(GtkWidget *UNUSED(widget) , gpointer data); FxLookup* fx_lookup_new(FxMain* fxmain) { FxLookup *fxlookup = (FxLookup*)malloc(sizeof(FxLookup)); memset(fxlookup , 0 , sizeof(fxlookup)); fxlookup->fxmain = fxmain; return fxlookup; } void fx_lookup_initialize(FxLookup* fxlookup) { fxlookup->dialog = gtk_dialog_new(); GdkPixbuf* pb = gdk_pixbuf_new_from_file(SKIN_DIR"find.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxlookup->dialog) , pb); gtk_window_set_title(GTK_WINDOW(fxlookup->dialog) , _("View information of any user (attribution etc)")); gtk_window_set_modal(GTK_WINDOW(fxlookup->dialog) , TRUE); gtk_dialog_set_has_separator(GTK_DIALOG(fxlookup->dialog) , FALSE); gtk_window_set_resizable(GTK_WINDOW(fxlookup->dialog) , FALSE); gtk_widget_set_usize(fxlookup->dialog , 300 , 150); gtk_container_set_border_width(GTK_CONTAINER(fxlookup->dialog) , 20); fxlookup->remark_label = gtk_label_new(_("Please input the user's phone number or fetion number:")); gtk_misc_set_alignment(GTK_MISC(fxlookup->remark_label) , 0 , 0 ); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookup->dialog)->vbox) , fxlookup->remark_label); fxlookup->remark_entry = gtk_entry_new(); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookup->dialog)->vbox) , fxlookup->remark_entry); g_signal_connect(fxlookup->remark_entry , "activate" , G_CALLBACK(fx_lookup_on_entry_activated) , fxlookup); fxlookup->ok_button = gtk_button_new_with_label(_("Find")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookup->dialog)->action_area) , fxlookup->ok_button); g_signal_connect(fxlookup->ok_button , "clicked" , G_CALLBACK(fx_lookup_on_ok_clicked) , fxlookup); fxlookup->cancel_button = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookup->dialog)->action_area) , fxlookup->cancel_button); g_signal_connect(fxlookup->cancel_button , "clicked" , G_CALLBACK(fx_lookup_on_cancel_clicked) , fxlookup->dialog); gtk_widget_show_all(fxlookup->dialog); } void* fx_lookup_ok_thread(void* data) { FxLookup *fxlookup = (FxLookup*)data; User* user = fxlookup->fxmain->user; const char* mobileno; Contact* contact; FxLookupres* fxlookupres; GtkWidget *dialog; mobileno = gtk_entry_get_text(GTK_ENTRY(fxlookup->remark_entry)); if(strlen(mobileno) != 11 && strlen(mobileno) != 9) { debug_error("Please input a correct mobileno or fetionno"); return NULL; } contact = fetion_contact_get_contact_info_by_no(user , mobileno , strlen(mobileno) == 11 ? MOBILE_NO : FETION_NO); if(contact == NULL) { gdk_threads_enter(); dialog = gtk_message_dialog_new(GTK_WINDOW(fxlookup->fxmain->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("Query failed, please input vaild phone number of China Mobile")); gtk_window_set_title(GTK_WINDOW(dialog), "Warning"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); gdk_threads_leave(); return NULL; } gdk_threads_enter(); gtk_dialog_response(GTK_DIALOG(fxlookup->dialog) , GTK_RESPONSE_OK); fxlookupres = fx_lookupres_new(fxlookup->fxmain , contact); fx_lookupres_initialize(fxlookupres); gtk_dialog_run(GTK_DIALOG(fxlookupres->dialog)); free(contact); gtk_widget_destroy(fxlookupres->dialog); gdk_threads_leave(); return NULL; } void fx_lookup_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data) { g_thread_create(fx_lookup_ok_thread , data , FALSE , NULL); } void fx_lookup_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_CANCEL); } static void fx_lookup_on_entry_activated(GtkWidget *UNUSED(widget) , gpointer data) { g_thread_create(fx_lookup_ok_thread , data , FALSE , NULL); } openfetion-2.2.1/src/fx_lookup.h0000644000175000017500000000510611561721144015314 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_LOOKUP_H #define FX_LOOKUP_H extern FxLookup* fx_lookup_new(FxMain* fxmain); extern void fx_lookup_initialize(FxLookup* fxlookup); extern void fx_lookup_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_lookup_on_cancel_clicked(GtkWidget* UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_lookupres.c0000644000175000017500000002450611561721144016026 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxLookupres* fx_lookupres_new(FxMain* fxmain , Contact* contact) { FxLookupres *fxlookupres = (FxLookupres*)malloc(sizeof(FxLookupres)); memset(fxlookupres , 0 , sizeof(FxLookupres)); fxlookupres->fxmain = fxmain; fxlookupres->contact = contact; return fxlookupres; } void fx_lookupres_bind(FxLookupres* fxlookupres) { Contact* contact; GdkPixbuf* pb = NULL; char portrait[100]; char *sid = NULL; char *res = NULL; User *user = fxlookupres->fxmain->user; Config* config = user->config; contact = fxlookupres->contact; if(contact->nickname != NULL ) gtk_entry_set_text(GTK_ENTRY(fxlookupres->nick_entry) , contact->nickname); gtk_entry_set_text(GTK_ENTRY(fxlookupres->gender_entry) , contact->gender == 1 ? _("Male") : ( contact->gender == 2 ? _("Female") : _("Secrecy"))); if(contact->mobileno != NULL) gtk_entry_set_text(GTK_ENTRY(fxlookupres->mno_entry) , contact->mobileno); if(contact->impression != NULL) gtk_entry_set_text(GTK_ENTRY(fxlookupres->impre_entry) , contact->impression); gtk_entry_set_text(GTK_ENTRY(fxlookupres->sid_entry) , contact->sId); if(contact->country != NULL) gtk_entry_set_text(GTK_ENTRY(fxlookupres->nation_entry) , strcmp(contact->country , "CN") == 0 ? _("China") : contact->country); if(contact->province != NULL) { res = fetion_config_get_province_name(contact->province); gtk_entry_set_text(GTK_ENTRY(fxlookupres->province_entry) , res == NULL ? _("Unknown") : res); free(res); } if(contact->city != NULL) { res = fetion_config_get_city_name(contact->province , contact->city); gtk_entry_set_text(GTK_ENTRY(fxlookupres->city_entry) , res == NULL ? _("Unknown") : res); free(res); } sid = fetion_sip_get_sid_by_sipuri(contact->sipuri); snprintf(portrait, sizeof(portrait) - 1 , "%s/%s.jpg" , config->iconPath , sid); free(sid); if(contact->birthday != NULL) gtk_entry_set_text(GTK_ENTRY(fxlookupres->birth_entry) , contact->birthday); if(contact->sipuri != NULL && strlen(contact->sipuri) != 0) { fetion_user_download_portrait(user , contact->sipuri); pb = gdk_pixbuf_new_from_file_at_size(portrait , 90 , 90 , NULL); } if(pb != NULL) { gtk_image_set_from_pixbuf(GTK_IMAGE(fxlookupres->image) , pb); g_object_unref(pb); } } void fx_lookupres_initialize(FxLookupres* fxlookupres) { GtkWidget* box = NULL ; GtkWidget* inbox = NULL ; GdkPixbuf* pb = NULL; FxMain* fxmain = fxlookupres->fxmain; fxlookupres->dialog = gtk_dialog_new_with_buttons ("View information of user" , GTK_WINDOW(fxmain->window) , GTK_DIALOG_DESTROY_WITH_PARENT , NULL); gtk_dialog_set_has_separator(GTK_DIALOG(fxlookupres->dialog) , FALSE); gtk_container_set_border_width(GTK_CONTAINER(fxlookupres->dialog) , 10); gtk_widget_set_usize(GTK_WIDGET(fxlookupres->dialog) , 500 , 340); gtk_window_set_resizable(GTK_WINDOW(fxlookupres->dialog) , FALSE); box = gtk_table_new(6 , 3 , TRUE); gtk_table_set_row_spacings(GTK_TABLE(box) , 2); gtk_table_set_col_spacings(GTK_TABLE(box) , 2); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookupres->dialog)->vbox) , box); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 90 , 90 , NULL); fxlookupres->image = gtk_image_new_from_pixbuf(pb); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->image , 0 , 1 , 0 , 4); fxlookupres->sid_label = gtk_label_new(_("Fetion Number:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->sid_label) , 0 , 0); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->sid_label , 1 , 2 , 0 , 1); fxlookupres->sid_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->sid_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->sid_entry , 1 , 2 , 1 , 2); fxlookupres->gender_label = gtk_label_new(_("Sex:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->gender_label) , 0 , 0); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->gender_label , 2 , 3 , 0 , 1); fxlookupres->gender_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->gender_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->gender_entry , 2 , 3 , 1 , 2); fxlookupres->mno_label = gtk_label_new(_("Cell Phone Number:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->mno_label) , 0 , 0); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->mno_label , 1 , 2 , 2 , 3); fxlookupres->mno_entry = gtk_entry_new(); gtk_widget_set_usize(fxlookupres->mno_entry , 150 , 25); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->mno_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->mno_entry , 1 , 2 , 3 , 4); fxlookupres->nick_label = gtk_label_new(_("Nickname:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->nick_label) , 0 , 0); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->nick_label , 2 , 3 , 2 , 3); fxlookupres->nick_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->nick_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->nick_entry , 2 , 3 , 3 , 4); fxlookupres->impre_label = gtk_label_new(_("Personal Signature:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->impre_label) , 0 , 0); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->impre_label , 0 , 3 , 4, 5); fxlookupres->impre_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->impre_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxlookupres->impre_entry , 0 , 3 , 5 , 6); inbox = gtk_table_new( 4 , 2 , TRUE); gtk_table_set_row_spacings(GTK_TABLE(inbox) , 2); gtk_table_set_col_spacings(GTK_TABLE(inbox) , 2); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookupres->dialog)->vbox) , inbox); fxlookupres->birth_label = gtk_label_new(_("Personal Signature:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->birth_label) , 0 , 0 ); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->birth_label , 0 , 1 , 0 , 1); fxlookupres->birth_entry = gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->birth_entry , 0 , 1 , 1 , 2); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->birth_entry) , FALSE); fxlookupres->nation_label = gtk_label_new(_("Country:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->nation_label) , 0 , 0 ); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->nation_label , 1 , 2 , 0 , 1); fxlookupres->nation_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->nation_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->nation_entry , 1 , 2 , 1 , 2); fxlookupres->province_label = gtk_label_new(_("Province:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->province_label) , 0 , 0 ); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->province_label , 0 , 1 , 2 , 3); fxlookupres->province_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->province_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->province_entry , 0 , 1 , 3 , 4); fxlookupres->city_label = gtk_label_new(_("City:")); gtk_misc_set_alignment(GTK_MISC(fxlookupres->city_label) , 0 , 0 ); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->city_label , 1 , 2 , 2 , 3); fxlookupres->city_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxlookupres->city_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxlookupres->city_entry , 1 , 2 , 3 , 4); fxlookupres->ok_button = gtk_button_new_with_label(_("OK")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookupres->dialog)->action_area) , fxlookupres->ok_button); fxlookupres->cancel_button = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxlookupres->dialog)->action_area) , fxlookupres->cancel_button); g_signal_connect(fxlookupres->ok_button , "clicked" , G_CALLBACK(fx_lookupres_on_ok_clicked) , fxlookupres->dialog); g_signal_connect(fxlookupres->cancel_button , "clicked" , G_CALLBACK(fx_lookupres_on_ok_clicked) , fxlookupres->dialog); fx_lookupres_bind(fxlookupres); gtk_widget_show_all(fxlookupres->dialog); } void fx_lookupres_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_OK); } openfetion-2.2.1/src/fx_lookupres.h0000644000175000017500000000503411561721144016026 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_LOOKUPRES_H #define FX_LOOKUPRES_H extern FxLookupres* fx_lookupres_new(FxMain* fxmain , Contact* contact); extern void fx_lookupres_initialize(FxLookupres* fxlookupres); extern void fx_lookupres_on_ok_clicked(GtkWidget* UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_main.c0000644000175000017500000015717611561721144014741 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" #ifdef USE_GSTREAMER #include #endif #include #include #include #include #include #ifdef USE_INDICATE #include #include #include #include #endif fd_set fd_read; gint presence_count = 0; gint window_pos_x; gint window_pos_y; gint window_pos_x_old = 0; gint window_pos_y_old = 0; gint start_popup_presence = 0; extern struct unacked_list *unackedlist; GStaticMutex mutex = G_STATIC_MUTEX_INIT; GdkScreen *current_screen; FxMain *fxmain; #ifdef USE_INDICATE GSList *indicators = NULL; #endif static void fx_main_process_pggetgroupinfo(FxMain *fxmain , const gchar *sipmsg); static void fx_main_process_pgpresencechanged(FxMain *fxmain , const gchar *sipmsg); static gboolean key_press_func(GtkWidget *widget , GdkEventKey *event , gpointer data); #ifdef USE_INDICATE static gint indicate_action(); static void server_display(IndicateServer *server, guint timestamp); #endif // USE_INDICATE FxMain* fx_main_new() { FxMain* fxmain = (FxMain*)malloc(sizeof(FxMain)); memset(fxmain , 0 , sizeof(FxMain)); fxmain->clist = fx_list_new(NULL); fxmain->mlist = fx_list_new(NULL); fxmain->slist = fx_list_new(NULL); fxmain->tlist = fx_list_new(NULL); fxmain->shlist = fx_list_new(NULL); fxmain->pglist = fx_list_new(NULL); return fxmain; } #if 0 static void fx_main_position_func(GtkWidget *UNUSED(widget) , GdkEventConfigure *event , gpointer UNUSED(user_data)){ window_pos_x = event->x; window_pos_y = event->y; } #endif void fx_main_initialize(FxMain* fxmain) { Config *config; fxmain->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_name(fxmain->window , "mainwindow"); gtk_window_set_title(GTK_WINDOW(fxmain->window) , "OpenFetion"); current_screen = gdk_screen_get_default(); config = fetion_config_new(); fetion_config_load_size(config); fetion_config_get_use_status_icon(config); if(config->window_width == 0){ int window_width , window_height; window_width = gdk_screen_get_width(current_screen); window_height = gdk_screen_get_height(current_screen); window_pos_x = window_width - WINDOW_WIDTH - 200; window_pos_y = (window_height - WINDOW_HEIGHT) / 2; }else{ window_pos_x = config->window_pos_x; window_pos_y = config->window_pos_y; } gtk_window_move(GTK_WINDOW(fxmain->window) , window_pos_x , window_pos_y); gtk_container_set_border_width(GTK_CONTAINER(fxmain->window) , 0); g_signal_connect(G_OBJECT(fxmain->window) , "delete-event" , G_CALLBACK(fx_main_delete) , fxmain); g_signal_connect(G_OBJECT(fxmain->window) , "key-press-event" , G_CALLBACK(key_press_func) , fxmain); g_signal_connect(G_OBJECT(fxmain->window) , "destroy" , G_CALLBACK(fx_main_destroy) , fxmain); g_signal_connect(G_OBJECT(fxmain->window) , "window-state-event" , G_CALLBACK(fx_main_window_state_func) , fxmain); #if 0 g_signal_connect(G_OBJECT(fxmain->window) , "configure-event" , G_CALLBACK(fx_main_position_func) , NULL); #endif gtk_window_set_default_size( GTK_WINDOW(fxmain->window), WINDOW_WIDTH , WINDOW_HEIGHT); GdkPixbuf* icon = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg" , 24 , 24 , NULL); gtk_window_set_icon(GTK_WINDOW(fxmain->window) , icon); #ifdef USE_LIBNOTIFY #ifdef LIBNOTIFY_OLD fxmain->notify = notify_notification_new("welcome", "", SKIN_DIR"offline.svg", NULL); #else fxmain->notify = notify_notification_new("welcome", "", SKIN_DIR"offline.svg"); #endif notify_notification_set_timeout(fxmain->notify , 2500); #endif if(USE_STATUS_ICON(config)) { /* set status icon */ fxmain->trayIcon = gtk_status_icon_new_from_file( SKIN_DIR"offline.svg"); gtk_status_icon_set_tooltip(fxmain->trayIcon, "OpenFetion"); fxmain->iconConnectId = g_signal_connect( GTK_STATUS_ICON(fxmain->trayIcon), "activate", GTK_SIGNAL_FUNC(fx_main_tray_activate_func), fxmain); g_signal_connect(GTK_STATUS_ICON(fxmain->trayIcon), "popup-menu", GTK_SIGNAL_FUNC(fx_main_tray_popmenu_func), fxmain); } fxmain->mainbox = gtk_vbox_new(FALSE , 4); gtk_container_add(GTK_CONTAINER(fxmain->window) , fxmain->mainbox); fxmain->loginPanel = fx_login_new(); fx_login_initialize(fxmain); gtk_widget_show_all(fxmain->window); /* ubuntu indicator */ /* get the default indicator */ #ifdef USE_INDICATE IndicateServer *server = indicate_server_ref_default(); indicate_server_set_type(server, "message.openfetion"); indicate_server_set_desktop_file(server, DESKTOP_DIR"openfetion.desktop"); indicate_server_show(server); fxmain->indserver = server; g_signal_connect(G_OBJECT(server), INDICATE_SERVER_SIGNAL_SERVER_DISPLAY, G_CALLBACK(server_display), fxmain); #endif /* free the temporary config object */ fetion_config_free(config); gdk_threads_enter(); gtk_main(); gdk_threads_leave(); } void fx_main_free(FxMain* fxmain) { if(fxmain->user != NULL) fetion_user_free(fxmain->user); free(fxmain); } void fx_main_set_user(FxMain* fxmain , User* user) { fxmain->user = user; } void fx_main_history_init(FxMain *fxmain) { fxmain->history = fetion_history_new(fxmain->user); } void update() { g_usleep(1); while(gtk_events_pending()){ gtk_main_iteration(); } } TimeOutArgs* timeout_args_new(FxMain *fxmain , FetionSip *sip , const gchar *sipuri) { TimeOutArgs *args = (TimeOutArgs*)malloc(sizeof(TimeOutArgs)); memset(args , 0 , sizeof(TimeOutArgs)); args->fxmain = fxmain; args->sip = sip; args->terminated = FALSE; strcpy(args->sipuri , sipuri); return args; } GtkWidget* fx_main_create_menu(const gchar* name , const gchar* iconpath , GtkWidget* parent , void (*func)(GtkWidget* item , gpointer data) , gpointer data ) { GtkWidget *item = gtk_image_menu_item_new_with_label(name); GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_size(iconpath , 16 , 16 , NULL); GtkWidget *img = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img); gtk_menu_shell_append(GTK_MENU_SHELL(parent) , item); if(func != NULL) g_signal_connect(item , "activate" , G_CALLBACK(func) , data); return item; } GtkWidget* fx_main_create_menu1(const gchar* name , const gchar *UNUSED(stockid) , GtkWidget* parent , void (*func)(GtkWidget* item , gpointer data) , gpointer data ) { GtkWidget *item = gtk_image_menu_item_new_with_label(name); #if 0 GtkWidget *img = gtk_image_new_from_stock(stockid , GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img); #endif gtk_menu_shell_append(GTK_MENU_SHELL(parent) , item); if(func != NULL) g_signal_connect(item , "activate" , G_CALLBACK(func) , data); return item; } void fx_main_process_notification(FxMain* fxmain , const gchar* sipmsg) { gint event; gint notification_type; gchar *xml; fetion_sip_parse_notification(sipmsg , ¬ification_type , &event , &xml); g_usleep(1); switch(notification_type) { case NOTIFICATION_TYPE_PRESENCE: switch(event) { case NOTIFICATION_EVENT_PRESENCECHANGED : fx_main_process_presence(fxmain , xml); break; default: break; } case NOTIFICATION_TYPE_CONVERSATION : if(event == NOTIFICATION_EVENT_USERLEFT){ fx_main_process_user_left(fxmain , sipmsg); break; } break; case NOTIFICATION_TYPE_REGISTRATION : if(event == NOTIFICATION_EVENT_DEREGISTRATION){ fx_main_process_deregistration(fxmain); break; } break; case NOTIFICATION_TYPE_SYNCUSERINFO : if(event == NOTIFICATION_EVENT_SYNCUSERINFO){ fx_main_process_syncuserinfo(fxmain , xml); break; } break; case NOTIFICATION_TYPE_CONTACT : if(event == NOTIFICATION_EVENT_ADDBUDDYAPPLICATION){ fx_main_process_addbuddyapplication(fxmain , sipmsg); break; } break; case NOTIFICATION_TYPE_PGGROUP : if(event == NOTIFICATION_EVENT_PGGETGROUPINFO){ fx_main_process_pggetgroupinfo(fxmain , sipmsg); break; } if(event == NOTIFICATION_EVENT_PRESENCECHANGED){ fx_main_process_pgpresencechanged(fxmain , sipmsg); break; } break; default: break; } g_free(xml); } static void *update_data(void *data) { FxMain *fxmain = (FxMain*)data; User *user = fxmain->user; fetion_user_save(user); fetion_contact_save(user); fx_tree_update_portrait(data); return NULL; } static void popup_online_notify(FxMain *fxmain, Contact *contact) { #ifdef USE_LIBNOTIFY gchar notifySummary[256]; gchar notifyText[1024]; gchar iconPath[256]; GdkPixbuf *pixbuf; Config *config; config = fxmain->user->config; if(start_popup_presence && presence_count > fxmain->user->contactCount && config->onlineNotify == ONLINE_NOTIFY_ENABLE){ sprintf(iconPath , "%s/%s.jpg", config->iconPath , contact->sId); sprintf(notifySummary, _("%s , now ONLINE") , contact->nickname); snprintf(notifyText, sizeof(notifyText) - 1, _("Phone Number: %s\n" "Fetion Number: %s\n" "Signature: %s"), contact->mobileno == NULL || strlen(contact->mobileno) == 0 ? _("unknown") : contact->mobileno, contact->sId, contact->impression ); pixbuf = gdk_pixbuf_new_from_file_at_size( iconPath, NOTIFY_IMAGE_SIZE, NOTIFY_IMAGE_SIZE , NULL); if(!pixbuf) pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", NOTIFY_IMAGE_SIZE, NOTIFY_IMAGE_SIZE , NULL); notify_notification_update(fxmain->notify , notifySummary , notifyText , NULL); notify_notification_set_icon_from_pixbuf(fxmain->notify , pixbuf); notify_notification_show(fxmain->notify , NULL); g_object_unref(pixbuf); } #endif } void fx_main_process_presence(FxMain* fxmain , const gchar* xml) { gchar *crc = NULL; gchar *name; gint oldstate , count; Contact *contactlist; Contact *contact; User *user = fxmain->user; GtkWidget *treeView = fxmain->mainPanel->treeView; GtkTreeModel *model; FxChat *fxchat; GtkTreeIter iter; GtkTreeIter parentIter; contactlist = fetion_user_parse_presence_body(xml , user); contact = contactlist; model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)); foreach_contactlist(contactlist , contact){ foreach_groupids(contact->groupids) { if(fx_tree_get_buddy_iter(model, group_id, contact->userId, &iter) == -1) continue; presence_count ++; /* all presence information has been pushed * then start update local data and buddy portrait */ if(presence_count == user->contactCount) g_thread_create(update_data, fxmain, FALSE, NULL); gtk_tree_model_get(model , &iter , B_CRC_COL , &crc , B_STATE_COL , &oldstate , -1); gdk_threads_enter(); fxchat = fx_list_find_chat_by_sipuri(fxmain->clist , contact->sipuri); if(oldstate > 0 && contact->state <= 0 && contact->serviceStatus == STATUS_NORMAL) { gtk_tree_model_iter_parent(model , &parentIter , &iter); gtk_tree_model_get(model , &parentIter , G_ONLINE_COUNT_COL , &count , -1); count --; gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter , G_ONLINE_COUNT_COL , count , -1); fx_tree_move_to_the_last(model , &iter); } if(oldstate <= 0 && contact->state > 0 && contact->serviceStatus == STATUS_NORMAL) { gtk_tree_model_iter_parent(model , &parentIter , &iter); gtk_tree_model_get(model , &parentIter , G_ONLINE_COUNT_COL , &count , -1); count ++; gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter , G_ONLINE_COUNT_COL , count , -1); fx_tree_move_to_the_last(model , &iter); fx_tree_move_to_the_first(model , &iter); popup_online_notify(fxmain, contact); } if(fxchat) fxchat->state = contact->state; name = (contact->nickname == NULL || strlen(contact->localname) == 0)? contact->nickname : contact->localname; gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , B_NAME_COL , g_markup_escape_text(name, -1) , B_SIPURI_COL , contact->sipuri , B_IMPRESSION_COL , g_markup_escape_text(contact->impression, -1) , B_PHONENUM_COL , contact->mobileno , B_USERID_COL , contact->userId , B_STATE_COL , contact->state , B_IDENTITY_COL , contact->identity , B_DEVICE_COL , contact->devicetype , B_RELATIONSTATUS_COL , contact->relationStatus , B_SERVICESTATUS_COL , contact->serviceStatus , B_CARRIERSTATUS_COL , contact->carrierStatus , B_CARRIER_COL , contact->carrier , B_CRC_COL , contact->portraitCrc , B_IMAGE_CHANGED_COL , crc == NULL ? IMAGE_CHANGED : (strcmp(crc , contact->portraitCrc) == 0 ? IMAGE_NOT_CHANGED : IMAGE_CHANGED) , -1); g_free(crc); gdk_threads_leave(); } end_groupids(contact->groupids) } } static void process_system_message(const char *sipmsg) { gint showonce; gint type; gchar *msg; gchar *url; FxSysmsg *sysmsg; fetion_sip_parse_sysmsg(sipmsg , &type , &showonce , &msg , &url); if(type == 0){ sysmsg = fx_sysmsg_new(); fx_sysmsg_initialize(sysmsg); fx_sysmsg_bind(sysmsg , msg , url); g_free(sysmsg); } } static void process_group_message(FxMain *fxmain , Message *message) { FxPGGroup *fxpgcur; FxPGGroup *fxpg = NULL; PGGroupMember *memcur; FxList *pglist; FxList *cur; User *user; Config *config; GdkPixbuf *pixbuf; gchar path[1024]; gchar *sid; user = fxmain->user; config = user->config; pglist = fxmain->pglist; foreach_list(pglist , cur){ fxpgcur = (FxPGGroup*)(cur->data); if(strcmp(fxpgcur->pggroup->pguri, message->pguri) == 0){ fxpg = fxpgcur; break; } } gdk_threads_enter(); if(fxpg == NULL || fxpg->hasFocus == CHAT_DIALOG_NOT_FOCUSED ){ if(fxpg == NULL){ if(config->autoPopup == AUTO_POPUP_ENABLE){ fxpg = pg_create_window(fxmain , message->pguri); foreach_pg_member(fxpg->pggroup->member , memcur){ if(strcmp(memcur->sipuri , message->sipuri) == 0) pg_add_message(fxpg , message->message , &(message->sendtime) , memcur); } }else{ cur = fx_list_new(message); fx_list_append(fxmain->mlist , cur); } }else{ foreach_pg_member(fxpg->pggroup->member , memcur){ if(strcmp(memcur->sipuri , message->sipuri) == 0) pg_add_message(fxpg , message->message , &(message->sendtime) , memcur); } } if(USE_STATUS_ICON(config)) { /* set the action of the status icon */ sid = fetion_sip_get_pgid_by_sipuri(message->pguri); snprintf(path , sizeof(path) - 1 , "%s/PG%s.jpg" , config->iconPath , sid); g_free(sid); pixbuf = gdk_pixbuf_new_from_file(path , NULL); if(pixbuf == NULL) pixbuf = gdk_pixbuf_new_from_file(SKIN_DIR"online.svg" , NULL); gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(fxmain->trayIcon) , pixbuf); g_object_unref(pixbuf); gtk_status_icon_set_blinking(GTK_STATUS_ICON(fxmain->trayIcon) , TRUE); g_signal_handler_disconnect(fxmain->trayIcon , fxmain->iconConnectId); fxmain->iconConnectId = g_signal_connect(G_OBJECT(fxmain->trayIcon) , "activate" , GTK_SIGNAL_FUNC(fx_main_message_func) , fxmain); } }else{ foreach_pg_member(fxpg->pggroup->member , memcur){ if(strcmp(memcur->sipuri , message->sipuri) == 0) pg_add_message(fxpg , message->message , &(message->sendtime) , memcur); } } gdk_threads_leave(); if(config->isMute == MUTE_DISABLE) fx_sound_play_file(RESOURCE_DIR"newmessage.wav"); } static void popup_msg_notify(FxMain *fxmain, Contact *senderContact, Message *msg) { #ifdef USE_LIBNOTIFY Config *config = fxmain->user->config; GdkPixbuf *notifyIcon; gchar *senderSid; gchar iconPath[256]; gchar notifySum[256]; if(config->msgAlert == MSG_ALERT_ENABLE){ if(senderContact){ sprintf(iconPath, "%s/%s.jpg", config->iconPath, senderContact->sId); senderSid = fetion_sip_get_sid_by_sipuri(msg->sipuri); sprintf(notifySum, _("%s(%s) said:"), senderContact->nickname , senderContact->sId); g_free(senderSid); notifyIcon = gdk_pixbuf_new_from_file_at_size( iconPath , 48 , 48 , NULL); notify_notification_update(fxmain->notify, notifySum, msg->message , NULL); if(!notifyIcon) notifyIcon = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", 48, 48, NULL); notify_notification_set_icon_from_pixbuf( fxmain->notify , notifyIcon); notify_notification_show(fxmain->notify , NULL); g_object_unref(notifyIcon); } } #endif } #ifdef USE_INDICATE static gint indicate_action() { GSList *iterator = NULL; IndicateIndicator *indicator = NULL; gint count = 0; for (iterator = indicators; iterator; iterator = iterator->next, count ++) { indicator = (IndicateIndicator*)iterator->data; /* clear attention */ indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, ""); /* remove the indicators from the indicate server */ indicate_server_remove_indicator(fxmain->indserver, indicator); } /* free the memory allocated for the indicator list */ g_slist_free(indicators); indicators = NULL; if(count == 0) return 0; /* process the incoming message */ fx_main_message_func(NULL, fxmain); return count; } #ifdef USE_INDICATE static void server_display(IndicateServer *UNUSED(server), guint UNUSED(timestamp)) { if(indicate_action() == 0) { //gtk_widget_show(fxmain->window); if(window_pos_x_old == 0 && window_pos_y_old == 0){ window_pos_x_old = window_pos_x; window_pos_y_old = window_pos_y; } gtk_window_move(GTK_WINDOW(fxmain->window), window_pos_x_old , window_pos_y_old); gtk_window_present(GTK_WINDOW(fxmain->window)); } } #endif //USE_INDICATE static void message_display(IndicateIndicator *UNUSED(indicator), gpointer UNUSED(data)) { indicate_action(); } static IndicateIndicator *get_indicator(IndicateServer *server, const gchar *sid) { GSList *iterator = NULL; IndicateIndicator *indicator; const gchar *id; gchar portrait[1024]; GdkPixbuf *pixbuf; for (iterator = indicators; iterator; iterator = iterator->next) { indicator = (IndicateIndicator*)iterator->data; id = indicate_indicator_get_property(indicator, "sid"); if(strcmp(sid, id) == 0) return indicator; } /* no indicator found, create one :) */ indicator = indicate_indicator_new(); /* add it to the global indicator list */ indicators = g_slist_append(indicators, indicator); indicate_server_add_indicator(server, indicator); indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, "0"); indicate_indicator_set_property(indicator, "sid", sid); /* set icon */ snprintf(portrait, sizeof(portrait) - 1, "%s/%s.jpg", fxmain->user->config->iconPath, sid); pixbuf = gdk_pixbuf_new_from_file(portrait, NULL); indicate_indicator_set_property_icon(indicator, INDICATE_INDICATOR_MESSAGES_PROP_ICON, pixbuf); g_object_unref(pixbuf); g_signal_connect(G_OBJECT(indicator), INDICATE_INDICATOR_SIGNAL_DISPLAY, G_CALLBACK(message_display), NULL); indicate_indicator_show(indicator); return indicator; } #endif // USE_INDICATE void messaging_menu_add_new_msg(FxMain *fxmain, Contact *cnt) { #ifdef USE_INDICATE gchar *sid = 0; gchar count[128]; sid = fetion_sip_get_sid_by_sipuri(cnt->sipuri); IndicateIndicator *indicator = get_indicator(fxmain->indserver, sid); gint count_int = atoi(indicate_indicator_get_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT)); snprintf(count, sizeof(count) - 1, "%d", count_int + 1); indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_COUNT, count); #if 0 GTimeVal time; g_get_current_time(&time); indicate_indicator_set_property_time(ind, "time", &time); #endif indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_NAME, *(cnt->localname) == '\0'?cnt->nickname: cnt->localname); indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, "GET A MESSAGE"); g_free(sid); #endif // USE_INDICATE } void fx_main_process_message(FxMain* fxmain , FetionSip* sip , const gchar* sipmsg) { Message *msg; FxList *clist; FxList *mitem; FxChat *fxchat; User *user; Config *config; gchar path[256]; gchar *sid; GdkPixbuf *pb; Contact *senderContact; clist = fxmain->clist; user = fxmain->user; config = user->config; fetion_sip_parse_message(sip , sipmsg , &msg); /* group message */ if(msg->pguri){ process_group_message(fxmain , msg); return; } fxchat = fx_list_find_chat_by_sipuri(clist , msg->sipuri); sid = fetion_sip_get_sid_by_sipuri(msg->sipuri); senderContact = fetion_contact_list_find_by_sipuri( user->contactList , msg->sipuri); /* system message */ if(strlen(sid) < 5 || strcmp(sid , "10000") == 0){ g_free(sid); if(config->closeSysMsg == CLOSE_SYSMSG_ENABLE) return; gdk_threads_enter(); process_system_message(sipmsg); gdk_threads_leave(); fetion_message_free(msg); return; } if(senderContact) fx_main_add_history(fxmain, senderContact->nickname, senderContact->userId, msg->message, 0); gdk_threads_enter(); if(!fxchat || fxchat->hasFocus == CHAT_DIALOG_NOT_FOCUSED){ /* chat window does not exist */ if(!fxchat) { /* auto popup enabled */ if(config->autoPopup == AUTO_POPUP_ENABLE) { fxchat = fx_main_create_chat_window(fxmain , msg->sipuri); if(!fxchat) { fetion_message_free(msg); gdk_threads_leave(); return; } fx_chat_add_message(fxchat , msg->message, &(msg->sendtime) , 0 , msg->sysback); fetion_message_free(msg); gdk_threads_leave(); return; } else { /* chat window doesn`t exist and auto-pupup wasn`t enabled * just push message into message queue,wait for user action */ mitem = fx_list_new(msg); fx_list_append(fxmain->mlist , mitem ); popup_msg_notify(fxmain, senderContact, msg); messaging_menu_add_new_msg(fxmain, senderContact); } /* chat window exist,but not focused */ } else { fx_chat_add_message(fxchat , msg->message, &(msg->sendtime) , 0 , msg->sysback); messaging_menu_add_new_msg(fxmain, senderContact); fxchat->unreadMsgCount ++; fx_chat_update_window(fxchat); } if(USE_STATUS_ICON(config)) { /* set the action of the status icon */ snprintf(path, sizeof(path) - 1, "%s/%s.jpg", config->iconPath, sid); g_free(sid); pb = gdk_pixbuf_new_from_file(path, NULL); if(!pb) pb = gdk_pixbuf_new_from_file(SKIN_DIR"online.svg", NULL); gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(fxmain->trayIcon), pb); g_object_unref(pb); gtk_status_icon_set_blinking(GTK_STATUS_ICON(fxmain->trayIcon), TRUE); g_signal_handler_disconnect(fxmain->trayIcon, fxmain->iconConnectId); fxmain->iconConnectId = g_signal_connect(G_OBJECT(fxmain->trayIcon) , "activate" , GTK_SIGNAL_FUNC(fx_main_message_func) , fxmain); } /* no message was pushed into the message queue,just free it */ if(fxchat && fxchat->hasFocus == CHAT_DIALOG_NOT_FOCUSED) fetion_message_free(msg); } else { fx_chat_add_message(fxchat , msg->message, &(msg->sendtime) , 0, msg->sysback); /* message was showed in the chat dialog directly,just free it */ fetion_message_free(msg); } gdk_threads_leave(); if(config->isMute == MUTE_DISABLE) fx_sound_play_file(RESOURCE_DIR"newmessage.wav"); } void fx_main_process_user_left(FxMain *fxmain, const gchar *msg) { gchar *sipuri; FxList *clist; FxChat *fxchat; Conversation *conv; clist = fxmain->clist; fetion_sip_parse_userleft(msg , &sipuri); /* remove sip struct from stack */ fx_list_remove_sip_by_sipuri(fxmain->slist , sipuri); /* if fxchat exist , set current sip struct to NULL , * and exit thread, orelse just exit current thread */ fxchat = fx_list_find_chat_by_sipuri(clist , sipuri); if(!fxchat) { debug_info("User %s left conversation" , sipuri); debug_info("Thread exit"); g_free(sipuri); g_thread_exit(0); } conv = fxchat->conv; conv->currentSip = NULL; debug_info("User %s left conversation" , sipuri); debug_info("Thread exit"); g_free(sipuri); g_thread_exit(0); } FxChat* fx_main_create_chat_window(FxMain* fxmain , const gchar* sipuri) { Conversation *conv; FxChat *fxchat; FxList *citem; Contact *contact; gchar *sid; if((fxchat = fx_list_find_chat_by_sipuri(fxmain->clist , sipuri)) != NULL) return fxchat; conv = fetion_conversation_new(fxmain->user , sipuri , NULL); /* this buddy is not in the friend list*/ if(!conv) { sid = fetion_sip_get_sid_by_sipuri(sipuri); if(strlen(sid) < 8 || strcmp(sid , "10000") == 0){ g_free(sid); return NULL; } contact = fetion_contact_get_contact_info_by_no(fxmain->user , sid , FETION_NO); if(!contact) return NULL; /* replace the sipuri*/ memset(contact->sipuri, 0, sizeof(contact->sipuri)); strcpy(contact->sipuri , sipuri); fetion_contact_list_append(fxmain->user->contactList , contact); conv = fetion_conversation_new(fxmain->user , sipuri , NULL); } if(!conv) return NULL; fxchat = fx_chat_new(fxmain , conv); fx_chat_initialize(fxchat); citem = fx_list_new(fxchat); fx_list_append(fxmain->clist , citem); return fxchat; } void fx_main_process_invitation(FxMain* fxmain , const gchar* sipmsg) { gchar *sipuri; FetionSip *osip; FetionSip *sip; FxList *list; TimeOutArgs *timeout; gchar event[16]; ThreadArgs *args; args = (ThreadArgs*)malloc(sizeof(ThreadArgs)); sip = fxmain->user->sip; memset(event, 0, sizeof(event)); if(fetion_sip_get_attr(sipmsg , "N" , event) != -1){ free(args); return; } fetion_sip_parse_invitation(sip, fxmain->user->config->proxy, sipmsg , &osip , &sipuri); list = fx_list_new(osip); fx_list_append(fxmain->slist , list); args->fxmain = fxmain; args->sip = osip; /* create a thread to listen in this channel */ g_thread_create(fx_main_listen_thread_func, args , FALSE , NULL); /* start send keep alive message throuth chat chanel * and put the timeout information into stack */ debug_info("Start periodically sending keep alive request"); timeout = timeout_args_new(fxmain , osip , sipuri); list = fx_list_new(timeout); fx_list_append(fxmain->tlist , list); } #if 0 static void process_share_action_accept(FxMain *fxmain , FetionSip *sip , const char *sipmsg , const char *sipuri){ return; } static void process_share_action_cancel(FxMain *fxmain , FetionSip *sip , const char *sipmsg , const char *sipuri){ return; } #endif static void *input_func(void *data) { FxChat *fxchat = (FxChat*)data; gdk_threads_enter(); if(--fxchat->inputRefcnt <= 0) fx_chat_clear_input(fxchat); gdk_threads_leave(); return (void*)0; } void fx_main_process_incoming(FxMain* fxmain , FetionSip* sip , const gchar* sipmsg) { IncomingType type; IncomingActionType action; gchar *sipuri; FxChat *fxchat; fetion_sip_parse_incoming(sip , sipmsg , &sipuri , &type , &action); switch(type) { case INCOMING_NUDGE : { gdk_threads_enter(); fxchat = fx_main_create_chat_window(fxmain , sipuri); gdk_threads_leave(); fx_chat_nudge_in_thread(fxchat); gdk_threads_enter(); fx_chat_add_information(fxchat , _("Receive a window jitter")); gdk_threads_leave(); debug_info("Received a nudge from %s" , sipuri); break; } case INCOMING_INPUT: { if(!(fxchat = fx_list_find_chat_by_sipuri(fxmain->clist , sipuri))) return; gdk_threads_enter(); fxchat->inputRefcnt ++; fx_chat_set_input(fxchat); g_timeout_add_seconds(3, (GSourceFunc)input_func, fxchat); gdk_threads_leave(); } case INCOMING_SHARE_CONTENT : { switch(action){ case INCOMING_ACTION_ACCEPT : //process_share_action_accept(fxmain , sip , sipmsg , sipuri); break; case INCOMING_ACTION_CANCEL : //process_share_action_cancel(fxmain , sip , sipmsg , sipuri); break; default: break; } break; } default: break; } } static void fx_main_process_group(FxMain *fxmain , const gchar *xml) { User *user = fxmain->user; PGGroup *pgcur; user->pggroup = pg_group_parse_list(xml); if(user->pggroup == NULL) return; pg_group_get_info(user , user->pggroup); foreach_pg_group(user->pggroup , pgcur){ pg_group_send_invitation(user , pgcur); pg_group_get_group_members(user , pgcur); } } void fx_main_process_sipc(FxMain* fxmain , const gchar* sipmsg) { int callid; int code; char *xml = NULL; User *user = fxmain->user; struct unacked_list *ulist; PGGroup *pggroup = user->pggroup; PGGroup *pgcur; code = fetion_sip_parse_sipc(sipmsg , &callid , &xml); /* get group info response */ if(callid == user->pgGroupCallId){ gdk_threads_enter(); fx_main_process_group(fxmain , xml); gdk_threads_leave(); return; } foreach_unacked_list(unackedlist , ulist) { if(callid == ulist->message->callid){ unacked_list_remove(unackedlist , ulist); fetion_message_free(ulist->message); free(ulist); return; } } if(pggroup != NULL){ foreach_pg_group(pggroup , pgcur){ #if 0 /* get member contact info response */ foreach_pg_member(pgcur->member , memcur){ if(memcur->getContactInfoCallId == callid){ memcur->contact = pg_group_parse_contact_info(xml); return; } } #endif /* group invitation response */ if(pgcur->inviteCallId == callid && code == 200){ if(pgcur->hasAcked == 0){ pg_group_send_invite_ack(user , sipmsg); pgcur->hasAcked = 1; return; } } /* get group member response */ if(pgcur->getMembersCallId == callid){ pg_group_parse_member_list(pggroup , sipmsg); pg_group_subscribe(user , pgcur); return; } } } free(xml); } void fx_main_process_deregistration(FxMain* fxmain) { gdk_threads_enter(); #ifdef USE_LIBNOTIFY GdkPixbuf *pixbuf; pixbuf = gdk_pixbuf_new_from_file_at_size( SKIN_DIR"fetion.svg", NOTIFY_IMAGE_SIZE, NOTIFY_IMAGE_SIZE, NULL); notify_notification_update(fxmain->notify , "Sorry.." , _("Your fetion login elsewhere. You are forced quit."), NULL); notify_notification_set_icon_from_pixbuf(fxmain->notify , pixbuf); notify_notification_show(fxmain->notify , NULL); g_object_unref(pixbuf); #endif gdk_threads_leave(); } void fx_main_process_syncuserinfo(FxMain* fxmain , const gchar* xml) { Contact* contact; GtkTreeIter iter; GtkTreeIter cIter; gchar *userid; GtkTreeModel* model = gtk_tree_view_get_model( GTK_TREE_VIEW(fxmain->mainPanel->treeView)); contact = fetion_user_parse_syncuserinfo_body(xml , fxmain->user); if(!contact) return; gtk_tree_model_get_iter_root(model , &iter); do { if(gtk_tree_model_iter_children(model , &cIter , &iter)){ do{ gtk_tree_model_get(model , &cIter , B_USERID_COL , &userid , -1); if(strcmp(userid , contact->userId) == 0){ gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model) , &cIter , B_SIPURI_COL , contact->sipuri , B_RELATIONSTATUS_COL , contact->relationStatus , -1); gdk_threads_leave(); g_free(userid); goto end; } g_free(userid); } while(gtk_tree_model_iter_next(model , &cIter)); } } while(gtk_tree_model_iter_next(model , &iter)); end: return; } void* fx_main_process_addbuddyapplication_thread(void* data) { struct args1 { FxMain *fxmain; gchar sipmsg[2048]; } *args = (struct args1*)data; gchar *userid; gchar *sipuri; gchar *desc; gint phrase; FxApp *fxapp; fetion_sip_parse_addbuddyapplication(args->sipmsg, &sipuri , &userid , &desc , &phrase); fxapp = fx_app_new(args->fxmain, sipuri, userid , desc , phrase); gdk_threads_enter(); fx_app_initialize(fxapp); gtk_dialog_run(GTK_DIALOG(fxapp->dialog)); gtk_widget_destroy(fxapp->dialog); gdk_threads_leave(); return NULL; } void fx_main_process_addbuddyapplication(FxMain* fxmain , const char* sipmsg) { struct args1 { FxMain* fxmain; char sipmsg[2048]; } *args = (struct args1*)malloc(sizeof(struct args1)); memset(args , 0 , sizeof(struct args1)); args->fxmain = fxmain; strcpy(args->sipmsg , sipmsg); g_thread_create(fx_main_process_addbuddyapplication_thread , args , FALSE , NULL); } void fx_main_destroy(GtkWidget* UNUSED(widget) , gpointer data) { FxMain *fxmain = (FxMain*)data; User *user = fxmain->user; char server_fifo[128]; if(user){ Config *config = user->config; fetion_config_save_size(config); extern int idlefifo; /* delete fifo file */ close(idlefifo); snprintf(server_fifo, sizeof(server_fifo) - 1, OPENFETION_FIFO_FILE, user->mobileno); unlink(server_fifo); } gtk_main_quit(); } gboolean fx_main_delete(GtkWidget *widget , GdkEvent *UNUSED(event) , gpointer data) { FxMain *fxmain = (FxMain*)data; FxClose *fxclose; Config *config; gint window_width; gint window_height; gint window_x; gint window_y; gint useMessagingMenu = 0; #ifdef USE_INDICATE useMessagingMenu = 1; #endif if(!fxmain->window) return TRUE; if(fxmain->user){ config = fxmain->user->config; if(!USE_STATUS_ICON(config) && !useMessagingMenu) return TRUE; gtk_window_get_position(GTK_WINDOW(fxmain->window), &window_x, &window_y); config->window_pos_x = window_x; config->window_pos_y = window_y; gtk_window_get_size(GTK_WINDOW(fxmain->window), &window_width, &window_height); config->window_width = window_width; config->window_height = window_height; } if(fxmain->user){ if(config->closeAlert == CLOSE_ALERT_ENABLE){ int ret; fxclose = fx_close_new(fxmain); fx_close_initialize(fxclose); ret = gtk_dialog_run(GTK_DIALOG(fxclose->dialog)); if(ret == GTK_RESPONSE_OK){ if(fx_close_alert(fxclose) == CLOSE_ALERT_DISABLE){ config->closeMode = fx_close_get_action(fxclose); config->closeAlert = CLOSE_ALERT_DISABLE; fetion_config_save(fxmain->user); } if(fx_close_get_action(fxclose) == CLOSE_DESTROY_MODE){ gtk_widget_destroy(fxclose->dialog); free(fxclose); gtk_widget_destroy(widget); return FALSE; }else{ gtk_widget_destroy(fxclose->dialog); gtk_widget_hide_on_delete(widget); return TRUE; } }else{ gtk_widget_destroy(fxclose->dialog); return TRUE; } } }else{ fx_main_destroy(widget , fxmain); return FALSE; } if(fxmain->user != NULL && fxmain->user->loginStatus != -1){ config = fxmain->user->config; if(config->closeMode == CLOSE_ICON_MODE){ gtk_widget_hide_on_delete(widget); return TRUE; }else{ gtk_widget_destroy(widget); return FALSE; } } return FALSE; } gboolean fx_main_window_state_func(GtkWidget *widget , GdkEventWindowState *event , gpointer data) { FxMain *fxmain; Config *config; fxmain = (FxMain*)data; config = fxmain->user == NULL ? NULL: fxmain->user->config; if(config){ if(event->changed_mask == GDK_WINDOW_STATE_ICONIFIED && event->new_window_state == GDK_WINDOW_STATE_ICONIFIED){ if(config->canIconify == ICON_CAN){ gtk_window_get_position(GTK_WINDOW(widget) , &window_pos_x_old , &window_pos_y_old); return TRUE; }else{ return FALSE; } } } return FALSE; } void fx_main_tray_activate_func(GtkWidget *UNUSED(widget) , gpointer data) { FxMain *fxmain; Config *config = NULL; fxmain = (FxMain*)data; if(fxmain->user && fxmain->user->config) config = fxmain->user->config; if(!config) return; gtk_window_deiconify(GTK_WINDOW(fxmain->window)); if(GTK_WIDGET_VISIBLE(fxmain->window)){ if(config->canIconify == ICON_CAN){ gtk_window_iconify(GTK_WINDOW(fxmain->window)); gtk_window_get_position(GTK_WINDOW(fxmain->window) , &window_pos_x_old , &window_pos_y_old); gtk_widget_hide(fxmain->window); } } else{ //gtk_window_deiconify(GTK_WINDOW(fxmain->window)); gtk_widget_show(fxmain->window); } if(window_pos_x_old == 0 && window_pos_y_old == 0){ window_pos_x_old = window_pos_x; window_pos_y_old = window_pos_y; } gtk_window_move(GTK_WINDOW(fxmain->window), window_pos_x_old , window_pos_y_old); } static void fx_main_mute_clicked( GtkWidget *UNUSED(widget) , gpointer data) { FxMain *fxmain; User *user; Config *config; fxmain = (FxMain*)data; user = fxmain->user; config = user->config; if(config->isMute == MUTE_ENABLE) config->isMute = MUTE_DISABLE; else config->isMute = MUTE_ENABLE; fetion_config_save(user); } static void fx_main_direct_sms_clicked( GtkWidget *UNUSED(widget) , gpointer data) { FxMain *fxmain; FxDSMS *fxdsms; fxmain = (FxMain*)data; fxdsms = fx_dsms_new(fxmain); if(fxmain->user->carrierStatus == CARRIER_STATUS_DOWN){ fx_util_popup_warning(fxmain, SERVICE_DOWN_MESSAGE); return; } fx_dsms_initialize(fxdsms); } void fx_main_tray_popmenu_func( GtkWidget* UNUSED(widget), guint button , guint activate_time, gpointer data) { FxMain *fxmain; User *user; Config *config; GtkWidget *item; GtkWidget *menu; GtkWidget *statemenu; GtkWidget *submenu; gchar stateMenu[48]; gint i; typedef struct { FxMain* fxmain; StateType type; } Args1; Args1 *args; fxmain = (FxMain*)data; user = fxmain->user; struct { const gchar* name; const gchar* icon; int type; } presence[] = { { N_("Online") , SKIN_DIR"online.svg" , P_ONLINE } , { N_("Leave") , SKIN_DIR"away.svg" , P_AWAY } , { N_("Busy") , SKIN_DIR"busy.svg" , P_BUSY } , { N_("Hide") , SKIN_DIR"invisible.svg" , P_HIDDEN } , { N_("Eating out") , SKIN_DIR"away.svg" , P_OUTFORLUNCH } , { N_("Do Not Disturb") , SKIN_DIR"away.svg" , P_DONOTDISTURB } , { N_("Back Soon") , SKIN_DIR"away.svg" , P_RIGHTBACK } , { N_("Meeting") , SKIN_DIR"away.svg" , P_MEETING } , { N_("Calling") , SKIN_DIR"away.svg" , P_ONTHEPHONE} , { NULL , NULL , -1} }; menu = gtk_menu_new(); fx_main_create_menu1(_("About OpenFetion") , GTK_STOCK_ABOUT , menu , fx_main_about_fetion_clicked , NULL); if(fxmain->user && fxmain->user->loginStatus != -1) { config = fxmain->user->config; item = gtk_check_menu_item_new_with_label(_("Close sound")); if(config->isMute == MUTE_ENABLE) gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item) , TRUE); else gtk_check_menu_item_set_active( GTK_CHECK_MENU_ITEM(item) , FALSE); g_signal_connect(item, "activate", G_CALLBACK(fx_main_mute_clicked) , fxmain); gtk_menu_shell_append(GTK_MENU_SHELL(menu) , item); item = gtk_check_menu_item_new_with_label(_("Receive SMS")); if(strcmp(user->smsOnLineStatus , "0.00:00:00") && strcmp(user->smsOnLineStatus , "0.0:0:0")) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item) , FALSE); else gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item) , TRUE); gtk_menu_shell_append(GTK_MENU_SHELL(menu) , item); g_signal_connect(item, "activate", G_CALLBACK(fx_head_set_sms_clicked) , fxmain); fx_main_create_menu1(_("Information query") , GTK_STOCK_FIND , menu , fx_main_info_lookup_clicked , fxmain); statemenu = fx_main_create_menu1(_("Edit statement"), GTK_STOCK_INFO , menu , NULL , NULL); submenu = gtk_menu_new(); for(i = 0 ; presence[i].type != -1 ; i++){ args = (Args1*)malloc(sizeof(Args1)); args->fxmain = fxmain; args->type = presence[i].type; sprintf(stateMenu , "%s " , _(presence[i].name)); fx_main_create_menu(stateMenu , presence[i].icon , submenu , fx_main_set_state_clicked , args); } gtk_menu_item_set_submenu(GTK_MENU_ITEM(statemenu) , submenu); statemenu = fx_main_create_menu1(_("Message Function"), GTK_STOCK_INFO , menu , NULL , NULL); submenu = gtk_menu_new(); fx_main_create_menu(_("SMS to many") , SKIN_DIR"groupsend.png" , submenu , fx_main_send_to_many_clicked , fxmain); fx_main_create_menu(_("SMS directly") , SKIN_DIR"directsms.png" , submenu , fx_main_direct_sms_clicked , fxmain); if(fxmain->user->boundToMobile == BOUND_MOBILE_ENABLE) fx_main_create_menu(_("SMS myself") , SKIN_DIR"myselfsms.png" , submenu , fx_main_send_to_myself_clicked , fxmain); gtk_menu_item_set_submenu(GTK_MENU_ITEM(statemenu) , submenu); fx_main_create_menu1(_("Add contact") , GTK_STOCK_ADD , menu , fx_main_add_buddy_clicked , fxmain); fx_main_create_menu1(_("Personal Settings") , GTK_STOCK_EDIT , menu , fx_main_personal_setting_clicked , fxmain); fx_main_create_menu1(_("System Settings") , GTK_STOCK_PREFERENCES , menu , fx_main_system_setting_clicked , fxmain); } fx_main_create_menu1(_("Exit OpenFetion ") , GTK_STOCK_QUIT , menu , fx_main_destroy , fxmain); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu) , NULL , NULL , NULL , NULL , button , activate_time); } int main(int argc , char* argv[]) { #ifdef ENABLE_NLS setlocale(LC_ALL, ""); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); bindtextdomain(GETTEXT_PACKAGE , LOCALE_DIR); textdomain(GETTEXT_PACKAGE); #endif /* cli mode */ if(argc != 1) { if(fx_cli_opt(argc, argv)) return 1; return fx_cli_exec(); } /* use the GLOBAL fxmain variable */ fxmain = fx_main_new(); if(!g_thread_supported()) g_thread_init(NULL); gdk_threads_init(); struct sigaction sa; sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, 0 ); #ifdef USE_GSTREAMER gst_init(&argc , &argv); #endif #ifdef USE_LIBNOTIFY notify_init("Openfetion"); #endif gtk_init(&argc , &argv); fx_conn_init(fxmain); fx_main_initialize(fxmain); return 0; } static void chat_listen_thread_end(FxMain *fxmain, const char *sipuri) { FxList *clist; FxChat *fxchat; Conversation *conv; clist = fxmain->clist; if(!sipuri || *sipuri == '\0') return; fx_list_remove_sip_by_sipuri(fxmain->slist , sipuri); fxchat = fx_list_find_chat_by_sipuri(clist , sipuri); if(!fxchat) { debug_info("User %s left conversation" , sipuri); debug_info("Thread exit"); g_thread_exit(0); } conv = fxchat->conv; conv->currentSip = NULL; debug_info("User %s left conversation" , sipuri); debug_info("Thread exit"); g_thread_exit(0); } void* fx_main_listen_thread_func(void* data) { ThreadArgs *args; FxMain *fxmain; FetionSip *sip; SipMsg *msg; SipMsg *pos; User *user; gint type; gint ret; gint error; args = (ThreadArgs*)data; fxmain = args->fxmain; user = fxmain->user; sip = args->sip; struct timeval tv; debug_info("A new thread entered"); sip = (sip == NULL ? fxmain->user->sip : sip); for(;;){ if(!fxmain) g_thread_exit(0); FD_ZERO(&fd_read); g_static_mutex_lock(&mutex); if(!sip || !sip->tcp){ debug_info("thread exited"); g_thread_exit(0); } FD_SET(sip->tcp->socketfd, &fd_read); g_static_mutex_unlock(&mutex); tv.tv_sec = 13; tv.tv_usec = 0; ret = select(sip->tcp->socketfd+1, &fd_read, NULL, NULL, &tv); if(ret == 0) continue; if (ret == -1) { debug_info ("Error.. to read socket %d,exit thread", sip->tcp->socketfd); if(sip != user->sip){ debug_info("Error.. thread sip freed\n"); g_free(sip); } g_thread_exit(0); } if (!FD_ISSET (sip->tcp->socketfd, &fd_read)) { g_usleep (100); continue; } msg = fetion_sip_listen(sip, &error); if(!msg && error){ /* if it is the main listening thread */ if(sip == user->sip){ gdk_threads_enter(); printf("\n\nError ...... break out...\n\n"); fx_conn_offline(fxmain); gdk_threads_leave(); g_thread_exit(0); }else{ printf("\n\n Error ... user listen thread break out\n\n"); chat_listen_thread_end(fxmain, sip->sipuri); tcp_connection_free(sip->tcp); g_thread_exit(0); } } pos = msg; while(pos){ type = fetion_sip_get_type(pos->message); switch(type){ case SIP_NOTIFICATION : fx_main_process_notification(fxmain , pos->message); break; case SIP_MESSAGE: fx_main_process_message(fxmain , sip , pos->message); break; case SIP_INVITATION: fx_main_process_invitation(fxmain , pos->message); break; case SIP_INCOMING : fx_main_process_incoming(fxmain , sip , pos->message); break; case SIP_SIPC_4_0: fx_main_process_sipc(fxmain , pos->message); break; default: //printf("%s\n" , pos->message); break; } pos = pos->next; } if(msg) fetion_sip_message_free(msg); } free(data); return NULL; } void fx_main_message_func(GtkWidget *UNUSED(widget) , gpointer data) { FxMain *fxmain; FxList *mlist; FxList *cur; FxList *tmp; FxChat *fxchat; FxPGGroup *fxpg; PGGroupMember *memcur; Message *msg; fxmain = (FxMain*)data; mlist = fxmain->mlist; cur = mlist->pre; #ifdef USE_LIBNOTIFY notify_notification_close(fxmain->notify , NULL); #endif #ifdef USE_INDICATE GSList *iterator = NULL; IndicateIndicator *indicator = NULL; for (iterator = indicators; iterator; iterator = iterator->next) { indicator = (IndicateIndicator*)iterator->data; /* clear attention */ indicate_indicator_set_property(indicator, INDICATE_INDICATOR_MESSAGES_PROP_ATTENTION, ""); /* remove the indicators from the indicate server */ indicate_server_remove_indicator(fxmain->indserver, indicator); } /* free the memory allocated for the indicator list */ g_slist_free(indicators); indicators = NULL; #endif while(cur != fxmain->mlist){ msg = (Message*)(cur->data); /* ordinary message */ if(!msg->pguri){ fxchat = fx_main_create_chat_window(fxmain , msg->sipuri); if(!fxchat){ g_print("Unknow Message\n"); g_print("%s:%s\n" , msg->sipuri , msg->message); continue; } fx_chat_add_message(fxchat , msg->message, &(msg->sendtime) , 0 , msg->sysback); }else{ /*group message*/ fxpg = pg_create_window(fxmain , msg->pguri); foreach_pg_member(fxpg->pggroup->member , memcur){ if(strcmp(memcur->sipuri , msg->sipuri) == 0){ pg_add_message(fxpg, msg->message, &(msg->sendtime) , memcur ); break; } } } fetion_message_free(msg); tmp = cur; cur = cur->pre; fx_list_remove(tmp); free(tmp); } fx_head_set_state_image(fxmain , fxmain->user->state); if(USE_STATUS_ICON(fxmain->user->config)) { /* set the action of the status icon */ gtk_status_icon_set_blinking( GTK_STATUS_ICON(fxmain->trayIcon) , FALSE); g_signal_handler_disconnect(fxmain->trayIcon, fxmain->iconConnectId); fxmain->iconConnectId = g_signal_connect( G_OBJECT(fxmain->trayIcon) , "activate" , GTK_SIGNAL_FUNC(fx_main_tray_activate_func) , fxmain); } foreach_list(fxmain->clist, cur){ fxchat = (FxChat*)cur->data; if(fxchat->unreadMsgCount != 0) gtk_window_present(GTK_WINDOW(fxchat->dialog)); } } gboolean fx_main_register_func(User* user) { if(fetion_user_keep_alive(user) < 0){ debug_info("keep alive terminated"); return FALSE; } return TRUE; } gboolean fx_main_check_func(FxMain* fxmain) { struct unacked_list *list; struct tm *now; char *msg; time_t now_t; time_t msg_time_t; long seconds; start_popup_presence = 1; if(fxmain->user->state == P_OFFLINE){ debug_info("Error.. check function exited"); return FALSE; } now = get_currenttime(); foreach_unacked_list(unackedlist , list){ now_t = mktime(now); msg_time_t = mktime(&(list->message->sendtime)); seconds = (long)now_t - (long)msg_time_t; if(seconds > 20) { unacked_list_remove(unackedlist , list); msg = contruct_message_sip(fxmain->user->sId , list->message); fx_main_process_message(fxmain , fxmain->user->sip , msg); free(msg); fetion_message_free(list->message); free(list); } } idle_autoaway(fxmain); return TRUE; } void fx_main_about_fetion_clicked(GtkWidget *UNUSED(widget) , gpointer UNUSED(data)) { show_about(); } void fx_main_send_to_myself_clicked(GtkWidget *widget , gpointer data) { fx_bottom_on_sendtome_clicked(widget , data); } void fx_main_send_to_many_clicked(GtkWidget *widget , gpointer data) { fx_bottom_on_sendtomany_clicked(widget , data); } void fx_main_personal_setting_clicked(GtkWidget *widget , gpointer data) { fx_bottom_on_setting_clicked(widget , data); } void fx_main_system_setting_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxMain *fxmain = (FxMain*)data; FxSet *fxset = fx_set_new(fxmain); fx_set_initialize(fxset); g_object_set(fxset->notebook , "page" , 1 , NULL); } void fx_main_set_state_clicked(GtkWidget *widget , gpointer data) { fx_head_change_state_func(widget , data); } void fx_main_add_buddy_clicked(GtkWidget *widget , gpointer data) { fx_bottom_on_addfriend_clicked(widget , data); } void fx_main_info_lookup_clicked(GtkWidget *widget , gpointer data) { fx_bottom_on_lookup_clicked(widget , data); } FetionSip* fx_list_find_sip_by_sipuri(FxList *fxlist , const char *sipuri) { FxList *cur; FetionSip *sip; gchar *sid; gchar *sid1; foreach_list(fxlist , cur){ sip = (FetionSip*)(cur->data); sid = fetion_sip_get_sid_by_sipuri(sip->sipuri); sid1 = fetion_sip_get_sid_by_sipuri(sipuri); if(strcmp(sid , sid1) == 0){ g_free(sid); sid = NULL; g_free(sid1); sid1 = NULL; return sip; } g_free(sid); sid = NULL; g_free(sid1); sid1 = NULL; } return NULL; } void fx_list_remove_sip_by_sipuri(FxList *fxlist , const char *sipuri) { FxList *cur; FetionSip *sip; gchar *sid; gchar *sid1; foreach_list(fxlist , cur){ sip = (FetionSip*)(cur->data); sid = fetion_sip_get_sid_by_sipuri(sip->sipuri); sid1 = fetion_sip_get_sid_by_sipuri(sipuri); if(strcmp(sid , sid1) == 0) { debug_info("Removing sip from sip list"); cur->next->pre = cur->pre; cur->pre->next = cur->next; g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; g_free(cur); break; } g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; } } FxChat* fx_list_find_chat_by_sipuri(FxList *fxlist , const char *sipuri) { FxChat *fxchat; FxList *cur; Contact *contact; gchar *sid; gchar *sid1; foreach_list(fxlist , cur){ fxchat = (FxChat*)(cur->data); contact = fxchat->conv->currentContact; sid = fetion_sip_get_sid_by_sipuri(contact->sipuri); sid1 = fetion_sip_get_sid_by_sipuri(sipuri); if(strcmp(sid , sid1) == 0){ g_free(sid); g_free(sid1); return fxchat; } g_free(sid); g_free(sid1); } return NULL; } void fx_list_remove_chat_by_sipuri(FxList *fxlist , const char *sipuri) { FxList *cur; Contact *contact; FxChat *fxchat; gchar *sid; gchar *sid1; foreach_list(fxlist , cur){ fxchat = (FxChat*)(cur->data); contact = fxchat->conv->currentContact; if(!contact){ printf("Unknown FxChat\n"); continue; } sid = fetion_sip_get_sid_by_sipuri(contact->sipuri); sid1 = fetion_sip_get_sid_by_sipuri(sipuri); if(strcmp(sid , sid1) == 0){ debug_info("Removing chat struct from chat list"); g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; cur->next->pre = cur->pre; cur->pre->next = cur->next; break; } g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; } } TimeOutArgs* fx_list_find_timeout_by_sipuri(FxList* fxlist , const char* sipuri) { TimeOutArgs *args; FxList *cur; gchar *sid; gchar *sid1; foreach_list(fxlist , cur){ args = (TimeOutArgs*)(cur->data); sid = fetion_sip_get_sid_by_sipuri(args->sipuri); sid1 = fetion_sip_get_sid_by_sipuri(sipuri); if(strcmp(sid , sid1) == 0){ g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; return args; } g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; } return NULL; } void fx_list_remove_timeout_by_sipuri(FxList* fxlist , const char* sipuri) { FxList *cur; TimeOutArgs *args; gchar *sid; gchar *sid1; foreach_list(fxlist , cur){ args = (TimeOutArgs*)(cur->data); sid = fetion_sip_get_sid_by_sipuri(args->sipuri); sid1 = fetion_sip_get_sid_by_sipuri(sipuri); if(strcmp(sid , sid1) == 0){ cur->next->pre = cur->pre; cur->pre->next = cur->next; g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; g_free(cur); break; } g_free(sid);sid = NULL; g_free(sid1);sid1 = NULL; } } void fx_list_remove_pg_by_sipuri(FxList* fxlist , const char* sipuri) { FxList *cur; FxPGGroup *fxpg; foreach_list(fxlist , cur){ fxpg = (FxPGGroup*)(cur->data); if(strcmp(fxpg->pggroup->pguri , sipuri) == 0){ cur->next->pre = cur->pre; cur->pre->next = cur->next; g_free(cur); break; } } } void fx_main_add_history(FxMain *fxmain, const char *name, const char *sid, const char *msg, int issend) { History *history; struct tm *now; now = get_currenttime(); history = fetion_history_message_new(name , sid , *now , msg , issend); g_static_mutex_lock(&mutex); fetion_history_add(fxmain->history , history); fetion_history_message_free(history); g_static_mutex_unlock(&mutex); } static void fx_main_process_pggetgroupinfo(FxMain *fxmain , const char *sipmsg) { PGGroup *pggroup = fxmain->user->pggroup; pg_group_parse_info(pggroup , sipmsg); gdk_threads_enter(); fx_tree_bind_pg_data(fxmain); gdk_threads_leave(); } static void fx_main_process_pgpresencechanged(FxMain *fxmain , const char *sipmsg) { PGGroup *pggroup = fxmain->user->pggroup; pg_group_parse_member(pggroup , sipmsg); #if 0 PGGroup *pgcur; /* get member contact info of current group */ foreach_pg_group(pggroup , pgcur){ if(pgcur->hasDetails == 0) pg_group_update_group_info(fxmain->user , pgcur); } #endif } static gboolean key_press_func(GtkWidget *widget , GdkEventKey *event , gpointer data) { if(event->keyval == GDK_w){ if(event->state & GDK_CONTROL_MASK){ gtk_window_iconify(GTK_WINDOW(widget)); return TRUE; }else{ return FALSE; } } if(event->keyval == GDK_q){ if(event->state & GDK_CONTROL_MASK) { fx_main_delete(widget , NULL , data); return TRUE; } else if (event->state == GDK_MOD1_MASK) { /* press `command-q` to quit on Mac OS X */ fx_main_delete(widget , NULL , data); return TRUE; }else{ return FALSE; } } return FALSE; } openfetion-2.2.1/src/fx_main.h0000644000175000017500000001413211561721144014726 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_MAIN_H #define FX_MAIN_H #define NOTIFY_IMAGE_SIZE 48 typedef struct{ FxMain *fxmain; FetionSip *sip; gboolean terminated; gchar sipuri[50]; } TimeOutArgs; extern FxMain* fx_main_new(); extern void fx_main_free(FxMain* main); extern void fx_main_set_user(FxMain* fxmain , User* user); extern void fx_main_history_init(FxMain *fxmain); extern void update(); /** * time out args function */ extern TimeOutArgs* timeout_args_new(FxMain* fxmain , FetionSip *sip , const char *sipuri); /** * private function */ extern GtkWidget* fx_main_create_menu(const char* name , const char* iconpath , GtkWidget* parent , void (*func)(GtkWidget* item , gpointer data) , gpointer data); extern void fx_main_process_notification(FxMain* fxmain , const char* sipmsg); extern void fx_main_process_presence(FxMain* fxmain , const char* xml); extern void fx_main_process_message(FxMain* fxmain , FetionSip* sip , const char* sipmsg); extern FxChat* fx_main_create_chat_window(FxMain* fxmain , const char* sipuri); extern void fx_main_process_invitation(FxMain* fxmain , const char* sipmsg); extern void fx_main_process_incoming(FxMain* fxmain , FetionSip* sip , const char* sipmsg); extern void fx_main_process_sipc(FxMain* fxmain , const char* sipmsg); extern void fx_main_process_deregistration(FxMain* fxmain); extern void fx_main_process_syncuserinfo(FxMain* fxmain , const char* xml); extern void fx_main_process_addbuddyapplication(FxMain* fxmain , const char* sipmsg); extern void fx_main_process_user_left(FxMain* fxmain , const char* sipmsg); extern void fx_main_add_history(FxMain *fxmain, const char *name, const char *userid, const char *msg, int issend); /** * signal function */ extern void fx_main_destroy(GtkWidget* UNUSED(widget) , gpointer UNUSED(data)); extern gboolean fx_main_delete(GtkWidget *widget , GdkEvent *UNUSED(event) , gpointer data); extern gboolean fx_main_window_state_func(GtkWidget *widget , GdkEventWindowState *event , gpointer data); extern void fx_main_tray_activate_func(GtkWidget *UNUSED(widget) , gpointer data); extern void fx_main_tray_popmenu_func(GtkWidget* UNUSED(widget) , guint button , guint activate_time , gpointer data); extern void* fx_main_listen_thread_func(void* data); extern void fx_main_message_func(GtkWidget *UNUSED(widget) , gpointer data); extern gboolean fx_main_register_func(User* user); extern gboolean fx_main_check_func(FxMain* fxmain); extern gboolean fx_main_chat_keep_alive_func(TimeOutArgs* user); extern void fx_main_about_author_clicked(GtkWidget *UNUSED(widget) , gpointer UNUSED(data)); extern void fx_main_about_fetion_clicked(GtkWidget *UNUSED(widget) , gpointer UNUSED(data)); extern void fx_main_check_update_clicked(GtkWidget* widget , gpointer data); extern void fx_main_send_to_myself_clicked(GtkWidget* widget , gpointer data); extern void fx_main_send_to_many_clicked(GtkWidget* widget , gpointer data); extern void fx_main_personal_setting_clicked(GtkWidget* widget , gpointer data); extern void fx_main_system_setting_clicked(GtkWidget* widget , gpointer data); extern void fx_main_add_buddy_clicked(GtkWidget* widget , gpointer data); extern void fx_main_set_state_clicked(GtkWidget* widget , gpointer data); extern void fx_main_info_lookup_clicked(GtkWidget* widget , gpointer data); extern FetionSip* fx_list_find_sip_by_sipuri(FxList* fxlist , const char* sipuri); extern void fx_list_remove_sip_by_sipuri(FxList* fxlist , const char* sipuri); extern void fx_list_remove_pg_by_sipuri(FxList* fxlist , const char* sipuri); extern FxChat* fx_list_find_chat_by_sipuri(FxList* clist , const char* sipuri); extern void fx_list_remove_chat_by_sipuri(FxList* fxlist , const char* sipuri); extern TimeOutArgs* fx_list_find_timeout_by_sipuri(FxList* fxlist , const char* sipuri); extern void fx_list_remove_timeout_by_sipuri(FxList* fxlist , const char* sipuri); #endif openfetion-2.2.1/src/fx_many.c0000644000175000017500000005202111561721144014740 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static void fx_many_add_information(FxMany* fxmany , const char* text); static void fx_many_on_close_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_many_on_send_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void* fx_many_sms_send_func(void* data); static GtkTreeModel* fx_many_create_all_model(FxMany* fxmany); static gboolean key_press_func(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data); FxMany* fx_many_new(FxMain* fxmain) { FxMany* fxmany = (FxMany*)malloc(sizeof(FxMany)); memset(fxmany , 0 , sizeof(FxMany)); fxmany->fxmain = fxmain; return fxmany; } static GtkTreeModel* fx_many_create_all_model(FxMany* fxmany) { char *name , *sipuri; GdkPixbuf* pb; GtkTreeIter iter , inIter , childIter; GtkWidget* treeview = fxmany->fxmain->mainPanel->treeView; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); GtkTreeStore* store = gtk_tree_store_new(S_COLS_NUM , G_TYPE_BOOLEAN , GDK_TYPE_PIXBUF , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING ); gtk_tree_model_get_iter_root(model , &iter); do { gtk_tree_model_get(model , &iter , G_NAME_COL , &name , -1); gtk_tree_store_append(store , &inIter , NULL); gtk_tree_store_set(store , &inIter , S_CHECK_COL, FALSE , S_NAME_COL , name , -1); free(name); if(gtk_tree_model_iter_children(model , &childIter , &iter)) { do { gtk_tree_model_get(model , &childIter , B_PIXBUF_COL , &pb , B_NAME_COL , &name , B_SIPURI_COL , &sipuri , -1); GtkTreeIter inChildIter; pb = gdk_pixbuf_scale_simple(pb , 16 , 16 , GDK_INTERP_NEAREST); gtk_tree_store_append(store , &inChildIter , &inIter); gtk_tree_store_set(store , &inChildIter , S_CHECK_COL , FALSE , S_PIXBUF_COL , pb , S_NAME_COL , name , S_SIPURI_COL , sipuri , -1); g_object_unref(pb); free(name); free(sipuri); } while(gtk_tree_model_iter_next(model , &childIter)); } } while(gtk_tree_model_iter_next(model , &iter)); return GTK_TREE_MODEL(store); } static GtkTreeModel* fx_many_create_choosed_model() { GtkTreeStore* store = gtk_tree_store_new(C_COLS_NUM , GDK_TYPE_PIXBUF , G_TYPE_STRING , G_TYPE_STRING ); return GTK_TREE_MODEL(store); } static void fx_many_item_toggled(GtkCellRendererToggle *UNUSED(cell) , char* path_str , gpointer data) { FxMany* fxmany = (FxMany*)data; GtkTreeView* tree = GTK_TREE_VIEW(fxmany->tree); GtkTreeModel* model = gtk_tree_view_get_model(tree); GtkTreeView* ctree = GTK_TREE_VIEW(fxmany->selected); GtkTreeModel* cmodel = gtk_tree_view_get_model(ctree); GtkTreePath* path = gtk_tree_path_new_from_string(path_str); GtkTreeIter iter; gboolean checked , checked1; char* name; char* sipuri; char* uri; char labeltext[128]; GdkPixbuf* pb; GtkTreeIter cIter; GtkTreeIter childiter; gtk_tree_model_get_iter(model , &iter , path); gtk_tree_model_get(model , &iter , S_SIPURI_COL , &sipuri , S_CHECK_COL , &checked , -1); checked ^= 1; if(checked) { if(gtk_tree_path_get_depth(path) > 1){ gtk_tree_model_get(model , &iter , S_NAME_COL , &name , S_PIXBUF_COL , &pb , -1); gtk_tree_store_append(GTK_TREE_STORE(cmodel) , &cIter , NULL); gtk_tree_store_set(GTK_TREE_STORE(cmodel) , &cIter , C_PIXBUF_COL , pb , C_NAME_COL , name , C_SIPURI_COL , sipuri , -1); fxmany->chooseCount ++; free(name); free(sipuri); g_object_unref(pb); }else{ if(gtk_tree_model_iter_children(model , &childiter , &iter)){ do{ gtk_tree_model_get(model , &childiter , S_CHECK_COL , &checked1 , S_NAME_COL , &name , S_SIPURI_COL , &sipuri , S_PIXBUF_COL , &pb , -1); if(!checked1){ gtk_tree_store_append(GTK_TREE_STORE(cmodel) , &cIter , NULL); gtk_tree_store_set(GTK_TREE_STORE(cmodel) , &cIter , C_PIXBUF_COL , pb , C_NAME_COL , name , C_SIPURI_COL , sipuri , -1); fxmany->chooseCount ++; gtk_tree_store_set(GTK_TREE_STORE(model) , &childiter , S_CHECK_COL , TRUE , -1); } free(name); free(sipuri); g_object_unref(pb); }while(gtk_tree_model_iter_next(model , &childiter)); } } } else { if(gtk_tree_path_get_depth(path) > 1){ gtk_tree_model_get_iter_root(cmodel , &cIter); do{ gtk_tree_model_get(cmodel , &cIter , C_SIPURI_COL , &uri , -1); if(strcmp(sipuri , uri) == 0){ free(uri); break; } }while(gtk_tree_model_iter_next(cmodel , &cIter)); gtk_tree_store_remove(GTK_TREE_STORE(cmodel) , &cIter); fxmany->chooseCount --; }else{ if(gtk_tree_model_iter_children(model , &childiter , &iter)){ do{ gtk_tree_model_get(model , &childiter , S_CHECK_COL , &checked1 , S_SIPURI_COL , &sipuri , -1); if(!checked1) continue; gtk_tree_model_get_iter_root(cmodel , &cIter); do{ gtk_tree_model_get(cmodel , &cIter , C_SIPURI_COL , &uri , -1); if(strcmp(sipuri , uri) == 0){ free(uri); break; } }while(gtk_tree_model_iter_next(cmodel , &cIter)); gtk_tree_store_remove(GTK_TREE_STORE(cmodel) , &cIter); fxmany->chooseCount --; gtk_tree_store_set(GTK_TREE_STORE(model) , &childiter , S_CHECK_COL , FALSE , -1); free(sipuri); }while(gtk_tree_model_iter_next(model , &childiter)); } } } gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , S_CHECK_COL , checked , -1); gtk_tree_path_free(path); snprintf(labeltext, sizeof(labeltext) - 1 , _("Choosed [%d] contacts, " "[%d] more available"), fxmany->chooseCount , 10000 - fxmany->chooseCount); gtk_label_set_markup(GTK_LABEL(fxmany->label) , labeltext); } static void fx_many_text_cell_data_func(GtkTreeViewColumn *UNUSED(col) , GtkCellRenderer *renderer, GtkTreeModel *model , GtkTreeIter *iter , gpointer UNUSED(user_data)) { GtkTreePath* path = gtk_tree_model_get_path(model , iter); gchar* name; gchar* sipuri; gchar* sid; gchar text[128]; /* render friend list text*/ if(gtk_tree_path_get_depth(path) > 1){ gtk_tree_model_get(model , iter , S_NAME_COL , &name , S_SIPURI_COL , &sipuri , -1); sid = fetion_sip_get_sid_by_sipuri(sipuri); sprintf(text , "%s" , name == NULL ? sid : name); g_object_set(renderer , "markup" , text , "width" , 100 , NULL); g_free(sid); g_free(sipuri); g_free(name); }/*render group list text*/ else{ gtk_tree_model_get(model , iter , S_NAME_COL , &name , -1); sprintf(text , "%s" , name ); g_object_set(renderer , "text" , text , "width" , 100 , NULL); g_free(name); } } static void fx_many_create_all_column(FxMany* fxmany) { GtkCellRenderer* renderer; GtkTreeViewColumn *col , *col1; GtkWidget* tree = fxmany->tree; renderer = gtk_cell_renderer_toggle_new(); g_signal_connect(renderer , "toggled" , G_CALLBACK(fx_many_item_toggled) , fxmany); col = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col , renderer , TRUE); gtk_tree_view_column_add_attribute(col, renderer, "active", S_CHECK_COL); gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (col) , GTK_TREE_VIEW_COLUMN_FIXED); gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (col), 40); gtk_tree_view_column_set_clickable (GTK_TREE_VIEW_COLUMN (col), TRUE); gtk_tree_view_append_column(GTK_TREE_VIEW(tree) , col); renderer = gtk_cell_renderer_pixbuf_new(); GtkTreeViewColumn* col0 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col0, renderer , FALSE); gtk_tree_view_column_add_attribute(col0, renderer, "pixbuf", S_PIXBUF_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col0); renderer = gtk_cell_renderer_text_new(); col1 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col1, renderer , FALSE); gtk_tree_view_column_set_cell_data_func(col1 , renderer , fx_many_text_cell_data_func , NULL , NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col1); gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (col) , GTK_TREE_VIEW_COLUMN_FIXED); } static void fx_many_create_selected_column(FxMany* fxmany) { GtkCellRenderer* renderer; GtkTreeViewColumn *col0 , *col1; renderer = gtk_cell_renderer_pixbuf_new(); col0 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col0, renderer , FALSE); gtk_tree_view_column_add_attribute(col0, renderer, "pixbuf", C_PIXBUF_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(fxmany->selected), col0); renderer = gtk_cell_renderer_text_new(); col1 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col1, renderer , FALSE); gtk_tree_view_column_add_attribute(col1, renderer, "text", C_NAME_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(fxmany->selected), col1); gtk_tree_view_column_set_sizing (GTK_TREE_VIEW_COLUMN (col1) , GTK_TREE_VIEW_COLUMN_FIXED); } void fx_many_add_information(FxMany* fxmany , const char* text) { GtkTextIter iter; GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxmany->recv_text)); gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter , text , -1 , "blue" , NULL); gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); fxmany->mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark (buffer, fxmany->mark, &iter); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(fxmany->recv_text), fxmany->mark); } void fx_many_initialize(FxMany* fxmany) { GtkWidget *lt_frame , *lb_frame , *scrollwindow , *scrollwindow1 , *rbox , *lbox; GtkWidget *close_button , *send_button; GtkTreeModel *model , *model1; GtkWidget *action_area = NULL; GdkPixbuf *pb = NULL; fxmany->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); GtkWidget *vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (fxmany->window), vbox); pb = gdk_pixbuf_new_from_file(SKIN_DIR"groupsend.png" , NULL); if(pb != NULL){ gtk_window_set_icon(GTK_WINDOW(fxmany->window) , pb); g_object_unref(pb); } gtk_window_set_title(GTK_WINDOW(fxmany->window) , _("SMS To Many")); gtk_widget_set_usize(fxmany->window , 660 , 520); g_signal_connect(fxmany->window , "key-press-event" , G_CALLBACK(key_press_func) , fxmany); gtk_container_set_border_width(GTK_CONTAINER(fxmany->window) , 5); fxmany->hbox = gtk_hbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(vbox) , fxmany->hbox , TRUE , TRUE , 0); rbox = gtk_vbox_new(FALSE , 0); lbox = gtk_vbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(fxmany->hbox) , rbox , TRUE , TRUE , 5); gtk_box_pack_start(GTK_BOX(fxmany->hbox) , lbox , FALSE , FALSE , 5); /*left top area*/ lt_frame = gtk_frame_new(_("Choose Contacts")); gtk_widget_set_usize(lt_frame , 180 , 0); model = fx_many_create_all_model(fxmany); fxmany->tree = gtk_tree_view_new_with_model(model); scrollwindow = gtk_scrolled_window_new(NULL , NULL); gtk_container_add(GTK_CONTAINER(scrollwindow) , fxmany->tree); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(fxmany->tree) , FALSE); //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (fxmany->tree), TRUE); gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(fxmany->tree) , -35); gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(fxmany->tree) , TRUE); gtk_tree_view_columns_autosize(GTK_TREE_VIEW(fxmany->tree)); fx_many_create_all_column(fxmany); gtk_box_pack_start(GTK_BOX(lbox) , lt_frame , TRUE , TRUE , 5); gtk_container_add(GTK_CONTAINER(lt_frame) , scrollwindow); gtk_frame_set_shadow_type(GTK_FRAME(lt_frame) , GTK_SHADOW_IN); /*left bottom area*/ model1 = fx_many_create_choosed_model(); fxmany->selected = gtk_tree_view_new_with_model(model1); scrollwindow1 = gtk_scrolled_window_new(NULL , NULL); gtk_container_add(GTK_CONTAINER(scrollwindow1) , fxmany->selected); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow1) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(fxmany->selected) , FALSE); gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (fxmany->selected), TRUE); gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(fxmany->selected) , 0); gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(fxmany->selected) , TRUE); gtk_tree_view_columns_autosize(GTK_TREE_VIEW(fxmany->selected)); fx_many_create_selected_column(fxmany); lb_frame = gtk_frame_new(_("Contacts Selected")); gtk_widget_set_usize(lb_frame , 0 , 160); gtk_box_pack_start(GTK_BOX(lbox) , lb_frame , FALSE , FALSE , 5); gtk_container_add(GTK_CONTAINER(lb_frame) , scrollwindow1); /*right area*/ fxmany->label = gtk_label_new(""); gtk_label_set_markup(GTK_LABEL(fxmany->label) , _("Choosed [0] contacts, " "[10000] more available")); gtk_box_pack_start(GTK_BOX(rbox) , fxmany->label , FALSE , FALSE , 5); gtk_widget_set_usize(fxmany->label , 200 , 20); fxmany->recv_scroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(rbox) , fxmany->recv_scroll , TRUE , TRUE , 5); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxmany->recv_scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(fxmany->recv_scroll) , GTK_SHADOW_ETCHED_IN); fxmany->recv_text = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxmany->recv_text) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxmany->recv_text) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxmany->recv_text) , FALSE); gtk_container_add(GTK_CONTAINER(fxmany->recv_scroll) , fxmany->recv_text); fxmany->recv_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxmany->recv_text)); gtk_text_buffer_create_tag(fxmany->recv_buffer , "blue" , "foreground" , "blue" , NULL); gtk_text_buffer_create_tag(fxmany->recv_buffer , "red" , "foreground" , "red" , NULL); gtk_text_buffer_create_tag(fxmany->recv_buffer , "lm10" , "left_margin" , 10 , NULL); gtk_text_buffer_get_end_iter(fxmany->recv_buffer , &fxmany->recv_iter); gtk_text_buffer_create_mark(fxmany->recv_buffer , "scroll" , &fxmany->recv_iter , FALSE); fxmany->send_scroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(rbox) , fxmany->send_scroll , FALSE , FALSE , 5); gtk_widget_set_usize(fxmany->send_scroll , 0 , 120); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxmany->send_scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(fxmany->send_scroll) , GTK_SHADOW_ETCHED_IN); fxmany->send_text = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxmany->send_text) , GTK_WRAP_CHAR); // g_signal_connect(send_text , "key_press_event" , G_CALLBACK(ctrlpressed) , pthis); gtk_container_add(GTK_CONTAINER(fxmany->send_scroll) , fxmany->send_text); fxmany->send_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxmany->send_text)); gtk_text_buffer_get_iter_at_offset(fxmany->send_buffer , &fxmany->send_iter , 0); action_area = gtk_hbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(vbox) , action_area , FALSE , FALSE , 10); close_button = gtk_button_new_with_label(_("Close")); gtk_widget_set_usize(close_button , 100 , 30); gtk_box_pack_end(GTK_BOX(action_area) , close_button , FALSE , TRUE , 2); g_signal_connect(close_button , "clicked" , G_CALLBACK(fx_many_on_close_clicked) , fxmany->window); send_button = gtk_button_new_with_label(_("Send")); gtk_widget_set_usize(send_button , 100 , 30); gtk_box_pack_end(GTK_BOX(action_area) , send_button , FALSE , TRUE , 2); g_signal_connect(send_button , "clicked" , G_CALLBACK(fx_many_on_send_clicked) , fxmany); gtk_window_set_position(GTK_WINDOW(fxmany->window) , GTK_WIN_POS_CENTER); GTK_WIDGET_SET_FLAGS(fxmany->send_text, GTK_CAN_FOCUS); gtk_widget_grab_focus(fxmany->send_text); gtk_widget_show_all(fxmany->window); } static void fx_many_on_close_clicked(GtkWidget* UNUSED(widget) , gpointer data) { gtk_widget_destroy(GTK_WIDGET(data)); } static void fx_many_on_send_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMany* fxmany = (FxMany*)data; if(fxmany->chooseCount == 0){ fx_many_add_information(fxmany, _("You have not selected contacts")); return; } g_thread_create(fx_many_sms_send_func , fxmany , FALSE , NULL); } static void* fx_many_sms_send_func(void* data) { FxMany* fxmany = (FxMany*)data; GtkTreeModel *model; GtkTreeIter iter; gchar *sipuri; gchar *name; GtkTextIter begin; GtkTextIter end; const gchar *text; gchar alertmsg[1024]; Conversation *conv; gint daycount; gint monthcount; model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxmany->selected)); gtk_text_buffer_get_start_iter(fxmany->send_buffer , &begin); gtk_text_buffer_get_end_iter(fxmany->send_buffer , &end); text = gtk_text_buffer_get_text(fxmany->send_buffer , &begin , &end , TRUE); if(*text == '\0') { gdk_threads_enter(); fx_many_add_information(fxmany , _("Please input the contents of message")); gdk_threads_leave(); g_thread_exit(0); } gdk_threads_enter(); gtk_text_buffer_delete(fxmany->send_buffer , &begin , &end); gdk_threads_leave(); if(gtk_tree_model_get_iter_root(model , &iter)){ do{ gtk_tree_model_get(model, &iter, C_NAME_COL , &name, C_SIPURI_COL, &sipuri, -1); conv = fetion_conversation_new(fxmany->fxmain->user, sipuri, NULL); if(fetion_conversation_send_sms_to_phone_with_reply(conv, text, &daycount, &monthcount) > 0) sprintf(alertmsg , _("Mesage \"%s\" has been" " sent to \"%s\". You have sent %d today and " "%d this month\n"), text , name , daycount , monthcount); else sprintf(alertmsg, _("Mesage \"%s\" did not send to \"%s\"\n"), text , name); gdk_threads_enter(); fx_many_add_information(fxmany , alertmsg); gdk_threads_leave(); g_free(conv); g_free(name); g_free(sipuri); }while(gtk_tree_model_iter_next(model , &iter)); } return NULL; } static gboolean key_press_func(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data) { FxMany *fxmany ; if(event->keyval == GDK_w){ if(event->state & GDK_CONTROL_MASK){ fxmany = (FxMany*)data; gtk_widget_destroy(GTK_WIDGET(fxmany->window)); return TRUE; }else{ return FALSE; } } return FALSE; } openfetion-2.2.1/src/fx_many.h0000644000175000017500000000510011561721144014741 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_MANY_H #define FX_MANY_H enum { S_CHECK_COL = 0 , S_PIXBUF_COL , S_TEXT_COL , S_SIPURI_COL , S_NAME_COL , S_COLS_NUM }; enum { C_PIXBUF_COL = 0 , C_NAME_COL , C_SIPURI_COL , C_COLS_NUM }; extern FxMany* fx_many_new(FxMain* fxmain); extern void fx_many_initialize(FxMany* fxmany); #endif openfetion-2.2.1/src/fx_myself.c0000644000175000017500000002603411561721144015300 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static gboolean key_press_func(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data); FxMyself* fx_myself_new(FxMain* fxmain) { FxMyself* fxmyself = (FxMyself*)malloc(sizeof(FxMyself)); memset(fxmyself , 0 , sizeof(FxMyself)); fxmyself->fxmain = fxmain; fxmyself->conv = fetion_conversation_new(fxmain->user , NULL , NULL); return fxmyself; } void fx_myself_bind(FxMyself* fxmyself) { FxMain* fxmain = fxmyself->fxmain; User* user = fxmain->user; Config* config = user->config; GdkPixbuf* pb; char name[128]; sprintf(name , "%s/%s.jpg" , config->iconPath , user->sId ); pb = gdk_pixbuf_new_from_file_at_size(name , 40 , 40 , NULL); if(pb != NULL) { gtk_image_set_from_pixbuf(GTK_IMAGE(fxmyself->headimage) , pb); gtk_window_set_icon(GTK_WINDOW(fxmyself->window) , pb); g_object_unref(pb); } gtk_window_set_title(GTK_WINDOW(fxmyself->window) , _("Sending sms to myself")); sprintf(name , "%s(%s)" , user->nickname , user->sId); gtk_label_set_markup(GTK_LABEL(fxmyself->name_label) , name); gtk_label_set_text(GTK_LABEL(fxmyself->impre_label) , user->impression); } void fx_myself_add_message(FxMyself* fxmyself , const char* message) { GtkTextIter iter; User* user = fxmyself->fxmain->user; char text[4096]; char time[30] = { 0 }; char color[] = "blue"; struct tm* sendtime = get_currenttime(); GtkTextBuffer* buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxmyself->recv_text)); strftime(time , sizeof(time) , "%H:%M:%S" , sendtime); sprintf(text , "%s(%s) %s\n" , user->nickname , user->sId , time); gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter , text , -1 , color , NULL); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter, message , -1 , "lm10" , NULL); gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); fxmyself->mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark (buffer, fxmyself->mark, &iter); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(fxmyself->recv_text), fxmyself->mark); } void fx_myself_initialize(FxMyself* fxmyself) { GtkWidget* close_button; GtkWidget* send_button; GtkWidget* vbox; GtkWidget *action_area; fxmyself->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); vbox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (fxmyself->window), vbox); gtk_window_set_modal(GTK_WINDOW(fxmyself->window) , FALSE); gtk_widget_set_usize(fxmyself->window , 550 , 490); g_signal_connect(fxmyself->window , "key-press-event" , G_CALLBACK(key_press_func) , fxmyself); gtk_container_set_border_width(GTK_CONTAINER(fxmyself->window) , 10); fxmyself->headbox = gtk_table_new(2 , 10 , FALSE ); fxmyself->headpix = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 40 , 40 , NULL); gtk_window_set_icon(GTK_WINDOW(fxmyself->window) , fxmyself->headpix); fxmyself->headimage = gtk_image_new_from_pixbuf(fxmyself->headpix); gtk_table_attach(GTK_TABLE(fxmyself->headbox) , fxmyself->headimage , 0 , 1 , 0 , 2 , GTK_FILL , GTK_FILL , 3 , 0); fxmyself->name_label = gtk_label_new(NULL); gtk_label_set_justify(GTK_LABEL(fxmyself->name_label) , GTK_JUSTIFY_LEFT); gtk_table_attach(GTK_TABLE(fxmyself->headbox) , fxmyself->name_label , 1 , 2 , 0 , 1 , GTK_FILL , GTK_FILL , 0 , 0); fxmyself->impre_label = gtk_label_new(NULL); gtk_label_set_justify(GTK_LABEL(fxmyself->impre_label) , GTK_JUSTIFY_LEFT); gtk_table_attach(GTK_TABLE(fxmyself->headbox) , fxmyself->impre_label , 1 , 10 , 1 , 2 , GTK_FILL , GTK_FILL , 0 , 0); GtkWidget* halign = gtk_alignment_new( 0 , 0 , 0 , 0); gtk_container_add(GTK_CONTAINER(halign) , fxmyself->headbox); gtk_box_pack_start(GTK_BOX(vbox) , halign , FALSE , FALSE , 0); fxmyself->recv_scroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(vbox) , fxmyself->recv_scroll , TRUE , TRUE , 10); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxmyself->recv_scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(fxmyself->recv_scroll) , GTK_SHADOW_ETCHED_IN); fxmyself->recv_text = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxmyself->recv_text) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxmyself->recv_text) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxmyself->recv_text) , FALSE); gtk_container_add(GTK_CONTAINER(fxmyself->recv_scroll) , fxmyself->recv_text); fxmyself->recv_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxmyself->recv_text)); gtk_text_buffer_create_tag(fxmyself->recv_buffer , "blue" , "foreground" , "blue" , NULL); gtk_text_buffer_create_tag(fxmyself->recv_buffer , "red" , "foreground" , "red" , NULL); gtk_text_buffer_create_tag(fxmyself->recv_buffer , "lm10" , "left_margin" , 10 , NULL); gtk_text_buffer_get_end_iter(fxmyself->recv_buffer , &(fxmyself->recv_iter)); gtk_text_buffer_create_mark(fxmyself->recv_buffer , "scroll" , &(fxmyself->recv_iter) , FALSE); fxmyself->send_scroll = gtk_scrolled_window_new(NULL , NULL); gtk_widget_set_usize(fxmyself->send_scroll , 0 , 100); gtk_box_pack_start(GTK_BOX(vbox) , fxmyself->send_scroll , FALSE , FALSE , 10); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxmyself->send_scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(fxmyself->send_scroll) , GTK_SHADOW_ETCHED_IN); fxmyself->send_text = gtk_text_view_new(); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxmyself->send_text) , GTK_WRAP_CHAR); g_signal_connect(fxmyself->send_text , "key_press_event" , G_CALLBACK(fx_myself_on_enter_pressed) , fxmyself); gtk_container_add(GTK_CONTAINER(fxmyself->send_scroll) , fxmyself->send_text); fxmyself->send_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxmyself->send_text)); gtk_text_buffer_get_iter_at_offset(fxmyself->send_buffer , &(fxmyself->send_iter) , 0); action_area = gtk_hbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(vbox) , action_area , FALSE , FALSE , 10); close_button = gtk_button_new_with_label(_("Close")); gtk_widget_set_usize(close_button , 100 , 30); gtk_box_pack_end(GTK_BOX(action_area) , close_button , FALSE , TRUE , 2); g_signal_connect(close_button , "clicked" , G_CALLBACK(fx_myself_on_close_clicked) , fxmyself); send_button = gtk_button_new_with_label(_("Send")); gtk_widget_set_usize(send_button , 100 , 30); gtk_box_pack_end(GTK_BOX(action_area) , send_button , FALSE , TRUE , 2); g_signal_connect(send_button , "clicked" , G_CALLBACK(fx_myself_on_send_clicked) , fxmyself); gtk_window_set_position(GTK_WINDOW(fxmyself->window) , GTK_WIN_POS_CENTER); fx_myself_bind(fxmyself); GTK_WIDGET_SET_FLAGS(fxmyself->send_text, GTK_CAN_FOCUS); gtk_widget_grab_focus(fxmyself->send_text); gtk_widget_show_all(fxmyself->window); } void fx_myself_on_close_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxMyself* fxmyself = (FxMyself*)data; gtk_widget_destroy(fxmyself->window); } void fx_myself_on_send_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxMyself* fxmyself = (FxMyself*)data; GtkTextIter begin , end; char* text; gtk_text_buffer_get_start_iter(fxmyself->send_buffer , &begin); gtk_text_buffer_get_end_iter(fxmyself->send_buffer , &end); text = gtk_text_buffer_get_text(fxmyself->send_buffer , &begin , &end , TRUE); if(*text == '\0' ) return; fetion_conversation_send_sms_to_myself(fxmyself->conv , text); fx_myself_add_message(fxmyself , text); gtk_text_buffer_delete(fxmyself->send_buffer , &begin , &end); } gboolean fx_myself_on_enter_pressed(GtkWidget* widget , GdkEventKey* event , gpointer data) { FxMyself* fxmyself = NULL; Config *config = NULL; if(event->keyval == GDK_Return || event->keyval == GDK_ISO_Enter || event->keyval == GDK_KP_Enter) { fxmyself = (FxMyself*)data; config = fxmyself->fxmain->user->config; if(config->sendMode == SEND_MODE_ENTER) { if(event->state & GDK_CONTROL_MASK || event->state & GDK_SHIFT_MASK){ return FALSE; }else{ if (gtk_im_context_filter_keypress (GTK_TEXT_VIEW(fxmyself->send_text)->im_context, event)) { GTK_TEXT_VIEW (fxmyself->send_text)->need_im_reset = TRUE; return TRUE; } fx_myself_on_send_clicked(widget, data); return TRUE; } } else { if(event->state & GDK_CONTROL_MASK) { fx_myself_on_send_clicked(widget, data); return TRUE; }else{ return FALSE; } } } return FALSE; } static gboolean key_press_func(GtkWidget *UNUSED(widget), GdkEventKey *event , gpointer data) { FxMyself *fxmyself; if(event->keyval == GDK_w){ if(event->state & GDK_CONTROL_MASK){ fxmyself = (FxMyself*)data; gtk_widget_destroy(fxmyself->window); return TRUE; }else{ return FALSE; } } return FALSE; } openfetion-2.2.1/src/fx_myself.h0000644000175000017500000000545311561721144015307 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_MYSELF_H #define FX_MYSELF_H extern FxMyself* fx_myself_new(FxMain* fxmain); extern void fx_myself_bind(FxMyself* fxmyself); extern void fx_myself_add_message(FxMyself* fxmyself , const char* message); extern void fx_myself_initialize(FxMyself* fxmyself); extern gboolean fx_myself_on_enter_pressed(GtkWidget* widget , GdkEventKey* event , gpointer data); extern void fx_myself_on_close_clicked(GtkWidget* UNUSED(widget) , gpointer data); extern void fx_myself_on_send_clicked(GtkWidget* UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_pggroup.c0000644000175000017500000006405211561721144015466 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include static GStaticMutex pg_mutex = G_STATIC_MUTEX_INIT; static void on_close_clicked(GtkWidget *UNUSED(widget) , gpointer data); static void on_send_clicked(GtkWidget *UNUSED(widget) , gpointer data); static GtkTreeModel *create_model(PGGroup *pggroup); static void create_column(GtkWidget* tree); static void text_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)); static void pixbuf_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)); static void add_information(FxPGGroup* fxpggroup , const char* msg); static gboolean pggroup_on_key_pressed(GtkWidget* UNUSED(widget) , GdkEventKey* event , gpointer data); static void pggroup_send_message(FxPGGroup *fxpg); static void pggroup_on_sendsms_clicked(GtkWidget *widget , gpointer data); static void pggroup_on_space_clicked(GtkWidget *UNUSED(widget) , gpointer data); static void *pggroup_update_portrait_thread(void *data); static gboolean on_show_tooltip(GtkWidget* widget , int x , int y , gboolean keybord_mode , GtkTooltip* tip , gpointer data); static void on_double_click(GtkTreeView *treeview , GtkTreePath *path , GtkTreeViewColumn *UNUSED(col) , gpointer data); static void *on_contact_show(void *data); static void pg_window_destroy(GtkWidget *UNUSED(widget) , gpointer data); static gboolean key_press_func(GtkWidget *UNUSED(widget) , GdkEventKey *event , gpointer data); FxPGGroup *fx_pggroup_new(FxMain *fxmain , PGGroup *pggroup) { FxPGGroup *fxpggroup = (FxPGGroup*)malloc(sizeof(FxPGGroup)); memset(fxpggroup , 0 , sizeof(FxPGGroup)); fxpggroup->pggroup = pggroup; fxpggroup->fxmain = fxmain; return fxpggroup; } void fx_pggroup_initialize(FxPGGroup *fxpggroup ) { GtkWidget *vbox; GtkWidget *hbox; GtkWidget *lbox; GtkWidget *rbox; GdkPixbuf *pixbuf; GtkWidget *halign1; GtkWidget *action_area; GtkWidget *close_button; GtkWidget *send_button; GtkWidget *frame; GtkWidget *sendScroll; GtkWidget *recvScroll; GtkWidget *noticeScroll; GtkWidget *listScroll; GtkWidget *toolImage; GtkTextBuffer *buffer; GtkTextIter iter; Config *config = fxpggroup->fxmain->user->config; char text[1024]; const char *nonotice = _("no notice!"); char *pgsid; PGGroup *pgcur = fxpggroup->pggroup; fxpggroup->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_name(fxpggroup->window , "mainwindow"); sprintf(text , _("Fetion Group [%s]") , pgcur->name); gtk_window_set_title(GTK_WINDOW(fxpggroup->window) , text); g_signal_connect(fxpggroup->window , "destroy" , G_CALLBACK(pg_window_destroy) , fxpggroup); g_signal_connect(fxpggroup->window , "key-press-event" , G_CALLBACK(key_press_func) , fxpggroup); pixbuf = gdk_pixbuf_new_from_file(SKIN_DIR"pggroup.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxpggroup->window) , pixbuf); gtk_widget_set_size_request(fxpggroup->window , 650 , 490); g_object_unref(pixbuf); vbox = gtk_vbox_new(FALSE , 2); gtk_container_add(GTK_CONTAINER(fxpggroup->window) , vbox); /* top */ hbox = gtk_hbox_new(FALSE , 5); gtk_box_pack_start(GTK_BOX(vbox) , hbox , FALSE , FALSE , 5); pgsid = fetion_sip_get_pgid_by_sipuri(fxpggroup->pggroup->pguri); snprintf(text , 1023 , "%s/PG%s.jpg" , config->iconPath , pgsid); pixbuf = gdk_pixbuf_new_from_file_at_size(text , 40 , 40 , NULL); fxpggroup->image = gtk_image_new_from_pixbuf(pixbuf); gtk_box_pack_start(GTK_BOX(hbox) , fxpggroup->image , FALSE , FALSE , 10); fxpggroup->nameLabel = gtk_label_new(NULL); sprintf(text , "%s(%s)" , pgcur->name , pgsid); free(pgsid); gtk_label_set_markup(GTK_LABEL(fxpggroup->nameLabel) , text); gtk_box_pack_start(GTK_BOX(hbox) , fxpggroup->nameLabel , FALSE , FALSE , 2); fxpggroup->otherLabel = gtk_label_new(NULL); gtk_box_pack_start(GTK_BOX(hbox) , fxpggroup->otherLabel , FALSE , FALSE , 2); /* middle */ hbox = gtk_hbox_new(FALSE , 5); gtk_box_pack_start(GTK_BOX(vbox) , hbox , TRUE , TRUE , 0); /* middle left */ lbox = gtk_vbox_new(FALSE , 5); gtk_box_pack_start(GTK_BOX(hbox) , lbox , TRUE , TRUE , 5); recvScroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(lbox) , recvScroll , TRUE , TRUE , 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(recvScroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(recvScroll) , GTK_SHADOW_ETCHED_IN); fxpggroup->recvView = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxpggroup->recvView) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxpggroup->recvView) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxpggroup->recvView) , FALSE); gtk_container_add(GTK_CONTAINER(recvScroll) , fxpggroup->recvView); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxpggroup->recvView)); gtk_text_buffer_create_tag(buffer , "blue" , "foreground" , "#639900" , NULL); gtk_text_buffer_create_tag(buffer , "grey" , "foreground" , "#808080" , NULL); gtk_text_buffer_create_tag(buffer , "green" , "foreground" , "green" , NULL); gtk_text_buffer_create_tag(buffer , "red" , "foreground" , "#0088bf" , NULL); gtk_text_buffer_create_tag(buffer , "lm10" , "left_margin" , 10 , NULL); gtk_text_buffer_create_tag(buffer , "small" , "left_margin" , 5 , NULL); gtk_text_buffer_get_end_iter(buffer , &iter); gtk_text_buffer_create_mark(buffer , "scroll" , &iter , FALSE); /* toolbar begin*/ fxpggroup->toolbar = gtk_toolbar_new(); gtk_toolbar_set_style(GTK_TOOLBAR(fxpggroup->toolbar) , GTK_TOOLBAR_ICONS); gtk_box_pack_start(GTK_BOX(lbox) , fxpggroup->toolbar , FALSE , FALSE , 0); pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"myselfsms.png" , 16 , 16 , NULL); toolImage = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(pixbuf); fxpggroup->phoneButton = gtk_toolbar_append_element(GTK_TOOLBAR(fxpggroup->toolbar) , GTK_TOOLBAR_CHILD_TOGGLEBUTTON , NULL , _("Send group message") , _("Send group message") , NULL , toolImage , G_CALLBACK(pggroup_on_sendsms_clicked) , fxpggroup ); if(fxpggroup->pggroup->identity != 1) gtk_widget_set_sensitive(fxpggroup->phoneButton , FALSE); pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"home.png" , 16 , 16 , NULL); toolImage = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(pixbuf); gtk_toolbar_append_item(GTK_TOOLBAR(fxpggroup->toolbar) , _("Access group space") , _("Access group space") , NULL , toolImage , G_CALLBACK(pggroup_on_space_clicked) , fxpggroup); gtk_toolbar_append_space(GTK_TOOLBAR(fxpggroup->toolbar)); /* toolbar end*/ sendScroll = gtk_scrolled_window_new(NULL , NULL); gtk_box_pack_start(GTK_BOX(lbox) , sendScroll , FALSE , FALSE , 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sendScroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sendScroll) , GTK_SHADOW_ETCHED_IN); fxpggroup->sendView = gtk_text_view_new(); gtk_widget_set_usize(fxpggroup->sendView , 0 , 100); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxpggroup->sendView) , GTK_WRAP_WORD_CHAR); g_signal_connect(fxpggroup->sendView , "key_press_event" , G_CALLBACK(pggroup_on_key_pressed) , fxpggroup); gtk_container_add(GTK_CONTAINER(sendScroll) , fxpggroup->sendView); /* action area */ action_area = gtk_hbox_new(FALSE , 0); halign1 = gtk_alignment_new( 1 , 0 , 0 , 0); gtk_container_add(GTK_CONTAINER(halign1) , action_area); gtk_box_pack_start(GTK_BOX(vbox) , halign1 , FALSE , FALSE , 5); close_button = gtk_button_new_with_label(_("Close")); gtk_widget_set_usize(close_button , 100 , 30); gtk_box_pack_start(GTK_BOX(action_area) , close_button , FALSE , TRUE , 5); g_signal_connect(close_button , "clicked" , G_CALLBACK(on_close_clicked) , fxpggroup); send_button = gtk_button_new_with_label(_("Send")); gtk_widget_set_usize(send_button , 100 , 30); gtk_box_pack_start(GTK_BOX(action_area) , send_button , FALSE , TRUE , 5); g_signal_connect(send_button , "clicked" , G_CALLBACK(on_send_clicked) , fxpggroup); gtk_window_set_position(GTK_WINDOW(fxpggroup->window) , GTK_WIN_POS_CENTER); /*right box */ rbox = gtk_vbox_new(FALSE , 0); gtk_box_pack_start(GTK_BOX(hbox) , rbox , FALSE , FALSE , 5); /* notice */ frame = gtk_frame_new(_("Group Notice")); gtk_frame_set_shadow_type(GTK_FRAME(frame) , GTK_SHADOW_NONE); gtk_widget_set_usize(frame , 200 , 0); gtk_box_pack_start(GTK_BOX(rbox) , frame , FALSE , FALSE , 0); noticeScroll = gtk_scrolled_window_new(NULL , NULL); gtk_container_add(GTK_CONTAINER(frame) , noticeScroll); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(noticeScroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(noticeScroll) , GTK_SHADOW_ETCHED_IN); fxpggroup->noticeView = gtk_text_view_new(); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxpggroup->noticeView)); gtk_text_buffer_get_end_iter(buffer , &iter); if(strlen(pgcur->bulletin) == 0){ gtk_text_buffer_insert(buffer , &iter , nonotice , strlen(nonotice)); } else gtk_text_buffer_insert(buffer , &iter , pgcur->bulletin , strlen(pgcur->bulletin)); gtk_widget_set_usize(fxpggroup->noticeView , 0 , 100); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxpggroup->noticeView) , GTK_WRAP_WORD_CHAR); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxpggroup->noticeView) , FALSE); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxpggroup->noticeView) , FALSE); gtk_container_add(GTK_CONTAINER(noticeScroll) , fxpggroup->noticeView); /* contact list */ frame = gtk_frame_new(_("Group Members")); gtk_frame_set_shadow_type(GTK_FRAME(frame) , GTK_SHADOW_NONE); gtk_box_pack_start(GTK_BOX(rbox) , frame , TRUE , TRUE , 0); listScroll = gtk_scrolled_window_new(NULL , NULL); gtk_widget_set_size_request(listScroll , 225 , 0); gtk_container_add(GTK_CONTAINER(frame) , listScroll); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(listScroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(listScroll) , GTK_SHADOW_ETCHED_IN); fxpggroup->treeView = gtk_tree_view_new_with_model(create_model(pgcur)); g_object_set(fxpggroup->treeView , "has-tooltip" , TRUE , NULL); g_signal_connect(fxpggroup->treeView , "query-tooltip" , G_CALLBACK(on_show_tooltip) , fxpggroup); g_signal_connect(fxpggroup->treeView , "row-activated" , G_CALLBACK(on_double_click) , fxpggroup); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(fxpggroup->treeView) , FALSE); //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (fxpggroup->treeView), TRUE); gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(fxpggroup->treeView) , -30); gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(fxpggroup->treeView) , TRUE); create_column(fxpggroup->treeView); gtk_container_add(GTK_CONTAINER(listScroll) , fxpggroup->treeView); g_thread_create(pggroup_update_portrait_thread , fxpggroup , FALSE , NULL); gtk_widget_show_all(fxpggroup->window); } static void on_close_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; gtk_widget_destroy(fxpg->window); } static void on_send_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; pggroup_send_message(fxpg); } static GtkTreeModel *create_model(PGGroup *pggroup) { PGGroupMember *member = pggroup->member; PGGroupMember *mcur; GtkTreeIter iter; GdkPixbuf *pixbuf; GtkTreeStore *store = gtk_tree_store_new(M_COL_NUM , GDK_TYPE_PIXBUF , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT); foreach_pg_member(member , mcur){ if(mcur->state <= 0){ gtk_tree_store_append(store , &iter , NULL); pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"invisible.svg" , MEMBER_PROTRAIT_SIZED , MEMBER_PROTRAIT_SIZED , NULL); } else{ gtk_tree_store_prepend(store , &iter , NULL); switch(mcur->state){ case P_ONLINE : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , MEMBER_PROTRAIT_SIZED , MEMBER_PROTRAIT_SIZED , NULL); break; case P_BUSY : pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"busy.svg" , MEMBER_PROTRAIT_SIZED , MEMBER_PROTRAIT_SIZED , NULL); break; default: pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"away.svg" , MEMBER_PROTRAIT_SIZED , MEMBER_PROTRAIT_SIZED , NULL); break; } } gtk_tree_store_set(store , &iter , M_PIXBUF_COL , pixbuf , M_NICKNAME_COL , g_markup_escape_text(mcur->nickname , strlen(mcur->nickname)) , M_SIPURI_COL , mcur->sipuri , M_IDENTITY_COL , mcur->identity , M_STATE_COL , mcur->state , -1); g_object_unref(pixbuf); } return GTK_TREE_MODEL(store); } static void create_column(GtkWidget* tree) { GtkCellRenderer* renderer; GtkTreeViewColumn *col , *col0; renderer = gtk_cell_renderer_pixbuf_new(); col = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col, renderer , FALSE); gtk_tree_view_column_add_attribute(col, renderer, "pixbuf", M_PIXBUF_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col); gtk_tree_view_column_set_cell_data_func(col , renderer , pixbuf_cell_data_func , NULL , NULL); renderer = gtk_cell_renderer_text_new(); col0 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col0, renderer , FALSE); gtk_tree_view_column_set_cell_data_func(col0 , renderer , text_cell_data_func , NULL , NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col0); } static void text_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)) { char *sipuri; char *nickname; char *sid; char text[1024]; int identity; int state; gtk_tree_model_get(model , iter , M_SIPURI_COL , &sipuri , M_NICKNAME_COL , &nickname , M_IDENTITY_COL , &identity , M_STATE_COL , &state , -1); sid = fetion_sip_get_sid_by_sipuri(sipuri); sprintf(text , "%s %s(%s)" , *nickname == '\0' ? sid : g_markup_escape_text(nickname , strlen(nickname)) , identity == 2 ? _("[Administrator]") : ( identity == 1 ?_("[Super Administrator]") : "") , sid); g_object_set(renderer , "markup" , text , NULL); free(sipuri); free(nickname); free(sid); } static void pixbuf_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)) { int state; gtk_tree_model_get(model , iter , M_STATE_COL , &state , -1); if(state > 0) g_object_set(renderer , "sensitive" , TRUE , NULL); else g_object_set(renderer , "sensitive" , FALSE , NULL); } void pg_add_message(FxPGGroup* fxpggroup , const char* msg , const struct tm* datetime , PGGroupMember *contact) { GtkTextIter iter; GtkTextBuffer* buffer; GtkTextMark *mark; FxMain* fxmain = fxpggroup->fxmain; User* user = fxmain->user; char time[256]; char text[2048]; char color[16]; //char *usid; if(contact == NULL) strcpy(color , "blue"); else strcpy(color , "red"); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxpggroup->recvView)); strftime(time , sizeof(time) , "%H:%M:%S" , datetime); //usid = fetion_sip_get_sid_by_sipuri(contact->sipuri); if(contact != NULL){ sprintf(text , _("%s says: (%s):\n") , contact->nickname , time); }else{ sprintf(text , _("%s says: (%s):\n") , user->nickname , time); } gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter , text , -1 , color , NULL); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter, msg , strlen(msg) , "lm10" , NULL); gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark (buffer, mark, &iter); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(fxpggroup->recvView), mark); } static void add_information(FxPGGroup* fxpggroup , const char* msg) { GtkTextIter iter; GtkTextBuffer* buffer; GtkTextMark *mark; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxpggroup->recvView)); gtk_text_buffer_get_end_iter(buffer , &iter ); gtk_text_buffer_insert_with_tags_by_name(buffer , &iter, msg , strlen(msg) , "grey" , NULL); gtk_text_buffer_insert(buffer , &iter , "\n" , -1); gtk_text_iter_set_line_offset (&iter, 0); mark = gtk_text_buffer_get_mark (buffer, "scroll"); gtk_text_buffer_move_mark (buffer, mark, &iter); gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW(fxpggroup->recvView), mark); } static gboolean pggroup_on_key_pressed(GtkWidget* UNUSED(widget) , GdkEventKey* event , gpointer data) { FxPGGroup *fxpg; Config *config = NULL; if(event->keyval == GDK_Return || event->keyval == GDK_ISO_Enter || event->keyval == GDK_KP_Enter) { fxpg = (FxPGGroup*)data; config = fxpg->fxmain->user->config; if(config->sendMode == SEND_MODE_ENTER) { if(event->state & GDK_CONTROL_MASK || event->state & GDK_SHIFT_MASK){ return FALSE; }else{ if (gtk_im_context_filter_keypress (GTK_TEXT_VIEW(fxpg->sendView)->im_context, event)) { GTK_TEXT_VIEW (fxpg->sendView)->need_im_reset = TRUE; return TRUE; } pggroup_send_message(fxpg); return TRUE; } } else { if(event->state & GDK_CONTROL_MASK) { pggroup_send_message(fxpg); return TRUE; }else{ return FALSE; } } } return FALSE; } static void pggroup_send_message(FxPGGroup *fxpg) { User *user = fxpg->fxmain->user; GtkTextView *text = GTK_TEXT_VIEW(fxpg->sendView); GtkTextBuffer *buffer = gtk_text_view_get_buffer(text); GtkTextIter biter; GtkTextIter eiter; gchar *value; struct tm *now; now = get_currenttime(); gtk_text_buffer_get_start_iter(buffer , &biter); gtk_text_buffer_get_end_iter(buffer , &eiter); value = gtk_text_buffer_get_text(buffer , &biter , &eiter , TRUE); if(*value == '\0') return; pg_add_message(fxpg , value , now , NULL); gtk_text_buffer_delete(buffer , &biter , &eiter); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxpg->phoneButton))) pg_group_send_sms(user , fxpg->pggroup , value); else pg_group_send_message(user , fxpg->pggroup , value); } void pggroup_on_sendsms_clicked(GtkWidget *widget , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; GtkToggleButton *btn = GTK_TOGGLE_BUTTON(widget); if(gtk_toggle_button_get_active(btn)){ add_information(fxpg , _("Group member who didn't bind fetion number" " to mobile number can't receive the group sms you send")); } } void pggroup_on_space_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; char *pgsid; char text[1024]; if(fork() == 0){ pgsid = fetion_sip_get_pgid_by_sipuri(fxpg->pggroup->pguri); sprintf(text , "%s?GroupID=%s" , PGGROUP_SPACE_URI , pgsid); execlp("xdg-open" , "xdg-open" , text , (char**)NULL); } } static void *pggroup_update_portrait_thread(void *data) { FxPGGroup *fxpg = (FxPGGroup*)data; User *user = fxpg->fxmain->user; Config *config = user->config; GtkTreeView *tree = GTK_TREE_VIEW(fxpg->treeView); GtkTreeModel *model = gtk_tree_view_get_model(tree); GtkTreeIter iter; GdkPixbuf *pixbuf; char portraitPath[256]; char path[1024]; char *sipuri; char *sid; if(gtk_tree_model_get_iter_first(model , &iter)){ do{ if(!fxpg || !fxpg->pggroup) return NULL; gtk_tree_model_get(model , &iter , M_SIPURI_COL , &sipuri , -1); sid = fetion_sip_get_sid_by_sipuri(sipuri); snprintf(path , 1023 , "%s/%s.jpg" , config->iconPath , sid); pixbuf = gdk_pixbuf_new_from_file_at_size(path , MEMBER_PROTRAIT_SIZED , MEMBER_PROTRAIT_SIZED , NULL); if(!fxpg || !fxpg->pggroup) return NULL; g_static_mutex_lock(&pg_mutex); if(pixbuf == NULL && fxpg->pggroup->hasImage == 0){ snprintf(portraitPath , 255 , "/%s/getportrait.aspx" , config->portraitServerPath ); fetion_user_download_portrait_with_uri(user , sipuri , config->portraitServerName , portraitPath); snprintf(path , 1023 , "%s/%s.jpg" , config->iconPath , sid); pixbuf = gdk_pixbuf_new_from_file_at_size(path , MEMBER_PROTRAIT_SIZED , MEMBER_PROTRAIT_SIZED , NULL); } g_static_mutex_unlock(&pg_mutex); if(!fxpg || !fxpg->pggroup) return NULL; if(pixbuf != NULL){ gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , PG_PIXBUF_COL , pixbuf , -1); gdk_threads_leave(); g_object_unref(pixbuf); } free(sipuri); free(sid); }while(gtk_tree_model_iter_next(model , &iter)); if(!fxpg) return NULL; fxpg->pggroup->hasImage = 1; } return NULL; } static gboolean on_show_tooltip(GtkWidget* widget , int x , int y , gboolean keybord_mode , GtkTooltip* tip , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; FxMain *fxmain = fxpg->fxmain; Config *config = fxmain->user->config; GtkTreePath *path; GtkTreeIter iter; GtkTreeView *tree; GtkTreeModel *model; GdkPixbuf *pixbuf; char *sipuri; char *nickname; char *sid; char text[2048]; char iconpath[256]; tree = GTK_TREE_VIEW(widget); model = gtk_tree_view_get_model(tree); if(!gtk_tree_view_get_tooltip_context(tree , &x , &y , keybord_mode , &model , &path , &iter)){ return FALSE; } gtk_tree_model_get(model , &iter , M_SIPURI_COL , &sipuri , M_NICKNAME_COL , &nickname , -1); sid = fetion_sip_get_sid_by_sipuri(sipuri); snprintf(text , 2047 , _("NickName : %s\t\n" "FetionNumber : %s\t\n") , g_markup_escape_text(nickname , strlen(nickname)) , sid); gtk_tooltip_set_markup(tip , text); sprintf(iconpath , "%s/%s.jpg" , config->iconPath , sid); pixbuf = gdk_pixbuf_new_from_file_at_size(iconpath , 80 , 80 , NULL); if(pixbuf == NULL) pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , 80 , 80 , NULL); gtk_tooltip_set_icon(tip , pixbuf); g_object_unref(pixbuf); gtk_tree_view_set_tooltip_row(tree , tip , path); gtk_tree_path_free(path); free(nickname); free(sipuri); free(sid); return TRUE; } static void on_double_click(GtkTreeView *treeview , GtkTreePath *path , GtkTreeViewColumn *UNUSED(col) , gpointer data) { struct args{ FxPGGroup *fxpg; char *sipuri; } *arg = (struct args*)malloc(sizeof(struct args)); FxPGGroup *fxpg = (FxPGGroup*)data; GtkTreeModel *model = gtk_tree_view_get_model(treeview); GtkTreeIter iter; char *sipuri; gtk_tree_model_get_iter(model , &iter , path); gtk_tree_model_get(model , &iter , M_SIPURI_COL , &sipuri , -1); arg->fxpg = fxpg; arg->sipuri = sipuri; g_thread_create(on_contact_show , arg , FALSE , NULL); } static void *on_contact_show(void *data) { struct args{ FxPGGroup *fxpg; char *sipuri; } *arg = (struct args*)data; FxPGGroup *fxpg = arg->fxpg; char *sipuri = arg->sipuri; char *sid; Contact *contact; User *user = fxpg->fxmain->user; FxLookupres *lookup; sid = fetion_sip_get_sid_by_sipuri(sipuri); contact = fetion_contact_get_contact_info_by_no(user , sid , FETION_NO); lookup = fx_lookupres_new(fxpg->fxmain , contact); gdk_threads_enter(); fx_lookupres_initialize(lookup); gtk_dialog_run(GTK_DIALOG(lookup->dialog)); gtk_widget_destroy(lookup->dialog); gdk_threads_leave(); free(sipuri); free(sid); free(arg); return NULL; } static void pg_window_destroy(GtkWidget *UNUSED(widget) , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; fx_list_remove_pg_by_sipuri(fxpg->fxmain->pglist , fxpg->pggroup->pguri); fxpg->pggroup = NULL; } static gboolean key_press_func(GtkWidget *widget , GdkEventKey *event , gpointer UNUSED(data)) { if(event->keyval == GDK_w){ if(event->state & GDK_CONTROL_MASK){ gtk_widget_destroy(widget); return TRUE; }else{ return FALSE; } } return FALSE; } openfetion-2.2.1/src/fx_pggroup.h0000644000175000017500000000533611561721144015473 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_PGGROUP_H #define FX_PGGROUP_H #define MEMBER_PROTRAIT_SIZED 30 enum{ M_PIXBUF_COL = 0 , M_TEXT_COL , M_NICKNAME_COL , M_SIPURI_COL , M_STATE_COL , M_IDENTITY_COL , M_COL_NUM }; extern FxPGGroup *fx_pggroup_new(FxMain *fxmain , PGGroup *pggroup); extern void fx_pggroup_initialize(FxPGGroup *fxpggroup); extern void pg_add_message(FxPGGroup* fxpggroup , const char* msg , const struct tm* datetime , PGGroupMember *contact); #endif openfetion-2.2.1/src/fx_pgprofile.c0000644000175000017500000002252111561721144015765 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static void bind_profile(FxPGProfile *fxpg); static gboolean focus_in_func(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data); static gboolean focus_out_func(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data); FxPGProfile *fx_pgprofile_new(FxMain *fxmain , PGGroup *pg) { FxPGProfile *fxpg = (FxPGProfile*)malloc(sizeof(FxPGProfile)); memset(fxpg , 0 , sizeof(FxPGProfile)); fxpg->fxmain = fxmain; fxpg->pggroup = pg; return fxpg; } void fx_pgprofile_initialize(FxPGProfile *fxpg) { GtkWidget *label; GtkWidget *frame; GtkWidget *scroll; GdkPixbuf *pixbuf; GtkWidget *fixed; fxpg->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_resizable(GTK_WINDOW(fxpg->window) , FALSE); gtk_window_set_position(GTK_WINDOW(fxpg->window) , GTK_WIN_POS_CENTER); pixbuf = gdk_pixbuf_new_from_file(SKIN_DIR"pggroup.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxpg->window) , pixbuf); g_object_unref(pixbuf); gtk_widget_set_name(fxpg->window , "mainwindow"); gtk_window_set_title(GTK_WINDOW(fxpg->window) , _("Group Details")); gtk_widget_set_usize(fxpg->window , 540 , 540); g_signal_connect(fxpg->window , "focus-in-event" , GTK_SIGNAL_FUNC(focus_in_func) , fxpg ); g_signal_connect(fxpg->window , "focus-out-event" , GTK_SIGNAL_FUNC(focus_out_func) , fxpg ); fixed = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(fxpg->window) , fixed); frame = gtk_frame_new(_("Basic Information")); gtk_widget_set_usize(frame , 500 , 200); gtk_fixed_put(GTK_FIXED(fixed) , frame , 20 , 10); label = gtk_label_new(_("Group Number:")); gtk_fixed_put(GTK_FIXED(fixed) , label , 60 , 50); label = gtk_label_new(_("Group Name:")); gtk_fixed_put(GTK_FIXED(fixed) , label , 60 , 90); label = gtk_label_new(_("Administrator:")); gtk_fixed_put(GTK_FIXED(fixed) , label , 60 , 130); label = gtk_label_new(_("Create Time:")); gtk_fixed_put(GTK_FIXED(fixed) , label , 60 , 170); fxpg->sidEntry = gtk_entry_new(); gtk_widget_set_usize(fxpg->sidEntry , 200 , 0); gtk_entry_set_editable(GTK_ENTRY(fxpg->sidEntry) , FALSE); gtk_fixed_put(GTK_FIXED(fixed) , fxpg->sidEntry , 150 , 45); fxpg->nameEntry = gtk_entry_new(); gtk_widget_set_usize(fxpg->nameEntry , 200 , 0); gtk_entry_set_editable(GTK_ENTRY(fxpg->nameEntry) , FALSE); gtk_fixed_put(GTK_FIXED(fixed) , fxpg->nameEntry , 150 , 85); fxpg->leaderEntry = gtk_entry_new(); gtk_widget_set_usize(fxpg->leaderEntry , 200 , 0); gtk_entry_set_editable(GTK_ENTRY(fxpg->leaderEntry) , FALSE); gtk_fixed_put(GTK_FIXED(fixed) , fxpg->leaderEntry , 150 , 125); fxpg->timeEntry = gtk_entry_new(); gtk_widget_set_usize(fxpg->timeEntry , 200 , 0); gtk_entry_set_editable(GTK_ENTRY(fxpg->timeEntry) , FALSE); gtk_fixed_put(GTK_FIXED(fixed) , fxpg->timeEntry , 150 , 165); pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 120 , 120 , NULL); fxpg->image = gtk_image_new_from_pixbuf(pixbuf); g_object_unref(pixbuf); frame = gtk_frame_new(NULL); gtk_container_add(GTK_CONTAINER(frame) , fxpg->image); gtk_fixed_put(GTK_FIXED(fixed) , frame , 370 , 50); frame = gtk_frame_new(_("Group Bulletin:")); gtk_widget_set_usize(frame , 500 , 140); gtk_fixed_put(GTK_FIXED(fixed) , frame , 20 , 225); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label) , _("Only visible to group members,less than 256 characters")); gtk_fixed_put(GTK_FIXED(fixed) , label , 40 , 250); scroll = gtk_scrolled_window_new(NULL , NULL); gtk_widget_set_usize(scroll , 460 , 80); gtk_fixed_put(GTK_FIXED(fixed) , scroll , 40 , 270); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll) , GTK_SHADOW_ETCHED_IN); fxpg->bulletinView = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxpg->bulletinView) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxpg->bulletinView) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxpg->bulletinView) , FALSE); gtk_container_add(GTK_CONTAINER(scroll) , fxpg->bulletinView); frame = gtk_frame_new(_("Group Summary:")); gtk_widget_set_usize(frame , 500 , 140); gtk_fixed_put(GTK_FIXED(fixed) , frame , 20 , 370); label = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(label) , _("Visible to anyone,less than 256 characters")); gtk_fixed_put(GTK_FIXED(fixed) , label , 40 , 390); scroll = gtk_scrolled_window_new(NULL , NULL); gtk_widget_set_usize(scroll , 460 , 80); gtk_fixed_put(GTK_FIXED(fixed) , scroll , 40 , 415); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll) , GTK_SHADOW_ETCHED_IN); fxpg->introView = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(fxpg->introView) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(fxpg->introView) , GTK_WRAP_CHAR); gtk_text_view_set_editable(GTK_TEXT_VIEW(fxpg->introView) , FALSE); gtk_container_add(GTK_CONTAINER(scroll) , fxpg->introView); bind_profile(fxpg); gtk_widget_show_all(fxpg->window); } void bind_profile(FxPGProfile *fxpg) { PGGroup *pggroup = fxpg->pggroup; Config *config = fxpg->fxmain->user->config; PGGroupMember *memcur; GdkPixbuf *pixbuf; GtkTextIter iter; struct tm date; char time[1024]; char *sid; char path[1024]; GtkTextView *text; GtkTextBuffer *buffer; sid = fetion_sip_get_pgid_by_sipuri(pggroup->pguri); if(sid == NULL){ fprintf(stderr , "ERROR : sid == NULL"); return; } gtk_entry_set_text(GTK_ENTRY(fxpg->sidEntry) , sid); gtk_entry_set_text(GTK_ENTRY(fxpg->nameEntry) , pggroup->name); foreach_pg_member(pggroup->member , memcur){ if(memcur->identity == 1){ gtk_entry_set_text(GTK_ENTRY(fxpg->leaderEntry) , memcur->nickname); break; } } date = convert_date(pggroup->createTime); strftime(time , sizeof(time) , _("%Y-%m-%d") , &date); gtk_entry_set_text(GTK_ENTRY(fxpg->timeEntry) , time); snprintf(path , 1023 , "%s/PG%s.jpg" , config->iconPath , sid); pixbuf = gdk_pixbuf_new_from_file_at_size(path , 120 , 120 , NULL); if(pixbuf != NULL){ gtk_image_set_from_pixbuf(GTK_IMAGE(fxpg->image) , pixbuf); g_object_unref(pixbuf); } text = GTK_TEXT_VIEW(fxpg->bulletinView); buffer = gtk_text_view_get_buffer(text); gtk_text_buffer_get_end_iter(buffer , &iter); gtk_text_buffer_insert(buffer , &iter , pggroup->bulletin , strlen(pggroup->bulletin)); text = GTK_TEXT_VIEW(fxpg->introView); buffer = gtk_text_view_get_buffer(text); gtk_text_buffer_get_end_iter(buffer , &iter); gtk_text_buffer_insert(buffer , &iter , pggroup->summary , strlen(pggroup->summary)); free(sid); } static gboolean focus_in_func(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; fxpg->hasFocus = CHAT_DIALOG_FOCUSED; return FALSE; } static gboolean focus_out_func(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data) { FxPGGroup *fxpg = (FxPGGroup*)data; fxpg->hasFocus = CHAT_DIALOG_NOT_FOCUSED; return FALSE; } openfetion-2.2.1/src/fx_pgprofile.h0000644000175000017500000000467411561721144016003 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_PGPROFILE_H #define FX_PGPROFILE_H extern FxPGProfile *fx_pgprofile_new(FxMain *fxmain , PGGroup *pg); extern void fx_pgprofile_initialize(FxPGProfile *fxpg); #endif openfetion-2.2.1/src/fx_profile.c0000644000175000017500000002363511561721144015445 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxProfile* fx_profile_new(FxMain* fxmain , const char* userid) { FxProfile* fxprofile = (FxProfile*)malloc(sizeof(FxProfile)); memset(fxprofile , 0 , sizeof(FxProfile)); fxprofile->fxmain = fxmain; strcpy(fxprofile->userid , userid); return fxprofile; } void fx_profile_initialize(FxProfile* fxprofile) { GtkWidget* box ; GtkWidget* inbox ; GdkPixbuf* pb; FxMain* fxmain = fxprofile->fxmain; fxprofile->dialog = gtk_dialog_new_with_buttons (_("view contact's information") , GTK_WINDOW(fxmain->window) ,GTK_DIALOG_DESTROY_WITH_PARENT , NULL); gtk_dialog_set_has_separator(GTK_DIALOG(fxprofile->dialog) , FALSE); gtk_container_set_border_width(GTK_CONTAINER(fxprofile->dialog) , 10); gtk_widget_set_usize(GTK_WIDGET(fxprofile->dialog) , 500 , 340); gtk_window_set_resizable(GTK_WINDOW(fxprofile->dialog) , FALSE); box = gtk_table_new(6 , 3 , TRUE); gtk_table_set_row_spacings(GTK_TABLE(box) , 2); gtk_table_set_col_spacings(GTK_TABLE(box) , 2); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxprofile->dialog)->vbox) , box); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 90 , 90 , NULL); fxprofile->image = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->image , 0 , 1 , 0 , 4); fxprofile->sid_label = gtk_label_new(_("Fetion Number:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->sid_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->sid_label , 1 , 2 , 0 , 1); fxprofile->sid_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->sid_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->sid_entry , 1 , 2 , 1 , 2); fxprofile->gender_label = gtk_label_new(_("Sex:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->gender_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->gender_label , 2 , 3 , 0 , 1); fxprofile->gender_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->gender_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->gender_entry , 2 , 3 , 1 , 2); fxprofile->mno_label = gtk_label_new(_("Cell Phone Number:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->mno_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->mno_label , 1 , 2 , 2 , 3); fxprofile->mno_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->mno_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->mno_entry , 1 , 2 , 3 , 4); fxprofile->nick_label = gtk_label_new(_("Nickname:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->nick_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->nick_label , 2 , 3 , 2 , 3); fxprofile->nick_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->nick_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->nick_entry , 2 , 3 , 3 , 4); fxprofile->impre_label = gtk_label_new(_("Personal Signature:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->impre_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->impre_label , 0 , 3 , 4, 5); fxprofile->impre_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->impre_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(box) , fxprofile->impre_entry , 0 , 3 , 5 , 6); inbox = gtk_table_new( 4 , 2 , TRUE); gtk_table_set_row_spacings(GTK_TABLE(inbox) , 2); gtk_table_set_col_spacings(GTK_TABLE(inbox) , 2); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxprofile->dialog)->vbox) , inbox); fxprofile->local_label = gtk_label_new(_("Note name:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->local_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->local_label , 0 , 1 , 0 , 1); fxprofile->local_entry = gtk_entry_new(); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->local_entry , 0 , 1 , 1 , 2); gtk_entry_set_editable(GTK_ENTRY(fxprofile->local_entry) , FALSE); fxprofile->nation_label = gtk_label_new(_("Country:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->nation_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->nation_label , 1 , 2 , 0 , 1); fxprofile->nation_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->nation_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->nation_entry , 1 , 2 , 1 , 2); fxprofile->province_label = gtk_label_new(_("Province:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->province_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->province_label , 0 , 1 , 2 , 3); fxprofile->province_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->province_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->province_entry , 0 , 1 , 3 , 4); fxprofile->city_label = gtk_label_new(_("City:")); gtk_misc_set_alignment(GTK_MISC(fxprofile->city_label) , 0 , 1); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->city_label , 1 , 2 , 2 , 3); fxprofile->city_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxprofile->city_entry) , FALSE); gtk_table_attach_defaults(GTK_TABLE(inbox) , fxprofile->city_entry , 1 , 2 , 3 , 4); fxprofile->finish_button = gtk_button_new_with_label(_("Finish")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxprofile->dialog)->action_area) , fxprofile->finish_button); GTK_WIDGET_SET_FLAGS(fxprofile->finish_button, GTK_CAN_FOCUS); gtk_widget_grab_focus(fxprofile->finish_button); g_signal_connect(fxprofile->finish_button , "clicked" , G_CALLBACK(fx_profile_on_button_clicked) , fxprofile->dialog); gtk_widget_show_all(fxprofile->dialog); } Contact *fx_profile_fetch(FxProfile *fxprofile) { Contact *cur; foreach_contactlist(fxprofile->fxmain->user->contactList, cur){ if(strcmp(cur->userId, fxprofile->userid) == 0) return cur; } return NULL; } void fx_profile_bind(FxProfile* fxprofile , Contact *contact) { GdkPixbuf *pb; User *user = fxprofile->fxmain->user; Config *config = user->config; gchar *res; gchar portrait[1024]; if(contact->nickname != NULL) gtk_entry_set_text(GTK_ENTRY(fxprofile->nick_entry) , contact->nickname); gtk_entry_set_text(GTK_ENTRY(fxprofile->gender_entry) , contact->gender == 1 ? _("Male") : ( contact->gender == 2 ? _("Female") : _("Secrecy"))); if(contact->mobileno != NULL) gtk_entry_set_text(GTK_ENTRY(fxprofile->mno_entry) , contact->mobileno); if(contact->impression != NULL) gtk_entry_set_text(GTK_ENTRY(fxprofile->impre_entry) , contact->impression); gtk_entry_set_text(GTK_ENTRY(fxprofile->sid_entry) , contact->sId); if(contact->country != NULL) gtk_entry_set_text(GTK_ENTRY(fxprofile->nation_entry) , strcmp(contact->country , "CN") == 0 ? _("China") : contact->country); if(contact->province != NULL) { res = fetion_config_get_province_name(contact->province); gtk_entry_set_text(GTK_ENTRY(fxprofile->province_entry) , res == NULL ? _("Unknown") : res); free(res); } if(contact->city != NULL) { res = fetion_config_get_city_name(contact->province , contact->city); gtk_entry_set_text(GTK_ENTRY(fxprofile->city_entry) , res == NULL ? _("Unknown") : res); free(res); } sprintf(portrait , "%s/%s.jpg" , config->iconPath , contact->sId); if(contact->localname != NULL) gtk_entry_set_text(GTK_ENTRY(fxprofile->local_entry) , contact->localname); pb = gdk_pixbuf_new_from_file_at_size(portrait , 90 , 90 , NULL); if(pb != NULL){ gtk_image_set_from_pixbuf(GTK_IMAGE(fxprofile->image) , pb); g_object_unref(pb); } } void fx_profile_free(FxProfile* fxprofile) { free(fxprofile); } void fx_profile_on_button_clicked(GtkWidget* UNUSED(widget) , gpointer data) { gtk_dialog_response(GTK_DIALOG(data) , GTK_RESPONSE_OK); } openfetion-2.2.1/src/fx_profile.h0000644000175000017500000000531011561721144015440 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_PROFILE_H #define FX_PROFILE_H extern FxProfile* fx_profile_new(FxMain* fxmain , const char* userid); extern void fx_profile_initialize(FxProfile* fxprofile); extern Contact *fx_profile_fetch(FxProfile *fxprofile); extern void fx_profile_bind(FxProfile *fxprofile , Contact *contact); extern void fx_profile_free(FxProfile *fxprofile); extern void fx_profile_on_button_clicked(GtkWidget* UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_proxy.c0000644000175000017500000002100111561721144015147 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxProxy *fx_proxy_new(FxLogin *fxlogin) { FxProxy *fxproxy = (FxProxy*)malloc(sizeof(FxProxy)); memset(fxproxy , 0 , sizeof(FxProxy)); fxproxy->fxlogin = fxlogin; return fxproxy; } static void fx_proxy_set_sensitive(FxProxy *fxproxy , gboolean enable) { gtk_widget_set_sensitive(fxproxy->hostEntry , enable); gtk_widget_set_sensitive(fxproxy->portEntry , enable); gtk_widget_set_sensitive(fxproxy->userEntry , enable); gtk_widget_set_sensitive(fxproxy->passEntry , enable); } static void fx_proxy_enable_toggled(GtkWidget *UNUSED(widget) , gpointer data) { FxProxy *fxproxy = (FxProxy*)data; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxproxy->enableBtn))) fx_proxy_set_sensitive(fxproxy , TRUE); else fx_proxy_set_sensitive(fxproxy , FALSE); } void fx_proxy_initialize(FxProxy *fxproxy) { GtkBox *vbox = NULL; GtkBox *action_area = NULL; GtkWidget *hostLabel = NULL; GtkWidget *portLabel = NULL; GtkWidget *userLabel = NULL; GtkWidget *passLabel = NULL; GtkWidget *fixed = NULL; GtkWidget *okBtn = NULL; GtkWidget *cancelBtn = NULL; GdkPixbuf *pb = NULL; char text[128]; Proxy *proxy = fxproxy->fxlogin->proxy; fxproxy->dialog = gtk_dialog_new(); gtk_widget_set_usize(fxproxy->dialog , 350 , 220); gtk_window_set_resizable(GTK_WINDOW(fxproxy->dialog) , FALSE); gtk_window_set_title(GTK_WINDOW(fxproxy->dialog) , _("Set HTTP Proxy")); pb = gdk_pixbuf_new_from_file(SKIN_DIR"proxy.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxproxy->dialog) , pb); vbox = GTK_BOX(GTK_DIALOG(fxproxy->dialog)->vbox); action_area = GTK_BOX(GTK_DIALOG(fxproxy->dialog)->action_area); fixed = gtk_fixed_new(); fxproxy->enableBtn = gtk_check_button_new_with_label(_("Trun on HTTP proxy")); g_signal_connect(fxproxy->enableBtn , "toggled" , G_CALLBACK(fx_proxy_enable_toggled) , fxproxy); gtk_fixed_put(GTK_FIXED(fixed) , fxproxy->enableBtn , 20 , 20); fxproxy->errorLabel = gtk_label_new(NULL); gtk_fixed_put(GTK_FIXED(fixed) , fxproxy->errorLabel , 180 , 22); hostLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(hostLabel) , _("Proxy host")); gtk_fixed_put(GTK_FIXED(fixed) , hostLabel , 20 , 55); portLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(portLabel) , _("Port")); gtk_fixed_put(GTK_FIXED(fixed) , portLabel , 190 , 55); fxproxy->hostEntry = gtk_entry_new(); gtk_widget_set_usize(fxproxy->hostEntry , 140 , 25); gtk_fixed_put(GTK_FIXED(fixed) , fxproxy->hostEntry , 20 , 75); fxproxy->portEntry = gtk_entry_new(); gtk_widget_set_usize(fxproxy->portEntry , 140 , 25); gtk_fixed_put(GTK_FIXED(fixed) , fxproxy->portEntry , 190 , 75); userLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(userLabel) , _("Uesrname")); gtk_fixed_put(GTK_FIXED(fixed) , userLabel , 20 , 110); passLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(passLabel) , _("Password")); gtk_fixed_put(GTK_FIXED(fixed) , passLabel , 190 , 110); fxproxy->userEntry = gtk_entry_new(); gtk_widget_set_usize(fxproxy->userEntry , 140 , 25); gtk_fixed_put(GTK_FIXED(fixed) , fxproxy->userEntry , 20 , 130); fxproxy->passEntry = gtk_entry_new(); gtk_widget_set_usize(fxproxy->passEntry , 140 , 25); gtk_entry_set_visibility(GTK_ENTRY(fxproxy->passEntry) , FALSE); gtk_fixed_put(GTK_FIXED(fixed) , fxproxy->passEntry , 190 , 130); okBtn = gtk_button_new_with_label(_("OK")); g_signal_connect(okBtn , "clicked" , G_CALLBACK(fx_proxy_on_ok_clicked) , fxproxy); cancelBtn = gtk_button_new_with_label(_("Cancel")); g_signal_connect(cancelBtn , "clicked" , G_CALLBACK(fx_proxy_on_cancel_clicked) , fxproxy); gtk_box_pack_start_defaults(vbox , fixed); gtk_box_pack_start_defaults(action_area , okBtn); gtk_box_pack_start_defaults(action_area , cancelBtn); /* bind data*/ if(proxy != NULL && proxy->proxyEnabled) { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxproxy->enableBtn) , TRUE); fx_proxy_set_sensitive(fxproxy , TRUE); } else { gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxproxy->enableBtn) , FALSE); fx_proxy_set_sensitive(fxproxy , FALSE); } if(proxy != NULL) { gtk_entry_set_text(GTK_ENTRY(fxproxy->hostEntry) , proxy->proxyHost); snprintf(text, sizeof(text) - 1 , "%d" , proxy->proxyPort); gtk_entry_set_text(GTK_ENTRY(fxproxy->portEntry) , text); gtk_entry_set_text(GTK_ENTRY(fxproxy->userEntry) , proxy->proxyUser); gtk_entry_set_text(GTK_ENTRY(fxproxy->passEntry) , proxy->proxyPass); } /* show widgets*/ gtk_widget_show_all(fxproxy->dialog); } void fx_proxy_on_ok_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxProxy *fxproxy = (FxProxy*)data; FxLogin *fxlogin = fxproxy->fxlogin; const char *text = NULL; Proxy *proxy = NULL; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxproxy->enableBtn))) { proxy = (Proxy*)malloc(sizeof(Proxy)); memset(proxy , 0 , sizeof(proxy)); proxy->proxyEnabled = TRUE; text = gtk_entry_get_text(GTK_ENTRY(fxproxy->hostEntry)); if(*text == '\0') { gtk_label_set_markup(GTK_LABEL(fxproxy->errorLabel) , _("Please input hostname")); free(proxy); return; } strcpy(proxy->proxyHost , text); text = gtk_entry_get_text(GTK_ENTRY(fxproxy->portEntry)); proxy->proxyPort = atoi(text); if(*text == '\0') { gtk_label_set_markup(GTK_LABEL(fxproxy->errorLabel) , _("Please input port number")); free(proxy); return; } text = gtk_entry_get_text(GTK_ENTRY(fxproxy->userEntry)); strcpy(proxy->proxyUser , text); text = gtk_entry_get_text(GTK_ENTRY(fxproxy->passEntry)); strcpy(proxy->proxyPass , text); fetion_config_save_proxy(proxy); free(fxlogin->proxy); fxlogin->proxy = proxy; gtk_label_set_markup(GTK_LABEL(fxlogin->proxyLabel) , _(" Proxy [on]")); } else { if(fxlogin->proxy != NULL) { fxlogin->proxy->proxyEnabled = FALSE; fetion_config_save_proxy(fxlogin->proxy); } gtk_label_set_markup(GTK_LABEL(fxlogin->proxyLabel) , _(" Proxy [off]")); } gtk_dialog_response(GTK_DIALOG(fxproxy->dialog) , GTK_RESPONSE_OK); } void fx_proxy_on_cancel_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxProxy *fxproxy = (FxProxy*)data; gtk_dialog_response(GTK_DIALOG(fxproxy->dialog) , GTK_RESPONSE_CANCEL); } openfetion-2.2.1/src/fx_proxy.h0000644000175000017500000000507711561721144015173 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_PROXY_H #define FX_PROXY_H extern FxProxy *fx_proxy_new(FxLogin *fxlogin); extern void fx_proxy_initialize(FxProxy *fxproxy); extern void fx_proxy_on_ok_clicked(GtkWidget *UNUSED(widget) , gpointer data); extern void fx_proxy_on_cancel_clicked(GtkWidget *UNUSED(widget) , gpointer data); #endif openfetion-2.2.1/src/fx_search.c0000644000175000017500000003123411561721144015244 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" FxSearch *fx_search_new(FxMain *fxmain) { FxSearch *search = (FxSearch*)malloc(sizeof(FxSearch)); search->fxmain = fxmain; return search; } static void row_activate_func(GtkTreeView *view , GtkTreePath *path , GtkTreeViewColumn *UNUSED(column) , gpointer data) { FxSearch *search = (FxSearch*)data; FxMain* fxmain = search->fxmain; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(view)); GtkTreeIter iter; char *sipuri , *mobileno , *carrier; int serviceStatus , relationStatus , carrierStatus; if(path == NULL){ gtk_widget_destroy(search->window); free(search); return; } if(!gtk_tree_model_get_iter(model , &iter , path)) return; gtk_tree_model_get(model , &iter , B_SIPURI_COL , &sipuri , B_PHONENUM_COL , &mobileno , B_SERVICESTATUS_COL , &serviceStatus , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , -1); if(relationStatus == RELATION_STATUS_UNAUTHENTICATED) { fx_util_popup_warning(fxmain , _("You can not send messages to him(her)" ", because he(she) is not in your contact list")); return; } if(serviceStatus == BASIC_SERVICE_ABNORMAL && (carrierStatus == CARRIER_STATUS_CLOSED || (*carrier != '\0' && *mobileno == '\0'))) { fx_util_popup_warning(fxmain , _("User has shut his fetion service" ", so you can not send a message to him")); return; } fx_main_create_chat_window(fxmain , sipuri); free(sipuri); free(mobileno); free(carrier); } static gboolean key_press_func(GtkWidget *UNUSED(tree) , GdkEventKey *event , gpointer data) { FxSearch *search = (FxSearch*)data; if(event->keyval == GDK_q){ gtk_widget_destroy(search->window); free(search); return TRUE; } return FALSE; } static gboolean button_press_func(GtkWidget* tree , GdkEventButton* event , gpointer data) { GtkTreePath* path = NULL; if(event->type == GDK_BUTTON_PRESS && event->button == 1) { gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tree) , (gint)event->x , (gint)event->y , &path , NULL , NULL , NULL); row_activate_func(GTK_TREE_VIEW(tree) , path , NULL , data); return TRUE; } return FALSE; } static gboolean window_focus_out(GtkWidget *UNUSED(widget) , GdkEventFocus *UNUSED(event) , gpointer data) { FxSearch *search = (FxSearch*)data; gtk_widget_destroy(search->window); free(search); return TRUE; } static void text_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)) { GtkTreePath* path = gtk_tree_model_get_path(model , iter); char text[1024]; /*contact data*/ char *name , *impression , *sipuri , *sid , *stateStr , *mobileno , *device , *carrier; char stateStr1[96]; char statusStr[256]; int presence , size; int carrierStatus , relationStatus , serviceStatus; /* render friend list text*/ memset(text, 0, sizeof(text)); gtk_tree_model_get(model , iter , B_NAME_COL , &name , B_SIPURI_COL , &sipuri , B_STATE_COL , &presence , B_IMPRESSION_COL , &impression , B_PHONENUM_COL , &mobileno , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , B_SERVICESTATUS_COL , &serviceStatus , B_SIZE_COL , &size , B_DEVICE_COL , &device , -1); stateStr = fx_util_get_state_name(presence); memset(statusStr, 0, sizeof(statusStr)); if(relationStatus == RELATION_STATUS_UNAUTHENTICATED){ sprintf(statusStr , "[Unverified]"); }else if(serviceStatus == BASIC_SERVICE_ABNORMAL){ if(carrierStatus == CARRIER_STATUS_CLOSED){ sprintf(statusStr , "[Has shut fetion service]"); }else{ if(carrier != NULL || strlen(carrier) != 0){ sprintf(statusStr , "[Online with SMS]"); if(mobileno == NULL || *mobileno == '\0'){ sprintf(statusStr , "[Has shut fetion service]"); } }else{ sprintf(statusStr , "[Has shut fetion service]"); } } }else if(carrierStatus == CARRIER_STATUS_DOWN){ if(*carrier != '\0'){ sprintf(statusStr , "[Out of service]"); } } if(sipuri == NULL){ return; } sid = fetion_sip_get_sid_by_sipuri(sipuri); memset(stateStr1, 0, sizeof(stateStr1)); sprintf(stateStr1 , "%s" , stateStr); if( size < 30) { sprintf(text , "%s%s%s" "(%s) %s" , name == NULL ? "" : g_markup_escape_text(name , strlen(name)) , (*statusStr == '\0' ? (presence == 0 ? "" : stateStr1) : statusStr) , (device != NULL && strcmp(device , "PC") != 0) ? "[Login with cell phone]" : "" , sid , impression == NULL ? "" : g_markup_escape_text(impression , strlen(impression))); } else { sprintf(text , "%s%s%s" "(%s) \n %s" , name == NULL ? "" : g_markup_escape_text(name , strlen(name)) , (*statusStr == '\0' ? (presence == 0 ? "" : stateStr1) : statusStr) , (device != NULL &&strcmp(device , "PC") != 0) ? "[Login with cell phone]" : "" , sid , impression == NULL ? "" : g_markup_escape_text(impression , strlen(impression))); } g_object_set(renderer , "markup" , text , NULL); free(name); free(stateStr); free(impression); free(sipuri); free(mobileno); free(sid); free(device); free(carrier); gtk_tree_path_free(path); } static void create_column(GtkWidget* tree , FxMain* UNUSED(fxmain)) { GtkCellRenderer* renderer; GtkTreeViewColumn *col , *col0; renderer = gtk_cell_renderer_pixbuf_new(); col = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col, renderer , FALSE); gtk_tree_view_column_add_attribute(col, renderer, "pixbuf", B_PIXBUF_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col); renderer = gtk_cell_renderer_text_new(); col0 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col0, renderer , FALSE); gtk_tree_view_column_set_cell_data_func(col0 , renderer , text_cell_data_func , NULL , NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col0); } static GtkTreeModel* create_model(GtkTreeModel *model , const char *str) { GtkTreeIter iter , citer , niter; GdkPixbuf *pixbuf; char *name , *impression , *sipuri; char *mobileno , *device , *carrier; int presence , size; char text[1024]; int carrierStatus , relationStatus , serviceStatus; char *pyname; GtkTreeStore *store = gtk_tree_store_new(COL_NUM , GDK_TYPE_PIXBUF , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT); if(str == NULL || *str == '\0') return GTK_TREE_MODEL(store); gtk_tree_model_get_iter_first(model , &iter); do{ if(gtk_tree_model_iter_children(model , &citer , &iter)){ do{ gtk_tree_model_get(model , &citer , B_PIXBUF_COL , &pixbuf , B_NAME_COL , &name , B_SIPURI_COL , &sipuri , B_STATE_COL , &presence , B_IMPRESSION_COL , &impression , B_PHONENUM_COL , &mobileno , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , B_SERVICESTATUS_COL , &serviceStatus , B_SIZE_COL , &size , B_DEVICE_COL , &device , -1); size_t j; strcpy(text , str); for(j = 0; j < strlen(text) ; j++) text[j] = toupper(text[j]); pyname = get_pystring(name); if(strstr(pyname , text) != NULL){ gtk_tree_store_append(store , &niter , NULL); gtk_tree_store_set(store , &niter , B_PIXBUF_COL , pixbuf , B_NAME_COL , name , B_SIPURI_COL , sipuri , B_STATE_COL , presence , B_IMPRESSION_COL , impression , B_PHONENUM_COL , mobileno , B_CARRIER_COL , carrier , B_CARRIERSTATUS_COL , carrierStatus , B_RELATIONSTATUS_COL , relationStatus , B_SERVICESTATUS_COL , serviceStatus , B_SIZE_COL , size , B_DEVICE_COL , device , -1); } free(pyname); g_object_unref(pixbuf); free(name); free(sipuri); free(impression); free(mobileno); free(carrier); free(device); }while(gtk_tree_model_iter_next(model , &citer)); } }while(gtk_tree_model_iter_next(model , &iter)); return GTK_TREE_MODEL(store); } void fx_search_initialize(FxSearch *search , GtkTreeModel *model , const char *str , int x , int y) { GtkWidget *frame; search->window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_decorated(GTK_WINDOW(search->window) , FALSE); gtk_window_set_type_hint(GTK_WINDOW(search->window), GDK_WINDOW_TYPE_HINT_DIALOG); // gtk_widget_set_name(search->window , "mainwindow"); gtk_window_set_default_size(GTK_WINDOW(search->window) , 240 , 60); gtk_window_set_skip_taskbar_hint (GTK_WINDOW(search->window), TRUE); gtk_window_move(GTK_WINDOW(search->window) , x , y); g_signal_connect(search->window , "focus-out-event" , GTK_SIGNAL_FUNC(window_focus_out) , search); frame = gtk_frame_new(NULL); gtk_frame_set_shadow_type(GTK_FRAME(frame) , GTK_SHADOW_ETCHED_IN); GtkTreeModel *nmodel = create_model(model , str); search->view = gtk_tree_view_new_with_model(nmodel); gtk_widget_set_usize(search->view , 320 , 0); create_column(search->view , search->fxmain); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(search->view) , FALSE); //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (search->view), TRUE); gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(search->view) , TRUE); gtk_container_add(GTK_CONTAINER(search->window) , frame); gtk_container_add(GTK_CONTAINER(frame) , search->view); g_signal_connect(search->view , "row-activated" , G_CALLBACK(row_activate_func) , search); g_signal_connect(search->view , "button-press-event" , G_CALLBACK(button_press_func) , search); g_signal_connect(search->view , "key-press-event" , G_CALLBACK(key_press_func) , search); gtk_widget_show_all(search->window); } openfetion-2.2.1/src/fx_search.h0000644000175000017500000000533711561721144015256 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_SEARCH_H #define FX_SEARCH_H enum { H_PIXBUF_COL = 0 , H_TEXT_COL , H_SIPURI_COL , H_USERID_COL , H_NAME_COL , H_IMPRESSION_COL , H_PHONENUM_COL , H_CARRIER_COL , H_STATE_COL , H_IDENTITY_COL , H_RELATIONSTATUS_COL , H_CARRIERSTATUS_COL , H_SERVICESTATUS_COL , H_COL_NUM }; extern FxSearch *fx_search_new(FxMain *fxmain); extern void fx_search_initialize(FxSearch *searcn , GtkTreeModel *model , const char *str , int x , int y); #endif openfetion-2.2.1/src/fx_server.c0000644000175000017500000003003011561721144015276 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include #include #include int idlefifo; static int process_request(FxMain *fxmain, struct fifo_mesg mesg, const char *body); static int process_send_message(FxMain *fxmain, int client_fifo, xmlNodePtr node); static int process_get_contact_info(FxMain *fxmain, int client_fifo, xmlNodePtr node); static int server_send_message_to_friend(FxMain *fxmain, const char *no, const char *body, int send_to_phone, char *errbuf); static int send_error(int client_fifo, const char *msg); static int send_success(int client_fifo, const char *msg); int init_server(FxMain *fxmain) { int fifo; User *user = fxmain->user; char server_fifo[128]; snprintf(server_fifo, sizeof(server_fifo) - 1, OPENFETION_FIFO_FILE, user->mobileno); if(mkfifo(server_fifo, FIFO_FILE_MODE) == -1 && errno != EEXIST) { debug_error("create fifo %s:%s\n", server_fifo, strerror(errno)); return -1; } if((fifo = open(server_fifo, O_RDONLY, 0)) == -1) { debug_error("open fifo %s:%s\n", server_fifo, strerror(errno)); return -1; } if((idlefifo = open(server_fifo, O_WRONLY, 0)) == -1) { debug_error("open fifo %s:%s\n", server_fifo, strerror(errno)); close(fifo); return -1; } return fifo; } int io_read(int fifo, void *buf, int len) { int n, ret; if(len == 0) return 0; for(n=0;n!=len && (ret = read(fifo, buf+n, len-n)) != -1 && ret;n += ret); return (n!=len)? -1:n; } int start_server(FxMain *fxmain, int fifo) { char buf[BUFLEN]; struct fifo_mesg mesg; int n; for(;;) { memset(buf, 0, sizeof(buf)); n = read(fifo, &mesg, FIFO_HEAD_SIZE); if(n != FIFO_HEAD_SIZE) { debug_error("fifo message error\n"); continue; } memset(buf, 0, sizeof(buf)); if((n = io_read(fifo, buf, mesg.length)) == -1) { continue; } process_request(fxmain, mesg, buf); } return 0; } static int process_request(FxMain *fxmain, struct fifo_mesg mesg, const char *body) { xmlDocPtr doc; xmlNodePtr node; char client_fifo_file[BUFLEN]; int client_fifo; sprintf(client_fifo_file, OPENFETION_CLIENT_FIFO, mesg.pid); if((client_fifo = open(client_fifo_file, O_WRONLY, 0)) == -1) { debug_error("open %s:%s", client_fifo_file, strerror(errno)); return -1; } if(!(doc = xmlParseMemory(body, mesg.length))) { debug_error("parse cli send message request failed"); send_error(client_fifo, "unknown request message"); close(client_fifo); return -1; } node = xmlDocGetRootElement(doc); node = node->xmlChildrenNode; if(strcmp((char*)node->name, "m") == 0) { switch(mesg.type) { case CLI_SEND_MESSAGE: process_send_message(fxmain, client_fifo, node); break; case CLI_GET_INFORMATION: process_get_contact_info(fxmain, client_fifo, node); break; default: debug_error("unknown request type"); send_error(client_fifo, "unknown request type"); xmlFreeDoc(doc); return -1; break; } }else{ debug_error("parse cli send message request failed"); send_error(client_fifo, "unknown request message"); xmlFreeDoc(doc); return -1; } xmlFreeDoc(doc); return 0; } static int process_send_message(FxMain *fxmain, int client_fifo, xmlNodePtr node) { xmlChar *res; char msg_no[BUFLEN]; char msg_body[BUFLEN]; User *user = fxmain->user; Conversation *conv; char errbuf[BUFLEN]; int send_to_phone = 0; if(!xmlHasProp(node, BAD_CAST "no")) { debug_error("parse cli send message request failed"); send_error(client_fifo, "unknown request message"); return -1; } if(!xmlHasProp(node, BAD_CAST "bd")) { debug_error("parse cli send message request failed"); send_error(client_fifo, "unknown request message"); return -1; } if(xmlHasProp(node, BAD_CAST "p")) { res = xmlGetProp(node, BAD_CAST "p"); send_to_phone = atoi((char*)res); xmlFree(res); } res = xmlGetProp(node, BAD_CAST "no"); sprintf(msg_no, "%s", (char*)res); xmlFree(res); res = xmlGetProp(node, BAD_CAST "bd"); sprintf(msg_body, "%s", (char*)res); xmlFree(res); if(strcmp(msg_no, user->mobileno) == 0) { /* send it to myself */ conv = fetion_conversation_new(user, NULL, NULL); if(fetion_conversation_send_sms_to_myself_with_reply(conv, msg_body) == -1) { snprintf(errbuf, sizeof(errbuf) - 1, "send sms to %s failed", msg_no); send_error(client_fifo, errbuf); return -1; }else{ snprintf(errbuf, sizeof(errbuf) - 1, "send sms to %s", msg_no); send_success(client_fifo, errbuf); return 0; } free(conv); }else{ memset(errbuf, 0, sizeof(errbuf)); if(server_send_message_to_friend(fxmain, msg_no, msg_body, send_to_phone, errbuf) == -1) { send_error(client_fifo, errbuf); return -1; }else{ send_success(client_fifo, errbuf); return 0; } } return 0; } static int process_get_contact_info(FxMain *fxmain, int client_fifo, xmlNodePtr node) { Contact *contact; xmlChar *res; User *user = fxmain->user; char *city; char *province; char *sid; char body_buf[BUFLEN]; char mobileno[BUFLEN]; if(!xmlHasProp(node, BAD_CAST "no")) { send_error(client_fifo, "unknown request message"); return -1; } res = xmlGetProp(node, BAD_CAST "no"); strcpy(mobileno, (char*)res); xmlFree(res); contact = fetion_contact_get_contact_info_by_no(user, mobileno, MOBILE_NO); if(contact) { province = fetion_config_get_province_name(contact->province); city = fetion_config_get_city_name(contact->province, contact->city); sid = fetion_sip_get_sid_by_sipuri(contact->sipuri); snprintf(body_buf, sizeof(body_buf) - 1, "get information successfully\n" "Mobile No:\t%s\n" "Sex:\t\t%s\n" "NickName:\t%s\n" "Impression:\t%s\n" "Birthday:\t%s\n" "City:\t\t%s\n" "Province\t%s", contact->mobileno, contact->gender == 1 ? _("Male") : ( contact->gender == 2 ? _("Female") : _("Secrecy")), contact->nickname, contact->impression, contact->birthday, city, province); free(city); free(province); free(sid); if(send_success(client_fifo, body_buf) == -1) { debug_info("send response successfully\n%s", body_buf); return -1; }else{ return 0; } }else{ snprintf(body_buf, sizeof(body_buf) - 1, "get contact information of %s failed", mobileno); send_error(client_fifo, body_buf); return -1; } return 0; } static int server_send_message_to_friend(FxMain *fxmain, const char *no, const char *body, int send_to_phone, char *resbuf) { FetionSip *sip; ThreadArgs *args = NULL; FxList *fxlist = NULL; Contact *contact; User *user = fxmain->user; Conversation *conv; contact = fetion_contact_list_find_by_mobileno(user->contactList, no); if(!contact) { sprintf(resbuf, "couldn't find %s in buddy list", no); debug_error(resbuf); return -1; } conv = fetion_conversation_new(user, contact->sipuri, NULL); /* send message directly to mobile phone */ if(send_to_phone) { int daycount = 0, monthcount = 0; if(fetion_conversation_send_sms_to_phone_with_reply(conv, body, &daycount, &monthcount) == -1) { sprintf(resbuf, "send message directly to mobile phone with number %s failed", no); debug_error(resbuf); return -1; }else{ sprintf(resbuf, "send message to %s\n%d messages sent today\n%d messages sent this month\n" "%d messages left for today\n%d messages left for this month", no, daycount, monthcount, user->smsDayLimit - daycount, user->smsMonthLimit - monthcount); debug_info(resbuf); return 0; } } if(contact->state == P_ONLINE) { sip = fx_list_find_sip_by_sipuri(fxmain->slist, contact->sipuri); if(!sip) { if(fetion_conversation_invite_friend(conv) > 0){ fx_conn_append(conv->currentSip->tcp); args = (ThreadArgs*)malloc(sizeof(ThreadArgs)); args->fxmain = fxmain; args->sip = conv->currentSip; fxlist = fx_list_new(conv->currentSip); fx_list_append(fxmain->slist , fxlist); g_thread_create(fx_main_listen_thread_func , args , FALSE , NULL); if(fetion_conversation_send_sms_with_reply(conv , body) == -1) { sprintf(resbuf, "send sms failed"); debug_error(resbuf); return -1; }else{ sprintf(resbuf, "send sms successfully"); debug_info(resbuf); } }else{ sprintf(resbuf, "user with mobile number %s is now online, but couldn't invite it", no); debug_error(resbuf); return -1; } }else{ conv->currentSip = sip; if(fetion_conversation_send_sms_with_reply(conv, body) == -1) { sprintf(resbuf, "send sms failed"); debug_error(resbuf); return -1; }else{ sprintf(resbuf, "successfully send message to %s", no); debug_info(resbuf); return 0; } } }else{ if(fetion_conversation_send_sms_with_reply(conv, body) == -1) { sprintf(resbuf, "send sms failed"); debug_error(resbuf); return -1; }else{ sprintf(resbuf, "successfully send message to %s", no); debug_info(resbuf); return 0; } } return 0; } static int send_error(int client_fifo, const char *msg) { struct fifo_resp *resp; char client_buf[BUFLEN]; unsigned int n; resp = (struct fifo_resp*)client_buf; resp->code = CLI_EXEC_FAIL; resp->length = strlen(msg); memcpy(client_buf + RESP_HEAD_SIZE, msg, strlen(msg)); n = write(client_fifo, client_buf, resp->length + RESP_HEAD_SIZE); if(n != resp->length + RESP_HEAD_SIZE) { debug_error("send back response failed"); return -1; } return 0; } static int send_success(int client_fifo, const char *msg) { struct fifo_resp *resp; char client_buf[BUFLEN]; unsigned int n; resp = (struct fifo_resp*)client_buf; resp->code = CLI_EXEC_OK; resp->length = strlen(msg); memcpy(client_buf + RESP_HEAD_SIZE, msg, strlen(msg)); n = write(client_fifo, client_buf, resp->length + RESP_HEAD_SIZE); if(n != resp->length + RESP_HEAD_SIZE) { debug_error("send back response failed"); return -1; } return 0; } openfetion-2.2.1/src/fx_server.h0000644000175000017500000000612511561721144015313 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include #include #include #include #ifndef FX_SERVER_H #define FX_SERVER_H struct fifo_mesg { unsigned short type; unsigned short length; unsigned int pid; }; struct fifo_resp { unsigned short code; unsigned short length; }; #define CLI_SEND_MESSAGE 1 #define CLI_GET_INFORMATION 2 #define OPENFETION_FIFO_FILE "/tmp/openfetion_fifo_%s" #define OPENFETION_CLIENT_FIFO "/tmp/openfetion_fifo_%d" #define FIFO_FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) #define CLI_EXEC_OK 200 #define CLI_EXEC_FAIL 400 #define BUFLEN 4096 #define FIFO_HEAD_SIZE (sizeof(struct fifo_mesg)) #define RESP_HEAD_SIZE (sizeof(struct fifo_resp)) int init_server(FxMain *fxmain); int start_server(FxMain *fxmain, int fifo); int fx_cli_opt(int argc, char **argv); int fx_cli_exec(); #endif openfetion-2.2.1/src/fx_set.c0000644000175000017500000005315111561721144014574 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" static void fx_set_on_ok_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxSet *fxset = (FxSet*)data; User *user = fxset->fxmain->user; Config *config = user->config; /* system setting varibles */ GtkTextView *textview = GTK_TEXT_VIEW(fxset->apEty); GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview); GtkTextIter startIter; GtkTextIter endIter; const gchar *autoReplyMsg = NULL; /* personal setting varibles */ const gchar *nickname = NULL; const gchar *impression = NULL; gchar nickname_text[1024]; gint gender; GtkTreeModel *genderModel = NULL; GtkTreeIter genderIter; if(gtk_notebook_get_current_page(GTK_NOTEBOOK(fxset->notebook)) == PAGE_SYSTEM) { if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->etBtn))) config->sendMode = SEND_MODE_ENTER; else config->sendMode = SEND_MODE_CTRL_ENTER; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->ppCb))) config->autoPopup = AUTO_POPUP_ENABLE; else config->autoPopup = AUTO_POPUP_DISABLE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->smallBtn))) config->closeMode = CLOSE_ICON_MODE; else config->closeMode = CLOSE_DESTROY_MODE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->muteBtn))) config->isMute = MUTE_ENABLE; else config->isMute = MUTE_DISABLE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->alertBtn))) config->msgAlert = MSG_ALERT_DISABLE; else config->msgAlert = MSG_ALERT_ENABLE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->iconBtn))){ config->canIconify = ICON_CAN; config->closeAlert = CLOSE_ALERT_DISABLE; }else config->canIconify = ICON_CANNOT; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->autoAwayBtn))) config->autoAway = AUTO_AWAY_ENABLE; else config->autoAway = AUTO_AWAY_DISABLE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->onlineNotifyBtn))) config->onlineNotify = ONLINE_NOTIFY_ENABLE; else config->onlineNotify = ONLINE_NOTIFY_DISABLE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->closeSysMsgBtn))) config->closeSysMsg = CLOSE_SYSMSG_ENABLE; else config->closeSysMsg = CLOSE_SYSMSG_DISABLE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->closeShowBtn))) config->closeFetionShow = CLOSE_FETION_SHOW_ENABLE; else config->closeFetionShow = CLOSE_FETION_SHOW_DISABLE; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fxset->useStatusIcon))) config->useStatusIcon = USE_STATUS_ICON_DISABLE; else config->useStatusIcon = USE_STATUS_ICON_ENABLE; gtk_text_buffer_get_start_iter(buffer , &startIter); gtk_text_buffer_get_end_iter(buffer , &endIter); autoReplyMsg = gtk_text_buffer_get_text(buffer , &startIter , &endIter , TRUE); memset(config->autoReplyMessage, 0, sizeof(config->autoReplyMessage)); if(autoReplyMsg != NULL) strcpy(config->autoReplyMessage , autoReplyMsg); fetion_config_set_use_status_icon(config); fetion_config_save(user); } else { nickname = gtk_entry_get_text(GTK_ENTRY(fxset->nick_entry)); if(*nickname == '\0') { fx_util_popup_warning(fxset->fxmain , _("Nick can not be empty!")); return; } impression = gtk_entry_get_text(GTK_ENTRY(fxset->impre_entry)); memset(user->nickname, 0, sizeof(user->nickname)); strcpy(user->nickname , nickname); memset(user->impression, 0, sizeof(user->impression)); strcpy(user->impression , impression); genderModel = gtk_combo_box_get_model(GTK_COMBO_BOX(fxset->gender_combo)); gtk_combo_box_get_active_iter(GTK_COMBO_BOX(fxset->gender_combo) , &genderIter); gtk_tree_model_get(genderModel , &genderIter , COMBO_ID_COL , &gender , -1); user->gender = gender; if(fetion_user_update_info(user) > 0) { sprintf(nickname_text , "%s" , user->nickname == NULL ? user->sId : user->nickname ); gtk_label_set_markup(GTK_LABEL(fxset->fxmain->headPanel->name_label) , nickname_text ); gtk_label_set_text(GTK_LABEL(fxset->fxmain->headPanel->impre_label) , strlen(user->impression) == 0 ? _("Click here to input signature") : user->impression); memset(fxset->fxmain->headPanel->oldimpression, 0, sizeof(fxset->fxmain->headPanel->oldimpression)); strcpy(fxset->fxmain->headPanel->oldimpression , (strlen(user->impression) == 0 || user->impression == NULL) ? _("Click here to input signature") : user->impression); } } gtk_widget_destroy(fxset->dialog); } static void fx_set_on_cancel_clicked(GtkWidget *UNUSED(widget) , gpointer data) { gtk_widget_destroy(GTK_WIDGET(data)); } static void fx_set_on_autoreply_toggled(GtkWidget *widget , gpointer data) { FxSet *fxset = (FxSet*)data; if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) gtk_widget_set_sensitive(fxset->apEty , TRUE); else gtk_widget_set_sensitive(fxset->apEty , FALSE); } FxSet* fx_set_new(FxMain* fxmain) { FxSet *fxset = (FxSet*)malloc(sizeof(FxSet)); memset(fxset , 0 , sizeof(FxSet)); fxset->fxmain = fxmain; return fxset; } void fx_set_initialize(FxSet* fxset) { GtkWidget *psetting_label = NULL; GtkWidget *ssetting_label = NULL; GtkWidget *ok_button = NULL; GtkWidget* cancel_button = NULL; GtkBox *vbox , *action_area; GdkPixbuf* pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg", 22, 22, NULL); fxset->dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(fxset->dialog), GTK_WIN_POS_CENTER); gtk_window_set_icon(GTK_WINDOW(fxset->dialog) , pb); g_object_unref(pb); gtk_widget_set_usize(fxset->dialog , 500 , 360); gtk_window_set_title(GTK_WINDOW(fxset->dialog) , _("OpenFetion Preference")); fxset->notebook = gtk_notebook_new(); gtk_widget_set_usize(fxset->notebook , 490 , 320); gtk_notebook_set_show_border(GTK_NOTEBOOK(fxset->notebook) , FALSE); gtk_notebook_set_tab_pos(GTK_NOTEBOOK(fxset->notebook) , GTK_POS_TOP); vbox = GTK_BOX(gtk_vbox_new (FALSE, 0)); gtk_container_add(GTK_CONTAINER(fxset->dialog), GTK_WIDGET(vbox)); gtk_box_pack_start(vbox, fxset->notebook , FALSE , FALSE , 0); fxset->psetting = gtk_vbox_new(FALSE , FALSE); psetting_label = gtk_label_new(_("Personal Settings")); gtk_notebook_append_page(GTK_NOTEBOOK(fxset->notebook) , fxset->psetting , psetting_label); fxset->ssetting = gtk_vbox_new(FALSE , FALSE); ssetting_label = gtk_label_new(_("System Settings")); gtk_notebook_append_page(GTK_NOTEBOOK(fxset->notebook) , fxset->ssetting , ssetting_label); action_area = GTK_BOX(gtk_hbox_new(FALSE , 0)); gtk_box_pack_start(GTK_BOX(vbox) , GTK_WIDGET(action_area) , FALSE , FALSE , 5); cancel_button = gtk_button_new_with_label(_("Cancel")); gtk_widget_set_usize(cancel_button, 100, 30); gtk_box_pack_end(action_area , cancel_button, FALSE, FALSE, 5); g_signal_connect(cancel_button , "clicked" , G_CALLBACK(fx_set_on_cancel_clicked) , fxset->dialog); ok_button = gtk_button_new_with_label(_("OK")); gtk_widget_set_usize(ok_button, 100, 30); gtk_box_pack_end(action_area , ok_button, FALSE, FALSE, 5); g_signal_connect(ok_button , "clicked" , G_CALLBACK(fx_set_on_ok_clicked) , fxset); fx_set_initialize_personal(fxset); fx_set_initialize_system(fxset); gtk_widget_show_all(fxset->dialog); } void fx_set_bind_system(FxSet* fxset) { FxMain *fxmain = fxset->fxmain; Config *config = fxmain->user->config; GtkTextBuffer *buffer = NULL; GtkTextIter startIter , endIter; char *autoReplyMsg = NULL; if(config->sendMode == SEND_MODE_ENTER) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->etBtn) , TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->ctBtn) , TRUE); if(config->autoPopup == AUTO_POPUP_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->ppCb) , TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->ppCb) , FALSE); if(config->closeMode == CLOSE_ICON_MODE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->smallBtn) , TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->smallBtn) , FALSE); if(config->isMute == MUTE_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->muteBtn) , TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->muteBtn) , FALSE); if(config->msgAlert == MSG_ALERT_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->alertBtn) , FALSE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->alertBtn) , TRUE); if(config->canIconify == ICON_CAN) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->iconBtn) , TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->iconBtn) , FALSE); if(config->autoAway == AUTO_AWAY_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->autoAwayBtn) , TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->autoAwayBtn) , FALSE); if(config->onlineNotify == ONLINE_NOTIFY_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->onlineNotifyBtn), TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->onlineNotifyBtn), FALSE); if(config->closeSysMsg == CLOSE_SYSMSG_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->closeSysMsgBtn), TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->closeSysMsgBtn), FALSE); if(config->closeFetionShow == CLOSE_FETION_SHOW_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->closeShowBtn), TRUE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->closeShowBtn), FALSE); if(config->useStatusIcon == USE_STATUS_ICON_ENABLE) gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->useStatusIcon), FALSE); else gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxset->useStatusIcon), TRUE); buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(fxset->apEty)); gtk_text_buffer_get_start_iter(buffer , &startIter); gtk_text_buffer_get_end_iter(buffer , &endIter); gtk_text_buffer_delete(buffer , &startIter , &endIter); if(strlen(config->autoReplyMessage) == 0) { autoReplyMsg = _("Sorry, I am not in now, and will reply to you soon"); gtk_text_buffer_insert(buffer , &startIter , autoReplyMsg , strlen(autoReplyMsg)); } else { gtk_text_buffer_insert(buffer , &startIter , config->autoReplyMessage , strlen(config->autoReplyMessage)); } } void fx_set_initialize_personal(FxSet* fxset) { FxMain *fxmain = fxset->fxmain; User *user = fxmain->user; Config *config = user->config; char filepath[128]; GdkPixbuf *pb = NULL; GtkWidget *box = NULL; GtkTreeModel *gmodel = NULL; GtkWidget *gender_entry = NULL; GtkTreeIter iter; int id; char *cityName = NULL; char *provinceName = NULL; box = gtk_fixed_new(); gtk_box_pack_start_defaults(GTK_BOX(fxset->psetting) , box); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 90 , 90 , NULL); fxset->image = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_fixed_put(GTK_FIXED(box) , fxset->image , 10 , 15 ); fxset->sid_label = gtk_label_new(_("Fetion Number:")); gtk_misc_set_alignment(GTK_MISC(fxset->sid_label) , 0 , 0); gtk_fixed_put(GTK_FIXED(box) , fxset->sid_label , 120 , 10 ); fxset->sid_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxset->sid_entry) , FALSE); gtk_fixed_put(GTK_FIXED(box) , fxset->sid_entry , 120 , 30 ); fxset->gender_label = gtk_label_new(_("Sex:")); gtk_misc_set_alignment(GTK_MISC(fxset->gender_label) , 0 , 0); gtk_fixed_put(GTK_FIXED(box) , fxset->gender_label , 310 , 10 ); gmodel = fx_set_create_gender_model(); fxset->gender_combo = gtk_combo_box_entry_new_with_model(gmodel , COMBO_NAME_COL); gender_entry = gtk_bin_get_child(GTK_BIN(fxset->gender_combo)); gtk_entry_set_editable(GTK_ENTRY(gender_entry) , FALSE); gtk_combo_box_set_active(GTK_COMBO_BOX(fxset->gender_combo) , 1); gtk_widget_set_usize(fxset->gender_combo , 150 , 25); gtk_fixed_put(GTK_FIXED(box) , fxset->gender_combo , 310 , 30 ); fxset->mno_label = gtk_label_new(_("Cell Phone Number:")); gtk_misc_set_alignment(GTK_MISC(fxset->mno_label) , 0 , 0); gtk_fixed_put(GTK_FIXED(box) , fxset->mno_label , 120 , 60 ); fxset->mno_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxset->mno_entry) , FALSE); gtk_fixed_put(GTK_FIXED(box) , fxset->mno_entry , 120 , 80 ); fxset->nick_label = gtk_label_new(_("Nickname:")); gtk_misc_set_alignment(GTK_MISC(fxset->nick_label) , 0 , 0); gtk_fixed_put(GTK_FIXED(box) , fxset->nick_label , 310 , 60 ); fxset->nick_entry = gtk_entry_new(); gtk_fixed_put(GTK_FIXED(box) , fxset->nick_entry , 310 , 80 ); fxset->impre_label = gtk_label_new(_("Personal Signature:")); gtk_misc_set_alignment(GTK_MISC(fxset->impre_label) , 0 , 0); gtk_fixed_put(GTK_FIXED(box) , fxset->impre_label , 10 , 115 ); fxset->impre_entry = gtk_entry_new(); gtk_widget_set_usize(fxset->impre_entry , 460 , 25); gtk_fixed_put(GTK_FIXED(box) , fxset->impre_entry , 10 , 135 ); fxset->province_label = gtk_label_new(_("Province:")); gtk_misc_set_alignment(GTK_MISC(fxset->province_label) , 0 , 0 ); gtk_fixed_put(GTK_FIXED(box) , fxset->province_label , 10 , 165 ); fxset->province_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxset->province_entry) , FALSE); gtk_widget_set_usize(fxset->province_entry , 220 , 25); gtk_fixed_put(GTK_FIXED(box) , fxset->province_entry , 10 , 185 ); fxset->city_label = gtk_label_new(_("City:")); gtk_misc_set_alignment(GTK_MISC(fxset->city_label) , 0 , 0 ); gtk_fixed_put(GTK_FIXED(box) , fxset->city_label , 250 , 165 ); fxset->city_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxset->city_entry) , FALSE); gtk_widget_set_usize(fxset->city_entry , 220 , 25); gtk_fixed_put(GTK_FIXED(box) , fxset->city_entry , 250 , 185 ); fxset->job_label = gtk_label_new(_("Job occupation:")); gtk_misc_set_alignment(GTK_MISC(fxset->job_label) , 0 , 0 ); gtk_fixed_put(GTK_FIXED(box) , fxset->job_label , 10 , 215 ); fxset->job_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxset->job_entry) , FALSE); gtk_widget_set_usize(fxset->job_entry , 220 , 25); gtk_fixed_put(GTK_FIXED(box) , fxset->job_entry , 10 , 235 ); fxset->email_label = gtk_label_new(_("Email:")); gtk_misc_set_alignment(GTK_MISC(fxset->email_label) , 0 , 0 ); gtk_fixed_put(GTK_FIXED(box) , fxset->email_label , 250 , 215 ); fxset->email_entry = gtk_entry_new(); gtk_entry_set_editable(GTK_ENTRY(fxset->email_entry) , FALSE); gtk_widget_set_usize(fxset->email_entry , 220 , 25); gtk_fixed_put(GTK_FIXED(box) , fxset->email_entry , 250 , 235 ); gtk_entry_set_text(GTK_ENTRY(fxset->sid_entry) , user->sId); if(user->mobileno) gtk_entry_set_text(GTK_ENTRY(fxset->mno_entry) , user->mobileno); if(user->nickname) gtk_entry_set_text(GTK_ENTRY(fxset->nick_entry) , user->nickname); if(user->impression) gtk_entry_set_text(GTK_ENTRY(fxset->impre_entry) , user->impression); provinceName = fetion_config_get_province_name(user->province); if(provinceName) gtk_entry_set_text(GTK_ENTRY(fxset->province_entry) , provinceName); free(provinceName); cityName = fetion_config_get_city_name(user->province , user->city); if(cityName) gtk_entry_set_text(GTK_ENTRY(fxset->city_entry) , cityName); free(cityName); gtk_entry_set_text(GTK_ENTRY(fxset->job_entry) , _("Secrecy")); gtk_entry_set_text(GTK_ENTRY(fxset->email_entry) , _("Secrecy")); gtk_tree_model_get_iter_root(gmodel , &iter); do { gtk_tree_model_get(gmodel , &iter , COMBO_ID_COL , &id , -1); if(id == user->gender) { gtk_combo_box_set_active_iter(GTK_COMBO_BOX(fxset->gender_combo), &iter); break; } } while(gtk_tree_model_iter_next(gmodel , &iter)); sprintf(filepath , "%s/%s.jpg" , config->iconPath , user->sId); pb = gdk_pixbuf_new_from_file_at_size(filepath , 90 , 90 , NULL); if(pb != NULL){ gtk_image_set_from_pixbuf(GTK_IMAGE(fxset->image) , pb); g_object_unref(pb); } } void fx_set_initialize_system(FxSet* fxset) { GtkWidget *fixed = NULL; GtkWidget *label1 = NULL; GtkWidget *label2 = NULL; GtkWidget *label3 = NULL; GtkWidget *apScr = NULL; GSList *gl = NULL; fixed = gtk_fixed_new(); label1 = gtk_label_new(""); gtk_label_set_markup(GTK_LABEL(label1) , _("Appearance")); gtk_fixed_put(GTK_FIXED(fixed) , label1 , 20 , 10); fxset->iconBtn = gtk_check_button_new_with_label(_("Minimize to Tray")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->iconBtn , 40 , 32); fxset->smallBtn = gtk_check_button_new_with_label(_("Close to Tray")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->smallBtn , 230 , 32); fxset->ppCb = gtk_check_button_new_with_label(_("Auto popup message")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->ppCb , 40 , 57); fxset->alertBtn = gtk_check_button_new_with_label(_("Disable Message Notification")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->alertBtn , 230 , 57); fxset->muteBtn = gtk_check_button_new_with_label(_("Mute")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->muteBtn , 40 , 82); fxset->autoAwayBtn = gtk_check_button_new_with_label(_("Auto away when idle")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->autoAwayBtn , 230 , 82); fxset->onlineNotifyBtn = gtk_check_button_new_with_label(_("Online notification enabled")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->onlineNotifyBtn , 40 , 107); fxset->closeSysMsgBtn = gtk_check_button_new_with_label(_("Disable System Message")); gtk_fixed_put(GTK_FIXED(fixed), fxset->closeSysMsgBtn, 230, 107); fxset->closeShowBtn = gtk_check_button_new_with_label(_("Disable Fetion Show")); gtk_fixed_put(GTK_FIXED(fixed), fxset->closeShowBtn, 40, 132); fxset->useStatusIcon = gtk_check_button_new_with_label(_("Don't Use Status Icon(restart)")); gtk_fixed_put(GTK_FIXED(fixed), fxset->useStatusIcon, 230, 132); label2 = gtk_label_new(""); gtk_label_set_markup(GTK_LABEL(label2) , _("Auto Reply")); gtk_fixed_put(GTK_FIXED(fixed) , label2 , 20 , 162); fxset->apBtn = gtk_check_button_new_with_label(_("Enable")); g_signal_connect(fxset->apBtn , "toggled" , G_CALLBACK(fx_set_on_autoreply_toggled) , fxset); gtk_fixed_put(GTK_FIXED(fixed) , fxset->apBtn , 140 , 162); fxset->apEty = gtk_text_view_new(); gtk_widget_set_sensitive(fxset->apEty , FALSE); gtk_widget_set_usize(fxset->apEty , 380 , 20); apScr = gtk_scrolled_window_new(NULL , NULL); gtk_container_add(GTK_CONTAINER(apScr) , fxset->apEty); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(apScr) , GTK_POLICY_NEVER , GTK_POLICY_NEVER); gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(apScr) , GTK_SHADOW_ETCHED_IN); gtk_fixed_put(GTK_FIXED(fixed) , apScr , 40 , 187); label3 = gtk_label_new(""); gtk_label_set_markup(GTK_LABEL(label3) , _("Send Message")); gtk_fixed_put(GTK_FIXED(fixed) , label3 , 20 , 217); fxset->etBtn = gtk_radio_button_new_with_label(NULL , _("Press Enter to Send")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->etBtn , 40 , 235); gl = gtk_radio_button_get_group(GTK_RADIO_BUTTON(fxset->etBtn)); fxset->ctBtn = gtk_radio_button_new_with_label(gl , _("Press CTRL + Enter to Send")); gtk_fixed_put(GTK_FIXED(fixed) , fxset->ctBtn , 40 , 255); gtk_box_pack_start_defaults(GTK_BOX(fxset->ssetting) , fixed); fx_set_bind_system(fxset); } GtkTreeModel* fx_set_create_gender_model() { struct { const char* name; int id; } genders[] = { { N_("Male") , 1 } , { N_("Female") , 2 } , { N_("Secrecy") , 0} , { NULL , 1} }; GtkTreeStore* model = gtk_tree_store_new(COMBO_COLS_NUM , G_TYPE_STRING , G_TYPE_INT); GtkTreeIter iter; int i; for(i = 0; genders[i].name != NULL ; i++) { gtk_tree_store_append(model , &iter , NULL); gtk_tree_store_set(model , &iter , COMBO_NAME_COL , _(genders[i].name) , COMBO_ID_COL , genders[i].id , -1); } return GTK_TREE_MODEL(model); } openfetion-2.2.1/src/fx_set.h0000644000175000017500000000706711561721144014606 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_SET_H #define FX_SET_H enum{ COMBO_NAME_COL = 0 , COMBO_ID_COL , COMBO_COLS_NUM }; typedef enum{ SEND_MODE_ENTER , SEND_MODE_CTRL_ENTER } SendModeType; typedef enum{ AUTO_POPUP_DISABLE , AUTO_POPUP_ENABLE } AutoPopupType; typedef enum{ AUTO_REPLY_DISABLE , AUTO_REPLY_ENABLE } AutoReplyType; typedef enum{ CLOSE_DESTROY_MODE , CLOSE_ICON_MODE } CloseType; typedef enum{ MUTE_DISABLE , MUTE_ENABLE } MuteType; typedef enum{ PAGE_PERSONAL , PAGE_SYSTEM } NotebookPageType; typedef enum{ ICON_CAN , ICON_CANNOT } IconType; typedef enum { AUTO_AWAY_ENABLE, AUTO_AWAY_DISABLE } AutoAway; typedef enum { ONLINE_NOTIFY_ENABLE, ONLINE_NOTIFY_DISABLE } OnlineNotify; typedef enum { CLOSE_SYSMSG_DISABLE, CLOSE_SYSMSG_ENABLE } CloseSysMsg; typedef enum { CLOSE_FETION_SHOW_DISABLE, CLOSE_FETION_SHOW_ENABLE } CloseFetionShow; typedef enum { USE_STATUS_ICON_ENABLE, USE_STATUS_ICON_DISABLE } UseStatusIcon; #define USE_STATUS_ICON(c) ((c)->useStatusIcon == USE_STATUS_ICON_ENABLE) extern FxSet* fx_set_new(FxMain* fxmain); extern void fx_set_initialize(FxSet* fxset); extern void fx_set_bind_system(FxSet* fxset); extern void fx_set_initialize_personal(FxSet* fxset); extern void fx_set_initialize_system(FxSet* fxset); extern GtkTreeModel* fx_set_create_gender_model(); #endif openfetion-2.2.1/src/fx_share.c0000644000175000017500000001412011561721144015074 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" #include #include #include #include #include #include #include #include FxShare *fx_share_new(FxMain *fxmain , const char *sipuri) { FxShare *fxshare = (FxShare*)malloc(sizeof(FxShare)); User *user = fxmain->user; // DEBUG_FOOTPRINT(); memset(fxshare , 0 , sizeof(FxShare)); fxshare->fxmain = fxmain; fxshare->contact = fetion_contact_list_find_by_sipuri(user->contactList , sipuri); if(fxshare->contact == NULL){ return NULL; } return fxshare; } void fx_share_initialize(FxShare *fxshare) { GtkBox *vbox; GtkWidget *fixed; GtkWidget *pLabel; GtkWidget *okButton; GtkWidget *cancelButton; GdkPixbuf *pb; char text[1024]; // DEBUG_FOOTPRINT(); fxshare->dialog = gtk_dialog_new(); gtk_window_set_default_size(GTK_WINDOW(fxshare->dialog) , 400 , 180); pb = gdk_pixbuf_new_from_file(SKIN_DIR"sendfile.png" , NULL); gtk_window_set_icon(GTK_WINDOW(fxshare->dialog) , pb); gtk_window_set_title(GTK_WINDOW(fxshare->dialog) , _("Transport files by Fetion")); vbox = GTK_BOX(GTK_DIALOG(fxshare->dialog)->vbox); fixed = gtk_fixed_new(); gtk_box_pack_start_defaults(GTK_BOX(vbox) , fixed); fxshare->uLabel = gtk_label_new(NULL); memset(text, 0, sizeof(text)); sprintf(text , _("Transporting files OS Revolution.mkv to %s...") , fxshare->contact->nickname); gtk_label_set_markup(GTK_LABEL(fxshare->uLabel) , text); gtk_fixed_put(GTK_FIXED(fixed) , fxshare->uLabel , 20 , 20); pLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(pLabel) , _("Progress: ")); gtk_fixed_put(GTK_FIXED(fixed) , pLabel , 10 , 65); fxshare->progress = gtk_progress_bar_new(); gtk_widget_set_usize(fxshare->progress , 300 , 30); gtk_fixed_put(GTK_FIXED(fixed) , fxshare->progress , 60 , 60); gtk_progress_set_percentage(GTK_PROGRESS(fxshare->progress) , 0.8); fxshare->iLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(fxshare->iLabel) , _("Establishing Connection...")); gtk_fixed_put(GTK_FIXED(fixed) , fxshare->iLabel , 60 , 100); okButton = gtk_button_new_with_label(_("OK")); gtk_widget_set_sensitive(okButton , FALSE); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxshare->dialog)->action_area) , okButton); cancelButton = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxshare->dialog)->action_area) , cancelButton); gtk_widget_show_all(fxshare->dialog); } FxShare *fx_share_find_by_sipuri(FxList *fxlist , const char *sipuri) { FxShare *fxshare; FxList *pos = fxlist; // DEBUG_FOOTPRINT(); while(pos != NULL){ fxshare = (FxShare*)(pos->data); if(fxshare->contact == NULL){ pos = pos->next; continue; } if(strcmp(fxshare->contact->sipuri , sipuri) == 0){ return fxshare; } pos = pos->next; } return NULL; } void fx_share_start_transfer(FxShare *fxshare) { Share *share = fxshare->share; FetionConnection *tcp ; char *innerIp; int innerUdpPort; FILE *file; unsigned char buf[1024]; int i; // DEBUG_FOOTPRINT(); gtk_label_set_markup(GTK_LABEL(fxshare->iLabel) , _("Contact acccept your request of transporting files. Transporting...")); tcp = tcp_connection_new_with_port(1435); tcp_connection_getname(tcp , &innerIp , &innerUdpPort); printf("%s:%d\n" , innerIp , innerUdpPort); share->innerUdpPort = 1435; printf("%s:%d\n" , share->outerIp , share->outerTcpPort); int ret; ret = tcp_connection_connect(tcp , share->outerIp , share->outerTcpPort); printf("%d\n" , ret); file = fopen(share->absolutePath , "r"); while(1){ i = fread(buf , 1 , sizeof(buf) , file); if(i == 0){ break; } printf("%d\n" , i); ret = tcp_connection_send(tcp , buf , i); printf("SEND : %d\n" , ret); } fclose(file); tcp_connection_free(tcp); } openfetion-2.2.1/src/fx_share.h0000644000175000017500000000506511561721144015111 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_SHARE_H #define FX_SHARE_H extern FxShare *fx_share_new(FxMain *fxmain , const char *sipuri); extern void fx_share_initialize(FxShare *fxshare); extern FxShare *fx_share_find_by_sipuri(FxList *fxlist , const char *sipuri); extern void fx_share_start_transfer(FxShare *fxshare); #endif openfetion-2.2.1/src/fx_smsstat.c0000644000175000017500000001362111561721144015475 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" int global_days; static void on_ok_clicked(GtkWidget *widget , gpointer data); static void on_cancel_clicked(GtkWidget *widget , gpointer data); static void on_days_toggled(GtkWidget *widget , gpointer data); FxSmsstat *fx_smsstat_new(FxMain *fxmain) { FxSmsstat *fxsmsst = (FxSmsstat*)malloc(sizeof(FxSmsstat)); global_days = 1; memset(fxsmsst , 0 , sizeof(FxSmsstat)); fxsmsst->fxmain = fxmain; return fxsmsst; } void fx_smsstat_initialize(FxSmsstat *fxst) { GtkWidget *fixed; GtkWidget *rbtn; GtkWidget *label; GdkPixbuf *pixbuf; GtkWidget *action_btn; GSList *gslist = NULL; int *arg; fxst->dialog = gtk_dialog_new(); gtk_widget_set_usize(fxst->dialog , 350 , 280); gtk_window_set_title(GTK_WINDOW(fxst->dialog) , _("Settings Of Receving Message")); pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg", 20 , 20 ,NULL); gtk_window_set_icon(GTK_WINDOW(fxst->dialog) , pixbuf); g_object_unref(pixbuf); gtk_window_set_resizable(GTK_WINDOW(fxst->dialog) , FALSE); fixed = gtk_fixed_new(); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxst->dialog)->vbox) , fixed); label = gtk_label_new(_("You can set not to receive sms here , even\n" "for a period,in whitch you won`t receive the \n" "sms sent from fetion,but you can still receive \n" "the message from fetion client, the period will be:")); gtk_widget_set_usize(label , 320 , 0); gtk_fixed_put(GTK_FIXED(fixed) , label , 20 , 20); rbtn = gtk_radio_button_new_with_label(gslist , _("24 hours")); arg = (int*)malloc(sizeof(int)); (*arg) = 1; g_signal_connect(rbtn , "toggled" , G_CALLBACK(on_days_toggled) , arg); gtk_fixed_put(GTK_FIXED(fixed) , rbtn , 35 , 110); gslist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbtn)); rbtn = gtk_radio_button_new_with_label(gslist , _("3 days")); arg = (int*)malloc(sizeof(int)); (*arg) = 3; g_signal_connect(rbtn , "toggled" , G_CALLBACK(on_days_toggled) , arg); gtk_fixed_put(GTK_FIXED(fixed) , rbtn , 35 , 135); gslist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbtn)); rbtn = gtk_radio_button_new_with_label(gslist , _("1 week")); arg = (int*)malloc(sizeof(int)); (*arg) = 7; g_signal_connect(rbtn , "toggled" , G_CALLBACK(on_days_toggled) , arg); gtk_fixed_put(GTK_FIXED(fixed) , rbtn , 35 , 160); gslist = gtk_radio_button_get_group(GTK_RADIO_BUTTON(rbtn)); rbtn = gtk_radio_button_new_with_label(gslist , _("forever")); arg = (int*)malloc(sizeof(int)); (*arg) = 36500; /* 100 years , fuck it... */ g_signal_connect(rbtn , "toggled" , G_CALLBACK(on_days_toggled) , arg); gtk_fixed_put(GTK_FIXED(fixed) , rbtn , 35 , 185); action_btn = gtk_button_new_with_label(_("OK")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxst->dialog)->action_area) , action_btn); g_signal_connect(action_btn , "clicked" , G_CALLBACK(on_ok_clicked) , fxst); action_btn = gtk_button_new_with_label(_("Cancel")); gtk_box_pack_start_defaults(GTK_BOX(GTK_DIALOG(fxst->dialog)->action_area) , action_btn); g_signal_connect(action_btn , "clicked" , G_CALLBACK(on_cancel_clicked) , fxst); gtk_widget_show_all(fxst->dialog); } static void on_ok_clicked(GtkWidget *UNUSED(widget), gpointer data) { FxSmsstat *fxst = (FxSmsstat*)data; FxMain *fxmain = fxst->fxmain; User *user = fxmain->user; fetion_user_set_sms_status(user , global_days); gtk_dialog_response(GTK_DIALOG(fxst->dialog) , GTK_RESPONSE_OK); } static void on_cancel_clicked(GtkWidget *UNUSED(widget), gpointer data) { FxSmsstat *fxst = (FxSmsstat*)data; gtk_dialog_response(GTK_DIALOG(fxst->dialog) , GTK_RESPONSE_CANCEL); } static void on_days_toggled(GtkWidget *UNUSED(widget), gpointer data) { int *d = (int*)data; global_days = (*d); } openfetion-2.2.1/src/fx_smsstat.h0000644000175000017500000000464211561721144015505 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_SMSSTAT_H #define FX_SMSSTAT_H extern FxSmsstat *fx_smsstat_new(FxMain *fxmain); extern void fx_smsstat_initialize(FxSmsstat *fxst); #endif openfetion-2.2.1/src/fx_sound.c0000644000175000017500000000722711561721144015134 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" #ifdef USE_GSTREAMER #include #endif #ifdef USE_GSTREAMER static void add_pad (GstElement *element , GstPad *pad , gpointer data){ gchar *name; GstElement *sink = (GstElement*)data; name = gst_pad_get_name(pad); gst_element_link_pads(element , name , sink , "sink"); g_free(name); } #endif /* USE_GSTREAMER */ void fx_sound_play_file(const char *filename){ #ifdef USE_GSTREAMER GstElement *pipeline; GstElement *source , *parser , *sink; pipeline = gst_pipeline_new("audio-player"); source = gst_element_factory_make("filesrc" , "source"); if(source == NULL){ g_warning("make filesrc element failed"); return; } parser = gst_element_factory_make("wavparse" , "parser"); if(parser == NULL){ g_warning("make wavparse element failed"); return; } sink = gst_element_factory_make("alsasink" , "output"); if(sink == NULL){ g_warning("make alsasink element failed"); return; } g_object_set(G_OBJECT(source) , "location" , filename , NULL); gst_bin_add_many(GST_BIN(pipeline) , source , parser , sink , NULL); g_signal_connect(parser , "pad-added" , G_CALLBACK(add_pad) , sink); if(! gst_element_link(source , parser)){ g_warning("linke source to parser failed"); } gst_element_set_state(pipeline , GST_STATE_PLAYING); sleep(1); gst_element_set_state(pipeline , GST_STATE_NULL); g_object_unref(pipeline); #endif /* USE_GSTREAMER */ } openfetion-2.2.1/src/fx_sound.h0000644000175000017500000000460611561721144015137 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_SOUND_H #define FX_SOUND_H #include "fx_include.h" extern void fx_sound_play_file(const char *filename); #endif openfetion-2.2.1/src/fx_sysmsg.c0000644000175000017500000001150111561721144015317 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_sysmsg.h" FxSysmsg *fx_sysmsg_new() { FxSysmsg *sysmsg = (FxSysmsg*)malloc(sizeof(FxSysmsg)); return sysmsg; } static void fx_on_more_clicked(GtkWidget *UNUSED(widget) , gpointer data) { char *url = (char*)data; if(fork() == 0) { execlp("xdg-open" , "xdg-open" , url , NULL); free(url); return; } } static void fx_on_close_clicked(GtkWidget *UNUSED(widget) , gpointer data) { GtkWidget *dialog = (GtkWidget*)data; gtk_widget_destroy(dialog); } void fx_sysmsg_initialize(FxSysmsg *sysmsg) { GtkWidget *closeBtn; GtkBox *vbox , *action_area; GdkPixbuf *pb; sysmsg->dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); vbox = GTK_BOX(gtk_vbox_new (FALSE, 0)); gtk_container_add (GTK_CONTAINER(sysmsg->dialog), GTK_WIDGET(vbox)); pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg", 22 , 22 ,NULL); gtk_window_set_icon(GTK_WINDOW(sysmsg->dialog) , pb); g_object_unref(pb); gtk_window_set_title(GTK_WINDOW(sysmsg->dialog) , _("System mesage")); gtk_window_set_position(GTK_WINDOW(sysmsg->dialog) , GTK_WIN_POS_CENTER); gtk_widget_set_usize(GTK_WIDGET(sysmsg->dialog) , 400 , 250); gtk_window_set_resizable(GTK_WINDOW(sysmsg->dialog) , FALSE); sysmsg->textview = gtk_text_view_new(); gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(sysmsg->textview) , FALSE); gtk_text_view_set_editable(GTK_TEXT_VIEW(sysmsg->textview) , FALSE); gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(sysmsg->textview) , GTK_WRAP_CHAR); gtk_box_pack_start(vbox , sysmsg->textview, TRUE, TRUE, 0); action_area = GTK_BOX(gtk_hbox_new(FALSE , 0)); gtk_box_pack_start(GTK_BOX(vbox) , GTK_WIDGET(action_area) , FALSE , FALSE , 5); closeBtn = gtk_button_new_with_label(_("Close")); gtk_widget_set_usize(closeBtn, 100, 30); gtk_box_pack_end(action_area , closeBtn, FALSE, FALSE, 2); g_signal_connect(closeBtn , "clicked" , G_CALLBACK(fx_on_close_clicked) , sysmsg->dialog); sysmsg->moreBtn = gtk_button_new_with_label(_("View details")); gtk_widget_set_usize(sysmsg->moreBtn, 100, 30); gtk_box_pack_end(action_area , sysmsg->moreBtn, FALSE, FALSE, 2); gtk_widget_show_all(sysmsg->dialog); } void fx_sysmsg_bind(FxSysmsg *sysmsg , const char *msg , const char *url) { GtkTextBuffer *buffer ; GtkTextIter iter; char *pos; buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(sysmsg->textview)); gtk_text_buffer_get_end_iter(buffer , &iter); gtk_text_buffer_insert(buffer , &iter , msg , strlen(msg)); pos = (char*)malloc(strlen(url) + 1); memset(pos, 0, strlen(pos)); strcpy(pos , url); g_signal_connect(sysmsg->moreBtn , "clicked" , G_CALLBACK(fx_on_more_clicked) , pos); } openfetion-2.2.1/src/fx_sysmsg.h0000644000175000017500000000513211561721144015327 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_SYSMSG_H #define FX_SYSMSG_H #include "fx_include.h" typedef struct{ GtkWidget *dialog; GtkWidget *textview; GtkWidget *moreBtn; } FxSysmsg; extern FxSysmsg *fx_sysmsg_new(); extern void fx_sysmsg_initialize(FxSysmsg *sysmsg); extern void fx_sysmsg_bind(FxSysmsg *sysmsg , const char *msg , const char *url); #endif openfetion-2.2.1/src/fx_tree.c0000644000175000017500000021000411561721144014730 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" /*private*/ static GtkTreeModel* create_model(User* groupList); static void fx_tree_create_column(GtkWidget* tree , FxMain* fxmain); static void pg_text_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)); static GtkWidget* fx_tree_create_menu(const char* name , const char* iconpath , GtkWidget* parent , gboolean sensitive , void (*func)(GtkWidget* item , gpointer data) , gpointer data); //static void fx_tree_add_new_buddy(FxMain* fxmain , Contact* contact); /*signal function*/ static gboolean fx_tree_on_rightbutton_click(GtkWidget* UNUSED(tree) , GdkEventButton* event , gpointer data); static gboolean pg_on_rightbutton_click(GtkWidget* UNUSED(tree) , GdkEventButton* event , gpointer data); static void fx_tree_on_double_click(GtkTreeView *treeview , GtkTreePath *path , GtkTreeViewColumn *UNUSED(col) , gpointer data); static void pg_on_double_click(GtkTreeView *treeview , GtkTreePath *path , GtkTreeViewColumn *UNUSED(col) , gpointer data); static void fx_tree_on_chatmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_profilemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_historymenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_editmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_deletemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_remove_from_menu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_reload_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_iconchange_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_gaddmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_gdeletemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_geditmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_movemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static void fx_tree_on_copymenu_clicked(GtkWidget* UNUSED(widget) , gpointer data); static gboolean fx_tree_on_show_tooltip(GtkWidget* widget , int x , int y , gboolean keybord_mode , GtkTooltip* tip , gpointer data); static gboolean pg_on_show_tooltip(GtkWidget* widget , int x , int y , gboolean keybord_mode , GtkTooltip* tip , gpointer UNUSED(data)); static void on_send_message_clicked(GtkWidget *UNUSED(widget) , gpointer data); static void on_send_sms_clicked(GtkWidget *widget , gpointer data); static void on_view_pgdetail_clicked(GtkWidget *UNUSED(widget) , gpointer data); int all_light = 0; Args* fx_args_new(FxMain* fxmain , GtkTreeIter iter , const char* ss , int ii) { Args* args = (Args*)malloc(sizeof(Args)); memset(args , 0 , sizeof(args)); args->fxmain = fxmain; if(ss != NULL) strcpy(args->s , ss); args->i = ii; args->iter = iter; return args; } FxTree* fx_tree_new() { FxTree* fxtree = (FxTree*)malloc(sizeof(FxTree)); memset(fxtree , 0 , sizeof(FxTree)); return fxtree; } static void show_search(GtkEntry *entry , gpointer data) { FxMain *fxmain = (FxMain*)data; FxSearch *search = fx_search_new(fxmain); GtkTreeView *view = GTK_TREE_VIEW(fxmain->mainPanel->treeView); GtkTreeModel *model = gtk_tree_view_get_model(view); int x , y , ex , ey , root_x , root_y; const char *text; text = gtk_entry_get_text(entry); if(text == NULL || *text == '\0') return; if(has_gb(text)){ fx_util_popup_warning(fxmain , _("Only English words are allowed here!")); return; } gtk_widget_translate_coordinates(GTK_WIDGET(entry) , fxmain->window , 0 , 0 , &ex , &ey ); gtk_window_get_position(GTK_WINDOW(fxmain->window) , &root_x , &root_y); x = root_x + ex + 3; y = root_y + ey + 46; fx_search_initialize(search , model , text , x , y); } static void on_search_button_clicked(GtkEntry *entry , GtkEntryIconPosition *UNUSED(pos) , GdkEvent *UNUSED(event) , gpointer data) { show_search(entry , data); } static GtkTreeModel *create_pg_model() { GtkTreeStore *store = gtk_tree_store_new(PG_COL_NUM , GDK_TYPE_PIXBUF , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT); return GTK_TREE_MODEL(store); } static void create_pg_column(GtkWidget* tree) { GtkCellRenderer* renderer; GtkTreeViewColumn *col , *col0; renderer = gtk_cell_renderer_pixbuf_new(); col = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col, renderer , FALSE); gtk_tree_view_column_add_attribute(col, renderer, "pixbuf", B_PIXBUF_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col); renderer = gtk_cell_renderer_text_new(); col0 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col0, renderer , FALSE); gtk_tree_view_column_set_cell_data_func(col0 , renderer , pg_text_cell_data_func , NULL , NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col0); } static gboolean pg_on_show_tooltip(GtkWidget* widget , int x , int y , gboolean keybord_mode , GtkTooltip* tip , gpointer UNUSED(data)) { GtkTreeView *tree = GTK_TREE_VIEW(widget); GtkTreeModel *model = gtk_tree_view_get_model(tree); GdkPixbuf *pixbuf; GtkTreePath *path; GtkTreeIter iter; char text[1024]; char time[1024]; char *name; char *createTime; int identity; int currentMemberCount; int limitMemberCount; int groupRank; int maxRank; struct tm date; if(!gtk_tree_view_get_tooltip_context(tree , &x , &y , keybord_mode , &model , &path , &iter)){ return FALSE; } pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , 90 , 90 , NULL); gtk_tooltip_set_icon(tip , pixbuf); g_object_unref(pixbuf); gtk_tree_model_get(model , &iter , PG_NAME_COL , &name , PG_CREATETIME_COL , &createTime , PG_IDENTITY_COL , &identity , PG_CCOUNT_COL , ¤tMemberCount , PG_LCOUNT_COL , &limitMemberCount , PG_GRANK_COL , &groupRank , PG_MRANK_COL , &maxRank , -1); date = convert_date(createTime); strftime(time , sizeof(time) , _("%Y-%m-%d") , &date); free(createTime); snprintf(text , sizeof(text) - 1 , _("\nGroup Name:%s\t\n" "Current Member Count: %d\t\n" "Limit Member Count: %d\t\n" "Group Rank: %d/%d\t\n" "Create Time: %s\t\n") , g_markup_escape_text(name, -1) , currentMemberCount , limitMemberCount , groupRank , maxRank , time); gtk_tooltip_set_markup(tip , text); free(name); gtk_tree_view_set_tooltip_row(tree , tip , path); gtk_tree_path_free(path); return TRUE; } void fx_tree_bind_pg_data(FxMain *fxmain) { FxTree *fxtree = fxmain->mainPanel; Config *config = fxmain->user->config; PGGroup *pggroup = fxmain->user->pggroup; PGGroup *pgcur; GtkTreeView *tree = GTK_TREE_VIEW(fxtree->pgTreeView); GtkTreeModel *model = gtk_tree_view_get_model(tree); GtkTreeStore *store = GTK_TREE_STORE(model); GtkTreeIter iter; GtkTreeIter citer; GdkPixbuf *pixbuf; char portraitPath[1024]; char *uri; char *pgsid; int hasGroup = 0; foreach_grouplist(pggroup , pgcur){ hasGroup = 0; if(gtk_tree_model_get_iter_first(model , &citer)){ do{ gtk_tree_model_get(model , &citer , PG_URI_COL , &uri , -1); if(strcmp(pgcur->pguri , uri) == 0){ free(uri); hasGroup = 1; break; } }while(gtk_tree_model_iter_next(model , &citer)); } if(!hasGroup){ gtk_tree_store_append(store , &iter , NULL); pgsid = fetion_sip_get_pgid_by_sipuri(pgcur->pguri); snprintf(portraitPath , sizeof(portraitPath) - 1, "%s/PG%s.jpg" , config->iconPath , pgsid); free(pgsid); pixbuf = gdk_pixbuf_new_from_file_at_size(portraitPath , PG_PORTRAIT_SIZE , PG_PORTRAIT_SIZE , NULL); if(pixbuf == NULL){ if(pgcur->identity == 1) pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"online.svg" , PG_PORTRAIT_SIZE , PG_PORTRAIT_SIZE , NULL); else pixbuf = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"invisible.svg" , PG_PORTRAIT_SIZE , PG_PORTRAIT_SIZE , NULL); } gtk_tree_store_set(store , &iter , PG_PIXBUF_COL , pixbuf , -1); g_object_unref(pixbuf); } gtk_tree_store_set(store , (hasGroup == 1 ? &citer : &iter) , PG_URI_COL , pgcur->pguri , PG_NAME_COL , g_markup_escape_text(pgcur->name, -1) , PG_CREATETIME_COL , pgcur->createTime , PG_IDENTITY_COL , pgcur->identity , PG_CCOUNT_COL , pgcur->currentMemberCount , PG_LCOUNT_COL , pgcur->limitMemberCount , PG_GRANK_COL , pgcur->groupRank , PG_MRANK_COL , pgcur->maxRank , -1); } } void fx_tree_initilize(FxMain* fxmain) { GtkWidget* mainbox = fxmain->mainbox; FxTree* fxtree; GtkTreeModel* treeModel; ThreadArgs* args = (ThreadArgs*)malloc(sizeof(ThreadArgs)); args->fxmain = fxmain; args->sip = NULL; GValue value; memset(&value, 0, sizeof(value)); all_light = fxmain->user->config->allHighlight; fxtree = fxmain->mainPanel; fxtree->searchbox = gtk_entry_new(); g_value_init(&value, G_TYPE_STRING); g_value_set_static_string(&value, "gtk-im-context-simple"); g_object_set_property(G_OBJECT(fxtree->searchbox), "im-module", &value); g_value_unset (&value); gtk_entry_set_icon_from_stock(GTK_ENTRY(fxtree->searchbox) , GTK_ENTRY_ICON_SECONDARY , GTK_STOCK_FIND); g_signal_connect(fxtree->searchbox , "icon-press" , G_CALLBACK(on_search_button_clicked) , fxmain); g_signal_connect(fxtree->searchbox , "activate" , G_CALLBACK(show_search) , fxmain); gtk_widget_show_all(fxtree->searchbox); gtk_box_pack_start(GTK_BOX(mainbox) , fxtree->searchbox , FALSE , FALSE , 0); /* contact tree */ fxtree->scrollWindow = gtk_scrolled_window_new(NULL , NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxtree->scrollWindow) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); treeModel = create_model(fxmain->user); fxtree->treeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(treeModel)); gtk_widget_set_usize(fxtree->treeView , 100 , 0); g_object_set(fxtree->treeView , "has-tooltip" , TRUE , NULL); g_signal_connect(fxtree->treeView , "query-tooltip" , G_CALLBACK(fx_tree_on_show_tooltip) , fxmain); fx_tree_create_column(fxtree->treeView , fxmain); g_signal_connect(fxtree->treeView , "button_press_event" , G_CALLBACK(fx_tree_on_rightbutton_click) , fxmain); g_signal_connect(fxtree->treeView , "row-activated" , G_CALLBACK(fx_tree_on_double_click) , fxmain); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(fxtree->treeView) , FALSE); //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (fxtree->treeView), TRUE); gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(fxtree->treeView) , -30); gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(fxtree->treeView) , TRUE); gtk_container_set_border_width(GTK_CONTAINER(fxtree->scrollWindow) , 0); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(fxtree->scrollWindow) , fxtree->treeView); gtk_box_pack_start(GTK_BOX(mainbox) , fxtree->scrollWindow , TRUE , TRUE , 0); /* pg group */ fxtree->pgScrollWindow = gtk_scrolled_window_new(NULL , NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxtree->pgScrollWindow) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); treeModel = create_pg_model(); fxtree->pgTreeView = gtk_tree_view_new_with_model(GTK_TREE_MODEL(treeModel)); gtk_widget_set_usize(fxtree->pgTreeView , 100 , 0); g_object_set(fxtree->pgTreeView , "has-tooltip" , TRUE , NULL); g_signal_connect(fxtree->pgTreeView , "query-tooltip" , G_CALLBACK(pg_on_show_tooltip) , fxmain); create_pg_column(fxtree->pgTreeView); g_signal_connect(fxtree->pgTreeView , "button_press_event" , G_CALLBACK(pg_on_rightbutton_click) , fxmain); g_signal_connect(fxtree->pgTreeView , "row-activated" , G_CALLBACK(pg_on_double_click) , fxmain); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(fxtree->pgTreeView) , FALSE); //gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (fxtree->pgTreeView), TRUE); gtk_tree_view_set_level_indentation(GTK_TREE_VIEW(fxtree->pgTreeView) , -30); gtk_tree_view_set_hover_selection(GTK_TREE_VIEW(fxtree->pgTreeView) , TRUE); gtk_container_set_border_width(GTK_CONTAINER(fxtree->pgScrollWindow) , 0); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(fxtree->pgScrollWindow) , fxtree->pgTreeView); gtk_box_pack_start(GTK_BOX(mainbox) , fxtree->pgScrollWindow , TRUE , TRUE , 0); /* no group label */ fxtree->noLabelScrollWindow = gtk_scrolled_window_new(NULL , NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(fxtree->noLabelScrollWindow) , GTK_POLICY_NEVER , GTK_POLICY_AUTOMATIC); fxtree->noPgLabel = gtk_label_new(NULL); gtk_label_set_markup(GTK_LABEL(fxtree->noPgLabel) , _("No Group!")); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(fxtree->noLabelScrollWindow) , fxtree->noPgLabel); gtk_box_pack_start(GTK_BOX(mainbox) , fxtree->noLabelScrollWindow , TRUE , TRUE , 0); gtk_widget_set_name(fxtree->noLabelScrollWindow , "mainwindow"); if(fxmain->user->state != P_OFFLINE){ fetion_contact_subscribe_only(fxmain->user); g_thread_create(fx_main_listen_thread_func , args , FALSE , NULL); } } void fx_tree_show(FxMain *fxmain) { FxTree *fxtree = fxmain->mainPanel; gtk_widget_show_all(fxtree->scrollWindow); gtk_widget_show_all(fxtree->pgScrollWindow); gtk_widget_show_all(fxtree->noLabelScrollWindow); gtk_widget_hide(fxtree->pgScrollWindow); gtk_widget_hide(fxtree->noLabelScrollWindow); } void fx_tree_free(FxTree* fxtree) { free(fxtree); } void fx_tree_move_to_the_first(GtkTreeModel* model , GtkTreeIter* iter) { gtk_tree_store_move_after(GTK_TREE_STORE(model) , iter , NULL); } void fx_tree_move_to_the_last(GtkTreeModel* model , GtkTreeIter* iter) { gtk_tree_store_move_before(GTK_TREE_STORE(model) , iter , NULL); } static GtkTreeModel* create_model(User* user) { Group *group = NULL; Contact *contact; Config *config = NULL; GdkPixbuf *pb = NULL; GtkTreeStore *store = NULL; GtkTreeIter iter; GtkTreeIter iter1; gchar *sid = NULL; gchar *name; gchar path[1024]; gint count; gint count1; gint imageset = 0; group = user->groupList; config = user->config; store = gtk_tree_store_new(COL_NUM , GDK_TYPE_PIXBUF , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_STRING , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT , G_TYPE_INT); foreach_grouplist(user->groupList , group){ gtk_tree_store_append(store , &iter , NULL); gtk_tree_store_set(store , &iter , G_NAME_COL , _(group->groupname) , G_ID_COL , group->groupid , G_ALL_COUNT_COL , 0 , G_ONLINE_COUNT_COL , 0 , -1); } foreach_contactlist(user->contactList , contact){ if(strlen(contact->sId) == 0) sid = fetion_sip_get_sid_by_sipuri(contact->sipuri); snprintf(path, sizeof(path) - 1, "%s/%s.jpg", config->iconPath, strlen(contact->sId) == 0 ? sid : contact->sId); if(sid) { g_free(sid); sid = NULL; } foreach_groupids(contact->groupids) { if(fx_tree_get_group_iter_by_id(GTK_TREE_MODEL(store), group_id , &iter ) < 0){ //debug_info("Error when a group iter not found , groupId :%d\n" , contact->groupid); continue; } pb = gdk_pixbuf_new_from_file_at_size(path , config->iconSize , config->iconSize , NULL); if(!pb){ pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , config->iconSize , config->iconSize , NULL); imageset = 0; }else imageset = 1; if(contact->state > 0) gtk_tree_store_prepend(store , &iter1 , &iter); else gtk_tree_store_append(store , &iter1 , &iter); name = (contact->localname == NULL || strlen(contact->localname) == 0) ? contact->nickname : contact->localname; gtk_tree_store_set(store , &iter1 , B_PIXBUF_COL , pb , B_SIPURI_COL , contact->sipuri ? contact->sipuri : "" , B_USERID_COL , contact->userId ? contact->userId : "" , B_NAME_COL , name ? g_markup_escape_text(name, -1) : "" , B_IMPRESSION_COL , g_markup_escape_text(contact->impression, -1) , B_PHONENUM_COL , contact->mobileno , B_DEVICE_COL , contact->devicetype , B_CRC_COL , contact->portraitCrc , B_CARRIER_COL , contact->carrier , B_STATE_COL , contact->state , B_IDENTITY_COL , contact->identity , B_SERVICESTATUS_COL , contact->serviceStatus , B_CARRIERSTATUS_COL , contact->carrierStatus , B_RELATIONSTATUS_COL , contact->relationStatus , B_CARRIERSTATUS_COL , contact->carrier , B_SIZE_COL , config->iconSize , B_IMAGE_SET_COL , imageset , B_IMAGE_CHANGED_COL, contact->imageChanged , -1); g_object_unref(pb); gtk_tree_model_get(GTK_TREE_MODEL(store) , &iter , G_ALL_COUNT_COL , &count , G_ONLINE_COUNT_COL , &count1 , -1); count ++; if(contact->state > 0) count1 ++; gtk_tree_store_set(store , &iter , G_ALL_COUNT_COL , count , G_ONLINE_COUNT_COL , count1 , -1); } end_groupids(contact->groupids) } return GTK_TREE_MODEL(store); } int fx_tree_get_group_iter_by_id(GtkTreeModel* model , int id , GtkTreeIter* iter) { int idt; if(gtk_tree_model_get_iter_root(model , iter)){ do{ gtk_tree_model_get(model , iter , G_ID_COL , &idt , -1); if(idt == id) return 1; }while(gtk_tree_model_iter_next(model , iter)); } return -1; } gint fx_tree_get_buddy_iter(GtkTreeModel *model, gint groupid, const gchar *userid, GtkTreeIter *iter) { gchar *id = NULL; gint gid = 0; GtkTreeIter pos; if(gtk_tree_model_get_iter_root(model, &pos)){ do{ gtk_tree_model_get(model, &pos, G_ID_COL, &gid, -1); if(gid == groupid) { if(gtk_tree_model_iter_children(model, iter, &pos)){ do{ gtk_tree_model_get(model, iter, B_USERID_COL, &id, -1); if(!id) continue; if(strcmp(userid , id) == 0) return 1; }while(gtk_tree_model_iter_next(model , iter)); } break; } }while(gtk_tree_model_iter_next(model , &pos)); } return -1; } int fx_tree_get_buddy_iter_by_userid(GtkTreeModel* model , const char* userid , GtkTreeIter* iter) { char *id = NULL; GtkTreeIter pos; if(gtk_tree_model_get_iter_root(model , &pos)){ do{ if(gtk_tree_model_iter_children(model , iter , &pos)){ do{ gtk_tree_model_get(model , iter , B_USERID_COL , &id , -1); if(id == NULL) continue; if(strcmp(userid , id) == 0) return 1; }while(gtk_tree_model_iter_next(model , iter)); } }while(gtk_tree_model_iter_next(model , &pos)); } return -1; } static void fx_tree_on_hightlight_clicked(GtkWidget *UNUSED(widget) , gpointer data) { FxMain *fxmain = (FxMain*)data; User *user = fxmain->user; Config *config = user->config; if(all_light){ all_light = 0; config->allHighlight = 0; }else{ all_light = 1; config->allHighlight = 1; } fetion_config_save(user); } static void fx_tree_create_buddy_menu(FxMain* fxmain , GtkWidget* UNUSED(tree) , GtkTreePath* path , GdkEventButton* event , GtkTreeIter iter) { gchar *sipuri; gchar *groupname; gchar *userid; gchar *mobileno; gchar *carrier; GtkWidget *menu = NULL; GtkWidget *groupSubmenu = NULL; GtkWidget *moveItem = NULL; GtkWidget *copyItem = NULL; GtkTreeSelection *selection = NULL; GtkTreeModel *model = NULL; GtkTreeIter groupiter; Args *profileargs; Args *moveargs; Args *chatargs; gint groupid; gint iconsize; gint serviceStatus; gint relationStatus; gint carrierStatus; FxTree *fxtree = fxmain->mainPanel; User *user = fxmain->user; Config *config = user->config; menu = gtk_menu_new(); /*select row*/ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(fxtree->treeView)); if(gtk_tree_selection_count_selected_rows(selection) <= 1) { model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxtree->treeView)); gtk_tree_selection_unselect_all(selection); gtk_tree_selection_select_path(selection , path); gtk_tree_model_get(GTK_TREE_MODEL(model) , &iter , B_SIPURI_COL , &sipuri , B_PHONENUM_COL , &mobileno , B_USERID_COL , &userid , B_SERVICESTATUS_COL , &serviceStatus , B_RELATIONSTATUS_COL , &relationStatus , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_SIZE_COL , &iconsize , -1); profileargs = fx_args_new(fxmain , iter , userid , 0); chatargs = fx_args_new(fxmain , iter , sipuri , 0); fx_tree_create_menu(_("Send IM mesages") , SKIN_DIR"myselfsms.png" , menu , ((serviceStatus == BASIC_SERVICE_ABNORMAL && (carrierStatus == CARRIER_STATUS_CLOSED || (*carrier != '\0' && *mobileno == '\0'))) || relationStatus == RELATION_STATUS_UNAUTHENTICATED || user->state == P_OFFLINE) ? FALSE : TRUE , fx_tree_on_chatmenu_clicked , chatargs); fx_tree_create_menu(_("view contact's information") , SKIN_DIR"profile.png" , menu , (serviceStatus == BASIC_SERVICE_ABNORMAL && (carrierStatus == CARRIER_STATUS_CLOSED || (*carrier != '\0' && *mobileno == '\0'))) ? FALSE : TRUE , fx_tree_on_profilemenu_clicked , profileargs); #if 0 fx_tree_create_menu("FILE" , SKIN_DIR"sendfile.png" , menu , TRUE , fx_tree_on_sendfile_clicked , profileargs); #endif fx_tree_create_menu(_("View chat logs") , SKIN_DIR"history.png" , menu , TRUE , fx_tree_on_historymenu_clicked , profileargs); if(user->state != P_OFFLINE) fx_tree_create_menu(_("Refresh information") , SKIN_DIR"refresh.png" , menu , TRUE , fx_tree_on_reload_clicked , profileargs); if(user->state != P_OFFLINE) fx_tree_create_menu(_("Edit note name") , SKIN_DIR"edit.png" , menu , TRUE , fx_tree_on_editmenu_clicked , profileargs); fx_tree_create_menu( config->allHighlight ? _("Hightlight online contacts") : _("Hightlight all contacts") , SKIN_DIR"hilight.png" , menu , TRUE , fx_tree_on_hightlight_clicked , fxmain); fx_tree_create_menu(iconsize > 30 ? _("Use small icon") : _("Use big icon") , SKIN_DIR"bigimage.png" , menu , TRUE , fx_tree_on_iconchange_clicked , fxmain); if(user->state != P_OFFLINE) fx_tree_create_menu(_("Remove this contact") , SKIN_DIR"delete.png" , menu , TRUE , fx_tree_on_deletemenu_clicked , profileargs); Contact *cnt = fetion_contact_list_find_by_userid(user->contactList, userid); if(user->state != P_OFFLINE) { if(cnt && strchr(cnt->groupids, ';') && cnt->groupids[strlen(cnt->groupids) - 1] != ';') fx_tree_create_menu(_("Remove from group"), SKIN_DIR"delete.png", menu, TRUE, fx_tree_on_remove_from_menu_clicked, profileargs); else fx_tree_create_menu(_("Remove from group"), SKIN_DIR"delete.png", menu, FALSE, fx_tree_on_remove_from_menu_clicked, profileargs); } gtk_tree_model_iter_parent(model , &groupiter , &iter); gtk_tree_model_get(model , &groupiter , G_ID_COL , &groupid , -1); groupSubmenu = gtk_menu_new(); if(groupid != BUDDY_LIST_STRANGER && user->state != P_OFFLINE) { moveItem = fx_tree_create_menu(_("Move this contact to") , SKIN_DIR"move.png" , menu , TRUE , NULL , NULL); /*add group child menu*/ gtk_tree_model_get_iter_root(GTK_TREE_MODEL(model) , &groupiter); do { gtk_tree_model_get(GTK_TREE_MODEL(model) , &groupiter , G_NAME_COL , &groupname , G_ID_COL , &groupid , -1); gchar gs[24] = { 0, }; sprintf(gs, "%d", groupid); if(!strstr(cnt->groupids, gs)) { moveargs = fx_args_new(fxmain , iter , userid , groupid); fx_tree_create_menu(groupname , SKIN_DIR"online.svg" , groupSubmenu , TRUE , fx_tree_on_movemenu_clicked , moveargs); } free(groupname); } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(model) , &groupiter)); gtk_menu_item_set_submenu(GTK_MENU_ITEM(moveItem) , groupSubmenu); } groupSubmenu = gtk_menu_new(); if(groupid != BUDDY_LIST_STRANGER && user->state != P_OFFLINE) { copyItem = fx_tree_create_menu(_("Copy this contact to") , SKIN_DIR"move.png" , menu , TRUE , NULL , NULL); /*add group child menu*/ gtk_tree_model_get_iter_root(GTK_TREE_MODEL(model) , &groupiter); do { gtk_tree_model_get(GTK_TREE_MODEL(model) , &groupiter , G_NAME_COL , &groupname , G_ID_COL , &groupid , -1); gchar gs[24] = { 0, }; sprintf(gs, "%d", groupid); if(!strstr(cnt->groupids, gs)) { moveargs = fx_args_new(fxmain, iter, userid, groupid); fx_tree_create_menu(groupname , SKIN_DIR"online.svg" , groupSubmenu , TRUE , fx_tree_on_copymenu_clicked , moveargs); } free(groupname); } while(gtk_tree_model_iter_next(GTK_TREE_MODEL(model) , &groupiter)); gtk_menu_item_set_submenu(GTK_MENU_ITEM(copyItem) , groupSubmenu); } } gtk_widget_show_all(menu); g_free(userid); g_free(sipuri); g_free(mobileno); g_free(carrier); gtk_menu_popup(GTK_MENU(menu) , NULL , NULL , NULL , NULL , (event != NULL) ? event->button : 0 , gdk_event_get_time((GdkEvent*)event)); } static void fx_tree_create_group_menu(FxMain* fxmain , GtkWidget* tree , GdkEventButton* event , GtkTreeIter iter) { GtkWidget* menu = NULL; Args* args = fx_args_new(fxmain , iter , NULL , 0); int count , groupid; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree)); menu = gtk_menu_new(); gtk_tree_model_get(model , &iter , G_ALL_COUNT_COL , &count , G_ID_COL , &groupid , -1); fx_tree_create_menu(_("Add a new group") , SKIN_DIR"myselfsms.png" , menu , TRUE , fx_tree_on_gaddmenu_clicked , fxmain); fx_tree_create_menu(_("Edit name of a group") , SKIN_DIR"edit.png" , menu , (groupid == BUDDY_LIST_NOT_GROUPED || groupid == BUDDY_LIST_STRANGER) ? FALSE : TRUE , fx_tree_on_geditmenu_clicked , args); fx_tree_create_menu(_("Remove this group") , SKIN_DIR"delete.png" , menu , (count == 0 && groupid != BUDDY_LIST_NOT_GROUPED && groupid != BUDDY_LIST_STRANGER) ? TRUE : FALSE , fx_tree_on_gdeletemenu_clicked , args); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu) , NULL , NULL , NULL , NULL , (event != NULL) ? event->button : 0 , gdk_event_get_time((GdkEvent*)event)); } static GtkWidget* fx_tree_create_menu(const char* name , const char* iconpath , GtkWidget* parent , gboolean sensitive , void (*func)(GtkWidget* item , gpointer data) , gpointer data) { GtkWidget *item = gtk_image_menu_item_new_with_label(name); GdkPixbuf *pb = gdk_pixbuf_new_from_file_at_size(iconpath , 16 , 16 , NULL); GtkWidget *img = gtk_image_new_from_pixbuf(pb); g_object_unref(pb); gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(item) , img); gtk_menu_shell_append(GTK_MENU_SHELL(parent) , item); if(sensitive == FALSE) { gtk_widget_set_sensitive(item , FALSE); return item; } if(func != NULL) g_signal_connect(item , "activate" , G_CALLBACK(func) , data); return item; } #if 0 static void fx_tree_add_new_buddy(FxMain* fxmain , Contact* contact) { GtkTreeView *tree = GTK_TREE_VIEW(fxmain->mainPanel->treeView); GtkTreeModel *model = gtk_tree_view_get_model(tree); GtkTreeIter oIter , nIter; GdkPixbuf *pb = NULL; Config *config = fxmain->user->config; int groupid; gtk_tree_model_get_iter_root(model , &oIter); do { gtk_tree_model_get(model , &oIter , G_ID_COL , &groupid , -1); if(groupid == contact->groupid) { pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , config->iconSize , config->iconSize , NULL); gtk_tree_store_append(GTK_TREE_STORE(model) , &nIter , &oIter); gtk_tree_store_set(GTK_TREE_STORE(model), &nIter , B_PIXBUF_COL , pb , B_NAME_COL , contact->localname , B_SIPURI_COL , contact->sipuri , B_USERID_COL , contact->userId , B_SERVICESTATUS_COL , contact->serviceStatus , B_RELATIONSTATUS_COL , contact->relationStatus , B_CARRIERSTATUS_COL , contact->carrierStatus , B_CARRIER_COL , "CMCC" , -1); } } while(gtk_tree_model_iter_next(model , &oIter)); } #endif static void fx_tree_pixbuf_cell_data_func(GtkTreeViewColumn *UNUSED(col) , GtkCellRenderer *renderer , GtkTreeModel *model , GtkTreeIter *iter , gpointer UNUSED(user_data)) { int state; GtkTreePath* path = gtk_tree_model_get_path(model , iter); if(gtk_tree_path_get_depth(path) > 1) { gtk_tree_model_get(model , iter , B_STATE_COL , &state , -1); g_object_set(renderer , "visible" , TRUE , NULL); g_object_set(renderer , "sensitive" , all_light ? TRUE : (state > 0 ? TRUE : FALSE) , NULL); } else { g_object_set(renderer , "visible" , FALSE , NULL); } gtk_tree_path_free(path); } static void fx_tree_text_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)) { GtkTreePath* path = gtk_tree_model_get_path(model , iter); char text[2048]; /*contact data*/ char *name , *impression , *sipuri , *sid , *stateStr , *mobileno , *device , *carrier; char stateStr1[1024]; char statusStr[1024]; int presence, size; int carrierStatus , relationStatus , serviceStatus; /*buddylist data*/ int allCount , onlineCount; char* buddylistName = NULL; /* render friend list text*/ if(gtk_tree_path_get_depth(path) > 1) { memset(text, 0, sizeof(text)); gtk_tree_model_get(model , iter , B_NAME_COL , &name , B_SIPURI_COL , &sipuri , B_STATE_COL , &presence , B_IMPRESSION_COL , &impression , B_PHONENUM_COL , &mobileno , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , B_SERVICESTATUS_COL , &serviceStatus , B_SIZE_COL , &size , B_DEVICE_COL , &device , -1); stateStr = fx_util_get_state_name(presence); memset(statusStr, 0, sizeof(statusStr)); if(relationStatus == RELATION_STATUS_UNAUTHENTICATED){ snprintf(statusStr , sizeof(statusStr) - 1 , _("[Unverified]")); }else if(serviceStatus == BASIC_SERVICE_ABNORMAL){ if(carrierStatus == CARRIER_STATUS_CLOSED){ snprintf(statusStr , sizeof(statusStr) - 1, _("[Has shut fetion service]")); }else{ if(carrier != NULL || strlen(carrier) != 0){ snprintf(statusStr , sizeof(statusStr) - 1, _("[Online with SMS]")); if(mobileno == NULL || *mobileno == '\0'){ snprintf(statusStr , sizeof(statusStr) - 1, _("[Has shut fetion service]")); } }else{ snprintf(statusStr , sizeof(statusStr) - 1, _("[Has shut fetion service]")); } } }else if(carrierStatus == CARRIER_STATUS_DOWN){ if(*carrier != '\0'){ snprintf(statusStr , sizeof(statusStr) - 1, _("[Out of service]")); } } if(sipuri == NULL){ printf("NULL\n"); return; } sid = fetion_sip_get_sid_by_sipuri(sipuri); snprintf(stateStr1 , sizeof(stateStr1) - 1, "%s" , stateStr); escape_impression(impression); char newline[3] = ""; if(size >= 30) sprintf(newline, "\n"); snprintf(text , sizeof(text) - 1 , "%s%s%s" "(%s) %s %s" , name == NULL ? "" : name , (*statusStr == '\0' ? (presence == 0 ? "" : stateStr1) : statusStr) , (device != NULL && strcmp(device , "PC") != 0) ? _("[Login with cell phone]") : "", sid, newline , impression == NULL ? "" : impression); g_object_set(renderer, "markup", text, NULL); free(name); free(stateStr); free(impression); free(sipuri); free(mobileno); free(sid); free(device); free(carrier); } /*render group list text*/ else { memset(text, 0, sizeof(text)); gtk_tree_model_get(model , iter , G_NAME_COL , &buddylistName , G_ALL_COUNT_COL , &allCount , G_ONLINE_COUNT_COL , &onlineCount ,-1); snprintf(text , sizeof(text) - 1 , "%s [%d/%d]" , buddylistName , onlineCount , allCount ); g_object_set(renderer , "text" , text , NULL); free(buddylistName); } gtk_tree_path_free(path); } static void pg_text_cell_data_func(GtkTreeViewColumn *UNUSED(col), GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer UNUSED(user_data)) { char *name; int identity; int currentMemberCount; int limitMemberCount; char *createTime; struct tm date; char time[1024]; char text[1024]; gtk_tree_model_get(model , iter , PG_NAME_COL , &name , PG_IDENTITY_COL , &identity , PG_CCOUNT_COL , ¤tMemberCount , PG_LCOUNT_COL , &limitMemberCount , PG_CREATETIME_COL , &createTime , -1); if(createTime != NULL && strlen(createTime) != 0){ date = convert_date(createTime); strftime(time , sizeof(time) , _("%Y-%m-%d") , &date); snprintf(text , sizeof(text) - 1, _("%s\nCreate Time: %s") , g_markup_escape_text(name , strlen(name)) , time); g_object_set(renderer , "markup" , text , NULL); free(createTime); } free(name); } static void fx_tree_create_column(GtkWidget* tree , FxMain* fxmain) { GtkCellRenderer* renderer; GtkTreeViewColumn *col , *col0; renderer = gtk_cell_renderer_pixbuf_new(); col = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col, renderer , FALSE); gtk_tree_view_column_add_attribute(col, renderer, "pixbuf", B_PIXBUF_COL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col); gtk_tree_view_column_set_cell_data_func(col , renderer , fx_tree_pixbuf_cell_data_func , fxmain , NULL); renderer = gtk_cell_renderer_text_new(); col0 = gtk_tree_view_column_new(); gtk_tree_view_column_pack_start(col0, renderer , FALSE); gtk_tree_view_column_set_cell_data_func(col0 , renderer , fx_tree_text_cell_data_func , NULL , NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(tree), col0); } void fx_tree_update_portrait(FxMain *fxmain) { GtkTreeModel *model; GtkTreeIter iter; GtkTreeIter pos; GdkPixbuf *pb; User *user = fxmain->user; Config *config = user->config; gchar *sipuri; gchar *crc; gchar *sid; gchar portraitPath[1024]; gint size; gint imageChanged; gint imageset; gint nr = 0; debug_info("updating portrait..."); model = gtk_tree_view_get_model( GTK_TREE_VIEW(fxmain->mainPanel->treeView)); gtk_tree_model_get_iter_root(model , &iter); do{ if(gtk_tree_model_iter_children(model , &pos , &iter)){ do{ gtk_tree_model_get(model , &pos, B_SIPURI_COL, &sipuri, B_CRC_COL, &crc, B_SIZE_COL, &size, B_IMAGE_CHANGED_COL, &imageChanged, B_IMAGE_SET_COL, &imageset, -1); /* if image has been set and no changes,then do nothing */ if(imageset && !imageChanged){ g_free(sipuri); g_free(crc); continue; } /* if image has not been set,but this buddy has no imaeg, * then also do nothing */ if(!imageset && strcmp(crc, "0") == 0){ g_free(sipuri); g_free(crc); continue; } sid = fetion_sip_get_sid_by_sipuri(sipuri); snprintf(portraitPath, sizeof(portraitPath) - 1, "%s/%s.jpg" , config->iconPath , sid); /* download portrait */ fetion_user_download_portrait(user , sipuri); pb = gdk_pixbuf_new_from_file_at_size(portraitPath, size , size , NULL); if(pb){ nr ++; gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model), &pos , B_PIXBUF_COL , pb , -1); g_object_unref(pb); gdk_threads_leave(); } gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model), &pos, B_IMAGE_CHANGED_COL , IMAGE_NOT_CHANGED, B_IMAGE_SET_COL, 1,-1); gdk_threads_leave(); g_free(sipuri); g_free(sid); } while(gtk_tree_model_iter_next(model , &pos)); } } while(gtk_tree_model_iter_next(model , &iter)); /* update pggroup portrait */ gchar pgPortraitServer[1024]; gchar pgPortraitPath[1024]; gchar *strcur; gchar *pgsid; PGGroup *pgcur; gint n; model = gtk_tree_view_get_model( GTK_TREE_VIEW(fxmain->mainPanel->pgTreeView)); if(gtk_tree_model_get_iter_root(model , &iter)){ do{ gtk_tree_model_get(model , &iter , PG_URI_COL , &sipuri , -1); pgsid = fetion_sip_get_pgid_by_sipuri(sipuri); snprintf(portraitPath, sizeof(portraitPath) - 1, "%s/PG%s.jpg", config->iconPath , pgsid); pb = gdk_pixbuf_new_from_file_at_size(portraitPath, PG_PORTRAIT_SIZE , PG_PORTRAIT_SIZE , NULL); if(pb == NULL){ foreach_pg_group(user->pggroup , pgcur){ if(strcmp(pgcur->pguri , sipuri) == 0) break; } strcur = pgcur->getProtraitUri; if(strstr(strcur , "http://") != NULL) strcur = strstr(strcur , "http://") + 7; n = strlen(strcur) - strlen(strstr(strcur , "/")); if(n == 0) continue; strncpy(pgPortraitServer , strcur , n); strcur = strstr(strcur , "/"); strcpy(pgPortraitPath , strcur); /* download portrait */ fetion_user_download_portrait_with_uri(user, sipuri , pgPortraitServer , pgPortraitPath); pb = gdk_pixbuf_new_from_file_at_size(portraitPath , PG_PORTRAIT_SIZE , PG_PORTRAIT_SIZE , NULL); if(pb != NULL){ gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , PG_PIXBUF_COL , pb , -1); g_object_unref(pb); gdk_threads_leave(); } }else{ g_object_unref(pb); } g_free(sipuri); g_free(pgsid); }while(gtk_tree_model_iter_next(model , &iter)); } debug_info("%d portrait was successfully updated", nr); } static void fx_tree_on_double_click(GtkTreeView *treeview , GtkTreePath *path , GtkTreeViewColumn *UNUSED(col) , gpointer data) { FxMain *fxmain = (FxMain*)data; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); GtkTreeIter iter; gtk_tree_model_get_iter(model , &iter , path); gint depth = gtk_tree_path_get_depth(path); gchar *sipuri , *mobileno , *carrier; gint serviceStatus , relationStatus , carrierStatus; FxList *mlist; FxList *cur; FxList *tmp; FxChat *fxchat; Message *msg; mlist = fxmain->mlist; cur = mlist->pre; if(depth > 1){ if(!fx_conn_check_action(fxmain)) return; gtk_tree_model_get(model , &iter , B_SIPURI_COL , &sipuri , B_PHONENUM_COL , &mobileno , B_SERVICESTATUS_COL , &serviceStatus , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , -1); if(relationStatus == RELATION_STATUS_UNAUTHENTICATED) { fx_util_popup_warning(fxmain , _("You can not send a message to anyone who has not been in your contact list")); return; } if(serviceStatus == BASIC_SERVICE_ABNORMAL && (carrierStatus == CARRIER_STATUS_CLOSED || (*carrier != '\0' && *mobileno == '\0'))) { fx_util_popup_warning(fxmain , _("This user have shut fetion service,so you cannot send mesage to him/her")); return; } while(cur != fxmain->mlist){ msg = (Message*)(cur->data); /* ordinary message */ if(!msg->pguri && strcmp(sipuri, msg->sipuri) == 0){ fxchat = fx_main_create_chat_window(fxmain , msg->sipuri); if(!fxchat){ g_print("Unknow Message\n"); g_print("%s:%s\n" , msg->sipuri , msg->message); continue; } fx_chat_add_message(fxchat , msg->message, &(msg->sendtime) , 0 , msg->sysback); fetion_message_free(msg); tmp = cur; cur = cur->pre; fx_list_remove(tmp); g_free(tmp); }else{ cur = cur->pre; } } fx_main_create_chat_window(fxmain , sipuri); g_free(sipuri); g_free(mobileno); g_free(carrier); } } static gboolean fx_tree_on_rightbutton_click(GtkWidget* UNUSED(tree) , GdkEventButton* event , gpointer data) { GtkTreeIter iter; GtkTreePath *path = NULL; GtkTreeModel *model = NULL; FxMain *fxmain = NULL; FxTree *fxtree = NULL; if(event->type == GDK_BUTTON_PRESS) { int depth; fxmain = (FxMain*)data; fxtree = fxmain->mainPanel; model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxtree->treeView)); gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(fxtree->treeView) , (gint)event->x , (gint)event->y , &path , NULL , NULL , NULL); if(path == NULL) return FALSE; if(!gtk_tree_model_get_iter(GTK_TREE_MODEL(model) , &iter , path)) return FALSE; depth = gtk_tree_path_get_depth(path); if(event->button == 3){ if(depth == 2) fx_tree_create_buddy_menu(fxmain , fxtree->treeView , path , event , iter); else fx_tree_create_group_menu(fxmain , fxtree->treeView , event , iter); gtk_tree_path_free(path); return TRUE; }else if(event->button == 1){ if(depth == 2) return FALSE; if(gtk_tree_view_row_expanded(GTK_TREE_VIEW(fxtree->treeView) , path)) gtk_tree_view_collapse_row(GTK_TREE_VIEW(fxtree->treeView) , path); else gtk_tree_view_expand_row(GTK_TREE_VIEW(fxtree->treeView) , path , TRUE); return TRUE; } } return FALSE; } static void fx_tree_on_chatmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; FxMain *fxmain = args->fxmain; gchar *sipuri = args->s; fx_main_create_chat_window(fxmain , sipuri); free(args); } static void* update_contact_info(void *data) { FxProfile *fxprofile = (FxProfile*)data; gchar *res; Contact *contact = fetion_contact_get_contact_info( fxprofile->fxmain->user, fxprofile->userid); gdk_threads_enter(); res = fetion_config_get_province_name(contact->province); gtk_entry_set_text(GTK_ENTRY(fxprofile->province_entry) , res == NULL ? _("Unknown") : res); update(); free(res); res = fetion_config_get_city_name(contact->province , contact->city); gtk_entry_set_text(GTK_ENTRY(fxprofile->city_entry) , res == NULL ? _("Unknown") : res); update(); free(res); gdk_threads_leave(); return NULL; } static void fx_tree_on_profilemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; FxMain *fxmain = args->fxmain; Contact *contact; gchar *userid = args->s; FxProfile *fxprofile; fxprofile = fx_profile_new(fxmain , userid); fx_profile_initialize(fxprofile); contact = fx_profile_fetch(fxprofile); if(contact){ fx_profile_bind(fxprofile , contact); if(strlen(contact->province) == 0 && fxmain->user->state != P_OFFLINE) g_thread_create(update_contact_info, fxprofile, FALSE, NULL); } gtk_dialog_run(GTK_DIALOG(fxprofile->dialog)); gtk_widget_destroy(fxprofile->dialog); g_free(fxprofile); g_free(args); } static void fx_tree_on_historymenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; FxMain *fxmain = args->fxmain; GtkTreeIter iter = args->iter; gchar *name = NULL; gchar *userid = args->s; FxHistory *fxhistory = NULL; GtkWidget* tree = fxmain->mainPanel->treeView; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree)); gtk_tree_model_get(model , &iter , B_NAME_COL , &name , -1); fxhistory = fx_history_new(fxmain , userid , name); fx_history_initialize(fxhistory); gtk_dialog_run(GTK_DIALOG(fxhistory->dialog)); gtk_widget_destroy(fxhistory->dialog); g_free(fxhistory); g_free(args); } static void fx_tree_on_editmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; FxMain *fxmain = args->fxmain; gchar *userid = args->s; gint ret; FxEdit *fxedit; if(!fx_conn_check_action(fxmain)) return; fxedit = fx_edit_new(fxmain , args->iter , userid); fx_edit_initialize(fxedit); ret = gtk_dialog_run(GTK_DIALOG(fxedit->dialog)); gtk_widget_destroy(fxedit->dialog); g_free(fxedit); g_free(args); } static void fx_tree_on_remove_from_menu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; FxMain *fxmain = args->fxmain; gchar *userid = args->s; GtkTreeIter iter = args->iter; GtkTreeIter parent; GtkTreeModel *model; gint gid, state, onCnt, allCnt; if(!fx_conn_check_action(fxmain)) return; model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxmain->mainPanel->treeView)); if(gtk_tree_model_iter_parent(model, &parent, &iter)) { gtk_tree_model_get(model, &parent, G_ID_COL, &gid, G_ONLINE_COUNT_COL, &onCnt, G_ALL_COUNT_COL, &allCnt, -1); gtk_tree_model_get(model, &iter, B_STATE_COL, &state, -1); if(fetion_contact_remove_from_group(fxmain->user, userid, gid) == -1) return; if(state > 0) onCnt --; gtk_tree_store_set(GTK_TREE_STORE(model), &parent, G_ONLINE_COUNT_COL, onCnt, G_ALL_COUNT_COL, allCnt - 1, -1); gtk_tree_store_remove(GTK_TREE_STORE(model), &iter); } g_free(args); } static void fx_tree_on_deletemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; FxMain *fxmain = args->fxmain; gchar *userid = args->s; GtkTreeIter iter = args->iter; GtkTreeIter parent; Contact *cnt; GtkWidget *dialog; GtkTreeModel *model; gint ocnt, acnt, state; if(!fx_conn_check_action(fxmain)) return; model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxmain->mainPanel->treeView)); dialog = gtk_message_dialog_new(GTK_WINDOW(fxmain->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Remove this contact?")); gtk_window_set_title(GTK_WINDOW(dialog), _("Remove contact")); gint result = gtk_dialog_run(GTK_DIALOG(dialog)); if(result == GTK_RESPONSE_YES){ if (fetion_contact_delete_buddy(fxmain->user , userid) != -1) { cnt = fetion_contact_list_find_by_userid(fxmain->user->contactList, userid); foreach_groupids(cnt->groupids) { if(fx_tree_get_buddy_iter(model, group_id, userid, &iter) != -1) { if(gtk_tree_model_iter_parent(model, &parent, &iter)) { gtk_tree_model_get(model, &parent, G_ONLINE_COUNT_COL, &ocnt, G_ALL_COUNT_COL, &acnt, -1); gtk_tree_model_get(model, &iter, B_STATE_COL, &state, -1); if(state > 0) ocnt --; gtk_tree_store_set(GTK_TREE_STORE(model), &parent, G_ONLINE_COUNT_COL, ocnt, G_ALL_COUNT_COL, acnt - 1, -1); } gtk_tree_store_remove(GTK_TREE_STORE(model) , &iter); } } end_groupids(cnt->groupids) fetion_contact_list_remove_by_userid(fxmain->user->contactList, userid); } } g_free(args); gtk_widget_destroy(dialog); } static void* fx_tree_reload_thread(void* data) { Args *args = (Args*)data; FxMain *fxmain = args->fxmain; GtkTreeIter iter = args->iter; GtkTreeView *tree = GTK_TREE_VIEW(fxmain->mainPanel->treeView); GtkTreeModel *model = gtk_tree_view_get_model(tree); gchar *userid = NULL; gchar *sipuri = NULL; gchar *sid = NULL; gchar *name = NULL; gchar portraitPath[1024]; GdkPixbuf *pb = NULL; Contact *contact = NULL; Config *config = fxmain->user->config; gtk_tree_model_get(model , &iter , B_USERID_COL , &userid , B_SIPURI_COL , &sipuri , -1); contact = fetion_contact_get_contact_info(fxmain->user , userid); debug_info("Updating information of user %s" , userid); g_free(userid); fetion_user_download_portrait(fxmain->user , sipuri); sid = fetion_sip_get_sid_by_sipuri(sipuri); g_free(sipuri); snprintf(portraitPath , sizeof(portraitPath) - 1, "%s/%s.jpg" , config->iconPath , sid); pb = gdk_pixbuf_new_from_file_at_size(portraitPath , 25 , 25 , NULL); if(pb == NULL) pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"fetion.svg" , 25 , 25 , NULL); name = (contact->localname == NULL || strlen(contact->localname) == 0) ? contact->nickname : contact->localname; gdk_threads_enter(); gtk_tree_store_set(GTK_TREE_STORE(model) , &iter , B_PIXBUF_COL , pb , B_SIPURI_COL , contact->sipuri , B_USERID_COL , contact->userId , B_NAME_COL , g_markup_escape_text(name, -1) , B_IMPRESSION_COL , g_markup_escape_text(contact->impression, -1) , B_PHONENUM_COL , contact->mobileno , B_DEVICE_COL , contact->devicetype , B_CRC_COL , contact->portraitCrc , B_IDENTITY_COL , contact->identity , -1); gdk_threads_leave(); g_object_unref(pb); return NULL; } static void fx_tree_on_reload_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain *fxmain = ((Args*)data)->fxmain; if(!fx_conn_check_action(fxmain)) return; g_thread_create(fx_tree_reload_thread , data , FALSE , NULL); } static void fx_tree_on_iconchange_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain *fxmain = (FxMain*)data; FxTree *fxtree = fxmain->mainPanel; Config *config = fxmain->user->config; GtkTreeView* tree = GTK_TREE_VIEW(fxtree->treeView); GtkTreeModel* model = gtk_tree_view_get_model(tree); GtkTreeIter iter; GtkTreeIter pointer; GdkPixbuf* pb = NULL; char *sipuri = NULL; char *sid = NULL; char path[128]; gtk_tree_model_get_iter_root(model , &iter); if(config->iconSize > 30) { config->iconSize = 25; fetion_config_save(fxmain->user); debug_info("Changed to use small icon , size : 25px"); } else { config->iconSize = 40; fetion_config_save(fxmain->user); debug_info("Changed to use large icon , size : 50px"); } do { if(gtk_tree_model_iter_children(model , &pointer , &iter)) { do { if(config->iconSize < 30) { gtk_tree_model_get(model , &pointer , B_PIXBUF_COL , &pb , -1); } else { gtk_tree_model_get(model , &pointer , B_SIPURI_COL , &sipuri , -1); sid = fetion_sip_get_sid_by_sipuri(sipuri); snprintf(path , sizeof(path) - 1, "%s/%s.jpg" , config->iconPath , sid); free(sid); pb = gdk_pixbuf_new_from_file(path , NULL); if(pb == NULL) pb = gdk_pixbuf_new_from_file(SKIN_DIR"fetion.svg" , NULL); } pb = gdk_pixbuf_scale_simple(pb , config->iconSize , config->iconSize , GDK_INTERP_NEAREST); gtk_tree_store_set(GTK_TREE_STORE(model) , &pointer , B_PIXBUF_COL , pb , B_SIZE_COL , config->iconSize , -1); g_object_unref(pb); } while(gtk_tree_model_iter_next(model , &pointer)); } } while(gtk_tree_model_iter_next(model , &iter)); } static void fx_tree_on_gaddmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { FxMain* fxmain = (FxMain*)data; FxAddGroup* fxaddgroup = fx_add_group_new(fxmain); fx_add_group_initialize(fxaddgroup); gtk_dialog_run(GTK_DIALOG(fxaddgroup->dialog)); gtk_widget_destroy(fxaddgroup->dialog); fx_add_group_free(fxaddgroup); } static void fx_tree_on_gdeletemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args* args = (Args*)data; FxMain* fxmain = args->fxmain; GtkWidget* tree = fxmain->mainPanel->treeView; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree)); int groupid; GtkWidget *dialog = NULL; gtk_tree_model_get(model , &(args->iter) , G_ID_COL , &groupid , -1); dialog = gtk_message_dialog_new(GTK_WINDOW(fxmain->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("Remove this group?")); gtk_window_set_title(GTK_WINDOW(dialog), _("Remove group")); int result = gtk_dialog_run(GTK_DIALOG(dialog)); if(result == GTK_RESPONSE_YES) { if(fetion_buddylist_delete(fxmain->user , groupid) != -1) { gtk_tree_store_remove(GTK_TREE_STORE(model) , &args->iter); } } free(args); gtk_widget_destroy(dialog); } static void fx_tree_on_geditmenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args* args = (Args*)data; FxMain* fxmain = args->fxmain; GtkWidget* tree = fxmain->mainPanel->treeView; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree)); int groupid; FxGEdit* fxgedit = NULL; gtk_tree_model_get(model , &(args->iter) , G_ID_COL , &groupid , -1); fxgedit = fx_gedit_new(fxmain , args->iter , groupid); fx_gedit_initialize(fxgedit); gtk_dialog_run(GTK_DIALOG(fxgedit->dialog)); gtk_widget_destroy(fxgedit->dialog); free(args); } static void fx_tree_on_copymenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; int groupid = args->i; char *userid = args->s; GtkTreeIter iter = args->iter; GtkTreeIter newIter; GtkTreeIter parentIter; GtkTreeIter oldParentIter; FxMain *fxmain = args->fxmain; GtkWidget *tree = fxmain->mainPanel->treeView; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree)); gchar *name , *sipuri , *impression , *mobileno , *device , *crc , *carrier; gint state , identity , size , imageChanged ; gint serviceStatus , carrierStatus , relationStatus; gint gid , oldOnlineCount , oldAllCount , newOnlineCount , newAllCount; GdkPixbuf *pb = NULL; if(fetion_contact_copy_to_group(fxmain->user , userid , groupid) == 0) { gtk_tree_model_get_iter_root(model , &parentIter); do { gtk_tree_model_get(model , &parentIter , G_ID_COL , &gid , G_ALL_COUNT_COL , &newAllCount , G_ONLINE_COUNT_COL , &newOnlineCount , -1); if(gid == groupid) break; } while(gtk_tree_model_iter_next(model , &parentIter)); gtk_tree_model_iter_parent(model , &oldParentIter , &iter); gtk_tree_model_get(model , &oldParentIter , G_ID_COL , &gid , G_ALL_COUNT_COL , &oldAllCount , G_ONLINE_COUNT_COL , &oldOnlineCount , -1); gtk_tree_model_get(model , &iter , B_PIXBUF_COL , &pb , B_SIPURI_COL , &sipuri , B_USERID_COL , &userid , B_NAME_COL , &name , B_IMPRESSION_COL , &impression , B_PHONENUM_COL , &mobileno , B_DEVICE_COL , &device , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , B_SERVICESTATUS_COL , &serviceStatus , B_CRC_COL , &crc , B_STATE_COL , &state , B_IDENTITY_COL , &identity , B_SIZE_COL , &size , B_IMAGE_CHANGED_COL , &imageChanged , -1); newAllCount ++; gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter , G_ALL_COUNT_COL , newAllCount , -1); if(state <= 0) { gtk_tree_store_append(GTK_TREE_STORE(model) , &newIter , &parentIter); } else { gtk_tree_store_prepend(GTK_TREE_STORE(model) , &newIter , &parentIter); newOnlineCount ++; gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter , G_ONLINE_COUNT_COL , newOnlineCount , -1); } gtk_tree_store_set(GTK_TREE_STORE(model) , &newIter , B_PIXBUF_COL , pb , B_SIPURI_COL , sipuri , B_USERID_COL , userid , B_NAME_COL , name , B_IMPRESSION_COL , impression , B_PHONENUM_COL , mobileno , B_CARRIER_COL , carrier , B_DEVICE_COL , device , B_CRC_COL , crc , B_SERVICESTATUS_COL , serviceStatus , B_CARRIERSTATUS_COL , carrierStatus , B_RELATIONSTATUS_COL , relationStatus , B_STATE_COL , state , B_IDENTITY_COL , identity , B_IMAGE_CHANGED_COL , imageChanged , B_SIZE_COL , size , -1); free(sipuri); free(userid); free(name); free(impression); free(mobileno); free(carrier); free(device); free(crc); } free(args); } static void fx_tree_on_movemenu_clicked(GtkWidget* UNUSED(widget) , gpointer data) { Args *args = (Args*)data; int groupid = args->i; char *userid = args->s; GtkTreeIter iter = args->iter; GtkTreeIter newIter; GtkTreeIter parentIter; GtkTreeIter oldParentIter; FxMain *fxmain = args->fxmain; GtkWidget *tree = fxmain->mainPanel->treeView; GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(tree)); gchar *name , *sipuri , *impression , *mobileno , *device , *crc , *carrier; gint state , identity , size , imageChanged ; gint serviceStatus , carrierStatus , relationStatus; gint gid , oldOnlineCount , oldAllCount , newOnlineCount , newAllCount; GdkPixbuf *pb = NULL; gtk_tree_model_iter_parent(model, &parentIter, &iter); gtk_tree_model_get(model, &parentIter, G_ID_COL, &gid, -1); if(fetion_contact_move_to_group(fxmain->user, userid, gid, groupid) == 0) { gtk_tree_model_get_iter_root(model, &parentIter); do { gtk_tree_model_get(model , &parentIter , G_ID_COL , &gid , G_ALL_COUNT_COL , &newAllCount , G_ONLINE_COUNT_COL , &newOnlineCount , -1); if(gid == groupid) break; } while(gtk_tree_model_iter_next(model , &parentIter)); gtk_tree_model_iter_parent(model , &oldParentIter , &iter); gtk_tree_model_get(model , &oldParentIter , G_ID_COL , &gid , G_ALL_COUNT_COL , &oldAllCount , G_ONLINE_COUNT_COL , &oldOnlineCount , -1); gtk_tree_model_get(model , &iter , B_PIXBUF_COL , &pb , B_SIPURI_COL , &sipuri , B_USERID_COL , &userid , B_NAME_COL , &name , B_IMPRESSION_COL , &impression , B_PHONENUM_COL , &mobileno , B_DEVICE_COL , &device , B_CARRIER_COL , &carrier , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , B_SERVICESTATUS_COL , &serviceStatus , B_CRC_COL , &crc , B_STATE_COL , &state , B_IDENTITY_COL , &identity , B_SIZE_COL , &size , B_IMAGE_CHANGED_COL , &imageChanged , -1); gtk_tree_store_remove(GTK_TREE_STORE(model) , &iter); oldAllCount --; gtk_tree_store_set(GTK_TREE_STORE(model) , &oldParentIter , G_ALL_COUNT_COL , oldAllCount , -1); newAllCount ++; gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter , G_ALL_COUNT_COL , newAllCount , -1); if(state <= 0) { gtk_tree_store_append(GTK_TREE_STORE(model) , &newIter , &parentIter); } else { gtk_tree_store_prepend(GTK_TREE_STORE(model) , &newIter , &parentIter); oldOnlineCount --; gtk_tree_store_set(GTK_TREE_STORE(model) , &oldParentIter , G_ONLINE_COUNT_COL , oldOnlineCount , -1); newOnlineCount ++; gtk_tree_store_set(GTK_TREE_STORE(model) , &parentIter , G_ONLINE_COUNT_COL , newOnlineCount , -1); } gtk_tree_store_set(GTK_TREE_STORE(model) , &newIter , B_PIXBUF_COL , pb , B_SIPURI_COL , sipuri , B_USERID_COL , userid , B_NAME_COL , name , B_IMPRESSION_COL , impression , B_PHONENUM_COL , mobileno , B_CARRIER_COL , carrier , B_DEVICE_COL , device , B_CRC_COL , crc , B_SERVICESTATUS_COL , serviceStatus , B_CARRIERSTATUS_COL , carrierStatus , B_RELATIONSTATUS_COL , relationStatus , B_STATE_COL , state , B_IDENTITY_COL , identity , B_IMAGE_CHANGED_COL , imageChanged , B_SIZE_COL , size , -1); free(sipuri); free(userid); free(name); free(impression); free(mobileno); free(carrier); free(device); free(crc); } free(args); } static gboolean fx_tree_on_show_tooltip(GtkWidget* widget , int x , int y , gboolean keybord_mode , GtkTooltip* tip , gpointer data) { FxMain *fxmain = (FxMain*)data; Config *config = fxmain->user->config; GtkTreePath *path; GtkTreeIter iter; GtkTreeView *tree; GtkTreeModel *model; GdkPixbuf *pb; gchar *sipuri; gchar *name; gchar *impression; gchar *sid; gchar *mobileno; gchar *carrier; gchar text[2048]; gchar phonetext[1024]; gchar iconpath[1024]; gint serviceStatus; gint carrierStatus; gint relationStatus; tree = GTK_TREE_VIEW(widget); model = gtk_tree_view_get_model(tree); if(!gtk_tree_view_get_tooltip_context(tree , &x , &y , keybord_mode , &model , &path , &iter)) return FALSE; if(gtk_tree_path_get_depth(path) == 1) return FALSE; gtk_tree_model_get(model , &iter , B_SIPURI_COL , &sipuri , B_NAME_COL , &name , B_IMPRESSION_COL , &impression , B_PHONENUM_COL , &mobileno , B_CARRIER_COL , &carrier , B_SERVICESTATUS_COL , &serviceStatus , B_CARRIERSTATUS_COL , &carrierStatus , B_RELATIONSTATUS_COL , &relationStatus , -1); sid = fetion_sip_get_sid_by_sipuri(sipuri); memset(phonetext, 0, sizeof(phonetext)); if(carrierStatus == CARRIER_STATUS_DOWN){ if(*carrier == '\0') snprintf(phonetext, sizeof(phonetext) - 1, _("Not bind to a phone number.")); else snprintf(phonetext, sizeof(phonetext) - 1, _("%s(Out of service)") , *mobileno == '\0' ? _("Phone number not be published.") : mobileno); }else if (carrierStatus == CARRIER_STATUS_NORMAL){ snprintf(phonetext, sizeof(phonetext) - 1, "%s" , (carrier == NULL || *carrier == '\0') ? _("Not bind to a phone number.") : (mobileno == NULL || *mobileno == '\0' ? _("Phone number not be published.") : mobileno)); } snprintf(text , sizeof(text) - 1 , _(" Nickname: %s\n" " Phone Number: %s\n" " Fetion Number: %s\n" " Signature: %s") , name == NULL ? "" : name , phonetext, sid , impression == NULL ? "" : impression); g_free(name); g_free(impression); g_free(mobileno); g_free(sipuri); g_free(carrier); snprintf(iconpath , sizeof(iconpath) - 1, "%s/%s.jpg" , config->iconPath , sid); g_free(sid); pb = gdk_pixbuf_new_from_file_at_size(iconpath , 80 , 80 , NULL); if(pb == NULL) pb = gdk_pixbuf_new_from_file_at_size(SKIN_DIR"portrait.png" , 80 , 80 , NULL); gtk_tooltip_set_markup(tip , text); gtk_tooltip_set_icon(tip , pb); g_object_unref(pb); gtk_tree_view_set_tooltip_row(tree , tip , path); gtk_tree_path_free(path); return TRUE; } FxPGGroup *pg_create_window(FxMain *fxmain , const char *pguri) { FxPGGroup *fxpg; PGGroup *pgcur; FxList *pglist; foreach_list(fxmain->pglist , pglist){ fxpg = (FxPGGroup*)(pglist->data); if(strcmp(fxpg->pggroup->pguri , pguri) == 0) return fxpg; } foreach_pg_group(fxmain->user->pggroup , pgcur){ if(strcmp(pgcur->pguri , pguri) == 0) break; } fxpg = fx_pggroup_new(fxmain , pgcur); fx_pggroup_initialize(fxpg); pglist = fx_list_new(fxpg); fx_list_append(fxmain->pglist , pglist); return fxpg; } static void pg_on_double_click(GtkTreeView *treeview , GtkTreePath *path , GtkTreeViewColumn *UNUSED(col) , gpointer data) { FxMain* fxmain = (FxMain*)data; GtkTreeIter iter; char *pguri; GtkTreeModel* model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)); gtk_tree_model_get_iter(model , &iter , path); gtk_tree_model_get(model , &iter , PG_URI_COL , &pguri , -1); pg_create_window(fxmain , pguri); free(pguri); } static gboolean pg_on_rightbutton_click(GtkWidget* UNUSED(tree) , GdkEventButton* event , gpointer data) { FxMain *fxmain = (FxMain*)data; FxTree *fxtree = fxmain->mainPanel; GtkTreeModel *model; GtkTreePath *path; GtkWidget *menu; GtkWidget *seperator; GtkTreeIter iter; gchar *sipuri; gint identity; Args *arg; if(event->type == GDK_BUTTON_PRESS && event->button == 3) { menu = gtk_menu_new(); model = gtk_tree_view_get_model(GTK_TREE_VIEW(fxtree->pgTreeView)); gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(fxtree->pgTreeView) , (gint)event->x , (gint)event->y , &path , NULL , NULL , NULL); if(!path) return FALSE; gtk_tree_model_get_iter(GTK_TREE_MODEL(model) , &iter , path); gtk_tree_model_get(model , &iter , PG_URI_COL , &sipuri , PG_IDENTITY_COL , &identity , -1); arg = fx_args_new(fxmain , iter , sipuri , 0); g_free(sipuri); fx_tree_create_menu(_("Send group message") , SKIN_DIR"groupsend.png" , menu , TRUE , on_send_message_clicked , arg); fx_tree_create_menu(_("Send group sms") , SKIN_DIR"myselfsms.png" , menu , (identity == 3 ? FALSE : TRUE) , on_send_sms_clicked , arg); seperator = gtk_separator_menu_item_new(); gtk_menu_shell_append(GTK_MENU_SHELL(menu) , seperator); fx_tree_create_menu(_("View group details") , SKIN_DIR"groupsend.png" , menu , TRUE , on_view_pgdetail_clicked , arg); gtk_widget_show_all(menu); gtk_menu_popup(GTK_MENU(menu) , NULL , NULL , NULL , NULL , (event != NULL) ? event->button : 0 , gdk_event_get_time((GdkEvent*)event)); gtk_tree_path_free(path); return TRUE; } return FALSE; } static void on_send_message_clicked(GtkWidget *UNUSED(widget) , gpointer data) { Args *arg = (Args*)data; FxMain *fxmain = arg->fxmain; char *pguri = arg->s; pg_create_window(fxmain , pguri); free(arg); } static void on_send_sms_clicked(GtkWidget *UNUSED(widget) , gpointer data) { Args *arg = (Args*)data; FxPGGroup *fxpg; FxMain *fxmain = arg->fxmain; char *pguri = arg->s; fxpg = pg_create_window(fxmain , pguri); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fxpg->phoneButton) , TRUE); free(arg); } static void on_view_pgdetail_clicked(GtkWidget *UNUSED(widget) , gpointer data) { Args *arg = (Args*)data; PGGroup *pgcur; FxMain *fxmain = arg->fxmain; FxPGProfile *fxpg; char *pguri = arg->s; foreach_pg_group(fxmain->user->pggroup , pgcur){ if(strcmp(pgcur->pguri , pguri) == 0) break; } fxpg = fx_pgprofile_new(fxmain , pgcur); fx_pgprofile_initialize(fxpg); free(arg); } openfetion-2.2.1/src/fx_tree.h0000644000175000017500000001031211561721144014735 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_TREE_H #define FX_TREE_H #define PG_PORTRAIT_SIZE 40 typedef enum buddycols { B_PIXBUF_COL = 0 , B_TEXT_COL , B_SIPURI_COL , B_USERID_COL , B_NAME_COL , B_IMPRESSION_COL , B_PHONENUM_COL , B_DEVICE_COL , B_CRC_COL , B_CARRIER_COL , B_STATE_COL , B_IDENTITY_COL , B_RELATIONSTATUS_COL , B_CARRIERSTATUS_COL , B_SERVICESTATUS_COL , B_SIZE_COL , B_IMAGE_CHANGED_COL , B_IMAGE_SET_COL , COL_NUM } BuddyCols; typedef enum groupcols { G_PIXBUF_COL = 0 , G_TEXT_COL , G_NAME_COL , G_NULL1_COL , G_NULL2_COL , G_NULL3_COL , G_NULL4_COL , G_NULL5_COL , G_NULL6_COL , G_NULL7_COL , G_NULL8_COL , G_NULL9_COL , G_NULL10_COL , G_ALL_COUNT_COL , G_ONLINE_COUNT_COL , G_ID_COL , G_NULL11_COL } GroupCols; typedef enum { PG_PIXBUF_COL = 0 , PG_TEXT_COL , PG_CREATETIME_COL , PG_URI_COL , PG_NAME_COL , PG_IDENTITY_COL , PG_CCOUNT_COL , PG_LCOUNT_COL , PG_GRANK_COL , PG_MRANK_COL , PG_COL_NUM } PGGroupCols; typedef struct tree_args { FxMain* fxmain; GtkTreeIter iter; char s[256]; int i; } Args; extern Args* fx_args_new(FxMain* fxmain , GtkTreeIter iter , const char* ss , int ii); extern FxTree* fx_tree_new(); extern void fx_tree_initilize(FxMain* fxmain); extern void fx_tree_show(FxMain *fxmain); extern void fx_tree_free(FxTree* fxtree); extern void fx_tree_move_to_the_first(GtkTreeModel* model , GtkTreeIter* iter); extern void fx_tree_move_to_the_last(GtkTreeModel* model , GtkTreeIter* iter); extern void fx_tree_bind_pg_data(FxMain *fxmain); extern int fx_tree_get_group_iter_by_id(GtkTreeModel* model , int id , GtkTreeIter* iter); extern gint fx_tree_get_buddy_iter(GtkTreeModel *model, gint groupid, const gchar *userid, GtkTreeIter *iter); extern int fx_tree_get_buddy_iter_by_userid(GtkTreeModel* model , const char* userid , GtkTreeIter* iter); extern FxPGGroup *pg_create_window(FxMain *fxmain , const char *pguri); extern void fx_tree_update_portrait(FxMain *fxmain); /*private*/ #endif openfetion-2.2.1/src/fx_types.h0000644000175000017500000002761711561721144015162 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_TYPES_H #define FX_TYPES_H #ifdef HAVE_LIBNOTIFY #include #endif #ifdef USE_INDICATE #include #endif #define WINDOW_WIDTH 280 #define WINDOW_HEIGHT 500 typedef enum { CHAT_DIALOG_FOCUSED = 1 , CHAT_DIALOG_NOT_FOCUSED = 2 } ChatDialogFocusedType; typedef struct { GThread* loginThread; long loginFuncId; long cancelFuncId; Proxy *proxy; /* login widget start */ GtkWidget* fixed; GtkWidget* portrait; GtkWidget* username; GtkWidget* password; GtkWidget* loginbutton; GtkWidget* userlabel; GtkWidget* passlabel; GtkWidget* statusLabel; GtkWidget* statecombo; GtkWidget* remember; GtkWidget* proxyBtn; GtkWidget* proxyLabel; GtkListStore* store; GtkTreeModel* model; /* logining panel */ GtkWidget* fixed1; GtkWidget* image; GtkWidget* label; GtkWidget* errlabel; } FxLogin; typedef struct { GtkWidget* topbox; GtkWidget* portrait; GtkWidget* portraitbox; GtkWidget* name_label; GtkWidget* state_label; GtkWidget* impre_box; GtkWidget* impre_label; GtkWidget* impre_entry; GtkWidget* state_button; GtkWidget* presence_menu; GtkWidget* state_img; char oldimpression[1024]; } FxHead; typedef struct { GtkWidget* toolbar; } FxBottom; typedef struct { GtkWidget *treeView; GtkWidget *noPgLabel; GtkWidget *pgTreeView; GtkWidget *searchbox; GtkTreeStore *treeModel; GtkWidget *scrollWindow; GtkWidget *pgScrollWindow; GtkWidget *noLabelScrollWindow; } FxTree; typedef struct { FxList* clist; /* chat window list */ FxList* mlist; /* unread message list */ FxList* slist; /* sip list wicth is now listening */ FxList* tlist; /* time out args list */ FxList* shlist; /* share content window list */ FxList* pglist; FetionHistory* history; #ifdef USE_LIBNOTIFY NotifyNotification *notify; #endif #ifdef USE_INDICATE IndicateServer *indserver; #endif int iconConnectId; /* status icon connect id */ FxLogin* loginPanel; /* login panel */ FxHead* headPanel; /* head panel */ FxTree* mainPanel; /* tree panel include treeview */ FxBottom* bottomPanel; /* bottom panel include some functional buttons*/ GtkWidget* window; /* main window */ GtkStatusIcon* trayIcon; /* status icon */ GtkWidget* mainbox; /* main layout box */ User* user; } FxMain; typedef struct { FxLogin *fxlogin; GtkWidget *dialog; GtkWidget *enableBtn; GtkWidget *hostEntry; GtkWidget *portEntry; GtkWidget *userEntry; GtkWidget *passEntry; GtkWidget *errorLabel; } FxProxy; typedef struct { GtkWidget* dialog; GtkWidget* add_label; GtkWidget* add_entry; GtkWidget* ok_button; GtkWidget* cancel_button; FxMain* fxmain; } FxAddGroup; typedef struct { FxMain* fxmain; char userid[16]; GtkWidget* dialog; GtkWidget* image ; GtkWidget* sid_label ; GtkWidget* sid_entry ; GtkWidget* gender_label ; GtkWidget* gender_entry ; GtkWidget* mno_label ; GtkWidget* mno_entry ; GtkWidget* nick_label ; GtkWidget* nick_entry ; GtkWidget* impre_label ; GtkWidget* impre_entry ; GtkWidget* local_label ; GtkWidget* local_entry ; GtkWidget* nation_label ; GtkWidget* nation_entry ; GtkWidget* province_label ; GtkWidget* province_entry ; GtkWidget* city_label ; GtkWidget* city_entry ; GtkWidget* finish_button ; } FxProfile; typedef struct { char userid[16]; GtkTreeIter iter; FxMain* fxmain; GtkWidget* dialog; GtkWidget* remark_label; GtkWidget* remark_entry; GtkWidget* ok_button; GtkWidget* cancel_button; } FxEdit; typedef struct { int groupid; GtkTreeIter iter; FxMain* fxmain; GtkWidget* dialog; GtkWidget* remark_label; GtkWidget* remark_entry; GtkWidget* ok_button; GtkWidget* cancel_button; } FxGEdit; typedef struct { FxMain* fxmain; GtkWidget* dialog; GtkWidget* remark_label; GtkWidget* remark_entry; GtkWidget* ok_button; GtkWidget* cancel_button; } FxLookup; typedef struct { FxMain* fxmain; Contact* contact; GtkWidget* dialog; GtkWidget* image ; GtkWidget* sid_label ; GtkWidget* sid_entry ; GtkWidget* gender_label ; GtkWidget* gender_entry ; GtkWidget* mno_label ; GtkWidget* mno_entry ; GtkWidget* nick_label ; GtkWidget* nick_entry ; GtkWidget* impre_label ; GtkWidget* impre_entry ; GtkWidget* birth_label ; GtkWidget* birth_entry ; GtkWidget* nation_label ; GtkWidget* nation_entry ; GtkWidget* province_label ; GtkWidget* province_entry ; GtkWidget* city_label ; GtkWidget* city_entry ; GtkWidget* ok_button ; GtkWidget* cancel_button ; } FxLookupres; typedef struct { FxMain* fxmain; Conversation* conv; ChatDialogFocusedType hasFocus; gboolean sendtophone; StateType state; int unreadMsgCount; int inputRefcnt; /* main widget begin */ GtkWidget* dialog; GtkWidget* headbox; GdkPixbuf* headpix; GtkWidget* headimage; GtkWidget* name_box; GtkWidget* input_label; GtkWidget* name_label; GtkWidget* impre_label; GtkWidget* recv_text; GtkWidget* send_text; GtkWidget* recv_scroll; GtkWidget* send_scroll; GtkTextMark* mark; GtkTextBuffer* send_buffer; GtkTextBuffer* recv_buffer; GtkTextIter send_iter; GtkTextIter recv_iter; /* toolbar begin */ GtkWidget* toolbar; GtkWidget* tophone; GtkWidget* tocomputer; GtkWidget* historybutton; GtkWidget* nouge; GtkWidget* countLabel; } FxChat; typedef struct { FxMain* fxmain; Conversation* conv; GtkWidget* window; GtkWidget* headbox; GdkPixbuf* headpix; GtkWidget* headimage; GtkWidget* name_label; GtkWidget* impre_label; GtkWidget* recv_text; GtkWidget* send_text; GtkWidget* recv_scroll; GtkWidget* send_scroll; GtkTextMark* mark; GtkTextBuffer* send_buffer; GtkTextBuffer* recv_buffer; GtkTextIter send_iter; GtkTextIter recv_iter; } FxMyself; typedef struct { FxMain* fxmain; char userid[16]; char name[48]; GtkWidget* dialog; GtkWidget* toolbar; GtkWidget* textview; GtkWidget* daycombo; GtkWidget* closebtn; } FxHistory; typedef struct { FxMain* fxmain; int chooseCount; GtkWidget* window; /*left*/ GtkWidget* hbox; GtkWidget* tree; GtkWidget* selected; /*right*/ GtkWidget* label; GtkWidget* close_button; GtkWidget* send_button; GtkWidget* recv_text; GtkWidget* send_text; GtkWidget* recv_scroll; GtkWidget* send_scroll; GtkTextMark* mark; GtkTextBuffer* send_buffer; GtkTextBuffer* recv_buffer; GtkTextIter send_iter; GtkTextIter recv_iter; } FxMany; typedef struct { FxMain* fxmain; FxList* phraselist; int phraseid; NumberType notype; GtkWidget* dialog; GtkWidget* fetion_button; GtkWidget* mobile_button; GtkWidget* fetion_entry; GtkWidget* mobile_entry; GSList* group; GtkWidget* tablebox; GtkWidget* group_combo; GtkWidget* name_entry; GtkWidget* myname_entry; GtkWidget* msgbox; } FxAddbuddy; typedef enum { CODE_ERROR , CODE_NOT_ERROR } ErrorType; typedef struct { char reason[256]; char tip[256]; ErrorType error; FxMain* fxmain; GtkWidget *dialog; GtkWidget *reasonlabel; GtkWidget *codeentry; GtkWidget *tiplabel; GtkWidget *codepic; GtkWidget *codebox; } FxCode; typedef struct { FxMain *fxmain; char sipuri[48]; char userid[16]; char desc[48]; int phraseid; GtkWidget *dialog; GtkWidget *msgLabel; GSList *rdoList; GtkWidget *aptButton; GtkWidget *rjtButton; GtkWidget *lnEntry; GtkWidget *agCombo; } FxApp; typedef struct { FxMain *fxmain; GtkWidget *dialog; GtkWidget *notebook; GtkWidget *psetting; GtkWidget *ssetting; /* system setting */ GtkWidget *apBtn; GtkWidget *apEty; GtkWidget *ppCb; GtkWidget *muteBtn; GtkWidget *smallBtn; GtkWidget *ctBtn; GtkWidget *etBtn; GtkWidget *alertBtn; GtkWidget *iconBtn; GtkWidget *autoAwayBtn; GtkWidget *onlineNotifyBtn; GtkWidget *closeSysMsgBtn; GtkWidget *closeShowBtn; GtkWidget *useStatusIcon; /* personal setting */ GtkWidget* image ; GtkWidget* sid_label ; GtkWidget* sid_entry ; GtkWidget* gender_label ; GtkWidget* mno_label ; GtkWidget* mno_entry ; GtkWidget* nick_label ; GtkWidget* nick_entry ; GtkWidget* impre_label ; GtkWidget* impre_entry ; GtkWidget* province_label ; GtkWidget* city_label ; GtkWidget* city_entry ; GtkWidget* email_label; GtkWidget* email_entry; GtkWidget* job_label; GtkWidget* job_entry; GtkWidget* gender_combo; GtkWidget* province_entry; } FxSet; typedef struct { FxChat *fxchat; GtkWidget *dialog; } FxEmotion; typedef struct { FxMain* fxmain; FetionSip* sip; Conversation* conv; } ThreadArgs; typedef struct { FxMain *fxmain; Share *share; Contact *contact; GtkWidget *dialog; GtkWidget *progress; GtkWidget *uLabel; GtkWidget *iLabel; } FxShare; typedef struct { FxMain *fxmain; GtkWidget *dialog; GtkWidget *codeEntry; } FxConfirm; typedef struct { FxMain *fxmain; GtkWidget *dialog; GtkWidget *recvText; GtkWidget *sendText; GtkWidget *numberEntry; GtkWidget *addEventBox; GtkWidget *msgLabel; GtkWidget *chooseList; GtkWidget *countLabel; GtkWidget *checkBtn; GtkWidget *sigEntry; } FxDSMS; typedef struct { FxMain *fxmain; GtkWidget *dialog; GtkWidget *closeBtn; GtkWidget *iconBtn; GtkWidget *notalert; } FxClose; typedef struct { FxMain *fxmain; GtkWidget *window; GtkWidget *view; }FxSearch; typedef struct { FxMain *fxmain; int hasFocus; PGGroup *pggroup; GtkWidget *window; GtkWidget *image; GtkWidget *nameLabel; GtkWidget *otherLabel; GtkWidget *phoneButton; GtkWidget *sendView; GtkWidget *recvView; GtkWidget *toolbar; GtkWidget *noticeView; GtkWidget *treeView; } FxPGGroup; typedef struct { FxMain *fxmain; PGGroup *pggroup; GtkWidget *window; GtkWidget *image; GtkWidget *sidEntry; GtkWidget *nameEntry; GtkWidget *leaderEntry; GtkWidget *timeEntry; GtkWidget *introView; GtkWidget *bulletinView; } FxPGProfile; typedef struct { FxMain *fxmain; GtkWidget *dialog; GtkWidget *label; GSList *gslist; } FxSmsstat; #endif openfetion-2.2.1/src/fx_util.c0000644000175000017500000002757711561721144014773 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #include "fx_include.h" char* fx_util_get_state_name(StateType type) { char *name = (char*)malloc(48); memset(name , 0 , 48); switch(type) { case P_ONLINE: strcpy(name , _("[Online]")); break; case P_BUSY: strcpy(name , _("[Busy]")); break; case P_AWAY: strcpy(name , _("[Leave]")); break; case P_HIDDEN: strcpy(name , _("[Hide]")); break; case P_OUTFORLUNCH: strcpy(name , _("[Eating out]")); break; case P_DONOTDISTURB: strcpy(name , _("[Do Not Disturb]")); break; case P_RIGHTBACK: strcpy(name , _("[Be Back Soon]")); break; case P_MEETING: strcpy(name , _("[Meeting]")); break; case P_ONTHEPHONE: strcpy(name , _("[Calling]")); break; case P_OFFLINE: strcpy(name, _("[Offline]")); break; default: if(type > 400 && type < 500) strcpy(name , _("[Online]")); else strcpy(name , _("[Unknown Statement]")); break; } return name; } void fx_util_popup_warning(FxMain* fxmain , const char* message) { GtkWidget *dialog = NULL; dialog = gtk_message_dialog_new(GTK_WINDOW(fxmain->window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,"%s", message); gtk_window_set_title(GTK_WINDOW(dialog), "Warning"); gtk_dialog_run(GTK_DIALOG(dialog)); gtk_widget_destroy(dialog); } char *fx_util_str_replace(char *str, const char *oldstr, const char *newstr) { gchar *out = NULL; gchar **tokens = NULL; tokens = g_strsplit(str , oldstr , -1); out = g_strjoinv(newstr , tokens); g_strfreev(tokens); return out; } char *fx_util_replace_emotion(char *str) { if ((g_strstr_len(str, -1, ">:)")) != NULL) { str = fx_util_str_replace(str, ">:)", "#50#"); } if ((g_strstr_len(str, -1, "*-:)")) != NULL) { str = fx_util_str_replace(str, "*-:)", "#37#"); } if ((g_strstr_len(str, -1, ":)")) != NULL) { str = fx_util_str_replace(str, ":)", "#1#"); } if ((g_strstr_len(str, -1, ":-d")) != NULL) { str = fx_util_str_replace(str, ":-d", "#2#"); } if ((g_strstr_len(str, -1, ";)")) != NULL) { str = fx_util_str_replace(str, ";)", "#3#"); } if ((g_strstr_len(str, -1, ":-o")) != NULL) { str = fx_util_str_replace(str, ":-o", "#4#"); } if ((g_strstr_len(str, -1, ":-p")) != NULL) { str = fx_util_str_replace(str, ":-p", "#5#"); } if ((g_strstr_len(str, -1, "(h)")) != NULL) { str = fx_util_str_replace(str, "(h)", "#6#"); } if ((g_strstr_len(str, -1, ":-@")) != NULL) { str = fx_util_str_replace(str, ":-@", "#7#"); } if ((g_strstr_len(str, -1, ":(")) != NULL) { str = fx_util_str_replace(str, ":(", "#8#"); } if ((g_strstr_len(str, -1, ":'(")) != NULL) { str = fx_util_str_replace(str, ":'(", "#9#"); } if ((g_strstr_len(str, -1, ":\">")) != NULL) { str = fx_util_str_replace(str, ":\">", "#10#"); } if ((g_strstr_len(str, -1, "^o)")) != NULL) { str = fx_util_str_replace(str, "^o)", "#11#"); } if ((g_strstr_len(str, -1, ":&")) != NULL) { str = fx_util_str_replace(str, ":&", "#12#"); } if ((g_strstr_len(str, -1, "8o|")) != NULL) { str = fx_util_str_replace(str, "8o|", "#13#"); } if ((g_strstr_len(str, -1, "|-)")) != NULL) { str = fx_util_str_replace(str, "|-)", "#14#"); } if ((g_strstr_len(str, -1, ":-#")) != NULL) { str = fx_util_str_replace(str, ":-#", "#15#"); } if ((g_strstr_len(str, -1, "8-)")) != NULL) { str = fx_util_str_replace(str, "8-)", "#16#"); } if ((g_strstr_len(str, -1, "(s)")) != NULL) { str = fx_util_str_replace(str, "(s)", "#17#"); } if ((g_strstr_len(str, -1, "(st)")) != NULL) { str = fx_util_str_replace(str, "(st)", "#18#"); } if ((g_strstr_len(str, -1, "(o)")) != NULL) { str = fx_util_str_replace(str, "(o)", "#19#"); } if ((g_strstr_len(str, -1, "(l)")) != NULL) { str = fx_util_str_replace(str, "(l)", "#20#"); } if ((g_strstr_len(str, -1, "(u)")) != NULL) { str = fx_util_str_replace(str, "(u)", "#21#"); } if ((g_strstr_len(str, -1, "(@)")) != NULL) { str = fx_util_str_replace(str, "(@)", "#22#"); } if ((g_strstr_len(str, -1, "(&)")) != NULL) { str = fx_util_str_replace(str, "(&)", "#23#"); } if ((g_strstr_len(str, -1, "(sn)")) != NULL) { str = fx_util_str_replace(str, "(sn)", "#24#"); } if ((g_strstr_len(str, -1, "(*)")) != NULL) { str = fx_util_str_replace(str, "(*)", "#25#"); } if ((g_strstr_len(str, -1, "(#)")) != NULL) { str = fx_util_str_replace(str, "(#)", "#26#"); } if ((g_strstr_len(str, -1, "(r)")) != NULL) { str = fx_util_str_replace(str, "(r)", "#27#"); } if ((g_strstr_len(str, -1, "(})")) != NULL) { str = fx_util_str_replace(str, "(})", "#29#"); } if ((g_strstr_len(str, -1, "({)")) != NULL) { str = fx_util_str_replace(str, "({)", "#28#"); } if ((g_strstr_len(str, -1, "(k)")) != NULL) { str = fx_util_str_replace(str, "(k)", "#30#"); } if ((g_strstr_len(str, -1, "(f)")) != NULL) { str = fx_util_str_replace(str, "(f)", "#31#"); } if ((g_strstr_len(str, -1, "(w)")) != NULL) { str = fx_util_str_replace(str, "(w)", "#32#"); } if ((g_strstr_len(str, -1, "(g)")) != NULL) { str = fx_util_str_replace(str, "(g)", "#33#"); } if ((g_strstr_len(str, -1, "(^)")) != NULL) { str = fx_util_str_replace(str, "(^)", "#34#"); } if ((g_strstr_len(str, -1, "(8)")) != NULL) { str = fx_util_str_replace(str, "(8)", "#35#"); } if ((g_strstr_len(str, -1, "(i)")) != NULL) { str = fx_util_str_replace(str, "(i)", "#36#"); } if ((g_strstr_len(str, -1, "(c)")) != NULL) { str = fx_util_str_replace(str, "(c)", "#38#"); } if ((g_strstr_len(str, -1, "(um)")) != NULL) { str = fx_util_str_replace(str, "(um)", "#39#"); } if ((g_strstr_len(str, -1, "(mp)")) != NULL) { str = fx_util_str_replace(str, "(mp)", "#40#"); } if ((g_strstr_len(str, -1, "(co)")) != NULL) { str = fx_util_str_replace(str, "(co)", "#41#"); } if ((g_strstr_len(str, -1, ":-|")) != NULL) { str = fx_util_str_replace(str, ":-|", "#42#"); } if ((g_strstr_len(str, -1, ":-/")) != NULL) { str = fx_util_str_replace(str, ":-/", "#43#"); } if ((g_strstr_len(str, -1, ":s")) != NULL) { str = fx_util_str_replace(str, ":s", "#44#"); } if ((g_strstr_len(str, -1, ")-|")) != NULL) { str = fx_util_str_replace(str, ")-|", "#45#"); } if ((g_strstr_len(str, -1, "(d)")) != NULL) { str = fx_util_str_replace(str, "(d)", "#46#"); } if ((g_strstr_len(str, -1, "O:)")) != NULL) { str = fx_util_str_replace(str, "O:)", "#47#"); } if ((g_strstr_len(str, -1, ":-?")) != NULL) { str = fx_util_str_replace(str, ":-?", "#48#"); } if ((g_strstr_len(str, -1, "(y)")) != NULL) { str = fx_util_str_replace(str, "(y)", "#49#"); } if ((g_strstr_len(str, -1, ":-b")) != NULL) { str = fx_util_str_replace(str, ":-b", "#51#"); } if ((g_strstr_len(str, -1, "b)")) != NULL) { str = fx_util_str_replace(str, "b)", "#52#"); } return str; } void escape_impression(char *impre) { if(!impre) return; unsigned int i; for(i = 0 ; i < strlen(impre); i++){ if(impre[i] == 10 || impre[i] == 13) impre[i] = 32; } } static gchar getpychar(guchar uword0 , guchar uword1) { gchar pychar; int i1 = (short)(uword0 - '\0'); int i2 = (short)(uword1 - '\0'); int tmp = i1 * 256 + i2; if(tmp >= 45217 && tmp <= 45252) pychar = 'A'; else if(tmp >= 45253 && tmp <= 45760) pychar = 'B'; else if(tmp >= 45761 && tmp <= 46317) pychar = 'C'; else if(tmp >= 46318 && tmp <= 46825) pychar = 'D'; else if(tmp >= 46826 && tmp <= 47009) pychar = 'E'; else if(tmp >= 47010 && tmp <= 47296) pychar = 'F'; else if(tmp >= 47297 && tmp <= 47613) pychar = 'G'; else if(tmp >= 47614 && tmp <= 48118) pychar = 'H'; else if(tmp >= 48119 && tmp <= 49061) pychar = 'J'; else if(tmp >= 49062 && tmp <= 49323) pychar = 'K'; else if(tmp >= 49324 && tmp <= 49895) pychar = 'L'; else if(tmp >= 49896 && tmp <= 50370) pychar = 'M'; else if(tmp >= 50371 && tmp <= 50613) pychar = 'N'; else if(tmp >= 50614 && tmp <= 50621) pychar = 'O'; else if(tmp >= 50622 && tmp <= 50905) pychar = 'P'; else if(tmp >= 50906 && tmp <= 51386) pychar = 'Q'; else if(tmp >= 51387 && tmp <= 51445) pychar = 'R'; else if(tmp >= 51446 && tmp <= 52217) pychar = 'S'; else if(tmp >= 52218 && tmp <= 52697) pychar = 'T'; else if(tmp >= 52698 && tmp <= 52979) pychar = 'W'; else if(tmp >= 52980 && tmp <= 53640) pychar = 'X'; else if(tmp >= 53689 && tmp <= 54480) pychar = 'Y'; else if(tmp >= 54481 && tmp <= 55289) pychar = 'Z'; else pychar = ' '; return pychar; } gchar *get_pystring(const gchar *in) { gsize inlen , olen , i , j = 0; gchar *gword = g_convert(in , strlen(in) , "gb18030" , "utf8" , &inlen , &olen , NULL); guchar *uword = (guchar*)gword; gchar *out = (gchar*)malloc(olen); memset(out , 0 , olen); for(i = 0 ; i < olen ; i++){ if(uword[i] >= 0xa1){ if(uword[i] != 0xa3){ out[j++] = getpychar(uword[i] , uword[i + 1]); i ++; } }else{ out[j++] = toupper((gchar)uword[i]); } } return out; } gboolean has_gb(const gchar *in) { gsize inlen , olen , i; gchar *gword = g_convert(in , strlen(in) , "gb18030" , "utf8" , &inlen , &olen , NULL); guchar *uword = (guchar*)gword; for(i = 0 ; i < olen ; i++) if(uword[i] >= 0xa1) return TRUE; return FALSE; } openfetion-2.2.1/src/fx_util.h0000644000175000017500000000530211561721144014756 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_UTIL_H #define FX_UTIL_H extern char* fx_util_get_state_name(StateType type); extern void fx_util_popup_warning(FxMain* fxmain , const char* message); extern char *fx_util_str_replace(char *str , const char *oldstr , const char *newstr); extern char *fx_util_replace_emotion(char *str); extern void escape_impression(char *impre); extern gchar *get_pystring(const gchar *in); extern gboolean has_gb(const gchar *in); #endif openfetion-2.2.1/src/fx_about.h0000644000175000017500000000456511561721144015125 0ustar aronaron/*************************************************************************** * Copyright (C) 2010 by lwp * * levin108@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * * * OpenSSL linking exception * * -------------------------- * * If you modify this Program, or any covered work, by linking or * * combining it with the OpenSSL project's "OpenSSL" library (or a * * modified version of that library), containing parts covered by * * the terms of OpenSSL/SSLeay license, the licensors of this * * Program grant you additional permission to convey the resulting * * work. Corresponding Source for a non-source form of such a * * combination shall include the source code for the parts of the * * OpenSSL library used as well as that of the covered work. * ***************************************************************************/ #ifndef FX_ABOUT_H #define FX_ABOUT_H #define OPENFETION_VERSION "2.2.1" extern void show_about(); #endif openfetion-2.2.1/CMakeLists.txt0000644000175000017500000002213211561721144015104 0ustar aronaronproject(openfetion) cmake_minimum_required(VERSION 2.6) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake-modules) set(TARNAME openfetion) # program name, version etc set(PACKAGE_VERSION "2.2.1") set(PACKAGE_NAME "OpenFetion") set(PACKAGE_TARNAME "${TARNAME}") set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "http://code.google.com/p/ofetion/issues/list") find_package(PkgConfig REQUIRED) ########################################################################## if(NOT DEFINED BIN_INSTALL_DIR) set(BIN_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/bin") endif(NOT DEFINED BIN_INSTALL_DIR) if(NOT DEFINED DATA_INSTALL_DIR) set(DATA_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share") endif(NOT DEFINED DATA_INSTALL_DIR) if(NOT DEFINED MAN_INSTALL_DIR) set(MAN_INSTALL_DIR "${DATA_INSTALL_DIR}/man") endif(NOT DEFINED MAN_INSTALL_DIR) if(NOT DEFINED DESKTOP_INSTALL_DIR) set(DESKTOP_INSTALL_DIR "${DATA_INSTALL_DIR}/applications/") endif(NOT DEFINED DESKTOP_INSTALL_DIR) if(NOT DEFINED RESOURCE_INSTALL_DIR) set(RESOURCE_INSTALL_DIR "${DATA_INSTALL_DIR}/openfetion/resource/") endif(NOT DEFINED RESOURCE_INSTALL_DIR) if(NOT DEFINED SKIN_INSTALL_DIR) set(SKIN_INSTALL_DIR "${DATA_INSTALL_DIR}/openfetion/skin/") endif(NOT DEFINED SKIN_INSTALL_DIR) if(NOT DEFINED LOCALE_INSTALL_DIR) set(LOCALE_INSTALL_DIR "${DATA_INSTALL_DIR}/locale/") endif(NOT DEFINED LOCALE_INSTALL_DIR) add_definitions(-DRESOURCE_DIR="${RESOURCE_INSTALL_DIR}") add_definitions(-DDESKTOP_DIR="${DESKTOP_INSTALL_DIR}") install(FILES resource/newmessage.wav DESTINATION ${RESOURCE_INSTALL_DIR}) install(FILES resource/openfetion.desktop DESTINATION ${DESKTOP_INSTALL_DIR}) # compile option switch option(NLS "Native language support" ON) option(WITH_LIBNOTIFY "Libnotify support" ON) option(WITH_GSTREAMER "GStreamer support" ON) option(WITH_LIBXSS "LibXScrnSaver support" ON) option(WITH_NETWORKMANAGER "NetworkManager support" ON) option(WITH_INDICATE "Ubuntu Indicator support" ON) # openfetion build requirements find_package(PkgConfig REQUIRED) if(NLS) find_package(Gettext) endif(NLS) # openfetion build requirements pkg_check_modules(GTK2 REQUIRED gtk+-2.0) pkg_check_modules(GDKPIXBUF REQUIRED gdk-pixbuf-2.0) pkg_check_modules(GLIB2 REQUIRED glib-2.0) pkg_check_modules(OFETION REQUIRED ofetion) if(WITH_LIBNOTIFY) pkg_check_modules(LIBNOTIFY libnotify) endif(WITH_LIBNOTIFY) if(WITH_GSTREAMER) pkg_check_modules(GSTREAMER gstreamer-0.10) endif(WITH_GSTREAMER) if(WITH_LIBXSS) pkg_check_modules(LIBXSS xscrnsaver) endif(WITH_LIBXSS) if(WITH_NETWORKMANAGER) pkg_check_modules(NETWORKMANAGER NetworkManager) pkg_check_modules(DBUSGLIB dbus-glib-1) endif(WITH_NETWORKMANAGER) if(WITH_INDICATE) pkg_check_modules(INDICATE indicate) pkg_check_modules(INDICATE_GTK indicate-gtk) pkg_check_modules(INDICATE_GTK_NEW indicate-gtk-0.5) endif(WITH_INDICATE) ########################################################################## message("==========================================") if(WITH_LIBNOTIFY AND LIBNOTIFY_FOUND) set(USE_LIBNOTIFY 1) if(LIBNOTIFY_VERSION LESS 0.7) set(LIBNOTIFY_OLD 1) message(STATUS "Libnotify support: OLD" ) else(LIBNOTIFY_VERSION LESS 0.7) message(STATUS "Libnotify support: NEW" ) endif(LIBNOTIFY_VERSION LESS 0.7) else(WITH_LIBNOTIFY AND LIBNOTIFY_FOUND) message(STATUS "Libnotify support: NO" ) endif(WITH_LIBNOTIFY AND LIBNOTIFY_FOUND) if(WITH_GSTREAMER AND GSTREAMER_FOUND) set(USE_GSTREAMER 1) message(STATUS "GStreamer support: YES" ) else(WITH_GSTREAMER AND GSTREAMER_FOUND) message(STATUS "GStreamer support: NO" ) endif(WITH_GSTREAMER AND GSTREAMER_FOUND) if(WITH_LIBXSS AND LIBXSS_FOUND) set(USE_LIBXSS 1) message(STATUS "Xscreensaver support: YES" ) else(WITH_LIBXSS AND LIBXSS_FOUND) message(STATUS "Xscreensaver support: NO" ) endif(WITH_LIBXSS AND LIBXSS_FOUND) if(WITH_NETWORKMANAGER AND NETWORKMANAGER_FOUND AND DBUSGLIB_FOUND) set(USE_NETWORKMANAGER 1) message(STATUS "NetworkManager support: YES" ) else(WITH_NETWORKMANAGER AND NETWORKMANAGER_FOUND AND DBUSGLIB_FOUND) message(STATUS "NetworkManager support: NO" ) endif(WITH_NETWORKMANAGER AND NETWORKMANAGER_FOUND AND DBUSGLIB_FOUND) if(WITH_INDICATE) if(INDICATE_GTK_FOUND OR INDICATE_GTK_NEW_FOUND) set(USE_INDICATE 1) message(STATUS "Ubuntu Indicator support: YES" ) else(INDICATE_GTK_FOUND OR INDICATE_GTK_NEW_FOUND) message(STATUS "Ubuntu Indicator support: NO" ) endif(INDICATE_GTK_FOUND OR INDICATE_GTK_NEW_FOUND) else(WITH_INDICATE) message(STATUS "Ubuntu Indicator support: NO" ) endif(WITH_INDICATE) message("==========================================") configure_file(config-ofetion.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) ########################################################################## add_definitions(-g -Wall -Wextra) if(NLS AND GETTEXT_FOUND) add_definitions(-DGETTEXT_PACKAGE="${PACKAGE_TARNAME}") add_definitions(-DENABLE_NLS="1") message(STATUS "Native language support: YES" ) else(NLS AND GETTEXT_FOUND) message(STATUS "Native language support: NO" ) endif(NLS AND GETTEXT_FOUND) add_definitions(-DSKIN_DIR="${SKIN_INSTALL_DIR}") add_definitions(-DLOCALE_DIR="${LOCALE_INSTALL_DIR}") ########################################################################## include_directories( ${GTK2_INCLUDE_DIRS} ${GDKPIXBUF_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${OFETION_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src ) if(WITH_LIBNOTIFY AND LIBNOTIFY_FOUND) include_directories(${LIBNOTIFY_INCLUDE_DIRS}) endif(WITH_LIBNOTIFY AND LIBNOTIFY_FOUND) if(WITH_GSTREAMER AND GSTREAMER_FOUND) include_directories(${GSTREAMER_INCLUDE_DIRS}) endif(WITH_GSTREAMER AND GSTREAMER_FOUND) if(WITH_NETWORKMANAGER AND NETWORKMANAGER_FOUND) include_directories(${NETWORKMANAGER_INCLUDE_DIRS}) include_directories(${DBUSGLIB_INCLUDE_DIRS}) endif(WITH_NETWORKMANAGER AND NETWORKMANAGER_FOUND) if(WITH_INDICATE AND INDICATE_FOUND) include_directories(${INDICATE_INCLUDE_DIRS}) endif(WITH_INDICATE AND INDICATE_FOUND) if(WITH_INDICATE AND INDICATE_GTK_FOUND) include_directories(${INDICATE_GTK_INCLUDE_DIRS}) endif(WITH_INDICATE AND INDICATE_GTK_FOUND) if(WITH_INDICATE AND INDICATE_GTK_NEW_FOUND) include_directories(${INDICATE_GTK_NEW_INCLUDE_DIRS}) endif(WITH_INDICATE AND INDICATE_GTK_NEW_FOUND) set(openfetion_SRC src/fx_about.c src/fx_addbuddy.c src/fx_add_group.c src/fx_app.c src/fx_bottom.c src/fx_chat.c src/fx_close.c src/fx_code.c src/fx_conn.c src/fx_dsms.c src/fx_edit.c src/fx_emotion.c src/fx_gedit.c src/fx_head.c src/fx_history.c src/fx_idle.c src/fx_login.c src/fx_lookup.c src/fx_lookupres.c src/fx_main.c src/fx_many.c src/fx_myself.c src/fx_pggroup.c src/fx_pgprofile.c src/fx_profile.c src/fx_proxy.c src/fx_search.c src/fx_set.c src/fx_share.c src/fx_smsstat.c src/fx_sound.c src/fx_sysmsg.c src/fx_tree.c src/fx_util.c src/fx_server.c src/fx_cli.c ) add_executable(openfetion ${openfetion_SRC}) target_link_libraries(openfetion ${GTK2_LIBRARIES} ${GDKPIXBUF_LIBRARIES} ${GTHREAD2_LIBRARIES} ${OFETION_LIBRARIES}) if(WITH_LIBNOTIFY AND LIBNOTIFY_FOUND) target_link_libraries(openfetion ${LIBNOTIFY_LIBRARIES}) endif(WITH_LIBNOTIFY AND LIBNOTIFY_FOUND) if(WITH_GSTREAMER AND GSTREAMER_FOUND) target_link_libraries(openfetion ${GSTREAMER_LIBRARIES}) endif(WITH_GSTREAMER AND GSTREAMER_FOUND) if(WITH_LIBXSS AND LIBXSS_FOUND) target_link_libraries(openfetion ${LIBXSS_LIBRARIES}) endif(WITH_LIBXSS AND LIBXSS_FOUND) if(WITH_INDICATE AND INDICATE_FOUND) target_link_libraries(openfetion ${INDICATE_LIBRARIES}) endif(WITH_INDICATE AND INDICATE_FOUND) if(WITH_INDICATE AND INDICATE_GTK_FOUND) target_link_libraries(openfetion ${INDICATE_GTK_LIBRARIES}) endif(WITH_INDICATE AND INDICATE_GTK_FOUND) if(WITH_INDICATE AND INDICATE_GTK_NEW_FOUND) target_link_libraries(openfetion ${INDICATE_GTK_NEW_LIBRARIES}) endif(WITH_INDICATE AND INDICATE_GTK_NEW_FOUND) if(WITH_NETWORKMANAGER AND NETWORKMANAGER_FOUND AND DBUSGLIB_FOUND) target_link_libraries(openfetion ${NETWORKMANAGER_LIBRARIES}) target_link_libraries(openfetion ${DBUSGLIB_LIBRARIES}) endif(WITH_NETWORKMANAGER AND NETWORKMANAGER_FOUND AND DBUSGLIB_FOUND) install(TARGETS openfetion RUNTIME DESTINATION ${BIN_INSTALL_DIR}) ########################################################################## file(GLOB openfetion_SKINIMAGES "skin/*.png" "skin/*.svg" "skin/*.gif") file(GLOB openfetion_FACEIMAGES "skin/face_images/*.gif") install(FILES ${openfetion_SKINIMAGES} DESTINATION ${SKIN_INSTALL_DIR}) install(FILES ${openfetion_FACEIMAGES} DESTINATION ${SKIN_INSTALL_DIR}/face_images) install(FILES skin/fetion.svg DESTINATION ${DATA_INSTALL_DIR}/pixmaps) install(FILES openfetion.1 DESTINATION ${MAN_INSTALL_DIR}/man1) if(NLS AND GETTEXT_FOUND) file(GLOB POFILES "${CMAKE_CURRENT_SOURCE_DIR}/po/*.po") gettext_create_translations("${CMAKE_CURRENT_SOURCE_DIR}/po/openfetion.pot" ALL ${POFILES}) endif(NLS AND GETTEXT_FOUND)