qchat-0.3/0000755000076500017500000000000011004460310011160 5ustar owerowerqchat-0.3/src/0000755000076500017500000000000011004461076011761 5ustar owerowerqchat-0.3/src/stylesheets/0000755000076500017500000000000010672341130014333 5ustar owerowerqchat-0.3/src/stylesheets/test.qss0000644000076500017500000000211710672340774016060 0ustar owerower QComboBox:disabled {color: black} QPushButton { background-color: rgb(128, 224, 96); border-style: outset; border-width: 2px; border-radius: 10px; border-color: beige; padding: 2px; } QPushButton:pressed { background-color: #d0e0f0; border-style: inset; border-radius: 15px; } ColorLabel:pressed { background-color: rgb(224, 0, 0); border-style: inset; border-color: gray; border-radius: 8px; } ColorLabel { border-style: ridge; border-width: 3px; border-radius: 8px; border-color: gray; padding: 1px; max-height: 20px; min-height: 20px; } PixLabel { border-style: ridge; border-width: 3px; border-radius: 8px; border-color: gray; padding: 1px; } QTextEdit { background-color: rgb(224, 223, 142); border-style: outset; border-width: 2px; border-radius: 10px; border-color: orange; padding: 2px; } UsersListWgt, QTableView { background-color: rgb(224, 223, 142); border-style: outset; border-width: 2px; border-radius: 10px; border-color: orange; padding: 5px; } qchat-0.3/src/stylesheets/empty0000644000076500017500000000000010672052623015410 0ustar owerowerqchat-0.3/src/translations/0000755000076500017500000000000011004426420014474 5ustar owerowerqchat-0.3/src/translations/qchat_ru.qm0000644000076500017500000006540511002654526016663 0ustar owerower>0h@0Kr0X1n\d2\t2:i2o2u2ju3 3@3xs44C4N50Pqp5_U5c6"iM6l^670H7f `8 80 Rd8] [i8 ]8 o4y9 t7J9 9 /E:s : ; ;L ȏ.; ʟ.; >< O~= $7z> 1:>< hP>r yT> > ? n@ IA* IAa IA IA B 5Bw 6B ?C :CM C %C tC tD DH D} 45D @E EP ^^E nF F7 iFi uF G ~GV G mH PtH2 Hl H H ޠI 猔I\ `I I "J8 J TJ TK +KN  eK} /`EK 1rK A4L, KM N0MF RVM} RVM w'M RN< eN cN x@N xO xOZ O ['P sP7 \Pp P YQ uQ Q *WdR =-RE H 3R MS jSj S ĬT <T? Tb %TzTU ?,U',U55VS\VGs]5VwzwV{ VPWdEW9WSXsXwdrXUY.YH66Z<['?=[{H \ H \iT] pIb]7]v,]]Cu^pCu^^_y_g_H_i`)SingleMsgsHistoryModelAsQObject A sPreferencesDlg.. IpListEditorIPSingleMsgsHistoryModelIPUsersStatisticsModel!OSUsersStatisticsModel:OkFiltrationRuleEditor:OkFormattingToolBar:Ok IpListEditor:OkMessageWithCheckBox:OkShortcutsEditor4 d QObjectG:h:QObject<:m:QObject <A msPreferencesDlg&OK&OKPreferencesDlg&:&Ok AddChannelDlg&:&OkEditUserInfoDlg =0  on  ChannelWgtBACBAB2CNAwayQObjectBoldFormattingToolBar 0=OBBusyQObjectChatQObjectICQ:ICQ:EditUserInfoDlg!2>1>45=FreeQObjectC6A:>9MaleEditUserInfoDlgC6A:>9MaleUsersStatisticsModel  07=>5MiscPreferencesDlgQuitQObjectB?@028BLSend ChannelWgtDisconnected from serverChatWgt&'0B&ChatChatWgt &KE>4&ExitChatWgt&!?@02:0&HelpChatWgt& 07=>5&MiscPreferencesDlg&B?@028BL&SendSingleMessageWgt&84&ViewChatWgt !B8;8 Style SheetsPreferencesDlg16x16ChatWgt24x24ChatWgtDisconnecting from server...ChatWgt32x32ChatWgtEdit IP List.. IpListEditor48x48ChatWgtAbortLogin2ServerDlg QChatAbout AboutQChat@8<5=8BLApplyFiltrationRuleEditor0:@KBLClose AboutQChat0:@KBLCloseFileTransferWgtLoginLogin2ServerDlgText:UserListIconConfigureWgtWidthUserListIconConfigureWgt.Close current message before switching to nextSingleMsgsHistoryView6;02=0O 0=5;L =AB@C<5=B>2 Main ToolbarChatWgt Gender Icon:UserListIconConfigureWgt00720=85 =>2>3> ?@>D8;O:New profile name:ChatWgt >@B: Input/Output Port : PreferencesDlg List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChatColumns count:FormattingToolBarConnect to server..ChatWgtV& 540:B8@>20BL =D>@<0F8N > >;L7>20B5;5...&Edit User Details...ChatWgt Avatar Icon:UserListIconConfigureWgtF2548B5 =0720=85 4;O =>2>3> ?@>D8;OInput name for new profileChatWgt<B>A;0BL 48=>G=>5 !>>1I5=85..Send Single Message.. UsersListWgt Status Icon:UserListIconConfigureWgt,K15@8B5 B5<C A<09;>2:Choose smiles theme:PreferencesDlg!B@>:0 A>>1I5=8O "!59G0A !;CH0N" : (%t - "@5:, %a - @B8AB, %b - 0;L><)=Now Listening string : (%t - Track, %a - Artist, %b - alBum)PreferencesDlg$>18;L=K9 "5;5D>=: Mobile Phone:EditUserInfoDlgNext Opened MessageQObjectNext opened messageSingleMsgsHistoryViewUse Animated SmilesPreferencesDlgChoose protocol version :PreferencesDlg5B $>B>No PhotoEditUserInfoDlg (Not loaded)PreferencesDlgSend Broadcast Message...ChatWgtL@>83@K20BL 2C: ?@8 @8E>45 !>>1I5=8OPlay Sound on Incomig MessagesPreferencesDlg "5:CI89 @>D8;L:Current profile:ChatWgt:&!59G0A !;CH0N ( 87 Amarok1 )Now &Listening (from Amarok1)PreferencesDlg!:@KB85 2 B@59Hiding in trayChatWgtEnter one IP per line IpListEditor"&>1028BL 0=0;..&Add Channel..ChatWgt Enable ruleMessageFilterEditor Nickname :Login2ServerDlgOpened Messages :SingleMsgsHistoryView025@H5=> (%p%)Completed (%p%)FileTransferWgtClose All New MessagesQObject &QChat&AboutChatWgt&@8<5=8BL&ApplyEditUserInfoDlg&@8<5=8BL&ApplyPreferencesDlg&0:@KBL&CloseSingleMessageWgt&B25B8BL&ReplySingleMessageWgt0B0  >645=8O: Date of Born:EditUserInfoDlgPlugins ToolbarChatWgt>;=K9  07<5@ Full SizePixLabel&8F5=78O&LicenseChatWgtN>:070BL AB>@8N 48=>G=KE !>>1I5=89...Show Single Messages History...ChatWgt&&8B8@>20BL Reply &QuotedSingleMessageWgt (Loaded)PreferencesDlg Insert TableFormattingToolBarH>:070BL =D>@<0F8N > >;L7>20B5;5..Show User Information.. UsersListWgtServerless ModeChatWgtConfigure QChatQObjectConfigure Shortcuts...ChatWgt&><0H=OO !B@0=8G:0: Homepage:EditUserInfoDlgMessageSingleMsgsHistoryModel Close ChannelQObjectd#AB0=02;820BL '!59G0A A;CH0N' 2 >?8A0=85 A>AB>O=8O)Set 'Now Listening' in status descriptionPreferencesDlgBG5AB2>: Second Name:EditUserInfoDlg*Direction / Date | IP | Nickname | MessageSingleMsgsHistoryView>2548B5 =>2>5 =0720=85 4;O '%1'Input new name for '%1'ChatWgtN:B828@>20BL :=> ?@8 @8E>45 !>>1I5=8O#Activate Window on Incomin MessagesPreferencesDlg<O ><?LNB5@0 Comp NameUsersStatisticsModel6 07C:@0H820BL 2A5 !>>1I5=85Color Whole MessagePreferencesDlg>$>@<0B >B>1@065=8O A>>1I5=89 : Messages display format : PreferencesDlg !515:About:EditUserInfoDlgActionShortcutsEditor50:B825=InactiveQObjectB>A;0BL $09;.. Send File.. UsersListWgt B<5=0CancelFiltrationRuleEditor B<5=0Cancel IpListEditor B<5=0CancelShortcutsEditor Show PluginsChatWgtIncomingSingleMsgsHistoryModel*#40;8BL ?8A0=85 (%1)Remove Description (%1) StatusEditWgt &!5BL&NetworkPreferencesDlg!5BLNetworkPreferencesDlg5=A:89FemaleEditUserInfoDlg5=A:89FemaleUsersStatisticsModel>;GenderUsersStatisticsModelGermanChatWgtZ0:A8<0;L=>5 :>;8G5AB2> A>>1I5=89 2 >B25B5 : /Maximum number of messages in history answer : PreferencesDlgHeightUserListIconConfigureWgtRegular ExpressionFiltrationRuleEditorItalicFormattingToolBarJ=B5@20; 70?@>A0 8AB>@88 A>>1I5=89 : $Messages history request interval : PreferencesDlg"><0H=89 "5;5D>=: Home Phone:EditUserInfoDlgD>;LH5 =5 ?>:07K20BL MB> A>>1I5=85Don't show this message againChatWgt  01>G89 "5;5D>=: Work Phone:EditUserInfoDlg Load PluginPreferencesDlgFiltration rules :PreferencesDlg Icons SizeChatWgtUse smiles from senderPreferencesDlgPrevious Opened MessageQObjectPrevious opened messageSingleMsgsHistoryView*0AB>@89:8 [@>D8;L: Preferences [Profile: PreferencesDlgAlways use smiles from senderPreferencesDlg $>B>:Photo:EditUserInfoDlg>;LA:89PolishChatWgtRefresh Users ListQObject!59G0A QChat 1C45B 4>ABC?5= 87 A8AB5<=>3> B@5O. A;8 2K 65;05B5 70:@KBL QChat - 8A?>;L7C9B5 459AB285 KE>4 87 <5=N '0B.nNow QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat.ChatWgt (white rule)MessageFilterEditorNext New MessageQObject !<09;KSmilesPreferencesDlg!>AB>O=85StatusUsersStatisticsModelNext new messageSingleMsgsHistoryViewUptimeUsersStatisticsModel Show SmilesQObject$>2>5 !>>1I5=85...New Message... StatusEditWgtNew Messages :SingleMsgsHistoryViewSmiles Policy :PreferencesDlg QChat About QChat AboutQChat<O: First Name:EditUserInfoDlgFormatting ToolbarChatWgtd 540:B8@>20BL =D>@<0F8N > >;L7>20B5;5 [@>D8;L: Edit user details [Profile: EditUserInfoDlg*Direction / IP - Nickname / Date | MessageSingleMsgsHistoryView$0<8;8O: Last Name:EditUserInfoDlg Send MessageQObject6AB>@8O 48=>G=KE !>>1I5=89Single Messages HistoryChatWgt6AB>@8O 48=>G=KE !>>1I5=89Single Messages HistoryQObject5 #25@5=> Not ShureUsersStatisticsModel&0=5;8 =AB@C<5=B>2ToolbarsChatWgt5 #25@5=>Not SureEditUserInfoDlg & Qt About &QtChatWgt Disable ruleMessageFilterEditorh5 =0945=> ?@83>4=KE 4;O @01>BK A5B52KE 8=B5@D59A>2!No valid network interface!ChatWgt Rows count:FormattingToolBarIP List Editor IpListEditorIP 04@5A : IP Address : PreferencesDlg5B 0@B8=:8 No PictureEditUserInfoDlgComputer name(s) to ignore :FiltrationRuleEditor00:@KBL ?>A;5 7025@H5=8OAuto close when completeFileTransferWgt Rule name :FiltrationRuleEditor5@52>4K Translations AboutQChatPluginsPreferencesDlgE>4OI89 >@B:  Input Port : PreferencesDlg Load pluginPreferencesDlgJ5C40G0: ?>;CG0B5;L =5 AB0; ?@8=8<0BLFailed: rejected by receiverFileTransferWgtRB?@02;OBL '!59G0A A;CH0N' A A>>1I5=8O<8 "Send 'Now Listening' with messagesPreferencesDlgX offsetUserListIconConfigureWgtY offsetUserListIconConfigureWgt ImportantSingleMessageWgt!>>1I5=85 :  Message to  UsersListWgt@>D8;LProfilePreferencesDlg Add ProfileQObject<O Real NameUsersStatisticsModelZK 459AB28B5;L=> 65;05B5 2K3@C78BL ?;038= %1?,Are you sure you want to unload plugin '%1'?ChatWgt4525@=K5 A5B52K5 =0AB@>9:8Incorrect network settingsChatWgt607>2K9 F25B 4;O A>>1I5=89:Base Color for Messages : PreferencesDlge-mail:e-mail:EditUserInfoDlg &/7K: &LanguageChatWgt(&25B >8E !>>1I5=89:Color of My Messages : PreferencesDlg8Message filter(one word per line or regular expression):FiltrationRuleEditor0=5;L @>D8;59Profiles ToolbarChatWgtF5C40G0: >B<5=5=> >B?@028B5;5<(%p%)!Failed: cancelled by sender (%p%)FileTransferWgt#:@08=A:89 UkrainianChatWgt1=>28BLRefresh ChannelWgtTK 459AB28B5;L=> 65;05B5 70:@KBL :0=0; %1?,Are you sure you want to close channel '%1'?ChatWgt running QChat  ChannelWgtBroadcast MessageChatWgt(!?8A>: >;L7>20B5;59 Users ListPreferencesDlg (disabled)MessageFilterEditorProfilesQObjectD5C40G0: >B<5=5=> ?>;CG0B5;5<(%p%)"Failed: cancelled by receiver(%p%)FileTransferWgt>2>5 =0720=85: New name:ChatWgtTK?>;=OBL :><<0=4C ?@8 ?@8E>45 A>>1I5=8O :&Execute command on incoming messages :PreferencesDlg"K15@8B5 0@B8=:CChoose PicturePixLabel>1028BL :0=0; Add Channel AddChannelDlg>1028BL :0=0; Add ChannelQObject8!?@OB0BL !8AB5<=K5 !>>1I5=8OHide System Messages ChannelWgtSerbianChatWgt CAA:89RussianChatWgt$?8A0=85 !>AB>O=8OStatus DescriptionUsersStatisticsModel8Unknown option: %1 Use -h for list of available options.QChat Add rule...MessageFilterEditorIP address(es) to ignore :FiltrationRuleEditorJ 07C:@0H820BL A5 !8AB5<=>5 !>>1I5=85Color Whole System MessagePreferencesDlg$&>:070BL !<09;K..&Show Smiles..ChatWgt8:: Nickname:EditUserInfoDlgAvailable Plugins :PreferencesDlgSpanishChatWgt&@8=OBL&AcceptFileTransferWgt!>AB>O=85 (Status (EditUserInfoDlg"0H8 A5B52K5 =0AB@>9:8 =5 A>>B25BAB2CNB =8 >4=><C 87 ACI5AB2CNI8E 8=B5@D59A>2. @>3@0<<0 <>65B =5 @01>B0BL. K 65;05B5 87<5=8BL =0AB@>9:8 A5G0A?Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now?ChatWgt(>1028BL &@>D8;L...Add pro&file...ChatWgtB&<5=0&Cancel AddChannelDlg&B<5=0&CancelEditUserInfoDlg&B<5=0&CancelFileTransferWgt&B<5=0&CancelPreferencesDlg2>;=K9 @07<5@ 87>1@065=8OFull size of picturePictureScrollArea,>;=K9  07<5@ 0@B8=:8Full Size of PicturePixLabel &&25B0&ColorsPreferencesDlg)Author: Ower QChat View Format:SingleMsgsHistoryView 4@5A:Address:EditUserInfoDlgDirection / DateSingleMsgsHistoryModelDefaultChatWgt UnderlineFormattingToolBarClose All Opened MessagesQObjectClose all opened messagesSingleMsgsHistoryView*=B5@20; 1=>2;5=8O :Refresh Interval : PreferencesDlg Unload pluginPreferencesDlg&B25@3=CBL&RejectFileTransferWgt@ 540:B8@>20BL >?8A0=85 A>AB>O=8OEdit status description StatusEditWgt FiltrationPreferencesDlgDisconnect from serverChatWgtSending: %1 Receiver: %2(%3)FileTransferWgt8K15@8B5 $09; 4;O !>E@0=5=8OChoose a file to saveFileTransferWgtUser(s) to ignore :FiltrationRuleEditor4K15@8B5 D09; 4;O B:@KB8OChoose a file to openChatWgt@5<O 2 '0B5 Time in ChatUsersStatisticsModelDelete ProfileQObjectScroll Message History ForwardQObjectB25B8BL =0  Replying to SingleMessageWgtDefaultsShortcutsEditorRename ProfileQObject AE>4OI89 >@B: Output Port : PreferencesDlgQChat %1 - Network chatQChat4(8@>:>25I0B5;L=K9 4@5A : Broadcast Address : PreferencesDlg>;CG5=85 Receiving FileTransferWgt<5C40G0: =5 <>3C >B>A;0BL D09;Failed: cannot send fileFileTransferWgtUsers List Icon Format :PreferencesDlgInput ShortcutShortcutButtonInput ShortcutShortcutGrabber Server IP :Login2ServerDlg Server ModeChatWgt Remove ruleMessageFilterEditorK15@8B5 !B8;L:Choose Style Sheet :PreferencesDlg>7<>6=0 =5C40G0: >B?@02:0 7025@H5=0, => B>;L:> (%p%) ?>4B25@645=>8Possibly failed: sending finished but only %p% confirmedFileTransferWgtBAK;:0Sending FileTransferWgt=3;89A:89EnglishChatWgt58725AB=>UnknownQObject58725AB=>UnknownUsersStatisticsModel#Use IP list instead of broadcasting IpListEditor5 15A?>:>8BLDo not disturbQObjectNew RuleMessageFilterEditorClose all new messagesSingleMsgsHistoryViewMessage SingleMessageWgt!>>1I5=8OMessagesPreferencesDlg!>>1I5=8OMessagesQObject8K15@8B5 !5B52K5 0AB@>9:8 :Choose Network Settings :PreferencesDlgOutgoingSingleMsgsHistoryModel&0AB@>9:8 &SettingsChatWgt &#40;8BL 0=0;..&Delete Channel..ChatWgt0AB@>8BL QChat PreferencesPreferencesDlg@5C40G0: B09<0CB ?>;CG5=8O (%p%)Failed: receiving timeout (%p%)FileTransferWgt52848<K9 InvisibleQObject<O 0=0;0:Channel's Name: AddChannelDlgScroll Message History BackwardQObject>B>2 : G0BCReady for chatQObjectN 540:B8@>20BL =D>@<0F8N > >;L7>20B5;5Edit user detailsEditUserInfoDlg25&@58<5=>20BL @>D8;L...&Rename profile...ChatWgt&&0AB@>8BL QChat...&Configure QChat...ChatWgt@820B=K9 '0B..Private Chat.. UsersListWgt>;:Gender:EditUserInfoDlgGeneralQObjectClear ShortcutShortcutsEditor Direction / IP - Nickname / DateSingleMsgsHistoryModel Total Size:UserListIconConfigureWgtXK 459AB28B5;L=> 65;05B5 C40;8BL ?@>D8;L %1?(Are you sure you want delete profile %1?ChatWgt Old protocolPreferencesDlg New protocolPreferencesDlgEnter table sizeFormattingToolBarPrevious New MessageQObjectPrevious new messageSingleMsgsHistoryViewDon't use Graphic SmilesPreferencesDlg6&25B !8AB5<=KE !>>1I5=89 : Color of System Messages : PreferencesDlgChannelsQObject"B<5=8BL 0@B8=:CCancel PicturePixLabelReceiving: %1 Sender: %2(%3)FileTransferWgt2=D>@<0F8O > >;L7>20B5;5 User detailsEditUserInfoDlg2=D>@<0F8O > >;L7>20B5;5 User DetailsEditUserInfoDlg!Now Listening to : %t by %a on %bQObjectSend Broadcast MessageQObject5 C40;>AL =09B8 =8 >4=>3> H8@>:>25I0B5;L=>3> 8=B5@D59A0.@>3@0<<0 <>65B =5 @01>B0BL.K 65;05B5 ?>A<>B@5BL 20H8 A5B52K5 =0AB@>9:8?|Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings?ChatWgt Use only smiles from local themePreferencesDlg&#40;8BL ?&@>D8;L...Delete p&rofile...ChatWgtL<br><center>!5B52>9 G0B.</center><br> '
Network chat.

 AboutQChatN 540:B8@>20BL =D>@<0F8N > >;L7>20B5;5Edit User DetailsEditUserInfoDlgN 540:B8@>20BL =D>@<0F8N > >;L7>20B5;5Edit User DetailsQObjectShortcutShortcutsEditorFiltration Rule EditorFiltrationRuleEditorUse CompressionPreferencesDlg CAB>5 !>>1I5=85 Empty Message StatusEditWgt>=B5@20; ;C1>:>3> 1=>2;5=8O :Deep Refresh Interval : PreferencesDlg8:NicknameSingleMsgsHistoryModel8:NicknameUsersStatisticsModel0@B8=:0:Picture:EditUserInfoDlg!59G0A !;CH0N Now Listening StatusEditWgt >;L7>20B5;LA:85Custom (not recommended)PreferencesDlg Hide to TrayQObjectK #25@5=K? Are you sure?ChatWgt ) , qchat-0.3/src/translations/qchat_de.ts0000644000076500017500000014061711002654043016627 0ustar owerower AboutQChat Close Schließen <br><center>Network chat.</center><br> Netzwerk chat About Über Translations Übersetzungen About QChat Über QChat AddChannelDlg Add Channel Kanal hinzufügen &Ok &Ok &Cancel &Abbrechen Channel's Name: Kanalname: ChannelWgt on auf running QChat ver. benutzt QChat ver. &Send(CTRL+Space or CTRL+Enter) &Senden(Strg+Space oder Strg+Enter) &Refresh &Aktualisieren Hide System Messages verstecke Systemnachrichten running QChat Send Refresh ChatWgt Are you shure? Sind Sie sicher ? Choose a file to open Wähle zu öffnende Datei Input new name for '%1' Neuen Namen für '%1' eingeben New name: Neuer Name: Input name for new profile Name für neues Profil New profile name: Neuer Profilname: Are you shure you want delete profile %1? Sind Sie sicher, daß sie Profil %1 löschen wollen ? &Edit User Details... &Benutzerdetails ändern... &Preferences... &Einstellungen... &Exit &Beenden &Show Smiles.. &Smilies anzeigen.. &Add Channel.. &Kanal hinzufügen.. &Delete Channel.. &Kanal löschen.. &About &Über About &Qt Über &Qt &License &Lizenz &Write Settings &Einstellungen speichern Main Toolbar Hauptwerkzeugleiste Profiles Toolbar Profilwerkzeugleiste Add pro&file... Pro&fil hinzufügen... Delete p&rofile... P&rofil löschen... &Rename profile... P&rofil umbenennen... Show Single Messages History... Zeige alte Einzelnachrichten... Single Messages History Nachrichtenverlauf &Chat &Chat &View &Ansicht &Settings &Einstellungen &Help &Hilfe &Language &Sprache Toolbars Werkzeugleisten Polish Polnisch Ukrainian Ukrainisch Russian Russisch English Englisch Current profile: Aktuelles Profil: Ctrl+M Single Messages History Strg+M Ctrl+D Show User Details Strg+D Ctrl+P Show Preferences Strg+P Ctrl+Q Quit Strg+Q Ctrl+S Show Smiles Strg+S Ctrl+N Add Channel Strg+N Ctrl+W Del Channel Strg+W Ctrl+Shift+A About Qt Strg+Shift+A Ctrl+L Show License Strg+L Ctrl+Shift+S Write Settings Strg+Shift+S Ctrl+Shift+N Add Profile Strg+Shift+N Ctrl+Shift+D Del Profile Strg+Shift+D Ctrl+Shift+R Rename Profile Strg+Shift+R Ctrl+Alt+U Set Ukrainian Strg+Alt+U Ctrl+Alt+P Set Polish Strg+Alt+P Ctrl+Alt+R Set Russian Strg+Alt+R Ctrl+Alt+E Set English Strg+Alt+E Ctrl+Shift+M Show Main Toolbar Strg+Shift+M Ctrl+Shift+P Show Profiles Toolbar Strg+Shift+P Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now? Die Netzwerkeinstellungen stimmen mit keiner vorhandenen Netzwerkschnittstelle überein. Wollen Sie trotzem die Einstellung vornehmen ? Incorrect network settings Falsche Netzwerkeinstellungen Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings? Konnte keine Netzwerkschnittstelle für Broadcast finden. Möchten Sie sich die Netzwerkeinstellungen ansehen ? No valid network interface! Keine gültige Netzwerkschnittstelle! Hiding in tray In Tray verstecken Now QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat. QChat ist nun über das Systemtray verfügbar. Wenn Sie QChat beenden wollen, benutzen sie Beenden im Chatmenü. Don't show this message again Nachricht nicht mehr anzeigen Are you sure? Are you sure you want to unload plugin '%1'? Are you sure you want to close channel '%1'? Are you sure you want delete profile %1? &Configure QChat... Configure Shortcuts... Plugins Toolbar Formatting Toolbar Show Plugins Send Broadcast Message... Spanish German Serbian Connect to server.. Disconnect from server Server Mode Serverless Mode Default 16x16 24x24 32x32 48x48 Icons Size Disconnecting from server... Disconnected from server Broadcast Message EditUserInfoDlg Status ( Status ( Edit user details [Profile: Benutzerdetails ändern [Profil: User details Benutzerdetails &Ok &Ok User Details Benutzerdetails &Cancel &Abbrechen Edit User Details Benutzerdetails ändern &Apply &Anwenden No Photo Kein Photo No Picture Kein Bild Nickname: Nickname: Last Name: Nachname: First Name: Vorname: Second Name: Mittlerer Name: Date of Birth: Geburtstag: Address: Adresse: Home Phone: Telephon (privat): Work Phone: Telephon (gesch.): Mobile Phone: Telephon (mobil): e-mail: e-mail: ICQ: ICQ: Homepage: Homepage: About: Über: Picture: Bild: Photo: Photo: Gender: Geschlecht: Male Männlich Female Weiblich Not Sure weiss nicht Edit user details Benutzerdetails ändern Date of Born: FileTransferWgt &Cancel &Abbrechen &Accept A&nnehmen &Reject A&blehnen Auto close when complete Automatisch schliessen wenn komplett Sending Sende Receiving Empfange Choose a file to save Dateiname wählen Completed (%p%) Fertiggestellt (%p%) Close Schliessen Failed: cancelled by receiver(%p%) Abbruch durch Empfänger (%p%) Failed: cancelled by sender (%p%) Abbruch durch Sender (%p) Failed: cannot send file Abbruch : Kann Datei nicht senden Failed: rejected by receiver Abbruch : abgelehnt Failed: receiving timeout (%p%) Abbruch : timeout (%p%) Possibly failed: sending finished but only %p% confirmed Evtl. Fehler : Sendevorgang abgeschlossen aber nur %p% bestätigt Receiving: %1 Sender: %2(%3) Sending: %1 Receiver: %2(%3) FiltrationRuleEditor Regular Expression Ok Ok Apply Cancel Rule name : User(s) to ignore : Computer name(s) to ignore : IP address(es) to ignore : Message filter(one word per line or regular expression): Filtration Rule Editor FormattingToolBar Ok Ok Bold Italic Underline Insert Table Enter table size Rows count: Columns count: IpListEditor Use IP list instead of broadcasting .. Ok Ok Cancel Edit IP List.. Enter one IP per line IP List Editor Login2ServerDlg Server IP : Nickname : Login Abort MessageFilterEditor Disable rule Add rule... Remove rule (disabled) (white rule) New Rule Enable rule MessageWithCheckBox Ok Ok PictureScrollArea Full size of picture Vollbildanzeige PixLabel Cancel Picture Bild Abbrechen Full Size Volle Größe Choose Picture Bild auswählen Full Size of Picture Volle Bildgröße PreferencesDlg Input/Output Port : Ein/Ausgabe Port : Input Port : Eingangsport : Preferences [Profile: Einstellungen [Profil: Color of My Messages : Nachrichten einfärben : Color of System Messages : Farbe Systemnachrichten : Base Color for Messages : Farbe Nachrichten : IP Address : IP Adresse : Broadcast Address : Broadcast Addresse : Now Listening string : (%t - Track, %a - Artist, %b - alBum) Hört gerade Mitteilung : (%t - Track, %a - Artist, %b - Album) &Colors &Farben &Network &Netzwerk &Misc &Sonst Now &Listening (from Amarok1) Hört &gerade (von Amarok1) Choose smiles theme: Wähle Smilietheme : Users List Benutzerliste Choose Style Sheet : Wähle Style Sheet : &OK &OK &Cancel &Abbrechen &Apply &Anwenden Color Whole Message Färbe gesamte Nachricht Color Whole System Message Färbe gesamte Systemnachricht Activate Window on Incomin Messages Aktiviere Fenster bei eingehenden Nachrichten Play Sound on Incomig Messages Spiele Ton bei eingehenden Nachrichten Send 'Now Listening' with messages Sende 'Hört gerade' mit Nachrichten Set 'Now Listening' in status description Zeige 'hört gerade' in Statusbeschreibung Output Port : Ausgabe Port : Profile Profil Misc Sonst Messages Nachrichten Network Netzwerk Smiles Smilies Style Sheets Style Sheets Execute command on incoming messages : Führe Befehl bei eingehenden Nachrichten aus : Messages display format : Darstellungsformat Nachrichten : Messages history request interval : Nachrichtenverlauf Anfrageintervall : Maximum number of messages in history answer : Höchstanzahl Nachrichten in Verlauf : Refresh Interval : Aktualisierungsrate : Deep Refresh Interval : Tiefe Aktualisierungsrate : Choose Network Settings : Wähle Netzwerkeinstellungen : ms milliseconds ms s seconds s Preferences Einstellungen Custom (not recommended) benutzerdefiniert (nicht empfohlen) Available Plugins : Users List Icon Format : Filtration rules : Choose protocol version : Plugins Filtration Load Plugin Use Compression Use Animated Smiles Smiles Policy : Don't use Graphic Smiles Use only smiles from local theme Use smiles from sender Always use smiles from sender Old protocol New protocol (Loaded) (Not loaded) Unload plugin Load plugin QChat Unknown option: %1 Use -h for list of available options. List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChat %1 - Network chat Author: Ower <ower@users.sourceforge.net> QObject Busy Beschäftigt Free Frei Ready for chat Bereit für Chat Do not disturb Nicht stören Inactive Inaktiv Away Weg Invisible Unsichtbar Now Listening to : %t by %a on %b Hört gerade : %t von %a auf %b Unknown OS Unbekannt d day t h: hour std: m: minute m: s second s Send Message Chat Scroll Message History Forward Scroll Message History Backward Refresh Users List Channels Show Smiles Single Messages History Nachrichtenverlauf General Edit User Details Benutzerdetails ändern Configure QChat Quit Add Channel Kanal hinzufügen Close Channel Add Profile Profiles Delete Profile Rename Profile Hide to Tray Send Broadcast Message Next New Message Messages Nachrichten Previous New Message Next Opened Message Previous Opened Message Close All New Messages Close All Opened Messages ShortcutButton Input Shortcut ShortcutGrabber Input Shortcut ShortcutsEditor Action Shortcut Ok Ok Cancel Defaults Clear Shortcut SingleMessageWgt Message from Nachricht von &Close &Schliessen &Send &Abschicken &Reply &Antworten Reply &Quoted Antworten (&zitiert) Replying to Antworten an Message Important SingleMsgsHistoryModel Direction / IP - Nickname / Date IP IP Nickname Nickname Message Incoming Outgoing Direction / Date SingleMsgsHistoryView New Messages : Opened Messages : Direction / IP - Nickname / Date | Message Direction / Date | IP | Nickname | Message View Format: Next new message Previous new message Next opened message Previous opened message Close all new messages Close all opened messages Close current message before switching to next StatusEditWgt Edit status description Statusbeschreibung bearbeiten New Message... Neue Nachricht... Empty Message Leere Nachricht Now Listening Hört gerade Remove Description (%1) Beschreibung (%1) entfernen UserListIconConfigureWgt Total Size: Gender Icon: Status Icon: Avatar Icon: Text: Width Height X offset Y offset UsersListWgt Send Single Message.. Einzelnachricht senden.. Show User Information.. Zeige Benutzerinformationen.. Send File.. Sende Datei.. Private Chat.. Privatchat.. Message to Nachricht an UsersStatisticsModel Male männlich Female weiblich Not Shure weiss nicht Unknown unbekannt Nickname Nickname Gender Geschlecht Real Name Realname Status Status Status Description Statusbeschreibung IP IP Comp Name Rechnername OS BS Uptime Anwesend Time in Chat Zeit im Chat qchat-0.3/src/translations/qchat_es.ts0000644000076500017500000013724311002654043016647 0ustar owerower AboutQChat Close Cerrar <br><center>Network chat.</center><br> <br><center>Chat de red.</center><br> About Acerca de Translations Traducciones About QChat Acerca de QChat AddChannelDlg Add Channel Añadir Canal &Ok &Ok &Cancel &Cancel Channel's Name: Nombre del Canal: ChannelWgt on enc running QChat ver. ejecutando QChat ver. &Send(CTRL+Space or CTRL+Enter) &Enviar(CTRL+Espacio o CTRL+Enter) &Refresh &Refrescar Hide System Messages Ocultar mensajes del sistema running QChat Send Refresh ChatWgt Are you shure? ¿Estas seguro? Choose a file to open Escoge un archivo a abrir Input new name for '%1' Nuevo nombre para '%1' New name: Nuevo nombre: Input name for new profile Nombre para el nuevo perfil New profile name: Nuevo nombre de perfil: Are you shure you want delete profile %1? ¿Estas seguro de que quieres borrar el perfil %1? &Edit User Details... &Editar detalles de usuario... &Preferences... &Opciones... &Exit &Salir &Show Smiles.. &Mostrar emoticonos.. &Add Channel.. &Añadir canal.. &Delete Channel.. &Borrar canal.. &About &Sobre About &Qt Sobre &Qt &License &Licencia &Write Settings &Escribir ajustes Main Toolbar Barra de herramientas principal Profiles Toolbar Barra de herramientas de perfiles Add pro&file... Añadir per&fil... Delete p&rofile... Borrar p&erfil... &Rename profile... &Renombrar perfil... &Chat &Chat &Settings &Ajustes &Help A&yuda &Language &Idioma Toolbars Barras Ukrainian Ucraniano Russian Ruso English Inglés Current profile: Perfil actual: Ctrl+D Show User Details Ctrl+D Ctrl+P Show Preferences Ctrl+P Ctrl+Q Quit Ctrl+Q Ctrl+S Show Smiles Ctrl+S Ctrl+N Add Channel Ctrl+N Ctrl+W Del Channel Ctrl+W Ctrl+Shift+A About Qt Ctrl+Shift+A Ctrl+L Show License Ctrl+L Ctrl+Shift+S Write Settings Ctrl+Shift+S Ctrl+Shift+N Add Profile Ctrl+Shift+N Ctrl+Shift+D Del Profile Ctrl+Shift+D Ctrl+Shift+R Rename Profile Ctrl+Shift+R Ctrl+Shift+M Show Main Toolbar Ctrl+Shift+M Ctrl+Shift+P Show Profiles Toolbar Ctrl+Shift+P Show Single Messages History... Mostrar historial de mensajes... Single Messages History Historial de mensajes &View &Ver Polish Polaco Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now? Tua ajustes de red no corresponden a ninguna interfaz de red. El programa puede no funcionar. ¿Deseas configurarlo ahora? Incorrect network settings Ajustes de red incorrectos Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings? No se puede encontrar ninguna interfaz de red que pueda hacer difusión. El programa puede no funcionar. ¿Deseas ver los ajustes de red? No valid network interface! ¡Ninguna interfaz de red válida! Hiding in tray Esconder en bandeja Now QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat. Ahora QChat estará disponible en la bandeja del sistema. Si quieres salir de QChat - usa Salir en el menú Chat. Don't show this message again No volver a mostrar este mensaje Are you sure? Are you sure you want to unload plugin '%1'? Are you sure you want to close channel '%1'? Are you sure you want delete profile %1? &Configure QChat... Configure Shortcuts... Plugins Toolbar Formatting Toolbar Show Plugins Send Broadcast Message... Spanish German Serbian Connect to server.. Disconnect from server Server Mode Serverless Mode Default 16x16 24x24 32x32 48x48 Icons Size Disconnecting from server... Disconnected from server Broadcast Message EditUserInfoDlg Status ( Estado ( Edit user details [Profile: Editar detalles de usuario [Perfil: User details Detalles de usuario &Ok &Ok User Details Detalles de usuario &Cancel &Cancelar Edit User Details Editar detalles de usuario &Apply &Aplicar No Photo Sin foto No Picture Sin dibujo Nickname: Nick: Last Name: Nombre: First Name: Primer apellido: Second Name: Segundo apellido: Date of Born: Fecha de nacimiento: Address: Dirección: Home Phone: Teléfono de casa: Work Phone: Teléfono del trabajo: Mobile Phone: Teléfono móvil: e-mail: correo-e: ICQ: ICQ: Homepage: Página web: About: Sobre: Edit user details Editar detalles de usuario Picture: Imagen: Photo: Foto: Gender: Género: Male Hombre Female Mujer Not Sure Sin seguridad FileTransferWgt &Cancel &Cancelar &Accept &Aceptar &Reject &Rechazar Auto close when complete Auto cerrar cuando se complete Sending Enviando Receiving Recibiendo Choose a file to save Elige un fichero para salvar Completed (%p%) Completado (%p%) Close Cerrar Failed: cancelled by receiver(%p%) Falló: cancelado por el destinatario(%p%) Failed: cancelled by sender (%p%) Falló: cancelado por el emisor (%p%) Failed: cannot send file Error: no se pudo enviar el archivo Failed: rejected by receiver Error: rechazo del destinatario Failed: receiving timeout (%p%) Error: recibido el tiempo de espera (%p%) Possibly failed: sending finished but only %p% confirmed Posible erro: envio finalizado pero se confirmo solo el %p% Receiving: %1 Sender: %2(%3) Sending: %1 Receiver: %2(%3) FiltrationRuleEditor Regular Expression Ok Ok Apply Cancel Rule name : User(s) to ignore : Computer name(s) to ignore : IP address(es) to ignore : Message filter(one word per line or regular expression): Filtration Rule Editor FormattingToolBar Ok Ok Bold Italic Underline Insert Table Enter table size Rows count: Columns count: IpListEditor Use IP list instead of broadcasting .. Ok Ok Cancel Edit IP List.. Enter one IP per line IP List Editor Login2ServerDlg Server IP : Nickname : Login Abort MessageFilterEditor Disable rule Add rule... Remove rule (disabled) (white rule) New Rule Enable rule MessageWithCheckBox Ok Ok PictureScrollArea Full size of picture Tamaño completo de la imagen PixLabel Cancel Picture Cancelar imagen Full Size Tamaño completo Choose Picture Elegir imagen Full Size of Picture Tamaño completo de la imagen PreferencesDlg Input/Output Port : Puerto E/S: Input Port : Puerto Entrda : Preferences [Profile: Opciones [Perfil: Color of My Messages : Color de mis mensajes : Color of System Messages : Color de los mensajes del sistema : Base Color for Messages : Color base de los mensajes : IP Address : Dirección IP : Broadcast Address : Dirección difusión : &Colors &Colores &Network &Red &Misc &Misc Now &Listening (from Amarok1) &Escuchando (desde Amarok1) Choose smiles theme: Elige tema de emoticonos: &OK &Ok &Cancel &Cancelar &Apply &Aplicar Color Whole Message Color de todo el mensaje Color Whole System Message Color de todo el mensaje del sistema Activate Window on Incomin Messages Activar ventana en mensajes entrantes Play Sound on Incomig Messages Reproducir un sonido en mensajes entrantes Send 'Now Listening' with messages Enviar 'Ahora escuchando' con los mensajes Set 'Now Listening' in status description Poner 'Ahora escuhando' en el estado de la descripción Output Port : Puerto salida : Profile Perfil Misc Misc Messages Mensajes Network Red Smiles Emoticonos Preferences Opciones Now Listening string : (%t - Track, %a - Artist, %b - alBum) Ahora escuhando string : (%t - Track, %a - Artist, %b - alBum) Users List Lista de usuarios Choose Style Sheet : Elige hoja de estilo : Style Sheets Hojas de estilo Execute command on incoming messages : Ejecutar comando en mensajes entrantes : Messages display format : Formato de los mensajes : Messages history request interval : Intérvalo de petición de mensajes : Maximum number of messages in history answer : Máximo número de mensajes en el hsitorial de respuestas : Refresh Interval : Intérvalo de refresco : Deep Refresh Interval : Intervalo de refresco prof. : Choose Network Settings : Elige ajustes de red : ms milliseconds ms s seconds s Custom (not recommended) Personalizado (no recomendado) Available Plugins : Users List Icon Format : Filtration rules : Choose protocol version : Plugins Filtration Load Plugin Use Compression Use Animated Smiles Smiles Policy : Don't use Graphic Smiles Use only smiles from local theme Use smiles from sender Always use smiles from sender Old protocol New protocol (Loaded) (Not loaded) Unload plugin Load plugin QChat Unknown option: %1 Use -h for list of available options. List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChat %1 - Network chat Author: Ower <ower@users.sourceforge.net> QObject Busy Ocupado Free Libre Ready for chat Listo para charlar Do not disturb No molestar Inactive Inactivo Away Ausente Invisible invisible Now Listening to : %t by %a on %b Escuchando a : %t by %a on %b Unknown OS Desconocido d day d h: hour h: m: minute m: s second s Send Message Chat Scroll Message History Forward Scroll Message History Backward Refresh Users List Channels Show Smiles Single Messages History Historial de mensajes General Edit User Details Editar detalles de usuario Configure QChat Quit Add Channel Añadir Canal Close Channel Add Profile Profiles Delete Profile Rename Profile Hide to Tray Send Broadcast Message Next New Message Messages Mensajes Previous New Message Next Opened Message Previous Opened Message Close All New Messages Close All Opened Messages ShortcutButton Input Shortcut ShortcutGrabber Input Shortcut ShortcutsEditor Action Shortcut Ok Ok Cancel Defaults Clear Shortcut SingleMessageWgt &Close &Cerrar &Send &Enviar &Reply &Responder Reply &Quoted Responder &citado Replying to Respondiendo a Message from Mensaje de Message Important SingleMsgsHistoryModel Direction / IP - Nickname / Date IP IP Nickname Alias Message Incoming Outgoing Direction / Date SingleMsgsHistoryView New Messages : Opened Messages : Direction / IP - Nickname / Date | Message Direction / Date | IP | Nickname | Message View Format: Next new message Previous new message Next opened message Previous opened message Close all new messages Close all opened messages Close current message before switching to next StatusEditWgt Edit status description Editar la descripción del estado New Message... Nuevo mensaje... Empty Message Mensaje en blanco Now Listening Ahora escuchando Remove Description (%1) Borrar descripción (%1) UserListIconConfigureWgt Total Size: Gender Icon: Status Icon: Avatar Icon: Text: Width Height X offset Y offset UsersListWgt Send Single Message.. Enviar mensaje único.. Show User Information.. Mostrar información del usuario.. Send File.. Enviar fichero.. Private Chat.. Chat privado.. Message to Mensaje a UsersStatisticsModel Male Hombre Female Mujer Not Shure Sin seguridad Unknown Desconocido Nickname Alias Gender Género Real Name Nombre real Status Estado Status Description Descripción del estado IP IP Comp Name Nombre de la compañía OS SO Uptime Tiempo disponible Time in Chat Tiempo en chat qchat-0.3/src/translations/qchat_sr.qm0000644000076500017500000002516011002652422016644 0ustar owerower_Kr}Xu /sGCNPqpciM?^( Rd o4y t7J# ; /E   ʟ. > e) S>c $7z yT   n I I) IS I}  5 6  453 g ^^y u ~  % ޠ? `_  "  1r A43 K N0 RV RV R x1 C s \  Y u% = =-Y DY} DY DY DY DZ DZ1 DZW H 3 M  Ĭ{ KEuSGssdr.<?=H  G, } Cu  !y!+!qi!s sekundasekundeIPOS Uredudanh:m:milisekunde &Uredu &Uredu AddChannelDlg &UredunaOdsutan ZauzetICQ:Slobodan MuakoEditUserInfoDlg MuakoMisc &Chat &Izlaz &Pomo &Misc&Poaalji&Pregled Datoteka o StiluO ProgramuZatvori AboutQChatZatvoriGlavni Toolbar"Novo ime profila:&Input/Output Port ::&Uredi korisnikove detalje....Stavi ime za nov profil,Poaalji Li nu Poruku..,Izaberi temu smajlija:Trenutno Sluaam : (new line) (%t - Track, %a - Artist, %b - alBum) Mobilni Telefon:Bez Slike<Play Sound on Incomig Messages Trenutni Profil:>Trenutno &Sluaam (from Amarok1)Sakrij u tray&Dodaj Kanal..Zavraeno (%p%)&O Programu&PrihvatiEditUserInfoDlg&Prihvati&Zatvori&OdgovoriDatum Roenja:Puna Veli ina&LicencaHPrika~i istoriju privatnih poruka..."Odgovori &Citiraj2Informacije o Korisniku..Web Stranica:XStavi 'Stavi Trenutno Sluaam' u opis statusaSrednja ime:*Izaberi novo ime '%1'FActivate Window on Incomin MessagesIme Ra unara Oboji celu poruu0Messages display forma :O meni:Neaktivan$Poaalji datoteku..Poruka Od>Prika~i informacije o korisnikuPria~i Licencu2Istorija Privatnih PorukaDodaj Kanal$Pria~i Podeaavanja Izlaz Prika~i SmajlijeIzbriai Kanal Ukloni Opis (%1) &Mre~a Mre~a }enskoEditUserInfoDlg }enskoPol\Maximum number of messages in history answer :FMessages history request interval :Kuni Telefon:6Ne prikazuj ovu poruku opet"Telefon sa Posla:(Podeaavanje Profila: Slika:PoljskiSada e QChat biti dostupan iz sistemskog traya. Ako ~elia da ugasia QChat - koristi Izlaz iz menia Chat. SmajliTrenutno Stanje&&Zapiai PodeaavanjaVreme RadaNova Poruka... O programu QChatIme:bJesi li siguran da ~elia izbrisat ovaj profil %1?FUredi korisnikov detaljni [Profil:Prezime:2Istorija privatnih porukaNisam SiguranToolbarsNisam Siguran O &Qt6No valid network interface!vozi QChat ver.IP Adresa :Bez AvataraBAutomatski zatvori kada se zavraiPrevodiInput Port :8Failed: rejected by receiverDSend 'Now Listening' with messagesPoruka za ProfilPravo Ime6Pogreana mre~na podeaavanja>Osnovna paleta boja za poruke :e-mail: &Jezik&Boje mojih poruka : Profiles ToolbarBFailed: cancelled by sender (%p%)Ukrajinski&Osve~iLista KorisnikaDFailed: cancelled by receiver(%p%)Novo Ime:LExecute command on incoming messages :Izaberi SlikuDodaj Kanal.Sakrij sistemsku poruku RuskiOpis Stanja4Color Whole System Message"&Prika~i Smajle..Nadimak:&PrihvatiStatus (Tvoja mre~na podeaavanja ne sla~u se sa mre~nim interfejsom tako da program verovatno nee radit dali ga ~elite konfigurisati sada? Dodaj Pro&fil...&Poniati AddChannelDlg&PoniatiEditUserInfoDlg&PoniatiFileTransferWgt&Poniati&Puna veli ina slike&Puna veli ina slike&Paleta Boja$Adresa Stanovanja:.Vremensko Osve~avanja : &Odbij.Promeni trenutno stanje*Choose a file to save Izaberi datotekuVreme na ChatuOdgovor zaOutput Port :$Broadcast Adresa :Primanje0Failed: cannot send file&Podeaavanja...4Izaberi datoteke o stilu :pPossibly failed: sending finished but only %p% confirmed `aljiEngleskiNepoznat OSQObjectNepoznatoNe Uznemiravaj Poruke8Izaberi Mre~na Podeaavanja :&Podeaavanja &Izbriai Kanal..Podeaavanja>Failed: receiving timeout (%p%)NevidljivIme Kanala:Spreman za chatO QTIzbriai Profil,Prika~i Glavni ToolbarDodaj Profil.Prika~i Toolbar Profila Preimenuj Profil$Zapiai Podeaavanja.Uredi Korisnikov Profil(&Preimenuj Profil...Privatni Chat..Pol:0Boje Sistemskih Poruka :D&Poaalji(CTRL+Space or CTRL+Enter)Poniati SlikuPotavi EngleskiPostavi PoljskiPostavi Ruski$Postavi Ukrajinski&Detalji o Korisniku&Detalji o Korisniku>Trenutno Sluaa : %t by %a on %bProgram nije naaao mre~ni interfejs i nemo~e da radi Da li ~elia da pregledaa tvoja mre~na podeaavanja?$Izbriai P&rofil...`<br><center>Lokalni chat.</center><br>(new line)0Uredi Korisnikove ProfilPrazna Poruka<Duboko Vremensko Osve~avanje :NadimakAvatar:Trenutno Sluaam@Proizvoljno (nije preporu ljivo) Jesi li siguran?/$-5;KRW\dmPixLabelUsersStatisticsModelPictureScrollAreaFileTransferWgtEditUserInfoDlgPreferencesDlg AboutQChatMessageWithCheckBox ChannelWgt UsersListWgtQObjectChatWgt AddChannelDlgSingleMessageWgt StatusEditWgtqchat-0.3/src/translations/qchat_sr.ts0000644000076500017500000014055211002654043016661 0ustar owerower AboutQChat Close Zatvori <br><center>Network chat.</center><br> <br><center>Lokalni chat.</center><br>(new line) About O Programu Translations Prevodi About QChat O programu QChat AddChannelDlg Add Channel Dodaj Kanal &Ok &Uredu &Cancel &Poništi Channel's Name: Ime Kanala: ChannelWgt on na running QChat ver. vozi QChat ver. &Send(CTRL+Space or CTRL+Enter) &Pošalji(CTRL+Space or CTRL+Enter) &Refresh &Osveži Hide System Messages Sakrij sistemsku poruku running QChat Send Refresh ChatWgt Are you shure? Jesi li siguran? Choose a file to open Izaberi datoteku Input new name for '%1' Izaberi novo ime '%1' New name: Novo Ime: Input name for new profile Stavi ime za nov profil New profile name: Novo ime profila: Are you shure you want delete profile %1? Jesi li siguran da želiš izbrisat ovaj profil %1? &Edit User Details... &Uredi korisnikove detalje... &Preferences... &Podešavanja... &Exit &Izlaz &Show Smiles.. &Prikaži Smajle.. &Add Channel.. &Dodaj Kanal.. &Delete Channel.. &Izbriši Kanal.. &About &O Programu About &Qt O &Qt &License &Licenca &Write Settings &Zapiši Podešavanja Main Toolbar Glavni Toolbar Profiles Toolbar Profiles Toolbar Add pro&file... Dodaj Pro&fil... Delete p&rofile... Izbriši P&rofil... &Rename profile... &Preimenuj Profil... Show Single Messages History... Prikaži istoriju privatnih poruka... Single Messages History Istorija privatnih poruka &Chat &Chat &View &Pregled &Settings &Podešavanja &Help &Pomoć &Language &Jezik Toolbars Toolbars Polish Poljski Ukrainian Ukrajinski Russian Ruski English Engleski Current profile: Trenutni Profil: Ctrl+M Single Messages History Istorija Privatnih Poruka Ctrl+D Show User Details Prikaži informacije o korisniku Ctrl+P Show Preferences Priaži Podešavanja Ctrl+Q Quit Izlaz Ctrl+S Show Smiles Prikaži Smajlije Ctrl+N Add Channel Dodaj Kanal Ctrl+W Del Channel Izbriši Kanal Ctrl+Shift+A About Qt O QT Ctrl+L Show License Priaži Licencu Ctrl+Shift+S Write Settings Zapiši Podešavanja Ctrl+Shift+N Add Profile Dodaj Profil Ctrl+Shift+D Del Profile Izbriši Profil Ctrl+Shift+R Rename Profile Preimenuj Profil Ctrl+Alt+U Set Ukrainian Postavi Ukrajinski Ctrl+Alt+P Set Polish Postavi Poljski Ctrl+Alt+R Set Russian Postavi Ruski Ctrl+Alt+E Set English Potavi Engleski Ctrl+Shift+M Show Main Toolbar Prikaži Glavni Toolbar Ctrl+Shift+P Show Profiles Toolbar Prikaži Toolbar Profila Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now? Tvoja mrežna podešavanja ne slažu se sa mrežnim interfejsom tako da program verovatno neće radit dali ga želite konfigurisati sada? Incorrect network settings Pogrešna mrežna podešavanja Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings? Program nije našao mrežni interfejs i nemože da radi Da li želiš da pregledaš tvoja mrežna podešavanja? No valid network interface! No valid network interface! Hiding in tray Sakrij u tray Now QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat. Sada će QChat biti dostupan iz sistemskog traya. Ako želiš da ugasiš QChat - koristi Izlaz iz menia Chat. Don't show this message again Ne prikazuj ovu poruku opet Are you sure? Are you sure you want to unload plugin '%1'? Are you sure you want to close channel '%1'? Are you sure you want delete profile %1? &Configure QChat... Configure Shortcuts... Plugins Toolbar Formatting Toolbar Show Plugins Send Broadcast Message... Spanish German Serbian Connect to server.. Disconnect from server Server Mode Serverless Mode Default 16x16 24x24 32x32 48x48 Icons Size Disconnecting from server... Disconnected from server Broadcast Message EditUserInfoDlg Status ( Status ( Edit user details [Profile: Uredi korisnikov detaljni [Profil: User details Detalji o Korisniku &Ok &Uredu User Details Detalji o Korisniku &Cancel &Poništi Edit User Details Uredi Korisnikove Profil &Apply &Prihvati No Photo Bez Slike No Picture Bez Avatara Nickname: Nadimak: Last Name: Prezime: First Name: Ime: Second Name: Srednja ime: Date of Born: Datum Rođenja: Address: Adresa Stanovanja: Home Phone: Kućni Telefon: Work Phone: Telefon sa Posla: Mobile Phone: Mobilni Telefon: e-mail: e-mail: ICQ: ICQ: Homepage: Web Stranica: About: O meni: Picture: Avatar: Photo: Slika: Gender: Pol: Male Muško Female Žensko Not Sure Nisam Siguran Edit user details Uredi Korisnikov Profil FileTransferWgt &Cancel &Poništi &Accept &Prihvati &Reject &Odbij Auto close when complete Automatski zatvori kada se završi Sending Šalji Receiving Primanje Choose a file to save Choose a file to save Completed (%p%) Završeno (%p%) Close Zatvori Failed: cancelled by receiver(%p%) Failed: cancelled by receiver(%p%) Failed: cancelled by sender (%p%) Failed: cancelled by sender (%p%) Failed: cannot send file Failed: cannot send file Failed: rejected by receiver Failed: rejected by receiver Failed: receiving timeout (%p%) Failed: receiving timeout (%p%) Possibly failed: sending finished but only %p% confirmed Possibly failed: sending finished but only %p% confirmed Receiving: %1 Sender: %2(%3) Sending: %1 Receiver: %2(%3) FiltrationRuleEditor Regular Expression Ok Uredu Apply Cancel Rule name : User(s) to ignore : Computer name(s) to ignore : IP address(es) to ignore : Message filter(one word per line or regular expression): Filtration Rule Editor FormattingToolBar Ok Uredu Bold Italic Underline Insert Table Enter table size Rows count: Columns count: IpListEditor Use IP list instead of broadcasting .. Ok Uredu Cancel Edit IP List.. Enter one IP per line IP List Editor Login2ServerDlg Server IP : Nickname : Login Abort MessageFilterEditor Disable rule Add rule... Remove rule (disabled) (white rule) New Rule Enable rule MessageWithCheckBox Ok Uredu PictureScrollArea Full size of picture Puna veličina slike PixLabel Cancel Picture Poništi Sliku Full Size Puna Veličina Choose Picture Izaberi Sliku Full Size of Picture Puna veličina slike PreferencesDlg Input/Output Port : Input/Output Port : Input Port : Input Port : Preferences [Profile: Podešavanje Profila: Color of My Messages : Boje mojih poruka : Color of System Messages : Boje Sistemskih Poruka : Base Color for Messages : Osnovna paleta boja za poruke : IP Address : IP Adresa : Broadcast Address : Broadcast Adresa : Now Listening string : (%t - Track, %a - Artist, %b - alBum) Trenutno Slušam : (new line) (%t - Track, %a - Artist, %b - alBum) &Colors &Paleta Boja &Network &Mreža &Misc &Misc Now &Listening (from Amarok1) Trenutno &Slušam (from Amarok1) Choose smiles theme: Izaberi temu smajlija: Users List Lista Korisnika Choose Style Sheet : Izaberi datoteke o stilu : &OK &Uredu &Cancel &Poništi &Apply &Prihvati Color Whole Message Oboji celu poruu Color Whole System Message Color Whole System Message Activate Window on Incomin Messages Activate Window on Incomin Messages Play Sound on Incomig Messages Play Sound on Incomig Messages Send 'Now Listening' with messages Send 'Now Listening' with messages Set 'Now Listening' in status description Stavi 'Stavi Trenutno Slušam' u opis statusa Output Port : Output Port : Profile Profil Misc Misc Messages Poruke Network Mreža Smiles Smajli Style Sheets Datoteka o Stilu Execute command on incoming messages : Execute command on incoming messages : Messages display format : Messages display forma : Messages history request interval : Messages history request interval : Maximum number of messages in history answer : Maximum number of messages in history answer : Refresh Interval : Vremensko Osvežavanja : Deep Refresh Interval : Duboko Vremensko Osvežavanje : Choose Network Settings : Izaberi Mrežna Podešavanja : ms milliseconds milisekunde s seconds sekunde Preferences Podešavanja Custom (not recommended) Proizvoljno (nije preporučljivo) Available Plugins : Users List Icon Format : Filtration rules : Choose protocol version : Plugins Filtration Load Plugin Use Compression Use Animated Smiles Smiles Policy : Don't use Graphic Smiles Use only smiles from local theme Use smiles from sender Always use smiles from sender Old protocol New protocol (Loaded) (Not loaded) Unload plugin Load plugin QChat Unknown option: %1 Use -h for list of available options. List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChat %1 - Network chat Author: Ower <ower@users.sourceforge.net> QObject Now Listening to : %t by %a on %b Trenutno Sluša : %t by %a on %b Busy Zauzet Free Slobodan Ready for chat Spreman za chat Do not disturb Ne Uznemiravaj Inactive Neaktivan Away Odsutan Invisible Nevidljiv Unknown OS Nepoznat OS d day dan h: hour h: m: minute m: s second s sekunda Send Message Chat Scroll Message History Forward Scroll Message History Backward Refresh Users List Channels Show Smiles Single Messages History Istorija privatnih poruka General Edit User Details Uredi Korisnikove Profil Configure QChat Quit Add Channel Dodaj Kanal Close Channel Add Profile Profiles Delete Profile Rename Profile Hide to Tray Send Broadcast Message Next New Message Messages Poruke Previous New Message Next Opened Message Previous Opened Message Close All New Messages Close All Opened Messages ShortcutButton Input Shortcut ShortcutGrabber Input Shortcut ShortcutsEditor Action Shortcut Ok Uredu Cancel Defaults Clear Shortcut SingleMessageWgt Message from Poruka Od &Close &Zatvori &Send &Pošalji &Reply &Odgovori Reply &Quoted Odgovori &Citiraj Replying to Odgovor za Message Important SingleMsgsHistoryModel Direction / IP - Nickname / Date IP IP Nickname Nadimak Message Incoming Outgoing Direction / Date SingleMsgsHistoryView New Messages : Opened Messages : Direction / IP - Nickname / Date | Message Direction / Date | IP | Nickname | Message View Format: Next new message Previous new message Next opened message Previous opened message Close all new messages Close all opened messages Close current message before switching to next StatusEditWgt Edit status description Promeni trenutno stanje New Message... Nova Poruka... Empty Message Prazna Poruka Now Listening Trenutno Slušam Remove Description (%1) Ukloni Opis (%1) UserListIconConfigureWgt Total Size: Gender Icon: Status Icon: Avatar Icon: Text: Width Height X offset Y offset UsersListWgt Send Single Message.. Pošalji Ličnu Poruku.. Show User Information.. Informacije o Korisniku.. Send File.. Pošalji datoteku.. Private Chat.. Privatni Chat.. Message to Poruka za UsersStatisticsModel Male Muško Female Žensko Not Shure Nisam Siguran Unknown Nepoznato Nickname Nadimak Gender Pol Real Name Pravo Ime Status Trenutno Stanje Status Description Opis Stanja IP IP Comp Name Ime Računara OS OS Uptime Vreme Rada Time in Chat Vreme na Chatu qchat-0.3/src/translations/qchat_ru.ts0000644000076500017500000020445611002654535016675 0ustar owerower AboutQChat Close Закрыть <br><center>Network chat.</center><br> <br><center>Сетевой чат.</center><br> About О QChat Translations Переводы About QChat О QChat AddChannelDlg &Ok &Ок &Cancel От&мена Add Channel Добавить канал Channel's Name: Имя Канала: ChannelWgt &Send(CTRL+Space or CTRL+Enter) О&тправить(CTRL+Space или CTRL+Enter) &Refresh О&бновить Hide System Messages Спрятать Системные Сообщения on на running QChat ver. Использует QChat версии running QChat Send Отправить Refresh Обновить ChatWgt &Settings &Настройки &Help &Справка &Edit User Details... &Редактировать Информацию о Пользователе... &Preferences... &Настроить QChat... &Exit &Выход &Show Smiles.. &Показать Смайлы.. &Add Channel.. &Добавить Канал.. &Delete Channel.. &Удалить Канал.. &About О &QChat About &Qt &О Qt &License &Лицензия Are you shure? Вы Уверены? QChat ver. QChat ver. Network chat. Сетевой чат. About О QChat Choose a file to open Выберите файл для Открытия &Write Settings &Записать Настройки Add pro&file... Добавить &Профиль... &Rename profile... Пе&реименовать Профиль... Main Toolbar Главная Панель Инструментов Profiles Toolbar Панель Профилей Input new name for '%1' Введите новое название для '%1' New name: Новое название: Input name for new profile Введите название для нового профиля New profile name: Название нового профиля: Ukrainian Украинский Russian Русский English Английский &Language &Язык Toolbars Панели Инструментов Current profile: Текущий Профиль: Are you shure you want delete profile %1? Вы действительно желаете удалить профиль %1? Delete p&rofile... Удалить п&рофиль... Show Single Messages History... Показать Историю Одиночных Сообщений... Single Messages History История Одиночных Сообщений &Chat &Чат &View &Вид Polish Польский Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now? Ваши сетевые настройки не соответствуют ни одному из существующих интерфейсов. Программа может не работать. Вы желаете изменить настройки сечас? Incorrect network settings Неверные сетевые настройки Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings? Не удалось найти ни одного широковещательного интерфейса.Программа может не работать.Вы желаете посмотреть ваши сетевые настройки? No valid network interface! Не найдено пригодных для работы сетевых интерфейсов! Hiding in tray Скрытие в трей Now QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat. Сейчас QChat будет доступен из системного трея. Если вы желаете закрыть QChat - используйте действие Выход из меню Чат. Don't show this message again Больше не показывать это сообщение Are you sure? Вы Уверены? Are you sure you want to unload plugin '%1'? Вы действительно желаете выгрузить плагин %1? Are you sure you want to close channel '%1'? Вы действительно желаете закрыть канал %1? Are you sure you want delete profile %1? Вы действительно желаете удалить профиль %1? &Configure QChat... &Настроить QChat... Configure Shortcuts... Plugins Toolbar Formatting Toolbar Show Plugins Send Broadcast Message... Spanish German Serbian Connect to server.. Disconnect from server Server Mode Serverless Mode Default 16x16 24x24 32x32 48x48 Icons Size Disconnecting from server... Disconnected from server Broadcast Message EditStatusDescriptionsDlg Ok Ок Apply Применить Cancel Отмена Edit status descriptions Редактировать описание состояний Edit status descriptions [Profile: Редактировать описание состояний [Профиль: EditUserInfoDlg &Apply &Применить &Ok &Ок &Cancel О&тмена No Photo Нет Фото No Picture Нет Картинки Nickname: Ник: Second Name: Отчество: Date of Born: Дата Рождения: Address: Адрес: Mobile Phone: Мобильный Телефон: e-mail: e-mail: ICQ: ICQ: Homepage: Домашняя Страничка: Photo: Фото: Picture: Картинка: About: О Себе: Edit user details Редактировать Информацию о Пользователе Last Name: Фамилия: First Name: Имя: Home Phone: Домашний Телефон: Work Phone: Рабочий Телефон: Status ( Состояние ( Edit user details [Profile: Редактировать Информацию о Пользователе [Профиль: User details Информация о Пользователе User Details Информация о Пользователе Edit User Details Редактировать Информацию о Пользователе Gender: Пол: Male Мужской Female Женский Not Sure Не Уверено FileTransferWgt &Cancel &Отмена &Accept &Принять &Reject &Отвергнуть Sending Отсылка Receiving Получение Choose a file to save Выберите Файл для Сохранения Auto close when complete Закрыть после завершения Completed (%p%) Завершено (%p%) Close Закрыть Failed: cancelled by receiver(%p%) Неудача: отменено получателем(%p%) Failed: cancelled by sender (%p%) Неудача: отменено отправителем(%p%) Failed: cannot send file Неудача: не могу отослать файл Failed: rejected by receiver Неудача: получатель не стал принимать Failed: receiving timeout (%p%) Неудача: таймаут получения (%p%) Possibly failed: sending finished but only %p% confirmed Возможна неудача: отправка завершена, но только (%p%) подтверждено Receiving: %1 Sender: %2(%3) Sending: %1 Receiver: %2(%3) FiltrationRuleEditor Regular Expression Ok Ок Apply Применить Cancel Отмена Rule name : User(s) to ignore : Computer name(s) to ignore : IP address(es) to ignore : Message filter(one word per line or regular expression): Filtration Rule Editor FormattingToolBar Ok Ок Bold Italic Underline Insert Table Enter table size Rows count: Columns count: IpListEditor Use IP list instead of broadcasting .. Ok Ок Cancel Отмена Edit IP List.. Enter one IP per line IP List Editor Login2ServerDlg Server IP : Nickname : Login Abort MessageFilterEditor Disable rule Add rule... Remove rule (disabled) (white rule) New Rule Enable rule MessageWithCheckBox Ok Ок PictureScrollArea Full size of picture Полный размер изображения PixLabel Cancel Picture Отменить Картинку Full Size Полный Размер Choose Picture Выберите Картинку Full Size of Picture Полный Размер Картинки PreferencesDlg &Colors &Цвета &Network &Сеть &Misc &Разное &OK &OK &Cancel О&тмена &Apply &Применить Color Whole Message Разукрашивать все Сообщение Color Whole System Message Разукрашивать Все Системное Сообщение Activate Window on Incomin Messages Активировать Окно при Приходе Сообщения Play Sound on Incomig Messages Проигрывать Звук при Приходе Сообщения Color of My Messages : Цвет Моих Сообщений: Base Color for Messages : Базовый цвет для сообщений: IP Address : IP адрес : Input Port : Входящий Порт: Output Port : Исходящий Порт: Preferences Настроить QChat Broadcast Address : Широковещательный Адрес : Input/Output Port : Порт: Preferences [Profile: Насторийки [Профиль: Color of System Messages : Цвет Системных Сообщений : Now &Listening (from Amarok1) &Сейчас Слушаю ( из Amarok1 ) Choose smiles theme: Выберите тему смайлов: Send 'Now Listening' with messages Отправлять 'Сейчас слушаю' с сообщениями Set 'Now Listening' in status description Устанавливать 'Сейчас слушаю' в описание состояния Profile Профиль Misc Разное Messages Сообщения Network Сеть Smiles Смайлы Now Listening string : (%t - Track, %a - Artist, %b - alBum) Строка сообщения "Сейчас Слушаю" : (%t - Трек, %a - Артист, %b - альБом) Users List Список Пользователей Choose Style Sheet : Выберите Стиль: Style Sheets Стили Execute command on incoming messages : Выполнять комманду при приходе сообщения : Messages display format : Формат отображения сообщений : Messages history request interval : Интервал запроса истории сообщений : Maximum number of messages in history answer : Максимальное количество сообщений в ответе : Refresh Interval : Интервал Обновления : Deep Refresh Interval : Интервал Глубокого Обновления : Choose Network Settings : Выберите Сетевые Настройки : ms milliseconds мс s seconds с Custom (not recommended) Пользовательские Available Plugins : Users List Icon Format : Filtration rules : Choose protocol version : Plugins Filtration Load Plugin Use Compression Use Animated Smiles Smiles Policy : Don't use Graphic Smiles Use only smiles from local theme Use smiles from sender Always use smiles from sender Old protocol New protocol (Loaded) (Not loaded) Unload plugin Load plugin QChat Unknown option: %1 Use -h for list of available options. List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChat %1 - Network chat Author: Ower <ower@users.sourceforge.net> QObject Busy Занят Free Свободен Ready for chat Готов к чату Do not disturb Не беспокоить Inactive Неактивен Away Отсутствую Invisible Невидимый Now Listening to : %t by %a on %b Unknown OS Неизвестно d day д h: hour ч: m: minute м: s second с Send Message Chat Scroll Message History Forward Scroll Message History Backward Refresh Users List Channels Show Smiles Single Messages History История Одиночных Сообщений General Edit User Details Редактировать Информацию о Пользователе Configure QChat Quit Add Channel Добавить канал Close Channel Add Profile Profiles Delete Profile Rename Profile Hide to Tray Send Broadcast Message Next New Message Messages Сообщения Previous New Message Next Opened Message Previous Opened Message Close All New Messages Close All Opened Messages ShortcutButton Input Shortcut ShortcutGrabber Input Shortcut ShortcutsEditor Action Shortcut Ok Ок Cancel Отмена Defaults Clear Shortcut SingleMessageWgt &Close &Закрыть &Send &Отправить &Reply О&тветить Reply &Quoted &Цитировать Replying to Ответить на Message from Сообщение от Message Important SingleMsgsHistoryModel Direction / IP - Nickname / Date IP Nickname Ник Message Incoming Outgoing Direction / Date SingleMsgsHistoryView New Messages : Opened Messages : Direction / IP - Nickname / Date | Message Direction / Date | IP | Nickname | Message View Format: Next new message Previous new message Next opened message Previous opened message Close all new messages Close all opened messages Close current message before switching to next StatusEditWgt Edit status description Редактировать описание состояния New Message... Новое Сообщение... Empty Message Пустое Сообщение Now Listening Сейчас Слушаю Remove Description (%1) Удалить Описание (%1) UserListIconConfigureWgt Total Size: Gender Icon: Status Icon: Avatar Icon: Text: Width Height X offset Y offset UsersListWgt Send Single Message.. Отослать Одиночное Сообщение.. Show User Information.. Показать Информацию о Пользователе.. Send File.. Отослать Файл.. Private Chat.. Приватный Чат.. Message to Сообщение к UsersStatisticsModel Male Мужской Female Женский Not Shure Не Уверено Unknown Неизвестно Nickname Ник Gender Пол Real Name Имя Status Состояние Status Description Описание Состояния IP Comp Name Имя Компьютера OS ОС Uptime Time in Chat Время в Чате qchat-0.3/src/translations/qchat_uk.qm0000644000076500017500000006473311004467050016653 0ustar owerower0@0Kr1X1z\d2\t2Fi2{2u2ju3/ 3V3s34LC4N5Pqp51U5c5iM6H^67H74 `7| 7 Rd7 [i8* ]8] o4y8 t7J9 9H /E9 :< : : ȏ.;- ʟ.;P >; O~; ~<* <] e< S>=- $7z={ 1:= hP= yT> >F > n@= I@ I@ IA IAG A 5A 6BP ?B :B C %C= tCx tC C C 45DB @D D ^^E nEx E iE uF F ~F G3 mG| PtG G H- HY ޠH 猔H `H I^ "I J TJU TJ +J  eJ /`EK 1rKA A4K KLt N0L RVL RVM w'M^ RM eM cN x@NT xN xN O ['Op sO \O P+ YPq uP Q+ *WdQt =-Q H 3Q MRb jR R ĬS> <Su S %SzTTM ?,T',T55TS\U%s]5UUzwU{ UPVHEVl9VSVsWOdrWUW.X66Y<Y?=ZSH ZH [jiT[pIb[\8,\j\Cu]:Cu]s]]y^3^H^i^SingleMsgsHistoryModelAsQObject A sPreferencesDlg.. IpListEditorIPSingleMsgsHistoryModelIPUsersStatisticsModel!OSUsersStatisticsModel:OkFiltrationRuleEditor:OkFormattingToolBar:Ok IpListEditor:OkMessageWithCheckBox:OkShortcutsEditor4 d QObject3:h:QObject<:m:QObject <A msPreferencesDlg&:&OKPreferencesDlg&:&Ok AddChannelDlg&:&OkEditUserInfoDlg =0  on  ChannelWgtV4ACB=V9AwayQObjectBoldFormattingToolBar09=OB89BusyQObjectChatQObjectICQ:ICQ:EditUserInfoDlgV;L=89FreeQObject'>;>2VG0MaleEditUserInfoDlg'>;>2VG0MaleUsersStatisticsModel  V7=5MiscPreferencesDlgQuitQObjectSend ChannelWgtDisconnected from serverChatWgt&'0B&ChatChatWgt &8EV4&ExitChatWgt&>2V4:0&HelpChatWgt & V7=5&MiscPreferencesDlg&V4?@028B8&SendSingleMessageWgt&83;O4&ViewChatWgt !B8;V Style SheetsPreferencesDlg16x16ChatWgt24x24ChatWgtDisconnecting from server...ChatWgt32x32ChatWgtEdit IP List.. IpListEditor48x48ChatWgtAbortLogin2ServerDlg@> QChatAbout AboutQChat0AB>AC20B8ApplyFiltrationRuleEditor0:@8B8Close AboutQChat0:@8B8CloseFileTransferWgtLoginLogin2ServerDlgText:UserListIconConfigureWgtWidthUserListIconConfigureWgt.Close current message before switching to nextSingleMsgsHistoryView>;>2=0 0=5;L Main ToolbarChatWgt Gender Icon:UserListIconConfigureWgt*0720 =>2>3> ?@>DV;N:New profile name:ChatWgt>@B : Input/Output Port : PreferencesDlg List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChatColumns count:FormattingToolBarConnect to server..ChatWgt>& 5403C20B8 0=V >@8ABC20G0...&Edit User Details...ChatWgt Avatar Icon:UserListIconConfigureWgt8254VBL =07VC =>2>3> ?@>DV;NInput name for new profileChatWgtDV4?@028B8 @820B=5 >2V4><;5==O..Send Single Message.. UsersListWgt Status Icon:UserListIconConfigureWgt*15@VBL B5<C A<09;V2:Choose smiles theme:PreferencesDlg$>@<0B ?>2V4><;5==O "0@07 A;CE0N" : (%t - "@5:, %a - @B8AB, %b - 0;L><) =Now Listening string : (%t - Track, %a - Artist, %b - alBum)PreferencesDlg$>1V;L=89 "5;5D>=: Mobile Phone:EditUserInfoDlgNext Opened MessageQObjectNext opened messageSingleMsgsHistoryViewUse Animated SmilesPreferencesDlgChoose protocol version :PreferencesDlg$>B> V4ACB=TNo PhotoEditUserInfoDlg (Not loaded)PreferencesDlgSend Broadcast Message...ChatWgtR@>3@020B8 72C: ?@8 >B@8<0==V ?>2V4><;5=LPlay Sound on Incomig MessagesPreferencesDlg">B>G=89 ?@>DV;L:Current profile:ChatWgt60@07 &!;CE0N ( 7 Amarok1 )Now &Listening (from Amarok1)PreferencesDlg&@8E>2C20==O 2 B@59Hiding in trayChatWgtEnter one IP per line IpListEditor&>40B8 0=0;..&Add Channel..ChatWgt Enable ruleMessageFilterEditor Nickname :Login2ServerDlgOpened Messages :SingleMsgsHistoryView025@H5=> (%p%)Completed (%p%)FileTransferWgtClose All New MessagesQObject&@> QChat&AboutChatWgt&0AB>AC20B8&ApplyEditUserInfoDlg&0AB>AC20B8&ApplyPreferencesDlg&0:@8B8&CloseSingleMessageWgt&V4?>2VAB8&ReplySingleMessageWgt 0B0 0@>465==O: Date of Born:EditUserInfoDlgPlugins ToolbarChatWgt>2=89  >7<V@ Full SizePixLabel&VF5=7VO&LicenseChatWgtR>:070B8 AB>@VN 48=>G=8E >2V4><;5=L...Show Single Messages History...ChatWgt0V4?>2VAB8 7 &&8BC20==O< Reply &QuotedSingleMessageWgt (Loaded)PreferencesDlg Insert TableFormattingToolBar6>:070B8 0=V >@8ABC20G0..Show User Information.. UsersListWgtServerless ModeChatWgtConfigure QChatQObjectConfigure Shortcuts...ChatWgt"><0H=O !B>@V=:0: Homepage:EditUserInfoDlgMessageSingleMsgsHistoryModel Close ChannelQObjectPAB0=>28B8 '0@07 !;CE0N' 2 >?8A AB0BCAC)Set 'Now Listening' in status descriptionPreferencesDlg> 0BL:>2V: Second Name:EditUserInfoDlg*Direction / Date | IP | Nickname | MessageSingleMsgsHistoryView6254VBL =>2C =072C 4;O '%1'Input new name for '%1'ChatWgtV:B82C20B8 2V:=> ?@8 >B@8<0==V ?>2V4><;5==O#Activate Window on Incomin MessagesPreferencesDlg<'O ><?'NB5@0 Comp NameUsersStatisticsModel> >7<0;L>2C20B8 2A5 ?>2V4><;5==OColor Whole MessagePreferencesDlgD$>@<0B 2V4>1@065==O ?>2V4><;5=L : Messages display format : PreferencesDlg@> 5=5:About:EditUserInfoDlgActionShortcutsEditor50:B82=89InactiveQObject V4VA;0B8 $09;.. Send File.. UsersListWgt!:0AC20B8CancelFiltrationRuleEditor!:0AC20B8Cancel IpListEditor!:0AC20B8CancelShortcutsEditor Show PluginsChatWgtIncomingSingleMsgsHistoryModel$840;8B8 ?8A (%1)Remove Description (%1) StatusEditWgt&5@560&NetworkPreferencesDlg 5@560NetworkPreferencesDlg V=>G0FemaleEditUserInfoDlg V=>G0FemaleUsersStatisticsModel !B0BLGenderUsersStatisticsModelGermanChatWgt`0:A8<0;L=0 :V;L:VABL ?>2V4><;5=L C 2V4?>2V4V : /Maximum number of messages in history answer : PreferencesDlgHeightUserListIconConfigureWgtRegular ExpressionFiltrationRuleEditorItalicFormattingToolBarN=B5@20; 70?@>AC VAB>@VW ?>2V4><;5=L : $Messages history request interval : PreferencesDlg"><0H=V9 "5;5D>=: Home Phone:EditUserInfoDlgHV;LH5 =5 ?>:07C20B8 F5 ?>2V4><;5==ODon't show this message againChatWgt  >1>GV9 "5;5D>=: Work Phone:EditUserInfoDlg Load PluginPreferencesDlgFiltration rules :PreferencesDlg Icons SizeChatWgtUse smiles from senderPreferencesDlgPrevious Opened MessageQObjectPrevious opened messageSingleMsgsHistoryView.0;0HBC20==O [@>DV;L: Preferences [Profile: PreferencesDlgAlways use smiles from senderPreferencesDlg $>B>:Photo:EditUserInfoDlg>;LAL:0PolishChatWgtRefresh Users ListQObject0@07 QChat 1C45 4>ABC?=89 7 A8AB5<=>3> B@5N. /:I> 8 1060TB5 70:@8B8 QChat - 28:>@8AB>2C9B5 4VN 8EV4 7 <5=N '0B.nNow QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat.ChatWgt (white rule)MessageFilterEditorNext New MessageQObject !<09;8SmilesPreferencesDlg !B0BCAStatusUsersStatisticsModelNext new messageSingleMsgsHistoryViewUptimeUsersStatisticsModel Show SmilesQObject(>25 >2V4><;5==O...New Message... StatusEditWgtNew Messages :SingleMsgsHistoryViewSmiles Policy :PreferencesDlg@> QChat About QChat AboutQChat <'O: First Name:EditUserInfoDlgFormatting ToolbarChatWgtL 5403C20B8 0=V >@8ABC20G0 [@>DV;L: Edit user details [Profile: EditUserInfoDlg*Direction / IP - Nickname / Date | MessageSingleMsgsHistoryView@V728I5: Last Name:EditUserInfoDlg Send MessageQObject:AB>@VO 48=>G=8E >2V4><;5=LSingle Messages HistoryChatWgt:AB>@VO 48=>G=8E >2V4><;5=LSingle Messages HistoryQObject5 ?52=5=> Not ShureUsersStatisticsModel 0=5;VToolbarsChatWgt5 2?52=5=>Not SureEditUserInfoDlg&@> Qt About &QtChatWgt Disable ruleMessageFilterEditor^5<0T 6>4=>3> ?@840B=>3> 4;O @>1>B8 V=B5@D59AC!No valid network interface!ChatWgt Rows count:FormattingToolBarIP List Editor IpListEditor4@5A0 IP :  IP Address : PreferencesDlg&>1@065==O V4ACB=T No PictureEditUserInfoDlgComputer name(s) to ignore :FiltrationRuleEditorH2B><0B8G=> 70:@8B8 ?VA;O 7025@H5==OAuto close when completeFileTransferWgt Rule name :FiltrationRuleEditor5@5:;048 Translations AboutQChatPluginsPreferencesDlg>@B 22>4C: Input Port : PreferencesDlg Load pluginPreferencesDlg:5240G0: >B@8<C20G 2V4<>282AOFailed: rejected by receiverFileTransferWgtRV4A8;0B8 '0@07 !;CE0N' 7 ?>2V4><;5==O<"Send 'Now Listening' with messagesPreferencesDlgX offsetUserListIconConfigureWgtY offsetUserListIconConfigureWgt ImportantSingleMessageWgt">2V4><;5==O 4;O  Message to  UsersListWgt@>DV;LProfilePreferencesDlg Add ProfileQObject<'O Real NameUsersStatisticsModel,Are you sure you want to unload plugin '%1'?ChatWgt>5?@025;L=V =0;0HBC20==O <5@56VIncorrect network settingsChatWgt@07>289 :>;V@ 4;O ?>2V4><;5=L : Base Color for Messages : PreferencesDlge-mail:e-mail:EditUserInfoDlg &>20 &LanguageChatWgt2>;V@ <>WE ?>2V4><;5=L : Color of My Messages : PreferencesDlg8Message filter(one word per line or regular expression):FiltrationRuleEditor0=5;L @>DV;V2Profiles ToolbarChatWgtH5240G0: 2V4<V=5=> 2V4?@02=8:><(%p%)!Failed: cancelled by sender (%p%)FileTransferWgt#:@0W=AL:0 UkrainianChatWgtRefresh ChannelWgt,Are you sure you want to close channel '%1'?ChatWgt running QChat  ChannelWgtBroadcast MessageChatWgt&!?8A>: >@8ABC20GV2 Users ListPreferencesDlg (disabled)MessageFilterEditorProfilesQObjectF5240G0: 2V4<V=5=> >B@8<C20G5<(%p%)"Failed: cancelled by receiver(%p%)FileTransferWgt>20 =0720: New name:ChatWgt\8:>=C20B8 :><0=4C ?@8 >B@8<0==V ?>2V4><;5=L :&Execute command on incoming messages :PreferencesDlg$15@VBL >1@065==OChoose PicturePixLabel>40B8 0=0; Add Channel AddChannelDlg>40B8 0=0; Add ChannelQObject:!E>20B8 !8AB5<=V >2V4><;5==OHide System Messages ChannelWgtSerbianChatWgt >AV9AL:0RussianChatWgt?8A !B0BCACStatus DescriptionUsersStatisticsModel8Unknown option: %1 Use -h for list of available options.QChat Add rule...MessageFilterEditorIP address(es) to ignore :FiltrationRuleEditorP >7<0;L>2C20B8 2A5 A8AB5<=5 ?>2V4><;5==OColor Whole System MessagePreferencesDlg$&>:070B8 !<09;8..&Show Smiles..ChatWgtV:: Nickname:EditUserInfoDlgAvailable Plugins :PreferencesDlgSpanishChatWgt&@89=OB8&AcceptFileTransferWgt!B0BCA (Status (EditUserInfoDlg0HV =0;0HBC20==O <5@56V =5 2V4?>2V40NBL 6>4=><C 7 VA=CNG8E V=B5@D59AV2. @>3@0<0 <>65 =5 ?@0FN20B8. 8 1060TB5 7<V=8B8 =0;0HBC20==O 70@07?Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now?ChatWgt$&>40B8 @>DV;L...Add pro&file...ChatWgt&!:0AC20B8&Cancel AddChannelDlg&!:0AC20B8&CancelEditUserInfoDlg&!:0AC20B8&CancelFileTransferWgt&!:0AC20B8&CancelPreferencesDlg0>2=89 @>7<V@ 7>1@065==OFull size of picturePictureScrollArea0>2=89 @>7<V@ 7>1@065==OFull Size of PicturePixLabel&>;L>@8&ColorsPreferencesDlg)Author: Ower QChat View Format:SingleMsgsHistoryView4@5A0:Address:EditUserInfoDlgDirection / DateSingleMsgsHistoryModelDefaultChatWgt UnderlineFormattingToolBarClose All Opened MessagesQObjectClose all opened messagesSingleMsgsHistoryView*=B5@20; =>2;5==O : Refresh Interval : PreferencesDlg Unload pluginPreferencesDlg&V4<>28B8&RejectFileTransferWgt. 5403C20B8 ?8A !B0BCACEdit status description StatusEditWgt FiltrationPreferencesDlgDisconnect from serverChatWgtSending: %1 Receiver: %2(%3)FileTransferWgt615@VBL D09; 4;O 715@565==OChoose a file to saveFileTransferWgtUser(s) to ignore :FiltrationRuleEditor@15@VBL D09; O:89 B@510 2V4:@8B8Choose a file to openChatWgt'0A C '0BV Time in ChatUsersStatisticsModelDelete ProfileQObjectScroll Message History ForwardQObjectV4?>2V40N 4>  Replying to SingleMessageWgtDefaultsShortcutsEditorRename ProfileQObject>@B 282>4C: Output Port : PreferencesDlgQChat %1 - Network chatQChat(4@5A0 "@0=A;OFVW : Broadcast Address : PreferencesDlgB@8<0==O  Receiving FileTransferWgt>5240G0: =5 <>6C 2V4VA;0B8 D09;Failed: cannot send fileFileTransferWgtUsers List Icon Format :PreferencesDlgInput ShortcutShortcutButtonInput ShortcutShortcutGrabber Server IP :Login2ServerDlg Server ModeChatWgt Remove ruleMessageFilterEditor15@VBL AB8;L:Choose Style Sheet :PreferencesDlg>6;820 =5240G0: 2V4A8;0==O 7025@H5=>, 0;5 BV;L:8 %p% ?V4B25@465=>8Possibly failed: sending finished but only %p% confirmedFileTransferWgtV4?@02:0 Sending FileTransferWgt=3;V9AL:0EnglishChatWgt52V4><>UnknownQObject52V4><>UnknownUsersStatisticsModel#Use IP list instead of broadcasting IpListEditor5 BC@1C20B8Do not disturbQObjectNew RuleMessageFilterEditorClose all new messagesSingleMsgsHistoryViewMessage SingleMessageWgt>2V4><;5==OMessagesPreferencesDlg>2V4><;5==OMessagesQObject415@VBL 0@0<5B@8 5@56V :Choose Network Settings :PreferencesDlgOutgoingSingleMsgsHistoryModel0&@0<5B@8 &SettingsChatWgt"&840;8B8 0=0;..&Delete Channel..ChatWgt0;0HBC20==O PreferencesPreferencesDlg@5240G0: B09<0CB ?@89=OBBO (%p%)Failed: receiving timeout (%p%)FileTransferWgt52848<89 InvisibleQObject<'O 0=0;C:Channel's Name: AddChannelDlgScroll Message History BackwardQObject>B>289 4> G0BCReady for chatQObject6 5403C20B8 0=V >@8ABC20G0Edit user detailsEditUserInfoDlg2&5@59<5=C20B8 @>DV;L...&Rename profile...ChatWgt&Configure QChat...ChatWgt@820B=89 '0B..Private Chat.. UsersListWgt !B0BL:Gender:EditUserInfoDlgGeneralQObjectClear ShortcutShortcutsEditor Direction / IP - Nickname / DateSingleMsgsHistoryModel Total Size:UserListIconConfigureWgt(Are you sure you want delete profile %1?ChatWgt Old protocolPreferencesDlg New protocolPreferencesDlgEnter table sizeFormattingToolBarPrevious New MessageQObjectPrevious new messageSingleMsgsHistoryViewDon't use Graphic SmilesPreferencesDlg<>;V@ A8AB5<=8E ?>2V4><;5=L : Color of System Messages : PreferencesDlgChannelsQObject(V4<V=8B8 >1@065==OCancel PicturePixLabelReceiving: %1 Sender: %2(%3)FileTransferWgt 0=V >@8ABC20G0 User detailsEditUserInfoDlg 0=V >@8ABC20G0 User DetailsEditUserInfoDlg!Now Listening to : %t by %a on %bQObjectSend Broadcast MessageQObject5 <>6C 7=09B8 6>4=>3> V=B5@D59AC O:89 ?V4B@8<CT B@0=A;OFVN. @>3@0<0 <>65 =5 ?@0FN20B8. 8 1060TB5 ?>4828B8AL =0;0HBC20==O <5@56V 70@07?|Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings?ChatWgt Use only smiles from local themePreferencesDlg(840;8B8 ?&@>DV;L...Delete p&rofile...ChatWgtf<br><center>'0B 4;O ;>:0;L=>W <5@56V.</center><br> '
Network chat.

 AboutQChat6 5403C20B8 0=V >@8ABC20G0Edit User DetailsEditUserInfoDlg6 5403C20B8 0=V >@8ABC20G0Edit User DetailsQObjectShortcutShortcutsEditorFiltration Rule EditorFiltrationRuleEditorUse CompressionPreferencesDlg(>@>6=T >2V4><;5==O Empty Message StatusEditWgt>=B5@20; 3;81>:>3> >=>2;5==O : Deep Refresh Interval : PreferencesDlgV:NicknameSingleMsgsHistoryModelV:NicknameUsersStatisticsModel>1@065==O:Picture:EditUserInfoDlg0@07 !;CE0N Now Listening StatusEditWgt@>@8ABC20FL:V (=5 @5:><5=4>20=>)Custom (not recommended)PreferencesDlg Hide to TrayQObject Are you sure?ChatWgt ) , qchat-0.3/src/translations/qchat_uk.ts0000644000076500017500000020553711004467046016670 0ustar owerower AboutQChat Close Закрити <br><center>Network chat.</center><br> <br><center>Чат для локальної мережі.</center><br> About Про QChat Translations Переклади About QChat Про QChat AddChannelDlg Add Channel Додати Канал &Ok &Ок &Cancel &Скасувати Channel's Name: Ім'я Каналу: ChannelWgt on на running QChat ver. використовує QChat версії &Send(CTRL+Space or CTRL+Enter) &Відіслати(CTRL+Space або CTRL+Enter) &Refresh &Оновити Hide System Messages Сховати Системні Повідомлення running QChat Send Refresh ChatWgt Are you shure? Ви Впевнені? QChat ver. QChat версії Network chat. Чат для Локальної Мережі. (c) 2007, Anistratov Oleg aka ower [ower@users.sourceforge.net] (c) 2007, Аністратов Олег aka ower [ower@users.sourceforge.net] About Про QChat Choose a file to open Оберіть файл який треба відкрити Input new name for '%1' Введіть нову назву для '%1' New name: Нова назва: Input name for new profile Введіть назіу нового профілю New profile name: Назва нового профілю: &Edit User Details... &Редагувати Дані Користувача... &Preferences... &Налаштувати QChat... &Exit &Вихід &Show Smiles.. &Показати Смайли.. &Add Channel.. &Додати Канал.. &Delete Channel.. &Видалити Канал.. &About &Про QChat About &Qt П&ро Qt &License &Ліцензія &Write Settings &Записати Налаштування Main Toolbar Головна Панель Profiles Toolbar Панель Профілів Add pro&file... &Додати Профіль... &Rename profile... &Перейменувати Профіль... &Settings Па&раметри &Help &Довідка &Language &Мова Toolbars Панелі Ukrainian Українська Russian Російська English Англійська Current profile: Поточний профіль: Are you shure you want delete profile %1? Ви насправді бажаєте видалити профіль %1? Delete p&rofile... Видалити п&рофіль... Show Single Messages History... Показати Історію Одиночних Повідомлень... Single Messages History Історія Одиночних Повідомлень &Chat &Чат &View &Вигляд Polish Польська Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now? Ваші налаштування мережі не відповідають жодному з існуючих інтерфейсів. Програма може не працювати. Ви бажаєте змінити налаштування зараз? Incorrect network settings Неправельні налаштування мережі Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings? Не можу знайти жодного інтерфейсу який підтримує трансляцію. Програма може не працювати. Ви бажаєте подивитись налаштування мережі зараз? No valid network interface! Немає жодного придатного для роботи інтерфейсу! Hiding in tray Приховування в трей Now QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat. Зараз QChat буде доступний з системного трею. Якщо Ви бажаєте закрити QChat - використовуйте дію Вихід з меню Чат. Don't show this message again Більше не показувати це повідомлення Are you sure? Are you sure you want to unload plugin '%1'? Are you sure you want to close channel '%1'? Are you sure you want delete profile %1? &Configure QChat... Configure Shortcuts... Plugins Toolbar Formatting Toolbar Show Plugins Send Broadcast Message... Spanish German Serbian Connect to server.. Disconnect from server Server Mode Serverless Mode Default 16x16 24x24 32x32 48x48 Icons Size Disconnecting from server... Disconnected from server Broadcast Message EditStatusDescriptionsDlg Ok Ок Apply Застосувати Cancel Скасувати Edit status descriptions Редагувати Опис Статусу Edit status descriptions [Profile: Редагувати Опис Статусу [Профіль: EditUserInfoDlg Status ( Статус ( Edit user details [Profile: Редагувати Дані Користувача [Профіль: User details Дані Користувача &Ok &Ок User Details Дані Користувача &Cancel &Скасувати Edit User Details Редагувати Дані Користувача &Apply &Застосувати No Photo Фото Відсутнє No Picture Зображення Відсутнє Nickname: Нік: Last Name: Прізвище: First Name: Ім'я: Second Name: По Батькові: Date of Born: Дата Народження: Address: Адреса: Home Phone: Домашній Телефон: Work Phone: Робочій Телефон: Mobile Phone: Мобільний Телефон: e-mail: e-mail: ICQ: ICQ: Homepage: Домашня Сторінка: About: Про Мене: Edit user details Редагувати Дані Користувача Picture: Зображення: Photo: Фото: Gender: Стать: Male Чоловіча Female Жіноча Not Sure Не впевнено FileTransferWgt &Cancel &Скасувати &Accept &Прийняти &Reject &Відмовити Auto close when complete Автоматично закрити після завершення Sending Відправка Receiving Отримання Choose a file to save Оберіть файл для збереження Completed (%p%) Завершено (%p%) Close Закрити Failed: cancelled by receiver(%p%) Невдача: відмінено отримувачем(%p%) Failed: cancelled by sender (%p%) Невдача: відмінено відправником(%p%) Failed: cannot send file Невдача: не можу відіслати файл Failed: rejected by receiver Невдача: отримувач відмовився Failed: receiving timeout (%p%) Невдача: таймаут прийняття (%p%) Possibly failed: sending finished but only %p% confirmed Можлива невдача: відсилання завершено, але тільки %p% підтверджено Receiving: %1 Sender: %2(%3) Sending: %1 Receiver: %2(%3) FiltrationRuleEditor Regular Expression Ok Ок Apply Застосувати Cancel Скасувати Rule name : User(s) to ignore : Computer name(s) to ignore : IP address(es) to ignore : Message filter(one word per line or regular expression): Filtration Rule Editor FormattingToolBar Ok Ок Bold Italic Underline Insert Table Enter table size Rows count: Columns count: IpListEditor Use IP list instead of broadcasting .. Ok Ок Cancel Скасувати Edit IP List.. Enter one IP per line IP List Editor Login2ServerDlg Server IP : Nickname : Login Abort MessageFilterEditor Disable rule Add rule... Remove rule (disabled) (white rule) New Rule Enable rule MessageWithCheckBox Ok Ок PictureScrollArea Full size of picture Повний розмір зображення PixLabel Cancel Picture Відмінити Зображення Full Size Повний Розмір Choose Picture Оберіть Зображення Full Size of Picture Повний розмір зображення PreferencesDlg Input/Output Port : Порт : Input Port : Порт вводу: Preferences [Profile: Налаштування [Профіль: Color of My Messages : Колір моїх повідомлень : Color of System Messages : Колір системних повідомлень : Base Color for Messages : Базовий колір для повідомлень : IP Address : Адреса IP : Broadcast Address : Адреса Трансляції : &Colors &Кольори &Network &Мережа &Misc &Різне Now &Listening (from Amarok1) Зараз &Слухаю ( з Amarok1 ) Choose smiles theme: Оберіть тему смайлів: &OK &Ок &Cancel &Скасувати &Apply &Застосувати Color Whole Message Розмальовувати все повідомлення Color Whole System Message Розмальовувати все системне повідомлення Activate Window on Incomin Messages Активувати вікно при отриманні повідомлення Play Sound on Incomig Messages Програвати звук при отриманні повідомлень Send 'Now Listening' with messages Відсилати 'Зараз Слухаю' з повідомленням Set 'Now Listening' in status description Встановити 'Зараз Слухаю' в опис статусу Output Port : Порт виводу: Profile Профіль Misc Різне Messages Повідомлення Network Мережа Smiles Смайли Preferences Налаштування Now Listening string : (%t - Track, %a - Artist, %b - alBum) Формат повідомлення "Зараз слухаю" : (%t - Трек, %a - Артист, %b - альБом) Users List Список Користувачів Choose Style Sheet : Оберіть стиль: Style Sheets Стилі Execute command on incoming messages : Виконувати команду при отриманні повідомлень : Messages display format : Формат відображення повідомлень : Messages history request interval : Інтервал запросу історії повідомлень : Maximum number of messages in history answer : Максимальна кількість повідомлень у відповіді : Refresh Interval : Інтервал Оновлення : Deep Refresh Interval : Інтервал глибокого оновлення : Choose Network Settings : Оберіть Параметри Мережі : ms milliseconds мс s seconds с Custom (not recommended) Користувацькі (не рекомендовано) Available Plugins : Users List Icon Format : Filtration rules : Choose protocol version : Plugins Filtration Load Plugin Use Compression Use Animated Smiles Smiles Policy : Don't use Graphic Smiles Use only smiles from local theme Use smiles from sender Always use smiles from sender Old protocol New protocol (Loaded) (Not loaded) Unload plugin Load plugin QChat Unknown option: %1 Use -h for list of available options. List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChat %1 - Network chat Author: Ower <ower@users.sourceforge.net> QObject Busy Зайнятий Free Вільний Ready for chat Готовий до чату Do not disturb Не турбувати Inactive Неактивний Away Відсутній Invisible Невидимий Now Listening to : %t by %a on %b Unknown OS Невідомо d day д h: hour г: m: minute м: s second с Send Message Chat Scroll Message History Forward Scroll Message History Backward Refresh Users List Channels Show Smiles Single Messages History Історія Одиночних Повідомлень General Edit User Details Редагувати Дані Користувача Configure QChat Quit Add Channel Додати Канал Close Channel Add Profile Profiles Delete Profile Rename Profile Hide to Tray Send Broadcast Message Next New Message Messages Повідомлення Previous New Message Next Opened Message Previous Opened Message Close All New Messages Close All Opened Messages ShortcutButton Input Shortcut ShortcutGrabber Input Shortcut ShortcutsEditor Action Shortcut Ok Ок Cancel Скасувати Defaults Clear Shortcut SingleMessageWgt &Close &Закрити &Send &Відправити &Reply &Відповісти Reply &Quoted Відповісти з &Цитуванням Replying to Відповідаю до Message from Повідомлення від Message Important SingleMsgsHistoryModel Direction / IP - Nickname / Date IP Nickname Нік Message Incoming Outgoing Direction / Date SingleMsgsHistoryView New Messages : Opened Messages : Direction / IP - Nickname / Date | Message Direction / Date | IP | Nickname | Message View Format: Next new message Previous new message Next opened message Previous opened message Close all new messages Close all opened messages Close current message before switching to next StatusEditWgt Edit status description Редагувати Опис Статусу New Message... Нове Повідомлення... Empty Message Порожнє Повідомлення Now Listening Зараз Слухаю Remove Description (%1) Видалити Опис (%1) UserListIconConfigureWgt Total Size: Gender Icon: Status Icon: Avatar Icon: Text: Width Height X offset Y offset UsersListWgt Send Single Message.. Відправити Приватне Повідомлення.. Show User Information.. Показати Дані Користувача.. Send File.. Відіслати Файл.. Private Chat.. Приватний Чат.. Message to Повідомлення для UsersStatisticsModel Male Чоловіча Female Жіноча Not Shure Не Впевнено Unknown Невідомо Nickname Нік Gender Стать Real Name Ім'я Status Статус Status Description Опис Статусу IP Comp Name Ім'я Комп'ютера OS ОС Uptime Time in Chat Час у Чаті qchat-0.3/src/translations/qchat_pl.qm0000644000076500017500000002565111002652422016640 0ustar owerower[f`pv 'C+;+[+[vJ ص8%.8%Z@r***0+@+D+2GHw9"J68J6[~(oҀu)DNq:(+8fYVIjy# aNXBw9w9)6A9W q%KvMQ-sc2u!p?%}%U]Եw| ylz cz wn I "p         ) ; 5 E8% S8% {J  V "G A0 e1LZ Wp ok* v0 = -   /ǰ5 YZ }D * ._ N+Qk*wXkYb#el)49)0 52m>KrXOum sC)N=PqpOciM^(5K Rdw o4y t7J  /E   ʟ. > e9 S> $7z yT   n I7 I] I I  5 61 E q0W 45  ^^ u ~? u  ޠ `  "- } 1r A4 Kq N0 RV RV R x  sS \o  Y u 1 =-Q DYs DYy DY DY DZ DZ DZ H 3 M  Ĭ-{ =EuSs!drK.< ?= H !A,!y!Cu!!"y"!"Oi"}IP"System operacyjnyKEditStatusDescriptionsDlgKg:m:&K&K AddChannelDlg&KwBczonyNiedostpny ZajtyICQ:DostpnyM|czyznaEditUserInfoDlgM|czyzna R|ne &Czat &Wyjdz &Pomoc &R|ne&Wy[lij &WidokArkusze styliO QChatZastosujZamknij AboutQChatZamknij0GBwny pasek narzdziowy*Nazwa nowego profilu:Port : :&Edytuj detale u|ytkownika...BWprowadz nazw dla nowego profilu:Wy[lij pojedyncz wiadomo[...Wybierz motyw emotikon:nTeraz sBucham: (%t - Zcie|ka, %a - Artysta, %b - Album)$Telefon komrkowy:Brak zdjciaVOdtwarzaj dzwiki wiadomo[ci przychodzcych Aktualny profil:8Ter&az sBucham ( z Amarok1 )8Ukrywanie w tacce systemowej&Dodaj kanaB.. ZakoDczono (%p%)&O QChat&ZastosujEditUserInfoDlg&Zastosuj&Zamknij&OdpowiedzData utodzenia:"CaBkowity rozmiar&LicencjaRPoka| histori pojedynczych wiadomo[ci...0Odpow&iedz z cudzysBowem@Poka| informacje o u|ytkowniku..Strona domowa:PUstaw 'Teraz sBucham', jako opis statusuDrugie imi:8Wprowadz now nazw dla '%1'FNadchodzca wiadomo[ aktywuje oknoNazwa komputera,Kolor caBej wiadomo[ci>Format wy[wietlania wiadomo[ci:O mnie:NieaktywnyWy[lij plik.. AnulujWiadomo[ od UsuD opis (%1) &SieSieKobietaEditUserInfoDlgKobietaPBeNMaksymalna ilo[ w historii odpowiedzi:JInterwaB |dania historii wiadomo[ci:Telefon domowy:BNie pokazuj wicej tej wiadomo[ci"Telefon do pracy:*Preferencje [Profil: Zdjcie: PolskiTeraz QChat bdzie dostpny z tacki systemowej. Je[li chcesz zamkn QChat, u|yj akcji Wyjdz z menu Czat.Emotikony Status$&Zapisz ustawieniaCzas aktywno[ci"Nowa wiadomo[...O QChat Imi:\Czy jeste[ pewien, |e chcesz usun profil %1?FEdytuj detale u|ytkownika [Profil: Nazwisko:@Histroia pojedynczych wiadomo[ciNiepewna"Paski narzdzioweNiepewna O &QtjBrak jakiegokolwiek poprawnego interfejsu sieciowego!6Wersja uruchomionego QChat.Adres IP : Brak obrazkaHZamknij automatycznie po zakoDczeniuTBumaczeniaPort wej[cia:NNiepowodzenie: odrzucone przez odbiorcLWy[lij 'Teraz sBucham', jako wiadomo[Wiadomo[ do ProfilPrawdziwe imi8Niepoprawne ustawienia sieciDPodstawowy kolor dla wiadomo[ci : e-mail: &Jzyk2Kolor moich wiadomo[ci : 2Pasek narzdziowy profiliXNiepowodzenie: anulowane przez nadawc (%p%)UkraiDski&Od[wie|&Edytuj opis statusu$Lista u|ytkownikwXNiepowodzenie: anulowane przez odbiorc(%p%)Nowa nazwa:jWykonaj polecenie, podczas przychodzcych wiadomo[ci:Wybierz obrazekDodaj kanaB4Ukryj wiadomo[ci systemoweRosyjskiOpis statusuBKolor caBej wiadomo[ci systemowejPoka| &emotki.. Nick:A&kceptujStatus ((Twoje ustawienia sieci nie odpowiadaj |adnemu istniejcemu interfejsowi sieciowemu. Aplikacja mo|e nie dziaBa. Czy chcesz j teraz skonfigurowa? Dodaj pro&fil...&Anuluj AddChannelDlg&AnulujEditUserInfoDlg&AnulujFileTransferWgt&Anuluj2CaBkowity rozmiar obrazka2CaBkowity rozmiar obrazka&Kolory Adres::Edytuj opisy statusu [Profil:*InterwaB od[wie|ania:&Odrzu&Edytuj opis statusu2Wybierz plik do zapisania0Wybierz plik do otwarciaCzas na czacieOdpowiedz doPort wyj[cia : .Adres rozgBoszeniowy : Otrzymywanie JNiepowodzenie: nie mo|na wysBa pliku&Preferencje...*Wybierz arkusz styli:Mo|liwe niepowodzenie: wysyBanie zakoDczone, ale potwierdzone tylko przez %p%WysyBanie AngielskiNieznanyQObjectNieznany Nie przeszkadzaWiadomo[ci2Wybierz ustawienia sieci:&Ustawienia&UsuD kanaB..ProferencjedNiepowodzenie: przekroczenie czasu wysyBania (%p%)NiewidocznyNazwa kanaBu:Gotowy na czat2Edytuj detale u|ytkownika.&ZmieD nazw profilu...Prywatny czat.. PBe:>Kolor wiadomo[ci systemowych : F&Wy[lij (CTRL+Space lub CTRL+Enter) Anuluj$Detale u|ytkownika$Detale u|ytkownika@Teraz sBucham: %t przez %a na %b0Nie mo|na odnalez |adnego interfejsu sieciowego, przez ktry mo|na rozgBasza. Aplikacja mo|e nie dziaBa. Czy chcesz zobaczy twoje ustawienia sieci?UsuD p&rofil...P<br><center>Czat sieciowy.</center><br> 2Edytuj detale u|ytkownikaPusta wiadomo[:GBboki interwaB od[wie|ania:NickObrazek:Teraz sBucham(WBasne (niezalecane)(Jeste[ pewien/pewna?/6$-5CIY`ejr{PixLabelUsersStatisticsModelPictureScrollAreaFileTransferWgtEditUserInfoDlgPreferencesDlgEditStatusDescriptionsDlg AboutQChatMessageWithCheckBox ChannelWgt UsersListWgtQObjectChatWgt AddChannelDlgSingleMessageWgt StatusEditWgt , qchat-0.3/src/translations/qchat_pl.ts0000600000076500017500000013572211002654043016643 0ustar owerower AboutQChat Close Zamknij <br><center>Network chat.</center><br> <br><center>Czat sieciowy.</center><br> About O QChat Translations Tłumaczenia About QChat O QChat AddChannelDlg Add Channel Dodaj kanał &Ok &ОK &Cancel &Anuluj Channel's Name: Nazwa kanału: ChannelWgt on włączony running QChat ver. Wersja uruchomionego QChat. &Send(CTRL+Space or CTRL+Enter) &Wyślij (CTRL+Space lub CTRL+Enter) &Refresh &Odśwież Hide System Messages Ukryj wiadomości systemowe running QChat Send Refresh ChatWgt Are you shure? Jesteś pewien/pewna? QChat ver. Wersja QChat. Network chat. Czat sieciowy. (c) 2007, Anistratov Oleg aka ower [ower@users.sourceforge.net] (c) 2007, Anistratov Oleg aka ower [ower@users.sourceforge.net] About O QChat Choose a file to open Wybierz plik do otwarcia Input new name for '%1' Wprowadź nową nazwę dla '%1' New name: Nowa nazwa: Input name for new profile Wprowadź nazwę dla nowego profilu New profile name: Nazwa nowego profilu: &Edit User Details... &Edytuj detale użytkownika... &Preferences... &Preferencje... &Exit &Wyjdź &Show Smiles.. Pokaż &emotki.. &Add Channel.. &Dodaj kanał.. &Delete Channel.. &Usuń kanał.. &About &O QChat About &Qt O &Qt &License &Licencja &Write Settings &Zapisz ustawienia Main Toolbar Główny pasek narzędziowy Profiles Toolbar Pasek narzędziowy profili Add pro&file... Dodaj pro&fil... &Rename profile... &Zmień nazwę profilu... &Settings &Ustawienia &Help &Pomoc &Language &Język Toolbars Paski narzędziowe Ukrainian Ukraiński Russian Rosyjski English Angielski Current profile: Aktualny profil: Are you shure you want delete profile %1? Czy jesteś pewien, że chcesz usunąć profil %1? Delete p&rofile... Usuń p&rofil... &Chat &Czat Polish Polski Show Single Messages History... Pokaż historię pojedynczych wiadomości... Single Messages History Histroia pojedynczych wiadomości &View &Widok Your network settings don't corresponds any of existing network interfaces. The program may not work. Do you want to configure it now? Twoje ustawienia sieci nie odpowiadają żadnemu istniejącemu interfejsowi sieciowemu. Aplikacja może nie działać. Czy chcesz ją teraz skonfigurować? Incorrect network settings Niepoprawne ustawienia sieci Couldn't find any network interface that can broadcast. The program may not work. Do you want to see your network settings? Nie można odnaleźć żadnego interfejsu sieciowego, przez który można rozgłaszać. Aplikacja może nie działać. Czy chcesz zobaczyć twoje ustawienia sieci? No valid network interface! Brak jakiegokolwiek poprawnego interfejsu sieciowego! Hiding in tray Ukrywanie w tacce systemowej Now QChat will be available from system tray. If you want to quit from QChat - use Exit action from menu Chat. Teraz QChat będzie dostępny z tacki systemowej. Jeśli chcesz zamknąć QChat, użyj akcji Wyjdź z menu Czat. Don't show this message again Nie pokazuj więcej tej wiadomości Are you sure? Are you sure you want to unload plugin '%1'? Are you sure you want to close channel '%1'? Are you sure you want delete profile %1? &Configure QChat... Configure Shortcuts... Plugins Toolbar Formatting Toolbar Show Plugins Send Broadcast Message... Spanish German Serbian Connect to server.. Disconnect from server Server Mode Serverless Mode Default 16x16 24x24 32x32 48x48 Icons Size Disconnecting from server... Disconnected from server Broadcast Message EditStatusDescriptionsDlg Ok ОK Apply Zastosuj Cancel Anuluj Edit status descriptions Edytuj opis statusu Edit status descriptions [Profile: Edytuj opisy statusu [Profil: EditUserInfoDlg Status ( Status ( Edit user details [Profile: Edytuj detale użytkownika [Profil: User details Detale użytkownika &Ok &ОK User Details Detale użytkownika &Cancel &Anuluj Edit User Details Edytuj detale użytkownika &Apply &Zastosuj No Photo Brak zdjęcia No Picture Brak obrazka Nickname: Nick: Last Name: Nazwisko: First Name: Imię: Second Name: Drugie imię: Date of Born: Data utodzenia: Address: Adres: Home Phone: Telefon domowy: Work Phone: Telefon do pracy: Mobile Phone: Telefon komórkowy: e-mail: e-mail: ICQ: ICQ: Homepage: Strona domowa: About: O mnie: Edit user details Edytuj detale użytkownika Picture: Obrazek: Photo: Zdjęcie: Gender: Płeć: Male Mężczyzna Female Kobieta Not Sure Niepewna FileTransferWgt &Cancel &Anuluj &Accept A&kceptuj &Reject &Odrzuć Auto close when complete Zamknij automatycznie po zakończeniu Sending Wysyłanie Receiving Otrzymywanie Choose a file to save Wybierz plik do zapisania Completed (%p%) Zakończono (%p%) Close Zamknij Failed: cancelled by receiver(%p%) Niepowodzenie: anulowane przez odbiorcę(%p%) Failed: cancelled by sender (%p%) Niepowodzenie: anulowane przez nadawcę (%p%) Failed: cannot send file Niepowodzenie: nie można wysłać pliku Failed: rejected by receiver Niepowodzenie: odrzucone przez odbiorcę Failed: receiving timeout (%p%) Niepowodzenie: przekroczenie czasu wysyłania (%p%) Possibly failed: sending finished but only %p% confirmed Możliwe niepowodzenie: wysyłanie zakończone, ale potwierdzone tylko przez %p% Receiving: %1 Sender: %2(%3) Sending: %1 Receiver: %2(%3) FiltrationRuleEditor Regular Expression Ok ОK Apply Zastosuj Cancel Anuluj Rule name : User(s) to ignore : Computer name(s) to ignore : IP address(es) to ignore : Message filter(one word per line or regular expression): Filtration Rule Editor FormattingToolBar Ok ОK Bold Italic Underline Insert Table Enter table size Rows count: Columns count: IpListEditor Use IP list instead of broadcasting .. Ok ОK Cancel Anuluj Edit IP List.. Enter one IP per line IP List Editor Login2ServerDlg Server IP : Nickname : Login Abort MessageFilterEditor Disable rule Add rule... Remove rule (disabled) (white rule) New Rule Enable rule MessageWithCheckBox Ok ОK PictureScrollArea Full size of picture Całkowity rozmiar obrazka PixLabel Cancel Picture Anuluj Full Size Całkowity rozmiar Choose Picture Wybierz obrazek Full Size of Picture Całkowity rozmiar obrazka PreferencesDlg Input/Output Port : Port : Input Port : Port wejścia: Preferences [Profile: Preferencje [Profil: Color of My Messages : Kolor moich wiadomości : Color of System Messages : Kolor wiadomości systemowych : Base Color for Messages : Podstawowy kolor dla wiadomości : IP Address : Adres IP : Broadcast Address : Adres rozgłoszeniowy : &Colors &Kolory &Network &Sieć &Misc &Różne Now &Listening (from Amarok1) Ter&az słucham ( z Amarok1 ) Choose smiles theme: Wybierz motyw emotikon: &OK &ОK &Cancel &Anuluj &Apply &Zastosuj Color Whole Message Kolor całej wiadomości Color Whole System Message Kolor całej wiadomości systemowej Activate Window on Incomin Messages Nadchodząca wiadomość aktywuje okno Play Sound on Incomig Messages Odtwarzaj dźwięki wiadomości przychodzących Send 'Now Listening' with messages Wyślij 'Teraz słucham', jako wiadomość Set 'Now Listening' in status description Ustaw 'Teraz słucham', jako opis statusu Output Port : Port wyjścia : Profile Profil Misc Różne Messages Wiadomości Network Sieć Smiles Emotikony Preferences Proferencje Now Listening string : (%t - Track, %a - Artist, %b - alBum) Teraz słucham: (%t - Ścieżka, %a - Artysta, %b - Album) Users List Lista użytkowników Choose Style Sheet : Wybierz arkusz styli: Style Sheets Arkusze styli Messages display format : Format wyświetlania wiadomości: Messages history request interval : Interwał żądania historii wiadomości: Maximum number of messages in history answer : Maksymalna ilość w historii odpowiedzi: Refresh Interval : Interwał odświeżania: Deep Refresh Interval : Głęboki interwał odświeżania: ms milliseconds s seconds Execute command on incoming messages : Wykonaj polecenie, podczas przychodzących wiadomości: Choose Network Settings : Wybierz ustawienia sieci: Custom (not recommended) Własne (niezalecane) Available Plugins : Users List Icon Format : Filtration rules : Choose protocol version : Plugins Filtration Load Plugin Use Compression Use Animated Smiles Smiles Policy : Don't use Graphic Smiles Use only smiles from local theme Use smiles from sender Always use smiles from sender Old protocol New protocol (Loaded) (Not loaded) Unload plugin Load plugin QChat Unknown option: %1 Use -h for list of available options. List of available options: -h, --help Prints this message -v, --version Prints version of QChat --author Information about author --settingsdir Directory with settings --logdir Dirictory for saving chat logs QChat %1 - Network chat Author: Ower <ower@users.sourceforge.net> QObject Busy Zajęty Free Dostępny Ready for chat Gotowy na czat Do not disturb Nie przeszkadzać Inactive Nieaktywny Away Niedostępny Invisible Niewidoczny Now Listening to : %t by %a on %b Teraz słucham: %t przez %a na %b Unknown OS Nieznany d day h: hour g: m: minute m: s second Send Message Chat Scroll Message History Forward Scroll Message History Backward Refresh Users List Channels Show Smiles Single Messages History Histroia pojedynczych wiadomości General Edit User Details Edytuj detale użytkownika Configure QChat Quit Add Channel Dodaj kanał Close Channel Add Profile Profiles Delete Profile Rename Profile Hide to Tray Send Broadcast Message Next New Message Messages Wiadomości Previous New Message Next Opened Message Previous Opened Message Close All New Messages Close All Opened Messages ShortcutButton Input Shortcut ShortcutGrabber Input Shortcut ShortcutsEditor Action Shortcut Ok ОK Cancel Anuluj Defaults Clear Shortcut SingleMessageWgt &Close &Zamknij &Send &Wyślij &Reply &Odpowiedz Reply &Quoted Odpow&iedź z cudzysłowem Replying to Odpowiedź do Message from Wiadomość od Message Important SingleMsgsHistoryModel Direction / IP - Nickname / Date IP IP Nickname Nick Message Incoming Outgoing Direction / Date SingleMsgsHistoryView New Messages : Opened Messages : Direction / IP - Nickname / Date | Message Direction / Date | IP | Nickname | Message View Format: Next new message Previous new message Next opened message Previous opened message Close all new messages Close all opened messages Close current message before switching to next StatusEditWgt Edit status description Edytuj opis statusu New Message... Nowa wiadomość... Empty Message Pusta wiadomość Now Listening Teraz słucham Remove Description (%1) Usuń opis (%1) UserListIconConfigureWgt Total Size: Gender Icon: Status Icon: Avatar Icon: Text: Width Height X offset Y offset UsersListWgt Send Single Message.. Wyślij pojedynczą wiadomość.. Show User Information.. Pokaż informacje o użytkowniku.. Send File.. Wyślij plik.. Private Chat.. Prywatny czat.. Message to Wiadomość do UsersStatisticsModel Male Mężczyzna Female Kobieta Not Shure Niepewna Unknown Nieznany Nickname Nick Gender Płeć Real Name Prawdziwe imię Status Status Status Description Opis statusu IP IP Comp Name Nazwa komputera OS System operacyjny Uptime Czas aktywności Time in Chat Czas na czacie qchat-0.3/src/translations/qchat_es.qm0000644000076500017500000002547511002652421016637 0ustar owerowereKrX)uC UsqCNPqpcMiM^( Rd o4y= t7J  /E + I ʟ. > e S> $7zE yTU k  ny I I I I 7 5u 6  45  ^^1 uw ~   ޠ3 `Y  "  1r A4A K N0 RV RV R+ xG ] s \  Y u7 O =-w DY DY DY DY DZ DZ7 DZU H 3s M  Ĭ{ _EuSsdr=.}< ?= H ! ,!E!mCu!!!y!";i"]s sIPSOOkd h:m: ms&Ok&Ok AddChannelDlg&Ok enc AusenteOcupadoICQ: Libre HombreEditUserInfoDlg HombreMisc &Chat &Salir A&yuda &Misc&Enviar&VerHojas de estiloAcerca de Cerrar AboutQChat Cerrar>Barra de herramientas principal.Nuevo nombre de perfil:Puerto E/S: <&Editar detalles de usuario...6Nombre para el nuevo perfil,Enviar mensaje nico..2Elige tema de emoticonos:~Ahora escuhando string : (%t - Track, %a - Artist, %b - alBum)Telfono mvil:Sin fotoTReproducir un sonido en mensajes entrantesPerfil actual:6&Escuchando (desde Amarok1)&Esconder en bandeja&Aadir canal.. Completado (%p%) &Sobre&AplicarEditUserInfoDlg&Aplicar&Cerrar&Responder(Fecha de nacimiento:Tamao completo&Licencia@Mostrar historial de mensajes..."Responder &citadoBMostrar informacin del usuario..Pgina web:lPoner 'Ahora escuhando' en el estado de la descripcin"Segundo apellido:,Nuevo nombre para '%1'JActivar ventana en mensajes entrantes*Nombre de la compaa0Color de todo el mensaje4Formato de los mensajes :  Sobre:Inactivo Enviar fichero..Mensaje de  Ctrl+D Ctrl+L Ctrl+N Ctrl+P Ctrl+Q Ctrl+S Ctrl+W.Borrar descripcin (%1)&RedRed MujerEditUserInfoDlg Mujer GnerotMximo nmero de mensajes en el hsitorial de respuestas : HIntrvalo de peticin de mensajes : "Telfono de casa:@No volver a mostrar este mensaje*Telfono del trabajo:$Opciones [Perfil:  Foto: PolacoAhora QChat estar disponible en la bandeja del sistema. Si quieres salir de QChat - usa Salir en el men Chat.Emoticonos Estado"&Escribir ajustes"Tiempo disponible Nuevo mensaje...Acerca de QChat Primer apellido:dEstas seguro de que quieres borrar el perfil %1?HEditar detalles de usuario [Perfil: Nombre:*Historial de mensajesSin seguridad BarrasSin seguridadSobre &Qt@Ninguna interfaz de red vlida!. ejecutando QChat ver. Direccin IP : Sin dibujo<Auto cerrar cuando se completeTraducciones Puerto Entrda : >Error: rechazo del destinatarioTEnviar 'Ahora escuchando' con los mensajesMensaje a  PerfilNombre real4Ajustes de red incorrectos:Color base de los mensajes : correo-e:&Idioma0Color de mis mensajes : BBarra de herramientas de perfilesHFall: cancelado por el emisor (%p%)Ucraniano&Refrescar"Lista de usuariosRFall: cancelado por el destinatario(%p%)Nuevo nombre:PEjecutar comando en mensajes entrantes :Elegir imagenAadir Canal8Ocultar mensajes del sistemaRuso,Descripcin del estadoHColor de todo el mensaje del sistema*&Mostrar emoticonos.. Nick:&AceptarEstado (Tua ajustes de red no corresponden a ninguna interfaz de red. El programa puede no funcionar. Deseas configurarlo ahora?"Aadir per&fil...&Cancel AddChannelDlg&CancelarEditUserInfoDlg&CancelarFileTransferWgt&Cancelar8Tamao completo de la imagen8Tamao completo de la imagen&ColoresDireccin:0Intrvalo de refresco : &Rechazar@Editar la descripcin del estado8Elige un fichero para salvar2Escoge un archivo a abrirTiempo en chatRespondiendo a  Puerto salida : *Direccin difusin : Recibiendo FError: no se pudo enviar el archivo&Opciones...,Elige hoja de estilo :vPosible erro: envio finalizado pero se confirmo solo el %p%Enviando  InglsDesconocidoQObjectDesconocidoNo molestarMensajes,Elige ajustes de red :&Ajustes&Borrar canal..OpcionesRError: recibido el tiempo de espera (%p%)invisible"Nombre del Canal:$Listo para charlarCtrl+Shift+ACtrl+Shift+DCtrl+Shift+MCtrl+Shift+NCtrl+Shift+PCtrl+Shift+RCtrl+Shift+S4Editar detalles de usuario(&Renombrar perfil...Chat privado..Gnero:HColor de los mensajes del sistema : D&Enviar(CTRL+Espacio o CTRL+Enter)Cancelar imagen&Detalles de usuario&Detalles de usuario:Escuchando a : %t by %a on %bNo se puede encontrar ninguna interfaz de red que pueda hacer difusin. El programa puede no funcionar. Deseas ver los ajustes de red?"Borrar p&erfil...J<br><center>Chat de red.</center><br>4Editar detalles de usuario"Mensaje en blanco<Intervalo de refresco prof. :  AliasImagen: Ahora escuchando<Personalizado (no recomendado)Estas seguro?/$-5;KRW\dmPixLabelUsersStatisticsModelPictureScrollAreaFileTransferWgtEditUserInfoDlgPreferencesDlg AboutQChatMessageWithCheckBox ChannelWgt UsersListWgtQObjectChatWgt AddChannelDlgSingleMessageWgt StatusEditWgtqchat-0.3/src/translations/qchat_de.qm0000644000076500017500000002502611002652421016610 0ustar owerower#KrGXsu sGCuNPqpciM^9(S Rdu o4y t7J  /ES u  ʟ. > e S>W $7z yT   n I I7 Ie I  5 6  45 Q ^^i u ~  # ޠC `g  "  1r 7M A4i K N0 RV RV; RS xq  s \  Y5 ui  =- DY DY DY DY DZ9 DZW DZu H 3 M  Ĭ{ /iEu %S?scdr.<?=H , % ICu   y !i!=s sIPBSOkt std:m: ms&OK&Ok AddChannelDlg&Ok auf WegBeschftigtICQ:FreiMnnlichEditUserInfoDlgmnnlich Sonst &Chat&Beenden &Hilfe &Sonst&Abschicken&AnsichtStyle SheetsberSchlieen AboutQChatSchliessen&Hauptwerkzeugleiste"Neuer Profilname:$Ein/Ausgabe Port :4&Benutzerdetails ndern...*Name fr neues Profil0Einzelnachricht senden..(Whle Smilietheme : ~Hrt gerade Mitteilung : (%t - Track, %a - Artist, %b - Album)"Telephon (mobil):Kein PhotoLSpiele Ton bei eingehenden Nachrichten"Aktuelles Profil:4Hrt &gerade (von Amarok1)$In Tray verstecken&&Kanal hinzufgen..(Fertiggestellt (%p%) &ber&AnwendenEditUserInfoDlg&Anwenden&Schliessen&AntwortenVolle Gre&Lizenz>Zeige alte Einzelnachrichten...(Antworten (&zitiert):Zeige Benutzerinformationen..Homepage:RZeige 'hrt gerade' in StatusbeschreibungMittlerer Name::Neuen Namen fr '%1' eingebenZAktiviere Fenster bei eingehenden NachrichtenRechnername.Frbe gesamte NachrichtBDarstellungsformat Nachrichten :  ber:InaktivSende Datei..Nachricht von  Strg+D Strg+L Strg+M Strg+N Strg+P Strg+Q Strg+S Strg+W6Beschreibung (%1) entfernen&NetzwerkNetzwerkWeiblichEditUserInfoDlgweiblichGeschlechtLHchstanzahl Nachrichten in Verlauf : LNachrichtenverlauf Anfrageintervall : $Telephon (privat)::Nachricht nicht mehr anzeigen$Telephon (gesch.):.Einstellungen [Profil:  Photo:PolnischQChat ist nun ber das Systemtray verfgbar. Wenn Sie QChat beenden wollen, benutzen sie Beenden im Chatmen.Smilies Status0&Einstellungen speichernAnwesend"Neue Nachricht...ber QChatVorname:fSind Sie sicher, da sie Profil %1 lschen wollen ?@Benutzerdetails ndern [Profil: Nachname:$Nachrichtenverlaufweiss nichtWerkzeugleistenweiss nichtber &QtHKeine gltige Netzwerkschnittstelle!( benutzt QChat ver. IP Adresse : Kein BildHAutomatisch schliessen wenn komplettbersetzungenEingangsport : &Abbruch : abgelehntFSende 'Hrt gerade' mit NachrichtenNachricht an  ProfilRealname:Falsche Netzwerkeinstellungen(Farbe Nachrichten : e-mail:&Sprache.Nachrichten einfrben :(Profilwerkzeugleiste2Abbruch durch Sender (%p)Ukrainisch&AktualisierenBenutzerliste:Abbruch durch Empfnger (%p%)Neuer Name:\Fhre Befehl bei eingehenden Nachrichten aus :Bild auswhlen Kanal hinzufgen6verstecke SystemnachrichtenRussisch$Statusbeschreibung:Frbe gesamte Systemnachricht&&Smilies anzeigen..Nickname:A&nnehmenStatus ( Die Netzwerkeinstellungen stimmen mit keiner vorhandenen Netzwerkschnittstelle berein. Wollen Sie trotzem die Einstellung vornehmen ?*Pro&fil hinzufgen...&Abbrechen AddChannelDlg&AbbrechenEditUserInfoDlg&AbbrechenFileTransferWgt&AbbrechenVollbildanzeigeVolle Bildgre&FarbenAdresse:,Aktualisierungsrate : A&blehnen:Statusbeschreibung bearbeiten"Dateiname whlen .Whle zu ffnende DateiZeit im ChatAntworten an Ausgabe Port : *Broadcast Addresse : Empfange BAbbruch : Kann Datei nicht senden"&Einstellungen...(Whle Style Sheet : Geburtstag:Evtl. Fehler : Sendevorgang abgeschlossen aber nur %p% besttigt Sende EnglischUnbekanntQObjectunbekanntNicht strenNachrichten:Whle Netzwerkeinstellungen :&Einstellungen &Kanal lschen..Einstellungen.Abbruch : timeout (%p%)UnsichtbarKanalname:Bereit fr ChatStrg+Shift+AStrg+Shift+DStrg+Shift+MStrg+Shift+NStrg+Shift+PStrg+Shift+RStrg+Shift+S,Benutzerdetails ndern*P&rofil umbenennen...Privatchat..Geschlecht:4Farbe Systemnachrichten : F&Senden(Strg+Space oder Strg+Enter)Bild AbbrechenStrg+Alt+EStrg+Alt+PStrg+Alt+RStrg+Alt+UBenutzerdetailsBenutzerdetails<Hrt gerade : %t von %a auf %bKonnte keine Netzwerkschnittstelle fr Broadcast finden. Mchten Sie sich die Netzwerkeinstellungen ansehen ?$P&rofil lschen...Netzwerk chat,Benutzerdetails ndernLeere Nachricht8Tiefe Aktualisierungsrate : Nickname Bild:Hrt geradeFbenutzerdefiniert (nicht empfohlen)"Sind Sie sicher ?/$-5;KRW\dmPixLabelUsersStatisticsModelPictureScrollAreaFileTransferWgtEditUserInfoDlgPreferencesDlg AboutQChatMessageWithCheckBox ChannelWgt UsersListWgtQObjectChatWgt AddChannelDlgSingleMessageWgt StatusEditWgtqchat-0.3/src/icons/0000755000076500017500000000000011004426107013070 5ustar owerowerqchat-0.3/src/icons/status/0000755000076500017500000000000011004426012014406 5ustar owerowerqchat-0.3/src/icons/status/user-dnd.png0000644000076500017500000000123210664050043016643 0ustar owerowerPNG  IHDRa pHYs  ~gAMA|Q cHRMz%u0`:o_FIDATxb?% (c0221k'0*H3=?[f?~/|L f87tjxp] Q0UB  /_on cdUK\8X ~2ُ &]aJ4}Ϟ|-[/ƒ@p0i+zr&@0|ݷASӟx@ `dx4u OJK1BG}=7v>~Qfv8@cۗ w~ #"a(<~d`:}s73?Cy9f~rs2L ~ZXax;q"ʊ B@1(!-?o`~̫W 7 55͙bߪ / aŀ9Bo`ba`db +Ù;tu P . Ƅ ĥS5b$eb47Ź w-*|IENDB`qchat-0.3/src/icons/status/user-busy.svg0000644000076500017500000001577010765243616017123 0ustar owerower image/svg+xml qchat-0.3/src/icons/status/user-online.svg0000644000076500017500000001300110765243634017406 0ustar owerower image/svg+xml qchat-0.3/src/icons/status/user-away.svg0000644000076500017500000003142310765243574017076 0ustar owerower image/svg+xml qchat-0.3/src/icons/status/user-away-extended.svg0000644000076500017500000003337210765243547020701 0ustar owerower image/svg+xml qchat-0.3/src/icons/status/user-offline.svg0000644000076500017500000001444310765243627017561 0ustar owerower image/svg+xml qchat-0.3/src/icons/status/user-invisible.svg0000644000076500017500000002054410765243623020116 0ustar owerower image/svg+xml qchat-0.3/src/icons/status/user-ready-for-chat.png0000644000076500017500000000156410664050043020713 0ustar owerowerPNG  IHDRa pHYs  ~gAMA|Q cHRMz%u0`:o_FIDATxb?% X@### @ S* oZ@`j5@N 8?e`xkƇ&u52|3 _.)c*P3@|E Gmc7.0|H/@1O?4Fk@ŧЊ@+Аo H´2*0ig A70A™h#ǁ dw[Y? ~}g/hU O7dw @Ƅ O6 XH/@ AQE0h30}!v+F>^G`B&L00}`Ġ 4 2v@obo8jWVvVy ]? Ovdxs?o^F^S2o ndbc?eX8z_E9< c(W,t"~ nik32|'b( x:J _>:K[  CI.JRz Gmv_exsËC&02@@jfb`Ԉ `6@IENDB`qchat-0.3/src/icons/renameProfile.svg0000644000076500017500000012512710664050042016413 0ustar owerower image/svg+xml qchat-0.3/src/icons/private-chat.png0000644000076500017500000000303010664050042016163 0ustar owerowerPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATXWOh}oޛٙݕv-kȢޢ1$$.-An/)Cz紾$r9r-צB 1(rWBղu=;3;ޟ4^KS>v{o2rk+++?t:?@7o|gccCn.^˗/߸qΝ;Vp8> lٳ/^~[[[l}}={n(WWW?m0x]zA%h4WRJݻw/ MD9!l6@xVsx,WƘnv-yDQ䬯?!"gU3(OQ "+Ejիj`0kkk[~ߎPZqARJ'MS' C}gi--- /0 iss=b^~…{ I{ޫv71q\^^^lZPj/ }p8z!}dfĤaeRbxps^4(8!SkM +++I߿4M4<!^f1V/NSR(}1'jZm,t/Fѯ1f&!%_Mlu*fq KoD^+6WfYixj*Ckډ,Ha:JOl3`z@lpxZ^|R0@-gU}^cIENDB`qchat-0.3/src/icons/message-unread.svg0000644000076500017500000022350410773234577016543 0ustar owerower image/svg+xml qchat-0.3/src/icons/emotes.png0000644000076500017500000000376210664050042015104 0ustar owerowerPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<oIDATX]lT3wzͲ{mlblH0 %@(*$4i@(QR}CyC+兇DmS*"j5T I$`ť|6`{}>ڬ 1G9sf̹A;ZIE}+ FL]}fN̉"pPDXiu[Ԃl1 }kL_e柿cevh;fה)fg- 6B7jclcI)7IL4%blCý;{ ϝ#o ebO>>R z=\vA8B*uB(+Xw~u~Œ_TDbh"6M^wyp~آߌռ΋My{a_}G<,]cKpv(ΦmOP߰o$\2b֬a1[řBD׆u-FDBDEJFk{HM8XZBh)in~|Oy6mB:Ck(ǎci2c5`9M` SMmmN2 ZkBzD޶G5!]V WHF)E{{;tQt4(#蠻d2 /A)Aڂѵ @ee*!\. >\e||I&{r .]DP N>EB!<*+[[jd ~8`@EcPJ1fźA|0>6 ކ0]w\" L@ɐ_]%p(_a`2ɮDQX$O!lV5ȱdcͻ%`cBA&JtIX =%$hoV4{\hm n|Z~tB^䁊4TfQ.hƈX UP830e *u, FDo߶rynYc*AH*@@XX)]եSSB \7&M3%ėJ| )+c8ɍdԥ{8A"8mI1&RL#fj&| xZK[hIqDŽƂa$l PVLo*aRES (Jw gJ,R0Е4/20>hvOƱy n Ҏ?/'$5bFOz$ǒiƎ'=~jmߘҼW͛-NPN#0?t/le1( |h קN'D+;CQE@ZwʢnO"5f¤aU>BlAP]q[V6{w|iUa`ZV>8ݶEUAVH2X+ȏsbrUdL5QcYi)wmֆelUj4/Él?]|te~O9I=t7-m 6VQlq A dYƯpy$3XGϏ|o ).ʹ9aI,QE>Fu|!ш-%Rk(d&qȎLp-L P Ƙ`!(sd2]QQ*;HuF>t&(1FdxjIENDB`qchat-0.3/src/icons/go-next.svg0000644000076500017500000010154610773224244015213 0ustar owerower image/svg+xml qchat-0.3/src/icons/help-about.svg0000644000076500017500000003731610765114533015675 0ustar owerower image/svg+xml qchat-0.3/src/icons/application-exit.svg0000644000076500017500000011003110765115057017073 0ustar owerower image/svg+xml qchat-0.3/src/icons/unknown.png0000644000076500017500000000352010615452704015306 0ustar owerowerPNG  IHDR00WsBIT|d pHYs11(RtEXtSoftwarewww.inkscape.org<IDATh͚[lggf{mIv"T$ U )B<CRCDB@AJ"$x E}AFx䡼qQU"PD8&zlgf׳3ggA=|.suHW\DD$H"zG :o/ǿ_l˷-kM,9$/>F3 >__x=\sRs˳09>MP~Io2˜|f}a~:^v6`Y@^Te:w6C|WC{?%-]v͆{…sMA$4jZ_w{Y]k<,f{ jؠj!FP,.]Ǐ [8pٵ3;o6mh4jNP\.clb@^g~~c~T54>9Oo>>֕mcnNR~ȑ⥏zGI@ $c$Jy~uNgl]նmfǛ/..fggWލ kw9eO8VFA\:jU?yY0Ј O%ZH;wRu%̙3]YY,C#ql&g`Y088͉'δoNY 2u,:Ji0M&xbu4B6+@3+GDrhf?G)poRixGxLlϽߦxse |<ܛsf&_xklnܷ,+IENDB`qchat-0.3/src/icons/format-text-underline.svg0000644000076500017500000003366510764612702020075 0ustar owerower image/svg+xml qchat-0.3/src/icons/go-previous.svg0000644000076500017500000010673410773224261016114 0ustar owerower image/svg+xml qchat-0.3/src/icons/help-about.svgz0000644000076500017500000000576610763304342016070 0ustar owerower`~uFdocument-properties.svgz[m6_sp@gɶ&!@rwٖjҞ7ʦei-{_rC̈R^s{ >ydq:fI8˻ Y|fo_0xQςUR^ߋit//z<V+DYس*|Pf$&jt/7EGe:~MƟMG2Ӳ]g_EvO5r9z Vbk툲c!r:-0-^tEź2J&?le2n׋8 騼DqPiPC(Iq_yZw'lBCQ<%{H۲5[ UtǢ&&%: Ng)u B)okGk5xfT`zVfɣ@ϸ:\EeܾC0Ð[cBnn NG[QVe$Vqyuf+9w42L8e<*Z[!UJ_1/:xG`@o{Z T.1Ph欱Y 7(L6")F )Kon|a1eXWljJ68NW\+E#%O.7UQӏ5|p`FYdNiKS,=>2[=43NJDC+@RWSУQRtV=TezXi{PTTR񾸂< J]@0^0DJʥ)/D > x@$`A#0+NfӞ=(zsiZ'{P 6e0Pcz1I4WK0S+^E |w` 瓫wD[̵&*ZJ47!"%ᚁoU%sx>Ny>: 򏋆(MQ)N鏓iFfl#ݿ)'wݽ$y<½8%S2^xZ@`Юף~ı(˹y@@gS(46 &XJᑻ0ZJ\.@{;,BP-SGoq$ݣ>!򈵲<.) VyN4`ԱCyt˨_RD -l] \1uXą[?|7ݣx?4T4 5M;߲NV<}?M }S>Ė0V7%խ1Zi0&Z+5*]}}r+cUn4o2ȣZ5)~++B*"bg{ P8Q!Pih*a4Ӡ"ç+l(a_=24e3-#mYAGj͕j1W Iu:ϫnd,7M:M3^Xb7궝v,[~,ed-* Y6q,7wmusǰ1YZWI3 7O='Se=YՄ eZTe~1#tTE_뺩Cc$- /h!O먼Dy, $kh E6w6ݶN}-Iv@W}jtpT~\E#ĿgG\c$4|+J\%>ؿwBv Q=Mmbe4жRvs}=]kL6#]>nr׿n\ZcTY귑ne L C+7(FJhⵧG h6^g3bc O(r9ٱK:F+TeԥB=X@"Tr톩@_8kMnwtRle+K59)b! ? `}-n`I,J7MX._tZ8"\MȲ B'% eY]B vtH5)1a$TG&h^ZXh30Z@-3q M9|h M9Z&AUibZ~T)*ÖKdYYWfOyy\s$(^K(HEYAe}P(0&x_Lq_crH28B\eiH 9uk;aL 1*H+Dj,6ߌ^ˏ" f9ĊDXF𸼽Xps)Nsf/(Y+C{@ image/svg+xml Oxygen team qchat-0.3/src/icons/insert-table.svg0000644000076500017500000012120110765004462016210 0ustar owerower image/svg+xml qchat-0.3/src/icons/tab-close.svg0000644000076500017500000062233010765121014015472 0ustar owerower image/svg+xml Oxygen team qchat-0.3/src/icons/user-male.svg0000644000076500017500000006021210615456331015515 0ustar owerower image/svg+xml Oxygen team qchat-0.3/src/icons/send-file.png0000644000076500017500000000307610664050042015454 0ustar owerowerPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<IDATX͗[lWߜ3]kq ih҈Ȕj)}+T D(HVLZ@zeC0@)79i>zKi[Ɋ[&.]kC)VD8/_g?Ku"З\y-1pbwn'b_ [GSlJ:_gr!7~'b1o0W^9qWWM azl޺ށ80[Q,/ <ӾcZeqp\@DY"oO#/0zkn]j5"‚q ԑS|nwc\v@ .x~^2u0_v?py)-M HfιD7ҝG_hD&4\*;_Z6zĻjVz[97=oetZ#wMmӏtr5Dtso͐ĨW}UFŧ^hTyVgZ)lBֹRJ&CAt5AA+r@?w2~V`+bj[ 1'ow;xZoD6фM,mӕюEa~Ý ݞ[ :fL}ǓٲSG,iFG,jU}Fi />uCuqhcL5PG=Ltսn)cJN妏>9| 4Ƅ &a)IENDB`qchat-0.3/src/icons/message-opened.svg0000644000076500017500000031773710772515711016542 0ustar owerower image/svg+xml Loren ipsumdecorum est valorsitum delor. Loren ipsumdecorum est valorsitum delorLoren ipsumdecorum est valor situm delor qchat-0.3/src/icons/remove-profile.svg0000644000076500017500000057324010765121754016574 0ustar owerower image/svg+xml qchat-0.3/src/icons/deleteProfile.svg0000644000076500017500000001146610664050042016406 0ustar owerower image/svg+xml qchat-0.3/src/icons/private-message.png0000644000076500017500000000274210664050042016701 0ustar owerowerPNG  IHDR szzsBIT|d pHYsvv}ՂtEXtSoftwarewww.inkscape.org<_IDATXߋW?9}ggwvggfCnSv? ))RD] T *PPJɍU0ƀB-5-8IvvvfqDś\px<>U{ޭ@TN>g %_v: b6['?YY+ln:wga`7Ws=A/ :cA!?6fNY)|~W0Iy11Xkx-N|Ṫ%k>!B{őE˧9#xU_awkLN=XQ&&&^C+Xcp FzO3x@߶}j} =i5! @|YzE&gƧVX#6}\^6o_@pHĄ¥?1ErSfl*#j J+Dis޾bR)9L?,K:T |%w1r#^"z!YCd']g'#4Bt3o6~$Q؝jߕ=b@U*ii`ow ƻ(,CG!wRpAQ #tF,ǏLх2ؐQ-2([?\/} {_U5 drҽԣKtw=Pm@F-=9 k®24t<)=^ظܕ ăb2.Z\Fgv AH Jsgry1;"˽-3֥_:n"D(.R89Mm`7!6h=uFGQzw:v0h}Gm.ݘ9lWV3۷0fMd|\Lz2@νLFcP]+m"K9Z.kV|̟yCl image/svg+xml qchat-0.3/src/icons/edit-rename.svg0000644000076500017500000010542610765122600016017 0ustar owerower image/svg+xml Oxygen team qchat-0.3/src/icons/format-text-italic.svg0000644000076500017500000002670610764612574017362 0ustar owerower image/svg+xml qchat-0.3/src/icons/format-text-strikethrough.svg0000644000076500017500000004114210764612676021011 0ustar owerower image/svg+xml qchat-0.3/src/icons/im-status-message-edit.svg0000644000076500017500000020532610765225347020134 0ustar owerower image/svg+xml qchat-0.3/src/icons/write-settings.svg0000644000076500017500000014350710664050043016616 0ustar owerower image/svg+xml Oxygen team qchat-0.3/src/icons/user-female.svg0000644000076500017500000005125310615456101016030 0ustar owerower image/svg+xml Oxygen team qchat-0.3/src/icons/add-profile.svg0000644000076500017500000044450610765121723016025 0ustar owerower image/svg+xml qchat-0.3/src/icons/animated-new-message.gif0000644000076500017500000001343210676554257017603 0ustar owerowerGIF89aU@   $&$)+(796AB@?FMIKH}ZEr,[(wZY%3fѢ]٭nl1 fp R*U+.b-&͙6nپU;Uw˧|9獽ѳ 0ll47s! NDѪE/_UM歚VtЩ5uΟemH7e}{*ZsvL1k 'ޚ.ݹ۷ng;F#Z5[6Mo޾KU]:u-[ċ3?z,ױei#-ܹ;UO9TӞpzgYSA 1Ts4 jMv)NK<Yf0τQh=D׌5VV%݀S-+J`[\zYg* pT 7┸g8M%3p',`+xBn4\\s[-POg 'ըc 5t3 #dɩmA/R96|W h'ٜ=O5Npp\g>VmB3vd5(`0"x1NR,:7c]3 aT[ jC &>JHCMC&l{܄A>:ՀAA,M͑X %CxNC& sgh';3*>@UuTfb3366B%s6E>arg9lmG؎ېF3%^$:_>pPQB,̜A4 t H9 91 R/z P8-Fc!I@b0uR\Ap#R a|`S +@ar q?%DS 1Y>ODeQWzG#xb,7R j2_0B 1PntqC_~qr+0L5`5PZ"3HFv&#㸎6 TlAR:{şjЧ(VM5C!~dalC`Fb/y[?b0hv b8_Ĭ=q[" =2\#9 OT#(2`>0F @ ;"#&n>dø5~2D%xIvEXݴCIY]fQ7]İŴ4g BC',CǓ! AX`#)P]w0qԙ}LE P Y &;>+:tAXX1@}Abq2+eazhiHcvjXlBh1? `D7r[x"#쀇b5.udCEU|VpO&P PhFD&n18@@,*6Ho5ڑ+x#9>t"@'9{Ƃ ! 5p4> nP\`9G,b!,WZ^s!`/Hכi0Q]\$ #A3JvRWwVl}ܱ!j!\?N-a{d}g] Wv R1gb+20 R q@a՗.@LW 0-uܤ"fI3Y %0p @H$-HPE#JHs 0"d!PC(&| t"s-r7 0W4pL!@f[PP! @ 7+DZZgXE# #'P ,8XxH!,U6́F*\ȰC婢ŋ3jȱǏsu4ɓ(S\ɲ˗0p֘,psϞ@ JtѢhϪMv۶pʍK\8봯߿ L|,m>Ð#K^hxʸ9?ʠCO旎ڵh=aQ4h܉M/<׭+YbʔQW8zՔUUlٲ\dL;L3}pň5͚3b6mZeB}ҿvLZ{g@'5P^5b˂cwS˂G [786Z5ˉ(3e t7|3N5魣9x#}G0O0~H23pcnފ^&V9T38|+7GljhTs}Nʰ:<738T.3|}57A ;A XMnl޻nPs9M#~u#kdh"l(rHV?݈skt u5Ԅw~5⁳^ h*? Ə*pu֫GN[8\X5턎}NZk-uЁw@;8wlܱkx[-8.9\Q xTсl&4xAK=$4h!uouKa`?ĝ,UHC~Co3Α]! @E}Q f`2A9P<` e(EڥC@` ӱE.nH;XK9QMh OH6'X! Pá<cE/zq/ ӡ1p|$#Ulb툢:uh#JPDiNu3ݤ_9 x:lћ2I^ճ-0R(S;Q^Ԭ3;*xpib=zpE]tĺ#U/o/Yo>xУgx8={l rP0q꿚8FlS/4#=m|ܣGnyCƇ o}]|Vw>q\ h0O=m|lA7y>qyFy9ry9M֍hfzQ>򏏛HCt}I9ҟnpr7>Sf\P7Q{c>򡏶>0cs_8#m)~p=v̤׸uŸi;?6};}t;C^CO6*{bkZ×0j}{߫EfL>>eRKj|V[FSS>_VC\oU|,߼SPyg䛅}!fc2 6p, 2ph 8x  Xh!0q\`/2!.X4X0.26x89(3x:hU0 ;qchat-0.3/src/icons/dialog-close.svg0000644000076500017500000003077110773224636016202 0ustar owerower image/svg+xml qchat-0.3/src/emoticons/0000755000076500017500000000000010704431163013761 5ustar owerowerqchat-0.3/src/emoticons/Adiumicons/0000755000076500017500000000000010704431163016054 5ustar owerowerqchat-0.3/src/emoticons/Adiumicons/alien.png0000644000076500017500000000162010654705376017667 0ustar owerowerPNG  IHDRĴl;gAMAOX2tEXtSoftwareAdobe ImageReadyqe<"IDATxڴKH[Q'cRUK].ήlA(iB"Zu "`ؘFc;K g3gfΉŒ(Mr++_899\,Fmwww餺:d2txxry,qY\.YVB< jjhhh׬M{Ioo{ppP@:N8F^/2CX048+VGLѶ6w__@޲QTQGGֺ0g4H6R*\c y3`?pjnn 瑎)Hɉ,6<!z_ eH&/GpvwwiggjjjbP HΤrgdKaiևp8<"pDHq?@xFh%\J^r`X5Z\\1cpHK: BLsg@@^/9Xry9\4X,&RpAoX5Ï|Wetn<9_Z MfIŹc32,{ک3[ٹs \N [PB[|\} ntn l ﷽{bM?!A@#O(HJ$_ 5j"ؿܺ;fƿRwv5u@ 6aYf$\6 Z#b)6+ڣ1MYΠ,XFƃ5J(zτf`%BU:5FDO~n 4$})h>4A ሁ~IN[S,_`YCc7*,|g= [Q)skw JSVxy-2?5!3`{o']-i3Tj&~9 w݇z6ؔFiFi7_=ъQ, dVyoFn/ $Rj%K4fH_П㼜 x'&c|uJ8gy:\X-&>+'nOKU1#ﲪfiR^?ΠnEWgyqgVVvv~Zyua,߇):ߘ8np.8/.\ [{#v˧gxy9\Lc!u3mH}j6/ +-t.J;p5)hэp#qMd%G` 5,1:,F[W>(ى,(V$'nIXSRy%oL՝rfeREFǟyw6yo*ǯe\&df :x&ΉcYvi:mq_+ZXT<3< V9*U|sBwOͮ<~{oWtydƁhchy_O*IENDB`qchat-0.3/src/emoticons/Adiumicons/angel.png0000644000076500017500000000217610654705376017674 0ustar owerowerPNG  IHDRKvgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڬkL\E,,HHVEWJ547h\JWbD5CƬn?-$u-[k*me}{3w.%S'gvΜ9s̊1Kɠ `i-~^R9fcUOOH ӱ4lۤ#QXlCN(xh@D/g>&8dF.:snOE(ǺhM=(tǏ.mt>MofyrcE6?p%6~!sV#gq&2fQ%DTOVVnkkCs+k+(+scbKτM@- ǻ_H[:[}|;mI @Cv4qa7& ,zհÍC{_1SCH/)c_:TTI2Ds~u_e+x'b`6#&l.q﫺g;)o7Ųool< {wJ.k=M5=nQn˵Ȑ2r.f"o,/w2}ױ." PCPjױQ gBWWI"3hKROb$ l~i6 wJ=8ModD8Uh x |{)owplwxXMO<*P)\VD3gȷ`%s^<&g"pLKoNڕ(^̇&c]j:\y= rNW4 XLz'saL^]= [_|YuvTT3,L"t=` Q=TnL.FS1=9)ҏ{`aNLQYuIENDB`qchat-0.3/src/emoticons/Adiumicons/wizard.png0000644000076500017500000000262410654705376020104 0ustar owerowerPNG  IHDR!gAMAOX2tEXtSoftwareAdobe ImageReadyqe<&IDATxڼV{lSU޻W :Ա :ǀÄTPW0.aLԠaM.DSb6b1!  E,lmѮڮwnˀGI7vvsMG'yi"2Z#1+q#q6CUe (N#^]<;pHU36,قnaRNغ,{D`5FF{llk9B b\ySȼL.H2\E>- ?x ^:|ŎA:Vu6-uk&ڳo8akT3PS /6װ`ANb%Ψ[MaPE0I^ 2Q _Wu#iNĦ|biz=毶,\4TK7awD%K;ٮ ީ־6{,QU37&oUM z#zgo,@'ڹxJ@ZG5`Ē3ebC6m~'cIWw,%$PDLWn'EP}t h,\zO<35HC)0{/xX'}xܝہn4\5qȆw@mT':\{\Eb޽~PT r a\hf6XIݒ(WdrHO'*~ Oj{=&u=C^ЙggDֺȎk,z` IENDB`qchat-0.3/src/emoticons/Adiumicons/angry.png0000644000076500017500000000172210654705376017722 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<dIDATxڬKLTW;8)amRiHHдVWI\EXݚM7 ƅm4mj|F&J!<8{ /Ӎϙ9~3BJ xS,QIMm Ǩ_kj~*TR'J+*?iiAu}WW@:YL ?{Iۣ{gggbFJv6%"(s/EP_(Rq?_+=y>CktwhDTM.$C/K|FT9;{u Z[CnlO4Ata%Ne9KK.Jw@&g(HRR2E#9y ƗIu/^V\9mgh$Y?EGé!5>TfH%)nZj*[r`B0:&ȫ@]Star\#O{.Wj)Cϰ[zg54 8zˊPv=ۉ)pG~J.Fّ06뗅%6]甪 c`Ȋ/SU`"%CG-?E[,:٩Z8 QgߖPPً1Mn\ZZ\`JפXn~ 0\)~"?tIENDB`qchat-0.3/src/emoticons/Adiumicons/bandit.png0000644000076500017500000000151710654705376020045 0ustar owerowerPNG  IHDRw=gAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڴVKOQ̴P!P`\j\I pk.HjL\7.ԅ&j$>Q!Ckit nr:7w=}29g,\1<b;S7Yϸڮ.@\]ٯ_|?>M||51_\3eOXp&;F-eD=j ǯyk,|D+JRd9wON$Ce"q1]m&wl$jX`>>7#& Ob1Lc,M Br$%M^FpQlrԺ.A$FDC~SD*IR$ɜ5Rذf ECmZ+[v?@'Y:gDE ]toŠokK,ݎ,AӢL3Svmor@0ecMJx 2 "k~<4wg3@?dZcTLw7uf.)vJ?E8`!H$bY!?<3bViDtEqXk  B9Af+K8o""GĒEVSZհfYdKiji=0U~DҘbu(Tzg hT%-$P\DZE,-(&PPŊ?%Hx]!D SAZ-AkHIENDB`qchat-0.3/src/emoticons/Adiumicons/devil.png0000644000076500017500000000201410654705376017700 0ustar owerowerPNG  IHDR|}gAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڬYhIUӉ f6C< $xlv|j`ԇ/Jt];d :,YE}Nj(4j cIB$h&s$sdzdb>WW_W?V6%P-z$E2Qۚkz ۻ׀ȩ.RrL@r5?CTҶ}=XZP3N(Bq [`tC娞/k \>kA)D3e蛮ZM.;?^FMr'*(=jl(o#UY&9z#Y2o~Tf2J@RP/}L z`J'8ayoǝI*ƈ%+т u[[gA'曞~4t/paDzѨRlGRxHn9ukҬ'. ub9B \䉧]Um%܄;̞O_Qcw) ah$.NPO0r7Q~yN]AqTRYR1nY7h=gb4q{/1Q&ԹE+^T_XҶG{Io "~ {fp2#uGVI9 au, X3ؕ>u9\ +s=`Z?.IENDB`qchat-0.3/src/emoticons/Adiumicons/heart.png0000644000076500017500000000142110654705376017701 0ustar owerowerPNG  IHDRZgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڬTMHa~fggvg5EC˟:RaBQ ١CЩ):ݺEt *]ͺDIm٥2[pumwuwv 73}ޅ"DNt6"N!M>XDWL3-7dѰmT| zF@qmfCBnmEgښb3Nw(VWC H#{:a; ifS>,ia`R&E#Ds윍lj '2E+Jri<HLF\A{4NȅʌJ!ch2ܴj$ ym/K1gy ObY-r2# c|VS_%tG򝺔W9E^Ir kφɒf݋t25`0\X~$R>gX`U_,A^yBLD4h6OD$yAVqV8b]sd,= xajLHǩyNJH[uexPkc6FtQM\c"wVߵe[Z.0a^98[]"f־p hy(H#l`5IENDB`qchat-0.3/src/emoticons/Adiumicons/wink.png0000644000076500017500000000173110654705376017552 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<kIDATxڬIhTY7`bʤ5 1!EZ bMP .tt5YԅnTЭP".t#JV*tJh4j*f{˘ƍEyԻ|QEOmUfRajZP7T0M}$TGiEő-- 3/^n|xi. l.4m޴y`vXX_" z?.l1k4]lcfU W Xi*̵;-o$D`sC[[5MuPt*&aiV7H|g@ PXմcK?#V2( lNL>uGd[R0!-0\$8gƻ W; !3bCAh•FYl=CXƄH}+B`qG@t&.-Mf{3 3eUd{IZg/Lq6`SΪ-7餁/R?)o㛳<`٢V̺2!mW#KXچ9'z~̑s!$qXW>9NS4TwR wrKpdOOCeaO<ZQԎQkiOi;ƒ\1TRdTO=49Y?Z=(D.hYfA0U|Du6O Hʁyk(tu806gP1dCN2xk"Hx;f ZР#i-NR0ZkQ0>fX79Ѣ"3MKɠn\k£\! [ Lǒ`:_(Q o)gS/|cO^K% ዥ kV {Ҩ/xڥ[,&ko* _d$Їx*j+4t _םc K1o99< $zxףb8n&3R?:WE7 \H7`'|~ 08SꕪIENDB`qchat-0.3/src/emoticons/Adiumicons/cool.png0000644000076500017500000000170710654705376017541 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<YIDATxڬ]HTA]]57LiIv>v1R"^ |K >^)¬"p5R Z~LgziÜ9co-$T>7Ϣ)-Tslae% Ř]0kχU۽ #ƴv(øVJ᪮*زfK2 h$]l=8il'hL{w9leN$@$#$0 XMX^ULe-}"`)j6W1m;.A Mh&E)U1KJQ<,Ϲr1I=po`pv\L| Gˆ\Ǎ}89[z2oϹ&WF,4Bom6<9voa+ "5EM2 q2 F{AӼ~T):2^~-5>P4Q@QPEC (pxS@!blFm`ԓLRECh]wI# ROKz:с5S؇Xބ[Pjly^lIENDB`qchat-0.3/src/emoticons/Adiumicons/wondering.png0000644000076500017500000000176410654705376020604 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڬT[L\U]ΝZ)&%mZ6"DlLjɐ61c?lef4O4HILј66 TtPa^㺏ɬ3g:{sd! 8.K0 ?A%0q"RAo9F9qz[Yٹ=--Ϊ2-uNNXeo$l ?z. dF=DizI$c&6#q)Nk2 %8x4Bv "g5 )/ M!8Dv]WFM.]YqGw_?_!Fe&@~k~ Ġ +id #jϰ(9 ј/:.{>" M| *­J'ͣCdm1cTvh}uM&y$ $<]8sX/ Y=Hx;)#d%uU%d僴cۤ` : ZD0YoίEE$J r&5g2ǚk̀אki2Z$c"/!JTF irC>cNY:bh޴`봧 Y͚7K h5N6 Ǔ5Sq*]b4b\,wr%zv4Fk&5e"d7'ñ.5Υ6lRⲎRgl&i@#;7͸S{kc7yvno}wyQZjV_ 2Ax.Lф!}{ʕB4Y}#8ၽN n]%r#ŔIENDB`qchat-0.3/src/emoticons/Adiumicons/emoticons.xml0000644000076500017500000001144410664126001020577 0ustar owerower ^_^ ^-^ ^^ :)) :-)) >:o >:-o >:O >:-O X( X-( x( x-( :@ <_< :"> :*> :-$ :$ :'( ='( :| =| :-| :-O :O :-o :o :-0 =-O =-o =o =O :-d :d :-D :D :d =D =-D O:) o:) o:-) O:-) 0:) 0:-) :-* :* :-) :) :P =P =p :-P :p :-p :b :-\ :-/ :/ :\ B) B-) 8) ;) ;-) ;> =) =-) =:) (alien) o_O o_0 O_O o_o O_o 0_o o0 0o oO Oo 0_0 >:) (LOL) lol (:) (ph33r) (ph34r) >_< (police) (cop) {):) :( =( =-( :-( :& :-& =] (-.-) |) |-) I-) I-| :s :-S :-s :S (woot) (w00t) (wOOt) :-" (wizard) :? :-X :-xX :x (wubya) (wubyou) (wub) (bandit) :(> (L) (h) (H) qchat-0.3/src/emoticons/Adiumicons/smile.png0000644000076500017500000000173010654705376017712 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<jIDATxڬU[O\U9gʴM*0BĐcbJ}H111i>˘B5_4% 0v\ps~207ַ׬=BJE%qt?@>8_!~ qPwcCfTR/׽gGwwRR:_v/tv|?->]ة-l_0tUDA77C /CME$! /ԡz[IrޠDˑ]zB wQݞ $1FIk 4]8=US^kϓ( $Mu XV H t#X"!H҉D pn{dTU $+QTl Pb($y6 lnr[zJjB /Xw9W(e%ih?Dd.w(MA"XzP!df2N3=ƩK#P V\z Q97T ͦS4(jD'9A,[[Iw^Ǖ 0y+DK tY4b?!2Rd,S! {*i#ճ.ҩF̐t:xOd15J{?/I:}5]:F˷_a/7Ꚙlo/N0tͫ219Y33Manv^^yef|AgWw9劑!Yځ=OI SمZJqΏ*^-_be54SmouL~I89B#IENDB`qchat-0.3/src/emoticons/Adiumicons/whistling.png0000644000076500017500000000213110654705376020605 0ustar owerowerPNG  IHDR/WgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڼVkh\E>rwXSm&6MҨMh)MRiS|D ࢈T)%VAh ZmښmmH6li׌gnf֭|ޙs\&Gnѳ{9)Xyz'XZ&n<Ԯ7@6Ϗ 'dIyQ_][N44cqC-;=܉Bwio,_#-$l%[k]AVaIK=j l[|%:ra\>i m}p60̏0D<Jg!Ұk)|{<>| g)q&M;ܸL#ŋ^@~*4!h÷5VTu׼;~zr3d(HUoˮ~`73ƁCH$54uz $6a]I7ds/E\C F1, c}WS%+A2-bd`XQo_M4}p9%rCTTBA̒r&e!&Z_# v>}07ꛫnXZr#fj-@"[gyA(# DL`rԄ51*"Lb~ ~3{䤚J_alpAH_*I"͸sJ I!GdxچrG/JPԔzy~쇙 !ey[PIK<gsJHvR)2 G2_>x#bwp|_Df]G"h!՗S8*HDN䤇Su?#o=[d؅ԞZ*l~lƅ ÿ޼a$3_i x;asA>B8T_  03<IENDB`qchat-0.3/src/emoticons/Adiumicons/sleeping.png0000644000076500017500000000204510654705376020407 0ustar owerowerPNG  IHDR|߯gAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڬ[lTEsKvJ[ZAjnX/m@ib"bȃ /JdO- Ӌ`Iiaٞs֥]5LϜ|fFRf[fP&PGβ^X5l0You`X^1(~u_w#(5҈S)j'0.OQS_RgroUk{ӍNv?}f'F\Hǹ3ڶ'ǘx%bMO;Z:bлǿ~elG'x-`n}nOsc/D$ hI I鬍In[f灟~=: Zk^LuuCta%<6Z #a3u+6)M_ Kmm?߻>:Y,-S =G]31Q5mF2!2a6'.\zׇfv}}xo6' 7=vŐ=^϶3Ed?يS_\  r )aAACL%{p {7`B8Ls~b> pD`V~H.q.Fu(Yғ,Tܒ;}w1#Bfn6]\ۢw13Krcu{5hn _S'sZ+PGвsJxiih#"zKЮN9cǮeJFSu "uliF1[" LS 7569/؆΁[azl j\P>6i{cR~ 09&1g^sqXSbS~!Α|W,Ҟxg'i,TI erHNIIT`997ö+wrh4n:5*I L(nJ W$ bR-$yuRe/U'زq-@܂5X}iٱ@ "UHх~'80cMTaeȑ{툈Ӻ˙s~ K%%5;.>_Lbtbf1)ɑ0h!e5Lò,ߦ؇6N:K*"b$ef?+x]PBIENDB`qchat-0.3/src/emoticons/Adiumicons/w00t.png0000644000076500017500000000145310654705376017375 0ustar owerowerPNG  IHDRAgAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڬT[HQ]Q nkfJVd7PKC=dP/ODR]ndRjmu9gܳ쮕̜ow/1ư!qAIRQvA}C`֑LKHD65(PH('&~SB79 KR& U陙5kJKa/X%L0ŋޯ6ǼwP B;cM0%JJ4yj CSffCZk!3Y F2{[2ӃܼTmWqq @~rz<G[U \Lz{&Eyz ٙ#cO~A+垵'x]\?!ȧu} ecNy \./^uzy18l\ZԊb:?m۶ |q}q|YSL5k ,& C3ׇQo<Y`+{" }^` Aa MTIENDB`qchat-0.3/src/emoticons/Adiumicons/kissing.png0000644000076500017500000000174610654705376020257 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<xIDATxڬUMlTUO;ZPZhZt"jZ6 PT u$: 7&JY.ąKSVH4FcE?҄S2mM_g޻iS|97syF M!c|H~bGe~8C|ML+՛^F`d+4xg_Z:ڱ N}~r_gǎ-.r\浄S]}q$!j- ޹#?:>va YXղ/NQS LHh(aAo qغٿsCĬڗnja | PR#p02OT=7{W*mZk@GsHyU fݜ;.rh4~>>#tq>)>m 94W\?F{`%aX &,Z.fT2ToW0<&v[Ⱦ"w|BDC-0ywm^Zٜ9ҼeWP: 9 B]VUYJׁXTP ?" +LZ6UsySv4E[S/RE9O0]WEZBPp|<&nB!tJ39tNe6F+ӖL [HR4V|H%W{&_>k@jm̯j;ɢZ.zcUG}?(:ٔ:n4Е0v"UYWݥuUtåE4nc[Ϊ@:;=۷vխ1Ba(i"% a#mS]RL-bP}w[zcM{BۘE8Wbyeզp]3#NL+GN xv֖okwОeEnN_|?É5{LGI1O_ W=xsU׌r}N ]+(S8|e%,0zn:_œ@o"Ek䐡ɭJP'M_:90L>}PLlx=,L K ! :B}NR {̚P2N)\9d"XpDd 3]&]a~GZڿ ^ZhD6;5mTy'=` I#A Ic{ (rP#@\KC٘f)l 5,4I1 |f'U\hpNx\|)[ɴIp2M® jZ>(pN7q͓_@D3Pl -֐9#Nk/ס(~D3:CeyLrRO*)E'} ڢHrPљڗάΆ╭pd2DЈy?^vȳ3n%u/[#{;?4-@Q 99"=CGSE8"}+Lo ?5X~ 0WsTIENDB`qchat-0.3/src/emoticons/Adiumicons/sick.png0000644000076500017500000000173210654705376017534 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<lIDATxڬUMlTUthRjkimO.\I$1FL ]F'$B.ՠ&&7ƅ!kjGht޼~oc,a}޽sZk\K!$:HHڛZѸF[{nN} 8p"֭)=s?J5664I\hݽV Lk=z NXhlǏ*ѮΗUR.;gՎh}-$,TB`S[]#Nz$U/#=hئ6QT8w&In᫉O(G>>it]"'U'셋(@ cq%#J#zh-i&aV]λ~PR.'zrXG#9ޱ)\4BB% ^%pх10L q2[!8@eE[#0 >"_ZÚR`'օ}W¡OҲ¥}?'JD~%ލSp|o2x$Ƨ12$pMU%pEPT6ݼ+}),z'EТOfBj= myraygOib25XÚ(GuMŲkX)Nc:ިDf=y̖2/:H7[PRce11Gn~ɽcY q^%~|Z"1IENDB`qchat-0.3/src/emoticons/Adiumicons/blushing.png0000644000076500017500000000173310654705376020417 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<mIDATxڬKhTW9cBj:ӊcJEc}3 W,ԑ\*EW*BE> . h|D 1N&3wqLn<{~w# !> ZuT4.SlѾ+p\jZ]}nPq55gb/=nsȿãGpRyԅū6h 9l3j"0&v<|A8bm:'RTigm~$-xO ;ݐ*4,]5r?T;/IԁU_.I,`-AP>=ˢkeE0yUoX n -[6_ b05,Ń$[̉A2`_ ߠa%TUЩE6Q$kb15.Ր$FЁ&A>4)22\IY3넃O _A )qfea B g e,Y2wE=`aoV0mV0 FdCDC.Lws0X(x N hI$W4&(mYS0\ߥ_۟^na:i703,PCK6jCƷ2P"Q@% @ē:ٶuۿݘqlw'$j@8ֶ# EbdtנBG_'=SbS:R5c0ZO3[ߤ kxF6g{:Z3H&;7ln"f];XTƘth ׫p澐c]+gb^Eȕ1߇ |p̻Î+:{N\4V^ =r ge4]$ywwr(K62= OgNRkb`ta#{w{;V#@:CfJ;k6nSN¨Ut:zCL(3݊p:*0J!=-,kJ9gז\Y!ǎNri }EpH _O[dLR4hsJ44;DL+?a*t B Bfb`G_om$Ö9HO Eb}Y'gcK׿i±o _/KjIENDB`qchat-0.3/src/emoticons/Adiumicons/surprised.png0000644000076500017500000000171510654705376020624 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<_IDATxڬ[Le;  miPD^%Qчq{}i_xjiF}4MThFmJ [rYe/sIW&9;|g&Z4 أ-KIujJo:yC@_!H5uNlnjĦUV3qpB'\;_6S_q p'K,N#=7[?gt ~#Cq1:O AH.~o܂ \-濤Qg;zB$HVc18fiDoaqqCa2?G3m憔+uCw[i)Dc&S9E=!{ А:Z(+"&{>$axz$LBg4((HGXGs]b^lXq#9LeJ wWg# 5# kJSYpElȕ=YJ D/oDשQ>)" @D*/f4X h~^8 *UK1 ;G>]:4([^ |`tT2sKQ5Dg= βS*rud8!#[ Wnӟ溴41HVos CRYɬ\%?[4q^ 3J!>؎2S]XGW ehdݠqƒe4!·9ám[i{Gg26!,R,~-z6s1O<^{[bI&R%s\kK^6`oWZ<`Tr%IENDB`qchat-0.3/src/emoticons/Adiumicons/andy.png0000644000076500017500000000166610654705376017544 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<HIDATxڬU[HTQ]GoLqP13 Aa/’?F)"#>&2HEEeJ1jB|3qꭙq>gg_1\"' a7!w>JxJx@'̇.:-F BCrzzJd 5;Lcbk;fMw|QLh-ٵac`FcYl\x\O`7aMs敺 c :Fb$lۙmˋfCq3UμC^HG版KP!ډ8V"ϹCﴡUWe>ھ~Yx~}wϽZkn]m)-QB+_d2k)C՗LnFiv/xmxgj88_&tڲ=luY_,¬x,80Bs@dH3i2þ2 Sd\o=;zn9*) d;՛O+|M&Aw?*p耯"-NT<]ݒO NDxCl#?R3T#='uIˉFgs(,Kj騬C׃p-ᯞ_0ĹqN&'+Hw5=q6`F#rz07x ,S~0ę$ N= vz=թk!& R B:_۴WRSȐihk[D\x'P%<\SR3G~_1D[Pe4.! _ k. j`ttebP.TUݤ,Y*zG.0?3= 5sbnoRS^ D締CK6Ğ47fy@2ֳZtQH] j\P-}wm]&7&YRD h+xv"=4r*zK 4 .uTySQT@v> ƣ<\XHs'أI ,_/UT,IENDB`qchat-0.3/src/emoticons/Adiumicons/pinched.png0000644000076500017500000000177410654705376020223 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<IDATxڬ]lTEsG[Y)Җ6M746V4K!`-p &'}'DkDb$MQL ?(@Vcn޹w]&0?9wΙ/C))lXbTMD+OR稯TeDYxtCo/Z:ڱJ03~k7qid~:7m;][lӏp,  f4D> 3:W35dC;_;h}& y@AQ!(bq/lYz܏? yAba5=%Z!L: I ?9FEkQtwF(VعCMOɁ@wKMOaE1 ]zkU>϶qT͛v`*z3'w0`HZOjainW{>X,9kﷰ`Ex90+j"Ks&x"d+}`ADŽ R5@7Ni',ȱx %w) =^Lmu+ yNI0>M2GIDWM|Y-Q. tPEbVc |ܹ贈# P:K#}CtPLa$=q=OʹUT5pl.y #Ck6plɱY&Lﻸr5٬IU:MݘExO5B2,{J0q- cY|Pf-{:3s{*fa]]JKKWG"+Jrv# jZY,ZPh~>tv{t >& $le.| @D}qc}b' -cw@u\rxN<[P%e1#5tƙ!gOgfYC0GtՄ9xpڐ#{X TbFcH_ bl,A4N-rDܺFEp!g=5R<I<"s(eg҉$r+Oyqʄӈ4&Y\E$w̙x4x0qsPq,DӿU"wLbRE؁Ż FZ̦ìyZVVRD63#'O!\,DzSdplLd%ys٬MIذf:pI'X٨~k+(#,,n)O"鿾/^rn[I.ts?,ūV^Q!ؽ_RMpLRZm;d?^je Vg[ Ϊe8ykFF2}{ao퇋p|D_?߇#B\^Y Z$D8g2 viyLx z>:5?`;IENDB`qchat-0.3/src/emoticons/Adiumicons/uncertain.png0000644000076500017500000000172310654705376020573 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<eIDATxڬT[hTW]w$1c$&GLȐؐX+U& ◢%8!Rү*A RF<4D[B'3NfΝ8fu!>eMxVb(i!nT cё_TISJ++PPZaD06G F5qnv" bDqe K]-@oBXb FXjڕmeP| AWhX~!3>+amgđ$&il- CCTXa='Mh9:ʼsP:TH64=8_ E8\2D{8W䨓\);V*Z_}Spfkph^ksqqkSa lt’(xŖi)U ͙ϸlSqhB́_' ί{o22xX:aȬѷA<7?Qkz*9UV:O0aa2l U)?FLړ6#9( DoBP0~qco鄗Br'NU.p,6mH)M}eT붺5D<΋R !^Fr7:*lH]wrIm]l6.*SedQ*$YHˮC)in V66̓QȜH`?pfJlKN~YSE ](,/06ȋzFLyWJwyf l`fk!NA2IENDB`qchat-0.3/src/emoticons/Adiumicons/sad.png0000644000076500017500000000174010654705376017351 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<rIDATxڬYlLQۙTBKѠ ZҨ"j{H D' oBbS B%ƒiHK[PHu,s|L;dsr9|$!P;!H**x>5yƵ)22N./GV~Ҳ2 4?}y׵_5WTm݂`A@`j~&ҳUMm':ڿ\ (@eˊPUtͰ$Y>H2'`*P6EPQQ"+RaL$-۰ 88j>G޹M1c*.ٍ= P* &b~@#p}E撑Օj<o^@^WVXagHǀf-ȥ/ >$JAwn{?5UzP4O)p798ֽj[$Ռs[n͉IN$*s{'\gsQ/x1կD3JNkZ?(@{YܲK?yU|~hQIMŦҲ(JD P^fvUρ?NOiV 77~ SW4mhL;~ 0UP\IENDB`qchat-0.3/src/emoticons/Adiumicons/tongue.png0000644000076500017500000000175010654705376020104 0ustar owerowerPNG  IHDR gAMAOX2tEXtSoftwareAdobe ImageReadyqe<zIDATxڬU]l Q=wf-JCKtCjiRBI $D4! ɔHBhU*UU?Umgvwf̲}3ٓ;ͽ|wasϋ Cx6:3qю&lQ=Yyo{m˜7Oj͓43qqIsE斖Z M9$Dz G󽯛,&Hk"̑ҭ9Ņ`$@!3 283xR̜;$CL]V1ߛSpT-jA%L UˏbӐ=rQ2)+.E9 %uGhNn~(y/{[Zцb]u '"YKK,)&f hB( G,( O뿡{?U`m@ؗƔ"@gwٝsgf {|sψ1< AH{\W Zr=sYo:`y"YJ5Y9 n+[e?XJ4UlybK!KYfl-I  q5sّD~K~x)#Q.9[^^`L PzZ;;U'Z^mp 27{{=ݗ;%̕ $;.5}Y AQL%\Ir@pWoiM]|}^ 'dhM>mVhg[i@xKʱ{BL -/VVx{Ȓ)e?1Wߪbr]A)Ed5>oP9twEs.ox!"kkD 2$Y-n. iԖ `!=HJmBlql>Z@s$a8-87o24rA& ӝMʎ@)A8#KH(銯OL3ZW!̼r g xgu?[ GW*&a*>0]0#Y|{}]F ҕk7Noc:1Z7k(r<& ʨtܣoM`lބvBvm 0 u9w;ݸCKpS۽(}E S31*\ll,*2 IN */ class SingleMsgsHistoryModel : public TreeModel { Q_OBJECT public: enum TreeLayout{IpUserDate, Date}; enum Columns{DateCol = 0, IpCol = 1, NicknameCol = 2, MessageCol = 3}; private: TreeLayout m_currentLayout; SingleMsgsHistory* m_messages; MessageTreeItem* m_incoming; MessageTreeItem* m_outgoing; /// \brief children of m_incoming and m_outgoing QMap m_secondLevelItems; int m_sortingOrder; int m_sortingColumn; public: SingleMsgsHistoryModel(QObject *parent = 0); ~SingleMsgsHistoryModel(); void init(); void rebuildTree(int); void addMessage(SingleMessage*); void appendIn3lvl(TreeItem*); void sort(int column, Qt::SortOrder order = Qt::AscendingOrder); void update(){emit layoutChanged();} protected: TreeItem* createRootItem(); }; #endif qchat-0.3/src/abstractprotocol.h0000644000076500017500000001043711002621041015510 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef ABSTRACTPROTOCOL_H #define ABSTRACTPROTOCOL_H #include #include "globals.h" /** @author Anistratov Oleg */ class AbstractProtocol { public: AbstractProtocol(); virtual ~AbstractProtocol(); // Protocol information functions virtual uint protocolVersion () const = 0; virtual uint protocolLen () const = 0; virtual const char* programId() const = 0; virtual uint optionsLen() const = 0; // NOTE size of char* buf in following functions must be at least ProtocolLen bytes virtual QString programId (const char* buf) = 0; virtual uint packetSize (const char* buf) = 0; virtual uint programVersion (const char* buf) = 0; virtual uint protocolVersion (const char* buf) = 0; virtual quint64 destIp (const char* buf) = 0; virtual quint64 srcIp (const char* buf) = 0; virtual uint packetType (const char* buf) = 0; virtual uint packetId (const char* buf) = 0; virtual uint fragmentSize (const char* buf) = 0; virtual uint packetNum (const char* buf) = 0; virtual quint64 time (const char* buf) = 0; virtual uint channelType (const char* buf) = 0; virtual uint compNameLen (const char* buf) = 0; virtual uint userNameLen (const char* buf) = 0; virtual uint messageLen (const char* buf) = 0; virtual uint parametrsLen (const char* buf) = 0; virtual uint optionsLen (const char* buf) = 0; virtual bool compressed (const char* buf) = 0; virtual QString compName (const char* buf, uint sz) = 0; virtual QString userName (const char* buf, uint sz) = 0; virtual QString message (const char* buf, uint sz) = 0; virtual QByteArray parametrs (const char* buf, uint sz) = 0; virtual void setProgramId (char* buf) = 0; virtual void setPacketSize (char* buf, uint) = 0; virtual void setProgramVersion (char* buf) = 0; virtual void setProtocolVersion(char* buf) = 0; virtual void setDestIp (char* buf, quint64 ip) = 0; virtual void setSrcIp (char* buf, quint64 ip) = 0; virtual void setPacketType (char* buf, uint type) = 0; virtual void setPacketId (char* buf, uint id) = 0; virtual void setFragmentSize (char* buf, uint sz) = 0; virtual void setPacketNum (char* buf, quint32 nm) = 0; virtual void setTime (char* buf, quint64 tm) = 0; virtual void setChannelType (char* buf, quint32 id) = 0; virtual void setCompNameLen (char* buf, uint sz) = 0; virtual void setUserNameLen (char* buf, uint sz) = 0; virtual void setMessageLen (char* buf, quint32 sz) = 0; virtual void setParametrsLen (char* buf, quint32 sz) = 0; virtual void setOptionsLen (char* buf, quint32 sz) = 0; virtual void setCompressed (char* buf, bool b) = 0; virtual void setCompName (char* buf, const QString& name) = 0; virtual void setUserName (char* buf, const QString& name) = 0; virtual void setMessage (char* buf, const QString& msg) = 0; virtual void setParametrs (char* buf, const QByteArray& pars) = 0; }; #endif qchat-0.3/src/colorlabel.cpp0000644000076500017500000000315610764552441014621 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "colorlabel.h" #include ColorLabel::ColorLabel(QWidget *parent, QColor color) : QLabel(parent) { setColor(color); } //\***************************************************************************** void ColorLabel::setColor(const QColor & color) { QPixmap pix(size()); m_color = color; pix.fill(color); setScaledContents(true); setPixmap(pix); } //\***************************************************************************** ColorLabel::ColorLabel(const ColorLabel & lab) : QLabel(lab.parentWidget()) { m_color = lab.color(); } qchat-0.3/src/singlemsgshistorymodel.cpp0000644000076500017500000001604210770516424017315 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "singlemsgshistorymodel.h" #include #include "singlemsgshistory.h" #include "messagetreeitem.h" #include "singlemessage.h" SingleMsgsHistoryModel::SingleMsgsHistoryModel(QObject* parent) : TreeModel(parent), m_currentLayout(IpUserDate), m_incoming(NULL), m_outgoing(NULL), m_sortingOrder (Qt::AscendingOrder), m_sortingColumn(0) { m_messages = new SingleMsgsHistory; setRootItem(createRootItem()); init(); } SingleMsgsHistoryModel::~SingleMsgsHistoryModel() { } TreeItem* SingleMsgsHistoryModel::createRootItem() { QList data; data.append(tr("Direction / IP - Nickname / Date")); data.append(tr("IP")); data.append(tr("Nickname")); data.append(tr("Message")); TreeItem* item = new MessageTreeItem(data); return item; } void SingleMsgsHistoryModel::addMessage(SingleMessage* msg) { QList data; QString user = QHostAddress(msg->srcIp()).toString() + " - " + msg->userName(); QString second_lvl_id = user + (msg->isIncoming() ? "-in" : "-out"); MessageTreeItem* second_lvl_item = NULL; MessageTreeItem* first_lvl_item = (msg->isIncoming() ? m_incoming : m_outgoing); QDateTime dt; dt.setTime_t(msg->receiveTime()); emit layoutAboutToBeChanged(); switch(m_currentLayout) { case Date : second_lvl_item = first_lvl_item; break; case IpUserDate : if(!m_secondLevelItems.contains(second_lvl_id)) { data << user << "" << "" << ""; second_lvl_item = new MessageTreeItem(data, first_lvl_item); m_secondLevelItems.insert(second_lvl_id, second_lvl_item); second_lvl_item->hideColumn(IpCol); second_lvl_item->hideColumn(NicknameCol); } else second_lvl_item = m_secondLevelItems[second_lvl_id]; break; } // preparing item which will be represents a message int max_len = 1024; QString res_msg = msg->msg(); res_msg.replace("\n", " ").left(max_len); if(res_msg.size() > max_len) res_msg += "..."; data.clear(); data.append(dt.toString("hh:mm:ss (dd.MM.yy)")); data.append(QHostAddress(msg->srcIp()).toString()); data.append(msg->userName()); data.append(res_msg); MessageTreeItem* msg_item = new MessageTreeItem(data, second_lvl_item); m_messages->addMessage(msg); msg_item ->setMessage(msg); data.clear(); data << dt.toString("hh:mm:ss (dd.MM.yy)") << "" << "" << msg->msg(); msg_item->setData(data, Qt::ToolTipRole); if(m_currentLayout == IpUserDate) { msg_item->hideColumn(IpCol); msg_item->hideColumn(NicknameCol); } sort(m_sortingColumn, (Qt::SortOrder)m_sortingOrder); emit layoutChanged(); } void SingleMsgsHistoryModel::init() { QList data; data.append(tr("Incoming")); data.append(tr("")); data.append(tr("")); data.append(tr("")); m_incoming = new MessageTreeItem(data); data.clear(); data.append(tr("Outgoing")); data.append(tr("")); data.append(tr("")); data.append(tr("")); m_outgoing = new MessageTreeItem(data); appendToRoot(m_incoming); appendToRoot(m_outgoing); rootItem()->hideColumn(IpCol); rootItem()->hideColumn(NicknameCol); } void SingleMsgsHistoryModel::rebuildTree(int layout) { if(m_currentLayout == (TreeLayout)layout) return; QList items; items.append(m_incoming); items.append(m_outgoing); reset(); switch((m_currentLayout = (TreeLayout)layout)) { case Date : { rootItem()->setData(0, tr("Direction / Date")); foreach(TreeItem* top_lvl_item, items) { foreach(TreeItem* item, *top_lvl_item->children()) { // checking is item represents message or not if(!static_cast(item)->message()) { foreach(TreeItem* msg_item, item->takeChildren()) { Message* message = static_cast(msg_item)->message(); if(message) top_lvl_item->appendChild(msg_item); else delete msg_item; } top_lvl_item->deleteChild(item); m_secondLevelItems.remove(m_secondLevelItems.key(static_cast(item))); } } } rootItem()->showColumn(IpCol); rootItem()->showColumn(NicknameCol); break; } case IpUserDate : rootItem()->setData(0, tr("Direction / IP - Nickname / Date")); foreach(TreeItem* top_lvl_item, items) { foreach(TreeItem* item, top_lvl_item->takeChildren()) { Message* msg = static_cast(item)->message(); if(msg) appendIn3lvl(item); else top_lvl_item->deleteChild(item); } } rootItem()->hideColumn(IpCol); rootItem()->hideColumn(NicknameCol); break; } } void SingleMsgsHistoryModel::appendIn3lvl(TreeItem* item) { Message* msg = static_cast(item)->message(); QHostAddress addr(msg->srcIp()); QString user = addr.toString() + " - " + msg->userName(); QString second_lvl_id = user + (msg->isIncoming() ? "-in" : "-out"); MessageTreeItem* second_lvl_item = NULL; MessageTreeItem* first_lvl_item = (msg->isIncoming() ? m_incoming : m_outgoing); QList data; if(msg) { if(!m_secondLevelItems.contains(second_lvl_id)) { data.append(user); data.append(""); data.append(""); data.append(""); second_lvl_item = new MessageTreeItem(data, first_lvl_item); m_secondLevelItems.insert(second_lvl_id, second_lvl_item); } else { second_lvl_item = m_secondLevelItems[second_lvl_id]; } second_lvl_item->appendChild(item); } } void SingleMsgsHistoryModel::sort(int column, Qt::SortOrder order) { emit layoutAboutToBeChanged(); m_sortingColumn = column; m_sortingOrder = order; m_incoming->sortChildren(rootItem()->realColumn(column), order); m_outgoing->sortChildren(rootItem()->realColumn(column), order); emit layoutChanged(); } qchat-0.3/src/textformattingwgt.cpp0000644000076500017500000000357510764020715016303 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "textformattingwgt.h" #include #include TextFormattingWgt::TextFormattingWgt(QWidget *parent) : QWidget(parent) { QGridLayout* grid = new QGridLayout(this); (m_setBoldAct = new QToolButton(this))->setCheckable(true); (m_setItalicAct = new QToolButton(this))->setCheckable(true); (m_setUnderlinedAct = new QToolButton(this))->setCheckable(true); grid->addWidget(m_setBoldAct, 0, 0); grid->addWidget(m_setItalicAct, 0, 1); grid->addWidget(m_setUnderlinedAct, 0, 2); connect(m_setBoldAct, SIGNAL(clicked(bool)), this, SIGNAL(wantSetBold(bool))); connect(m_setItalicAct, SIGNAL(clicked(bool)), this, SIGNAL(wantSetItalic(bool))); connect(m_setUnderlinedAct, SIGNAL(clicked(bool)), this, SIGNAL(wantSetUnderlined(bool))); } TextFormattingWgt::~TextFormattingWgt() { } qchat-0.3/src/colorchooser.cpp0000644000076500017500000001162411002605066015167 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "colorchooser.h" #include #include "colorlabel.h" ColorPicker::ColorPicker(QWidget *parent) : QFrame(parent), m_colorsNum(16), m_maxColors(16) { grid = new QGridLayout(this); m_button = new QToolButton(this); m_baseColors.append(Qt::white); m_baseColors.append(Qt::black); m_baseColors.append(Qt::red); m_baseColors.append(Qt::green); m_baseColors.append(Qt::blue); m_baseColors.append(Qt::cyan); m_baseColors.append(Qt::magenta); m_baseColors.append(Qt::yellow); m_baseColors.append(Qt::gray); m_baseColors.append(Qt::darkGray); m_baseColors.append(Qt::darkRed); m_baseColors.append(Qt::darkYellow); m_baseColors.append(Qt::darkMagenta); m_baseColors.append(Qt::darkCyan); m_baseColors.append(Qt::darkBlue); m_baseColors.append(Qt::darkGreen); grid->setMargin(0); grid->setSpacing(0); for(int i = 0; i < m_colorsNum; i++) { ColorLabel* lab = new ColorLabel(this); lab->setFrameStyle(QFrame::StyledPanel); // lab->setFrameStyle(QFrame::Box); lab->setMinimumHeight(20); lab->setMinimumWidth (20); lab->setMaximumHeight(20); lab->setMaximumWidth (20); connect(lab, SIGNAL(clicked()), this, SLOT(colorClicked())); m_colorLabels.append(lab); } // for(int i = 0; i < 2; i++) // for(int j = 0; j < (m_colorsNum / 2); j++) for(int i = 0; i < m_colorsNum; i++) grid->addWidget(m_colorLabels[i], i % 2, i / 2); grid->addWidget(m_button, 0, (m_colorsNum / 2), 2, 1); connect(m_button, SIGNAL(clicked()), this, SLOT(selectColorDialog())); setFrameStyle(QFrame::StyledPanel); setLineWidth(1); redrawLabels(); } void ColorPicker::selectColorDialog() { QColor color = QColorDialog::getColor(m_color, this); if(color.isValid()) emit colorChanged(m_color = color); redrawLabels(); setButtonColor(); } void ColorPicker::redrawLabels() { int i; if(!m_colorsNum) return; m_colors.clear(); for(i = 0; i < m_colorsNum && i < QColorDialog::customCount (); i++) if(!m_colors.contains(QColorDialog::customColor(i))) m_colors.append(QColor(QColorDialog::customColor(i))); i = m_colors.size(); foreach(QColor color, m_baseColors) { if(!m_colors.contains(color)) { m_colors.append(color); i++; } if(i >= m_colorsNum) break; } if(!m_colors.contains(m_color)) m_colors.replace(m_colorsNum - 1, m_color); for(int i = 0; i < m_colors.size() && i < m_colorLabels.size(); i++) m_colorLabels[i]->setColor(m_colors[i]); } void ColorPicker::colorClicked() { ColorLabel* lab = qobject_cast(sender()); m_color = lab->color(); emit colorChanged(m_color); setButtonColor(); } void ColorPicker::setButtonColor() { QPixmap pix(m_button->width(), m_button->height()); pix.fill(m_color); m_button->setIcon(QIcon(pix)); } void ColorPicker::setColor(QColor color) { m_color = color; setButtonColor(); } void ColorPicker::setColorsNum(int num) { m_colorsNum = (num > m_maxColors ? m_maxColors : (num < 0 ? 0 : num)); int i = 0; // if((m_colorsNum == (m_maxColors / 2) && (m_colorsNum - old) == 1) || // (m_colorsNum == (m_maxColors / 2) && (m_colorsNum - old) == -1)) // changeRows(); foreach(ColorLabel* cl, m_colorLabels) { bool hid = (i++ >= m_colorsNum); cl->setHidden(hid); } } void ColorPicker::wheelEvent(QWheelEvent* ev) { if(ev->delta() > 0 && m_colorsNum < m_maxColors) setColorsNum(m_colorsNum + 1); else if(ev->delta() < 0 && m_colorsNum > 0) setColorsNum(m_colorsNum - 1); } void ColorPicker::changeRows() { foreach(ColorLabel* cl, m_colorLabels) grid->removeWidget(cl); if(m_colorsNum > (m_maxColors / 2)) { for(int i = 0; i < m_maxColors; i++) grid->addWidget(m_colorLabels[i], i % 2, i / 2); } else { for(int i = 0; i < m_maxColors; i++) grid->addWidget(m_colorLabels[i], 0, i); } } qchat-0.3/src/qchatsocket.h0000644000076500017500000000645511002651142014446 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHATSOCKET_H #define QCHATSOCKET_H #include #include #include "abstractchatcore.h" /** @author Anistratov Oleg */ class QChatSocket : public QObject, public AbstractChatCore { Q_OBJECT public: enum QChatSocketState{Unconnected, Connected, LoggedIn}; private: char* m_buffer; char* m_dtgrm; int m_bufferSize; QChatSocketState m_state; int m_fullDtgrmSize; int m_currentDtgrmSize; bool m_newDtgrmReady; QString m_nickname; QTcpSocket* m_socket; private: char* appendData(const char*, int&); public: QChatSocket(QObject* parent = 0, QTcpSocket* = 0); ~QChatSocket(); void login(const QString&, const QString& = ""); // QChatSocketState state() const {return m_state;} int readDtgrm(char*, int); const QString& nickname() const {return m_nickname;} //****************************** QTcpSocket* socket() const {return m_socket;} qint64 write(const char* data, qint64 maxSize) {return m_socket->write(data, maxSize);} QHostAddress peerAddress() const {return m_socket->peerAddress();} quint16 peerPort() const {return m_socket->peerPort();} void disconnectFromHost() {m_socket->disconnectFromHost();} void connectToHost(const QString & hostName, quint16 port, QIODevice::OpenMode openMode = QIODevice::ReadWrite) {m_socket->connectToHost(hostName, port, openMode);} void connectToHost(const QHostAddress & address, quint16 port, QIODevice::OpenMode openMode = QIODevice::ReadWrite) {m_socket->connectToHost(address, port, openMode);} bool waitForConnected (int msecs = 30000) {return m_socket->waitForConnected(msecs);} bool flush() {return m_socket->flush();} QAbstractSocket::SocketState state () const {return m_socket->state();} //****************************** void sendData(); public slots: void processNewData(); signals: void badLogin(const QString&); void newDtgrm(); /** * * @param err_id id of error * 0: no errors * 2: cannot login to server * @param descr optional text description of error */ void loginFinished(int err_id, const QString& descr); void disconnected(); }; #endif qchat-0.3/src/textformattingwgt.h0000644000076500017500000000311410764017641015741 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef TEXTFORMATTINGWGT_H #define TEXTFORMATTINGWGT_H #include #include #include /** @author Anistratov Oleg */ class TextFormattingWgt : public QWidget { Q_OBJECT private: QToolButton* m_setBoldAct; QToolButton* m_setItalicAct; QToolButton* m_setUnderlinedAct; public: TextFormattingWgt(QWidget *parent = 0); ~TextFormattingWgt(); signals: void wantSetBold(bool); void wantSetItalic(bool); void wantSetUnderlined(bool); }; #endif qchat-0.3/src/userprofile.cpp0000644000076500017500000000207510665277450015045 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ // :) qchat-0.3/src/protocolversion4.h0000644000076500017500000001300711004425034015460 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PROTOCOLVERSION4_H #define PROTOCOLVERSION4_H #include /** @author Anistratov Oleg */ class ProtocolVersion4 : public AbstractProtocol { private: static const char* m_programId; public: ProtocolVersion4(); ~ProtocolVersion4(); // Protocol information functions uint protocolVersion() const {return 4;} uint protocolLen () const {return 57;} const char* programId() const {return m_programId;} uint optionsLen() const {return 1;} // NOTE size of char* buf in following functions must be at least AbstractChatCore::protocolLen() bytes QString programId (const char* buf){return QString::fromAscii(buf, 5);} // 5 bytes uint packetSize (const char* buf){return str2US (buf + 5);} // 2 bytes uint programVersion (const char* buf){return str2US (buf + 7);} // 2 uint protocolVersion (const char* buf){return str2US (buf + 9);} // 2 quint64 destIp (const char* buf){return str2ULL(buf + 11);} // 8 quint64 srcIp (const char* buf){return str2ULL(buf + 19);} // 8 uint packetType (const char* buf){return *(buf + 27);} // 1 uint packetId (const char* buf){return str2US (buf + 28);} // 2 uint fragmentSize (const char* buf){return str2US (buf + 30);} // 2 uint packetNum (const char* buf){return str2UL (buf + 32);} // 4 quint64 time (const char* buf){return str2ULL(buf + 36);} // 8 uint channelType (const char* buf){return *(buf + 44);} // 1 uint compNameLen (const char* buf){return *(buf + 45);} // 1 uint userNameLen (const char* buf){return *(buf + 46);} // 1 uint messageLen (const char* buf){return str2UL (buf + 47);} // 4 uint parametrsLen (const char* buf){return str2UL (buf + 51);} // 4 uint optionsLen (const char* buf){return str2US (buf + 55);} // 2 bool compressed (const char* buf){if(optionsLen(buf) < 1) return false; return buf[57] & 128;} QByteArray options (const char* buf, uint sz); QString compName (const char* buf, uint sz); QString userName (const char* buf, uint sz); QString message (const char* buf, uint sz); QByteArray parametrs (const char* buf, uint sz); void setProgramId (char* buf){strncpy(buf, programId(), 5);} void setPacketSize (char* buf, uint sz){catUS2str(buf + 5, sz);} // 2 bytes void setProgramVersion (char* buf){catUS2str(buf + 7, Globals::VersionID);} void setProtocolVersion(char* buf){catUS2str(buf + 9, protocolVersion());} void setDestIp (char* buf, quint64 ip){catULL2str(buf + 11, ip);} // 8 void setSrcIp (char* buf, quint64 ip){catULL2str(buf + 19, ip);} // 8 void setPacketType (char* buf, uint type){ (buf[27] = type);} // 1 void setPacketId (char* buf, uint id){catUS2str (buf + 28, id);} // 2 void setFragmentSize (char* buf, uint sz){catUS2str (buf + 30, sz);} // 2 void setPacketNum (char* buf, quint32 nm){catUL2str (buf + 32, nm);} // 4 void setTime (char* buf, quint64 tm){catULL2str(buf + 36, tm);} // 8 void setChannelType (char* buf, quint32 id){buf[44] = id;} // 1 void setCompNameLen (char* buf, uint sz){buf[45] = sz;} // 1 void setUserNameLen (char* buf, uint sz){buf[46] = sz;} // 1 void setMessageLen (char* buf, quint32 sz){catUL2str(buf + 47, sz);} // 4 void setParametrsLen (char* buf, quint32 sz){catUL2str(buf + 51, sz);} // 4 void setOptionsLen (char* buf, quint32 sz = 1){catUS2str(buf + 55, sz);} // 2 void setCompressed (char* buf, bool b){ b ? buf[57] |= 128 : buf[57] &= 127;} void setCompName (char* buf, const QString& name) {strncpy(buf + protocolLen() + optionsLen(), name.toUtf8().data(), compNameLen(buf));} void setUserName (char* buf, const QString& name) // ?? {strncpy(buf + protocolLen() + optionsLen() + compNameLen(buf), name.toUtf8().data(), userNameLen(buf));} void setMessage (char* buf, const QString& msg) // ?? {memcpy(buf + protocolLen() + optionsLen() + compNameLen(buf) + userNameLen(buf), msg.toUtf8().data(), messageLen(buf));} void setParametrs (char* buf, const QByteArray& pars) // ?? {memcpy(buf + protocolLen() + optionsLen() + compNameLen(buf) + userNameLen(buf) + messageLen(buf), pars.data(), parametrsLen(buf));} }; #endif qchat-0.3/src/qchatsettings.cpp0000644000076500017500000003563411004415202015347 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchatsettings.h" #include "globals.h" #include #include #include "userlisticonformat.h" #include "messagefilter.h" #include "option.h" QChatSettings* QChatSettings::m_currentSettings(0); QChatSettings* QChatSettings::m_defaultSettings(0); QString QChatSettings::m_profileName (""); QString QChatSettings::m_settingsDir (""); QString QChatSettings::m_loggingDir (""); QChatSettings::Mode QChatSettings::m_mode (Serverless); QHostAddress QChatSettings::m_servBroadcast (quint32(0)); QList QChatSettings::m_ipList; QMap QChatSettings::m_generalOptions; QChatSettings::QChatSettings(): m_myMsgsColor (Qt::red), m_sysMsgsColor (Qt::gray), m_baseMsgColor (Qt::black), m_nlMode (0), m_nHistoryMsgs (-1), m_historyReqTimeout(5000), m_smilesThemePath (defaultSmilesDir()), m_smilesPolicy (AlwaysUseSmilesFromSender), m_usersListRefreshInterval(60), m_usersListDeepRefreshInterval(600), m_toolbarIconsSize(24) { m_iconFormat = new UserListIconFormat; m_messageFilter = new MessageFilter; initOptions(); createShortcut("SendMessage" , QObject::tr("Send Message"), QObject::tr("Chat") , QKeySequence("Ctrl+Return")); createShortcut("NextMessage" , QObject::tr("Scroll Message History Forward"), QObject::tr("Chat") , QKeySequence("Ctrl+Down")); createShortcut("PrevMessage" , QObject::tr("Scroll Message History Backward"), QObject::tr("Chat") , QKeySequence("Ctrl+Up")); createShortcut("RefreshUsersList" , QObject::tr("Refresh Users List"), QObject::tr("Channels"), QKeySequence("F5")); // chatWgt createShortcut("ShowSmiles" , QObject::tr("Show Smiles"), QObject::tr("Chat") , QKeySequence("Ctrl+S")); createShortcut("SingleMessagesHistory", QObject::tr("Single Messages History"), QObject::tr("General") , QKeySequence("Ctrl+M")); createShortcut("EditUserDetails" , QObject::tr("Edit User Details"), QObject::tr("General") , QKeySequence("Ctrl+D")); createShortcut("ConfigureQChat" , QObject::tr("Configure QChat"), QObject::tr("General") , QKeySequence("Ctrl+P")); createShortcut("Quit" , QObject::tr("Quit"), QObject::tr("General") , QKeySequence("Ctrl+Q")); createShortcut("AddChannel" , QObject::tr("Add Channel"), QObject::tr("Channels"), QKeySequence("Ctrl+N")); createShortcut("DelChannel" , QObject::tr("Close Channel"), QObject::tr("Channels"), QKeySequence("Ctrl+W")); createShortcut("AddProfile" , QObject::tr("Add Profile"), QObject::tr("Profiles"), QKeySequence("Ctrl+Shift+N")); createShortcut("DelProfile" , QObject::tr("Delete Profile"), QObject::tr("Profiles"), QKeySequence("Ctrl+Shift+D")); createShortcut("RenameProfile" , QObject::tr("Rename Profile"), QObject::tr("Profiles"), QKeySequence("Ctrl+Shift+R")); createShortcut("Hide2Tray" , QObject::tr("Hide to Tray"), QObject::tr("General") , QKeySequence("Escape")); createShortcut("BroadcastMessage" , QObject::tr("Send Broadcast Message"), QObject::tr("Chat") , QKeySequence("Alt+B")); // createShortcut("NextNewMessage" , QObject::tr("Next New Message"), QObject::tr("Messages"), QKeySequence("")); createShortcut("PrevNewMessage" , QObject::tr("Previous New Message"), QObject::tr("Messages"), QKeySequence("")); createShortcut("NextOpenedMessage" , QObject::tr("Next Opened Message"), QObject::tr("Messages"), QKeySequence("")); createShortcut("PrevOpenedMessage" , QObject::tr("Previous Opened Message"), QObject::tr("Messages"), QKeySequence("")); createShortcut("CloseAllNewMessages" , QObject::tr("Close All New Messages"), QObject::tr("Messages"), QKeySequence("")); createShortcut("CloseAllOpenedMessages", QObject::tr("Close All Opened Messages"), QObject::tr("Messages") , QKeySequence("")); } void QChatSettings::setStatusDescription(const QString & descr, int status) { Q_ASSERT(status >=0 && status < 6 || status == Globals::INVISIBLE); if(status != Globals::INVISIBLE) m_statusDescription[status] = descr; } const QString & QChatSettings::statusDescription(int status) const { Q_ASSERT(status >=0 && status < 6 || status == Globals::INVISIBLE); if(status == Globals::INVISIBLE) return m_statusDescription[0]; return m_statusDescription[status]; } void QChatSettings::appendStatusDescription(const QString & value) { if(!value.isEmpty() && !m_statusDescriptions.contains(value)) { m_statusDescriptions.removeAll(value); m_statusDescriptions.prepend(value); } } QString QChatSettings::defaultSmilesDir() { QList dirs; QString res; QDir dir; dirs.append(QDir(QChatSettings::settings()->settingsDir() + "/smiles")); #if defined(Q_OS_LINUX) dir.setPath(QApplication::applicationDirPath()); if(dir.cd("../share/qchat/emoticons")) dirs.append(dir); #else dirs.append(QDir(QApplication::applicationDirPath() + "/emoticons")); #endif res = defaultSmilesDir(dirs); #if defined(Q_OS_LINUX) if(res.isEmpty()) { dirs.clear(); dirs.append(QDir(QDir::homePath() + "/.kde/share/emoticons")); dir.setPath(QApplication::applicationDirPath()); if(dir.cd("../share/emoticons")) dirs.append(dir); res = defaultSmilesDir(dirs); } #endif return res; } QString QChatSettings::defaultSmilesDir(QList dirs) { QString res; foreach(QDir dir, dirs) if(dir.exists()) foreach(QString em_dir, dir.entryList()) { if(em_dir == "." || em_dir == ".." || QFileInfo(dir.absolutePath() + "/" + em_dir).isFile() || !QFile(dir.absolutePath() + "/" + em_dir + "/emoticons.xml").exists()) continue; if(res.isEmpty()) res = dir.absolutePath() + "/" + em_dir + "/"; if(!em_dir.compare("default", Qt::CaseInsensitive)) return dir.absolutePath() + "/" + em_dir + "/"; else if(em_dir.contains("default", Qt::CaseInsensitive)) res = dir.absolutePath() + "/" + em_dir + "/"; } return res; } void QChatSettings::createShortcut(const QString & name, const QString & displayName, const QString & group, const QKeySequence & seq) { QStringList list; list.append(displayName); list.append(group); setShortcut(name, seq); m_shortcutsInfo.insert(name, list); } void QChatSettings::initOptions() { // bool options m_options.insert("UseAnimatedSmiles" , new Option(true , "Preferences", Option::bool_opt)); m_options.insert("ColorWholeMessage" , new Option(false, "Preferences", Option::bool_opt)); m_options.insert("ColorWholeSystemMessage" , new Option(true , "Preferences", Option::bool_opt)); m_options.insert("ActivateOnMessageIn" , new Option(false, "Preferences", Option::bool_opt)); m_options.insert("SoundOnMessageIn" , new Option(false, "Preferences", Option::bool_opt)); m_options.insert("IsExecuteCommandOnIncomingMessage", new Option(false, "Preferences", Option::bool_opt)); m_options.insert("WarningAboutHidingInTray" , new Option(true , "Warnings" , Option::bool_opt)); m_options.insert("SoundOnMessageIn" , new Option(false, "Preferences", Option::bool_opt)); // int options m_options.insert("LastServersNum" , new Option(10, "Preferences", Option::int_opt)); m_options.insert("LastLoginsNum" , new Option(10, "Preferences", Option::int_opt)); // QHostAddress options // string options m_options.insert("DisplayMessagesFormat" , new Option("%time%hh:mm:ss%time% | [[%user@%comp]] : ", "Preferences", Option::string_opt)); m_options.insert("NLFormat" , new Option(QObject::tr("Now Listening to : %t by %a on %b"), "NowListening", Option::string_opt)); m_options.insert("LastServers" , new Option("", "Preferences", Option::string_opt)); m_options.insert("LastLogins" , new Option("", "Preferences", Option::string_opt)); } void QChatSettings::initGeneralOptions() { m_defaultSettings = new QChatSettings; // bool options m_generalOptions.insert("AllowDifferentPorts", new Option(false, "Network", Option::bool_opt)); m_generalOptions.insert("UseIPList" , new Option(false, "Network", Option::bool_opt)); m_generalOptions.insert("UseCompression" , new Option(false, "Network", Option::bool_opt)); m_generalOptions.insert("UseCompression" , new Option(false, "Network", Option::bool_opt)); m_generalOptions.insert("UseCompression" , new Option(false, "Network", Option::bool_opt)); // int options m_generalOptions.insert("InputPort" , new Option(61108, "Network", Option::int_opt)); m_generalOptions.insert("OutputPort" , new Option(61108, "Network", Option::int_opt)); m_generalOptions.insert("ProtocolVersion" , new Option(4 , "Network", Option::int_opt)); // QHostAddress options m_generalOptions.insert("IP" , new Option(0x7f000001, "Network", Option::HostAddress_opt)); m_generalOptions.insert("Broadcast" , new Option(0xffffffff, "Network", Option::HostAddress_opt)); m_generalOptions.insert("CustomIP" , new Option(0x7f000001, "Network", Option::HostAddress_opt)); m_generalOptions.insert("CustomBroadcast" , new Option(0xffffffff, "Network", Option::HostAddress_opt)); // string options } void QChatSettings::setOption(const QString & opt, QVariant val) { Option* option; Q_ASSERT(m_options.find(opt) != m_options.end() || m_generalOptions.find(opt) != m_generalOptions.end()); option = m_generalOptions.find(opt) != m_generalOptions.end() ? m_generalOptions[opt] : m_options[opt]; option->setOption(val); } bool QChatSettings::boolOption(const QString & opt) const { Option* option; Q_ASSERT(m_options.find(opt) != m_options.end() || m_generalOptions.find(opt) != m_generalOptions.end()); option = m_generalOptions.find(opt) != m_generalOptions.end() ? m_generalOptions[opt] : m_options[opt]; Q_ASSERT(option->type() == Option::bool_opt || m_options[opt]->type() == Option::bool_opt); return option->option().toBool(); } qint64 QChatSettings::intOption(const QString & opt) const { Option* option; Q_ASSERT(m_options.find(opt) != m_options.end() || m_generalOptions.find(opt) != m_generalOptions.end()); option = m_generalOptions.find(opt) != m_generalOptions.end() ? m_generalOptions[opt] : m_options[opt]; Q_ASSERT(option->type() == Option::int_opt || m_options[opt]->type() == Option::int_opt); return option->option().toInt(); } QString QChatSettings::strOption(const QString & opt) const { Option* option; Q_ASSERT(m_options.find(opt) != m_options.end() || m_generalOptions.find(opt) != m_generalOptions.end()); option = m_generalOptions.find(opt) != m_generalOptions.end() ? m_generalOptions[opt] : m_options[opt]; Q_ASSERT(option->type() == Option::string_opt || m_options[opt]->type() == Option::string_opt); return option->option().toString(); } void QChatSettings::saveOptions(QSettings* settings) { save(settings, m_options); } void QChatSettings::saveGeneralOptions(QSettings* settings) { save(settings, m_generalOptions); } void QChatSettings::loadGeneralOptions(QSettings* settings) { load(settings, m_generalOptions); } void QChatSettings::loadOptions(QSettings* settings) { load(settings, m_options); } void QChatSettings::save(QSettings* settings, QMap< QString, Option* > options) { QStringList sections; int nsections = 0; QMapIterator op(options); while (op.hasNext()) { op.next(); sections = op.value()->section().split("/"); nsections = 0; foreach(QString s, sections) { settings->beginGroup(s); nsections++; } settings->setValue(op.key(), op.value()->option()); for(int i = 0; i < nsections; i++) settings->endGroup(); } } void QChatSettings::load(QSettings* settings, QMap< QString, Option* >& options) { QStringList sections; int nsections = 0; QMapIterator op(options); while (op.hasNext()) { op.next(); sections = op.value()->section().split("/"); nsections = 0; foreach(QString s, sections) { settings->beginGroup(s); nsections++; } op.value()->setOption(settings->value(op.key(), op.value()->option())); for(int i = 0; i < nsections; i++) settings->endGroup(); } } QVariant QChatSettings::option(const QString& opt) const { Option* option; Q_ASSERT(m_options.find(opt) != m_options.end() || m_generalOptions.find(opt) != m_generalOptions.end()); option = m_generalOptions.find(opt) != m_generalOptions.end() ? m_generalOptions[opt] : m_options[opt]; Q_ASSERT(option); return option->option(); } QChatSettings * QChatSettings::settings() { return m_currentSettings ? m_currentSettings : m_defaultSettings; } QHostAddress QChatSettings::realBroadcast() { return settings()->hostAddressOption("Broadcast"); } QHostAddress QChatSettings::hostAddressOption(const QString & opt) const { Option* option; QHostAddress addr; Q_ASSERT(m_options.find(opt) != m_options.end() || m_generalOptions.find(opt) != m_generalOptions.end()); option = m_generalOptions.find(opt) != m_generalOptions.end() ? m_generalOptions[opt] : m_options[opt]; Q_ASSERT(option->type() == Option::HostAddress_opt || m_options[opt]->type() == Option::HostAddress_opt); if(!addr.setAddress(option->option().toString())) addr.setAddress(option->option().toInt()); return addr; } QHostAddress QChatSettings::broadcast() { return ((m_mode == Server) ? m_servBroadcast : QHostAddress(settings()->option("Broadcast").toString())); } qchat-0.3/src/inputrichtextwgt.cpp0000644000076500017500000001103410771514441016125 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "inputrichtextwgt.h" #include #include #include "colorchooser.h" InputRichTextWgt::InputRichTextWgt(QWidget *parent) : QWidget(parent) { m_inputText = new InputTextWgt(this); QGridLayout* grid = new QGridLayout(this); grid->addWidget(m_inputText, 0, 0); grid->setMargin(0); connect(m_inputText, SIGNAL(currentCharFormatChanged(const QTextCharFormat &)), this, SIGNAL(currentCharFormatChanged(const QTextCharFormat &))); connect(m_inputText, SIGNAL(wantSend()), this, SIGNAL(wantSend())); } InputRichTextWgt::~InputRichTextWgt() { qDebug("[~InputRichTextWgt]"); } //\***************************************************************************** void InputRichTextWgt::setBold(bool b) { QTextCharFormat fmt; fmt.setFontWeight(b ? QFont::Bold : QFont::Normal); mergeFormat(fmt); } void InputRichTextWgt::setUnderline(bool b) { QTextCharFormat fmt; fmt.setFontUnderline(b); mergeFormat(fmt); } void InputRichTextWgt::setItalic(bool b) { QTextCharFormat fmt; fmt.setFontItalic(b); mergeFormat(fmt); } void InputRichTextWgt::setColor(const QColor & color) { QTextCharFormat fmt; if(!color.isValid()) return; fmt.setForeground(color); mergeFormat(fmt); } void InputRichTextWgt::mergeFormat(const QTextCharFormat & fmt) { QTextCursor cursor = m_inputText->textCursor(); if(!cursor.hasSelection()) cursor.movePosition(cursor.position() == 0 ? QTextCursor::NextCharacter : QTextCursor::PreviousCharacter, QTextCursor::KeepAnchor); cursor.mergeCharFormat(fmt); m_inputText->mergeCurrentCharFormat(fmt); if(m_inputText->toPlainText().isEmpty()) { cursor.setBlockCharFormat(m_inputText->currentCharFormat()); cursor.clearSelection(); } } void InputRichTextWgt::clear() { QTextCharFormat fmt = m_inputText->currentCharFormat(); m_inputText->clear(); mergeFormat(fmt); } void InputRichTextWgt::setFontFamily(const QString & fam) { QTextCharFormat fmt; fmt.setFontFamily(fam); mergeFormat(fmt); } void InputRichTextWgt::setFontSize(const QString & pnt) { QTextCharFormat fmt; fmt.setFontPointSize(pnt.toFloat()); mergeFormat(fmt); } // just copy-pasted frm qt4/demos/textedit void InputRichTextWgt::setTextStyle(int styleIndex) { QTextCursor cursor = m_inputText->textCursor(); if(styleIndex != 0) { QTextListFormat::Style style = QTextListFormat::ListDisc; switch (styleIndex) { default: case 1: style = QTextListFormat::ListDisc; break; case 2: style = QTextListFormat::ListCircle; break; case 3: style = QTextListFormat::ListSquare; break; case 4: style = QTextListFormat::ListDecimal; break; case 5: style = QTextListFormat::ListLowerAlpha; break; case 6: style = QTextListFormat::ListUpperAlpha; break; } cursor.beginEditBlock(); QTextBlockFormat blockFmt = cursor.blockFormat(); QTextListFormat listFmt; if (cursor.currentList()) { listFmt = cursor.currentList()->format(); } else { listFmt.setIndent(blockFmt.indent() + 1); blockFmt.setIndent(0); cursor.setBlockFormat(blockFmt); } listFmt.setStyle(style); cursor.createList(listFmt); cursor.endEditBlock(); } else { } } void InputRichTextWgt::createTable(uint rows, uint cols) { QTextTableFormat fmt; fmt.setHeaderRowCount(rows); m_inputText->textCursor().insertTable(rows, cols, fmt); } qchat-0.3/src/nlamarok.h0000644000076500017500000000415710665277445013766 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef NLAMAROK_H #define NLAMAROK_H #include #include #include /** @author Anistratov Oleg */ class NLAmarok : public QObject { Q_OBJECT private: bool m_updated; QTimer* m_updateTimer; QProcess* m_processArtist; QProcess* m_processAlbum; QProcess* m_processTitle; QString m_artist; QString m_album; QString m_title; int m_nRequests; public: NLAmarok(QObject *parent = 0); ~NLAmarok(); const QString & artist() const {return m_artist;} const QString & album () const {return m_album ;} const QString & title () const {return m_title ;} void requestArtist(); void requestAlbum (); void requestTitle (); public slots: void updateAlbum (int); void updateArtist(int); void updateTitle (int); void update(){if(!m_nRequests){requestArtist(); requestAlbum (); requestTitle ();}} signals: void updated(const QString &, const QString &, const QString &); }; #endif qchat-0.3/src/shortcutgrabber.cpp0000644000076500017500000000333210767346016015701 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "shortcutgrabber.h" #include ShortcutGrabber::ShortcutGrabber(QWidget *parent) : QDialog(parent) { QGridLayout* grid = new QGridLayout(this); m_shortcutBtn = new ShortcutButton(this); grid->addWidget(m_shortcutBtn); m_shortcutBtn->setFocus(); connect(m_shortcutBtn, SIGNAL(sequenceAccepted(const QKeySequence&)), this, SLOT(acceptSequence(const QKeySequence&))); setWindowTitle(tr("Input Shortcut")); } ShortcutGrabber::~ShortcutGrabber() { } void ShortcutGrabber::acceptSequence(const QKeySequence& seq) { m_sequence = seq; accept(); } bool ShortcutGrabber::execute() { m_shortcutBtn->grabKeyboard(); return exec(); } qchat-0.3/src/userstatistics.h0000644000076500017500000000357010671575701015242 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERSTATISTICS_H #define USERSTATISTICS_H #include /** @author Anistratov Oleg */ class UserStatistics { private: QString m_os; qint32 m_uptime; quint32 m_chatTime; public: UserStatistics(); ~UserStatistics(); static QString OsString(); static qint32 getUptime(); static QString time2string(quint64); void setOs(const QString & value){m_os = value;} const QString & os() const {return m_os;} void setUptime(qint32 value){m_uptime = value;} qint32 uptime() const {return m_uptime;} QString uptimeString() const {return time2string(m_uptime);} void setChatTime(quint32 value){m_chatTime = value;} quint32 chatTime() const {return m_chatTime;} QString chatTimeString() const {return time2string(m_chatTime);} }; #endif qchat-0.3/src/logwgt.cpp0000644000076500017500000000372410665277445014017 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "logwgt.h" #include #include #include LogWgt::LogWgt(QWidget *parent) : QWidget(parent) { QGridLayout* grid = new QGridLayout(this); mw_text = new QTextEdit(this); grid->addWidget(mw_text); grid->setMargin(2); mw_text->setReadOnly(true); } //\***************************************************************************** void LogWgt::addMessage(const QString & msg, const QColor & color) { QTextCursor cur_new, cur_old; cur_new = cur_old = mw_text->textCursor(); cur_new.clearSelection(); cur_new.setPosition(mw_text->toPlainText().size()); mw_text->setTextCursor(cur_new); mw_text->setTextColor (color); mw_text->append(msg); cur_new.setPosition(mw_text->toPlainText().size()); mw_text->setTextCursor(cur_new); mw_text->setTextCursor(cur_old); mw_text->verticalScrollBar()->setValue(mw_text->verticalScrollBar()->maximum()); } qchat-0.3/src/singlemessagewgt.cpp0000644000076500017500000002332711002604042016032 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "singlemessagewgt.h" #include #include #include #include "inputtextwgt.h" #include "chattextwgt.h" #include "singlemessage.h" QList SingleMessageWgt::m_newMessages; QList SingleMessageWgt::m_openedMessages; int SingleMessageWgt::m_currentNewMessage(-1); int SingleMessageWgt::m_currentOpenedMessage(-1); QSize SingleMessageWgt::m_lastSize(500, 250); QPoint SingleMessageWgt::m_lastPosition(-1, -1); SingleMessageWgt::SingleMessageWgt(const QString & title, const QString & message, uint destUid, const QHostAddress & addr, bool isIncoming, QWidget *parent) : /*QDialog*/QWidget(parent) { init(title, message, destUid, addr, isIncoming); } SingleMessageWgt::SingleMessageWgt(SingleMessage* msg, bool isIncoming, QWidget * parent) : /*QDialog*/QWidget(parent) { QDateTime dt; dt.setTime_t(msg->receiveTime()); init(tr("Message ") + tr(isIncoming ? "from " : "to ") + msg->userName() + QString("[") + dt.toString("hh:mm:ss") + "] ", msg->msg(), msg->srcUid(), QHostAddress(msg->srcIp()), isIncoming); m_message = msg; m_message->setIsVisible(true); m_message->setMessageWgt(this); if(!msg->isIncoming()) if(msg->isHtml()) m_inputText->setHtml(msg->msg()); else m_inputText->setPlainText(msg->msg()); m_inputText->moveCursor(QTextCursor::End); } //\***************************************************************************** SingleMessageWgt::~SingleMessageWgt() { qDebug("[SingleMessageWgt::~SingleMessageWgt]\n"); } //\***************************************************************************** void SingleMessageWgt::retranslate() { m_closeBtn ->setText(tr("&Close" )); m_sendBtn ->setText(tr("&Send" )); m_replyBtn ->setText(tr("&Reply" )); m_replyQuotedBtn ->setText(tr("Reply &Quoted")); m_importantChbx ->setText(tr("Important")); } //\***************************************************************************** void SingleMessageWgt::slot_reply() { m_importantChbx->show(); m_sendBtn ->show(); m_inputText->show(); m_replyQuotedBtn->hide(); m_replyBtn ->hide(); QGridLayout* grid = qobject_cast(this->layout()); Q_ASSERT(grid); grid->removeWidget(m_replyQuotedBtn); grid->removeWidget(m_replyBtn); grid->addWidget(m_sendBtn , 2, 0, 1, 1); grid->addWidget(m_closeBtn , 2, 1, 1, 1); grid->addWidget(m_importantChbx, 2, 2, 1, 1); grid->setColumnStretch(0, 1); grid->setColumnStretch(1, 1); m_inputText->setToolTip(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")"); setWindowTitle(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")"); m_inputText->setFocus(); } //\***************************************************************************** void SingleMessageWgt::slot_replyQuoted() { QString str = QString(">") + m_messageIn->toPlainText(); m_quot = true; str.replace("\n", "\n>"); if(str[str.size() - 1] == ('>') && str.size() > 1) str.resize(str.size() - 1); else str.append("\n"); m_messageIn->text()->setFontItalic(true); m_messageIn->text()->setPlainText(str); m_importantChbx->show(); m_sendBtn ->show(); m_inputText->show(); m_replyQuotedBtn->hide(); m_replyBtn ->hide(); QGridLayout* grid = qobject_cast(this->layout()); Q_ASSERT(grid); grid->removeWidget(m_replyQuotedBtn); grid->removeWidget(m_replyBtn); grid->addWidget(m_sendBtn , 2, 0, 1, 1); grid->addWidget(m_closeBtn , 2, 1, 1, 1); grid->addWidget(m_importantChbx, 2, 2, 1, 1); grid->setColumnStretch(0, 1); grid->setColumnStretch(1, 1); m_inputText->setToolTip(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")"); setWindowTitle(tr("Replying to ") + m_title + "(" + m_destAddr.toString() + ")"); m_inputText->setFocus(); } //\***************************************************************************** void SingleMessageWgt::slot_selfDestroy() { if(m_message) { m_message->setIsVisible(false); m_message->setMessageWgt(NULL); m_message->setOld(); } // removing object from new and opened messages lists if(m_newMessages.contains(this)) { int idx = m_newMessages.indexOf(this); if(m_currentNewMessage >= idx) m_currentNewMessage--; m_newMessages.removeAll(this); } if(m_openedMessages.contains(this)) { int idx = m_openedMessages.indexOf(this); if(m_currentOpenedMessage >= idx) m_currentOpenedMessage--; m_openedMessages.removeAll(this); } hide(); this->~SingleMessageWgt(); } //\***************************************************************************** void SingleMessageWgt::slot_sendMessage() { qDebug("[SingleMessageWgt::slot_sendMessage]: addr = '%s'", m_destAddr.toString().toLocal8Bit().data()); if(m_quot) emit singleMessage(m_messageIn->toPlainText() + m_inputText->toPlainText(), m_destUid, m_importantChbx->checkState() == Qt::Checked); else emit singleMessage(m_inputText->toPlainText(), m_destUid, m_importantChbx->checkState() == Qt::Checked); slot_selfDestroy(); } //\***************************************************************************** void SingleMessageWgt::init(const QString & title, const QString & message, uint destUid, const QHostAddress & addr, bool isIncoming) { m_isIncoming = isIncoming; m_quot = false; m_destAddr = addr; m_title = title; m_destUid = destUid; m_message = NULL; QGridLayout* grid; grid = new QGridLayout (this); m_closeBtn = new QPushButton (this); m_sendBtn = new QPushButton (this); m_replyBtn = new QPushButton (this); m_replyQuotedBtn = new QPushButton (this); m_messageIn = new ChatTextWgt (this); m_inputText = new InputTextWgt(this); m_importantChbx = new QCheckBox (this); m_messageIn->setMinimumWidth(400); m_inputText->setMinimumWidth(400); if(m_isIncoming) { grid->addWidget(m_messageIn , 1, 0, 1, 3); grid->addWidget(m_replyBtn , 2, 0, 1, 1); grid->addWidget(m_replyQuotedBtn, 2, 1, 1, 1); grid->addWidget(m_closeBtn , 2, 2, 1, 1); grid->addWidget(m_inputText , 4, 0, 1, 3); m_importantChbx->hide(); m_sendBtn ->hide(); m_inputText->hide(); m_messageIn->setMsg(message); } else { grid->addWidget(m_inputText , 1, 0, 1, 3); grid->addWidget(m_importantChbx , 2, 2, 1, 1); grid->addWidget(m_sendBtn , 2, 0, 1, 1); grid->addWidget(m_closeBtn , 2, 1, 1, 1); grid->setColumnStretch(0, 1); grid->setColumnStretch(1, 1); m_replyBtn ->hide(); m_replyQuotedBtn->hide(); m_messageIn ->hide(); m_inputText->setFocus(); } grid->setMargin(4); m_messageIn->setFocus(); resize(m_lastSize); if(m_lastPosition != QPoint(-1, -1)) move(m_lastPosition); connect(m_replyBtn , SIGNAL(clicked()) , this, SLOT(slot_reply ())); connect(m_replyQuotedBtn, SIGNAL(clicked()) , this, SLOT(slot_replyQuoted())); connect(m_closeBtn , SIGNAL(clicked()) , this, SLOT(slot_selfDestroy())); connect(m_sendBtn , SIGNAL(clicked()) , this, SLOT(slot_sendMessage())); connect(m_inputText , SIGNAL(wantSend()), this, SLOT(slot_sendMessage())); setWindowTitle(m_title + "(" + addr.toString() + ")"); qDebug("[SingleMessageWgt::SingleMessageWgt]: addr = '%s'", m_destAddr.toString().toLocal8Bit().data()); retranslate(); SingleMessageWgt::addOpenedMessage(this); show(); } void SingleMessageWgt::closeEvent(QCloseEvent * ev) { if(m_message) { m_message->setIsVisible(false); m_message->setMessageWgt(NULL); } ev->ignore(); slot_selfDestroy(); } void SingleMessageWgt::resizeEvent(QResizeEvent* ev) { m_lastSize = ev->size(); } void SingleMessageWgt::moveEvent(QMoveEvent* ev) { m_lastPosition = ev->pos(); } void SingleMessageWgt::nextPrevMessage(const QList& msgs, int& curMsg, int direction, bool closeCurrent) { int size = msgs.size(); if(!size) return; if(closeCurrent && curMsg >= 0 && curMsg < size) { msgs[curMsg]->slot_selfDestroy(); size = msgs.size(); } if(!size) return; if(direction > 0) curMsg += ((curMsg < 0 || curMsg >= size - 1) ? -curMsg : 1); else if(direction < 0) curMsg = ((curMsg <= 0) ? (size - 1) : curMsg - 1); else return; QRect geometry = msgs[curMsg]->geometry(); msgs[curMsg]->hide(); msgs[curMsg]->show(); msgs[curMsg]->setGeometry(geometry); msgs[curMsg]->setFocus(); } void SingleMessageWgt::closeMessages(QList& msgs, int& curMsg) { foreach(SingleMessageWgt* sm, msgs) sm->slot_selfDestroy(); msgs.clear(); curMsg = -1; } qchat-0.3/src/userprofile.h0000644000076500017500000000354410771600125014477 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERPROFILE_H #define USERPROFILE_H #include class QChatSettings; class UserInfo; /** @author Anistratov Oleg */ class UserProfile { private: QString m_name; QChatSettings* m_prefs; UserInfo* m_info; public: UserProfile(QString name, QChatSettings* prefs = 0, UserInfo* info = 0) : m_name(name), m_prefs(prefs), m_info(info){} ~UserProfile(){}; bool inited() const {return m_prefs && m_info;} UserInfo* info () const {return m_info;} QChatSettings* prefs () const {return m_prefs;} const QString & name () const {return m_name;} void rename(const QString & name){m_name = name;} void setProfile(QChatSettings* prefs, UserInfo* info){m_prefs = prefs; m_info = info;} }; #endif qchat-0.3/src/pixlabel.h0000644000076500017500000000544010665277445013756 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PIXLABEL_H #define PIXLABEL_H #include #include #include #include #include #include #include class PictureScrollArea; /** @author Anistratov Oleg */ class PixLabel : public QLabel { Q_OBJECT private: QLabel* m_fullPicture; QString m_filename; QString m_lastdir; QString m_label; QPixmap* m_pixmap; QMenu* m_menu; QAction* m_cancelAct; QAction* m_fullSizeAct; bool m_readOnly; PictureScrollArea* m_scrollPic; public: PixLabel(QString label, QWidget* parent = 0 ); ~PixLabel(){}; void retranslate(); const QPixmap* pixmap () const {return m_pixmap ;} const QString & filename () const {return m_filename;} void freePixmap (); void setReadOnly(bool ro){m_readOnly = ro;} void setTextLabel(const QString & str){setText(str); m_label = str;} public slots: void slot_cancelPicture (); void slot_choosePictureDlg(); void slot_setPixmap(const QPixmap & pix); void slot_setPixmap (const QPixmap* ); void slot_setFilename (const QString & fname){if(!fname.isNull())m_filename = fname; else m_filename = "";} void slot_setLastdir (const QString & ldir ){if(!ldir .isNull())m_lastdir = ldir ;} void slot_showFullSize (); protected: void mouseReleaseEvent(QMouseEvent * ev) { if(ev->button() == Qt::RightButton && !m_readOnly) m_menu->popup(ev->globalPos()); } void mouseDoubleClickEvent(QMouseEvent * ev) { if(ev->button()== Qt::LeftButton) emit clicked(); if(m_readOnly) slot_showFullSize(); } signals: void clicked(); void changed(); }; #endif qchat-0.3/src/chatwgt.cpp0000755000076500017500000015224311004417740014137 0ustar owerower/*************************************************************************** * Copyright (C) 2007-2008 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "chatwgt.h" #include "globals.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "singlemessagewgt.h" #include "filetransferwgt.h" #include "userwgt.h" #include "userinfo.h" #include "addchanneldialog.h" #include "edituserinfodlg.h" #include "receiverthread.h" #include "senderthread.h" #include "largedatagram.h" #include "largedatagramout.h" #include "logwgt.h" #include "qchatsettings.h" #include "preferencesdlg.h" #include "chatcore.h" #include "smileswgt.h" #include "channelwgt.h" #include "chattextwgt.h" #include "inputrichtextwgt.h" #include "qchattrayicon.h" #include "message.h" #include "singlemsgshistoryview.h" #include "singlemsgshistory.h" #include "aboutqchat.h" #include "pluginsinterfaces.h" #include "login2serverdlg.h" #include "tcpreceiverthread.h" #include "formattingtoolbar.h" #include "qchaticon.h" #include "shortcutseditor.h" #include "messagetreeitem.h" #include "singlemessage.h" #include "pluginmanager.h" #include "plugin.h" #include #include const char* BuildDate = ""; ChatWgt::ChatWgt(ChatCore* chc, QWidget* parent) : QMainWindow(parent), m_chatCore (chc), m_formattingToolBar(NULL), m_menuToolbars(NULL), m_cursorX (-1), m_cursorY (-1), m_hidePlugins (true) { m_translator = new QTranslator; m_activityTimer = new QTimer(this); createWidgets(); createActions(); setupLayout(); ChatTextWgt::initSmiles(QChatSettings::settings()->smilesThemePath()); mw_smiles->init(); mw_log->hide(); Globals::m_log = mw_log; m_trayIcon->show (); m_trayIcon->setContextMenu(m_menuFile); //*********************************** connect(this , SIGNAL( singleMessage(const QString &, quint64, bool)), m_chatCore , SLOT (slot_singleMessage(const QString &, quint64, bool))); connect(m_chatCore , SIGNAL(profileLoaded(const QString &)), this , SLOT (slot_reloadProfileData())); connect(this , SIGNAL(wantLoadProfile (const QString &)), m_chatCore , SLOT (slot_loadProfile(const QString &))); connect(this , SIGNAL(wantRenameProfile (const QString &, const QString &)), m_chatCore , SLOT (slot_renameProfile(const QString &, const QString &))); connect(this , SIGNAL(wantDeleteProfile (const QString &)), m_chatCore , SLOT (slot_deleteProfile(const QString &))); connect(m_activityTimer, SIGNAL(timeout()), this , SLOT (activity())); connect(m_chatCore , SIGNAL(disconnectedFromServer()), this , SLOT (disconnectedFromServer())); connect(m_preferencesDlg, SIGNAL(formatChanged(UserListIconFormat)), this, SLOT(changeIconFormat(UserListIconFormat))); connect(m_preferencesDlg, SIGNAL(wantLoadPlugin(QString)) , this, SLOT(loadPlugin(QString))); connect(m_preferencesDlg, SIGNAL(wantUnloadPlugin(QString)), this, SLOT(unloadPlugin(QString))); connect(m_preferencesDlg, SIGNAL(useAnimatedSmiles(bool)) , this, SLOT(setAnimationsRunning(bool))); //*********************************** UserInfo::myInfo()->setStatus(Globals::FREE); setWindowTitle(QString("Q_Chat %1").arg(Globals::VersionStr)); QApplication::setWindowIcon(QChatIcon::icon("tray-icon")); if(!m_translator->load("qchat_" + QLocale().name () + ".qm", QChatSettings::settings()->settingsDir())) if(!m_translator->load("qchat_" + QLocale().name () + ".qm", "/usr/share/qchat/translations/")) m_translator->load("qchat_" + QLocale().name () + ".qm", "/usr/local/share/qchat/translations/"); QApplication::installTranslator(m_translator); m_activityTimer->start(1000); retranslate(); setIcons(); } //\***************************************************************************** ChatWgt::~ChatWgt() { qDebug("[~ChatWgt]\n"); m_addChannelDlg->~AddChannelDlg(); } //\***************************************************************************** ChannelWgt* ChatWgt::findChannel(const QString & name, quint32 type) const { foreach(ChannelWgt* cw, mw_channels) if(cw->name() == name && (1 || cw->type() == type)) return cw; return NULL; } //\***************************************************************************** ChannelWgt* ChatWgt::findChannel(quint64 uid, quint32 type) const { foreach(ChannelWgt* cw, mw_channels) if(cw->destUid() == uid && (cw->type() == type)) return cw; return NULL; } //\***************************************************************************** void ChatWgt::slot_singleMessageIn(SingleMessage* msg, bool important) { SingleMessageWgt* smw = new SingleMessageWgt(msg, 1); connect(smw , SIGNAL(singleMessage (const QString &, quint64, bool)), this, SIGNAL(singleMessageOut(const QString &, quint64, bool))); if(important) smw->setWindowFlags(smw->windowFlags() | Qt::WindowStaysOnTopHint/* | Qt::Popup*/); SingleMessageWgt::addNewMessage(smw); smw->show(); } //\***************************************************************************** void ChatWgt::createChannel(const QString & name, quint64 uid) { qDebug("[ChatWgt::createChannel]: begin"); int new_idx = 0; ChannelWgt* new_ch; if(uid == 0) { if(name == "Log" || name == "log") { new_idx = mw_tabs->addTab(mw_log, QString("Log")); mw_tabs->setCurrentIndex(new_idx); return; } if(findChannel(name)) return; } else { if(findChannel(name, 1)) return; foreach(ChannelWgt* cw, mw_channels) if(cw->destUid() == uid) return; } if(uid == 0) { new_ch = new ChannelWgt(name, this); new_idx = mw_tabs->addTab(new_ch, name); } else { new_ch = new ChannelWgt(name, this, AbstractChatCore::Private, uid); new_idx = mw_tabs->addTab(new_ch, name + "(private)"); } if(!mw_channels.contains(new_ch)) mw_channels.append(new_ch); new_ch->show(); connect(new_ch, SIGNAL(wantActivate ()), this, SLOT(slot_activateWindow ())); connect(new_ch , SIGNAL( statusAnswer (QString, quint64, AbstractChatCore::ChannelType, bool, bool)), m_chatCore, SLOT (slot_statusAnswer (QString, quint64, AbstractChatCore::ChannelType, bool, bool))); connect(new_ch , SIGNAL( infoAnswer (QString, quint64, AbstractChatCore::ChannelType, uchar)), m_chatCore, SLOT (slot_infoAnswer (QString, quint64, AbstractChatCore::ChannelType, uchar))); connect(new_ch , SIGNAL(sendSomeData(QString, quint64, AbstractChatCore::DataType, QString, AbstractChatCore::ChannelType, QByteArray*)), m_chatCore, SLOT (slot_prepareAndSend(QString, quint64, AbstractChatCore::DataType, QString, AbstractChatCore::ChannelType, QByteArray*))); connect(new_ch , SIGNAL(sendMsgsHistory (QString, quint64, QByteArray, AbstractChatCore::ChannelType)), m_chatCore, SLOT (slot_msgsHistoryAnswer(QString, quint64, QByteArray, AbstractChatCore::ChannelType))); connect(new_ch , SIGNAL(sendMsgsNum (const QString &, quint64, quint32, AbstractChatCore::ChannelType)), m_chatCore, SLOT (slot_msgsNumAnswer(const QString &, quint64, quint32, AbstractChatCore::ChannelType))); connect(m_preferencesDlg, SIGNAL(ulRefreshIntervalChanged(uint)), new_ch , SLOT (slot_changeUlRefreshInterval(uint))); connect(m_preferencesDlg, SIGNAL(ulDeepRefreshIntervalChanged(uint)), new_ch , SLOT (slot_changeUlDeepRefreshInterval(uint))); connect(new_ch , SIGNAL(sendMessage (const QString &, quint64, AbstractChatCore::ChannelType, QTextDocument*)), m_chatCore, SLOT (slot_sendMessage(const QString &, quint64, AbstractChatCore::ChannelType, QTextDocument*))); connect(new_ch , SIGNAL(wantSaveState (const QString &, const QByteArray &)), m_chatCore, SLOT (setChannelState(const QString &, const QByteArray &))); connect(new_ch , SIGNAL(avatarAnswer (const QString &, quint64, AbstractChatCore::ChannelType)), m_chatCore, SLOT (slot_avatarAnswer(const QString &, quint64, AbstractChatCore::ChannelType))); connect(m_chatCore, SIGNAL(loginFinished (int, QString)), new_ch , SLOT (slot_refreshUL())); new_ch->setFocus(); new_ch->setFocus2InputText(); new_ch->setSndOnMsgIn(QChatSettings::settings()->boolOption("SoundOnMessageIn")); new_ch->initChannel(); mw_tabs->setCurrentIndex(new_idx); if(uid != 0) m_chatCore->slot_privateChatRequest(UserInfo::myInfo()->nickname(), uid); new_ch->restoreState(m_chatCore->channelState(name)); qDebug("[ChatWgt::createChannel]: end"); } //\***************************************************************************** void ChatWgt::slot_delChannell() { ChannelWgt* wgt = qobject_cast(mw_tabs->currentWidget()); if(!wgt) { QChatWidgetPlugin* plug = qobject_cast(mw_tabs->currentWidget()); if(plug) { QMessageBox* msgbx; int ans; msgbx = new QMessageBox(tr("Are you sure?"), tr("Are you sure you want to unload plugin '%1'?").arg(plug->name()), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No, 0, this, 0); ans = msgbx->exec(); delete msgbx; if(ans == QMessageBox::No) return; unloadPlugin(plug->path()); } return; } qDebug("[ChatWgt::slot_delChannell]: name = %s\n", wgt->name().toLocal8Bit().data()); if(mw_tabs->currentWidget() == mw_log) { mw_tabs->removeTab(mw_tabs->currentIndex()); return; } QString name_id = wgt->name(); quint32 type = wgt->type(); ChannelWgt* ch = findChannel(name_id, type); if(name_id == "Main") return; QMessageBox* msgbx; int ans; msgbx = new QMessageBox(tr("Are you sure?"), tr("Are you sure you want to close channel '%1'?").arg(name_id), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No, 0, this, 0); ans = msgbx->exec(); delete msgbx; if(ans == QMessageBox::No) return; if(ch) mw_channels.removeAll(ch); delete ch; } //\***************************************************************************** void ChatWgt::slot_license() { QString str = "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License version 2\n" "as published by the Free Software Foundation;\n\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n\n" "Copyright (C) 2007-2008 by Anistratov Oleg\n" "ower@users.sourceforge.net"; QMessageBox::information (this, "License", str); } //\***************************************************************************** void ChatWgt::slot_aboutQt() { QMessageBox::aboutQt(this); } //\***************************************************************************** void ChatWgt::slot_about() { AboutQChat* dlg = new AboutQChat(this); dlg->exec(); delete dlg; } //\***************************************************************************** void ChatWgt::slot_showSettings() { m_userInfoDlg->setReadOnly(false); m_userInfoDlg->slot_loadInfo(UserInfo::myInfo()); m_userInfoDlg->slot_notEdited(); m_userInfoDlg->toggleVisible(); } //\***************************************************************************** void ChatWgt::slot_showPreferences() { m_preferencesDlg->init(); m_preferencesDlg->toggleVisible(); } //\***************************************************************************** void ChatWgt::slot_showUserInfo(UserWgt* user) { m_userInfoDlg->slot_loadInfo(user->info()); m_userInfoDlg->setReadOnly(true); m_userInfoDlg->show(); } //\***************************************************************************** void ChatWgt::slot_activateWindow() { if(!QApplication::focusWidget()) m_trayIcon->setAnimatedIcon(QChatIcon::iconPath("animated-new-message")); if(QChatSettings::settings()->boolOption("ActivateOnMessageIn") && isHidden()) show(); if(windowState() & Qt::WindowMaximized) this->setWindowState(Qt::WindowMaximized|Qt::WindowActive); else if(windowState () & Qt::WindowMinimized) { this->setWindowState(Qt::WindowNoState); this->setWindowState(Qt::WindowActive ); } else this->setWindowState(Qt::WindowActive); } //\***************************************************************************** void ChatWgt::slot_sendFile(quint64 uid) { QString filename; filename = QFileDialog::getOpenFileName( this, tr("Choose a file to open"), "/" ""); qDebug("[ChatWgt::slot_sendFile]: filename = %s", filename.toLocal8Bit().data()); if(filename.isEmpty()) return; FileTransferWgt* ftw = new FileTransferWgt(filename, 0); quint32 id = m_chatCore->initSendingFile(uid, filename, ftw); UserInfo* info = m_chatCore->getUserInfo(uid); if(info) { ftw->setUserName(info->nickname()); ftw->setIp(info->ip()); } if(id) { ftw->setID(id); ftw->setUid(uid); } ftw->init(); } //\***************************************************************************** void ChatWgt::slot_receiveFile(const QString & filename, quint16 ID, quint64 srcIP) { FileTransferWgt* ftw = new FileTransferWgt(filename, 1); UserInfo* info = m_chatCore->getUserInfo(srcIP); if(info) { ftw->setUserName(info->nickname()); ftw->setIp(info->ip()); } ftw->setID (ID ); ftw->setUid(srcIP); ftw->init(); m_chatCore->initReceivingFile(ftw); } //\***************************************************************************** void ChatWgt::slot_openSocketError(quint16 port) { mw_log->addError(QString("Couldn't open UDP socket on port %1 ").arg(port)); } //\***************************************************************************** void ChatWgt::slot_exit() { foreach(ChannelWgt* cw, mw_channels) cw->slot_disconnected(); m_chatCore->stopThreads(); m_chatCore->saveSettings(true); QApplication::quit(); } //\***************************************************************************** void ChatWgt::slot_trayIconClicked(QSystemTrayIcon::ActivationReason reason) { ChannelWgt* chnnl = findChannel(currentChannelName()); if(reason == QSystemTrayIcon::Trigger) { m_trayIcon->setStaticIcon(QChatIcon::iconPath("tray-icon")); if(isHidden() || windowState () & Qt::WindowMinimized) { show(); if(windowState() & Qt::WindowMaximized) setWindowState(Qt::WindowMaximized|Qt::WindowActive); else setWindowState(Qt::WindowNoState); if(chnnl) chnnl->setFocus2InputText(); } else hide(); } } //\***************************************************************************** void ChatWgt::slot_showSmiles() { if(!mw_smiles || !mw_smiles->inited()) return; if(m_smilesScrllArea->isHidden()) { mw_smiles->setOptimalSize(); mw_smiles->unselectAll(); QDesktopWidget dsctp; int wd = mw_smiles->width(); int he = mw_smiles->height(); int max_wd, max_he; max_wd = (dsctp.availableGeometry().width() / 8) * 7; max_he = (dsctp.availableGeometry().height() / 8) * 7; if(wd > max_wd) wd = max_wd; if(he > max_he) he = max_he; m_smilesScrllArea->setWindowFlags(Qt::FramelessWindowHint | m_smilesScrllArea->windowFlags() | Qt::WindowStaysOnTopHint); m_smilesScrllArea->resize(wd + 5, he + 5); m_smilesScrllArea->move(QCursor().pos()); m_smilesScrllArea->show(); mw_smiles->show(); if(wd >= mw_smiles->width()) m_smilesScrllArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); else m_smilesScrllArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); if(he >= mw_smiles->height()) m_smilesScrllArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); else m_smilesScrllArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); } else m_smilesScrllArea->hide(); } //\***************************************************************************** void ChatWgt::slot_insertSmile(const QString & smile) { ChannelWgt* chnnl = qobject_cast(mw_tabs->currentWidget()); if(chnnl) chnnl->inputText()->append(smile); } //\***************************************************************************** QString ChatWgt::currentChannelName() const { ChannelWgt* chnnl = qobject_cast(mw_tabs->currentWidget()); return (chnnl ? chnnl->name() : ""); } //\***************************************************************************** void ChatWgt::fillProfilesCmbx(const QStringList & profiles, const QString & current) { disconnect(m_profilesCmbx, SIGNAL(currentIndexChanged(const QString &)), m_chatCore , SLOT (slot_loadProfile (const QString &))); QStringList::const_iterator i; QStringList::const_iterator end = profiles.constEnd(); int idx; for(i = profiles.constBegin(); i != end; ++i) m_profilesCmbx->addItem(*i); if((idx = m_profilesCmbx->findText(current)) >= 0) m_profilesCmbx->setCurrentIndex(idx); connect(m_profilesCmbx, SIGNAL(currentIndexChanged(const QString &)), m_chatCore , SLOT (slot_loadProfile (const QString &))); } //\***************************************************************************** void ChatWgt::slot_setCurrentProfileName(const QString & name) { int idx; if((idx = m_profilesCmbx->findText(name)) >= 0) m_profilesCmbx->setCurrentIndex(idx); else m_profilesCmbx->addItem(name); if((idx = m_profilesCmbx->findText(name)) >= 0) m_profilesCmbx->setCurrentIndex(idx); } void ChatWgt::slot_reloadProfileData() { if(!m_userInfoDlg->isHidden() && !m_userInfoDlg->readOnly()) m_userInfoDlg->slot_loadInfo(UserInfo::myInfo()); if(!m_preferencesDlg->isHidden()) m_preferencesDlg->init(); ChatTextWgt::initSmiles(QChatSettings::settings()->smilesThemePath()); mw_smiles->loadTheme(QChatSettings::settings()->smilesThemePath()); // FIXME incorrect works if other channel set its status in myInfo foreach(ChannelWgt* cw, mw_channels) m_chatCore->slot_statusAnswer(cw->name(), QChatSettings::settings()->broadcast().toIPv4Address(), AbstractChatCore::Common, 0, 1); m_preferencesDlg->setIconFormat(*QChatSettings::settings()->iconFormat()); changeIconFormat(*QChatSettings::settings()->iconFormat()); } void ChatWgt::createActions() { m_showSettingsAct = new QAction(this); m_showPreferencesAct = new QAction(this); m_exitAct = new QAction(this); m_showSmilesAct = new QAction(this); m_showEditShortcutsAct = new QAction(this); m_addChannelAct = new QAction(this); m_delChannelAct = new QAction(this); m_aboutAct = new QAction(this); m_aboutQtAct = new QAction(this); m_licenseAct = new QAction(this); m_writeSettingsAct = new QAction(this); m_addProfileAct = new QAction(this); m_deleteProfileAct = new QAction(this); m_renameProfileAct = new QAction(this); (m_translateEnAct = new QAction(this))->setData("en"); (m_translatePlAct = new QAction(this))->setData("pl"); (m_translateRuAct = new QAction(this))->setData("ru"); (m_translateUkAct = new QAction(this))->setData("uk"); (m_translateEsAct = new QAction(this))->setData("es"); (m_translateDeAct = new QAction(this))->setData("de"); (m_translateSrAct = new QAction(this))->setData("sr"); (m_showMainTBarAct = new QAction(this))->setCheckable(true); (m_showProfilesTBarAct = new QAction(this))->setCheckable(true); (m_showPluginsTBarAct = new QAction(this))->setCheckable(true); (m_showFormattingTBarAct = new QAction(this))->setCheckable(true); m_showSingleMessagesAct= new QAction(this); m_showPluginsAct = new QAction(this); m_broadcastMessageAct = new QAction(this); (m_setServerModeAct = new QAction(this))->setCheckable(true); (m_setServerlessModeAct = new QAction(this))->setCheckable(true); m_connectToServerAct = new QAction(this); m_disconnectFromServerAct = new QAction(this); (m_toolButtonsSizeDefault = new QAction(this))->setData(0); (m_toolButtonsSize16 = new QAction(this))->setData(16); (m_toolButtonsSize24 = new QAction(this))->setData(24); (m_toolButtonsSize32 = new QAction(this))->setData(32); (m_toolButtonsSize48 = new QAction(this))->setData(48); QActionGroup* tbSizeGroup = new QActionGroup(this); m_toolButtonsSizeDefault->setCheckable(true); m_toolButtonsSize16 ->setCheckable(true); m_toolButtonsSize24 ->setCheckable(true); m_toolButtonsSize32 ->setCheckable(true); m_toolButtonsSize48 ->setCheckable(true); m_toolButtonsSizeDefault->setActionGroup(tbSizeGroup); m_toolButtonsSize16 ->setActionGroup(tbSizeGroup); m_toolButtonsSize24 ->setActionGroup(tbSizeGroup); m_toolButtonsSize32 ->setActionGroup(tbSizeGroup); m_toolButtonsSize48 ->setActionGroup(tbSizeGroup); m_disconnectFromServerAct->setVisible(false); m_setServerModeAct ->setData(ChatCore::Server); m_setServerlessModeAct->setData(ChatCore::Serverless); QActionGroup* actGrp = new QActionGroup(this); actGrp->addAction(m_setServerModeAct); actGrp->addAction(m_setServerlessModeAct); m_menuFile->addAction(m_connectToServerAct); m_menuFile->addAction(m_disconnectFromServerAct); m_menuFile->addAction(m_setServerModeAct); m_menuFile->addAction(m_setServerlessModeAct); m_menuFile->addSeparator(); m_menuTranslations->addAction(m_translateEnAct); m_menuTranslations->addAction(m_translateDeAct); m_menuTranslations->addAction(m_translatePlAct); m_menuTranslations->addAction(m_translateRuAct); m_menuTranslations->addAction(m_translateSrAct); m_menuTranslations->addAction(m_translateEsAct); m_menuTranslations->addAction(m_translateUkAct); m_menuFile ->addAction(m_broadcastMessageAct); m_menuFile ->addAction(m_addChannelAct); m_menuFile ->addAction(m_delChannelAct); m_menuFile ->addAction(m_exitAct); m_menuSettings->addAction(m_showSettingsAct); m_menuSettings->addAction(m_showPreferencesAct); // m_menuSettings->addAction(m_writeSettingsAct); m_menuSettings->addAction(m_showEditShortcutsAct); m_menuSettings->addMenu (m_menuTranslations); m_menuSettings->addMenu (m_menuToolbars); m_menuView ->addAction(m_showSmilesAct); m_menuView ->addAction(m_showSingleMessagesAct); m_menuView ->addAction(m_showPluginsAct); m_menuHelp ->addAction(m_aboutAct); m_menuHelp ->addAction(m_aboutQtAct); m_menuHelp ->addAction(m_licenseAct); m_menuToolbars->addAction(m_showMainTBarAct); m_menuToolbars->addAction(m_showProfilesTBarAct); m_menuToolbars->addAction(m_showPluginsTBarAct); m_menuToolbars->addAction(m_showFormattingTBarAct); m_menuBar ->addMenu(m_menuFile); m_menuBar ->addMenu(m_menuView); m_menuBar ->addMenu(m_menuSettings); m_menuBar ->addMenu(m_menuHelp); connect(m_showSettingsAct , SIGNAL(triggered(bool)), this , SLOT(slot_showSettings())); connect(m_showPreferencesAct , SIGNAL(triggered(bool)), this , SLOT(slot_showPreferences())); connect(m_exitAct , SIGNAL(triggered(bool)), this , SLOT(slot_exit())); connect(m_showSmilesAct , SIGNAL(triggered(bool)), this , SLOT(slot_showSmiles())); connect(m_showEditShortcutsAct, SIGNAL(triggered(bool)), this , SLOT(showConfigureShortcuts())); connect(m_addChannelAct , SIGNAL(triggered(bool)), m_addChannelDlg , SLOT(getValues())); connect(m_delChannelAct , SIGNAL(triggered(bool)), this , SLOT(slot_delChannell())); connect(m_aboutAct , SIGNAL(triggered(bool)), this , SLOT(slot_about())); connect(m_aboutQtAct , SIGNAL(triggered(bool)), this , SLOT(slot_aboutQt())); connect(m_licenseAct , SIGNAL(triggered(bool)), this , SLOT(slot_license())); connect(m_writeSettingsAct , SIGNAL(triggered(bool)), m_chatCore , SLOT(slot_saveSettings())); connect(m_renameProfileAct , SIGNAL(triggered(bool)), this , SLOT(slot_editProfileName())); connect(m_addProfileAct , SIGNAL(triggered(bool)), this , SLOT(slot_addProfile())); connect(m_deleteProfileAct , SIGNAL(triggered(bool)), this , SLOT(slot_delProfile())); connect(m_showMainTBarAct , SIGNAL(triggered(bool)), m_mainToolBar , SLOT(setVisible(bool))); connect(m_showProfilesTBarAct , SIGNAL(triggered(bool)), m_profilesToolBar , SLOT(setVisible(bool))); connect(m_showPluginsTBarAct , SIGNAL(triggered(bool)), m_pluginsToolBar , SLOT(setVisible(bool))); connect(m_showFormattingTBarAct, SIGNAL(triggered(bool)), m_formattingToolBar, SLOT(setVisible(bool))); connect(m_showSingleMessagesAct, SIGNAL(triggered(bool)), this , SLOT(slot_showSingleMessagesHistory())); connect(m_showPluginsAct , SIGNAL(triggered(bool)), this , SLOT(showPlugins())); connect(m_broadcastMessageAct , SIGNAL(triggered(bool)), this , SLOT(sendBroadcastMessage())); connect(m_translatePlAct , SIGNAL(triggered(bool)), this , SLOT(setLanguage())); connect(m_translateUkAct , SIGNAL(triggered(bool)), this , SLOT(setLanguage())); connect(m_translateRuAct , SIGNAL(triggered(bool)), this , SLOT(setLanguage())); connect(m_translateEnAct , SIGNAL(triggered(bool)), this , SLOT(setLanguage())); connect(m_translateEsAct , SIGNAL(triggered(bool)), this , SLOT(setLanguage())); connect(m_translateDeAct , SIGNAL(triggered(bool)), this , SLOT(setLanguage())); connect(m_translateSrAct , SIGNAL(triggered(bool)), this , SLOT(setLanguage())); connect(m_setServerlessModeAct, SIGNAL(triggered(bool)), this , SLOT(setMode())); connect(m_setServerModeAct , SIGNAL(triggered(bool)), this , SLOT(setMode())); connect(m_setServerModeAct , SIGNAL(triggered(bool)), this, SLOT(chvisConnectToServerAct())); connect(m_setServerlessModeAct, SIGNAL(triggered(bool)), this, SLOT(chvisConnectToServerAct())); connect(m_connectToServerAct , SIGNAL(triggered(bool)), this, SLOT(connect2server())); connect(m_disconnectFromServerAct, SIGNAL(triggered(bool)), this, SLOT(disconnectFromServer())); connect(m_toolButtonsSizeDefault , SIGNAL(triggered(bool)), this, SLOT(setToolbarsIconsSize())); connect(m_toolButtonsSize16 , SIGNAL(triggered(bool)), this, SLOT(setToolbarsIconsSize())); connect(m_toolButtonsSize24 , SIGNAL(triggered(bool)), this, SLOT(setToolbarsIconsSize())); connect(m_toolButtonsSize32 , SIGNAL(triggered(bool)), this, SLOT(setToolbarsIconsSize())); connect(m_toolButtonsSize48 , SIGNAL(triggered(bool)), this, SLOT(setToolbarsIconsSize())); connect(m_preferencesDlg , SIGNAL(wantChangeProtocol(uint)), m_chatCore, SLOT(changeProtocolVersion(uint))); } void ChatWgt::createWidgets() { m_profilesLab = new QLabel(this); m_pluginsTabs = new QTabWidget(this); m_widgetsStack = new QStackedWidget(this); mw_tabs = new QTabWidget (this); m_addChannelBtn = new QToolButton(mw_tabs); m_delChannelBtn = new QToolButton(mw_tabs); m_addChannelDlg = new AddChannelDlg(this); m_userInfoDlg = new EditUserInfoDlg (0); m_preferencesDlg = new PreferencesDlg (this); mw_log = new LogWgt(this); mw_smiles = new SmilesWgt; m_trayIcon = new QChatTrayIcon(QChatIcon::icon("tray-icon"), this); m_profilesCmbx = new QComboBox(this); m_menuBar = new QMenuBar (this); (m_mainToolBar = new QToolBar (this))->setObjectName("Main Toolbar"); (m_profilesToolBar = new QToolBar (this))->setObjectName("Profiles Toolbar"); (m_pluginsToolBar = new QToolBar (this))->setObjectName("Plugins Toolbar"); (m_formattingToolBar = new FormattingToolBar(this))->setObjectName("Formatting Toolbar"); m_menuFile = new QMenu (this); m_menuView = new QMenu (this); m_menuSettings = new QMenu (this); m_menuHelp = new QMenu (this); m_menuTranslations = new QMenu (this); m_menuToolbars = new QMenu (this); m_smilesScrllArea = new QScrollArea(0); m_smhView = new SingleMsgsHistoryView(0); m_smhView->setModel(m_chatCore->smhModel()); m_smhView->resizeColumnToContents(0); m_smhView->resizeColumnToContents(1); m_smhView->resizeColumnToContents(2); m_smhView->resizeColumnToContents(3); m_smhView->resize(800, 600); setStatusBar(new QStatusBar(this)); statusBar()->setSizeGripEnabled(false); m_profilesCmbx->setMinimumWidth(150); m_smilesScrllArea->setWidget(mw_smiles); m_smilesScrllArea->resize(400, 400); connect(m_preferencesDlg, SIGNAL(portChanged (int)), m_chatCore , SLOT (slot_bindInputPort(int))); connect(m_preferencesDlg, SIGNAL(wantChangeSmileTheme (const QString &)), this , SLOT (slot_changeSmileTheme(const QString &))); connect(m_preferencesDlg, SIGNAL(styleSheetChanged(QString)), this , SIGNAL(wantChangeStyleSheet(QString))); connect(m_preferencesDlg, SIGNAL(accepted()), m_chatCore , SLOT (slot_saveSettings())); connect(m_userInfoDlg , SIGNAL(accepted()), m_chatCore , SLOT (slot_saveSettings())); connect(m_userInfoDlg , SIGNAL(wantChangeNickname(QString)), m_chatCore , SLOT (changeLogin(QString))); connect(mw_smiles , SIGNAL(smileClicked(const QString &)), this, SLOT(slot_insertSmile(const QString &))); connect(mw_smiles , SIGNAL(wantHide()) , m_smilesScrllArea, SLOT(hide())); connect(m_addChannelDlg, SIGNAL(dataAccepted(const QString &)), this, SLOT(slot_addChannell(const QString &))); connect(m_trayIcon , SIGNAL(activated (QSystemTrayIcon::ActivationReason)), this , SLOT (slot_trayIconClicked(QSystemTrayIcon::ActivationReason))); connect(m_smhView , SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(showSingleMessage(const QModelIndex &))); // connect(m_pluginsTabs, SIGNAL(currentChanged(int)), this, SLOT(pluginSwitched())); connect(mw_tabs , SIGNAL(currentChanged(int)), this, SLOT(pluginSwitched())); } void ChatWgt::setupLayout() { mw_tabs->setCornerWidget (m_addChannelBtn, Qt::TopLeftCorner); mw_tabs->setCornerWidget (m_delChannelBtn, Qt::TopRightCorner); m_addChannelBtn->setDefaultAction(m_addChannelAct); m_delChannelBtn->setDefaultAction(m_delChannelAct); m_mainToolBar->addAction(m_showSmilesAct); m_mainToolBar->addAction(m_showSettingsAct); m_mainToolBar->addAction(m_showPreferencesAct); // m_mainToolBar->addAction(m_writeSettingsAct); m_profilesToolBar->addWidget(m_profilesLab); m_profilesToolBar->addAction(m_addProfileAct); m_profilesToolBar->addWidget(m_profilesCmbx); m_profilesToolBar->addAction(m_renameProfileAct); m_profilesToolBar->addAction(m_deleteProfileAct); m_widgetsStack->insertWidget(0, mw_tabs); m_widgetsStack->insertWidget(1, m_pluginsTabs); setMenuBar(m_menuBar); addToolbar(m_mainToolBar); addToolbar(m_profilesToolBar); addToolbar(m_pluginsToolBar); addToolbar(m_formattingToolBar); setCentralWidget(m_widgetsStack); } void ChatWgt::slot_editProfileName() { bool ok; QString str = QInputDialog::getText(this, QString(tr("Input new name for '%1'")).arg(m_profilesCmbx->currentText()), tr("New name:"), QLineEdit::Normal, m_profilesCmbx->currentText(), &ok); if(ok && !str.isEmpty() && (m_profilesCmbx->findText(str) < 0) ) { emit wantRenameProfile(m_profilesCmbx->currentText(), str); m_profilesCmbx->setItemText(m_profilesCmbx->currentIndex(), str); } } void ChatWgt::slot_addProfile() { bool ok; QString str = QInputDialog::getText(this, tr("Input name for new profile"), tr("New profile name:"), QLineEdit::Normal, "", &ok); if(ok && !str.isEmpty() && (m_profilesCmbx->findText(str) < 0) ) { emit wantLoadProfile(str); m_profilesCmbx->addItem(str); m_profilesCmbx->setCurrentIndex(m_profilesCmbx->findText(str)); } } void ChatWgt::slot_delProfile() { if(m_profilesCmbx->count() > 1) { QMessageBox* msgbx; int ans; msgbx = new QMessageBox(tr("Are you sure?"), tr("Are you sure you want delete profile %1?").arg(m_profilesCmbx->currentText()), QMessageBox::Question, QMessageBox::Yes, QMessageBox::No, 0, this, 0); ans = msgbx->exec(); delete msgbx; if(ans == QMessageBox::No) return; emit wantDeleteProfile(m_profilesCmbx->currentText()); m_profilesCmbx->removeItem(m_profilesCmbx->currentIndex()); } } void ChatWgt::retranslate() { m_showSettingsAct ->setText(tr("&Edit User Details...")); m_showPreferencesAct ->setText(tr("&Configure QChat..." )); m_exitAct ->setText(tr("&Exit" )); m_showSmilesAct ->setText(tr("&Show Smiles.." )); m_addChannelAct ->setText(tr("&Add Channel.." )); m_delChannelAct ->setText(tr("&Delete Channel.." )); m_aboutAct ->setText(tr("&About" )); m_aboutQtAct ->setText(tr("About &Qt" )); m_licenseAct ->setText(tr("&License" )); // m_writeSettingsAct ->setText(tr("&Write Settings" )); m_showEditShortcutsAct->setText(tr("Configure Shortcuts...")); m_showMainTBarAct ->setText(tr("Main Toolbar" )); m_showProfilesTBarAct ->setText(tr("Profiles Toolbar" )); m_showPluginsTBarAct ->setText(tr("Plugins Toolbar" )); m_showFormattingTBarAct->setText(tr("Formatting Toolbar" )); m_addProfileAct ->setText(tr("Add pro&file..." )); m_deleteProfileAct ->setText(tr("Delete p&rofile..." )); m_renameProfileAct ->setText(tr("&Rename profile..." )); m_showSingleMessagesAct->setText(tr("Show Single Messages History...")); m_showPluginsAct ->setText(tr("Show Plugins")); m_broadcastMessageAct ->setText(tr("Send Broadcast Message...")); m_mainToolBar ->setWindowTitle(tr("Main Toolbar" )); m_profilesToolBar ->setWindowTitle(tr("Profiles Toolbar")); m_pluginsToolBar ->setWindowTitle(tr("Plugins Toolbar")); m_smhView ->setWindowTitle(tr("Single Messages History")); m_menuFile ->setTitle(tr("&Chat" )); m_menuView ->setTitle(tr("&View" )); m_menuSettings ->setTitle(tr("&Settings")); m_menuHelp ->setTitle(tr("&Help" )); m_menuTranslations ->setTitle(tr("&Language")); m_menuToolbars ->setTitle(tr("Toolbars" )); m_translatePlAct ->setText(tr("Polish")); m_translateUkAct ->setText(tr("Ukrainian")); m_translateRuAct ->setText(tr("Russian")); m_translateEnAct ->setText(tr("English")); m_translateEsAct ->setText(tr("Spanish")); m_translateDeAct ->setText(tr("German")); m_translateSrAct ->setText(tr("Serbian")); m_connectToServerAct ->setText(tr("Connect to server..")); m_disconnectFromServerAct->setText(tr("Disconnect from server")); m_setServerModeAct ->setText(tr("Server Mode")); m_setServerlessModeAct ->setText(tr("Serverless Mode")); m_profilesLab ->setText(tr("Current profile:")); m_toolButtonsSizeDefault->setText(tr("Default")); m_toolButtonsSize16 ->setText(tr("16x16")); m_toolButtonsSize24 ->setText(tr("24x24")); m_toolButtonsSize32 ->setText(tr("32x32")); m_toolButtonsSize48 ->setText(tr("48x48")); updateShortcuts(); } void ChatWgt::setLanguage() { QString lang = ((QAction*)sender())->data().toString(); m_chatCore->setLang(lang); #if defined(Q_OS_LINUX) QDir dir(QCoreApplication::applicationDirPath() + "/../share/qchat/translations"); #else QDir dir(QCoreApplication::applicationDirPath() + "/translations"); #endif if(!m_translator->load("qchat_" + m_chatCore->lang() + ".qm", QChatSettings::settings()->settingsDir())) if(!m_translator->load("qchat_" + m_chatCore->lang() + ".qm", dir.path())) if(!m_translator->load("qchat_" + m_chatCore->lang() + ".qm", "/usr/share/qchat/translations/")) m_translator->load("qchat_" + m_chatCore->lang() + ".qm", "/usr/local/share/qchat/translations/"); QApplication::installTranslator(m_translator); retranslate(); } void ChatWgt::slot_changeSmileTheme(const QString & path) { qDebug("[ChatWgt::slot_changeSmileTheme]: path = %s", path.toLocal8Bit().data()); if(path != QChatSettings::settings()->smilesThemePath()) { QChatSettings::settings()->setSmilesThemePath(path); ChatTextWgt::initSmiles(path); mw_smiles->loadTheme(path); } } QMenu* ChatWgt::createPopupMenu() { QMenu* menu = new QMenu(this); QMenu* menu_tb = new QMenu(tr("Toolbars"), menu); QMenu* menu_sz = new QMenu(tr("Icons Size"), menu); menu_tb->addAction(m_showMainTBarAct); menu_tb->addAction(m_showProfilesTBarAct); if(!m_hidePlugins) menu_tb->addAction(m_showPluginsTBarAct); menu_tb->addAction(m_showFormattingTBarAct); menu_sz->addAction(m_toolButtonsSizeDefault); menu_sz->addAction(m_toolButtonsSize16); menu_sz->addAction(m_toolButtonsSize24); menu_sz->addAction(m_toolButtonsSize32); menu_sz->addAction(m_toolButtonsSize48); menu->addMenu(menu_tb); menu->addMenu(menu_sz); return menu; } void ChatWgt::restoreAndShow() { QMessageBox::StandardButton ans; QString msg; restoreState(m_chatCore->state()); if(!m_chatCore->geometry().isEmpty()) restoreGeometry(m_chatCore->geometry()); else resize(800, 600); show(); m_showMainTBarAct ->setChecked(m_mainToolBar ->isVisible()); m_showProfilesTBarAct ->setChecked(m_profilesToolBar ->isVisible()); m_showPluginsTBarAct ->setChecked(m_pluginsToolBar ->isVisible()); m_showFormattingTBarAct->setChecked(m_formattingToolBar->isVisible()); // restoring tool buttons size int sz = QChatSettings::settings()->toolbarIconsSize(); switch(sz) { case 16 : m_toolButtonsSize16->setChecked(true); break; case 24 : m_toolButtonsSize24->setChecked(true); break; case 32 : m_toolButtonsSize32->setChecked(true); break; case 48 : m_toolButtonsSize48->setChecked(true); break; } foreach(QToolBar* tb, m_toolbars) tb->setIconSize(QSize(sz, sz)); if(!m_chatCore->lang().isEmpty()) { #if defined(Q_OS_LINUX) QDir dir(QCoreApplication::applicationDirPath() + "/../share/qchat/translations"); #else QDir dir(QCoreApplication::applicationDirPath() + "/translations"); #endif if(!m_translator->load("qchat_" + m_chatCore->lang() + ".qm", QChatSettings::settings()->settingsDir())) if(!m_translator->load("qchat_" + m_chatCore->lang() + ".qm", dir.path())) if(!m_translator->load("qchat_" + m_chatCore->lang() + ".qm", "/usr/share/qchat/translations/")) m_translator->load("qchat_" + m_chatCore->lang() + ".qm", "/usr/local/share/qchat/translations/"); QApplication::installTranslator(m_translator); } retranslate(); if(m_chatCore->needCheckIp() == 1) { msg = tr("Your network settings don't corresponds any of existing network interfaces.\n" "The program may not work.\n\n" "Do you want to configure it now?"); ans = QMessageBox::warning(this, tr("Incorrect network settings"), msg, QMessageBox::Yes | QMessageBox::No); if(ans == QMessageBox::Yes) slot_showPreferences(); } else if(m_chatCore->needCheckIp() == 2) { msg = tr("Couldn't find any network interface that can broadcast.\n" "The program may not work.\n\n" "Do you want to see your network settings?"); ans = QMessageBox::warning(this, tr("No valid network interface!"), msg, QMessageBox::Yes | QMessageBox::No); if(ans == QMessageBox::Yes) slot_showPreferences(); } setHidePlugins(!m_chatCore->pluginManager()->plugins().size()); if(m_hidePlugins) { m_showPluginsTBarAct->setVisible(false); m_pluginsToolBar->hide(); m_preferencesDlg->hidePluginsSection(); } m_showPluginsAct->setVisible(false); m_setServerlessModeAct->trigger(); } void ChatWgt::slot_focusChanged(QWidget* old, QWidget* new_) { QChatWidgetPlugin* plug; m_trayIcon->setStaticIcon(QChatIcon::iconPath("tray-icon")); if(!mw_smiles || !mw_smiles->inited()) return; if(new_ && new_ != m_smilesScrllArea) m_smilesScrllArea->hide(); if(isPLugin(old)) { // m_pluginsToolBar->clear(); if((plug = isPLugin(new_))) { // plug->setupToolBar(m_pluginsToolBar); } } } void ChatWgt::slot_processData(QC_DatagramHeader* Hdr) { ChannelWgt* chnnl; qDebug("[ChatWgt::slot_processData]: chnnl_name = %s\n", QString().fromUtf8(ChatCore::getParametr("Channel", Hdr->parametrs)).toLocal8Bit().data()); qDebug("[ChatWgt::slot_processData]: src_ip = %u\n", (uint)Hdr->src_ip); // checking if data arrived into private channel if(Hdr->chnnl_id == 1) { // checking is data arrived from us // in serverless mode we using IP addresses but in Server - UIDs quint64 uid; if(QChatSettings::settings()->mode() == QChatSettings::Serverless) uid = QChatSettings::settings()->hostAddressOption("IP").toIPv4Address(); else uid = UserInfo::myInfo()->uid(); if(Hdr->src_ip == uid || Hdr->src_ip == 0x7f000001 || Hdr->src_ip == 1) chnnl = findChannel(QString().fromUtf8(ChatCore::getParametr("Channel", Hdr->parametrs))); else chnnl = findChannel(Hdr->src_ip, 1); } else chnnl = findChannel(QString().fromUtf8(ChatCore::getParametr("Channel", Hdr->parametrs))); if(chnnl) { chnnl->processData(Hdr); if(Hdr->type == AbstractChatCore::INFO_ANSWER && m_userInfoDlg->readOnly() && m_userInfoDlg->userUid() == Hdr->src_ip && !m_userInfoDlg->isHidden()) { UserWgt* user = chnnl->findUser(Hdr->src_ip); if(user) m_userInfoDlg->slot_loadInfo(user->info()); } } delete Hdr; } void ChatWgt::activity() { } void ChatWgt::closeEvent(QCloseEvent * ev) { int res; MessageWithCheckBox* mes; QMessageBox* mbox; if(QChatSettings::settings()->boolOption("WarningAboutHidingInTray")) { mbox = new QMessageBox; mbox->setIcon(QMessageBox::Information); mes = new MessageWithCheckBox(tr("Hiding in tray"), tr("Now QChat will be available from system tray.\n" "If you want to quit from QChat - use Exit action from menu Chat."), tr("Don't show this message again"), &res, this); mes->setIcon(mbox->iconPixmap()); mes->exec(); QChatSettings::settings()->setOption("WarningAboutHidingInTray", res); delete mes; delete mbox; } ev->accept(); } void ChatWgt::slot_showSingleMessagesHistory() { m_smhView->setHidden(!m_smhView->isHidden()); } void ChatWgt::showSingleMessage(const QModelIndex & idx) { SingleMessage* msg = NULL; MessageTreeItem *item = static_cast(idx.internalPointer()); if(item) msg = item->message(); if(msg && !msg->activate()) { SingleMessageWgt* smw = new SingleMessageWgt(msg, msg->isIncoming()); connect(smw , SIGNAL(singleMessage (const QString &, quint64, bool)), this, SIGNAL(singleMessageOut(const QString &, quint64, bool))); smw->show(); } } void ChatWgt::showPlugins() { m_widgetsStack->setCurrentIndex(!m_widgetsStack->currentIndex()); } QChatWidgetPlugin* ChatWgt::isPLugin(QWidget* wgt) { QTabWidget* tab; QChatWidgetPlugin* plugin = NULL; tab = qobject_cast(wgt); if(tab) { wgt = tab->currentWidget(); while(wgt) { plugin = qobject_cast(wgt); if(plugin) return plugin; wgt = wgt->parentWidget(); } } while(wgt) { plugin = qobject_cast(wgt); if(plugin) return plugin; wgt = wgt->parentWidget(); } return plugin; } void ChatWgt::setupPluginToolBar(QWidget* wgt) { QChatWidgetPlugin* plug = qobject_cast(wgt); m_pluginsToolBar->clear(); if(plug) plug->setupToolBar(m_pluginsToolBar); } void ChatWgt::pluginSwitched() { setupPluginToolBar(mw_tabs->currentWidget()); // setupPluginToolBar(m_pluginsTabs->currentWidget()); } void ChatWgt::connect2server() { QStringList m_lastServers = QChatSettings::settings()->strOption("LastServers").split("\n", QString::SkipEmptyParts); QStringList m_lastLogins = QChatSettings::settings()->strOption("LastLogins").split("\n", QString::SkipEmptyParts); QString server = !m_lastServers.count() ? QString("127.0.0.1") : m_lastServers[0]; Login2ServerDlg* dlg = new Login2ServerDlg(&m_lastServers, &m_lastLogins, this, server, UserInfo::myInfo()->nickname()); bool res; dlg->setModal(true); connect(dlg , SIGNAL(wantLogin(QHostAddress, QString)), m_chatCore, SLOT(slot_login(QHostAddress, QString))); connect(m_chatCore, SIGNAL(loginFinished(int, QString)) , dlg , SLOT(loginFinished(int, QString))); connect(dlg , SIGNAL(loginSuccessful()) , this , SLOT(swapConnectDisconnectAct())); res = dlg->exec(); delete dlg; } void ChatWgt::disconnectFromServer() { statusBar()->showMessage(tr("Disconnecting from server...")); m_chatCore->disconnectFromServer(); } void ChatWgt::disconnectedFromServer() { m_disconnectFromServerAct->setVisible(0); m_connectToServerAct->setVisible(1); statusBar()->showMessage(tr("Disconnected from server")); m_setServerlessModeAct->trigger(); } void ChatWgt::chvisConnectToServerAct() { QAction* act = qobject_cast(sender()); bool conn; if(act) { switch(act->data().toInt()) { case ChatCore::Server : conn = (m_chatCore->tcpReceiver()->state() == QAbstractSocket::ConnectedState); m_connectToServerAct->setVisible(!conn); m_disconnectFromServerAct->setVisible(conn); break; case ChatCore::Serverless : m_connectToServerAct->setVisible(false); m_disconnectFromServerAct->setVisible(false); } foreach(ChannelWgt* cw, channels()) cw->slot_refreshUL(); } } UserInfo* ChatWgt::findUser(quint64 uid) { UserWgt* usr; foreach(ChannelWgt* cw, mw_channels) if((usr = cw->findUser(uid))) return usr->info(); return NULL; } void ChatWgt::setIcons() { m_showSettingsAct ->setIcon(QChatIcon::icon("personal")); m_showPreferencesAct->setIcon(QChatIcon::icon("configure")); m_exitAct ->setIcon(QChatIcon::icon("application-exit")); m_showSmilesAct ->setIcon(QChatIcon::icon("emotes")); m_addChannelAct ->setIcon(QChatIcon::icon("tab-new")); m_delChannelAct ->setIcon(QChatIcon::icon("tab-close")); m_aboutAct ->setIcon(QChatIcon::icon("help-about")); m_aboutQtAct ->setIcon(QChatIcon::icon("help-about")); m_licenseAct ->setIcon(QChatIcon::icon("help-about")); m_writeSettingsAct ->setIcon(QChatIcon::icon("write-settings")); m_addProfileAct ->setIcon(QChatIcon::icon("add-profile")); m_deleteProfileAct ->setIcon(QChatIcon::icon("remove-profile")); m_renameProfileAct ->setIcon(QChatIcon::icon("edit-rename")); } void ChatWgt::setToolbarsIconsSize() { QAction* act = qobject_cast(sender()); if(act) { int sz = act->data().toInt(); if(!sz) sz = QStyle::PM_ToolBarIconSize; foreach(QToolBar* tb, m_toolbars) tb->setIconSize(QSize(sz, sz)); QChatSettings::settings()->setToolbarIconsSize(sz); } } void ChatWgt::setToolButtonsStyle() { QAction* act = qobject_cast(sender()); if(act) { Qt::ToolButtonStyle style = (Qt::ToolButtonStyle)(act->data().toInt()); foreach(QToolBar* tb, m_toolbars) tb->setToolButtonStyle(style); } } void ChatWgt::addToolbar(QToolBar* tb) { m_toolbars.append(tb); addToolBar(tb); } void ChatWgt::changeIconFormat(const UserListIconFormat & fmt) { *(QChatSettings::settings()->iconFormat()) = fmt; foreach(ChannelWgt* ch, channels()) ch->redrawIcons(); } void ChatWgt::showConfigureShortcuts() { ShortcutsEditor* dlg = new ShortcutsEditor(0); dlg->resize(800, 600); dlg->exec(); delete dlg; updateShortcuts(); m_chatCore->saveSettings(true); } void ChatWgt::updateShortcuts() { QChatSettings* prefs = QChatSettings::settings(); m_showSingleMessagesAct->setShortcut(prefs->shortcut("SingleMessagesHistory")); m_showSettingsAct ->setShortcut(prefs->shortcut("EditUserDetails")); m_showPreferencesAct ->setShortcut(prefs->shortcut("ConfigureQChat")); m_exitAct ->setShortcut(prefs->shortcut("Quit")); m_showSmilesAct ->setShortcut(prefs->shortcut("ShowSmiles")); m_addChannelAct ->setShortcut(prefs->shortcut("AddChannel")); m_delChannelAct ->setShortcut(prefs->shortcut("DelChannel")); m_addProfileAct ->setShortcut(prefs->shortcut("AddProfile")); m_deleteProfileAct ->setShortcut(prefs->shortcut("DelProfile")); m_renameProfileAct ->setShortcut(prefs->shortcut("RenameProfile")); m_broadcastMessageAct ->setShortcut(prefs->shortcut("BroadcastMessage")); m_smhView->updateShortcuts(); } void ChatWgt::sendBroadcastMessage() { SingleMessageWgt* smw = new SingleMessageWgt(tr("Broadcast Message"), "", QChatSettings::settings()->broadcast().toIPv4Address(), QHostAddress("255.255.255.255") ); connect(smw , SIGNAL(singleMessage (QString, quint64, bool)), this, SIGNAL(singleMessage (QString, quint64, bool))); smw->show(); } void ChatWgt::loadPlugin(const QString & path) { qDebug("![ChatWgt::loadPlugin]: loading '%s'\n", path.toAscii().data()); m_chatCore->pluginManager()->load(path); Plugin* loader = m_chatCore->pluginManager()->getPluginByPath(path); QChatWidgetPlugin* pluginWgt = NULL; QChatBasicPlugin* plugin = NULL; if(loader) { pluginWgt = loader->instanceWgt(); if(!pluginWgt) plugin = loader->instanceBasic(); else plugin = pluginWgt; if(loader->isLoaded() && plugin) { plugin->setPath(loader->path()); m_allPlugins.append(loader->instance()); m_preferencesDlg->addSection(plugin->settingsPage(), plugin->name()); if(pluginWgt) { // m_pluginsTabs->addTab(pluginWgt->widget(), pluginWgt->name()); mw_tabs->addTab(pluginWgt->widget(), pluginWgt->name()); setupPluginToolBar(m_pluginsTabs->currentWidget()); } } } } void ChatWgt::unloadPlugin(const QString & path) { qDebug("![ChatWgt::unloadPlugin]: unloading '%s'\n", path.toAscii().data()); setupPluginToolBar(NULL); QChatBasicPlugin* plugin; Plugin* loader = m_chatCore->pluginManager()->getPluginByPath(path); if(loader) { plugin = loader->instanceBasic(); if(plugin) m_preferencesDlg->removeSection(plugin->settingsPage()); } m_chatCore->pluginManager()->unload(path); setupPluginToolBar(m_pluginsTabs->currentWidget()); } void ChatWgt::keyPressEvent(QKeyEvent* ev) { QKeySequence seq = ev->key() + ev->modifiers(); QWidget::keyPressEvent(ev); } void ChatWgt::setAnimationsRunning(bool b) { foreach(ChannelWgt* cw, mw_channels) cw->setAnimationsRunning(b); } void ChatWgt::setMode() { QAction* act = qobject_cast(sender()); if(act) m_chatCore->initMode((ChatCore::Mode)act->data().toInt()); if((ChatCore::Mode)act->data().toInt() == ChatCore::Server && !m_chatCore->loggedIn()) connect2server(); } qchat-0.3/src/singlemessage.h0000644000076500017500000000326110773233761014774 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SINGLEMESSAGE_H #define SINGLEMESSAGE_H #include class SingleMessageWgt; /** @author Anistratov Oleg */ class SingleMessage : public Message { private: SingleMessageWgt* m_messageWgt; bool m_isNew; public: SingleMessage(QC_DatagramHeader* Hdr = 0, quint64 = 0); ~SingleMessage(); void setMessageWgt( SingleMessageWgt* theValue ){m_messageWgt = theValue;} SingleMessageWgt* messageWgt() const {return m_messageWgt;} bool activate(); void setOld(){m_isNew = false;} void setNew(){m_isNew = true;} bool isNew() const {return m_isNew;} }; #endif qchat-0.3/src/option.cpp0000644000076500017500000000230511002366363013776 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "option.h" Option::Option(QVariant o, QString s, OptionType t) : m_option(o), m_section(s), m_type(t) { } Option::~Option() { } qchat-0.3/src/userslist.cpp0000755000076500017500000001466311002603747014540 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "userslist.h" #include #include #include "userinfo.h" #include "userwgt.h" UsersList::UsersList() : m_users (NULL), m_usersNum (0), m_maxUsersNum (1024), m_hiddenUsers (NULL), m_hiddenUsersNum (0), m_maxHiddenUsersNum(1024) { m_users = (UserWgt**)malloc(m_maxUsersNum * sizeof(UserWgt*)); assert(NULL != m_users); m_hiddenUsers = (UserWgt**)malloc(m_maxHiddenUsersNum * sizeof(UserWgt*)); assert(NULL != m_hiddenUsers); } //\***************************************************************************** UsersList::~UsersList() { qDebug("[~UsersList]\n"); free(m_users); free(m_hiddenUsers); } //\***************************************************************************** void UsersList::addUser(UserWgt* user) { if(exists(user->info()->uid())) return; qDebug("[UsersList::addUser] uid = %s\n", QHostAddress(user->info()->ip()).toString().toAscii().data()); if(++m_usersNum >= m_maxUsersNum) { m_maxUsersNum += 1024; m_users = (UserWgt**)realloc(m_users, m_maxUsersNum * sizeof(UserWgt*)); assert(NULL != m_users); } m_users[m_usersNum - 1] = user; } //\***************************************************************************** UserWgt* UsersList::findUser(quint64 uid) const { for(uint i = 0; i < m_usersNum; i++) if(m_users[i]->info()->uid() == uid) return m_users[i]; return NULL; } UserWgt* UsersList::findHidden(quint64 uid) const { for(uint i = 0; i < m_hiddenUsersNum; i++) if(m_users[i]->info()->uid() == uid) return m_hiddenUsers[i]; return NULL; } qint32 UsersList::findNum(quint64 uid) const { for(uint i = 0; i < m_usersNum; i++) if(m_users[i]->info()->uid() == uid) return i; return -1; } //\***************************************************************************** UserWgt* UsersList::enable(quint64 uid) { uint num; for(num = 0; num < m_hiddenUsersNum; num++) if(m_hiddenUsers[num]->info()->uid() == uid) break; if(num >= m_hiddenUsersNum) { for(num = 0; num < m_usersNum; num++) if(m_users[num]->info()->uid() == uid) break; if(num >= m_usersNum) return NULL; else return m_users[num]; } if(++m_usersNum >= m_maxUsersNum) { m_maxUsersNum += 1024; m_users = (UserWgt**)realloc(m_users, m_maxUsersNum * sizeof(UserWgt*)); assert(NULL != m_users); } m_users[m_usersNum - 1] = m_hiddenUsers[num]; m_hiddenUsers[num]->info()->setEnabled(true); m_hiddenUsers[num] = m_hiddenUsers[--m_hiddenUsersNum]; return m_users[m_usersNum - 1]; } //\***************************************************************************** UserWgt* UsersList::disable(quint64 uid) { int num = findNum(uid); if(num < 0) return NULL; if(++m_hiddenUsersNum >= m_maxHiddenUsersNum) { m_maxHiddenUsersNum += 1024; m_hiddenUsers = (UserWgt**)realloc(m_hiddenUsers, m_maxHiddenUsersNum * sizeof(UserWgt*)); assert(NULL != m_hiddenUsers); } m_hiddenUsers[m_hiddenUsersNum - 1] = m_users[num]; m_users[num]->info()->setEnabled(false); m_users[num] = m_users[--m_usersNum]; return m_hiddenUsers[m_hiddenUsersNum - 1]; } //\***************************************************************************** void UsersList::disableAll() { qDebug("[UsersList::disableAll]"); uint i, j; for(i = 0; i < m_usersNum; i++) m_users[i]->info()->setEnabled(false); i = m_hiddenUsersNum; m_hiddenUsersNum += m_usersNum; if(m_hiddenUsersNum >= m_maxHiddenUsersNum) { m_maxHiddenUsersNum += 1024; m_hiddenUsers = (UserWgt**)realloc(m_hiddenUsers, m_maxHiddenUsersNum * sizeof(UserWgt*)); assert(NULL != m_hiddenUsers); } for(j = 0; i < m_hiddenUsersNum && j < m_usersNum; i++, j++) m_hiddenUsers[i] = m_users[j]; m_usersNum = 0; } //\***************************************************************************** void UsersList::enableAll() { qDebug("[UsersList::enableAll]"); uint i, j; i = m_usersNum; m_usersNum += m_hiddenUsersNum; if(m_usersNum >= m_maxUsersNum) { m_maxUsersNum += 1024; m_users = (UserWgt**)realloc(m_users, m_maxUsersNum * sizeof(UserWgt*)); assert(NULL != m_users); } for(j = 0; j < m_hiddenUsersNum && i < m_usersNum; i++, j++) m_users[i] = m_hiddenUsers[j]; m_hiddenUsersNum = 0; for(i = 0; i < m_usersNum; i++) m_users[i]->info()->setEnabled(true); } //\***************************************************************************** bool UsersList::enabled(quint64 uid) const { UserWgt* usr = findUser(uid); return (usr && usr->info()->enabled()); } //\***************************************************************************** bool UsersList::exists(quint64 uid) const { for(uint i = 0; i < m_usersNum; i++) if(m_users[i]->info()->uid() == uid) return true; for(uint i = 0; i < m_hiddenUsersNum; i++) if(m_hiddenUsers[i]->info()->uid() == uid) return true; return false; } //\***************************************************************************** UserWgt* UsersList::user(int n) const { Q_ASSERT(n >= 0); if(n < (int)m_usersNum) return m_users[n]; return NULL; } UserWgt* UsersList::enableIfExists(quint64 uid) { uint i; for(i = 0; i < m_hiddenUsersNum; i++) if(m_hiddenUsers[i]->info()->uid() == uid) return enable(uid); for(i = 0; i < m_usersNum; i++) if(m_users[i]->info()->uid() == uid) return enable(uid); return NULL; } qchat-0.3/src/filtrationruleeditor.cpp0000644000076500017500000001120011001121632016715 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "filtrationruleeditor.h" #include #include "filtrationrule.h" FiltrationRuleEditor::FiltrationRuleEditor(QWidget *parent) : QDialog(parent), m_edited(false), m_rule(NULL) { QGridLayout* grid = new QGridLayout(this); m_nameEdit = new QLineEdit(this); m_userNamesEdit = new QTextEdit(this); m_compNamesEdit = new QTextEdit(this); m_IPsEdit = new QTextEdit(this); m_messageFilterEdit = new QTextEdit(this); m_isRegExpChbx = new QCheckBox(tr("Regular Expression"), this); m_okBtn = new QPushButton(tr("Ok") , this); m_applyBtn = new QPushButton(tr("Apply") , this); m_cancelBtn = new QPushButton(tr("Cancel"), this); grid->addWidget(new QLabel(tr("Rule name :")), 0, 0); grid->addWidget(m_nameEdit , 0, 1, 1, 2); grid->addWidget(new QLabel(tr("User(s) to ignore :")) , 1, 0, 1, 3); grid->addWidget(m_userNamesEdit , 2, 0, 1, 3); grid->addWidget(new QLabel(tr("Computer name(s) to ignore :")), 3, 0, 1, 3); grid->addWidget(m_compNamesEdit , 4, 0, 1, 3); grid->addWidget(new QLabel(tr("IP address(es) to ignore :")) , 5, 0, 1, 3); grid->addWidget(m_IPsEdit , 6, 0, 1, 3); grid->addWidget(new QLabel(tr("Message filter(one word per line or regular expression):")), 7, 0, 1, 3); grid->addWidget(m_messageFilterEdit , 8, 0, 1, 3); grid->addWidget(m_isRegExpChbx , 9, 0, 1, 3); grid->addWidget(m_okBtn , 10, 0); grid->addWidget(m_applyBtn , 10, 1); grid->addWidget(m_cancelBtn , 10, 2); setWindowTitle(tr("Filtration Rule Editor")); m_applyBtn->setEnabled(false); connect(m_nameEdit , SIGNAL(textEdited (QString)), this, SLOT(edited())); connect(m_userNamesEdit , SIGNAL(textChanged()), this, SLOT(edited())); connect(m_compNamesEdit , SIGNAL(textChanged()), this, SLOT(edited())); connect(m_IPsEdit , SIGNAL(textChanged()), this, SLOT(edited())); connect(m_messageFilterEdit , SIGNAL(textChanged()), this, SLOT(edited())); connect(m_isRegExpChbx , SIGNAL(stateChanged(int)), this, SLOT(edited())); connect(m_okBtn , SIGNAL(clicked()), this, SLOT(saveRule())); connect(m_okBtn , SIGNAL(clicked()), this, SLOT(accept())); connect(m_applyBtn , SIGNAL(clicked()), this, SLOT(saveRule())); connect(m_cancelBtn, SIGNAL(clicked()), this, SLOT(reject())); } FiltrationRuleEditor::~FiltrationRuleEditor() { } void FiltrationRuleEditor::init(FiltrationRule* rule) { m_rule = rule; m_nameEdit ->setText(m_rule->name()); m_userNamesEdit ->setText(m_rule->userNames()); m_compNamesEdit ->setText(m_rule->compNames()); m_IPsEdit ->setText(m_rule->IPs()); m_messageFilterEdit->setText(m_rule->messageFilter()); m_isRegExpChbx ->setCheckState(m_rule->isRegExp() ? Qt::Checked : Qt::Unchecked ); } void FiltrationRuleEditor::saveRule() { if(m_edited && m_rule) { m_rule->setName (m_nameEdit ->text()); m_rule->setUserNames (m_userNamesEdit ->toPlainText()); m_rule->setCompNames (m_compNamesEdit ->toPlainText()); m_rule->setIPs (m_IPsEdit ->toPlainText()); m_rule->setMessageFilter(m_messageFilterEdit->toPlainText()); m_rule->setIsRegExp (m_isRegExpChbx->checkState() == Qt::Checked); } m_edited = false; m_applyBtn->setEnabled(false); } qchat-0.3/src/inputtextwgt.h0000644000076500017500000000423110767343647014742 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef INPUTTEXTWGT_H #define INPUTTEXTWGT_H #include #include #include /** @author Anistratov Oleg */ class InputTextWgt : public QTextEdit { Q_OBJECT private: static QString Chars_US; static QString Chars_UA; static QString Chars_RU; static bool inited; QString m_currentMsg; QString** m_msgHistory; quint16 m_msgsSize; quint16 m_currentMsgNumber; int m_current; void nextMsg (); void prevMsg (); void addMsg (const QString &); public: InputTextWgt(QWidget *parent = 0); ~InputTextWgt(){qDebug("[InputTextWgt::~InputTextWgt]");} static void initChars(const QString &); protected: void keyPressEvent(QKeyEvent* ev); // void wheelEvent (QWheelEvent* ev) // { // if (ev->delta() > 0) prevMsg(); // else if(ev->delta() < 0) nextMsg(); // } public slots: void changeTextCharMap(); void sendMsg (); void append (const QString & str){insertPlainText(str);} signals: void wantSend(); }; #endif qchat-0.3/src/filetransferwgt.cpp0000644000076500017500000001670010772536733015715 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "filetransferwgt.h" #include FileTransferWgt::FileTransferWgt(const QString & filename_, bool receiving_, QWidget *parent) : QWidget(parent), m_id (0), m_uid (0), m_ip (0), m_filename (filename_), m_finished (false), m_receiving(receiving_), m_accepted (false) { } //\***************************************************************************** FileTransferWgt::~FileTransferWgt() { qDebug("[~FileTransferWgt]"); } //\***************************************************************************** void FileTransferWgt::retranslate() { m_cancelBtn ->setText(tr("&Cancel")); m_acceptBtn ->setText(tr("&Accept")); m_rejectBtn ->setText(tr("&Reject")); m_autoCloseChbx ->setText(tr("Auto close when complete")); if(!m_receiving) setWindowTitle(QString(tr("Sending " )) + m_filename); else setWindowTitle(QString(tr("Receiving ")) + m_filename); } //\***************************************************************************** void FileTransferWgt::slot_accept() { qDebug("[FileTransferWgt::slot_accept]"); QString filename = QFileDialog::getSaveFileName( this, tr("Choose a file to save"), QString("/") + m_filename, ""); if(filename.isEmpty()) return; m_filenameLab->setText(tr("Receiving: %1\nSender: %2(%3)").arg(filename).arg(m_userName).arg(QHostAddress(m_ip).toString())); m_filename = filename; m_grid ->removeWidget(m_acceptBtn); m_grid ->removeWidget(m_rejectBtn); m_acceptBtn->hide(); m_rejectBtn->hide(); m_grid ->addWidget(m_autoCloseChbx, 2, 0, 1, 2); m_grid ->addWidget(m_cancelBtn , 3, 0, 1, 2); m_autoCloseChbx->show(); m_cancelBtn ->show(); m_accepted = true; emit accepted(m_filename, m_id, m_uid); } //\***************************************************************************** void FileTransferWgt::slot_reject() { qDebug("[FileTransferWgt::slot_reject] ip = %lu", (unsigned long) m_uid); if(!m_receiving) { emit rejected(m_id, m_uid, 2); emit cancel (m_id); } if(!m_finished) emit rejected(m_id, m_uid, m_accepted); slot_selfDestroy(); } //\***************************************************************************** void FileTransferWgt::slot_selfDestroy() { hide(); this->~FileTransferWgt(); } //\***************************************************************************** void FileTransferWgt::slot_setProgress(quint8 progress, quint16 id, quint64 uid) { if(!m_finished && m_id == id && (!m_receiving || uid == m_uid)) { m_progress->setValue(100 - progress); if(progress == 0) { m_finished = true; if(m_autoCloseChbx->checkState() == Qt::Checked) slot_selfDestroy(); else { m_progress->setFormat(tr("Completed (%p%)")); m_progress->repaint(); m_cancelBtn->setText(tr("Close")); } } } } //\***************************************************************************** void FileTransferWgt::slot_cancelledByReceiver(quint16 id) { if(!m_finished && id == m_id) { m_progress->setFormat(tr("Failed: cancelled by receiver(%p%)")); m_progress->repaint(); m_finished = true; } } //\***************************************************************************** void FileTransferWgt::slot_cancelledBySender(quint16 id, quint64 ip) { if(!m_finished && id == m_id && ip == m_uid && !m_finished) { m_progress->setFormat(tr("Failed: cancelled by sender (%p%)")); m_progress->repaint(); m_finished = true; } } //\***************************************************************************** void FileTransferWgt::slot_cannotSend(quint16 id) { if(!m_finished && id == m_id) { m_progress->setFormat(tr("Failed: cannot send file")); m_progress->repaint(); m_finished = true; } } //\***************************************************************************** void FileTransferWgt::slot_rejectedByReceiver (quint16 id) { if(!m_finished && id == m_id) { m_progress->setFormat(tr("Failed: rejected by receiver")); m_progress->repaint(); m_finished = true; } } //\***************************************************************************** void FileTransferWgt::slot_receivingTimeout(quint16 id, quint64 ip) { if(!m_finished && id == m_id && ip == m_uid) { m_progress->setFormat(tr("Failed: receiving timeout (%p%)")); m_progress->repaint(); m_finished = true; } } //\***************************************************************************** void FileTransferWgt::slot_sendingTimeout(quint16 id) { if(!m_finished && id == m_id) { m_progress->setFormat(tr("Possibly failed: sending finished but only %p% confirmed")); m_progress->repaint(); m_finished = true; } } //\***************************************************************************** void FileTransferWgt::init() { m_grid = new QGridLayout (this); m_cancelBtn = new QPushButton (this); m_acceptBtn = new QPushButton (this); m_rejectBtn = new QPushButton (this); m_progress = new QProgressBar(this); m_autoCloseChbx = new QCheckBox (this); m_filenameLab = new QLabel (m_filename, this); if(!m_receiving) { m_grid->addWidget(m_filenameLab , 0, 0, 1, 2); m_grid->addWidget(m_progress , 1, 0, 1, 2); m_grid->addWidget(m_autoCloseChbx , 2, 0, 1, 2); m_grid->addWidget(m_cancelBtn , 3, 0, 1, 2); m_acceptBtn->hide(); m_rejectBtn->hide(); m_filenameLab->setText(tr("Sending: %1\nReceiver: %2(%3)").arg(m_filename).arg(m_userName).arg(QHostAddress(m_ip).toString())); } else { m_grid->addWidget(m_filenameLab , 0, 0, 1, 2); m_grid->addWidget(m_progress , 1, 0, 1, 2); m_grid->addWidget(m_acceptBtn , 2, 0); m_grid->addWidget(m_rejectBtn , 2, 1); m_cancelBtn ->hide(); m_autoCloseChbx->hide(); m_filenameLab->setText(tr("Receiving: %1\nSender: %2(%3)").arg(m_filename).arg(m_userName).arg(QHostAddress(m_ip).toString())); } m_progress->setMinimumHeight(25); setMinimumWidth (300); m_progress->setTextVisible(true); m_progress->setValue(0); connect(m_cancelBtn, SIGNAL(clicked()), this, SLOT(slot_reject ())); connect(m_acceptBtn, SIGNAL(clicked()), this, SLOT(slot_accept ())); connect(m_rejectBtn, SIGNAL(clicked()), this, SLOT(slot_reject ())); retranslate(); show(); } qchat-0.3/src/inputtextwgt.cpp0000644000076500017500000001345210772032343015262 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "inputtextwgt.h" #include #include #include #include #include #include #include "qchatsettings.h" static QString Chars_US(""); static QString Chars_UA(""); static QString Chars_RU(""); static bool inited = false; InputTextWgt::InputTextWgt(QWidget *parent) : QTextEdit(parent), m_currentMsg (""), m_msgHistory (NULL), m_msgsSize (0), m_currentMsgNumber(1), m_current (0) { } //\***************************************************************************** void InputTextWgt::initChars(const QString & filename) { QByteArray ba; QFile file(filename); if(!::inited && file.open(QIODevice::ReadOnly)) { ba = file.readLine(); ::Chars_US = QString::fromUtf8(ba.data(), ba.size()); ba = file.readLine(); ::Chars_RU = QString::fromUtf8(ba.data(), ba.size()); ba = file.readLine(); ::Chars_UA = QString::fromUtf8(ba.data(), ba.size()); } ::inited = true; } //\***************************************************************************** void InputTextWgt::changeTextCharMap() // TODO rewrite { QString str = toPlainText(); QTextCursor tc = textCursor(); int i; QString original; QString replace; switch(m_current) { case 0 : original = ::Chars_US; if(!::Chars_UA.isEmpty()){ replace = ::Chars_UA; m_current = 1; } else if(!::Chars_RU.isEmpty()){ replace = ::Chars_RU; m_current = 2; } else m_current = -1; break; case 1 : original = ::Chars_UA; if(!::Chars_RU.isEmpty()){ replace = ::Chars_RU; m_current = 2; } else if(!::Chars_US.isEmpty()){ replace = ::Chars_US; m_current = 0; } else m_current = -1; break; case 2 : original = ::Chars_RU; if(!::Chars_US.isEmpty()){ replace = ::Chars_US; m_current = 0; } else if(!::Chars_UA.isEmpty()){ replace = ::Chars_UA; m_current = 1; } else m_current = -1; break; } if(m_current < 0) return; for(i = 0; i < str.size(); i++) if(original.contains(str[i])) str[i] = replace[original.indexOf(str[i])]; setPlainText(str); setTextCursor(tc); } //\***************************************************************************** void InputTextWgt::keyPressEvent(QKeyEvent* ev) { QKeySequence seq = ev->key() + ev->modifiers(); if(QChatSettings::settings()->shortcuts("SendMessage").contains(seq)) sendMsg(); // FIXME shortcuts("SendMessage") can contain QKeySequence("Ctrl+Return") also else if(QChatSettings::settings()->shortcuts("SendMessage").contains(QKeySequence("Return")) && QKeySequence("Ctrl+Return") == seq) insertPlainText("\n"); else if(QChatSettings::settings()->shortcuts("ChangeTextCharMap").contains(seq)) changeTextCharMap(); else if(QChatSettings::settings()->shortcuts("NextMessage").contains(seq)) nextMsg(); else if(QChatSettings::settings()->shortcuts("PrevMessage").contains(seq)) prevMsg(); else if((ev->key() == Qt::Key_Tab)) QWidget::keyPressEvent(ev); else QTextEdit::keyPressEvent(ev); } //\***************************************************************************** void InputTextWgt::nextMsg() { if(m_currentMsgNumber + 1 >= 0 && m_currentMsgNumber + 1 < m_msgsSize) { m_currentMsgNumber++; setHtml(*m_msgHistory[m_currentMsgNumber]); } else if(m_currentMsgNumber + 1 == m_msgsSize) { m_currentMsgNumber++; setHtml(m_currentMsg); } } //\***************************************************************************** void InputTextWgt::prevMsg () { if(m_currentMsgNumber == m_msgsSize) m_currentMsg = toHtml(); if(m_currentMsgNumber - 1 >= 0 && m_currentMsgNumber - 1 < m_msgsSize) { m_currentMsgNumber--; setHtml(*m_msgHistory[m_currentMsgNumber]); } } //\***************************************************************************** void InputTextWgt::addMsg(const QString & msg) { quint16 i; if(msg.isEmpty()) return; if(m_msgHistory != NULL) for(i = 0; i < m_msgsSize; i++) if(*m_msgHistory[i] == msg) { *m_msgHistory[i] = *m_msgHistory[m_msgsSize - 1]; *m_msgHistory[m_msgsSize - 1] = msg; return; } ++m_msgsSize; m_msgHistory = (QString**)realloc(m_msgHistory, m_msgsSize * sizeof(QString*)); assert(NULL != m_msgHistory); m_msgHistory[m_msgsSize - 1] = new QString(msg); } //\***************************************************************************** void InputTextWgt::sendMsg() { // addMsg(toPlainText()); addMsg(toHtml()); m_currentMsgNumber = m_msgsSize; emit wantSend(); } qchat-0.3/src/singlemsgshistoryview.h0000644000076500017500000000645210777005111016631 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SINGLEMSGSHISTORYVIEW_H #define SINGLEMSGSHISTORYVIEW_H #include #include #include #include #include #include #include #include #include #include "singlemessagewgt.h" class SingleMessage; class SingleMsgsHistoryModel; /** @author Anistratov Oleg */ class SingleMsgsHistoryView : public QWidget { Q_OBJECT private: QTreeView* m_treeView; QComboBox* m_layoutCmbx; SingleMsgsHistoryModel* m_model; QLabel* m_viewFormatLab; QToolButton* m_nextNewMessageBtn; QToolButton* m_prevNewMessageBtn; QToolButton* m_nextOpenedMessageBtn; QToolButton* m_prevOpenedMessageBtn; QToolButton* m_closeAllNewMessagesBtn; QToolButton* m_closeAllOpenedMessagesBtn; QCheckBox* m_currentCloseChbx; QAction* m_nextNewMessageAct; QAction* m_prevNewMessageAct; QAction* m_nextOpenedMessageAct; QAction* m_prevOpenedMessageAct; QAction* m_closeAllNewMessagesAct; QAction* m_closeAllOpenedMessagesAct; public: SingleMsgsHistoryView(QWidget *parent = 0); ~SingleMsgsHistoryView(); void resizeColumnToContents(int col){m_treeView->resizeColumnToContents(col);} void setModel(QAbstractItemModel* model); void retranslate(); void updateShortcuts(); void update(); public slots: void setTreeLayout(int); void sort(int, Qt::SortOrder); void nextNewMessage() {SingleMessageWgt::nextPrevNewMessage(1, m_currentCloseChbx->checkState() == Qt::Checked); update();} void prevNewMessage() {SingleMessageWgt::nextPrevNewMessage(-1, m_currentCloseChbx->checkState() == Qt::Checked); update();} void nextOpenedMessage() {SingleMessageWgt::nextPrevOpenedMessage(1, m_currentCloseChbx->checkState() == Qt::Checked); update();} void prevOpenedMessage() {SingleMessageWgt::nextPrevOpenedMessage(-1, m_currentCloseChbx->checkState() == Qt::Checked); update();} void closeAllNewMessages() {SingleMessageWgt::closeAllNewMessages(); update();} void closeAllOpenedMessages(){SingleMessageWgt::closeAllOpenedMessages(); update();} signals: void doubleClicked(const QModelIndex&); }; #endif qchat-0.3/src/receiverthread.cpp0000644000076500017500000002573111002651142015462 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include #include #include "largedatagram.h" #include "receiverthread.h" #include "abstractchatcore.h" ReceiverThread::ReceiverThread(QObject *parent) : QThread (parent), m_opened (false), m_finished (false), m_datagrams (NULL), m_datagramsNum (0), m_datagramsMaxNum(0), m_bufferSize (65535), m_socket (NULL), m_socketNotifier (NULL), m_port (61108) { qDebug("[ReceiverThread]: constructor begin"); moveToThread(this); m_buffer = (char*)malloc(m_bufferSize); assert(NULL != m_buffer); qDebug("[ReceiverThread]: constructor end"); } //\***************************************************************************** ReceiverThread::~ReceiverThread() { qDebug("[~ReceiverThread]"); delete m_socketNotifier; free(m_buffer); } //\***************************************************************************** void ReceiverThread::run() { m_socket = new QUdpSocket(this); exec(); } //\***************************************************************************** void ReceiverThread::changePort(quint16 port_) { Q_ASSERT(currentThread() == this); qDebug("[ReceiverThread::setPort]: port = %d", port_); if(m_opened) m_socket->close(); qDebug("[ReceiverThread::setPort]: closed"); m_opened = false; m_port = port_; m_opened = m_socket->bind(m_port); qDebug("[ReceiverThread::setPort]: opened = %d", m_opened); if(m_opened == 0) { emit openSocketError(port_); return; } if(m_socketNotifier) disconnect(m_socketNotifier, SIGNAL(activated(int)), this, SLOT(receiving())); delete m_socketNotifier; m_socketNotifier = NULL; m_socketNotifier = new QSocketNotifier(m_socket->socketDescriptor(), QSocketNotifier::Read, this); connect(m_socketNotifier, SIGNAL(activated(int)), this, SLOT(receiving())); } //\***************************************************************************** LargeDatagram* ReceiverThread::findDatagram(quint64 IP, quint32 ID) const { for(quint32 i = 0; i < m_datagramsNum; i++) if(m_datagrams[i]->cmp(IP, ID)) return m_datagrams[i]; return NULL; } //\***************************************************************************** void ReceiverThread::removeDatagram(LargeDatagram* dtgrm) { if(!dtgrm) return; for(quint32 i = 0; i < m_datagramsNum; i++) if(m_datagrams[i] == dtgrm) { --m_datagramsNum; m_datagrams[i] = m_datagrams[m_datagramsNum]; } } //\***************************************************************************** LargeDatagram* ReceiverThread::addDatagram(quint64 IP, quint32 ID) { Q_ASSERT(currentThread() == this); LargeDatagram* dtgrm = new LargeDatagram(IP, ID, this); LargeDatagram** tmp; dtgrm->moveToThread(this); qDebug("[ReceiverThread::addDatagram]: adding(%lu, %lu)", (unsigned long)IP, (unsigned long)ID); if(dtgrm) { m_datagramsNum++; if(m_datagramsMaxNum < m_datagramsNum) { m_datagramsMaxNum++; tmp = (LargeDatagram**)realloc(m_datagrams, m_datagramsMaxNum * sizeof(LargeDatagram*)); if(!tmp) { delete dtgrm; return NULL; } m_datagrams = tmp; } m_datagrams[m_datagramsNum - 1] = dtgrm; connect(dtgrm, SIGNAL( wantDie(LargeDatagram*)), this, SLOT(deleteDatagram(LargeDatagram*))); connect(dtgrm, SIGNAL(completed(LargeDatagram*)), this, SLOT(deleteDatagram(LargeDatagram*))); connect(dtgrm, SIGNAL(wantFragments(char*, quint32, quint32, quint64)), this, SIGNAL(wantFragments(char*, quint32, quint32, quint64))); connect(dtgrm, SIGNAL(percentsRemain(quint8, quint16, quint64)), this, SIGNAL(percentsRemain(quint8, quint16, quint64))); connect(dtgrm, SIGNAL(readyReceive (quint16, quint64)), this, SIGNAL(readyReceive (quint16, quint64))); } return dtgrm; } //\***************************************************************************** quint32 ReceiverThread::getValidID(quint64 IP) const { for(quint32 i = 1; i > 0; i++) if(!findDatagram(IP, i)) return i; return 0; } //\***************************************************************************** void ReceiverThread::receiving() { quint32 dtgrmNum; quint32 dtgrmID; quint64 sender_uid; // IP for serverless mode or UserID for server mode int dataSize; LargeDatagram* dtgrm; quint8 type; char* buffer = m_buffer; m_opened = true; if(m_opened) { if((dataSize = readData(m_buffer, m_bufferSize)) <= 0) qWarning("[ReceiverThread::receiving]: Cannot read data from socket(return code = %d)", dataSize); else { if(dataSize >= (int)AbstractChatCore::protocolLen() && AbstractChatCore::checkProtocolVersion(m_buffer)) { if(AbstractChatCore::compressed(m_buffer)) { uint size = dataSize; buffer = AbstractChatCore::uncompress((const char*)m_buffer, size); dataSize = size; if(!buffer) return; AbstractChatCore::setProgramVersion(buffer); } else buffer = m_buffer; type = AbstractChatCore::packetType(buffer); sender_uid = AbstractChatCore::srcIp (buffer); dtgrmID = AbstractChatCore::packetId (buffer); dtgrmNum = AbstractChatCore::packetNum (buffer); // qDebug("[ReceiverThread::run]: sender_uid = %s", QHostAddress(sender_uid).toString().toAscii().data()); if(type == AbstractChatCore::SINGLE_MESSAGE) qDebug("[ReceiverThread::run]: SINGLE_MESSAGE"); if(type == AbstractChatCore::FRAGMENTS_REQUEST) { qDebug("[ReceiverThread::run]: FRAGMENTS_REQUEST"); emit fragmentsRequest(buffer, dataSize); } else if(type == AbstractChatCore::FINISHED) { qDebug("[ReceiverThread::run]: FINISHED!"); // emit dtgrmFinished(dtgrmID); } else if(dtgrmID != 0) { switch(type) { case AbstractChatCore::CONFIRM : qDebug("[ReceiverThread::run]: CONFIRM| dtgrmID = %d, dtgrmNum = %d", dtgrmID, dtgrmNum); emit percentsConfirmed(dtgrmNum, dtgrmID, sender_uid); break; case AbstractChatCore::ACCEPT: qDebug("[ReceiverThread::run]: ACCEPT"); emit receivingAccepted(dtgrmID); break; case AbstractChatCore::REJECT: qDebug("[ReceiverThread::run]: REJECT"); qDebug("[ReceiverThread::run]: reason = %d", dtgrmNum); if(dtgrmNum == 0) emit receivingRejected(dtgrmID); else if(dtgrmNum == 1) emit receivingCancelled(dtgrmID); else if(dtgrmNum == 2) { deleteDatagram(findDatagram(sender_uid, dtgrmID)); emit sendingCancelled(dtgrmID, sender_uid); } break; default: if(!(dtgrm = findDatagram(sender_uid, dtgrmID))) { qDebug("[ReceiverThread::run]: ADDING DATAGRAM"); dtgrm = addDatagram(sender_uid, dtgrmID); if(NULL == dtgrm) return; } if(dtgrmID != 0) { if(!dtgrmNum) { dtgrm->initDatagram(buffer, dataSize); if(type == AbstractChatCore::FILE) emit wantReceiveFile(dtgrm->filename(), dtgrmID, sender_uid); } else if(type == AbstractChatCore::FILE) { dtgrm->addFileFragment(buffer, dataSize); if(dtgrm->complete()) qDebug("[ReceiverThread::run]: File COMPLETED!"); } else { dtgrm->addFragment(buffer, dataSize); if(dtgrm->complete()) { qDebug("[ReceiverThread::run]: COMPLETED!"); emit largeDataReceived(dtgrm); } } }// default: // if(dtgrmID != 0) } // switch(type) } // else if(dtgrmID != 0) else { qDebug("[ReceiverThread::run]: DATA_RECEIVED!"); emit dataReceived(datadup(buffer, dataSize), dataSize); } }// if(dataSize >= (int)AbstractChatCore::protocolLen() && !strncmp(m_buffer, AbstractChatCore::programId(), strlen(AbstractChatCore::programId()))) } } } //\***************************************************************************** void ReceiverThread::deleteDatagram(LargeDatagram* dtgrm) { Q_ASSERT(currentThread() == this); if(!dtgrm) return; qDebug("[ReceiverThread::deleteDatagram]"); if(!dtgrm->complete()) emit receivingTimeout(dtgrm->id(), dtgrm->ip()); removeDatagram(dtgrm); delete dtgrm; } //\***************************************************************************** void ReceiverThread::slot_acceptDatagram(const QString & filename, quint16 ID, quint64 IP) { qDebug("[ReceiverThread::slot_acceptDatagram]"); LargeDatagram* dtgrm = findDatagram(IP, ID); if(dtgrm) dtgrm->slot_initFile(filename); else qWarning("[ReceiverThread::slot_acceptDatagram]: [error] dtgrm is NULL"); } //\***************************************************************************** void ReceiverThread::slot_rejectDatagram(quint16 ID, quint64 IP) { deleteDatagram(findDatagram(IP, ID)); } int ReceiverThread::readData(char* buffer, uint bufferSize) { int dataSize = 0; if(m_socket->hasPendingDatagrams()) { #if defined (Q_OS_WIN) m_socketNotifier->setEnabled(false); dataSize = m_socket->readDatagram(buffer, bufferSize); m_socketNotifier->setEnabled(true); #else dataSize = m_socket->readDatagram(buffer, bufferSize); #endif if(dataSize < 0) qWarning("[ReceiverThread::readData]: datagram read error"); } return dataSize; } qchat-0.3/src/userstatistics.cpp0000644000076500017500000000776710674511675015614 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "userstatistics.h" #if defined(Q_OS_LINUX) # include # include # include # include #endif #if defined(Q_OS_WIN) # include # include #endif #include #include UserStatistics::UserStatistics() : m_os(QObject::tr("Unknown", "OS")), m_uptime(-1), m_chatTime(0) { } UserStatistics::~UserStatistics() { } QString UserStatistics::OsString() { #if defined(Q_OS_LINUX) utsname buf; if(!uname(&buf)) return QString("GNU/") + buf.sysname + " (Linux " + buf.release + ")"; else return "GNU/Linux"; #else #if defined(Q_OS_MAC) switch(QSysInfo::MacintoshVersion) { case QSysInfo::MV_CHEETAH : return "MacOS 10.0(Cheetah)"; case QSysInfo::MV_PUMA : return "MacOS 10.1(Puma)"; case QSysInfo::MV_JAGUAR : return "MacOS 10.2(Jaguar)"; case QSysInfo::MV_PANTHER : return "MacOS 10.3(Panther)"; case QSysInfo::MV_TIGER : return "MacOS 10.4(Tiger)"; case QSysInfo::MV_LEOPARD : return "MacOS 10.5(Leopard)"; case QSysInfo::MV_Unknown : return "MacOS(unknown)"; default : return "MacOS(unknown)"; } #else #if defined(Q_OS_WIN) switch(QSysInfo::WindowsVersion) { case QSysInfo::WV_32s : return "Windows 3.1 with Win 32s"; case QSysInfo::WV_95 : return "Windows 95"; case QSysInfo::WV_98 : return "Windows 98"; case QSysInfo::WV_Me : return "Windows Me"; case QSysInfo::WV_NT : return "Windows NT"; case QSysInfo::WV_2000 : return "Windows 2000"; case QSysInfo::WV_XP : return "Windows XP"; case QSysInfo::WV_2003 : return "Windows Server 2003"; case QSysInfo::WV_VISTA : return "Windows Vista"; case QSysInfo::WV_CE : return "Windows CE"; case QSysInfo::WV_CENET : return "Windows CE .NET"; default : return "Windows(unknown)"; } #else return "Unknown"; #endif #endif #endif } qint32 UserStatistics::getUptime() { #if defined(Q_OS_LINUX) QFile file; QString ut; qint32 res = -1; file.setFileName("/proc/uptime"); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning("[UserStatistics::getUptime]: couldn't open /proc/uptime"); return -1; } QTextStream in(&file); ut = in.readLine(); file.close(); res = (int)(ut.split(" ")[0]).toDouble(); return res; #else #if defined(Q_OS_MAC) return -1; #else #if defined(Q_OS_WIN) return GetTickCount() / 1000; #else return -1; #endif #endif #endif } QString UserStatistics::time2string(quint64 tm) { QString str(""); qint32 s; qint32 m; qint32 h; qint32 d; d = tm / (60 * 60 * 24); tm -= d * 60 * 60 * 24; h = tm / (60 * 60); tm -= h * 60 * 60; m = tm / 60; tm -= m * 60; s = tm; if(d) str += QString().setNum(d) + QObject::tr("d ", "day"); str += QString().setNum(h) + QObject::tr("h:", "hour"); str += QString().setNum(m) + QObject::tr("m:", "minute"); str += QString().setNum(s) + QObject::tr("s", "second"); return str; } qchat-0.3/src/logwgt.h0000644000076500017500000000321510665277445013457 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef LOGWGT_H #define LOGWGT_H #include #include #include /** @author Anistratov Oleg */ class LogWgt : public QWidget { Q_OBJECT private: QTextEdit* mw_text; public: LogWgt(QWidget *parent = 0); ~LogWgt(){}; void addMessage(const QString &, const QColor & color = QColor(Qt::black)); void addInfo (const QString & msg){addMessage(QString("[Information]: ") + msg, QColor(Qt::blue));} void addError (const QString & msg){addMessage(QString("[Error]: " ) + msg, QColor(Qt::red));} }; #endif qchat-0.3/src/chatcore.cpp0000755000076500017500000010706511004454155014271 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "chatcore.h" #include #include #include #include #include #include #include #include #include "chatwgt.h" #include "channelwgt.h" #include "userinfo.h" #include "userwgt.h" #include "qchatsettings.h" #include "receiverthread.h" #include "senderthread.h" #include "largedatagram.h" #include "edituserinfodlg.h" #include "nlamarok.h" #include "userprofile.h" #include "smileswgt.h" #include "chattextwgt.h" #include "userstatistics.h" #include "singlemessage.h" #include "singlemsgshistory.h" #include "pluginsinterfaces.h" #include "pluginmanager.h" #include "tcpreceiverthread.h" #include "messagefilter.h" QTimer* ChatCore::m_chatTimer = new QTimer; ChatCore::ChatCore(QObject* parent) : QThread(parent), AbstractChatCore(), m_loggedIn (false), m_needCheckIp (0), m_nowListening (""), m_nlIsNew (false), m_chatWgt (NULL), m_myInfo (0), m_currentProfile (0), m_chatTime (0), m_mode (Serverless), m_uid (0) { m_sender = new SenderThread (); m_udpReceiver = new ReceiverThread(); m_tcpReceiver = new TcpReceiverThread(); m_udpReceiver->setObjectName("udpReceiver"); m_tcpReceiver->setObjectName("tcpReceiver"); m_receiver = m_udpReceiver; m_settings = new QChatSettings; m_smhModel = new SingleMsgsHistoryModel; #if defined(Q_OS_LINUX) m_nlAmarok = new NLAmarok(this); #endif UserInfo::setMyInfo(m_myInfo); QChatSettings::setSettings(m_settings); m_pluginManager = new PluginManager; m_statusTimer = new QTimer(this); m_chatTimer->start(1000); connect(m_chatTimer , SIGNAL(timeout()), this, SLOT(slot_updateChatTime())); connect(m_tcpReceiver, SIGNAL(disconnected()), this, SLOT(slot_disconnectedFromServer())); #if defined(Q_OS_LINUX) connect(m_nlAmarok, SIGNAL(updated (const QString&, const QString&, const QString&)), this , SLOT (slot_setNl(const QString&, const QString&, const QString&))); #endif } ChatCore::~ChatCore() { qDebug("[~ChatCore]"); stopThreads(); delete m_settings; delete m_smhModel; delete m_pluginManager; m_sender ->deleteLater(); m_udpReceiver->deleteLater(); m_tcpReceiver->deleteLater(); qDebug("[~ChatCore]: end"); } //\***************************************************************************** void ChatCore::sendData(quint64 uid) { // qDebug("sending to %u %s", uid, QHostAddress(uid).toString().toAscii().data()); if(largeDtgrm()) { quint32 id = m_sender->getValidID(); if(id) { emit wantSendLargeData(header(), headerSize(), data(), dataSize(), uid, id); setNULLdataAndHeader(); } } else { //********************* // Compression setCompressed(outputBuffer(), settings()->boolOption("UseCompression")); if(settings()->boolOption("UseCompression") && protocolVersion() >= 4) { char* buf; uint size = outputBufferSize(); buf = compress(outputBuffer(), size); if(buf && size < (uint)outputBufferSize()) setOutputBuffer(buf, size); else setCompressed(outputBuffer(), false); free(buf); } // Compression //********************* quint16 size = outputBufferSize() <= MAX_PACKET_LEN ? outputBufferSize() : (MAX_PACKET_LEN); if(m_settings->intOption("ProtocolVersion") < 4 && m_receiver == m_udpReceiver) { } else { setPacketSize(size); } int bs = -2; if(m_mode == Serverless && QChatSettings::settings()->boolOption("UseIPList") && (QHostAddress(uid) == QChatSettings::broadcast())) { foreach(QHostAddress addr, QChatSettings::ipList()) m_sender->send(outputBuffer(), size, addr); m_sender->send(outputBuffer(), size, QHostAddress(QChatSettings::settings()->hostAddressOption("IP"))); } else bs = m_sender->send(outputBuffer(), size, QHostAddress(uid)); qDebug("[ChatCore::sendData]: dtgrm size = %d, sent = %d\n", size, bs); } clearParametrs(); } //\***************************************************************************** void ChatCore::slot_prepareAndSend(const QString & ch_name_id, quint64 uid, AbstractChatCore::DataType data_type, const QString & msg, AbstractChatCore::ChannelType ch_type, QByteArray* add_pars) { qDebug("[ChatCore::slot_prepareAndSend]: type = %u", data_type); qDebug("[ChatCore::slot_prepareAndSend]: 'channel_name' = '%s'", ch_name_id.toLocal8Bit().data()); qDebug("[ChatCore::slot_prepareAndSend]: 'msg' = '%s'", msg.toLocal8Bit().data()); if(data_type != AbstractChatCore::SINGLE_MESSAGE) addParametr("Channel", ch_name_id.toUtf8()); if(add_pars) { parametrs().append(*add_pars); add_pars->clear(); } if(data_type == AbstractChatCore::MESSAGE) { addParametr("HTML", QByteArray()); addParametr("Color", QByteArray().append(m_settings->myColor().red ()) .append(m_settings->myColor().green()) .append(m_settings->myColor().blue ())); processSmiles(msg); bool send_nl = m_nlIsNew && !m_nowListening.isEmpty() && (m_settings->nlMode() & 1); if(send_nl) { m_nowListening = m_settings->strOption("NLFormat"); m_nowListening.replace("%a", m_nlArtist).replace("%b", m_nlAlbum).replace("%t", m_nlTitle); } prepareDatagramWrapper(AbstractChatCore::MESSAGE, uid, send_nl ? msg + "\n" + m_nowListening : msg, ch_type); m_nlIsNew = (m_nlIsNew && !send_nl); } else prepareDatagramWrapper(data_type, uid, msg, ch_type); sendData(uid); } //\***************************************************************************** void ChatCore::slot_singleMessage(const QString & msg, quint64 uid, bool important/*, quint32 type*/) { qDebug("[ChatCore::slot_singleMessage]: addr = '%s'", QHostAddress(uid).toString().toLocal8Bit().data()); qDebug("[ChatCore::slot_singleMessage]: msg = '%s'", msg.toLocal8Bit().data()); if(important) addParametr("Important", QByteArray()); prepareDatagramWrapper(AbstractChatCore::SINGLE_MESSAGE, uid, msg, Common); { // FIXME this is not optimal solution :) //*************** setInputBuffer(outputBuffer(), outputBufferSize()); fillHeader(); UserInfo* info = getUserInfo(uid); hdr()->src_ip = hdr()->dest_ip; if(info) { hdr()->name = info->nickname(); hdr()->comp_name = info->compName(); hdr()->programVersion = info->programVerID(); } else hdr()->name = "*"; hdr()->comp_name = "*"; hdr()->programVersion = Globals::VersionID; //*************** SingleMessage* msg = new SingleMessage(hdr(), info ? info->ip() : uid); m_smhModel->addMessage(msg); } sendData(uid); } //\***************************************************************************** void ChatCore::slot_statusAnswer(const QString & name_id, quint64 uid, ChannelType channel_type, bool changed, bool send_icon) { if(m_myInfo->status(name_id) == Globals::INVISIBLE) return; if(send_icon) { QByteArray data; QBuffer buffer; const QImage* icon = m_myInfo->newIconImg(); buffer.setBuffer(&data); if(icon) { icon->save(&buffer, "PNG", 100); delete icon; } addParametr("Icon" , data); } addParametr("Status" , QByteArray().append((char)m_myInfo->status(name_id))); addParametr("Channel" , name_id.toUtf8()); addParametr("Version" , Globals::VersionStr.toUtf8()); addParametr("StatusDescription", UserInfo::myInfo()->statusDescription(name_id).toUtf8()); addParametr("Gender" , QString().setNum(m_myInfo->gender()).toUtf8()); addParametr("OS" , UserStatistics::OsString().toUtf8()); addParametr("Uptime" , QString().setNum(UserStatistics::getUptime()).toUtf8()); addParametr("ChatTime" , QString().setNum(m_chatTime).toUtf8()); addParametr("FirstName", m_myInfo->firstName().toUtf8()); addParametr("IpAddress", QString().setNum(m_settings->hostAddressOption("IP").toIPv4Address()).toUtf8()); if(!changed) prepareDatagramWrapper(AbstractChatCore::STATUS_ANSWER, uid, QString(""), channel_type); else { QString str = "Status Changed : " + Globals::StatusStr[m_myInfo->status(name_id)]; if(!UserInfo::myInfo()->statusDescription(name_id).isEmpty()) str += " (" + UserInfo::myInfo()->statusDescription(name_id) + ")"; prepareDatagramWrapper(AbstractChatCore::INF_STATUS_CHNGD, QChatSettings::settings()->broadcast().toIPv4Address(), str); } qDebug("[ChatCore::slot_statusAnswer] ip = %s, ip = %u", QHostAddress(uid).toString().toLocal8Bit().data(), (int)uid); sendData(uid); } //\***************************************************************************** void ChatCore::slot_infStatusChanged(const QString & name_id) { addParametr("Channel", name_id.toUtf8()); addParametr("Status" , QByteArray().append((char)m_myInfo->status(name_id))); prepareDatagramWrapper(AbstractChatCore::INF_STATUS_CHNGD, QChatSettings::settings()->broadcast().toIPv4Address(), QString("STATUS CHANGED") ); sendData(QChatSettings::settings()->broadcast().toIPv4Address()); } //\***************************************************************************** void ChatCore::slot_infoAnswer(const QString & name_id, quint64 uid, ChannelType type, uchar pics_ok) { if(m_myInfo->status(name_id) == Globals::INVISIBLE) return; qDebug("\n[ChatCore::slot_infoAnswer] channel_name = %s, pics_ok = %d\n", name_id.toLocal8Bit().data(), pics_ok); QByteArray data; QBuffer buffer; QImage* pix; addParametr("LastName" , m_myInfo->lastName ().toUtf8()); addParametr("FirstName" , m_myInfo->firstName ().toUtf8()); addParametr("SecondName" , m_myInfo->secondName ().toUtf8()); addParametr("DateOfBorn" , m_myInfo->dateOfBorn ().toString().toUtf8()); addParametr("Address" , m_myInfo->address ().toUtf8()); addParametr("HomePhone" , m_myInfo->homePhone ().toUtf8()); addParametr("WorkPhone" , m_myInfo->workPhone ().toUtf8()); addParametr("MobilePhone", m_myInfo->mobilePhone().toUtf8()); addParametr("e-mail" , m_myInfo->e_mail ().toUtf8()); addParametr("ICQ" , m_myInfo->icq ().toUtf8()); addParametr("Homepage" , m_myInfo->homepage ().toUtf8()); addParametr("AboutInfo" , m_myInfo->aboutInfo ().toUtf8()); addParametr("Gender" , QString().setNum(m_myInfo->gender()).toUtf8()); addParametr("IpAddress" , QString().setNum(m_settings->hostAddressOption("IP").toIPv4Address()).toUtf8()); // TODO sdelat' nastraivaemyi razmer kartinok buffer.setBuffer(&data); if(pics_ok & 1) addParametr("PictureOk", QByteArray()); else { if((pix = m_myInfo->newPictureImg())) { // if(pix->height() > 500) // pix->scaledToHeight(500).save(&buffer); // else pix->save(&buffer, "PNG", 100); delete pix; } addParametr("Picture" , data); addParametr("PictureHash", m_myInfo->pictureHash()); } buffer.close (); data.clear(); buffer.setBuffer(&data); buffer.setData(QByteArray()); if(pics_ok & 2) addParametr("PhotoOk", QByteArray()); else { if((pix = m_myInfo->newPhotoImg())) { // if(pix->height() > 500) // pix->scaledToHeight(500).save(&buffer); // else pix->save(&buffer, "PNG", 100); delete pix; } addParametr("Photo" , data); addParametr("PhotoHash", m_myInfo->photoHash()); } addParametr("Status" , QByteArray().append((char)m_myInfo->status(name_id))); addParametr("Version", Globals::VersionStr.toUtf8()); addParametr("Channel", name_id.toUtf8()); addParametr("StatusDescription", UserInfo::myInfo()->statusDescription(name_id).toUtf8()); prepareDatagramWrapper(AbstractChatCore::INFO_ANSWER, uid, QString(""), type); sendData(uid); } //\***************************************************************************** void ChatCore::slot_requestFragments(char* fragments, quint32 len, quint32 id, quint64 uid) { char buf[2]; catUS2str(buf, len); qDebug("\n[ChatCore::slot_fragmentsRequest]:len = %lu, ID = %lu, addr = %s", (unsigned long)len, (unsigned long)id, QHostAddress(uid).toString().toLocal8Bit().data()); clearParametrs(); addParametr("FragmentsRequest", QByteArray(fragments, len)); addParametr("FragmentsLen" , QByteArray(buf , 2)); prepareDatagramWrapper(AbstractChatCore::FRAGMENTS_REQUEST, uid, QString(""), Common, id); sendData(uid); } //\***************************************************************************** void ChatCore::slot_confirmReceivingFile(quint8 percents, quint16 dtgrmID, quint64 uid) { prepareDatagramWrapper(AbstractChatCore::CONFIRM, uid, QString(""), Common, dtgrmID, percents); sendData(uid); } //\***************************************************************************** void ChatCore::slot_acceptReceiving(quint16 dtgrmID, quint64 uid) { qDebug("\n[ChatCore::slot_acceptReceiving] addr = %s", QHostAddress(uid).toString().toLocal8Bit().data()); prepareDatagramWrapper(AbstractChatCore::ACCEPT, uid, QString(""), Common, dtgrmID, 0); sendData(uid); } //\***************************************************************************** void ChatCore::slot_rejectReceiving(quint16 dtgrmID, quint64 uid, int reason) { qDebug("\n[ChatCore::slot_rejectReceiving] addr = %s", QHostAddress(uid).toString().toLocal8Bit().data()); prepareDatagramWrapper(AbstractChatCore::REJECT, uid, QString(""), Common, dtgrmID, reason); sendData(uid); } //\***************************************************************************** void ChatCore::slot_privateChatRequest(const QString & name_id, quint64 uid) { addParametr("Channel", name_id.toUtf8()); prepareDatagramWrapper(AbstractChatCore::PRIVATE_CHAT_REQUEST, uid, QString("")); sendData(uid); } void ChatCore::processData() { QString chnnl_name = QString().fromUtf8(getParametr("Channel", hdr()->parametrs)); QString pl_name; UserInfo* info = m_chatWgt->findUser(hdr()->src_ip); quint64 src_ip = info ? info->ip() : 0; qDebug("[ChatCore::processData]: chnnl_name = %s", chnnl_name.toLocal8Bit().data()); QDateTime dt; dt.setTime_t(hdr()->receive_tm); Message* msg = new Message(hdr(), src_ip); if(!filter()->validateMessage(msg)) { delete msg; return; } delete msg; switch(hdr()->type) { case AbstractChatCore::SINGLE_MESSAGE : { SingleMessage* smsg = new SingleMessage(hdr(), src_ip); smsg->setIsIncoming(true); smsg->setNew(); m_smhModel->addMessage(smsg); emit singleMessageIn(smsg, !getParametr("Important", hdr()->parametrs).isNull()); break; } case AbstractChatCore::FILE: break; case AbstractChatCore::PRIVATE_CHAT_REQUEST: qDebug("[ChatCore::processData]: PRIVATE_CHAT_REQUEST chnnl_name = %s", chnnl_name.toLocal8Bit().data()); privateChatRequest(chnnl_name, hdr()->src_ip); break; case AbstractChatCore::PLUGIN_DATA: pl_name = QString().fromUtf8(getParametr("PluginId", hdr()->parametrs)); foreach(QObject* obj, m_chatWgt->m_allPlugins) { QChatWidgetPlugin* plug = qobject_cast(obj); QMap pars; if(plug) if(plug->name() == pl_name) plug->processData(getAllParametrs(hdr()->parametrs)); } break; case AbstractChatCore::LOGIN_ACCEPTED: m_uid = hdr()->dest_ip; UserInfo::myInfo()->setNickname(hdr()->name); UserInfo::myInfo()->setUid(m_uid); if(m_loggedIn) { foreach(ChannelWgt* ch, m_chatWgt->channels()) ch->sendStatusAnswer(0); } else { m_loggedIn = true; foreach(ChannelWgt* ch, m_chatWgt->channels()) { ch->initChannel(); ch->sendStatusAnswer(0); } emit loginFinished(0, hdr()->msg); } case AbstractChatCore::LOGIN_REJECTED: emit loginFinished(2, hdr()->msg); default: { emit chatDataReceived(hdr()); newHdr(); clearParametrs(); } } } //\***************************************************************************** void ChatCore::slot_processData(char* data, quint16 dataSize) { setInputBuffer(data, dataSize); free(data); if(fillHeader()) processData(); } //\***************************************************************************** void ChatCore::slot_processLargeData(LargeDatagram* dtgrm) { Q_ASSERT(NULL != dtgrm); if(dtgrm->fillHeader(hdr())) processData(); prepareDatagramWrapper(AbstractChatCore::FINISHED, dtgrm->destUid(), "", Common, dtgrm->id()); sendData(dtgrm->destUid()); } //\***************************************************************************** void ChatCore::startThreads() { qDebug("[ChatCore::startThreads]: begin"); connect(this , SIGNAL(wantSendFile(char*, quint16, const QString &, quint64, quint32)), m_sender , SLOT (addFileTask (char*, quint16, const QString &, quint64, quint32))); connect(this , SIGNAL(wantSendLargeData(char*, quint16, char*, quint32, quint64, quint32)), m_sender , SLOT (addTask (char*, quint16, char*, quint32, quint64, quint32))); m_sender ->setPort(m_settings->intOption("OutputPort")); m_tcpReceiver->start(); m_udpReceiver->start(); m_sender ->start(); start(); moveToThread(this); // sleep(1); initMode(Serverless, 1); qDebug("[ChatCore::startThreads]: end"); } //\***************************************************************************** void ChatCore::stopThreads() { m_receiver->exit(); m_sender->exit(); exit(); } //\***************************************************************************** void ChatCore::slot_openSocketError(quint16 port) { Globals::addError(QString("Couldn't open UDP socket on port %1 ").arg(port)); qWarning("Couldn't open UDP socket on port %d\n", port); } //\***************************************************************************** void ChatCore::slot_bindInputPort(int port) { QChatSettings::settings()->setOption("InputPort", port); emit wantChangeInputPort(port); } //\***************************************************************************** void ChatCore::slot_setNl(const QString & title, const QString & artist, const QString & album) { #if defined(Q_OS_LINUX) if(!title.isEmpty() || !artist.isEmpty() || !album.isEmpty()) { m_nlTitle = title; m_nlArtist = artist; m_nlAlbum = album; m_nowListening = m_settings->strOption("NLFormat"); m_nowListening.replace("%a", artist).replace("%b", album).replace("%t", title); m_nlIsNew = true; } else m_nowListening = ""; m_settings->setNowListening(m_nowListening); if(m_settings->nlMode() & 2) { m_myInfo->setStatusDescription(m_chatWgt->currentChannelName(), m_nowListening); // FIXME incorrect works if other channel set its status in myInfo slot_statusAnswer(m_chatWgt->currentChannelName(), QChatSettings::settings()->broadcast().toIPv4Address(), Common, 0); } #endif } //\***************************************************************************** quint32 ChatCore::initSendingFile(quint64 uid, const QString & filename, QObject* ftw) { clearParametrs(); prepareDatagramWrapper(AbstractChatCore::FILE, uid); quint32 id = m_sender->getValidID(); if(id) { qDebug("[ChatCore::sendFile]:str = %s", filename.right(filename.size() - 1 - filename.lastIndexOf("/")).toLocal8Bit().data()); emit wantSendFile(header(), headerSize(), filename, uid, id); setNULLdataAndHeader(); connect(m_receiver, SIGNAL(percentsConfirmed(quint8, quint16, quint64)), ftw , SLOT (slot_setProgress (quint8, quint16, quint64))); connect(m_receiver, SIGNAL(receivingRejected (quint16)), ftw , SLOT (slot_rejectedByReceiver (quint16))); connect(m_receiver, SIGNAL(receivingCancelled (quint16)), ftw , SLOT (slot_cancelledByReceiver(quint16))); connect(m_receiver, SIGNAL(receivingCancelled (quint16)), m_sender , SLOT (slot_cancelTask (quint16))); connect(m_sender , SIGNAL(sendingCancelled (quint16)), ftw , SLOT (slot_cannotSend (quint16))); connect(m_sender , SIGNAL(sendingFinished (quint16)), ftw , SLOT (slot_sendingTimeout (quint16))); connect(ftw , SIGNAL(rejected (quint16, quint64, int)), this , SLOT (slot_rejectReceiving(quint16, quint64, int)));// slot_rejectReceiving, but here it working such 'cancel Sending' :) connect(ftw , SIGNAL(cancel (quint16)), m_sender , SLOT (slot_cancelTask(quint16))); } return id; } //\***************************************************************************** void ChatCore::initReceivingFile(QObject* obj) { connect(m_receiver, SIGNAL(percentsRemain (quint8, quint16, quint64)), obj , SLOT (slot_setProgress (quint8, quint16, quint64))); connect(obj , SIGNAL(accepted (QString, quint16, quint64)), m_receiver, SLOT (slot_acceptDatagram (QString, quint16, quint64))); connect(obj , SIGNAL(rejected (quint16, quint64, int)), m_receiver, SLOT (slot_rejectDatagram (quint16, quint64))); connect(m_receiver, SIGNAL(readyReceive (quint16, quint64)), this , SLOT (slot_acceptReceiving (quint16, quint64))); connect(m_receiver, SIGNAL(sendingCancelled (quint16, quint64)), obj , SLOT (slot_cancelledBySender(quint16, quint64))); connect(obj , SIGNAL(rejected (quint16, quint64, int)), this , SLOT (slot_rejectReceiving(quint16, quint64, int))); connect(m_receiver, SIGNAL(percentsRemain (quint8, quint16, quint64)), this , SLOT (slot_confirmReceivingFile(quint8, quint16, quint64))); connect(m_receiver, SIGNAL(receivingTimeout (quint16, quint64)), obj , SLOT (slot_receivingTimeout(quint16, quint64))); } //\***************************************************************************** void ChatCore::slot_loadProfile(const QString & name) { UserProfile* profile = m_profiles[name]; QByteArray data; QImage pix; if(profile) { qDebug("[ChatCore::loadProfile]: %s", name.toLocal8Bit().data()); m_currentProfile = profile; m_myInfo = profile->info(); m_settings = profile->prefs(); m_myInfo->setCompName(QHostInfo::localHostName()); UserInfo::setMyInfo(m_myInfo); QChatSettings::setSettings(m_settings); } else { m_myInfo = new UserInfo; m_settings = new QChatSettings; profile = new UserProfile(name, m_settings, m_myInfo); m_currentProfile = profile; UserInfo::setMyInfo(m_myInfo); QChatSettings::setSettings(m_settings); m_profiles.insert(name, profile); m_myInfo->setNickname(name); } QChatSettings::setProfileName(name); emit profileLoaded(name); } //\***************************************************************************** QStringList ChatCore::profiles() const { QStringList profiles; QMapIterator i(m_profiles); while (i.hasNext()) { i.next(); profiles << i.key(); } return profiles; } //\***************************************************************************** const QString & ChatCore::currentProfile() const { return m_currentProfile->name(); } //\***************************************************************************** void ChatCore::slot_renameProfile(const QString & old_name, const QString & new_name) { UserProfile* profile = m_profiles[old_name]; if(profile) { profile->rename(new_name); m_profiles.erase(m_profiles.find(old_name)); m_profiles.insert(new_name, profile); } } void ChatCore::slot_deleteProfile(const QString & name) { m_profiles.erase(m_profiles.find(name)); delete m_currentProfile->info(); delete m_currentProfile->prefs(); delete m_currentProfile; slot_loadProfile(m_profiles.begin().key()); } void ChatCore::processSmiles(QString msg) // TODO perepisat' { Smile* smile; QList smiles; QString sm_str; QString msg_ = msg; int idx_end = 0; QString str; smile = 0; sm_str = ChatTextWgt::nextSmile(msg, &smile); idx_end = msg.indexOf(sm_str); for(; idx_end != -1 && !sm_str.isEmpty();) { if(smile) { if(sm_str != smile->smiles[0]) { msg_.replace(sm_str, smile->smiles[0]); sm_str = smile->smiles[0]; } if(!smiles.contains(smile)) { smiles.append(smile); m_smilesParam.append(sm_str.toUtf8()); m_smilesParam.append((char)0); } } str = msg.left(idx_end); msg = msg.right(msg.size() - idx_end - sm_str.size()); sm_str = ChatTextWgt::nextSmile(msg, &smile); if(sm_str.isEmpty()) break; idx_end = msg.indexOf(smile->smiles[0]); } addParametr("Smiles", m_smilesParam); QList::const_iterator i; for (i = smiles.constBegin(); i != smiles.constEnd(); ++i) { str = QChatSettings::settings()->smilesThemePath() + (*i)->name; if(QFile(str).exists()) addParametr(QString("Smile") + (*i)->smiles[0], str); else if(QFile(str + ".png").exists()) addParametr(QString("Smile") + (*i)->smiles[0], str + ".png"); else if(QFile(str + ".gif").exists()) addParametr(QString("Smile") + (*i)->smiles[0], str + ".gif"); else if(QFile(str + ".jpg").exists()) addParametr(QString("Smile") + (*i)->smiles[0], str + ".jpg"); } } void ChatCore::slot_msgsHistoryAnswer(const QString & ch_name_id, quint64 uid, const QByteArray & msgs, AbstractChatCore::ChannelType ch_type) { addParametr("Channel" , ch_name_id.toUtf8()); addParametr("MsgsHistory", msgs); prepareDatagramWrapper(AbstractChatCore::MSGS_HISTORY_ANSWER, uid, QString(""), ch_type); sendData(uid); } void ChatCore::slot_msgsNumAnswer(const QString & ch_name_id, quint64 uid, quint32 msgs_num, AbstractChatCore::ChannelType type) { addParametr("Channel", ch_name_id.toUtf8()); addParametr("MsgsNum", QString().setNum(msgs_num).toUtf8()); prepareDatagramWrapper(AbstractChatCore::MSGS_NUM_ANSWER, uid, QString(""), type); sendData(uid); } void ChatCore::slot_sendMessage(const QString & ch_name_id, quint64 uid, AbstractChatCore::ChannelType ch_type, QTextDocument* doc) { QString fname; QString smname; int sm_num = 0; QTextCursor cur(doc); QMap smiles; m_smilesParam.clear(); for(QTextBlock it = doc->begin(); it != doc->end(); it = it.next()) { cur = QTextCursor(it); QTextBlock::iterator i = cur.block().begin(); for (; i != cur.block().end(); i++) { QTextFormat fmt = i.fragment().charFormat(); if(fmt.isImageFormat()) { fname = fmt.stringProperty(QTextFormat::ImageName); if(!smiles.contains(fname)) { smname = QString().setNum(sm_num) + QString(QChar(0xFFFC + 1)); m_smilesParam.append(smname.toUtf8()); m_smilesParam.append((char)0); smiles.insert(fname, sm_num); sm_num++; addParametr("Smile" + smname, fname); } else smname = QString().setNum(smiles.value(fname)) + QString(QChar(0xFFFC + 1)); cur.beginEditBlock(); cur.clearSelection(); cur.setPosition(i.fragment().position()); cur.deleteChar(); cur.insertText(smname); cur.endEditBlock(); i = cur.block().begin(); } } } if(protocolVersion() >= 4) slot_prepareAndSend(ch_name_id, uid, AbstractChatCore::MESSAGE, doc->toHtml(), ch_type, NULL); else slot_prepareAndSend(ch_name_id, uid, AbstractChatCore::MESSAGE, doc->toPlainText(), ch_type, NULL); doc->deleteLater(); } void ChatCore::slot_avatarAnswer(const QString & ch_name_id, quint64 uid, AbstractChatCore::ChannelType channel_type) { if(m_myInfo->status(ch_name_id) == Globals::INVISIBLE) return; QByteArray data; QBuffer buffer; const QImage* icon = m_myInfo->newIconImg(); buffer.setBuffer(&data); if(icon) { icon->save(&buffer, "PNG", 100); delete icon; } addParametr("Channel", ch_name_id.toUtf8()); addParametr("Icon", data); addParametr("IconHash", UserInfo::myInfo()->avatarHash()); prepareDatagramWrapper(AbstractChatCore::AVATAR_ANSWER, uid, QString(""), channel_type); sendData(uid); } void ChatCore::sendPluginData(const QString & plugin_id , const QMap & parametrs, quint64 uid , AbstractChatCore::DataType data_type, const QString & channel_id, uint ch_type, const QString & msg) { foreach(QString name, parametrs.keys()) addParametr(name, parametrs[name]); addParametr("PluginId", plugin_id.toUtf8()); slot_prepareAndSend(channel_id, uid, data_type, msg, (AbstractChatCore::ChannelType)ch_type); } void ChatCore::prepareDatagramWrapper(AbstractChatCore::DataType dtgrm_type, quint64 dest_uid, const QString & msg, AbstractChatCore::ChannelType chnnl_type, quint64 dtgrm_id, quint64 dtgrm_num) { // FIXME krivovato sdelano.. //***** quint64 src_ip; quint64 dest_ip = dest_uid; // in serverless mode we using IP addresses but in Server - UIDs if(m_mode == Serverless) src_ip = m_settings->hostAddressOption("IP").toIPv4Address(); else src_ip = m_uid; //***** prepareDatagram(dtgrm_type, dest_ip, m_myInfo->nickname(), m_myInfo->compName(), src_ip, msg, chnnl_type, dtgrm_id, dtgrm_num); } void ChatCore::initMode(Mode mode_, bool first) { m_settings->setMode((QChatSettings::Mode)mode_); m_mode = mode_; if(!first) { disconnect(m_receiver , SIGNAL(dataReceived (char *, quint16)), this, SLOT (slot_processData(char *, quint16))); disconnect(m_receiver , SIGNAL(largeDataReceived (LargeDatagram*)), this, SLOT (slot_processLargeData(LargeDatagram*))); disconnect(m_receiver , SIGNAL(wantFragments (char*, quint32, quint32, quint64)), this, SLOT (slot_requestFragments(char*, quint32, quint32, quint64))); disconnect(m_receiver , SIGNAL( fragmentsRequest(char*, quint32)), m_sender , SLOT (slot_fragmentsRequest(char*, quint32))); disconnect(m_receiver , SIGNAL( receivingAccepted(quint16)), m_sender , SLOT (slot_acceptSending (quint16))); disconnect(m_receiver , SIGNAL(openSocketError(quint16)), this , SLOT (slot_openSocketError(quint16))); disconnect(m_receiver , SIGNAL(dtgrmFinished (quint16)), m_sender , SLOT (slot_cancelTask(quint16))); disconnect(this , SIGNAL(wantChangeInputPort(quint16)), m_receiver , SLOT (changePort (quint16))); } else { connect(this , SIGNAL(wantLogin(const QString&, const QHostAddress&, uint, const QString&)), m_tcpReceiver, SLOT (login (const QString&, const QHostAddress&, uint, const QString&))); // connect(m_tcpReceiver, SIGNAL(loginFinished(int, const QString&)), // this , SIGNAL(loginFinished(int, const QString&))); } switch(mode_) { case Server : changeProtocolVersion(4); m_receiver = m_tcpReceiver; m_sender->useTcp(m_tcpReceiver->socket()); break; case Serverless : m_receiver = m_udpReceiver; m_sender->useUdp(); break; default: m_receiver = m_udpReceiver; m_sender->useUdp(); } createReceiverConnections(); emit wantChangeInputPort(m_settings->intOption("InputPort")); } void ChatCore::createReceiverConnections() { connect(m_receiver , SIGNAL(dataReceived (char *, quint16)), this, SLOT (slot_processData(char *, quint16))); connect(m_receiver , SIGNAL(largeDataReceived (LargeDatagram*)), this, SLOT (slot_processLargeData(LargeDatagram*))); connect(m_receiver , SIGNAL(wantFragments (char*, quint32, quint32, quint64)), this, SLOT (slot_requestFragments(char*, quint32, quint32, quint64))); connect(m_receiver , SIGNAL( fragmentsRequest(char*, quint32)), m_sender , SLOT (slot_fragmentsRequest(char*, quint32))); connect(m_receiver , SIGNAL( receivingAccepted(quint16)), m_sender , SLOT (slot_acceptSending (quint16))); connect(m_receiver , SIGNAL(openSocketError(quint16)), this , SLOT (slot_openSocketError(quint16))); connect(m_receiver , SIGNAL(dtgrmFinished (quint16)), m_sender , SLOT (slot_cancelTask(quint16))); connect(this , SIGNAL(wantChangeInputPort(quint16)), m_receiver , SLOT (changePort (quint16))); } void ChatCore::slot_setMode() // Server or Serverless { } void ChatCore::slot_login(const QHostAddress & addr, const QString & nick) { // FIXME !!! emit wantLogin(nick, addr, 61100, ""); } void ChatCore::disconnectFromServer() { m_tcpReceiver->socket()->disconnectFromHost(); m_loggedIn = false; } void ChatCore::changeLogin(const QString & newLogin) { prepareDatagram(AbstractChatCore::CHANGE_LOGIN, 1, newLogin, UserInfo::myInfo()->compName(), UserInfo::myInfo()->uid(), ""); sendData(1); } void ChatCore::initPlugins() { m_pluginManager->getPlugins(); connect(m_pluginManager, SIGNAL(sendData(const QString &, const QMap &, quint64, AbstractChatCore::DataType, const QString &, uint, const QString &)), this, SLOT (sendPluginData(const QString &, const QMap &, quint64, AbstractChatCore::DataType, const QString &, uint, const QString &))); } UserInfo* ChatCore::getUserInfo(quint64 uid) { UserWgt* user; foreach(ChannelWgt* cw, m_chatWgt->channels()) if(cw->name() == "Main") if((user = cw->findUser(uid))) return user->info(); return NULL; } void ChatCore::changeProtocolVersion(uint ver) { m_settings->setOption("ProtocolVersion", ver); setProtocolVersion(ver); } bool ChatCore::loggedIn() { return (m_mode == Server && m_loggedIn); } void ChatCore::slot_disconnectedFromServer() { m_loggedIn = false; emit disconnectedFromServer(); } #include "chatcore_settings.cpp" qchat-0.3/src/abstractchatcore.h0000644000076500017500000002503111002520152015434 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef ABSTRACTCORE_H #define ABSTRACTCORE_H #include // TODO remove "globals.h" from this header #include "globals.h" #include "abstractprotocol.h" class QC_DatagramHeader; class AbstractProtocol; class ProtocolVersion3; class ProtocolVersion4; bool isSystemMsg(quint16 type); /** @author Anistratov Oleg @brief Abstract class for manipulating with QChat's protocol */ class AbstractChatCore { private: static AbstractProtocol* m_protocol; static ProtocolVersion3* m_protocolV3; static ProtocolVersion4* m_protocolV4; /// Output buffer - here writes data(<= 2^16-1) before sending char* m_outputBuffer; /// Size of m_outputBuffer uint m_outputBufferSize; /// Input buffer - here writes data(<= 2^16-1) after receiving char* m_inputBuffer; /// Size of m_inputBuffer uint m_inputBufferSize; /// Flag shows that size of sending packet > 2^16-1 bool m_largeDtgrm; /** Used for sending large(> 2^16-1) packets * Stores header of large packet */ char* m_header; /// Size if m_header int m_headerSize; /** Used for sending large(> 2^16-1) packets * Stores data(message and Parametrs array) of large packet */ char* m_data; /// Size if m_data int m_dataSize; QByteArray m_parametrs; /// Stores data(name and sender's IP, message, etc) received after processing m_inputBuffer QC_DatagramHeader* Hdr; public: enum ChannelType{Common, Private}; enum DataType { MESSAGE = 0, INFORMATION, CONNECTED, DISCONNECTED, AVATAR_REQUEST, AVATAR_ANSWER, STATUS_REQUEST, STATUS_ANSWER, INFO_REQUEST, INFO_ANSWER, INF_STATUS_CHNGD = 10, FRAGMENTS_REQUEST, SINGLE_MESSAGE, FILE, ACCEPT, REJECT, CONFIRM, FINISHED, PRIVATE_CHAT_REQUEST, MSGS_HISTORY_REQUEST, MSGS_HISTORY_ANSWER, MSGS_NUM_REQUEST, MSGS_NUM_ANSWER, PLUGIN_DATA, WANT_LOGIN, LOGIN_ACCEPTED, LOGIN_REJECTED, CHANGE_LOGIN, INSTRUCTION }; public: AbstractChatCore(); virtual ~AbstractChatCore(); // virtual void sendData(const QHostAddress &) = 0; // get-set char* outputBuffer (){return m_outputBuffer;} int outputBufferSize(){return m_outputBufferSize;} char* header (){return m_header;} int headerSize (){return m_headerSize;} char* data (){return m_data;} int dataSize (){return m_dataSize;} void setNULLdataAndHeader(){m_data = NULL; m_header = NULL;} bool largeDtgrm (){return m_largeDtgrm;} QC_DatagramHeader* hdr(){return Hdr;} void newHdr(); /*non const!*/ QByteArray& parametrs(){return m_parametrs;} void setInputBuffer (char* data, int dataSize){memcpy(m_inputBuffer , data, dataSize); m_inputBufferSize = dataSize;} void setOutputBuffer(char* data, int dataSize){memcpy(m_outputBuffer, data, dataSize); m_outputBufferSize = dataSize;} /** * @brief Preparing data for sending * @param dtgrm_type - paket type * @param dest_uid - user id of receiver(in serverless mode this is IP address) * @param nickname - sender's nickname * @param compname - name of sender's computer * @param src_uid - user id of sender(in serverless mode this is IP address) * @param msg - text message * @param chnnl_type - type of channel(Common, Private, etc) * @param dtgrm_id - paket id(for fragmented pakets) * @param dtgrm_num - paket number(for fragmented pakets) */ void prepareDatagram(AbstractChatCore::DataType dtgrm_type, quint64 dest_uid, const QString& nickname, const QString& compname, quint64 src_uid, const QString & msg = "", ChannelType chnnl_type = Common, unsigned long dtgrm_id = 0, unsigned long dtgrm_num = 0); bool fillHeader(); static QByteArray getParametr(const QString & par_name, const QByteArray & pars); static void addParametr(const QString & par_name, const QByteArray & par, QByteArray & buf); static QColor getColorParametr(QByteArray*); void addParametr (const QString & par_name, const QByteArray & par); QByteArray getParametr(const QString & par_name); void clearParametrs (); void addParametr(const QString & par_name, const QString & filename); QMap getAllParametrs(const QByteArray &); // NOTE size of char* buf in following functions must be at least AbstractChatCore::protocolLen() bytes static uint packetSize (const char* buf) {return m_protocol->packetSize(buf);} static void setPacketSize(char* buf, uint sz){m_protocol->setPacketSize(buf, sz);} void setPacketSize(uint sz) {m_protocol->setPacketSize(m_outputBuffer, sz);} static QString programId (const char* buf){return m_protocol->programId (buf);} static uint programVersion (const char* buf){return m_protocol->programVersion (buf);} static uint protocolVersion (const char* buf){return m_protocol->protocolVersion(buf);} static uint checkProtocolVersion(const char* buf); static quint64 destIp (const char* buf){return m_protocol->destIp (buf);} static quint64 srcIp (const char* buf){return m_protocol->srcIp (buf);} static uint packetType (const char* buf){return m_protocol->packetType (buf);} static uint packetId (const char* buf){return m_protocol->packetId (buf);} static uint fragmentSize (const char* buf){return m_protocol->fragmentSize (buf);} static uint packetNum (const char* buf){return m_protocol->packetNum (buf);} static quint64 time (const char* buf){return m_protocol->time (buf);} static uint channelType (const char* buf){return m_protocol->channelType (buf);} static uint compNameLen (const char* buf){return m_protocol->compNameLen (buf);} static uint userNameLen (const char* buf){return m_protocol->userNameLen (buf);} static uint messageLen (const char* buf){return m_protocol->messageLen (buf);} static uint parametrsLen (const char* buf){return m_protocol->parametrsLen (buf);} static uint optionsLen (const char* buf){return m_protocol->optionsLen (buf);} static bool compressed (const char* buf){return m_protocol->compressed (buf);} static QString compName (const char* buf, uint sz){return m_protocol->compName (buf, sz);} static QString userName (const char* buf, uint sz){return m_protocol->userName (buf, sz);} static QString message (const char* buf, uint sz){return m_protocol->message (buf, sz);} static QByteArray parametrs (const char* buf, uint sz){return m_protocol->parametrs(buf, sz);} static void setProgramId (char* buf){m_protocol->setProgramId (buf);} static void setProgramVersion (char* buf){m_protocol->setProgramVersion (buf);} static void setProtocolVersion(char* buf){m_protocol->setProtocolVersion(buf);} static void setDestIp (char* buf, quint64 val){m_protocol->setDestIp (buf, val);} static void setSrcIp (char* buf, quint64 val){m_protocol->setSrcIp (buf, val);} static void setPacketType (char* buf, uint val){m_protocol->setPacketType (buf, val);} static void setPacketId (char* buf, uint val){m_protocol->setPacketId (buf, val);} static void setFragmentSize (char* buf, uint val){m_protocol->setFragmentSize(buf, val);} static void setPacketNum (char* buf, quint32 val){m_protocol->setPacketNum (buf, val);} static void setTime (char* buf, quint64 val){m_protocol->setTime (buf, val);} static void setChannelType (char* buf, uint val){m_protocol->setChannelType (buf, val);} static void setCompNameLen (char* buf, uint val){m_protocol->setCompNameLen (buf, val);} static void setUserNameLen (char* buf, uint val){m_protocol->setUserNameLen (buf, val);} static void setMessageLen (char* buf, quint32 val){m_protocol->setMessageLen (buf, val);} static void setParametrsLen (char* buf, quint32 val){m_protocol->setParametrsLen(buf, val);} static void setOptionsLen (char* buf, quint32 val){m_protocol->setOptionsLen (buf, val);} static void setCompressed (char* buf, bool val){m_protocol->setCompressed (buf, val);} static void setCompName (char* buf, const QString& name) {m_protocol->setCompName (buf, name);} static void setUserName (char* buf, const QString& name) {m_protocol->setUserName (buf, name);} static void setMessage (char* buf, const QString& msg) {m_protocol->setMessage (buf, msg);} static void setParametrs (char* buf, const QByteArray& pars){m_protocol->setParametrs(buf, pars);} static char* uncompress(const char* buf, uint& size); static char* compress (const char* buf, uint& size); static uint protocolVersion (){return m_protocol->protocolVersion();} static uint protocolLen (){return m_protocol->protocolLen();} static const char* programId (){return m_protocol->programId();} static uint programIdLen (){return strlen(m_protocol->programId());} static uint optionsLen (){return m_protocol->optionsLen();} static void setProtocolVersion(uint); }; #endif qchat-0.3/src/protocolversion3.h0000644000076500017500000001246211002616470015467 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PROTOCOLVERSION3_H #define PROTOCOLVERSION3_H #include /** @author Anistratov Oleg */ class ProtocolVersion3 : public AbstractProtocol { private: static const char* m_programId; public: ProtocolVersion3(); ~ProtocolVersion3(); // Protocol information functions uint protocolVersion() const {return 3;} uint protocolLen () const {return 69;} const char* programId() const {return m_programId;} uint optionsLen() const {return 0;} // NOTE size of char* buf in following functions must be at least AbstractChatCore::protocolLen() bytes QString programId (const char* buf){return QString::fromAscii(buf, 18);} // 18 bytes // Only for server mode uint packetSize (const char* buf){return str2US (buf + 16);} // 2 uint programVersion (const char* buf){return str2US (buf + 18);} // 2 uint protocolVersion (const char* buf){return str2US (buf + 20);} // 2 quint64 destIp (const char* buf){return str2ULL(buf + 22);} // 8 quint64 srcIp (const char* buf){return str2ULL(buf + 30);} // 8 uint packetType (const char* buf){return *(buf + 38);} // 1 uint packetId (const char* buf){return str2US (buf + 39);} // 2 uint fragmentSize (const char* buf){return str2US (buf + 41);} // 2 uint packetNum (const char* buf){return str2UL (buf + 43);} // 4 quint64 time (const char* buf){return str2ULL(buf + 47);} // 8 uint channelType (const char* buf){return str2UL (buf + 55);} // 4 uint compNameLen (const char* buf){return *(buf + 59);} // 1 uint userNameLen (const char* buf){return *(buf + 60);} // 1 uint messageLen (const char* buf){return str2UL (buf + 61);} // 4 uint parametrsLen (const char* buf){return str2UL (buf + 65);} // 4 uint optionsLen (const char* /*buf*/){return 0;} bool compressed (const char* /*buf*/){return false;} QString compName (const char* buf, uint sz); QString userName (const char* buf, uint sz); QString message (const char* buf, uint sz); QByteArray parametrs (const char* buf, uint sz); void setProgramId (char* buf){strncpy(buf, programId(), 18);} // Only for server mode void setPacketSize (char* buf, uint sz){catUS2str(buf + 16, sz);} // 2 void setProgramVersion (char* buf){catUS2str(buf + 18, Globals::VersionID);} void setProtocolVersion(char* buf){catUS2str(buf + 20, protocolVersion());} void setDestIp (char* buf, quint64 ip){catULL2str(buf + 22, ip);} // 8 void setSrcIp (char* buf, quint64 ip){catULL2str(buf + 30, ip);} // 8 void setPacketType (char* buf, uint type){(buf[38] = type);} // 1 void setPacketId (char* buf, uint id){catUS2str(buf + 39, id);} // 2 void setFragmentSize (char* buf, uint sz){catUS2str(buf + 41, sz);} // 2 void setPacketNum (char* buf, quint32 nm){catUL2str (buf + 43, nm);} // 4 void setTime (char* buf, quint64 tm){catULL2str(buf + 47, tm);} // 8 void setChannelType (char* buf, quint32 id){catUL2str (buf + 55, id);} // 4 void setCompNameLen (char* buf, uint sz){buf[59] = sz;} // 1 void setUserNameLen (char* buf, uint sz){buf[60] = sz;} // 1 void setMessageLen (char* buf, quint32 sz){catUL2str(buf + 61, sz);} // 4 void setParametrsLen (char* buf, quint32 sz){catUL2str(buf + 65, sz);} // 4 void setOptionsLen (char* /*buf*/, quint32 /*sz*/){} void setCompressed (char* /*buf*/, bool /*b*/){} void setCompName (char* buf, const QString& name) {strncpy(buf + 69, name.toUtf8().data(), compNameLen(buf));} void setUserName (char* buf, const QString& name) // ?? {strncpy(buf + 69 + compNameLen(buf), name.toUtf8().data(), userNameLen(buf));} void setMessage (char* buf, const QString& msg) // ?? {memcpy(buf + 69 + compNameLen(buf) + userNameLen(buf), msg.toUtf8().data(), messageLen(buf));} void setParametrs (char* buf, const QByteArray& pars) // ?? {memcpy(buf + 69 + compNameLen(buf) + userNameLen(buf) + messageLen(buf), pars.data(), parametrsLen(buf));} }; #endif qchat-0.3/src/preferencesdlg.h0000644000076500017500000001644011002232516015120 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PREFERENCESDLG_H #define PREFERENCESDLG_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "userlisticonformat.h" class Globals; class ColorLabel; class EditStatusDescriptionsDlg; class UserListIconConfigureWgt; class IpListEditor; class MessageFilterEditor; /** @author Anistratov Oleg */ class PreferencesDlg : public QDialog { Q_OBJECT public: enum Sections{Network, Messages, Filtration = 2, Smiles, Misc, StyleSheets, Plugins, LastSection}; private: QListWidget* m_sectionsChooser; QListWidgetItem* m_networkSection; QListWidgetItem* m_messagesSection; QListWidgetItem* m_profileSection; QListWidgetItem* m_miscSection; QListWidgetItem* m_smilesSection; QListWidgetItem* m_styleSheetsSection; QListWidgetItem* m_pluginsSection; QListWidgetItem* m_filtrationSection; QStackedWidget* m_sections; QGroupBox* m_colorsGrbx; QGroupBox* m_networkGrbx; QGroupBox* m_miscGrbx; QGroupBox* m_nowListeningGrbx; QGroupBox* m_smilesThemesGrbx; QGroupBox* m_usersListGrbx; QGroupBox* m_styleSheetsGrbx; QGroupBox* m_pluginsGrbx; QGroupBox* m_iconFormatGrbx; QGroupBox* m_filtrationGrbx; QGroupBox* m_protocolsGrbx; QString m_profileName; ColorLabel* m_myColor; ColorLabel* m_sysColor; ColorLabel* m_baseColor; QPushButton* m_okBtn; QPushButton* m_cancelBtn; QPushButton* m_applyBtn; QColorDialog* m_colorDlg; QCheckBox* m_colorWholeMsgChbx; QCheckBox* m_colorWholeSysMsgChbx; QCheckBox* m_activateOnMsgInChbx; QCheckBox* m_soundOnMsgInChbx; QSpinBox* m_portInSpbx; QSpinBox* m_portOutSpbx; QLineEdit* m_ipEdit; QLineEdit* m_commandOnIncomingEdit; QCheckBox* m_isCommandOnIncomingChbx; QLineEdit* m_broadcastEdit; QComboBox* m_networkIfCmbx; // Now listening QCheckBox* m_nlWithMessageChbx; QCheckBox* m_nlInStatusChbx; QLineEdit* m_nlFormatEdit; // Smiles QListWidget* m_smilesThemeChooser; QStringList m_smilesThemes; QCheckBox* m_useAnimatedSmilesChbx; QComboBox* m_smilesPolicyCmbx; // Style Sheets QListWidget* m_styleSheetsChooser; QStringList m_styleSheets; // Plugins QListWidget* m_pluginsChooser; QPushButton* m_loadUnloadPluginBtn; QLabel* m_portOutLab; QLabel* m_portInLab; QLabel* m_myColorLab; QLabel* m_sysColorLab; QLabel* m_baseColorLab; QLabel* m_ipLab; QLabel* m_broadcastLab; QLabel* m_nlFormatLab; QLabel* m_displayMsgFmtLab; QLabel* m_msgsHistoryIntervalLab; QLabel* m_msgsHistoryNumLab; QLabel* m_ulRefreshIntervalLab; QLabel* m_ulDeepRefreshIntervalLab; QLabel* m_networkIfLab; QLabel* m_smilesPolicyLab; bool m_edited; quint16 m_oldPortIn; QLineEdit* m_displayMsgFmtEdit; QSpinBox* m_msgsHistoryIntervalSpbx; QSpinBox* m_msgsHistoryNumSpbx; QSpinBox* m_ulRefreshIntervalSpbx; QSpinBox* m_ulDeepRefreshIntervalSpbx; QVector m_addressEntries; UserListIconConfigureWgt* m_iconFormatWgt; IpListEditor* m_ipListEditor; QCheckBox* m_useCompressionChbx; MessageFilterEditor* m_messageFilterEditor; QButtonGroup* m_protocolsBgrp; QRadioButton* m_protocolV3Rbtn; QRadioButton* m_protocolV4Rbtn; private: void emoticonsThemesFromDir(QDir); void styleSheetsFromDir(QDir); public: PreferencesDlg(QWidget *parent = 0); ~PreferencesDlg(); void retranslate(); void createWidgets(); void setupConnections(); void init(); QWidget* setupSectionLayout(QList); QWidget* setupSectionLayout(QWidget*, bool = true); void setupSections(); void reloadSmileThemeList(); void toggleVisible(){if(isHidden()) show(); else hide();} void reloadStyleSheetsList(); int addSection(QWidget*, const QString &); void removeSection(QWidget*); void setupPluginsSection(QList); void setIconFormat(const UserListIconFormat&); void reloadPluginsList(); void hidePluginsSection(); public slots: void slot_chooseColor(); void edited(); void slot_setPrefs(); void slot_accept(){accept();} void slot_cancel(); void slot_validateIp(const QString &); void slot_setMsgColorMode (int mode); void slot_setSysMsgColorMode(int mode); void slot_setActivateOnMsgIn(int mode); void slot_setSoundOnMsgIn (int mode); void slot_setNlWithMessage (int mode); void slot_setNlInStatus (int mode); void slot_setExecuteCommandMode(int); void setUseCompression(int); void slot_activateSection(int idx); void reloadNetworkIfs(); void setNetworkIf(int); void updatePluginButtons(int); /** * @brief Loads or unloads plugin * * Changes state of currently selected plugin: loads if plugin is unloaded or unloads if plugin is loaded */ void loadOrUnloadPlugin(); void protocolChanged(); protected: void changeEvent(QEvent *ev) { if(ev->type() == QEvent::LanguageChange) retranslate(); else QDialog::changeEvent(ev); } signals: void myColor (const QColor &); void sysColor (const QColor &); void baseColor(const QColor &); void portChanged(int); void ipTextChanged(const QString &); void wantChangeSmileTheme(const QString &); void ulRefreshIntervalChanged(uint); void ulDeepRefreshIntervalChanged(uint); void styleSheetChanged(const QString &); void formatChanged(const UserListIconFormat&); void wantLoadPlugin(const QString&); void wantUnloadPlugin(const QString&); void useAnimatedSmiles(bool); void wantChangeProtocol(uint); }; #endif qchat-0.3/src/colorlabel.h0000644000076500017500000000375610764552354014277 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef COLORLABEL_H #define COLORLABEL_H #include #include #include /** @author Anistratov Oleg */ class ColorLabel : public QLabel { Q_OBJECT private: QColor m_color; public: ColorLabel(QWidget *parent = 0, QColor color = Qt::white); ColorLabel(const ColorLabel &); ~ColorLabel(){}; const QColor & color() const {return m_color;} void setColor(const QColor & color); protected: void mousePressEvent(QMouseEvent * ev) { if(ev->button() == Qt::LeftButton) setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); } void mouseReleaseEvent(QMouseEvent * ev) { if(ev->button() == Qt::LeftButton) { setFrameStyle(QFrame::StyledPanel); if((ev->x() >= 0 && ev->y() >= 0) && (ev->x() < width() && ev->y() < height())) emit clicked(); } } signals: void clicked(); }; #endif qchat-0.3/src/smilelabel.cpp0000644000076500017500000000650310776767275014633 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "smilelabel.h" #include #include #include SmileLabel::SmileLabel(QWidget *parent) : QLabel(parent), m_inited(false), m_selected(false) { m_movie = new QMovie(this); setMovie(m_movie); setAlignment(Qt::AlignCenter); setMouseTracking(true); } SmileLabel::~SmileLabel() { } bool SmileLabel::load( const QString & prefix ) { if(!m_filename.isEmpty()) { QPixmap pix(prefix + "/" + m_filename); m_movie->setFileName(prefix + "/" + m_filename); // m_movie->start(); m_movie->jumpToNextFrame(); m_inited = (m_movie->isValid() && !m_smileStrings.isEmpty ()); } else return false; return true; } void SmileLabel::setSmileText(const QStringList & list) { m_smileStrings = list; if(!m_smileStrings.isEmpty () && m_movie->isValid() && !m_filename.isEmpty()) { setToolTip(m_smileStrings[0]); m_inited = true; } else m_inited = false; } void SmileLabel::mouseMoveEvent(QMouseEvent* ev) { QPainter painter; if(!isVisible()) return; if(ev->x() <= 0 || ev->x() >= width() - 1 || ev->y() <= 0 || ev->y() >= height() - 1) { setMovie(m_movie); m_movie->stop(); m_selected = false; } else { m_movie->jumpToFrame(0); if(m_movie->format() == QString("gif").toAscii() || m_movie->format() == QString("mng").toAscii()) { setMovie(m_movie); m_movie->start(); } else { QPixmap pix(width(), height()); QPixmap mask(width(), height()); pix = m_movie->currentPixmap(); mask.fill(Qt::white); QPixmap tmp(width(), height()); int trans = 150; tmp.fill(QColor(trans, trans, trans)); mask.setAlphaChannel(tmp); painter.begin(&pix); painter.drawPixmap(0, 0, mask); painter.end(); setPixmap(pix); } m_selected = true; emit hovered(); } } void SmileLabel::mousePressEvent(QMouseEvent * ev) { if(m_inited) emit clicked(m_smileStrings[0]); setMovie(m_movie); ev->accept(); } int SmileLabel::pixmapWidth() { return m_movie->currentPixmap().width(); } int SmileLabel::pixmapHeight() { return m_movie->currentPixmap().height(); } void SmileLabel::unselect() { if(m_selected) { setMovie(m_movie); m_movie->stop(); m_selected = false; } } qchat-0.3/src/msghistory.h0000644000076500017500000000322710666054276014363 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef MSGHISTORY_H #define MSGHISTORY_H #include #include class Message; /** @author Anistratov Oleg */ class MsgHistory { private: Message** m_msgs; quint32 m_msgsNum; quint32 m_msgsMaxNum; quint16 m_allocStep; mutable QByteArray m_allMsgs; public: MsgHistory (); ~MsgHistory (); void addMsg(Message* msg); void fromByteArray(const QByteArray &); Message* msg(qint32 n); quint32 size() const {return m_msgsNum;} const QByteArray & toByteArray(qint32) const; }; #endif qchat-0.3/src/shortcutgrabber.h0000644000076500017500000000312510767346033015345 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SHORTCUTGRABBER_H #define SHORTCUTGRABBER_H #include #include #include "shortcutbutton.h" /** @author Anistratov Oleg */ class ShortcutGrabber : public QDialog { Q_OBJECT private: ShortcutButton* m_shortcutBtn; QKeySequence m_sequence; public: ShortcutGrabber(QWidget *parent = 0); ~ShortcutGrabber(); const QKeySequence& sequence() const {return m_sequence;} bool execute(); public slots: void acceptSequence(const QKeySequence&); }; #endif qchat-0.3/src/aboutqchat.h0000644000076500017500000000253110771561405014275 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef ABOUTQCHAT_H #define ABOUTQCHAT_H #include /** @author Anistratov Oleg @brief Creates a dialog with 'about' information */ class AboutQChat : public QDialog { Q_OBJECT public: AboutQChat(QWidget *parent = 0); ~AboutQChat(); }; #endif qchat-0.3/src/senderthread.cpp0000644000076500017500000001553111002651142015133 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include #include "senderthread.h" #include "globals.h" #include "abstractchatcore.h" SenderThread::SenderThread(QObject *parent) : QThread (parent), m_socket (NULL), m_udp (NULL), m_tcp (NULL), m_port (61100), m_datagrams (NULL), m_datagramsNum (0), m_datagramsMaxNum(0), m_timer (NULL) { m_buffer = (char*)malloc(65535); assert(NULL != m_buffer); moveToThread(this); } //\***************************************************************************** SenderThread::~SenderThread() { qDebug("[~SenderThread]"); delete m_socket; free(m_buffer); } //\***************************************************************************** void SenderThread::run() { // TODO stop timer when $m_datagramsNum == 0 and start it when new task added.. // TODO ..or create timer for every datagram(maybe include it in LargeDatagramOut) m_udp = new QUdpSocket(this); m_socket = m_udp; m_timer = new QTimer(this); m_timer->setInterval(10); m_timer->start(); connect(m_timer, SIGNAL(timeout()), this, SLOT(sending())); exec(); } //\***************************************************************************** void SenderThread::addTask(char* header, quint16 header_len, char* data, quint32 data_len, quint64 dest_uid, quint32 id) { Q_ASSERT(currentThread() == this); qDebug("[SenderThread::addTask]: ID = %u", id); LargeDatagramOut** tmp; LargeDatagramOut* dtgrm = new LargeDatagramOut(this); QHostAddress addr = QHostAddress(dest_uid); dtgrm->moveToThread(this); if(dtgrm) { dtgrm->init(header, header_len, data, data_len, dest_uid, id); connect(dtgrm, SIGNAL(wantDie(LargeDatagramOut*)), this, SLOT(deleteDatagram(LargeDatagramOut*))); qDebug("[SenderThread::addTask]: adding(%lu)", (unsigned long)id); m_datagramsNum++; if(m_datagramsMaxNum < m_datagramsNum) { m_datagramsMaxNum++; tmp = (LargeDatagramOut**)realloc(m_datagrams, m_datagramsMaxNum * sizeof(LargeDatagramOut*)); if(!tmp) delete dtgrm; else { m_datagrams = tmp; m_datagrams[m_datagramsNum - 1] = dtgrm; } } else m_datagrams[m_datagramsNum - 1] = dtgrm; } } //\***************************************************************************** void SenderThread::addFileTask(char* header, quint16 header_len, const QString & filename, quint64 dest_uid, quint32 id) { Q_ASSERT(currentThread() == this); LargeDatagramOut** tmp; LargeDatagramOut* dtgrm = new LargeDatagramOut(this); dtgrm->moveToThread(this); if(dtgrm) { connect(dtgrm, SIGNAL(wantDie(LargeDatagramOut*)), this, SLOT (deleteDatagram(LargeDatagramOut*))); connect(dtgrm, SIGNAL(sendingCancelled(quint16 )), this, SIGNAL(sendingCancelled(quint16 ))); dtgrm->init(header, header_len, filename, dest_uid, id); qDebug("[SenderThread::addFileTask]: adding(%lu)", (unsigned long)id); m_datagramsNum++; if(m_datagramsMaxNum < m_datagramsNum) { m_datagramsMaxNum++; tmp = (LargeDatagramOut**)realloc(m_datagrams, m_datagramsMaxNum * sizeof(LargeDatagramOut*)); if(!tmp) delete dtgrm; else { m_datagrams = tmp; m_datagrams[m_datagramsNum - 1] = dtgrm; } } else m_datagrams[m_datagramsNum - 1] = dtgrm; } } //\*******s********************************************************************** quint32 SenderThread::getValidID() const { for(quint32 i = 1; i > 0; i++) if(!containID(i)) return i; return 0; } //\***************************************************************************** bool SenderThread::containID(quint32 ID) const { quint32 i; for(i = 0; i < m_datagramsNum; i++) if(m_datagrams[i]->id() == ID) return true; return false; } //\***************************************************************************** void SenderThread::deleteDatagram(LargeDatagramOut* dtgrm) { Q_ASSERT(currentThread() == this); for(quint32 i = 0; i < m_datagramsNum; i++) if(dtgrm == m_datagrams[i]) { emit sendingFinished(dtgrm->id()); m_datagrams[i] = m_datagrams[m_datagramsNum - 1]; m_datagramsNum--; delete dtgrm; break; } } //\***************************************************************************** void SenderThread::slot_fragmentsRequest(char* dtgrm_, quint32 dtgrm_len) { qDebug("[SenderThread::slot_fragmentsRequest]"); quint16 ID = AbstractChatCore::packetId(dtgrm_); LargeDatagramOut* dtgrm = findDatagram(ID); if(dtgrm) dtgrm->fragmentsRequest(dtgrm_, dtgrm_len); } //\***************************************************************************** LargeDatagramOut* SenderThread::findDatagram(quint16 ID) const { for(quint32 i = 0; i < m_datagramsNum; i++) if(m_datagrams[i]->id() == ID) return m_datagrams[i]; return NULL; } //\***************************************************************************** void SenderThread::slot_acceptSending (quint16 ID) { LargeDatagramOut* dtgrm = findDatagram(ID); if(dtgrm) dtgrm->acceptSending(); } //\***************************************************************************** void SenderThread::slot_cancelTask(quint16 id) { Q_ASSERT(currentThread() == this); LargeDatagramOut* dtgrm = findDatagram(id); if(dtgrm) deleteDatagram(dtgrm); } //\***************************************************************************** int SenderThread::send(char* buf, int size, const QHostAddress& addr) { int bs = -2; if(m_socket == m_tcp) { if(m_socket->state() == QAbstractSocket::ConnectedState) bs = m_socket->write(buf, size); m_socket->flush(); } else if(m_socket == m_udp) bs = m_udp->writeDatagram(buf, size, addr, m_port); qDebug("[SenderThread::send]: dtgrm size = %d, sent = %d\n", size, bs); return bs; } qchat-0.3/src/usersstatisticswgt.h0000644000076500017500000000275710700463635016150 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERSSTATISTICSWGT_H #define USERSSTATISTICSWGT_H #include class UsersList; /** @author Anistratov Oleg */ class UsersStatisticsWgt : public QTableView { Q_OBJECT public: UsersStatisticsWgt(QWidget* = 0); ~UsersStatisticsWgt(); QByteArray saveState(); void restoreState(const QByteArray&); public slots: void sortByColumn(int); signals: void sorted(); }; #endif qchat-0.3/src/userwgt.cpp0000644000076500017500000000313210766273246014202 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "userwgt.h" #include "userinfo.h" UserWgt::UserWgt(QListWidget* parent) : QObject(0), QListWidgetItem(parent), m_info(NULL) { } //\***************************************************************************** UserWgt::~UserWgt() { qDebug("[~UserWgt]\n"); delete m_info; } //\***************************************************************************** void UserWgt::setInfo(UserInfo* info) { m_info = info; setText(m_info->nickname()); } //\***************************************************************************** qchat-0.3/src/pluginmanager.h0000644000076500017500000000422411002651142014756 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PLUGINMANAGER_H #define PLUGINMANAGER_H #include #include class QChatBasicPlugin; class QChatWidgetPlugin; class Plugin; #include "abstractchatcore.h" #include /** @author Anistratov Oleg */ class PluginManager : public QObject { Q_OBJECT private: QList m_plugins; public: PluginManager(QObject *parent = 0); ~PluginManager(); /** * @brief Gets information about available plugins * * This function checks all appropriate directories for availability of plugins,\n * trying to load every plugin and get information about it(put this information to PluginInfo object)\n * and after all unloads plugin. */ void getPlugins(); QList plugins(){return m_plugins;} Plugin* getPluginByPath(const QString&); public slots: void load(const QString&); void unload(const QString&); signals: void sendData(const QString &, const QMap &, quint64, AbstractChatCore::DataType, const QString &, uint, const QString &); }; #endif qchat-0.3/src/qchatsettings.h0000644000076500017500000002232711002426351015014 0ustar owerower/*************************************************************************** * Copyright (C) 2007-2008 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PREFERENCES_H #define PREFERENCES_H #include #include #include #include #include #include class UserListIconFormat; class MessageFilter; class Option; /** @author Anistratov Oleg */ // TODO finish moving all possible settings to m_options an m_generalOptions class QChatSettings { public: enum Mode{Serverless, Server, Combined}; /** @enum SmilesPolicy NoSmiles - never use graphic smiles DontUseSmilesFromSender - never use smiles from sender UseSmilesFromSender - use smiles from sender only if smile isn't present in local smile theme AlwaysUseSmilesFromSender - use smiles from sender even if smile is present in local smile theme */ enum SmilesPolicy{NoSmiles = 0, DontUseSmilesFromSender = 1, UseSmilesFromSender = 2, AlwaysUseSmilesFromSender = 3}; private: static QChatSettings* m_currentSettings; static QChatSettings* m_defaultSettings; static QString m_profileName; static QString m_settingsDir; static QString m_loggingDir; // Messages QColor m_myMsgsColor; QColor m_sysMsgsColor; QColor m_baseMsgColor; MessageFilter* m_messageFilter; // Network static QHostAddress m_servBroadcast; /// ip list for using instead broadcasting static QList m_ipList; // Status QString m_statusDescription[6]; QStringList m_statusDescriptions; // Now Listening /// 1 - send with message, 2 - change status, (1 | 2) - both int m_nlMode; /*static*/ QString m_nowListening; // Request message history /// -1 - request maximum messages int m_nHistoryMsgs; /// how long we will be wait answer for 'messages number request' int m_historyReqTimeout; // Smiles QString m_smilesThemePath; SmilesPolicy m_smilesPolicy; // Shortcuts QMap< QString, QList > m_shortcuts; QMap< QString, QStringList> m_shortcutsInfo; // Users List int m_usersListRefreshInterval; int m_usersListDeepRefreshInterval; QString m_executeCommandOnIncomingMsg; UserListIconFormat* m_iconFormat; static Mode m_mode; int m_toolbarIconsSize; QMap m_options; static QMap m_generalOptions; public: QChatSettings(); ~QChatSettings(){}; void initOptions(); static void initGeneralOptions(); void setOption(const QString&, QVariant); QVariant option(const QString&) const; bool boolOption(const QString&) const; qint64 intOption(const QString&) const; QString strOption(const QString&) const; QHostAddress hostAddressOption(const QString&) const; static QString defaultSmilesDir(); static QString defaultSmilesDir(QList); void saveOptions(QSettings*); void saveGeneralOptions(QSettings*); void loadOptions(QSettings*); void loadGeneralOptions(QSettings*); void save(QSettings*, QMap); void load(QSettings*, QMap&); static void setSettingsDir (const QString & dir){m_settingsDir = dir;} void setMyColor (const QColor & color) {m_myMsgsColor = color;} void setSysColor (const QColor & color) {m_sysMsgsColor = color;} void setBaseColor (const QColor & color) {m_baseMsgColor = color;} void setStatusDescription(const QString & descr, int status); static QHostAddress realBroadcast(); static QHostAddress broadcast(); static const QString & settingsDir (){return m_settingsDir;} const QString & statusDescription(int status) const; const QColor & sysColor () const {return m_sysMsgsColor;} const QColor & myColor () const {return m_myMsgsColor;} const QColor & baseColor() const {return m_baseMsgColor;} void setNHistoryMsgs(int value){m_nHistoryMsgs = value;} int nHistoryMsgs() const {return m_nHistoryMsgs;} void setHistoryReqTimeout(int value){m_historyReqTimeout = value;} int historyReqTimeout() const {return m_historyReqTimeout;} void setNlMode(int value){Q_ASSERT(value >= 0 && value <= 3); m_nlMode = value;} int nlMode() const{return m_nlMode;} void setSmilesThemePath(const QString & value) {m_smilesThemePath = value; if(!value.isEmpty() && value[value.size() - 1] != '/') m_smilesThemePath += "/";} const QString & smilesThemePath() const {return m_smilesThemePath;} void setExecuteCommandOnIncomingMsg(const QString& value){m_executeCommandOnIncomingMsg = value;} const QString & executeCommandOnIncomingMsg() const {return m_executeCommandOnIncomingMsg;} void setUsersListRefreshInterval(int value){m_usersListRefreshInterval = value;} int usersListRefreshInterval() const {return m_usersListRefreshInterval;} void setUsersListDeepRefreshInterval(int value){m_usersListDeepRefreshInterval = value;} int usersListDeepRefreshInterval() const {return m_usersListDeepRefreshInterval;} void setStatusDescriptions(const QStringList & value){m_statusDescriptions = value;} void appendStatusDescription(const QString & value); void removeStatusDescription(const QString & value){m_statusDescriptions.removeAll(value);} QStringList statusDescriptions() const {return m_statusDescriptions;} void setNowListening(const QString& value){m_nowListening = value;} QString nowListening() const {return m_nowListening;} void setMode(Mode m) {m_mode = m;} Mode mode() const {return m_mode;} static void addIpListEntry(const QHostAddress& addr) {if(!m_ipList.contains(addr)) m_ipList.append(addr);} static void removeIpListEntry(const QHostAddress& addr) {m_ipList.removeAll(addr);} static const QList ipList(){return m_ipList;} static void clearIpList(){m_ipList.clear();} static void setSettings(QChatSettings* value){m_currentSettings = value;} static QChatSettings* settings(); static QString profileName() {return m_profileName;} static void setProfileName(const QString & name){m_profileName = name;} void setIconFormat(UserListIconFormat* theValue){m_iconFormat = theValue;} UserListIconFormat* iconFormat() const {return m_iconFormat;} void setToolbarIconsSize(int theValue){m_toolbarIconsSize = theValue;} int toolbarIconsSize() const {return m_toolbarIconsSize;} // Shortcuts void createShortcut(const QString&, const QString&, const QString&, const QKeySequence&); void addShortcut(const QString& shrtctname, const QKeySequence& shrtct) {if(!m_shortcuts[shrtctname].contains(shrtct)) m_shortcuts[shrtctname].append(shrtct);} void setShortcut(const QString& shrtctname, const QKeySequence& shrtct) {m_shortcuts[shrtctname].clear(); m_shortcuts[shrtctname].append(shrtct);} void clearShortcut(const QString& shrtctname){m_shortcuts[shrtctname].clear();} QList shortcuts(const QString& shctname) const {return m_shortcuts[shctname];} QKeySequence shortcut(const QString& shctname) const {if(m_shortcuts[shctname].size() > 0) return m_shortcuts[shctname][0]; return QKeySequence();} const QMap< QString, QList >& allShortcuts(){return m_shortcuts;} void setAllShortcuts(const QMap< QString, QList >& value){m_shortcuts = value;} const QString& shortcutDisplayName(const QString& name) {Q_ASSERT(m_shortcutsInfo.value(name).size() > 0); return m_shortcutsInfo.value(name)[0];} const QString& shortcutGroup(const QString& name) {Q_ASSERT(m_shortcutsInfo.value(name).size() > 1); return m_shortcutsInfo.value(name)[1];} bool shortcutExists(const QString& name) {return m_shortcutsInfo.value(name).size();} void setSmilesPolicy(SmilesPolicy theValue ){m_smilesPolicy = theValue;} void setSmilesPolicy(int theValue ){m_smilesPolicy = (QChatSettings::SmilesPolicy)theValue;} SmilesPolicy smilesPolicy() const {return m_smilesPolicy;} void setMessageFilter(MessageFilter* theValue){m_messageFilter = theValue;} MessageFilter* messageFilter() const {return m_messageFilter;} static void setLoggingDir(const QString& theValue){m_loggingDir = theValue;} static QString loggingDir(){return m_loggingDir;} }; #endif qchat-0.3/src/userslistwgt.cpp0000755000076500017500000001705311002603746015255 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "userslistwgt.h" #include "globals.h" #include #include #include #include #include #include #include "singlemessagewgt.h" #include "userwgt.h" #include "userinfo.h" #include "qchaticon.h" #include "userlisticonformat.h" #include "qchatsettings.h" UsersListWgt::UsersListWgt(QWidget *parent) : QListWidget(parent) { m_menu = new QMenu (this); m_singleMessageAct = new QAction(this); m_showInfoAct = new QAction(this); m_sendFileAct = new QAction(this); m_privateChatAct = new QAction(this); m_menu->addAction(m_singleMessageAct); m_menu->addAction(m_sendFileAct); m_menu->addAction(m_privateChatAct); // FIXME move to setIcons ":/ m_sendFileAct ->setIcon(QChatIcon::icon("send-file")); m_singleMessageAct->setIcon(QChatIcon::icon("private-message")); m_privateChatAct ->setIcon(QChatIcon::icon("private-chat")); connect(m_singleMessageAct, SIGNAL(triggered(bool)), this , SLOT (slot_singleMessage())); connect(m_sendFileAct , SIGNAL(triggered(bool)), this , SLOT (slot_sendFile())); connect(m_privateChatAct , SIGNAL(triggered(bool)), this , SLOT (slot_privateChat())); connect(this , SIGNAL( itemDoubleClicked(QListWidgetItem*)), this , SLOT (send_itemDoubleClicked(QListWidgetItem*))); setIconSize(QSize(QChatSettings::settings()->iconFormat()->totalWidth(), QChatSettings::settings()->iconFormat()->totalHeight())); setSortingEnabled(true); setMouseTracking(true); setAcceptDrops(true); retranslate(); } //\***************************************************************************** UsersListWgt::~UsersListWgt() { qDebug("[~UsersListWgt]\n"); } //\***************************************************************************** void UsersListWgt::retranslate() { m_singleMessageAct->setText(tr("Send Single Message.." )); m_showInfoAct ->setText(tr("Show User Information..")); m_sendFileAct ->setText(tr("Send File..")); m_privateChatAct ->setText(tr("Private Chat..")); } //\***************************************************************************** void UsersListWgt::addUser(UserWgt* user) { QFont fnt; Q_ASSERT(NULL != user); if(user->info()) { qDebug("[UsersListWgt::addUser]: status = %d", user->info()->status()); if(user->info()->status() == Globals::FREE || user->info()->status() == Globals::READY4CHAT) fnt.setBold(true); user->setFont(fnt); user->setText(QChatSettings::settings()->iconFormat()->text(). replace(QRegExp("%nick") , user->info()->nickname()). replace(QRegExp("%compname") , user->info()->compName()). replace(QRegExp("%firstname") , user->info()->firstName()). replace(QRegExp("%lastname") , user->info()->lastName()). replace(QRegExp("%secondname"), user->info()->secondName()). replace(QRegExp("%version") , user->info()->programVerName()). replace(QRegExp("%uid") , QString("%1").arg(user->info()->uid())). replace(QRegExp("%ip") , QHostAddress(user->info()->ip()).toString())); } if(row(user) >= 0) setItemHidden(user, false); else addItem(user); user->setSizeHint(QSize(1, QChatSettings::settings()->iconFormat()->totalHeight())); qDebug("[UsersListWgt::addUser]: added: '%s'", user->text().toLocal8Bit().data()); } //\***************************************************************************** void UsersListWgt::hideUser(UserWgt* user) { takeItem(row(user)); } //\***************************************************************************** void UsersListWgt::clear() { int cnt = count(); UserWgt* item_; while(count() || cnt) { item_ = (UserWgt*)item(0); if(NULL != item_) { item_->setText(""); takeItem(0); } --cnt; } } //\***************************************************************************** void UsersListWgt::slot_singleMessage() { UserWgt* usr = (UserWgt*)(currentItem()); SingleMessageWgt* smw = new SingleMessageWgt(QString(tr("Message to ")) + usr->info()->nickname(), "", usr->info()->uid(), QHostAddress(usr->info()->ip()) ); connect(smw , SIGNAL(singleMessage (QString, quint64, bool)), this, SIGNAL(singleMessage (QString, quint64, bool))); smw->show(); } //\***************************************************************************** void UsersListWgt::slot_sendFile() { UserWgt* usr = (UserWgt*)(currentItem()); if(usr) emit wantSendFile(usr->info()->uid()); } //\***************************************************************************** void UsersListWgt::mousePressEvent (QMouseEvent * ev) { int i; int nitems = 0; int cnt = count(); int height = 0; for(i = 0; i < cnt; i++) if(!isItemHidden(item(i))) nitems++; if(nitems) height = (item(0)->sizeHint().height()) * nitems; if(ev->button() == Qt::RightButton && currentItem() && isItemSelected(currentItem()) && !isItemHidden(currentItem()) && ev->y() < height ) { // UserWgt* usr = (UserWgt*)(currentItem()); // m_privateChatAct ->setText((tr("Private Chat with ") + usr->info()->nickname())); // m_sendFileAct ->setText((tr("Send File to " ) + usr->info()->nickname())); // m_singleMessageAct->setText((tr("Single Message to ") + usr->info()->nickname())); m_menu->popup(ev->globalPos()); } QListWidget::mousePressEvent(ev); } //\***************************************************************************** void UsersListWgt::slot_privateChat() { UserWgt* usr = (UserWgt*)(currentItem()); if(usr) emit wantPrivateChat(usr->info()->nickname(), usr->info()->uid()); } //\***************************************************************************** void UsersListWgt::send_itemDoubleClicked(QListWidgetItem* item) { emit itemDoubleClicked((UserWgt*)item); } void UsersListWgt::dropEvent(QDropEvent * ev) { ev->acceptProposedAction(); qDebug("[UsersListWgt::dropEvent]: data = %s\n", ev->mimeData()->text().toLocal8Bit().data()); } void UsersListWgt::dragEnterEvent(QDragEnterEvent * ev) { ev->acceptProposedAction(); } void UsersListWgt::dragMoveEvent(QDragMoveEvent * ev) { ev->acceptProposedAction(); } qchat-0.3/src/shortcutbutton.cpp0000644000076500017500000000414710767345676015630 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "shortcutbutton.h" ShortcutButton::ShortcutButton(QWidget *parent) : QPushButton(parent) { setText(tr("Input Shortcut")); } ShortcutButton::~ShortcutButton() { } void ShortcutButton::keyPressEvent(QKeyEvent* ev) { if(ev->isAutoRepeat()) return; setShortcutText(ev); if(/*ev->modifiers() &&*/ validKey(ev->key())) { emit sequenceAccepted(QKeySequence(ev->modifiers() + validKey(ev->key()))); setText(tr("Input Shortcut")); releaseKeyboard(); } } void ShortcutButton::keyReleaseEvent(QKeyEvent* ev) { setShortcutText(ev); } int ShortcutButton::validKey(int key) { if(key < 0 || key == Qt::Key_unknown) return 0; switch(key) { case Qt::Key_Shift : case Qt::Key_Control : case Qt::Key_Alt : case Qt::Key_Meta : case Qt::Key_AltGr : return 0; } return key; } void ShortcutButton::setShortcutText(QKeyEvent* ev) { QString seq = QKeySequence(ev->modifiers() + validKey(ev->key())).toString(); if(!seq.isEmpty()) setText(seq); else setText(tr("Input Shortcut")); } qchat-0.3/src/userslist.h0000755000076500017500000000375310763635737014224 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERLIST_H #define USERLIST_H #include #include "userinfo.h" class UserWgt; /** @author Anistratov Oleg */ class UsersList { private: UserWgt** m_users; quint32 m_usersNum; quint32 m_maxUsersNum; UserWgt** m_hiddenUsers; quint32 m_hiddenUsersNum; quint32 m_maxHiddenUsersNum; public: UsersList(); ~UsersList(); bool enabled (quint64) const; bool exists (quint64) const; UserWgt* findUser (quint64) const; UserWgt* findHidden(quint64) const; qint32 findNum (quint64) const; UserWgt* user (int n) const; quint32 num ( ) const {return m_usersNum;} void addUser (UserWgt*); void disableAll (); void enableAll (); UserWgt* disable (quint64); UserWgt* enable (quint64); UserWgt* enableIfExists(quint64); }; #endif qchat-0.3/src/userwgt.h0000644000076500017500000000317510670750401013641 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERWGT_H #define USERWGT_H #include #include class UserInfo; class UserStatistics; /** @author Anistratov Oleg */ class UserWgt : public QObject, public QListWidgetItem { Q_OBJECT private: UserInfo* m_info; UserStatistics* m_stats; public: UserWgt(QListWidget* parent = 0); ~UserWgt(); void setInfo(UserInfo* info); UserInfo* info() const {return m_info;} void setStats(UserStatistics* value){m_stats = value;} UserStatistics* stats() const {return m_stats;} }; #endif qchat-0.3/src/plugin.h0000644000076500017500000000411410772323215013433 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PLUGIN_H #define PLUGIN_H #include #include #include class QChatBasicPlugin; class QChatWidgetPlugin; /** @author Anistratov Oleg */ class Plugin { public: enum PluginType{Basic, Widget}; private: QString m_path; QString m_name; QPluginLoader* m_plugin; PluginType m_type; bool m_isLoaded; public: Plugin(); ~Plugin(); void setPath(const QString& path){m_path = path;} const QString& path() const {return m_path;} void setName(const QString& name){m_name = name;} const QString& name() const {return m_name;} QPluginLoader* plugin(){return m_plugin;} void setPlugin(QPluginLoader* plug){m_plugin = plug;} void setType(PluginType theValue){m_type = theValue;} PluginType type() const {return m_type;} bool isLoaded(){return m_isLoaded;} bool load(); bool unload(); QObject* instance(); QChatBasicPlugin* instanceBasic(); QChatWidgetPlugin* instanceWgt(); }; #endif qchat-0.3/src/iplisteditor.cpp0000644000076500017500000000703211002407233015173 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "iplisteditor.h" #include #include #include "qchatsettings.h" IpListEditor::IpListEditor(QWidget *parent) : QWidget(parent) { QGridLayout* grid = new QGridLayout(this); QGridLayout* dlgGrid; m_useIpListChbx = new QCheckBox (this); m_showEditorBtn = new QPushButton(this); m_ipListEdit = new QTextEdit (this); m_okBtn = new QPushButton(this); m_cancelBtn = new QPushButton(this); m_editorDlg = new QDialog (this); dlgGrid = new QGridLayout(m_editorDlg); dlgGrid->addWidget(m_ipListEdit, 0, 0, 3, 1); dlgGrid->addWidget(m_okBtn , 0, 1); dlgGrid->addWidget(m_cancelBtn , 1, 1); dlgGrid->setMargin(0); m_editorDlg->hide(); grid->addWidget(m_useIpListChbx, 0, 0); grid->addWidget(m_showEditorBtn, 0, 1); grid->setColumnStretch(0, 1); grid->setMargin(0); connect(m_showEditorBtn, SIGNAL(clicked()), this, SLOT(showEditor())); connect(m_okBtn , SIGNAL(clicked()), this, SLOT(applyChanges())); connect(m_cancelBtn , SIGNAL(clicked()), this, SLOT(discardChanges())); connect(m_useIpListChbx, SIGNAL(stateChanged(int)), this, SLOT(setUseIpList(int))); retranslate(); } IpListEditor::~IpListEditor() { qDebug("[~IpListEditor]"); } void IpListEditor::retranslate() { m_useIpListChbx->setText(tr("Use IP list instead of broadcasting")); m_showEditorBtn->setText(tr("..")); m_okBtn ->setText(tr("Ok")); m_cancelBtn ->setText(tr("Cancel")); m_showEditorBtn->setToolTip(tr("Edit IP List..")); m_ipListEdit ->setToolTip(tr("Enter one IP per line")); m_editorDlg ->setWindowTitle(tr("IP List Editor")); } void IpListEditor::showEditor() { m_ipListEdit->clear(); foreach(QHostAddress ip, QChatSettings::ipList()) m_ipListEdit->append(ip.toString()); m_editorDlg->show(); } void IpListEditor::applyChanges() { QStringList ipList = m_ipListEdit->toPlainText().split("\n"); QChatSettings::clearIpList(); foreach(QString ip, ipList) { if(QHostAddress(ip).toIPv4Address() != 0) QChatSettings::addIpListEntry(QHostAddress(ip)); } m_editorDlg->accept(); } void IpListEditor::discardChanges() { m_editorDlg->reject(); } void IpListEditor::setUseIpList(int checked) { if(checked == Qt::Checked) QChatSettings::settings()->setOption("UseIPList", true); else QChatSettings::settings()->setOption("UseIPList", false); } void IpListEditor::init() { m_useIpListChbx->setChecked(QChatSettings::settings()->boolOption("UseIPList")); } qchat-0.3/src/message.h0000644000076500017500000000677010770513444013576 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef MESSAGE_H #define MESSAGE_H #include #include #include #include "globals.h" /** @author Anistratov Oleg */ class Message { private: /// version of QChat which sent this msg quint16 m_version; /// type of msg : MESSAGE, INFO, ERROR, etc quint16 m_type; quint64 m_srcIp; quint64 m_srcUid; quint64 m_sendTime; quint64 m_receiveTime; QColor m_color; QString m_msg; QString m_userName; QString m_compName; bool m_requested; bool m_isHtml; bool m_isIncoming; bool m_isVisible; public: Message(QC_DatagramHeader* Hdr = 0, quint64 = 0); ~Message(); quint16 version () const {return m_version ;} quint16 type () const {return m_type ;} quint64 srcIp () const {return m_srcIp ;} quint64 sendTime () const {return m_sendTime ;} quint64 receiveTime () const {return m_receiveTime;} const QColor & color () const {return m_color ;} const QString & userName() const {return m_userName ;} const QString & compName() const {return m_compName ;} const QString & msg () const {return m_msg ;} bool requested () const {return m_requested ;} void setVersion (quint16 ver) {m_version = ver ;} void setType (quint16 type) {m_type = type ;} void setSrcIp (quint64 ip) {m_srcIp = ip ;} void setSendTime (quint64 tm) {m_sendTime = tm ;} void setReceiveTime(quint64 tm) {m_receiveTime = tm ;} void setColor (const QColor & color){m_color = color;} void setUserName (const QString & name){m_userName = name ;} void setCompName (const QString & name){m_compName = name ;} void setMsg (const QString & msg) {m_msg = msg ;} void setMsg (const QC_DatagramHeader* Hdr); void setRequested (bool rq){m_requested = rq;} void setIsHtml(bool value) {m_isHtml = value;} bool isHtml() const {return m_isHtml;} void setSrcUid( const quint64& theValue ){m_srcUid = theValue;} quint64 srcUid() const {return m_srcUid;} void setIsIncoming(bool theValue){m_isIncoming = theValue;} bool isIncoming() const {return m_isIncoming;} void setIsVisible(bool theValue){m_isVisible = theValue;} bool isVisible() const {return m_isVisible;} }; #endif qchat-0.3/src/qchateventfilter.cpp0000644000076500017500000000710210777007540016045 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchateventfilter.h" #include #include #include "qchatsettings.h" #include "chatwgt.h" #include "singlemsgshistoryview.h" // #include // // #include // #include // #include QChatEventFilter::QChatEventFilter(QObject *parent) : QObject(parent), m_chatWgt(NULL) { // int i; // int grab_keys[4] = {0x25, 0x40, 0x6d, 0x71}; /* alt and ctl keys */ // for (i = 0; i < 4; i++) // XGrabKey(QX11Info::display(), grab_keys[i], AnyModifier, QX11Info::appRootWindow(), False, GrabModeAsync, GrabModeAsync); // XGrabKey(QX11Info::display(), XKeysymToKeycode(QX11Info::display(), XK_Escape), 0, QX11Info::appRootWindow(), False, GrabModeAsync, GrabModeAsync); // XGrabKey(QX11Info::display(), XKeysymToKeycode(QX11Info::display(), XK_H), AnyModifier, QX11Info::appRootWindow(), False, GrabModeAsync, GrabModeAsync); // XGrabKeyboard(QX11Info::display(), QX11Info::appRootWindow(), False, GrabModeAsync, GrabModeAsync, CurrentTime); // XSync(QX11Info::display(), False); } QChatEventFilter::~QChatEventFilter() { qDebug("[~QChatEventFilter]"); } bool QChatEventFilter::eventFilter(QObject* obj, QEvent* ev) { QKeySequence seq; bool processed = false; if(ev->type() == QEvent::KeyPress/* 6*/) { QKeyEvent* keyEvent = static_cast(ev); seq = keyEvent->key() + keyEvent->modifiers(); processed = true; if(QChatSettings::settings()->shortcuts("Hide2Tray").contains(seq)) emit wantHide2Tray(); else if(m_chatWgt) { if(QChatSettings::settings()->shortcuts("NextNewMessage").contains(seq)) m_chatWgt->smhView()->nextNewMessage(); else if(QChatSettings::settings()->shortcuts("PrevNewMessage").contains(seq)) m_chatWgt->smhView()->prevNewMessage(); else if(QChatSettings::settings()->shortcuts("NextOpenedMessage").contains(seq)) m_chatWgt->smhView()->nextOpenedMessage(); else if(QChatSettings::settings()->shortcuts("PrevOpenedMessage").contains(seq)) m_chatWgt->smhView()->prevOpenedMessage(); else if(QChatSettings::settings()->shortcuts("CloseAllNewMessages").contains(seq)) m_chatWgt->smhView()->closeAllNewMessages(); else if(QChatSettings::settings()->shortcuts("CloseAllOpenedMessages").contains(seq)) m_chatWgt->smhView()->closeAllOpenedMessages(); else processed = false; } } return processed ? true : QObject::eventFilter(obj, ev); } void QChatEventFilter::setChatWgt(ChatWgt* wgt) { m_chatWgt = wgt; } qchat-0.3/src/usersstatisticsmodel.h0000644000076500017500000000575110704206041016432 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERSSTATISTICSMODEL_H #define USERSSTATISTICSMODEL_H #include #include class UsersList; class UserWgt; /** @author Anistratov Oleg */ class UsersStatisticsModel : public QAbstractTableModel { Q_OBJECT public: enum ColumnID{NickName, Gender, RealName, Status, StatusDescription, IP, CompName, OS, Uptime, ChatTime, Last, Invalid = 1000}; private: UsersList* m_users; QVector m_columns; mutable int m_sortingColumn; mutable Qt::SortOrder m_sortOrder; mutable UserWgt** m_usersOrder; mutable int m_usersOrderSize; mutable int m_usersOrderMaxSize; private: int cmp(UserWgt*, UserWgt*, int, Qt::SortOrder) const; public: UsersStatisticsModel(QObject* = 0); ~UsersStatisticsModel(); int rowCount(const QModelIndex & = QModelIndex()) const; int columnCount(const QModelIndex & = QModelIndex()) const {return m_columns.size();} QVariant data (const QModelIndex &index, int role) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; void sort (int column, Qt::SortOrder order = Qt::AscendingOrder) const; void resort() const {sort(m_sortingColumn, m_sortOrder);} void setUsers(UsersList* u) {m_users = u;} void resetModel() {reset();} int columnID(uint n) {if(n >= (uint)m_columns.size()) return Invalid; else return m_columns[n];} int columnsCount() const {return m_columns.size();} void clearColumns() {m_columns.clear();} void addColumn(uint c) {if(c < Last) m_columns.append(c);} int sortingColumn() const {return m_sortingColumn;} void setSortingColumn(int c) {m_sortingColumn = c; resort();} Qt::SortOrder sortOrder() const {return m_sortOrder;} void setSortOrder(Qt::SortOrder o) {m_sortOrder = o; resort();} }; #endif qchat-0.3/src/singlemsgshistory.cpp0000644000076500017500000000257310770030502016264 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "singlemsgshistory.h" #include "message.h" SingleMsgsHistory::SingleMsgsHistory(QObject *parent) : QObject(parent) { } SingleMsgsHistory::~SingleMsgsHistory() { } void SingleMsgsHistory::addMessage(Message * msg) { if(msg->isIncoming()) m_messagesIn.append(msg); else m_messagesOut.append(msg); } qchat-0.3/src/qchatmainwindow.cpp0000644000076500017500000000244010771514655015676 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchatmainwindow.h" QChatMainWindow::QChatMainWindow(QWidget *parent) : QMainWindow(parent) { } QChatMainWindow::~QChatMainWindow() { qDebug("[~QChatMainWindow]"); } void QChatMainWindow::addToolBar(QToolBar *) { } qchat-0.3/src/qchaticon.cpp0000644000076500017500000001217210773234573014455 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchaticon.h" #include #include #include #include #include #include "qchatsettings.h" QMap QChatIcon::m_icons; QMap QChatIcon::m_iconPaths; QChatIcon::QChatIcon() { } QChatIcon::~QChatIcon() { qDebug("[~QChatIcon]"); } const QIcon & QChatIcon::icon(const QString & icon_name) { return m_icons[icon_name]; } void QChatIcon::initIcons() { QStringList icon_names; QStringList icon_types; QString full_path; QString icons_path; if(!QDir((icons_path = QChatSettings::settings()->settingsDir() + "/icons/")).exists()) #ifdef Q_OS_LINUX icons_path = QCoreApplication::applicationDirPath() + "/../share/qchat/icons/"; #else icons_path = QCoreApplication::applicationDirPath() + "/share/icons/"; #endif if(!QDir(icons_path).exists()) icons_path = ":/icons/"; icon_types.append("svg"); icon_types.append("png"); icon_types.append("jpg"); icon_types.append("gif"); icon_types.append(""); icon_names.append("format-text-bold"); icon_names.append("format-text-italic"); icon_names.append("format-text-underline"); icon_names.append("insert-table"); icon_names.append("application-exit"); icon_names.append("help-about"); icon_names.append("configure"); icon_names.append("tab-new"); icon_names.append("tab-close"); icon_names.append("user-male"); icon_names.append("user-female"); icon_names.append("personal"); icon_names.append("emotes"); icon_names.append("add-profile"); icon_names.append("remove-profile"); icon_names.append("edit-rename"); icon_names.append("send-file"); icon_names.append("private-message"); icon_names.append("private-chat"); icon_names.append("write-settings"); icon_names.append("animated-new-msg"); icon_names.append("im-status-message-edit"); icon_names.append("tray-icon"); icon_names.append("unknown"); icon_names.append("message-opened"); icon_names.append("message-unread"); icon_names.append("dialog-close"); icon_names.append("go-next"); icon_names.append("go-previous"); icon_names.append("status/user-ready-for-chat"); icon_names.append("status/user-online"); icon_names.append("status/user-dnd"); icon_names.append("status/user-offline"); icon_names.append("status/user-invisible"); icon_names.append("status/user-busy"); icon_names.append("status/user-away"); icon_names.append("status/user-away-extended"); foreach(QString in, icon_names) { if(!in.contains(".")) { foreach(QString it, icon_types) { full_path = icons_path + in + "." + it; if(QFile::exists(full_path)) { m_icons .insert(in, QIcon(full_path)); m_iconPaths.insert(in, full_path); break; } } } else { full_path = icons_path + in; if(QFile::exists(full_path)) { m_icons .insert(in, QIcon(full_path)); m_iconPaths.insert(in, full_path); break; } } } } const QString & QChatIcon::iconPath(const QString & icon_name) { return m_iconPaths[icon_name]; } QPixmap* QChatIcon::newPixmap(const QString & icon_name, int wd, int he) { QSize sz(wd, he); if(wd < 0 || he < 0) sz = m_icons[icon_name].actualSize(QSize(-1, -1)); // FIXME sz must be equal size of icon QPixmap* pix = new QPixmap(sz); drawPixmap(pix, icon_name, QSize(wd, he)); return pix; } QPixmap QChatIcon::pixmap(const QString& icon_name, int wd, int he) { QSize sz(wd, he); if(wd < 0 || he < 0) sz = m_icons[icon_name].actualSize(QSize(-1, -1)); // FIXME sz must be equal size of icon QPixmap pix(sz); drawPixmap(&pix, icon_name, QSize(wd, he)); return pix; } void QChatIcon::drawPixmap(QPixmap* pix, const QString & icon_name, const QSize& sz) { if(iconPath(icon_name).contains(".svg")) { QSvgRenderer svg(iconPath(icon_name)); QPixmap tmp(sz); QPainter painter; tmp.fill(Qt::black); pix->setAlphaChannel(tmp); painter.begin(pix); svg.render(&painter); painter.end(); } else *pix = m_icons[icon_name].pixmap(sz); } qchat-0.3/src/picturescrollarea.cpp0000644000076500017500000000562310766273620016230 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "picturescrollarea.h" #include PictureScrollArea::PictureScrollArea(QWidget *parent) : QScrollArea(parent) { setWindowTitle(tr("Full size of picture")); } //\***************************************************************************** void PictureScrollArea::resizeEvent (QResizeEvent * ev) { if(widget()) { if(frameSize().width() >= widget()->width() && frameSize().height() >= widget()->height()) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); } else { setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); } } QScrollArea::resizeEvent(ev); } //\***************************************************************************** void PictureScrollArea::mousePressEvent(QMouseEvent* ev) { if(ev->button() == Qt::LeftButton) { m_lastX = ev->globalX(); m_lastY = ev->globalY(); } QScrollArea::mousePressEvent(ev); } //\***************************************************************************** void PictureScrollArea::mouseMoveEvent(QMouseEvent* ev) { int x = ev->globalX(); int y = ev->globalY(); int ver = m_lastY - y; int hor = m_lastX - x; m_lastX = x; m_lastY = y; verticalScrollBar() ->setValue(ver + verticalScrollBar ()->value()); horizontalScrollBar()->setValue(hor + horizontalScrollBar()->value()); QScrollArea::mouseMoveEvent(ev); } //\***************************************************************************** void PictureScrollArea::mouseDoubleClickEvent(QMouseEvent* ev) { if(windowState() == Qt::WindowFullScreen) setWindowState(Qt::WindowNoState); else setWindowState(Qt::WindowFullScreen); QScrollArea::mouseDoubleClickEvent(ev); } //\***************************************************************************** qchat-0.3/src/msghistory.cpp0000644000076500017500000001044510771514553014712 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "msghistory.h" #include #include "message.h" MsgHistory::MsgHistory() : m_msgsNum (0), m_msgsMaxNum(1024), m_allocStep (1024) { m_msgs = (Message**)malloc(m_msgsMaxNum * sizeof(Message*)); assert(NULL != m_msgs); } MsgHistory::~MsgHistory() { qDebug("[~MsgHistory]"); for(uint i = 0; i < m_msgsNum; i++) delete m_msgs[i]; free(m_msgs); } void MsgHistory::addMsg(Message* new_msg) { if(++m_msgsNum == m_msgsMaxNum) { m_msgsMaxNum += m_allocStep; m_msgs = (Message**)realloc(m_msgs, m_msgsMaxNum * sizeof(Message*)); } m_msgs[m_msgsNum - 1] = new_msg; } Message* MsgHistory::msg(qint32 n) { if(n >= 0 && n < (qint32)m_msgsNum) return m_msgs[n]; return NULL; } const QByteArray & MsgHistory::toByteArray(qint32 max_num) const { int i; char buf[38]; // format of array: // 2 m_version; // 2 m_type; // 8 m_srcIp; // 8 m_sendTime; // 8 m_receiveTime; // 4 m_color; // 4 m_msg.size() // 1 m_userName.size(); // 1 m_compName.size(); // _______________ // 38 // QString m_msg; // QString m_userName; // QString m_compName; // _______________ // 38 + m_msg.size() + m_userName.size() + m_compName.size() m_allMsgs.clear(); i = (max_num >= (int)m_msgsNum || max_num < 0 ? 0 : m_msgsNum - max_num - 1); for(; i < (int)m_msgsNum; i++) { catUS2str (buf , m_msgs[i]->version()); catUS2str (buf + 2 , m_msgs[i]->type()); catULL2str(buf + 4 , m_msgs[i]->srcIp()); catULL2str(buf + 12, m_msgs[i]->sendTime()); catULL2str(buf + 20, m_msgs[i]->receiveTime()); buf[28] = (uchar)m_msgs[i]->color().red(); buf[29] = (uchar)m_msgs[i]->color().green(); buf[30] = (uchar)m_msgs[i]->color().blue(); buf[31] = (uchar)m_msgs[i]->color().alpha(); catULL2str(buf + 32, m_msgs[i]->msg().toUtf8().size()); buf[36] = (char)m_msgs[i]->userName().toUtf8().size(); buf[37] = (char)m_msgs[i]->compName().toUtf8().size(); m_allMsgs.append(QByteArray(buf, 38)); m_allMsgs.append(m_msgs[i]->msg ().toUtf8()); m_allMsgs.append(m_msgs[i]->userName().toUtf8()); m_allMsgs.append(m_msgs[i]->compName().toUtf8()); } return m_allMsgs; } void MsgHistory::fromByteArray(const QByteArray & arr) { Message* msg; uint size = arr.size(); uint msgl; uint cnl; uint unl; char* data = (char * )arr.data(); for(uint i = 0; i < size; ) { msg = new Message; i += 38; if(i < size) { msg->setVersion (str2US (data )); msg->setType (str2US (data + 2 )); msg->setSrcIp (str2ULL(data + 4 )); msg->setSendTime (str2ULL(data + 12)); msg->setReceiveTime(str2ULL(data + 20)); msg->setColor (QColor((uchar)data[28], (uchar)data[29], (uchar)data[30], (uchar)data[31])); msgl = str2ULL(data + 32); unl = data[36]; cnl = data[37]; i += msgl + unl + cnl; if(i < size) { msg->setMsg (QString().fromUtf8(data + 38 , msgl)); msg->setUserName(QString().fromUtf8(data + 38 + msgl , unl )); msg->setCompName(QString().fromUtf8(data + 38 + msgl + unl, cnl )); data += 38 + msgl + unl + cnl; msg->setRequested(true); addMsg(msg); } else break; } } } qchat-0.3/src/messagefilter.h0000644000076500017500000000423311001130551014752 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef MESSAGEFILTER_H #define MESSAGEFILTER_H #include #include class FiltrationRule; class Message; /** @author Anistratov Oleg */ class MessageFilter { private: QList m_whiteRules; QList m_blackRules; public: MessageFilter(); ~MessageFilter(); void addBlackRule(FiltrationRule* rule) {if(!m_blackRules.contains(rule)) m_blackRules.append(rule);} void addWhiteRule(FiltrationRule* rule) {if(!m_whiteRules.contains(rule)) m_whiteRules.append(rule);} QList blackRules(){return m_blackRules;} QList whiteRules(){return m_whiteRules;} void removeRule(FiltrationRule* rule); bool isGoodMessage(Message*); bool isBadMessage (Message*); /** * @brief Accepts or rejects message based on filtration rules * @param msg message to filter * @param blacklist is filtration going by blacklist or whitelist */ bool validateMessage(Message* msg, bool blacklist = true); void save(QSettings*) const; void load(QSettings*); }; #endif qchat-0.3/src/smileswgt.cpp0000644000076500017500000001162610772030714014513 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "smileswgt.h" #include "globals.h" #include #include #include #include #include #include #include #include #include #include #include #include "smilelabel.h" #include "qchaticon.h" SmilesWgt::SmilesWgt(QWidget *parent) : QWidget(parent), m_inited(false), m_smilesNum(0), m_smilesMaxNum(100) { // QScrollArea* scrll = new QScrollArea(parentWidget()); m_grid = new QGridLayout(this); m_smiles = (SmileLabel**)malloc(m_smilesMaxNum * sizeof(SmileLabel*)); Q_ASSERT(NULL != m_smiles); m_grid->setMargin(1); m_grid->setSpacing(1); setMouseTracking(true); // resize(600, 400); // scrll->setWidget(this); // scrll->show(); setWindowIcon(QChatIcon::icon("emotes")); } SmilesWgt::~SmilesWgt() { } void SmilesWgt::loadTheme(const QString & path) { if(!QDir().exists(path)) return; if(m_inited) clear(); QFile file(path + "/emoticons.xml"); QDomDocument dom_document; QDomElement root; QDomElement child; QDomElement emoticon; QDomElement name; QDomNodeList elements; QDomNodeList elements_names; QStringList list; if(!file.open(QIODevice::ReadOnly)) { Globals::addError("Couldn't open " + path + "/emoticons.xml"); return; } if(!dom_document.setContent(&file, true)) { Globals::addError("Couldn't parse " + path + "/emoticons.xml"); return; } root = dom_document.documentElement(); elements = root.elementsByTagName("emoticon"); for(uint i = 0, len = elements.length(); i < len; i++) { emoticon = elements.item(i).toElement(); elements_names = emoticon.elementsByTagName("string"); list.clear(); for(uint j = 0, len = elements_names.length(); j < len; j++) { child = elements_names.item(j).toElement(); list.append(child.text()); } addSmile(emoticon.attribute("file"), list, path); } int cols = (int)sqrt(m_smilesNum); for(int i = 0; i < m_smilesNum; i++) m_grid->addWidget(m_smiles[i], i / cols, i % cols); m_inited = true; } void SmilesWgt::addSmile(const QString & fname, const QStringList & list, const QString & dir) { if(m_smilesMaxNum <= ++m_smilesNum) { m_smilesMaxNum += 10; m_smiles = (SmileLabel**)realloc(m_smiles, m_smilesMaxNum * sizeof(SmileLabel*)); assert(NULL != m_smiles); } m_smiles[m_smilesNum - 1] = new SmileLabel(this); connect(m_smiles[m_smilesNum - 1], SIGNAL(clicked(const QString &)), this, SIGNAL(smileClicked(const QString &))); connect(m_smiles[m_smilesNum - 1], SIGNAL(clicked(const QString &)), this, SIGNAL(wantHide())); connect(m_smiles[m_smilesNum - 1], SIGNAL(hovered( )), this, SLOT (unselectAll())); m_smiles[m_smilesNum - 1]->setFilename(fname); m_smiles[m_smilesNum - 1]->setSmileText(list); m_smiles[m_smilesNum - 1]->load(dir); } void SmilesWgt::init() { loadTheme(QChatSettings::settings()->smilesThemePath()); } void SmilesWgt::clear() { if(m_inited) { for(; m_smilesNum > 0; m_smilesNum--) { m_grid->removeWidget(m_smiles[m_smilesNum - 1]); delete m_smiles[m_smilesNum - 1]; } m_inited = 0; } } void SmilesWgt::setOptimalSize() { resize(optimalSize()); } QSize SmilesWgt::optimalSize() { int maxHe = 0, maxWd = 0; for(int i = 0; i < m_smilesNum; i++) { if(m_smiles[i]->pixmapWidth() > maxWd) maxWd = m_smiles[i]->pixmapWidth(); if(m_smiles[i]->pixmapHeight() > maxHe) maxHe = m_smiles[i]->pixmapHeight(); } int cols = (int)sqrt(m_smilesNum); int rows = (int)sqrt(m_smilesNum) + (m_smilesNum != cols * cols); return QSize(maxWd * cols, maxHe * rows); } void SmilesWgt::unselectAll() { SmileLabel* lab = qobject_cast(sender()); for(int i = 0; i < m_smilesNum; i++) { if(m_smiles[i] != lab) m_smiles[i]->unselect(); } } qchat-0.3/src/statuseditwgt.h0000644000076500017500000000514710772032353015057 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef STATUSEDITWGT_H #define STATUSEDITWGT_H #include #include #include #include #include #include #include #include "userinfo.h" #include "qchatsettings.h" /** @author Anistratov Oleg */ class StatusEditWgt : public QWidget { Q_OBJECT private: QGridLayout* m_grid; QToolButton* m_editStatusBtn; QLineEdit* m_statusEdit; QComboBox* m_statusCmbx; QMenu* m_descriptionsMenu; QString m_lastText; QString m_description; public: StatusEditWgt(QWidget *parent = 0); ~StatusEditWgt(){}; void retranslate(); int status () const {return m_statusCmbx->itemData(m_statusCmbx->currentIndex()).toUInt();} void setStatus(int s){m_statusCmbx->setCurrentIndex(s);} const QString & description() const {return m_description;} public slots: void slot_setStatusDescription(const QString & d) {m_description = d; UserInfo::myInfo()->setStatusDescription(d); QChatSettings::settings()->setStatusDescription(d, status());} void slot_statusChanged (); void showDescriptionsMenu (); void setDescription(QAction*); void hideEditor(); void slot_editStatusClicked(); void changeStatus(); protected: void changeEvent(QEvent *ev) { if(ev->type() == QEvent::LanguageChange) retranslate(); else QWidget::changeEvent(ev); } signals: void statusChanged(); void statusDescriptionChanged(); void editing(); }; #endif qchat-0.3/src/qchatmainwindow.h0000644000076500017500000000267210766276163015355 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHATMAINWINDOW_H #define QCHATMAINWINDOW_H #include #include #include /** @author Anistratov Oleg */ class QChatMainWindow : public QMainWindow { Q_OBJECT private: QList m_toolBars; public: QChatMainWindow(QWidget *parent = 0); ~QChatMainWindow(); void addToolBar(QToolBar*); }; #endif qchat-0.3/src/protocolversion4.cpp0000644000076500017500000000474011002163155016020 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "protocolversion4.h" const char* ProtocolVersion4::m_programId = "QChat"; ProtocolVersion4::ProtocolVersion4() : AbstractProtocol() { } ProtocolVersion4::~ProtocolVersion4() { } QString ProtocolVersion4::compName(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + compNameLen(buf) + optionsLen(buf)) return QString(); return QString::fromUtf8(buf + protocolLen() + optionsLen(buf), compNameLen(buf)); } QString ProtocolVersion4::userName(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + optionsLen(buf) + compNameLen(buf) + userNameLen(buf)) return QString(); return QString::fromUtf8(buf + protocolLen() + optionsLen(buf) + compNameLen(buf), userNameLen(buf)); } QString ProtocolVersion4::message(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + optionsLen(buf) + compNameLen(buf) + userNameLen(buf) + messageLen(buf)) return QString(); return QString::fromUtf8(buf + protocolLen() + optionsLen(buf) + compNameLen(buf) + userNameLen(buf), messageLen(buf)); } QByteArray ProtocolVersion4::parametrs(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + optionsLen(buf) + compNameLen(buf) + userNameLen(buf) + messageLen(buf) + parametrsLen(buf)) return QByteArray(); return QByteArray(buf + protocolLen() + optionsLen(buf) + compNameLen(buf) + userNameLen(buf) + messageLen(buf), parametrsLen(buf)); } qchat-0.3/src/chattextwgt.h0000644000076500017500000000546611002234305014502 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef CHATTEXTWGT_H #define CHATTEXTWGT_H #include #include #include #include #include #include #include #include #include "smileswgt.h" #include "textbrowser.h" struct Smile; class Message; struct AnimatedSmile; /** @author Anistratov Oleg */ class ChatTextWgt : public QWidget { Q_OBJECT private: QList m_animatedSmiles; TextBrowser* m_text; static QList m_smiles; QList* m_smilesFromSender; int m_keepAnimations; private: static void addSmile (const QStringList & smiles, const QString & name); void insertSmile(QTextCursor cursor, const QString & smile); void processLinks(QTextDocument*); // void processSmiles(); bool insertSmileFromSender(QTextCursor cursor, const QString & smile); bool insertSmileFromLocalTheme(QTextCursor cursor, const QString & smile); public: ChatTextWgt(QWidget *parent = 0); ~ChatTextWgt(); QString nextSmile (const QString &) const; static QString nextSmile (const QString &, Smile**); static QList smiles(){return m_smiles;} static void initSmiles(const QString &); QString toPlainText() const {return m_text->toPlainText();} QTextEdit* text() const {return m_text;} void setMsg(const QString & msg); void setSmilesFromSender(QList*); void stopAnimations(); void setAnimationsPaused(bool); void setKeepAnimations(int n){m_keepAnimations = n;} public slots: void clear(){m_text->clear();} void addMsg(const Message* msg); void setAnimations(); void playPauseAnimations(bool); }; #endif qchat-0.3/src/login2serverdlg.cpp0000644000076500017500000001205711004422233015572 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "login2serverdlg.h" #include Login2ServerDlg::Login2ServerDlg(QStringList* ls, QStringList* ll, QWidget *parent, const QString& addr, const QString& nick) : QDialog(parent), m_lastServers(ls), m_lastLogins(ll), m_finished(false) { QGridLayout* grid = new QGridLayout(this); // m_ipEdit = new QLineEdit(addr, this); // m_loginEdit = new QLineEdit(nick, this); m_ipCmbx = new QComboBox(this); m_loginCmbx = new QComboBox(this); m_loginBtn = new QPushButton(this); m_abortBtn = new QPushButton(this); m_ipLab = new QLabel(this); m_loginLab = new QLabel(this); m_descriptionLab = new QLabel(this); grid->addWidget(m_ipLab , 0, 0); grid->addWidget(m_ipCmbx , 0, 1); grid->addWidget(m_loginLab , 1, 0); grid->addWidget(m_loginCmbx, 1, 1); grid->addWidget(m_loginBtn , 2, 0, 1, 2); grid->addWidget(m_abortBtn , 2, 0, 1, 2); grid->addWidget(m_descriptionLab, 3, 0); grid->setColumnStretch(1, 1); grid->setColumnMinimumWidth(1, 150); m_ipCmbx ->setEditable(true); m_loginCmbx->setEditable(true); m_ipCmbx ->setDuplicatesEnabled(false); m_loginCmbx->setDuplicatesEnabled(false); foreach(QString s, (*m_lastServers)) // m_ipCmbx->insertItem(0, s); m_ipCmbx->addItem(s); int idx; if((idx = m_ipCmbx->findText(addr)) >= 0) m_ipCmbx->removeItem(idx); m_ipCmbx->insertItem(0, addr); foreach(QString l, (*m_lastLogins)) // m_loginCmbx->insertItem(0, l); m_loginCmbx->addItem(l); if((idx = m_loginCmbx->findText(nick)) >= 0) m_loginCmbx->removeItem(idx); m_loginCmbx->insertItem(0, nick); m_loginCmbx->setCurrentIndex(0); m_ipCmbx ->setCurrentIndex(0); m_abortBtn->hide(); m_descriptionLab->hide(); retranslate(); connect(m_loginBtn, SIGNAL(clicked()), this, SLOT(slot_login())); connect(m_abortBtn, SIGNAL(clicked()), this, SLOT(abort())); } Login2ServerDlg::~Login2ServerDlg() { qDebug("[~Login2ServerDlg]"); } void Login2ServerDlg::retranslate() { m_ipLab ->setText(tr("Server IP :")); m_loginLab->setText(tr("Nickname :")); m_loginBtn->setText(tr("Login")); m_abortBtn->setText(tr("Abort")); m_descriptionLab->setText(""); } void Login2ServerDlg::slot_login() { QString server = m_ipCmbx->lineEdit()->text(); QString login = m_loginCmbx->lineEdit()->text(); m_descriptionLab->show(); if(m_finished) { accept(); } else { m_loginBtn->hide(); m_abortBtn->show(); m_descriptionLab->setText(tr("Connecting to server...")); emit wantLogin(QHostAddress(server), login); if(m_lastServers->contains(server)) m_lastServers->removeAll(server); m_lastServers->prepend(server); if(m_lastLogins->contains(login)) m_lastLogins->removeAll(login); m_lastLogins->prepend(login); QString last; int num; num = QChatSettings::settings()->intOption("LastServersNum"); foreach(QString s, *m_lastServers) { num--; last += s; if(num < 0) break; last += "\n"; } QChatSettings::settings()->setOption("LastServers", last); last.clear(); num = QChatSettings::settings()->intOption("LastLoginsNum"); foreach(QString s, *m_lastLogins) { num--; last += s; if(num < 0) break; last += "\n"; } QChatSettings::settings()->setOption("LastLogins", last); } } void Login2ServerDlg::abort() { m_loginBtn->show(); m_abortBtn->hide(); emit wantAbort(); } void Login2ServerDlg::loginRejected(const QString& /*reason*/) { } void Login2ServerDlg::loginAccepted(const QString &) { } void Login2ServerDlg::loginFinished(int err, const QString & descr) { if(!err) { if(!descr.isEmpty()) m_descriptionLab->setText(descr); else m_descriptionLab->setText(tr("Login Accepted")); m_finished = true; m_loginBtn->setText(tr("Ok")); m_ipCmbx ->setEnabled(false); m_loginCmbx->setEnabled(false); emit loginSuccessful(); } else m_descriptionLab->setText(descr); m_loginBtn->show(); m_abortBtn->hide(); } qchat-0.3/src/picturescrollarea.h0000644000076500017500000000324410665277445015701 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef PICTURESCROLLAREA_H #define PICTURESCROLLAREA_H #include #include #include #include /** @author Anistratov Oleg */ class PictureScrollArea : public QScrollArea { Q_OBJECT private: int m_lastX; int m_lastY; public: PictureScrollArea(QWidget *parent = 0); ~PictureScrollArea(){}; protected: void resizeEvent (QResizeEvent* ev); void mousePressEvent (QMouseEvent* ev); void mouseMoveEvent (QMouseEvent* ev); void mouseDoubleClickEvent(QMouseEvent* ev); }; #endif qchat-0.3/src/userinfo.h0000644000076500017500000001740110766270337014003 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERINFO_H #define USERINFO_H #include #include #include #include #include #include struct QC_DatagramHeader; /** @author Anistratov Oleg */ class UserInfo { private: static UserInfo* m_myInfo; bool m_enabled; quint16 m_programVerID; QString m_programVerName; quint16 m_status; quint64 m_ip; QString m_compName; QString m_statusDescription; // USER_DETAILS: int m_gender; // 'm' - male, 'f' - female, 0 - not sure ) QString m_nickname; QString m_firstName; QString m_lastName; QString m_secondName; QDate m_dateOfBorn; QString m_address; QString m_homePhone; QString m_workPhone; QString m_mobilePhone; QString m_email; QString m_ICQ; QString m_homepage; QString m_aboutInfo; QString m_pictureFilename; QString m_photoFilename; QByteArray m_pictureHash; QByteArray m_photoHash; mutable QByteArray m_avatarHash; QPixmap* m_avatar; // here storing values for all channels QMap m_statuses; QMap m_descriptions; // user id on server uint m_uid; private: void setPictureOrPhoto(const QString &, QString &, QByteArray &); public: UserInfo (const QHostAddress& = QHostAddress(), const QString & = "", int = 0); UserInfo (QC_DatagramHeader* ); ~UserInfo(); void setEnabled(bool enable){m_enabled = enable;} bool enabled () const { return m_enabled ; } quint64 ip () const { return m_ip ; } quint16 status () const { return m_status ; } quint16 programVerID () const { return m_programVerID ; } const QString & nickname () const { return m_nickname ; } const QString & lastName () const { return m_lastName ; } const QString & firstName () const { return m_firstName ; } const QString & secondName () const { return m_secondName ; } const QDate & dateOfBorn () const { return m_dateOfBorn ; } const QString & address () const { return m_address ; } const QString & homePhone () const { return m_homePhone ; } const QString & workPhone () const { return m_workPhone ; } const QString & mobilePhone () const { return m_mobilePhone ; } const QString & e_mail () const { return m_email ; } const QString & icq () const { return m_ICQ ; } const QString & homepage () const { return m_homepage ; } const QString & aboutInfo () const { return m_aboutInfo ; } const QString & compName () const { return m_compName ; } const QString & statusDescription () const { return m_statusDescription; } const QString & programVerName () const { return m_programVerName ; } const QString & photoFilename () const { return m_photoFilename ; } const QString & pictureFilename () const { return m_pictureFilename ; } const QByteArray & pictureHash () const { return m_pictureHash ; } const QByteArray & photoHash () const { return m_photoHash ; } void setPictureHash(const QByteArray & ba){m_pictureHash = ba;} void setPhotoHash (const QByteArray & ba){m_photoHash = ba;} QPixmap* newPhoto () const {return new QPixmap(m_photoFilename);} QPixmap* newPicture () const {return new QPixmap(m_pictureFilename);} QPixmap* newIcon (uint = 32, uint = 32, bool = false) const; QImage* newPhotoImg () const {return new QImage(m_photoFilename);} QImage* newPictureImg () const {return new QImage(m_pictureFilename);} QImage* newIconImg (uint = 32, uint = 32) const; void setProgramVerName(QString str){m_programVerName = str;} void setIP (quint64 ip ) {m_ip = ip;} void setStatus (quint16 status ) {m_status = status;} void setStatusDescription(const QString & des ) {if(!des.isNull()) m_statusDescription = des;} void setCompName (const QString & str ) {if(!str.isNull()) m_compName = str;} void setNickname (const QString & str ) {if(!str.isNull()) m_nickname = str;} void setFirstName (const QString & str ) {if(!str.isNull()) m_firstName = str;} void setLastName (const QString & str ) {if(!str.isNull()) m_lastName = str;} void setSecondName (const QString & str ) {if(!str.isNull()) m_secondName = str;} void setDateOfBorn (const QDate & dte ) {if(!dte.isNull()) m_dateOfBorn = dte;} void setAddress (const QString & str ) {if(!str.isNull()) m_address = str;} void setHomePhone (const QString & str ) {if(!str.isNull()) m_homePhone = str;} void setWorkPhone (const QString & str ) {if(!str.isNull()) m_workPhone = str;} void setMobilePhone (const QString & str ) {if(!str.isNull()) m_mobilePhone = str;} void setE_mail (const QString & str ) {if(!str.isNull()) m_email = str;} void setICQ (const QString & str ) {if(!str.isNull()) m_ICQ = str;} void setHomepage (const QString & str ) {if(!str.isNull()) m_homepage = str;} void setAboutInfo (const QString & str ) {if(!str.isNull()) m_aboutInfo = str;} void setPhoto (const QString & fname){setPictureOrPhoto(fname, m_photoFilename, m_photoHash);} void setPicture (const QString & fname){setPictureOrPhoto(fname, m_pictureFilename, m_pictureHash);} void setPhoto (const QByteArray &); void setPicture (const QByteArray &); void setGender(int value){m_gender = value;} int gender() const {return m_gender;} void setAvatarHash(const QByteArray& value){m_avatarHash = value;} const QByteArray & avatarHash() const {return m_avatarHash;} void setAvatar(QPixmap* value){m_avatar = value;} QPixmap* avatar() const {return m_avatar;} void setStatus(const QString & channel, quint16 status){m_statuses[channel] = status;} uint status(const QString & channel) const {return m_statuses[channel];} void setStatusDescription(const QString & channel, const QString & descr){m_descriptions[channel] = descr;} QString statusDescription(const QString & channel) const {return m_descriptions[channel];} void setUid( const uint& theValue ){m_uid = theValue;} uint uid() const {return m_uid;} static void setMyInfo (UserInfo* info){m_myInfo = info;} static UserInfo* myInfo() {return m_myInfo;} }; #endif qchat-0.3/src/globals.cpp0000644000076500017500000001134111004425610014102 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "globals.h" #include #include #include QString Globals::m_profileName = ""; QChatSettings* Globals::m_settings = 0; UserInfo* Globals::m_info = 0; LogWgt* Globals::m_log = NULL; const uint Globals::VersionID = 15; const uint Globals::Revision = 37; QString Globals::VersionStr = "0.3"; QString Globals::StatusStr[7] = { QObject::tr("Busy"), QObject::tr("Free"), QObject::tr("Ready for chat"), QObject::tr("Do not disturb"), QObject::tr("Inactive"), QObject::tr("Away"), QObject::tr("Invisible"), }; const char* Globals::VersionsTable[15] = { "0.0.1" , //1 "0.0.2" , //2 "0.0.3" , //3 "0.0.4" , //4 "0.1.0" , //5 "0.1.1" , //6 "0.1.2" , //7 "0.1.3" , //8 "0.1.4" , //9 "0.1.5" , //10 "0.1.6" , //11 "0.2" , //12 "0.2.1" , //13 "0.2.2" , //14 "0.3" , //15 }; //\***************************************************************************** quint32 Globals::localIp(QHostAddress* br) { QList all_i = QNetworkInterface::allInterfaces(); QList all_e; foreach(QNetworkInterface i, all_i) { all_e = i.addressEntries(); foreach(QNetworkAddressEntry e, all_e) { if(e.broadcast().isNull()) continue; *br = e.broadcast(); return e.ip().toIPv4Address(); } } return 0; } //\***************************************************************************** char* datadup(const char* src, int n) { int i; char* dest = (char*)malloc(n); assert(NULL != dest); for(i = 0; i < n; i++) dest[i] = src[i]; return dest; } //\***************************************************************************** unsigned long long str2ULL(const char* str) // char[8] -> unsigned long long { union{ char str[8]; unsigned long long num; }un; memcpy(un.str, str, 8); return un.num; } //\***************************************************************************** unsigned long str2UL(const char* str) // char[4] -> unsigned long { union{ char str[4]; unsigned long num; }un; memcpy(un.str, str, 4); return un.num; } //\***************************************************************************** unsigned short str2US(const char* str) // char[2] -> unsigned short { union{ char str[2]; unsigned long num; }un; memcpy(un.str, str, 2); return un.num; } //\***************************************************************************** int catULL2str(char* str, unsigned long long num) { union{ char str[8]; unsigned long long num; }un; un.num = num; memcpy(str, un.str, 8); return 1; } //\***************************************************************************** int catUL2str(char* str, unsigned long num) { union{ char str[4]; unsigned long num; }un; un.num = num; memcpy(str, un.str, 4); return 1; } //\***************************************************************************** int catUS2str(char* str, unsigned short num) { union{ char str[2]; unsigned short num; }un; un.num = num; memcpy(str, un.str, 2); return 1; } //\***************************************************************************** QList Globals::validInterfeices() { QList all_i = QNetworkInterface::allInterfaces(); QList all_e; QList valid_i; foreach(QNetworkInterface i, all_i) { if(i.flags() & QNetworkInterface::IsRunning && i.flags() & QNetworkInterface::CanBroadcast && i.flags() & QNetworkInterface::IsUp) valid_i.append(i); } return valid_i; } qchat-0.3/src/tcpreceiverthread.h0000644000076500017500000000404311004404612015627 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef TCPRECEIVERTHREAD_H #define TCPRECEIVERTHREAD_H #include "receiverthread.h" #include #include "qchatsocket.h" /** @author Anistratov Oleg */ class TcpReceiverThread : public ReceiverThread { Q_OBJECT private: // QTcpSocket* m_socket; QChatSocket* m_socket; public: TcpReceiverThread(QObject *parent = 0); ~TcpReceiverThread(); void run(); void changePort(quint16); int readData(char*, uint); QTcpSocket* socket(){return m_socket->socket();} QAbstractSocket::SocketState state(){return m_socket->state();} public slots: void login(const QString&, const QHostAddress&, uint, const QString& = ""); signals: /** * * @param err_id id of error * 0: no errors * 1: cannot connect to server * 2: cannot login to server * @param descr optional text description of error */ void loginFinished(int err_id, const QString& descr = ""); void disconnected(); }; #endif qchat-0.3/src/channelwgt.h0000644000076500017500000001631011002651142014256 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef CHANNELWGT_H #define CHANNELWGT_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "abstractchatcore.h" #include "userinfo.h" class ChatWgt; class MsgHistory; class UsersList; class UsersListWgt; class StatusEditWgt; class ChatTextWgt; class InputRichTextWgt; class Message; class StatusEditWgt; class UserWgt; class UsersStatisticsWgt; class UsersStatisticsModel; struct Smile; struct QC_DatagramHeader; /** @author Anistratov Oleg */ class ChannelWgt : public QWidget { Q_OBJECT private: QFile* m_logFile; quint8 m_status; quint8 m_oldStatus; QGridLayout* mw_grid; QStackedWidget* mw_chatTextStack; ChatWgt* m_parent; AbstractChatCore::ChannelType m_type; // 0 - common, 1 - private /// m_destUid is UserID in server mode and IP address in serverless quint64 m_destUid; QString m_name; MsgHistory* m_chatMsgs; UsersList* m_users; quint32 m_usersNum; quint16 m_passwordSize; quint32 m_messageSize; bool m_displayInfoMsgs; bool m_soundOnMessageIn; QTimer* m_refreshTimer; // информация об изменении статуса отсылается не моментально, а через определенный промежуток времени QTimer* m_statusChangedTimer; QTimer* m_initTimer; ChatTextWgt* mw_chatText; ChatTextWgt* mw_clearChatText; // without system messages InputRichTextWgt* mw_inputText; UsersListWgt* mw_usersList; UsersStatisticsModel* m_usersModel; UsersStatisticsWgt* mw_usersStatistics; QStackedWidget* mw_usersStack; QPushButton* m_sendBtn; QPushButton* m_refreshUlBtn; QCheckBox* m_sysMessagesChbx; QFile* m_file; StatusEditWgt* m_statusWgt; QString m_statusDescription; QList* m_smilesFromSender; QHostAddress m_msgsReqAddr; uint m_msgsReqNum; QTime m_msgsReqSent; QTime m_msgsReqReceived; mutable QByteArray m_parametrs; QVector m_splitters; int m_requestsRest; private: QPixmap* drawUsersIcon(const QPixmap*, UserInfo*); public: ChannelWgt(QString name_, QWidget* = 0, AbstractChatCore::ChannelType = AbstractChatCore::Common, quint64 = 0); ~ChannelWgt(); void retranslate(); void processData (QC_DatagramHeader* Hdr); void getSmilesFromData(QC_DatagramHeader* Hdr); void addUser (QC_DatagramHeader* Hdr); void hideUser (QC_DatagramHeader* Hdr); void addUserInfo (QC_DatagramHeader* Hdr); void addUserInfo (UserWgt*, QC_DatagramHeader* Hdr); void addMsg (QC_DatagramHeader* Hdr); void addAvatar (QC_DatagramHeader* Hdr); void addMsg2Chat (Message* msg); void sendInfoAnswer (QC_DatagramHeader* Hdr); void sendStatusAnswer (quint64, bool = 0, bool = 0); UserWgt* findUser (quint64) const; const QString & name () const {return m_name;} quint64 destUid () const {return m_destUid;} quint32 type () const {return m_type;} InputRichTextWgt* inputText () const {return mw_inputText;} void initChannel (); void rebuildChatText(); void msgsNumAnswer (QC_DatagramHeader* ); void emitSomeData(AbstractChatCore::DataType, const QString & = "", quint64 = 0) const; QByteArray saveState() const; void restoreState(const QByteArray&); void logMessage(QC_DatagramHeader* Hdr); public slots: void setFocus2InputText (); void slot_msgOut (); void slot_refreshUL (); // UL - users list void slot_deepRefreshUL (); void addInfoMsg (QC_DatagramHeader* Hdr); void slot_chbxInfChgd (); void setSndOnMsgIn (bool b) {m_soundOnMessageIn = b;} void slot_infoRequest (UserWgt*); void slot_statusRequest() const {emitSomeData(AbstractChatCore::STATUS_REQUEST);} void slot_connected () const {emitSomeData(AbstractChatCore::CONNECTED, "Connected");} void slot_disconnected () const {emitSomeData(AbstractChatCore::DISCONNECTED, "Disconnected");} void slot_statusChanged (); void slot_startStatusChangedTimer(); void slot_finMsgsHistoryReq(); void slot_changeUlRefreshInterval(uint); void slot_changeUlDeepRefreshInterval(uint); void slot_controlSplitter(int, int); void updateUsersView(); void nextStatusRequest(); void redrawIcons(); void setAnimationsRunning(bool b); protected: void keyPressEvent(QKeyEvent* ev); void changeEvent(QEvent *ev) { if(ev->type() == QEvent::LanguageChange) retranslate(); else QWidget::changeEvent(ev); } signals: void statusAnswer (const QString &, quint64, AbstractChatCore::ChannelType, bool changed = 0, bool = 0); void avatarAnswer (const QString &, quint64, AbstractChatCore::ChannelType); void infStatusChanged(const QString &, quint64, AbstractChatCore::ChannelType); void infoAnswer (const QString &, quint64, AbstractChatCore::ChannelType, uchar); void sendMsgsHistory (const QString &, quint64, const QByteArray &, AbstractChatCore::ChannelType); void sendMsgsNum (const QString &, quint64, quint32, AbstractChatCore::ChannelType); void sendSomeData (const QString &, quint64, AbstractChatCore::DataType, const QString &, AbstractChatCore::ChannelType, QByteArray*) const; void sendMessage (const QString &, quint64, AbstractChatCore::ChannelType, QTextDocument*); void wantActivate (); void rebuildChat (short type); void showStatusDescriptionDlg(); void wantSaveState(const QString &, const QByteArray &); }; #endif qchat-0.3/src/option.h0000644000076500017500000000334311002420401013426 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef OPTION_H #define OPTION_H #include #include /** @author Anistratov Oleg */ class Option { public: enum OptionType{int_opt, string_opt, bool_opt, HostAddress_opt}; private: QVariant m_option; QString m_section; OptionType m_type; public: Option(QVariant o, QString s, OptionType t = int_opt); ~Option(); OptionType type() const {return m_type;} QVariant option() const {return m_option;} void setOption(const QVariant& opt){m_option = opt;} const QString& section() const {return m_section;} // Option& operator=(const QVariant& val){m_option = val; return *this;} }; #endif qchat-0.3/src/aboutqchat.cpp0000644000076500017500000000726411004425217014626 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "aboutqchat.h" #include #include #include #include #include #include #include "globals.h" AboutQChat::AboutQChat(QWidget *parent) : QDialog(parent) { QString msg; QGridLayout* grid = new QGridLayout(this); QTabWidget* tabs = new QTabWidget(this); QTextBrowser* tab = new QTextBrowser(this); QLabel* lab = new QLabel(this); QPushButton* btn = new QPushButton(tr("Close"), this); lab->setPixmap(QApplication::windowIcon().pixmap(64)); grid->addWidget(lab, 0, 0); lab = new QLabel(this); lab->setText(QString("QChat ") + Globals::VersionsTable[Globals::VersionID - 1] + QString(" (%1)").arg(Globals::Revision) + ""); lab->setAlignment(Qt::AlignCenter); grid->addWidget(lab, 0, 1); grid->addWidget(tabs, 1, 0, 1, 2); grid->addWidget(btn, 2, 1, Qt::AlignRight); grid->setColumnStretch(1, 1); msg.append(tr("
Network chat.

\n")). append("
  (c) 2007-2008, Anistratov Oleg aka ower" "
  ower@users.sourceforge.net"); tab->setOpenExternalLinks(true); tab->setHtml(msg); tab->setWordWrapMode(QTextOption::NoWrap); tabs->addTab(tab, tr("About")); msg = " Ower" "
    ower@users.sourceforge.net" "
    Ukrainian, Russian translations" "

 Adrian Lubik" "
    adrian5632@gmail.com " "
    Polish translation" "

 Salas Jose Luis" "
    josacar@gmail.com " "
    Spanish translation" "

 Karsten Brockmann" "
    arcam@ccux-linux.de " "
    German translation" "

 Alen Keri" "
    kosava@gmail.com " "
    Serbian translation"; tab = new QTextBrowser(this); tab->setOpenExternalLinks(true); tab->setHtml(msg); tabs->addTab(tab, tr("Translations")); grid->setMargin(3); grid->setSpacing(10); connect(btn, SIGNAL(clicked()), this, SLOT(accept())); setMinimumWidth(400); setMinimumHeight(300); setWindowTitle(tr("About QChat")); } AboutQChat::~AboutQChat() { qDebug("[~AboutQChat]"); } qchat-0.3/src/tcpreceiverthread.cpp0000644000076500017500000000435411002604016016165 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "tcpreceiverthread.h" TcpReceiverThread::TcpReceiverThread(QObject *parent) : ReceiverThread(parent) { } TcpReceiverThread::~TcpReceiverThread() { } void TcpReceiverThread::run() { m_socket = new QChatSocket(this); // m_socket->moveToThread(this); connect(m_socket, SIGNAL(newDtgrm()), this, SLOT(receiving())); // connect(m_socket, SIGNAL(loginFinished(int, QString)), this, SLOT(loginFinished(int, QString))); connect(m_socket, SIGNAL(disconnected()), this, SIGNAL(disconnected())); exec(); } void TcpReceiverThread::changePort(quint16 /*port*/) { } int TcpReceiverThread::readData(char* buffer, uint bufferSize) { int dataSize = -2; if(m_socket->state() == QAbstractSocket::ConnectedState) dataSize = m_socket->readDtgrm(buffer, bufferSize); return dataSize; } void TcpReceiverThread::login(const QString & nick, const QHostAddress & addr, uint port, const QString& pwd) { m_socket->disconnectFromHost(); qDebug("[TcpReceiverThread::login]: connecting to %s:%d", addr.toString().toAscii().data(), port); m_socket->connectToHost(addr, port); if(m_socket->waitForConnected(10000)) m_socket->login(nick, pwd); else emit loginFinished(1); } qchat-0.3/src/senderthread.h0000644000076500017500000000544411002604106014600 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SENDERTHREAD_H #define SENDERTHREAD_H #include #include #include #include #include "largedatagramout.h" #include "userinfo.h" /** @author Anistratov Oleg */ class SenderThread : public QThread { Q_OBJECT private: char* m_buffer; QAbstractSocket* m_socket; QUdpSocket* m_udp; QTcpSocket* m_tcp; quint16 m_port; LargeDatagramOut** m_datagrams; quint32 m_datagramsNum; quint32 m_datagramsMaxNum; QTimer* m_timer; public: SenderThread(QObject *parent = 0); ~SenderThread(); void run(); quint32 getValidID() const; bool containID(quint32 ID) const; LargeDatagramOut* findDatagram(quint16 ID) const; void setPort(quint16 port){m_port = port;} void useTcp(QTcpSocket* s = 0){if(s)m_tcp = s; m_socket = m_tcp;} void useUdp(QUdpSocket* s = 0){if(s)m_udp = s; m_socket = m_udp;} int send(char*, int, const QHostAddress& = QHostAddress()); public slots: void sending() { for(quint32 i = 0; i < m_datagramsNum; i++, usleep(1)) m_datagrams[i]->sendNextFragment(m_socket, m_port, m_buffer); } void deleteDatagram(LargeDatagramOut* dtgrm); void slot_fragmentsRequest(char* dtgrm, quint32 dtgrm_len); void slot_acceptSending(quint16); void slot_cancelTask (quint16); void addTask (char* hdr, quint16 hdr_len, char* data, quint32 data_len, quint64, quint32 ID); void addFileTask(char* hdr, quint16 hdr_len, const QString & filename , quint64, quint32 ID); signals: void sendingCancelled(quint16); void sendingFinished (quint16); }; #endif qchat-0.3/src/usersstatisticswgt.cpp0000644000076500017500000000564310703762727016507 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "usersstatisticswgt.h" #include "userslist.h" #include "usersstatisticsmodel.h" #include "channelwgt.h" #include UsersStatisticsWgt::UsersStatisticsWgt(QWidget* parent) : QTableView(parent) { setIconSize(QSize(32 + 16 + 16, 32)); setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel); } UsersStatisticsWgt::~UsersStatisticsWgt() { } void UsersStatisticsWgt::sortByColumn(int column) { ((UsersStatisticsModel*)model())->sort(column, horizontalHeader()->sortIndicatorOrder()); emit sorted(); } QByteArray UsersStatisticsWgt::saveState() { // Format: // 1 byte - sorting column // 1 byte - sorting order // 1xcolumnsCount : // 1 byte - columnID // 2 bytes - columnWidth UsersStatisticsModel* mdl = (UsersStatisticsModel*)model(); QByteArray state; char arr2[2]; if(mdl) { state.append(char(mdl->sortingColumn())); state.append(char(mdl->sortOrder())); for(int i = 0; i < mdl->columnsCount(); i++) if(mdl->columnID(i) != UsersStatisticsModel::Invalid) { catUS2str(arr2, columnWidth(i)); state.append(mdl->columnID(i)); state.append(arr2[0]); state.append(arr2[1]); } } return state; } void UsersStatisticsWgt::restoreState(const QByteArray & state) { UsersStatisticsModel* mdl = (UsersStatisticsModel*)model(); char arr2[2]; Qt::SortOrder order; int column; if(mdl) { if(state.size() >= 3) mdl->clearColumns(); column = state.at(0); order = Qt::SortOrder(state.at(1)); for(int i = 0, j = 2; ; i++) { if(j + 3 > state.size()) break; mdl->addColumn(state.at(j++)); arr2[0] = state.at(j++); arr2[1] = state.at(j++); setColumnWidth(i, str2US(arr2)); } mdl->setSortingColumn(column); mdl->setSortOrder (order); horizontalHeader()->setSortIndicator(column, order); } } qchat-0.3/src/abstractchatcore.cpp0000644000076500017500000004152411004427403016003 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "abstractchatcore.h" #include "globals.h" #include #include "protocolversion3.h" #include "protocolversion4.h" #include "abstractprotocol.h" #include AbstractProtocol* AbstractChatCore::m_protocol = NULL; ProtocolVersion3* AbstractChatCore::m_protocolV3 = new ProtocolVersion3; ProtocolVersion4* AbstractChatCore::m_protocolV4 = new ProtocolVersion4; AbstractChatCore::AbstractChatCore() : m_outputBuffer(NULL), m_outputBufferSize(65535), m_inputBuffer(NULL), m_inputBufferSize(65535), m_largeDtgrm(false), m_header(NULL), m_headerSize(0), m_data(NULL), m_dataSize(0), m_parametrs("") { Hdr = new QC_DatagramHeader; m_protocol = m_protocolV4; // m_protocol = m_protocolV3; m_outputBuffer = (char*)malloc(m_outputBufferSize); assert(NULL != m_outputBuffer); m_inputBuffer = (char*)malloc(m_inputBufferSize); assert(NULL != m_inputBuffer ); } AbstractChatCore::~AbstractChatCore() { qDebug("[~AbstractChatCore]"); free(m_outputBuffer); // we do not need to free m_data because m_data = m_header + m_headerSize; free(m_header); } void AbstractChatCore::addParametr(const QString & name, const QByteArray & par, QByteArray & buf) { char size[4]; char nameSize[2]; if(name.size() <= 65535) { catUS2str(nameSize, name.toUtf8().size()); buf.append(nameSize[0]); buf.append(nameSize[1]); buf.append(name.toUtf8()); catUL2str(size, par.size()); buf.append(size[0]); buf.append(size[1]); buf.append(size[2]); buf.append(size[3]); buf.append(par); } else qWarning("[AbstractChatCore::addParametr]: '%s' is too large (%d bytes). not added\n", name.toLocal8Bit().data(), name.size()); } //\***************************************************************************** void AbstractChatCore::addParametr(const QString & name, const QByteArray & par) { addParametr(name, par, parametrs()); } //\***************************************************************************** void AbstractChatCore::addParametr(const QString & name, const QString & filename) { QFile file(filename); QByteArray par; char size[4]; char nameSize[2]; // qDebug("[ChatCore::addParametr]: name = %s", name.toLocal8Bit().data()); if(name.size() <= 65535) { file.open(QIODevice::ReadOnly); if(file.exists ()) { par = file.readAll(); catUS2str(nameSize, name.toUtf8().size()); parametrs().append(nameSize[0]); parametrs().append(nameSize[1]); parametrs().append(name.toUtf8()); catUL2str(size, file.size()); parametrs().append(size[0]); parametrs().append(size[1]); parametrs().append(size[2]); parametrs().append(size[3]); parametrs().append(par); par.clear(); } } else qWarning("[AbstractChatCore::addParametr]: '%s' is too large (%d bytes). not added\n", name.toLocal8Bit().data(), name.size()); } //\***************************************************************************** void AbstractChatCore::clearParametrs() { parametrs().clear(); hdr()->parametrs.clear(); hdr()->color = Qt::black; } //\***************************************************************************** QByteArray AbstractChatCore::getParametr(const QString & par_name, const QByteArray& pars) { // qDebug("[static ChatCore::getParametr]: req = '%s'", par_name.toLocal8Bit().data()); qint32 idx = -1; quint32 size; quint32 pars_size = pars.size(); QByteArray par(""); uchar n_size; char arr2[2]; char par_size[4]; QString name; for(uint i = 0; i < pars_size; ) { arr2[0] = pars.at(i++); arr2[1] = pars.at(i++); n_size = str2US(arr2); name.clear(); if(i + n_size >= pars_size) break; for(int j = 0; j < n_size; j++, i++) par.append(pars.at(i)); name = QString().fromUtf8(par); par.resize(0); // qDebug("[static ChatCore::getParametr]: name = %s", name.toLocal8Bit().data()); if(name == par_name) { idx = i - n_size; break; } if(i + 3 < pars_size) { par_size[0] = pars.at(i ); par_size[1] = pars.at(i + 1); par_size[2] = pars.at(i + 2); par_size[3] = pars.at(i + 3); size = str2UL(par_size); i += 4 + size; } else break; } // qDebug("[static ChatCore::getParametr]: pars.size() = %d", pars.size()); // qDebug("[static ChatCore::getParametr]: idx = '%d'", idx); if(idx < 0) return QByteArray(); idx += par_name.toUtf8().size(); par_size[0] = pars.at(idx ); par_size[1] = pars.at(idx + 1); par_size[2] = pars.at(idx + 2); par_size[3] = pars.at(idx + 3); idx += 4; size = str2UL(par_size); // qDebug("[static ChatCore::getParametr]: size = %lu", (unsigned long)size); for(quint32 i = idx; i < idx + size && i < pars_size; i++) par.append(pars.at(i)); return par; } //\***************************************************************************** QByteArray AbstractChatCore::getParametr(const QString & par_name) { return getParametr(par_name, parametrs()); } //\***************************************************************************** QColor AbstractChatCore::getColorParametr(QByteArray* pars) { QByteArray par = getParametr("Color", *pars); QColor col(Qt::black); if(par.size() >= 3) col.setRgb((quint8)par[0], (quint8)par[1], (quint8)par[2]); else if(par.size() >= 4) col.setRgb(par[0], par[1], par[2], par[3]); return col; } //\***************************************************************************** QMap AbstractChatCore::getAllParametrs(const QByteArray & pars) { qint32 idx = -1; quint32 size; quint32 pars_size = pars.size(); QByteArray par(""); uchar n_size; char arr2[2]; char par_size[4]; QString name; QMap all_pars; for(uint i = 0; i < pars_size; ) { arr2[0] = pars.at(i++); arr2[1] = pars.at(i++); n_size = str2US(arr2); name.clear(); if(i + n_size >= pars_size) break; for(int j = 0; j < n_size; j++, i++) par.append(pars.at(i)); name = QString().fromUtf8(par); par.resize(0); //\***************** idx = i ; par_size[0] = pars.at(idx); par_size[1] = pars.at(idx + 1); par_size[2] = pars.at(idx + 2); par_size[3] = pars.at(idx + 3); idx += 4; size = str2UL(par_size); for(quint32 j = idx; j < idx + size && j < pars_size; j++) par.append(pars.at(j)); all_pars[name] = par; par.resize(0); //\***************** if(i + 3 < pars_size) { par_size[0] = pars.at(i ); par_size[1] = pars.at(i + 1); par_size[2] = pars.at(i + 2); par_size[3] = pars.at(i + 3); size = str2UL(par_size); i += 4 + size; } else break; } return all_pars; } //\***************************************************************************** void AbstractChatCore::prepareDatagram(AbstractChatCore::DataType dtgrm_type, quint64 dest_uid, const QString & nickname, const QString & compName, quint64 src_uid, const QString & msg /* = 0*/, AbstractChatCore::ChannelType chnnl_type/* = 0*/, // 0 - common, 1 - private, 2 - password unsigned long dtgrm_id /* = 0*/, unsigned long dtgrm_num /* = 0*/) { m_largeDtgrm = false; QByteArray msgData = msg .toUtf8(); QByteArray nameData = nickname.toUtf8(); QByteArray compNameData = compName.toUtf8(); int unl = nameData .size(); // user_name_len int cnl = compNameData.size(); // comp_name_len char* buf; m_outputBufferSize = protocolLen() + unl + cnl + msgData.size() + m_parametrs.size() + optionsLen(); if(m_outputBufferSize > MAX_PACKET_LEN) { m_largeDtgrm = true; // addParametr("Large"); } qDebug("[AbstractChatCore::prepareDatagram]: pr_len = %d, unl = %d, cnl = %d, msgData.size() = %d, m_parametrs.size() = %d", AbstractChatCore::protocolLen(), unl, cnl, msgData.size(), m_parametrs.size()); m_headerSize = protocolLen() + unl + cnl + optionsLen(); // 4 + 4 - dlya razmerov esli paket budet fragmented m_dataSize = msgData.size() + m_parametrs.size() + 4 + 4; m_header = (char*)realloc(m_header, m_dataSize + m_headerSize); assert(NULL != m_header); m_data = m_header + m_headerSize; setProgramId (m_header); setProgramVersion (m_header); setProtocolVersion(m_header); setDestIp (m_header, dest_uid); setSrcIp (m_header, src_uid); setPacketType (m_header, dtgrm_type); setPacketId (m_header, dtgrm_id); setPacketNum (m_header, dtgrm_num); setTime (m_header, QDateTime::currentDateTime().toTime_t()/*time(NULL)*/); // FIXME why segfaults on time() ??? setChannelType (m_header, chnnl_type); setCompNameLen (m_header, cnl); setUserNameLen (m_header, unl); setMessageLen (m_header, msgData.size()); setParametrsLen (m_header, m_parametrs.size()); setOptionsLen (m_header, 1); // FIXME !!!!!! setCompName (m_header, compName); setUserName (m_header, nickname); setCompressed (m_header, false); buf = m_data; if(m_largeDtgrm) { // SetMsgLen (m_header, msgData.size()); // SetParametrsLen(m_header, m_parametrs.size()); catUL2str(buf , msgData .size()); catUL2str(buf += 4, m_parametrs.size()); buf += 4; } memcpy(buf, msgData.data(), msgData.size()); if(!m_parametrs.isEmpty()) memcpy (buf += msgData.size(), m_parametrs.data(), m_parametrs.size()); // NOTE setParametrs will NOT work!! // FIXME remove that hack // setParametrs(m_header, m_parametrs); if(!m_largeDtgrm) { memcpy(m_outputBuffer , m_header, m_headerSize ); memcpy(m_outputBuffer + m_headerSize, m_data , m_dataSize - 8); // -8, t.k. paket ne fragmented m_outputBufferSize = m_headerSize + m_dataSize - 8; } } //\***************************************************************************** bool AbstractChatCore::fillHeader() { QHostAddress address; AbstractProtocol* prot = m_protocol; setProtocolVersion(checkProtocolVersion(m_inputBuffer)); // Razbor Dannyh if(m_inputBufferSize < protocolLen()) { qWarning("[AbstractChatCore::fillHeader]: [LengthError!] (m_inputBufferSize < AbstractChatCore::protocolLen()). Ignoring this packet\n"); m_protocol = prot; return 0; } if(strncmp(m_inputBuffer, programId(), programIdLen())) { qWarning("[AbstractChatCore::fillHeader]: [ID_ERROR!] (strncmp(m_inputBuffer, AbstractChatCore::programId(), 18) != 0). Ignoring this packet\n"); m_protocol = prot; return 0; } Hdr->receive_tm = QDateTime::currentDateTime().toTime_t();//time(NULL); Hdr->programVersion = programVersion(m_inputBuffer); if(Hdr->programVersion < 5) { qWarning("[AbstractChatCore::fillHeader]: [error] packet from old version of qchat ( < 5). Ignoring this packet\n"); m_protocol = prot; return 0; } Hdr->protocolVersion = protocolVersion(m_inputBuffer); if(Hdr->protocolVersion != protocolVersion()) { qWarning("[AbstractChatCore::fillHeader]: [error] protocol version mismatch (%d != %d). Ignoring this packet\n", Hdr->protocolVersion, protocolVersion()); m_protocol = prot; return 0; } Hdr->dest_ip = destIp (m_inputBuffer); Hdr->src_ip = srcIp (m_inputBuffer); Hdr->type = packetType (m_inputBuffer); Hdr->id = packetId (m_inputBuffer); Hdr->num = packetNum (m_inputBuffer); Hdr->tm = time (m_inputBuffer); Hdr->chnnl_id = channelType (m_inputBuffer); Hdr->comp_name_len = compNameLen (m_inputBuffer); Hdr->name_len = userNameLen (m_inputBuffer); Hdr->msg_len = messageLen (m_inputBuffer); Hdr->parametrs_len = parametrsLen(m_inputBuffer); qDebug("[AbstractChatCore::fillHeader]: type = %d", Hdr->type); uint expectedSize; if(protocolVersion() < 4) expectedSize = protocolLen() + Hdr->comp_name_len + Hdr->name_len + Hdr->msg_len + Hdr->parametrs_len; else expectedSize = packetSize(m_inputBuffer); if(m_inputBufferSize < expectedSize) { qWarning("[AbstractChatCore::fillHeader]: [error] wrong length of packet (actual size(%d) smaller than expected(%u)). Ignoring this packet\n", m_inputBufferSize, expectedSize); qDebug("[AbstractChatCore::fillHeader]: AbstractChatCore::protocolLen() = %d, Hdr->comp_name_len = %d, Hdr->name_len = %d, Hdr->msg_len = %lu, Hdr->parametrs_len = %lu", protocolLen(), Hdr->comp_name_len, Hdr->name_len, Hdr->msg_len, Hdr->parametrs_len); m_protocol = prot; return 0; } Hdr->comp_name = compName(m_inputBuffer, m_inputBufferSize); Hdr->name = userName(m_inputBuffer, m_inputBufferSize); Hdr->msg = message (m_inputBuffer, m_inputBufferSize); Hdr->parametrs.clear(); Hdr->parametrs = parametrs(m_inputBuffer, m_inputBufferSize); Hdr->color = getColorParametr(&Hdr->parametrs); Hdr->isHtml = !getParametr("HTML", Hdr->parametrs).isNull(); //********* getting versionName ********* QByteArray ba = getParametr("Version", Hdr->parametrs); if(!ba.isEmpty()) Hdr->versionName = QString().fromUtf8(ba); else if(Hdr->programVersion <= Globals::VersionID) Hdr->versionName = QString(Globals::VersionsTable[Hdr->programVersion - 1]); else Hdr->versionName = QString("New Version[id = %1]").arg(Hdr->programVersion); //********* getting status ********* Hdr->status = Globals::FREE; ba = getParametr("Status", Hdr->parametrs); if(!ba.isEmpty()) Hdr->status = ba[0]; m_protocol = prot; return 1; } //\***************************************************************************** void AbstractChatCore::newHdr() { Hdr = new QC_DatagramHeader; } bool isSystemMsg(quint16 type) { switch(type) { case AbstractChatCore::CONNECTED : case AbstractChatCore::DISCONNECTED : case AbstractChatCore::INF_STATUS_CHNGD : return true; } return false; } char* AbstractChatCore::uncompress(const char* buf, uint& size) { char* data_pos; uint shift = protocolLen() + optionsLen(buf) + compNameLen(buf) + userNameLen(buf); char* data; QByteArray ba; if(size < protocolLen() || size < shift) return NULL; data_pos = (char*)buf + shift; ba = qUncompress((const uchar*)data_pos, size - shift); size = ba.size() + shift; data = (char*)malloc(size); memcpy(data , buf , shift); memcpy(data + shift, ba.data(), ba.size()); return data; } char* AbstractChatCore::compress(const char * buf, uint & size) { char* data_pos; uint shift = protocolLen() + optionsLen(buf) + compNameLen(buf) + userNameLen(buf); char* data; QByteArray ba; if(size < protocolLen() || size < shift) return NULL; data_pos = (char*)buf + shift; ba = qCompress((const uchar*)data_pos, size - shift, 9); size = ba.size() + shift; data = (char*)malloc(size); memcpy(data , buf , shift); memcpy(data + shift, ba.data(), ba.size()); return data; } void AbstractChatCore::setProtocolVersion(uint ver) { if (ver == 3) m_protocol = m_protocolV3; else if(ver == 4) m_protocol = m_protocolV4; } uint AbstractChatCore::checkProtocolVersion(const char * buf) { AbstractProtocol* tmp = m_protocol; // int res; m_protocol = m_protocolV3; if(!strncmp(buf, programId(), programIdLen()) && protocolVersion(buf) == 3) { m_protocol = tmp; return 3; } m_protocol = m_protocolV4; if(!strncmp(buf, programId(), programIdLen()) && protocolVersion(buf) == 4) { m_protocol = tmp; return 4; } // res = protocolVersion(buf); m_protocol = tmp; return 0; } qchat-0.3/src/filtrationruleeditor.h0000644000076500017500000000370710777157461016433 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef FILTRATIONRULEEDITOR_H #define FILTRATIONRULEEDITOR_H #include #include #include #include #include #include #include class FiltrationRule; /** @author Anistratov Oleg */ class FiltrationRuleEditor : public QDialog { Q_OBJECT private: bool m_edited; FiltrationRule* m_rule; QLineEdit* m_nameEdit; QTextEdit* m_userNamesEdit; QTextEdit* m_compNamesEdit; QTextEdit* m_messageFilterEdit; QTextEdit* m_IPsEdit; QCheckBox* m_isRegExpChbx; QPushButton* m_okBtn; QPushButton* m_applyBtn; QPushButton* m_cancelBtn; public: FiltrationRuleEditor(QWidget *parent = 0); ~FiltrationRuleEditor(); void init(FiltrationRule*); public slots: void saveRule(); void edited(){m_edited = true; m_applyBtn->setEnabled(true);} }; #endif qchat-0.3/src/addchanneldialog.h0000644000076500017500000000326410665277442015416 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef ADDCHANNELDIALOG_H #define ADDCHANNELDIALOG_H #include #include #include #include /** @author Anistratov Oleg */ class AddChannelDlg : public QDialog { Q_OBJECT private: QLineEdit* m_editChannelName; QPushButton* m_okBtn; QPushButton* m_cancelBtn; QLabel* m_lab; public: AddChannelDlg(QWidget *parent = 0); ~AddChannelDlg(){}; void retranslate(); public slots: void setValues(); void getValues(){show(); m_editChannelName->setFocus();} signals: void dataAccepted(const QString &); }; #endif qchat-0.3/src/singlemsgshistory.h0000644000076500017500000000346410770077413015745 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SINGLEMSGSHISTORY_H #define SINGLEMSGSHISTORY_H #include #include #include #include "message.h" /** @author Anistratov Oleg */ class SingleMsgsHistory : public QObject { Q_OBJECT private: QList m_messagesIn; QList m_messagesOut; public: SingleMsgsHistory(QObject *parent = 0); ~SingleMsgsHistory(); void addMessage(Message* msg); Message* messageIn(int n){if(m_messagesIn.size()) return m_messagesIn[n]; else return NULL;} Message* messageOut(int n){if(m_messagesOut.size()) return m_messagesOut[n]; else return NULL;} QList messagesIn () const {return m_messagesIn;} QList messagesOut() const {return m_messagesOut;} }; #endif qchat-0.3/src/messagefiltereditor.h0000644000076500017500000000363611001133176016175 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef MESSAGEFILTEREDITOR_H #define MESSAGEFILTEREDITOR_H #include #include #include class MessageFilter; class FiltrationRule; /** @author Anistratov Oleg */ class MessageFilterEditor : public QWidget { Q_OBJECT private: MessageFilter* m_filter; QListWidget* m_rulesListWgt; QPushButton* m_addRuleBtn; QPushButton* m_delRuleBtn; QPushButton* m_enableDisableRuleBtn; private: void retranslate(); public: MessageFilterEditor(QWidget *parent = 0); ~MessageFilterEditor(); void setFilter(MessageFilter* filter){m_filter = filter;} void refresh(); bool editRule(FiltrationRule*); public slots: void addRule(); void editRule(QListWidgetItem*); void removeRule(); void enableDisableRule(); void itemActivated(int); }; #endif qchat-0.3/src/protocolversion3.cpp0000644000076500017500000000454211002155514016017 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "protocolversion3.h" const char* ProtocolVersion3::m_programId = "QChat4Linux&Others"; // :) ProtocolVersion3::ProtocolVersion3() : AbstractProtocol() { } ProtocolVersion3::~ProtocolVersion3() { } QString ProtocolVersion3::compName(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + compNameLen(buf)) return QString(); return QString::fromUtf8(buf + protocolLen(), compNameLen(buf)); } QString ProtocolVersion3::userName(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + compNameLen(buf) + userNameLen(buf)) return QString(); return QString::fromUtf8(buf + protocolLen() + compNameLen(buf), userNameLen(buf)); } QString ProtocolVersion3::message(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + compNameLen(buf) + userNameLen(buf) + messageLen(buf)) return QString(); return QString::fromUtf8(buf + protocolLen() + compNameLen(buf) + userNameLen(buf), messageLen(buf)); } QByteArray ProtocolVersion3::parametrs(const char * buf, uint sz) { if(sz < protocolLen() || sz < protocolLen() + compNameLen(buf) + userNameLen(buf) + messageLen(buf) + parametrsLen(buf)) return QByteArray(); return QByteArray(buf + protocolLen() + compNameLen(buf) + userNameLen(buf) + messageLen(buf), parametrsLen(buf)); } qchat-0.3/src/largedatagram.cpp0000644000076500017500000003427011004454114015261 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "largedatagram.h" #include "globals.h" #include #include #include "chatcore.h" #include "userinfo.h" LargeDatagram::LargeDatagram(quint64 IP, quint32 ID, QObject* parent) : QObject(parent), m_remain (101), m_isFile (false), m_fileInited (false), m_inited (false), m_srcIP (IP), m_datagramID (ID), m_lastFragmentNum (0), m_fragments (NULL), m_data (NULL), m_requestInterval (1000), m_selfDestroyInterval(60 * 1000) { qDebug("[LargeDatagram::LargeDatagram]: ID = %lu", (unsigned long)ID); m_requestTimer = new QTimer(this); m_selfDestroyTimer = new QTimer(this); connect(m_requestTimer , SIGNAL(timeout()), this, SLOT(slot_fragmentsRequest ())); connect(m_selfDestroyTimer, SIGNAL(timeout()), this, SLOT(slot_selfDestroy ())); } //\***************************************************************************** LargeDatagram::~LargeDatagram() { qDebug("[~LargeDatagram]: ID = %lu", (unsigned long)m_datagramID); free(m_fragments); free(m_data); } //\***************************************************************************** void LargeDatagram::initDatagram(const char* dtgrm, quint32 dtgrm_len) { quint8 cnl; // comp_name_len quint8 unl; // user_name_len if(m_inited || dtgrm_len < AbstractChatCore::protocolLen()) return; m_programVersion = ChatCore::programVersion (dtgrm); m_protocolVersion = ChatCore::protocolVersion(dtgrm); m_destIP = ChatCore::destIp (dtgrm); m_packetType = ChatCore::packetType (dtgrm); m_fragmentSize = ChatCore::fragmentSize (dtgrm); m_firstFragmentTime = ChatCore::time (dtgrm); m_channelType = ChatCore::channelType (dtgrm); cnl = ChatCore::compNameLen (dtgrm); unl = ChatCore::userNameLen (dtgrm); if(dtgrm_len < quint32(AbstractChatCore::protocolLen() + unl + cnl + AbstractChatCore::optionsLen(dtgrm))) return; m_totalFragments = ChatCore::messageLen (dtgrm); m_totalSize = ChatCore::parametrsLen(dtgrm); m_senderCompName = ChatCore::compName (dtgrm, dtgrm_len); m_senderName = ChatCore::userName (dtgrm, dtgrm_len); // не m_totalFragments-1, потому что 0-й фрагмент является инициализирующим m_lastFragmentNum = m_totalFragments; // вычисляем есть ли остаток if(m_totalSize < m_fragmentSize * m_totalFragments) m_lastFragmentSize = m_totalSize - (m_fragmentSize * (m_totalFragments - 1)); else m_lastFragmentSize = m_fragmentSize; m_currentSize = 0; m_fragmentsRemain = m_totalFragments; m_fragments = (char*)calloc(m_totalFragments, 1); assert(NULL != m_fragments); //****************** if(AbstractChatCore::packetType(dtgrm) == AbstractChatCore::FILE) { QByteArray ba; quint16 size; if(dtgrm_len >= quint32(AbstractChatCore::protocolLen() + unl + cnl + 2 + AbstractChatCore::optionsLen(dtgrm))) { size = str2US(dtgrm + AbstractChatCore::protocolLen() + unl + cnl + AbstractChatCore::optionsLen(dtgrm)); if(dtgrm_len >= quint32(AbstractChatCore::protocolLen() + unl + cnl + 2 + size + AbstractChatCore::optionsLen(dtgrm))) { m_filename = QString().fromUtf8(dtgrm + AbstractChatCore::protocolLen() + unl + cnl + 2, size + AbstractChatCore::optionsLen(dtgrm)); // FIXME kraine koryavo qDebug("[LargeDatagram::initDatagram]: filename = %s", m_filename.toLocal8Bit().data()); } m_isFile = true; } else { m_selfDestroyTimer->setInterval(m_selfDestroyInterval); m_selfDestroyTimer->start(); return; } } //****************** else { m_data = (char*)calloc(m_totalSize, 1); assert(NULL != m_data); } m_inited = true; if((!m_isFile || m_fileInited) && m_requestTimer && m_selfDestroyTimer) { m_requestTimer->setInterval(m_requestInterval); m_requestTimer->start(); m_selfDestroyTimer->setInterval(m_selfDestroyInterval); m_selfDestroyTimer->start(); } else if(!m_requestTimer || !m_selfDestroyTimer) { Globals::addError("Timer(s) is(are) NULL!"); qWarning("[LargeDatagram[%d]::initDatagram]: Timer(s) is(are) NULL! req_timer = %p, destr_timer = %p\n ", m_datagramID, m_requestTimer, m_selfDestroyTimer); } } //\***************************************************************************** void LargeDatagram::addFragment(const char* dtgrm, quint32 dtgrm_len) { // qDebug("[LargeDatagram[%d]::addFragment]:", m_datagramID); // TODO proveryat' sootvetstvie dtgrm_len neobhodimomu razmeru if(!m_inited || !m_fragmentsRemain || dtgrm_len < AbstractChatCore::protocolLen()) return; quint32 num = ChatCore::packetNum (dtgrm); quint8 cnl = ChatCore::compNameLen(dtgrm); quint8 unl = ChatCore::userNameLen(dtgrm); if((dtgrm_len < quint32(AbstractChatCore::protocolLen() + unl + cnl + AbstractChatCore::optionsLen(dtgrm))) || m_fragments[num - 1] || (ChatCore::packetType(dtgrm) == AbstractChatCore::FILE)) return; // если фрагмент последний - его размер может быть меньше чем у остальных.. выясним это: int fragment_size = (num != m_totalFragments) ? m_fragmentSize : m_lastFragmentSize; if(dtgrm_len < quint32(AbstractChatCore::protocolLen() + unl + cnl + fragment_size + AbstractChatCore::optionsLen(dtgrm))) return; memcpy((m_data + (num - 1) * m_fragmentSize), dtgrm + AbstractChatCore::protocolLen() + cnl + unl + AbstractChatCore::optionsLen(dtgrm), fragment_size); m_fragmentsRemain--; m_currentSize += fragment_size; m_fragments[num - 1] = 1; if(!m_fragmentsRemain) { m_finalFragmentTime = time(NULL); m_requestTimer->stop(); m_selfDestroyTimer->stop(); delete m_selfDestroyTimer; delete m_requestTimer; m_selfDestroyTimer = NULL; m_requestTimer = NULL; return; } else if(num == m_lastFragmentNum) { qDebug("[LargeDatagram[%d]::addFragment]: fragmentsRemain = %d", m_datagramID, m_fragmentsRemain); qDebug("[LargeDatagram[%d]::addFragment]: lastFragmentNum = %d", m_datagramID, m_lastFragmentNum); for(int i = m_lastFragmentNum; i >= 0; i--) if(!m_fragments[i]) { m_lastFragmentNum = i; break; } qDebug("[LargeDatagram[%d]::addFragment]: newLastFragmentNum = %d", m_datagramID, m_lastFragmentNum); emit wantFragments(m_fragments, m_totalFragments, m_datagramID, m_srcIP); } if(m_requestTimer) m_requestTimer->start(m_requestInterval); if(m_selfDestroyTimer) m_selfDestroyTimer->start(m_selfDestroyInterval); } //\***************************************************************************** void LargeDatagram::addFileFragment(const char* dtgrm, quint32 dtgrm_len) { if(!m_inited || !m_fragmentsRemain || dtgrm_len < AbstractChatCore::protocolLen() || (m_isFile && !m_fileInited)) return; quint32 num = ChatCore::packetNum (dtgrm); quint8 cnl = ChatCore::compNameLen(dtgrm); quint8 unl = ChatCore::userNameLen(dtgrm); if(dtgrm_len < quint32(AbstractChatCore::protocolLen() + unl + cnl + AbstractChatCore::optionsLen(dtgrm))) return; if(m_fragments[num - 1]) return; // если фрагмент последний - его размер может быть меньше чем у остальных.. выясним это: int fragment_size = (num != m_totalFragments) ? m_fragmentSize : m_lastFragmentSize; if(dtgrm_len < quint32(AbstractChatCore::protocolLen() + unl + cnl + fragment_size + AbstractChatCore::optionsLen(dtgrm))) return; m_file.seek(m_fragmentSize * (num - 1)); m_file.write(dtgrm + AbstractChatCore::protocolLen() + cnl + unl + AbstractChatCore::optionsLen(dtgrm), fragment_size); m_fragmentsRemain--; m_currentSize += fragment_size; m_fragments[num - 1] = 1; if(!m_fragmentsRemain) { m_finalFragmentTime = time(NULL); printf("[LargeDatagram[%d]::addFileFragment]: 0%% left\n", m_datagramID); emit percentsRemain(0, m_datagramID, m_srcIP); m_file.close(); m_requestTimer->stop(); m_selfDestroyTimer->stop(); delete m_selfDestroyTimer; delete m_requestTimer; m_selfDestroyTimer = NULL; m_requestTimer = NULL; emit completed(this); return; } else if(num == m_lastFragmentNum) { qDebug("[LargeDatagram[%d]::addFileFragment]: fragmentsRemain = %d", m_datagramID, m_fragmentsRemain); qDebug("[LargeDatagram[%d]::addFileFragment]: lastFragmentNum = %d", m_datagramID, m_lastFragmentNum); for(int i = m_lastFragmentNum; i >= 0; i--) if(!m_fragments[i]) { m_lastFragmentNum = i; break; } qDebug("[LargeDatagram[%d]::addFileFragment]: newLastFragmentNum = %d", m_datagramID, m_lastFragmentNum); emit wantFragments(m_fragments, m_totalFragments, m_datagramID, m_srcIP); } quint8 remain = (quint8)((double)m_fragmentsRemain / ((double)m_totalFragments / (double)100)); if(remain < m_remain) { m_remain = remain; printf("[LargeDatagram[%d]::addFileFragment]: %d%% left\n", m_datagramID, remain); emit percentsRemain(remain, m_datagramID, m_srcIP); } if(m_requestTimer) m_requestTimer->start(m_requestInterval); if(m_selfDestroyTimer) m_selfDestroyTimer->start(m_selfDestroyInterval); } //\***************************************************************************** bool LargeDatagram::fillHeader(QC_DatagramHeader* Hdr) { qDebug("[LargeDatagram(%lu, %lu)::fillHeader], m_inited = %d", (unsigned long)m_srcIP, (unsigned long)m_datagramID, m_inited); int shift; shift = /*m_protocolVersion >= 4 ? 0 :*/ 8; if(m_inited == false || m_programVersion < 5 || (m_protocolVersion != AbstractChatCore::protocolVersion())) return 0; Hdr->programVersion = m_programVersion; Hdr->protocolVersion = m_protocolVersion; Hdr->dest_ip = m_destIP; Hdr->src_ip = m_srcIP; Hdr->type = m_packetType; Hdr->tm = m_firstFragmentTime; Hdr->receive_tm = m_finalFragmentTime; Hdr->name = m_senderName; Hdr->comp_name = m_senderCompName; Hdr->chnnl_id = m_channelType; Hdr->msg_len = str2UL(m_data ); Hdr->parametrs_len = str2UL(m_data + 4); printf("protver = %d\n", m_protocolVersion); // if(m_protocolVersion >= 4) // { // Hdr->msg_len = AbstractChatCore::messageLen(m_data); // Hdr->parametrs_len = AbstractChatCore::parametrsLen(m_data); // } if(m_totalSize < shift + Hdr->msg_len + Hdr->parametrs_len) { qWarning("[LargeDatagram::fillHeader]: [error] wrong length of fragmented packet (total size smaller than expected[%jd < %lu]) [3]\n Exiting from fillHeader\n", m_totalSize, shift + Hdr->msg_len + Hdr->parametrs_len ); // qWarning("[LargeDatagram::fillHeader]: %d + %d\n", Hdr->msg_len, Hdr->parametrs_len); return 0; } Hdr->msg = QString().fromUtf8( QByteArray(m_data + shift, Hdr->msg_len), Hdr->msg_len ); Hdr->parametrs = QByteArray(m_data + shift + Hdr->msg_len, Hdr->parametrs_len); Hdr->color = ChatCore::getColorParametr(&Hdr->parametrs); // getting versionName QByteArray ba = ChatCore::getParametr("Version", Hdr->parametrs); if(!ba.isEmpty()) Hdr->versionName = QString().fromUtf8(ba); else if(Hdr->programVersion <= Globals::VersionID) Hdr->versionName = QString(Globals::VersionsTable[Hdr->programVersion - 1]); else Hdr->versionName = QString("New Version[id = %1]").arg(Hdr->programVersion); // getting status Hdr->status = Globals::FREE; ba = ChatCore::getParametr("Status", Hdr->parametrs); if(!ba.isEmpty()) Hdr->status = ba[0]; clear(); emit completed(this); return 1; } //\***************************************************************************** void LargeDatagram::clear() { if(m_inited) { free(m_data); free(m_fragments); m_data = NULL; m_fragments = NULL; } m_inited = false; } //\***************************************************************************** void LargeDatagram::slot_fragmentsRequest() { qDebug("[LargeDatagram[%d]::slot_fragmentsRequest]", m_datagramID); if(m_inited && m_fragmentsRemain) emit wantFragments(m_fragments, m_totalFragments, m_datagramID, m_srcIP); } //\***************************************************************************** void LargeDatagram::slot_selfDestroy() { qDebug("[LargeDatagram[%d]::selfDestroy]", m_datagramID); delete m_requestTimer; delete m_selfDestroyTimer; clear(); m_inited = false; emit wantDie(this); } //\***************************************************************************** void LargeDatagram::allocateSpace() { if(!m_fileInited) return; m_file.open(QIODevice::WriteOnly); m_file.resize(m_totalSize); m_file.seek(0); } //\***************************************************************************** void LargeDatagram::slot_initFile(const QString & filename) { m_file.setFileName(filename); m_fileInited = true; allocateSpace(); m_requestTimer->setInterval(m_requestInterval); m_requestTimer->start(); emit readyReceive(m_datagramID, m_srcIP); } //\***************************************************************************** qchat-0.3/src/smileswgt.h0000644000076500017500000000405410767213764014171 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SMILESWGT_H #define SMILESWGT_H #include #include #include #include #include struct Smile { QStringList smiles; QString name; Smile(QStringList smiles_, QString name_){smiles = smiles_; name = name_;} }; class SmileLabel; /** @author Anistratov Oleg */ class SmilesWgt : public QWidget { Q_OBJECT private: bool m_inited; QGridLayout* m_grid; SmileLabel** m_smiles; int m_smilesNum; int m_smilesMaxNum; public: SmilesWgt(QWidget *parent = 0); ~SmilesWgt(); void init(); void loadTheme(const QString &); bool inited() const {return m_inited;} void clear(); void setOptimalSize(); QSize optimalSize(); private: void addSmile(const QString &, const QStringList &, const QString &); public slots: void unselectAll(); signals: void smileClicked(const QString &); void wantHide(); }; #endif qchat-0.3/src/userlisticonconfigurewgt.cpp0000644000076500017500000002662410767026021017650 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "userlisticonconfigurewgt.h" #include "userlisticonformat.h" #include UserListIconConfigureWgt::UserListIconConfigureWgt(QWidget *parent, const UserListIconFormat& fmt) : QWidget(parent), m_format(fmt) { QGridLayout* grid = new QGridLayout(this); m_textLab = new QLabel(this); m_totalLab = new QLabel(this); m_genderLab = new QLabel(this); m_statusLab = new QLabel(this); m_avatarLab = new QLabel(this); m_widthLab = new QLabel(this); m_heightLab = new QLabel(this); m_xOffsetLab = new QLabel(this); m_yOffsetLab = new QLabel(this); m_totalWidthSpbx = new QSpinBox(this); m_totalHeightSpbx = new QSpinBox(this); m_genderWidthSpbx = new QSpinBox(this); m_genderHeightSpbx = new QSpinBox(this); m_statusWidthSpbx = new QSpinBox(this); m_statusHeightSpbx = new QSpinBox(this); m_avatarWidthSpbx = new QSpinBox(this); m_avatarHeightSpbx = new QSpinBox(this); m_genderXSpbx = new QSpinBox(this); m_genderYSpbx = new QSpinBox(this); m_statusXSpbx = new QSpinBox(this); m_statusYSpbx = new QSpinBox(this); m_avatarXSpbx = new QSpinBox(this); m_avatarYSpbx = new QSpinBox(this); m_textEdit = new QLineEdit(this); grid->addWidget(m_widthLab , 0, 1); grid->addWidget(m_heightLab , 0, 2); grid->addWidget(m_xOffsetLab, 0, 3); grid->addWidget(m_yOffsetLab, 0, 4); grid->addWidget(m_totalLab , 1, 0); grid->addWidget(m_totalWidthSpbx , 1, 1); grid->addWidget(m_totalHeightSpbx, 1, 2); // grid->addWidget(m_totalXSpbx , 1, 3); // grid->addWidget(m_totalYSpbx , 1, 4); grid->addWidget(m_genderLab , 2, 0); grid->addWidget(m_genderWidthSpbx , 2, 1); grid->addWidget(m_genderHeightSpbx, 2, 2); grid->addWidget(m_genderXSpbx , 2, 3); grid->addWidget(m_genderYSpbx , 2, 4); grid->addWidget(m_statusLab , 3, 0); grid->addWidget(m_statusWidthSpbx , 3, 1); grid->addWidget(m_statusHeightSpbx, 3, 2); grid->addWidget(m_statusXSpbx , 3, 3); grid->addWidget(m_statusYSpbx , 3, 4); grid->addWidget(m_avatarLab , 4, 0); grid->addWidget(m_avatarWidthSpbx , 4, 1); grid->addWidget(m_avatarHeightSpbx, 4, 2); grid->addWidget(m_avatarXSpbx , 4, 3); // grid->addWidget(m_avatarYSpbx , 4, 4); m_avatarYSpbx->hide(); // grid->addWidget(m_genderWidthLab , 1, 0); // grid->addWidget(m_genderWidthSpbx , 1, 1); // grid->addWidget(m_genderHeightLab , 1, 2); // grid->addWidget(m_genderHeightSpbx, 1, 3); // grid->addWidget(m_statusWidthLab , 2, 0); // grid->addWidget(m_statusWidthSpbx , 2, 1); // grid->addWidget(m_statusHeightLab , 2, 2); // grid->addWidget(m_statusHeightSpbx, 2, 3); grid->addWidget(m_textLab , 5, 0); grid->addWidget(m_textEdit, 5, 1, 1, 4); setFormat(m_format); m_textEdit->setToolTip("%nick\n" "%compname\n" "%firstname\n" "%lastname\n" "%secondname\n" "%version\n" "%uid\n" "%ip"); connect(m_totalWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_totalHeightSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_textEdit , SIGNAL(textChanged (QString)), this, SLOT(changeFormat())); retranslate(); } UserListIconConfigureWgt::~UserListIconConfigureWgt() { } void UserListIconConfigureWgt::changeFormat() { m_format.setText(m_textEdit->text()); m_format.setTotalWidth (m_totalWidthSpbx ->value()); m_format.setTotalHeight (m_totalHeightSpbx ->value()); m_format.setGenderWidth (m_genderWidthSpbx ->value()); m_format.setGenderHeight (m_genderHeightSpbx->value()); m_format.setGenderXoffset(m_genderXSpbx ->value()); m_format.setGenderYoffset(m_genderYSpbx ->value()); m_format.setStatusWidth (m_statusWidthSpbx ->value()); m_format.setStatusHeight (m_statusHeightSpbx->value()); m_format.setStatusXoffset(m_statusXSpbx ->value()); m_format.setStatusYoffset(m_statusYSpbx ->value()); m_format.setAvatarWidth (m_avatarWidthSpbx ->value()); m_format.setAvatarHeight (m_avatarHeightSpbx->value()); m_format.setAvatarXoffset(m_avatarXSpbx ->value()); m_format.setAvatarYoffset(m_avatarYSpbx ->value()); m_statusHeightSpbx ->setMaximum(m_format.totalHeight()); m_statusYSpbx ->setMaximum(m_format.totalHeight() - m_format.statusHeight()); m_statusWidthSpbx ->setMaximum(m_format.totalWidth()); m_statusXSpbx ->setMaximum(m_format.totalWidth() - m_format.statusWidth()); m_genderHeightSpbx ->setMaximum(m_format.totalHeight()); m_genderYSpbx ->setMaximum(m_format.totalHeight() - m_format.genderHeight()); m_genderWidthSpbx ->setMaximum(m_format.totalWidth()); m_genderXSpbx ->setMaximum(m_format.totalWidth() - m_format.genderWidth()); m_avatarHeightSpbx ->setMaximum(m_format.totalHeight()); m_avatarYSpbx ->setMaximum(m_format.totalHeight() - m_format.avatarHeight()); m_avatarWidthSpbx ->setMaximum(m_format.totalWidth()); m_avatarXSpbx ->setMaximum(m_format.totalWidth() - m_format.avatarWidth()); emit formatChanged(m_format); } void UserListIconConfigureWgt::retranslate() { m_totalLab ->setText(tr("Total Size:")); m_genderLab ->setText(tr("Gender Icon:")); m_statusLab ->setText(tr("Status Icon:")); m_avatarLab ->setText(tr("Avatar Icon:")); m_textLab ->setText(tr("Text:")); m_widthLab ->setText(tr("Width")); m_heightLab ->setText(tr("Height")); m_xOffsetLab->setText(tr("X offset")); m_yOffsetLab->setText(tr("Y offset")); } void UserListIconConfigureWgt::setFormat(const UserListIconFormat & fmt) { disconnect(m_totalWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_totalHeightSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_genderWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_genderHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_genderXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_genderYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_statusWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_statusHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_statusXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_statusYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_avatarWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_avatarHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_avatarXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); disconnect(m_avatarYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); m_format = fmt; m_textEdit->setText(m_format.text()); m_statusHeightSpbx ->setMaximum(99); m_statusYSpbx ->setMaximum(99); m_statusWidthSpbx ->setMaximum(99); m_statusXSpbx ->setMaximum(99); m_genderHeightSpbx ->setMaximum(99); m_genderYSpbx ->setMaximum(99); m_genderWidthSpbx ->setMaximum(99); m_genderXSpbx ->setMaximum(99); m_avatarHeightSpbx ->setMaximum(99); m_avatarYSpbx ->setMaximum(99); m_avatarWidthSpbx ->setMaximum(99); m_avatarXSpbx ->setMaximum(99); m_totalWidthSpbx ->setValue(m_format.totalWidth()); m_totalHeightSpbx ->setValue(m_format.totalHeight()); m_genderWidthSpbx ->setValue(m_format.genderWidth()); m_genderHeightSpbx->setValue(m_format.genderHeight()); m_genderXSpbx ->setValue(m_format.genderXoffset()); m_genderYSpbx ->setValue(m_format.genderYoffset()); m_statusWidthSpbx ->setValue(m_format.statusWidth()); m_statusHeightSpbx->setValue(m_format.statusHeight()); m_statusXSpbx ->setValue(m_format.statusXoffset()); m_statusYSpbx ->setValue(m_format.statusYoffset()); m_avatarWidthSpbx ->setValue(m_format.avatarWidth()); m_avatarHeightSpbx->setValue(m_format.avatarHeight()); m_avatarXSpbx ->setValue(m_format.avatarXoffset()); m_avatarYSpbx ->setValue(m_format.avatarYoffset()); connect(m_totalWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_totalHeightSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_genderYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_statusYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarWidthSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarHeightSpbx, SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarXSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); connect(m_avatarYSpbx , SIGNAL(valueChanged(int)), this, SLOT(changeFormat())); changeFormat(); } qchat-0.3/src/largedatagramout.cpp0000644000076500017500000002233211002616255016011 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "largedatagramout.h" #include #include "chatcore.h" LargeDatagramOut::LargeDatagramOut(QObject *parent) : QObject(parent), m_confirmed (false), m_inited (false), m_header (NULL), m_data (NULL), m_fragments (NULL), m_selfDestroyInterval(10 * 1000) { m_selfDestroyTimer = new QTimer(this); connect(m_selfDestroyTimer, SIGNAL(timeout()), this, SLOT(selfDestroy())); } //\***************************************************************************** LargeDatagramOut::~LargeDatagramOut() { qDebug("[~LargeDatagramOut]: ID = %lu", (unsigned long)m_id); free(m_header); // we need free only m_header beckause m_data points to m_header + m_headerSize free(m_fragments); } //\***************************************************************************** void LargeDatagramOut::init(char* header, quint16 header_size, char* data , quint32 data_size , quint64 dest_uid, quint32 id) { m_id = id; m_header = header; m_data = data ; m_headerSize = header_size; m_dataSize = data_size; m_sizePerFragment = (MAX_PACKET_LEN - m_headerSize); m_rest = m_dataSize % m_sizePerFragment; m_totalFragments = m_dataSize / m_sizePerFragment + m_rest; m_fragmentsRemain = m_totalFragments; m_fragments = (char*)calloc(m_totalFragments + 1, 1);// + 1, beckause we need to send initialization packet m_inited = true; m_confirmed = true; m_destUid = dest_uid; } //\***************************************************************************** void LargeDatagramOut::init(char* header, quint16 header_size, const QString & filename, quint64 dest_uid, quint32 id) { m_id = id; m_header = header; m_data = NULL; m_headerSize = header_size; m_dataSize = 0; m_filename = filename; m_destUid = dest_uid; m_file.setFileName(filename); if(!m_file.open(QIODevice::ReadOnly)) { qWarning("[LargeDatagramOut::init]: Failed. couldn't open file %s for reading!\n", m_filename.toLocal8Bit().data()); emit wantDie(this); emit sendingCancelled(id); return; } if(m_file.handle() < 0) { qWarning("[LargeDatagramOut::init]: m_file.handle() < 0\n"); // emit wantDie(this); // return; } m_fileSize = m_file.size(); m_sizePerFragment = (MAX_PACKET_LEN - m_headerSize); m_rest = m_fileSize % m_sizePerFragment; m_totalFragments = m_fileSize / m_sizePerFragment + m_rest; m_fragmentsRemain = m_totalFragments; m_fragments = (char*)calloc(m_totalFragments + 1, 1);// + 1, t.k. nado otoslat' esche i initsializir. paket! m_inited = true; } //\***************************************************************************** void LargeDatagramOut::prepareInitHeader() { if(!m_inited) return; AbstractChatCore::setPacketId (m_header, m_id); AbstractChatCore::setFragmentSize(m_header, m_sizePerFragment); AbstractChatCore::setPacketNum (m_header, 0); AbstractChatCore::setMessageLen (m_header, m_totalFragments); // +61 MsgLen / TotalFragments / DataLen // FIXME !!!file size may be greater then quint32!!! if(!m_filename.isEmpty()) AbstractChatCore::setParametrsLen(m_header, m_fileSize); else AbstractChatCore::setParametrsLen(m_header, m_dataSize); // +65 ParametersLen / TotalSize / == 0 } //\***************************************************************************** void LargeDatagramOut::sendNextFragment(QAbstractSocket* socket, quint16 port, char* buf) { quint32 num; quint32 i; quint32 size; int res = -1; QTcpSocket* tcp = qobject_cast(socket); QUdpSocket* udp = qobject_cast(socket); if(!m_fragmentsRemain) { if(m_selfDestroyTimer && (m_selfDestroyTimer->timerId() < 0)) { m_selfDestroyTimer->setSingleShot(true); m_selfDestroyTimer->start(m_selfDestroyInterval); } return; } // TODO optimizirovat' for(i = 0; i <= m_totalFragments; i++) if(m_fragments[i] == 0) break; num = i; if(num != 0 && !m_confirmed) return; if(num > m_totalFragments)// znachit net neotoslannyh fragmentov. i soobschenii o peresylke ne prihodilo return; size = writeFragment(buf, num); if(tcp) { AbstractChatCore::setPacketSize(buf, size); res = tcp->write(buf, size); tcp->flush(); } else if(udp) res = udp->writeDatagram(buf, size, QHostAddress(m_destUid), port); if(res < 0) qWarning("\n[LargeDatagramOut::sendNextFragment]: datagram send error !\n"); else { m_fragments[num] = 1; if(num) m_fragmentsRemain--; // esli vse otoslali - zhdem nekotoroe vremya zaprosov pereslat' zanovo fragmenty, // i esli zaprosa ne prihodit unichtozhaemsya if(!m_fragmentsRemain) { m_selfDestroyTimer->setSingleShot(true); m_selfDestroyTimer->start(m_selfDestroyInterval); } } } //\***************************************************************************** quint32 LargeDatagramOut::writeFragment(char* buf, quint32 num) { if(!m_inited || !buf || num > m_totalFragments) return 0; uint fragmentSize = m_sizePerFragment; if(num == m_totalFragments && m_rest) if(!m_filename.isEmpty()) fragmentSize = m_fileSize % m_sizePerFragment; else fragmentSize = m_dataSize % m_sizePerFragment; if(!num) { prepareInitHeader(); memcpy(buf, m_header, m_headerSize); if(!m_filename.isEmpty()) { QByteArray ba = m_filename.right(m_filename.size() - 1 - m_filename.lastIndexOf("/")).toUtf8(); catUS2str(buf + m_headerSize, ba.size()); memcpy(buf + m_headerSize + 2, ba.data(), ba.size()); return m_headerSize + 2 + ba.size(); } return m_headerSize; } AbstractChatCore::setParametrsLen(m_header, 0); // +65 ParametersLen / TotalSize / == 0 AbstractChatCore::setPacketNum (m_header, num); //PacketNUM AbstractChatCore::setMessageLen (m_header, m_sizePerFragment); // +61 MsgLen / TotalFragments / DataLen memcpy(buf, m_header, m_headerSize); if(!m_filename.isEmpty()) { m_file.seek((num - 1) * m_sizePerFragment); m_file.read(buf + m_headerSize, fragmentSize); return m_headerSize + fragmentSize; } memcpy(buf + m_headerSize, m_data + (m_sizePerFragment * (num - 1)), fragmentSize); return m_headerSize + fragmentSize; } //\***************************************************************************** void LargeDatagramOut::selfDestroy() { qDebug("[LargeDatagramOut[%d]::selfDestroy]", m_id); emit wantDie(this); } //\***************************************************************************** void LargeDatagramOut::slot_confirmed(unsigned short ID) { if(m_id == ID) m_confirmed = true; } //\***************************************************************************** void LargeDatagramOut::fragmentsRequest(const char* dtgrm, quint16 len) { // qDebug("[LargeDatagramOut::fragmentsRequest]"); quint32 i; quint32 shift; quint32 pars_len = AbstractChatCore::parametrsLen(dtgrm); shift = AbstractChatCore::compNameLen(dtgrm) + AbstractChatCore::protocolLen() + AbstractChatCore::userNameLen(dtgrm) + AbstractChatCore::messageLen(dtgrm) + AbstractChatCore::optionsLen(dtgrm); if(len - shift < pars_len) return; QByteArray pars(dtgrm + shift, pars_len); QByteArray buf; quint16 frags_len; const char* frags; if(!m_inited) return; buf = ChatCore::getParametr("FragmentsLen", pars); frags_len = str2US(buf.data()); qDebug("[LargeDatagramOut::fragmentsRequest]: fragments_len = %d", frags_len); buf = ChatCore::getParametr("FragmentsRequest", pars); frags = buf.constData(); qDebug("[LargeDatagramOut::fragmentsRequest]: fragmentsRemain before = %d", m_fragmentsRemain); for(i = 0; i < frags_len && i < m_totalFragments; i++) if(!frags[i]) { m_fragmentsRemain += m_fragments[i + 1]; m_fragments[i + 1] = 0; } qDebug("[LargeDatagramOut::fragmentsRequest]: fragmentsRemain after = %d", m_fragmentsRemain); if(m_fragmentsRemain) m_selfDestroyTimer->stop(); } //\***************************************************************************** qchat-0.3/src/chattextwgt.cpp0000755000076500017500000003512711004062331015035 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "chattextwgt.h" // TODO remove "globals.h" from this header #include "globals.h" #include #include #include #include #include #include "message.h" #include "smileswgt.h" #include "smileswgt.h" #include "abstractchatcore.h" #include "animatedsmile.h" QList ChatTextWgt::m_smiles; ChatTextWgt::ChatTextWgt(QWidget *parent) : QWidget(parent), m_smilesFromSender(0), m_keepAnimations(-1) { QGridLayout* grid = new QGridLayout(this); m_text = new TextBrowser(this); m_text->setOpenExternalLinks(true); grid->addWidget(m_text, 0, 0); grid->setMargin(0); m_text->verticalScrollBar()->setTracking(true); initSmiles(QChatSettings::settings()->smilesThemePath()); connect(m_text, SIGNAL(viewportChanged()) , this, SLOT(setAnimations())); connect(m_text, SIGNAL(viewportVisible(bool)), this, SLOT(playPauseAnimations(bool))); } ChatTextWgt::~ChatTextWgt() { foreach(AnimatedSmile* sm, m_animatedSmiles) delete sm; qDebug("[ChatTextWgt::~ChatTextWgt]\n"); } //\***************************************************************************** void ChatTextWgt::addSmile(const QStringList & smiles, const QString & name) { m_smiles.append(Smile(smiles, name)); } //\***************************************************************************** void ChatTextWgt::initSmiles(const QString & path) { QFile file(path + "/emoticons.xml"); QDomDocument dom_document; QDomElement root; QDomElement child; QDomElement emoticon; QDomElement name; QDomNodeList elements; QDomNodeList elements_names; QStringList list; m_smiles.clear(); if(!file.open(QIODevice::ReadOnly)) { Globals::addError("Couldn't open " + path + "/emoticons.xml"); return; } if(!dom_document.setContent(&file, true)) { Globals::addError("Couldn't parse " + path + "/emoticons.xml"); return; } root = dom_document.documentElement(); elements = root.elementsByTagName("emoticon"); for(uint i = 0, len = elements.length(); i < len; i++) { emoticon = elements.item(i).toElement(); elements_names = emoticon.elementsByTagName("string"); list.clear(); for(uint j = 0, len = elements_names.length(); j < len; j++) { child = elements_names.item(j).toElement(); list.append(child.text()); } addSmile(list, emoticon.attribute("file")); } } //\***************************************************************************** void ChatTextWgt::addMsg(const Message* msg) { QTextDocument* doc = new QTextDocument; QTextCharFormat fmt; QTextBlockFormat bl_fmt; QDateTime date_time; QTextCursor cur_old = m_text->textCursor(); QTextCursor cur_new; QBrush brush(Qt::SolidPattern); int insert_begin; if(msg->isHtml()) doc->setHtml(msg->msg()); else doc->setPlainText(msg->msg()); // preparing msg header(user and time information) // ************************ date_time.setTime_t(msg->receiveTime()); if(isSystemMsg(msg->type())) brush.setColor(QChatSettings::settings()->sysColor()); else brush.setColor(msg->color()); fmt.setForeground(brush); QString msg_hdr(QChatSettings::settings()->strOption("DisplayMessagesFormat")); QString tm_fmt = msg_hdr.section(QString("%time%"), 1, 1); msg_hdr.replace(QRegExp("%time%([^<]*)%time%"), date_time.toString(tm_fmt)); msg_hdr.replace("%user", msg->userName()); msg_hdr.replace("%comp", msg->compName()); if(msg->requested()) msg_hdr.prepend(">"); // ************************ // setting cursor to the end of document and inserting msg header text with needed format cur_new = m_text->textCursor(); cur_new.clearSelection(); cur_new.setPosition(m_text->toPlainText().size()); cur_new.setCharFormat(fmt); cur_new.insertText(msg_hdr); // processing message and inserting smiles // ************************ int idx_end = 0; QString str; QString smile; QString msg_ = doc->toPlainText(); cur_new = doc->rootFrame()->firstCursorPosition(); smile = nextSmile (msg_); idx_end = msg_.indexOf(smile); for(; idx_end != -1 && !smile.isEmpty();) { str = msg_.left(idx_end); msg_ = msg_.right(msg_.size() - idx_end - smile.size()); cur_new = doc->find(smile, cur_new); if(!cur_new.isNull()) { while(cur_new.selectedText() != smile) { cur_new.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); if(cur_new.position() == doc->toPlainText().size()) break; } if(cur_new.selectedText() == smile) { // FIXME workarounding qt4.3 bug if(cur_new.currentList()) cur_new.insertText(" "); insertSmile(cur_new, smile); } if(cur_new.position() == doc->toPlainText().size()) break; } if((smile = nextSmile(msg_)).isEmpty()) break; idx_end = msg_.indexOf(smile); } // ************************ processLinks(doc); // inserting processed text in the end of the chat view cur_new = m_text->textCursor(); insert_begin = m_text->toPlainText().size(); cur_new.setPosition(insert_begin); cur_new.insertHtml(doc->toHtml()); // cur_new.insertText(doc->toPlainText()); // coloring whole msg accordingly to settings if(!(isSystemMsg(msg->type()) && !QChatSettings::settings()->boolOption("ColorWholeSystemMessage") || (msg->type() == AbstractChatCore::MESSAGE && !QChatSettings::settings()->boolOption("ColorWholeMessage")))) { cur_new.setPosition (insert_begin); cur_new.movePosition(QTextCursor::End, QTextCursor::KeepAnchor); cur_new.mergeCharFormat(fmt); cur_new.clearSelection(); } // restoring selection m_text->setTextCursor(cur_old); playPauseAnimations(QChatSettings::settings()->boolOption("UseAnimatedSmiles")); // if animation is disabled we will show only the first frame except showing nothing if(!QChatSettings::settings()->boolOption("UseAnimatedSmiles")) foreach(AnimatedSmile* sm, m_animatedSmiles) { sm->setPaused(false); sm->nextFrame(); sm->setPaused(true); } cur_new.insertBlock(QTextBlockFormat()); // TODO add autoscroll settings // if(scrl_max) m_text->verticalScrollBar()->setValue(m_text->verticalScrollBar()->maximum()); setAnimations(); delete doc; } //\***************************************************************************** void ChatTextWgt::setMsg(const QString & msg ) { QTextCursor cur_new = m_text->textCursor(); cur_new.clearSelection(); // Obrabotka soobscheniya i vstavka smailov int idx_end = 0; QString str; QString smile; QString msg_ = msg; cur_new.beginEditBlock(); smile = nextSmile (msg_); idx_end = msg_.indexOf(smile); for(int i = 0; i < 10 && idx_end != -1 && !smile.isEmpty(); i++) { str = msg_.left(idx_end); msg_ = msg_.right(msg_.size() - idx_end - smile.size()); cur_new.insertText(str); insertSmile(cur_new, smile); if((smile = nextSmile(msg_)).isEmpty()) break; idx_end = msg_.indexOf(smile); } str = msg_; cur_new.insertText(str); cur_new.endEditBlock(); } //\***************************************************************************** QString ChatTextWgt::nextSmile(const QString & str, Smile** smile_) { int i, j; int idx = -1, idx1; int smile = -1; int smile_pos = -1; int smile_size = 0; for(i = 0; i < m_smiles.size(); i++) for(j = 0; j < m_smiles[i].smiles.size(); j++) { idx1 = str.indexOf(m_smiles[i].smiles[j]); if(idx1 >= 0 && (idx1 <= idx || idx < 0)) { if(m_smiles[i].smiles[j].size() >= smile_size) { smile_size = m_smiles[i].smiles[j].size(); smile = i; smile_pos = j; idx = idx1; } } } if(smile >= 0 && smile_pos >= 0) { if(smile_) *smile_ = &m_smiles[smile]; return m_smiles[smile].smiles[smile_pos]; } else return QString(""); } //\***************************************************************************** QString ChatTextWgt::nextSmile(const QString & str) const { int i, j; int idx = -1, idx1; int smile = -1; int smile_pos = -1; int smile_size = 0; for(i = 0; i < m_smiles.size(); i++) for(j = 0; j < m_smiles[i].smiles.size(); j++) { idx1 = str.indexOf(m_smiles[i].smiles[j]); if(idx1 >= 0 && (idx1 < idx || idx < 0 || (idx1 == idx && m_smiles[i].smiles[j].size() >= smile_size))) { smile_size = m_smiles[i].smiles[j].size(); smile = i; smile_pos = j; idx = idx1; } } if(m_smilesFromSender) { for(i = 0; i < m_smilesFromSender->size(); i++) { idx1 = str.indexOf((*m_smilesFromSender)[i].smiles[0]); if(idx1 >= 0 && (idx1 <= idx || idx < 0)) { if((*m_smilesFromSender)[i].smiles[0].size() >= smile_size) { smile_size = (*m_smilesFromSender)[i].smiles[0].size(); smile = i; smile_pos = -1; idx = idx1; } } } } if(smile >= 0 && smile_pos >= 0) return m_smiles[smile].smiles[smile_pos]; else if(smile >= 0 && smile_pos == -1) return (*m_smilesFromSender)[smile].smiles[0]; return QString(""); } //\***************************************************************************** void ChatTextWgt::insertSmile(QTextCursor cursor, const QString & smile) { switch(QChatSettings::settings()->smilesPolicy()) { case QChatSettings::NoSmiles : return; case QChatSettings::DontUseSmilesFromSender : insertSmileFromLocalTheme(cursor, smile); break; case QChatSettings::UseSmilesFromSender : if(!insertSmileFromLocalTheme(cursor, smile)) insertSmileFromSender(cursor, smile); break; case QChatSettings::AlwaysUseSmilesFromSender : if(!insertSmileFromSender(cursor, smile)) insertSmileFromLocalTheme(cursor, smile); break; } } //\***************************************************************************** void ChatTextWgt::setSmilesFromSender(QList * smiles) { m_smilesFromSender = smiles; } void ChatTextWgt::processLinks(QTextDocument* doc) { QTextCursor cursor = doc->rootFrame()->firstCursorPosition(); for(;;) { cursor = doc->find(QRegExp("\\b(http|ftp|https)://[\\S]+"), cursor); if(!cursor.isNull()) cursor.insertHtml((QString("%2").arg(cursor.selectedText()).arg(cursor.selectedText()))); else break; } } void ChatTextWgt::setAnimations() { int min = m_text->cursorForPosition(QPoint(0, 0)).position(); int max = m_text->cursorForPosition(QPoint(m_text->size().width(), m_text->size().height())).position(); foreach(AnimatedSmile* sm, m_animatedSmiles) sm->pauseIfHidden(min, max); } bool ChatTextWgt::insertSmileFromSender(QTextCursor cursor, const QString & smile) { int i; if(m_smilesFromSender) { for(i = 0; i < m_smilesFromSender->size(); i++) if((*m_smilesFromSender)[i].smiles[0] == smile) { if(QFile((*m_smilesFromSender)[i].name).exists()) { cursor.insertText(" "); AnimatedSmile* asmile = new AnimatedSmile; asmile->init(cursor.position() + m_text->toPlainText().size() - 1, (*m_smilesFromSender)[i].name, m_text->document()); m_animatedSmiles.append(asmile); return true; } m_smilesFromSender->clear(); break; } } return false; } bool ChatTextWgt::insertSmileFromLocalTheme(QTextCursor cursor, const QString & smile) { QString smiles_dir = QChatSettings::settings()->smilesThemePath(); int i, j; for(i = 0; i < m_smiles.size(); i++) for(j = 0; j < m_smiles[i].smiles.size(); j++) if(m_smiles[i].smiles[j] == smile) { if(QFile(smiles_dir + m_smiles[i].name).exists()) cursor.insertImage(smiles_dir + m_smiles[i].name); else if(QFile(smiles_dir + m_smiles[i].name + ".png").exists()) cursor.insertImage(smiles_dir + m_smiles[i].name + ".png"); else if(QFile(smiles_dir + m_smiles[i].name + ".jpg").exists()) cursor.insertImage(smiles_dir + m_smiles[i].name + ".jpg"); else if(QFile(smiles_dir + m_smiles[i].name + ".gif").exists()) { cursor.insertText(" "); AnimatedSmile* asmile = new AnimatedSmile; asmile->init(cursor.position() + m_text->toPlainText().size() - 1, (smiles_dir + m_smiles[i].name + ".gif"), m_text->document()); m_animatedSmiles.append(asmile); } else if(QFile(smiles_dir + m_smiles[i].name + ".mng").exists()) { cursor.insertText(" "); AnimatedSmile* asmile = new AnimatedSmile; asmile->init(cursor.position() + m_text->toPlainText().size() - 1, (smiles_dir + m_smiles[i].name + ".mng"), m_text->document()); m_animatedSmiles.append(asmile); } else cursor.insertText(m_smiles[i].smiles[j]); return true; } return false; } void ChatTextWgt::playPauseAnimations(bool play) { if(play && !QChatSettings::settings()->boolOption("UseAnimatedSmiles")) return; if(play && m_keepAnimations < 0) foreach(AnimatedSmile* sm, m_animatedSmiles) sm->start(); else if(!play) foreach(AnimatedSmile* sm, m_animatedSmiles) sm->stop(); else { int i, j; for(i = m_animatedSmiles.size() - 1, j = 0; i >= 0 && j < m_keepAnimations; i--) { if(m_animatedSmiles[i]->animated()) { m_animatedSmiles[i]->start(); j++; } } for(; i >= 0; i--) if(m_animatedSmiles[i]->animated()) m_animatedSmiles[i]->setPaused(true); } if(play) setAnimations(); } qchat-0.3/src/edituserinfodlg.cpp0000644000076500017500000004030410772032342015656 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "edituserinfodlg.h" #include "pixlabel.h" #include "userinfo.h" #include "qchaticon.h" #include "globals.h" #include "qchatsettings.h" EditUserInfoDlg::EditUserInfoDlg(QWidget *parent) : QDialog (parent), m_profileName (""), m_photoFilename (""), m_pictureFilename(""), m_edited (false), m_readOnly (false) { QHBoxLayout* hbox = new QHBoxLayout(0); m_applyLab = new QLabel(this); m_okLab = new QLabel(this); m_cancelLab = new QLabel(this); m_photoLab = new QLabel(this); m_pictureLab = new QLabel(this); m_nickLab = new QLabel(this); m_lastNameLab = new QLabel(this); m_firstNameLab = new QLabel(this); m_secondNameLab = new QLabel(this); m_bornLab = new QLabel(this); m_addressLab = new QLabel(this); m_homePhoneLab = new QLabel(this); m_workPhoneLab = new QLabel(this); m_mobilePhoneLab = new QLabel(this); m_emailLab = new QLabel(this); m_icqLab = new QLabel(this); m_homepageLab = new QLabel(this); m_aboutLab = new QLabel(this); m_genderLab = new QLabel(this); m_grid = new QGridLayout(this); m_lastNameEdit = new QLineEdit(this); m_firstNameEdit = new QLineEdit(this); m_secondNameEdit = new QLineEdit(this); m_nickNameEdit = new QLineEdit(this); m_homePhoneEdit = new QLineEdit(this); m_workPhoneEdit = new QLineEdit(this); m_mobilePhoneEdit = new QLineEdit(this); m_e_mailEdit = new QLineEdit(this); m_homepageEdit = new QLineEdit(this); m_icqEdit = new QLineEdit(this); m_dateOfBornEdit = new QDateEdit(this); m_addressEdit = new QLineEdit(this); m_aboutInfoEdit = new QTextEdit(this); m_applyBtn = new QPushButton(this); m_okBtn = new QPushButton(this); m_cancelBtn = new QPushButton(this); m_setPhoto = new PixLabel ("", this); m_setPic = new PixLabel ("", this); m_statusLab = new QLabel (this); mw_statusDescription = new QLineEdit (this); m_genderCmbx = new QComboBox (this); // col 0 1 m_grid->addWidget(m_genderLab , 0, 0); m_grid->addWidget(m_nickLab , 1, 0); m_grid->addWidget(m_lastNameLab , 2, 0); m_grid->addWidget(m_firstNameLab , 3, 0); m_grid->addWidget(m_secondNameLab, 4, 0); m_grid->addWidget(m_bornLab , 5, 0); m_grid->addWidget(m_addressLab , 6, 0); m_genderCmbx->setMinimumWidth(100); m_grid->addWidget(m_genderCmbx , 0, 1); m_nickNameEdit->setMinimumWidth(100); m_grid->addWidget(m_nickNameEdit , 1, 1); m_lastNameEdit->setMinimumWidth(100); m_grid->addWidget(m_lastNameEdit , 2, 1); m_firstNameEdit->setMinimumWidth(100); m_grid->addWidget(m_firstNameEdit , 3, 1); m_secondNameEdit->setMinimumWidth(100); m_grid->addWidget(m_secondNameEdit , 4, 1); m_dateOfBornEdit->setMinimumWidth(100); m_grid->addWidget(m_dateOfBornEdit , 5, 1); m_addressEdit->setMinimumWidth(100); m_grid->addWidget(m_addressEdit , 6, 1, 1, 3); // col 2 3 m_grid->addWidget(m_homePhoneLab , 0, 2); m_grid->addWidget(m_workPhoneLab , 1, 2); m_grid->addWidget(m_mobilePhoneLab, 2, 2); m_grid->addWidget(m_emailLab , 3, 2); m_grid->addWidget(m_icqLab , 4, 2); m_grid->addWidget(m_homepageLab , 5, 2); m_grid->addWidget(m_homePhoneEdit , 0, 3); m_homePhoneEdit ->setMinimumWidth(100); m_grid->addWidget(m_workPhoneEdit , 1, 3); m_workPhoneEdit ->setMinimumWidth(100); m_grid->addWidget(m_mobilePhoneEdit, 2, 3); m_mobilePhoneEdit->setMinimumWidth(100); m_grid->addWidget(m_e_mailEdit , 3, 3); m_e_mailEdit ->setMinimumWidth(100); m_grid->addWidget(m_icqEdit , 4, 3); m_icqEdit ->setMinimumWidth(100); m_grid->addWidget(m_homepageEdit , 5, 3); m_homepageEdit ->setMinimumWidth(100); m_grid->addWidget(m_photoLab , 7, 0, 1, 2); m_grid->addWidget(m_pictureLab, 7, 2, 1, 2); m_setPhoto ->setMinimumWidth (260); m_setPhoto ->setMinimumHeight(195); m_setPhoto ->setMaximumWidth (260); m_setPhoto ->setMaximumHeight(195); m_setPic ->setMinimumWidth (260); m_setPic ->setMinimumHeight(195); m_setPic ->setMaximumWidth (260); m_setPic ->setMaximumHeight(195); m_grid->addWidget(m_setPhoto , 8, 0, 1, 2); m_grid->addWidget(m_setPic , 8, 2, 1, 2); m_grid->addWidget(m_aboutLab, 9, 0, 1, 2); m_grid->addWidget(m_aboutInfoEdit, 10, 0, 1, 4); m_aboutInfoEdit->setMinimumHeight(150); m_aboutInfoEdit->setMaximumHeight(1500); m_aboutInfoEdit->setMaximumWidth (1500); hbox->addWidget(m_statusLab ); hbox->addWidget(mw_statusDescription); m_grid->addLayout(hbox, 11, 0, 1, 4); mw_statusDescription->setReadOnly(true); m_grid->addWidget(m_okBtn , 0, 4); m_grid->addWidget(m_applyBtn , 1, 4); m_grid->addWidget(m_cancelBtn, 2, 4); m_grid->setColumnStretch(0, 1); m_grid->setColumnStretch(1, 2); m_grid->setColumnStretch(2, 1); m_grid->setColumnStretch(3, 2); m_grid->setRowStretch(8, 1); m_grid->setRowStretch(10, 2); m_aboutInfoEdit->setMaximumWidth(1000); m_aboutInfoEdit->setMaximumHeight(1000); m_aboutInfoEdit->resize(300, 200); setTabOrder(m_nickNameEdit , m_lastNameEdit); setTabOrder(m_lastNameEdit , m_firstNameEdit); setTabOrder(m_firstNameEdit , m_secondNameEdit); setTabOrder(m_dateOfBornEdit , m_addressEdit); setTabOrder(m_addressEdit , m_homePhoneEdit); setTabOrder(m_homePhoneEdit , m_workPhoneEdit); setTabOrder(m_workPhoneEdit , m_mobilePhoneEdit); setTabOrder(m_mobilePhoneEdit, m_e_mailEdit); setTabOrder(m_e_mailEdit , m_icqEdit); setTabOrder(m_icqEdit , m_homepageEdit); setTabOrder(m_homepageEdit , m_aboutInfoEdit); setTabOrder(m_aboutInfoEdit , m_okBtn); setTabOrder(m_okBtn , m_applyBtn); setTabOrder(m_applyBtn , m_cancelBtn); m_applyBtn ->setEnabled(false); m_okBtn ->setDefault(false); m_applyBtn ->setDefault(true); m_cancelBtn->setDefault(false); m_dateOfBornEdit->setDisplayFormat("dd / MMM / yyyy"); connect(m_okBtn , SIGNAL(clicked()) , this, SLOT (slot_sendInfo())); connect(m_okBtn , SIGNAL(clicked()) , this, SLOT (slot_accept ())); connect(m_okBtn , SIGNAL(clicked()) , this, SIGNAL(infoChanged ())); connect(m_applyBtn , SIGNAL(clicked()) , this, SLOT (slot_sendInfo())); connect(m_applyBtn , SIGNAL(clicked()) , this, SIGNAL(infoChanged ())); connect(m_cancelBtn , SIGNAL(clicked()) , this, SLOT (slot_cancel ())); connect(m_nickNameEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_lastNameEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_firstNameEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_secondNameEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_dateOfBornEdit , SIGNAL(dateChanged(const QDate )), this, SLOT (slot_edited())); connect(m_addressEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_homePhoneEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_workPhoneEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_mobilePhoneEdit, SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_e_mailEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_icqEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_homepageEdit , SIGNAL(textEdited(const QString )), this, SLOT (slot_edited())); connect(m_aboutInfoEdit , SIGNAL(textChanged( )), this, SLOT (slot_edited())); connect(m_setPic , SIGNAL(changed ( )), this, SLOT (slot_edited())); connect(m_setPhoto , SIGNAL(changed ( )), this, SLOT (slot_edited())); connect(m_genderCmbx , SIGNAL(currentIndexChanged(int)) , this, SLOT (slot_edited())); retranslate(); } //\***************************************************************************** EditUserInfoDlg::~EditUserInfoDlg() { qDebug("[~EditUserInfoDlg]"); } //\***************************************************************************** void EditUserInfoDlg::slot_sendInfo() { if(QChatSettings::profileName() == m_profileName) { UserInfo::myInfo()->setLastName (m_lastNameEdit ->text()); UserInfo::myInfo()->setFirstName (m_firstNameEdit ->text()); UserInfo::myInfo()->setSecondName (m_secondNameEdit ->text()); UserInfo::myInfo()->setDateOfBorn (m_dateOfBornEdit ->date()); UserInfo::myInfo()->setAddress (m_addressEdit ->text()); UserInfo::myInfo()->setHomePhone (m_homePhoneEdit ->text()); UserInfo::myInfo()->setWorkPhone (m_workPhoneEdit ->text()); UserInfo::myInfo()->setMobilePhone(m_mobilePhoneEdit->text()); UserInfo::myInfo()->setE_mail (m_e_mailEdit ->text()); UserInfo::myInfo()->setICQ (m_icqEdit ->text()); UserInfo::myInfo()->setHomepage (m_homepageEdit ->text()); UserInfo::myInfo()->setAboutInfo (m_aboutInfoEdit ->toPlainText()); UserInfo::myInfo()->setPhoto (m_setPhoto ->filename()); UserInfo::myInfo()->setPicture (m_setPic ->filename()); UserInfo::myInfo()->setGender (m_genderCmbx ->itemData(m_genderCmbx->currentIndex()).toInt()); if(QChatSettings::settings()->mode() == QChatSettings::Server) emit wantChangeNickname(m_nickNameEdit->text()); else { UserInfo::myInfo()->setNickname (m_nickNameEdit ->text()); emit nickNameChanged(m_nickNameEdit ->text()); } } m_applyBtn ->setEnabled(false); m_edited = false; } //\***************************************************************************** void EditUserInfoDlg::slot_accept() { m_setPhoto->freePixmap(); m_setPic ->freePixmap(); accept(); } //\***************************************************************************** void EditUserInfoDlg::slot_cancel() { slot_notEdited(); m_setPhoto->freePixmap(); m_setPic ->freePixmap(); reject(); } //\***************************************************************************** void EditUserInfoDlg::slot_loadInfo (const UserInfo* info) { QPixmap* pix; m_userUid = info->uid(); m_nickNameEdit ->setText (info->nickname ()); m_firstNameEdit ->setText (info->firstName ()); m_lastNameEdit ->setText (info->lastName ()); m_secondNameEdit ->setText (info->secondName ()); m_dateOfBornEdit ->setDate(QDate(1900, 1, 1)); m_dateOfBornEdit ->setDate (info->dateOfBorn ()); m_addressEdit ->setText (info->address ()); m_homePhoneEdit ->setText (info->homePhone ()); m_workPhoneEdit ->setText (info->workPhone ()); m_mobilePhoneEdit->setText (info->mobilePhone ()); m_e_mailEdit ->setText (info->e_mail ()); m_icqEdit ->setText (info->icq ()); m_homepageEdit ->setText (info->homepage ()); m_aboutInfoEdit ->setPlainText (info->aboutInfo ()); pix = info->newPhoto(); m_setPhoto ->slot_setPixmap (*pix); delete pix; pix = info->newPicture(); m_setPic ->slot_setPixmap (*pix); delete pix; m_setPic ->slot_setLastdir (info->pictureFilename()); m_setPhoto ->slot_setLastdir (info->photoFilename ()); m_setPic ->slot_setFilename(info->pictureFilename()); m_setPhoto ->slot_setFilename(info->photoFilename ()); m_statusLab ->setText(tr("Status (") + Globals::StatusStr[info->status()] + ") : "); if(m_readOnly) mw_statusDescription->setText(info->statusDescription()); else mw_statusDescription->setText(QChatSettings::settings()->statusDescription(info->status())); m_profileName = QChatSettings::profileName(); if(!m_readOnly) setWindowTitle(tr("Edit user details [Profile: ") + m_profileName + "]"); else setWindowTitle(tr("User details")); switch(info->gender()) { case 'm' : m_genderCmbx->setCurrentIndex(0); break; case 'f' : m_genderCmbx->setCurrentIndex(1); break; default : m_genderCmbx->setCurrentIndex(2); } slot_notEdited(); } //\***************************************************************************** void EditUserInfoDlg::setReadOnly(bool ro) { m_readOnly = ro; if(ro == true) { m_okBtn ->hide(); m_applyBtn->hide(); m_grid->removeWidget (m_okBtn ); m_grid->removeWidget (m_cancelBtn ); m_grid->addWidget (m_cancelBtn, 0, 4); m_cancelBtn->setText(tr("&Ok") ); setWindowTitle(tr("User Details")); } else { m_grid->removeWidget (m_okBtn ); m_grid->removeWidget (m_cancelBtn ); m_grid->addWidget (m_okBtn , 0, 4); m_grid->addWidget (m_cancelBtn, 2, 4); m_cancelBtn->setText(tr("&Cancel") ); m_okBtn ->show(); m_applyBtn->show(); setWindowTitle(tr("Edit User Details")); } m_lastNameEdit ->setReadOnly(ro); m_firstNameEdit ->setReadOnly(ro); m_secondNameEdit ->setReadOnly(ro); m_nickNameEdit ->setReadOnly(ro); m_homePhoneEdit ->setReadOnly(ro); m_workPhoneEdit ->setReadOnly(ro); m_mobilePhoneEdit ->setReadOnly(ro); m_e_mailEdit ->setReadOnly(ro); m_homepageEdit ->setReadOnly(ro); m_icqEdit ->setReadOnly(ro); m_dateOfBornEdit ->setReadOnly(ro); m_addressEdit ->setReadOnly(ro); m_setPhoto ->setReadOnly(ro); m_setPic ->setReadOnly(ro); m_aboutInfoEdit ->setReadOnly(ro); m_genderCmbx ->setEnabled(!ro); } //\***************************************************************************** void EditUserInfoDlg::retranslate() { m_applyBtn ->setText(tr("&Apply")); m_okBtn ->setText(tr("&Ok")); m_cancelBtn ->setText(tr("&Cancel")); m_setPhoto ->setTextLabel(tr("No Photo")); m_setPic ->setTextLabel(tr("No Picture")); m_nickLab ->setText(tr("Nickname:")); m_lastNameLab ->setText(tr("Last Name:")); m_firstNameLab ->setText(tr("First Name:")); m_secondNameLab ->setText(tr("Second Name:")); m_bornLab ->setText(tr("Date of Born:")); m_addressLab ->setText(tr("Address:")); m_homePhoneLab ->setText(tr("Home Phone:")); m_workPhoneLab ->setText(tr("Work Phone:" )); m_mobilePhoneLab->setText(tr("Mobile Phone:")); m_emailLab ->setText(tr("e-mail:")); m_icqLab ->setText(tr("ICQ:")); m_homepageLab ->setText(tr("Homepage:")); m_aboutLab ->setText(tr("About:")); m_pictureLab ->setText(tr("Picture:")); m_photoLab ->setText(tr("Photo:")); m_genderLab ->setText(tr("Gender:")); m_genderCmbx->clear(); // FIXME move to setIcons ":/ m_genderCmbx->addItem(QChatIcon::icon("user-male") , tr("Male") , 'm'); m_genderCmbx->addItem(QChatIcon::icon("user-female"), tr("Female") , 'f'); m_genderCmbx->addItem(QChatIcon::icon("unknown") , tr("Not Sure"), -1); setWindowTitle(tr("Edit user details")); } qchat-0.3/src/messagefiltereditor.cpp0000644000076500017500000001137211001133402016514 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "messagefiltereditor.h" #include #include "messagefilter.h" #include "filtrationrule.h" #include "filtrationruleeditor.h" MessageFilterEditor::MessageFilterEditor(QWidget *parent) : QWidget(parent), m_filter(NULL) { QGridLayout* grid = new QGridLayout(this); m_rulesListWgt = new QListWidget(this); m_addRuleBtn = new QPushButton(this); m_delRuleBtn = new QPushButton(this); m_enableDisableRuleBtn = new QPushButton(this); grid->addWidget(m_rulesListWgt, 0, 0, 1, 3); grid->addWidget(m_addRuleBtn , 1, 0); grid->addWidget(m_delRuleBtn , 1, 1); grid->addWidget(m_enableDisableRuleBtn, 1, 2); connect(m_addRuleBtn , SIGNAL(clicked()), this, SLOT(addRule())); connect(m_delRuleBtn , SIGNAL(clicked()), this, SLOT(removeRule())); connect(m_enableDisableRuleBtn, SIGNAL(clicked()), this, SLOT(enableDisableRule())); connect(m_rulesListWgt, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(editRule(QListWidgetItem*))); connect(m_rulesListWgt, SIGNAL(currentRowChanged(int)), this, SLOT(itemActivated(int))); m_enableDisableRuleBtn->setText(tr("Disable rule")); m_enableDisableRuleBtn->setEnabled(false); retranslate(); } MessageFilterEditor::~MessageFilterEditor() { } void MessageFilterEditor::retranslate() { m_addRuleBtn->setText(tr("Add rule...")); m_delRuleBtn->setText(tr("Remove rule")); } void MessageFilterEditor::refresh() { QListWidgetItem* item; retranslate(); if(!m_filter) return; m_rulesListWgt->clear(); foreach(FiltrationRule* fr, m_filter->blackRules()) { item = new QListWidgetItem(fr->name() + (fr->activated() ? "" : tr(" (disabled)")));// + tr(" (black rule)")); item->setData(Qt::UserRole, (quint64)(fr)); m_rulesListWgt->addItem(item); } foreach(FiltrationRule* fr, m_filter->whiteRules()) { item = new QListWidgetItem(fr->name() + tr(" (white rule)")); item->setData(Qt::UserRole, (quint64)(fr)); m_rulesListWgt->addItem(item); } } void MessageFilterEditor::addRule() { FiltrationRule* rule = new FiltrationRule(); rule->setName(tr("New Rule")); if(!editRule(rule)) delete rule; else m_filter->addBlackRule(rule); refresh(); } bool MessageFilterEditor::editRule(FiltrationRule* rule) { int ret; FiltrationRuleEditor* fre = new FiltrationRuleEditor(this); fre->init(rule); ret = fre->exec(); delete fre; refresh(); return ret; } void MessageFilterEditor::editRule(QListWidgetItem* item) { FiltrationRule* rule; rule = static_cast((void*)(item->data(Qt::UserRole).toInt())); if(rule) editRule(rule); } void MessageFilterEditor::removeRule() { QListWidgetItem* item = m_rulesListWgt->currentItem(); FiltrationRule* rule; if(item) { rule = static_cast((void*)(item->data(Qt::UserRole).toInt())); if(rule) m_filter->removeRule(rule); refresh(); } } void MessageFilterEditor::enableDisableRule() { QListWidgetItem* item = m_rulesListWgt->currentItem(); FiltrationRule* rule; if(item) { rule = static_cast((void*)(item->data(Qt::UserRole).toInt())); if(rule) { rule->setActivated(!rule->activated()); m_enableDisableRuleBtn->setText(rule->activated() ? tr("Disable rule") : tr("Enable rule")); } refresh(); } } void MessageFilterEditor::itemActivated(int row) { QListWidgetItem* item = m_rulesListWgt->currentItem(); FiltrationRule* rule; if(item) { rule = static_cast((void*)(item->data(Qt::UserRole).toInt())); if(rule) m_enableDisableRuleBtn->setText(rule->activated() ? tr("Disable rule") : tr("Enable rule")); } m_enableDisableRuleBtn->setEnabled(row >= 0); } qchat-0.3/src/singlemessagewgt.h0000644000076500017500000001001510773237616015514 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SINGLEMESSAGEWGT_H #define SINGLEMESSAGEWGT_H #include #include #include #include #include #include #include #include class InputTextWgt; class ChatTextWgt; class SingleMessage; /** @author Anistratov Oleg */ class SingleMessageWgt : /*public QDialog*/public QWidget { Q_OBJECT private: static QList m_newMessages; static QList m_openedMessages; static int m_currentNewMessage; static int m_currentOpenedMessage; private: bool m_isIncoming; bool m_quot; QHostAddress m_destAddr; uint m_destUid; QString m_title; QPushButton* m_sendBtn; QPushButton* m_closeBtn; QPushButton* m_replyBtn; QPushButton* m_replyQuotedBtn; ChatTextWgt* m_messageIn; InputTextWgt* m_inputText; QCheckBox* m_importantChbx; // QLabel* m_infoLab; SingleMessage* m_message; /// Stores position of last moved SingleMessageWgt for restoring this position for newly created SingleMessageWgt widgets static QPoint m_lastPosition; /// Stores size of last resized SingleMessageWgt for restoring this size for newly created SingleMessageWgt widgets static QSize m_lastSize; private: static void nextPrevMessage(const QList&, int&, int, bool); static void closeMessages(QList&, int&); public: SingleMessageWgt(const QString &, const QString &, uint, const QHostAddress &, bool isIncoming_ = false, QWidget *parent = 0); SingleMessageWgt(SingleMessage*, bool isIncoming_ = false, QWidget *parent = 0); ~SingleMessageWgt(); void init(const QString &, const QString &, uint, const QHostAddress &, bool isIncoming_); void retranslate(); static void addNewMessage (SingleMessageWgt* msg){if(!m_newMessages.contains(msg) ) m_newMessages.append(msg);} static void addOpenedMessage(SingleMessageWgt* msg){if(!m_openedMessages.contains(msg)) m_openedMessages.append(msg);} static void nextPrevNewMessage (int direction = 1, bool closeCurrent = false) {nextPrevMessage (m_newMessages , m_currentNewMessage, direction, closeCurrent);} static void nextPrevOpenedMessage (int direction = 1, bool closeCurrent = false) {nextPrevMessage (m_openedMessages, m_currentOpenedMessage, direction, closeCurrent);} static void closeAllNewMessages (){closeMessages(m_newMessages , m_currentNewMessage);} static void closeAllOpenedMessages(){closeMessages(m_openedMessages, m_currentOpenedMessage);} public slots: void slot_reply (); void slot_replyQuoted(); void slot_selfDestroy(); void slot_sendMessage(); signals: void singleMessage(const QString&, quint64, bool); protected: void closeEvent(QCloseEvent* ev); void resizeEvent(QResizeEvent* ev); void moveEvent(QMoveEvent* ev); }; #endif qchat-0.3/src/largedatagramout.h0000644000076500017500000000575110761310041015457 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef LARGEDATAGRAMOUT_H #define LARGEDATAGRAMOUT_H #include #include #include #include #include #include /** @author Anistratov Oleg */ class LargeDatagramOut : public QObject { Q_OBJECT private: quint32 m_id; QString m_filename; QFile m_file; bool m_confirmed; bool m_inited; bool m_rest; quint16 m_headerSize; quint32 m_dataSize; quint64 m_fileSize; quint32 m_sizePerFragment; quint32 m_totalFragments; quint32 m_fragmentsRemain; char* m_header; char* m_data; /// shows which fragments was sent char* m_fragments; QTimer* m_selfDestroyTimer; quint32 m_selfDestroyInterval; /// UserID in server mode and User's IP Address in serverless mode quint64 m_destUid; public: LargeDatagramOut(QObject *parent = 0); ~LargeDatagramOut(); // const QHostAddress & addr() const {return m_destAddr;} bool complete () const {return !m_fragmentsRemain;} quint32 id () const {return m_id;} void init(char* hdr, quint16 hdr_sz, char* data, quint32 data_sz, quint64, quint32 id); void init(char* hdr, quint16 hdr_sz, const QString & filename , quint64, quint32 id); void prepareInitHeader(); void fragmentsRequest (const char* , quint16); void sendNextFragment (QAbstractSocket* socket, quint16 port, char* buf); void acceptSending (){m_confirmed = true;} quint32 writeFragment (char* buf, quint32 num); void setDestUid( const uint& theValue ){m_destUid = theValue;} uint destUid() const {return m_destUid;} public slots: void selfDestroy(); void slot_confirmed(unsigned short ID); signals: void wantDie (LargeDatagramOut*); void sendingCancelled(quint16); }; #endif qchat-0.3/src/usersstatisticsmodel.cpp0000755000076500017500000002267110766353550017010 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "usersstatisticsmodel.h" #include "globals.h" #include "userslist.h" #include "userwgt.h" #include "userinfo.h" #include "userstatistics.h" #include "qchaticon.h" #include UsersStatisticsModel::UsersStatisticsModel(QObject* parent) : QAbstractTableModel(parent), m_users(NULL), m_sortingColumn(0), m_sortOrder(Qt::AscendingOrder), m_usersOrder(NULL), m_usersOrderSize(0), m_usersOrderMaxSize(1024) { m_usersOrder = (UserWgt**)malloc(m_usersOrderMaxSize * sizeof(UserWgt*)); m_columns.append(NickName); m_columns.append(Gender); m_columns.append(RealName); m_columns.append(Status); m_columns.append(StatusDescription); m_columns.append(IP); m_columns.append(CompName); m_columns.append(OS); m_columns.append(Uptime); m_columns.append(ChatTime); } UsersStatisticsModel::~UsersStatisticsModel() { } int UsersStatisticsModel::rowCount(const QModelIndex &) const { if(!m_users) return 0; return m_users->num(); } QVariant UsersStatisticsModel::data(const QModelIndex & index, int role) const { UserInfo* info; UserWgt* user; if(!index.isValid() || !m_users) return QVariant(); if(index.row() > (int)m_users->num() || index.column() >= m_columns.size()) return QVariant(); if(m_usersOrderSize && (index.row() < m_usersOrderSize)) user = m_usersOrder[index.row()]; else user = m_users->user(index.row()); info = user->info(); switch(m_columns[index.column()]) { case NickName : if(role == Qt::DecorationRole) return user->icon(); else if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return info->nickname(); else return QVariant(); case Gender : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) switch(info->gender()) { case 'm' : return QString(tr("Male")); case 'f' : return tr("Female"); default : return tr("Not Shure"); } else if(role == Qt::DecorationRole) switch(info->gender()) { case 'm' : return QIcon(QChatIcon::pixmap("user-male" , 24, 24)); case 'f' : return QIcon(QChatIcon::pixmap("user-female", 24, 24)); default : return QIcon(QChatIcon::pixmap("unknown" , 24, 24)); } else return QVariant(); case RealName : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return info->firstName(); break; case Status : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return Globals::StatusStr[info->status()]; else if(role == Qt::DecorationRole) { QString icon_name = "unknown"; switch(info->status()) { case Globals::READY4CHAT : icon_name = "status/user-ready-for-chat"; break; case Globals::FREE : icon_name = "status/user-online"; break; case Globals::BUSY : icon_name = "status/user-busy"; break; case Globals::DND : icon_name = "status/user-dnd"; break; case Globals::INACTIVE : icon_name = "status/user-away"; break; case Globals::AWAY : icon_name = "status/user-away-extended"; break; } return QIcon(QChatIcon::pixmap(icon_name, 24, 24)); } break; case StatusDescription : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return info->statusDescription(); break; case IP : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return QHostAddress(info->ip()).toString(); break; case CompName : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return info->compName(); break; case OS : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return user->stats()->os(); break; case Uptime : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) if(user->stats()->uptime() > 0) return user->stats()->uptimeString(); else return tr("Unknown"); break; case ChatTime : if(role == Qt::DisplayRole || role == Qt::ToolTipRole) return user->stats()->chatTimeString(); break; default : return QVariant(); } return QVariant(); } QVariant UsersStatisticsModel::headerData(int section, Qt::Orientation orientation, int role) const { if(role != Qt::DisplayRole || section >= m_columns.size()) return QVariant(); if(orientation == Qt::Horizontal) { switch(m_columns[section]) { case NickName : return tr("Nickname"); case Gender : return tr("Gender"); case RealName : return tr("Real Name"); case Status : return tr("Status"); case StatusDescription : return tr("Status Description"); case IP : return tr("IP"); case CompName : return tr("Comp Name"); case OS : return tr("OS"); case Uptime : return tr("Uptime"); case ChatTime : return tr("Time in Chat"); default : return QVariant(); } } else return QString("%1").arg(section + 1); } void UsersStatisticsModel::sort(int column, Qt::SortOrder order) const { UserWgt* tmp; for(uint i = 0; i < m_users->num(); i++) m_usersOrder[i] = m_users->user(i); if(column != 0) sort(0, order); m_usersOrderSize = m_users->num(); if(m_usersOrderSize > m_usersOrderMaxSize) { m_usersOrderMaxSize = m_usersOrderSize; m_usersOrder = (UserWgt**)realloc(m_usersOrder, m_usersOrderMaxSize * sizeof(UserWgt*)); assert(NULL != m_usersOrder); } uint num = m_usersOrderSize; for(uint i = 0; i < num; i++) for(uint j = i + 1; j < num; j++) { if(cmp(m_usersOrder[i], m_usersOrder[j], column, order) > 0) { tmp = m_usersOrder[i]; m_usersOrder[i] = m_usersOrder[j]; m_usersOrder[j] = tmp; } } m_sortingColumn = column; m_sortOrder = order; } int UsersStatisticsModel::cmp(UserWgt* u1, UserWgt* u2, int column, Qt::SortOrder order) const { Q_ASSERT(column >= 0 && column < m_columns.size()); switch(m_columns[column]) { case NickName : if(order) return u1->info()->nickname().compare(u2->info()->nickname()); else return u2->info()->nickname().compare(u1->info()->nickname()); case Gender : if(order) return (u1->info()->gender() > u2->info()->gender() ? 1 : -(u1->info()->gender() < u2->info()->gender())); else return (u2->info()->gender() > u1->info()->gender() ? 1 : -(u2->info()->gender() < u1->info()->gender())); case RealName : if(order) return u1->info()->firstName().compare(u2->info()->firstName()); else return u2->info()->firstName().compare(u1->info()->firstName()); case Status : if(order) return Globals::StatusStr[u1->info()->status()].compare(Globals::StatusStr[u2->info()->status()]); else return Globals::StatusStr[u2->info()->status()].compare(Globals::StatusStr[u1->info()->status()]); case StatusDescription : if(order) return u1->info()->statusDescription().compare(u2->info()->statusDescription()); else return u2->info()->statusDescription().compare(u1->info()->statusDescription()); case IP : if(order) return (u1->info()->ip() > u2->info()->ip() ? 1 : -(u1->info()->ip() < u2->info()->ip())); else return (u2->info()->ip() > u1->info()->ip() ? 1 : -(u2->info()->ip() < u1->info()->ip())); case CompName : if(order) return u1->info()->compName().compare(u2->info()->compName()); else return u2->info()->compName().compare(u1->info()->compName()); case OS : if(order) return u1->stats()->os().compare(u2->stats()->os()); else return u2->stats()->os().compare(u1->stats()->os()); case Uptime : if(order) return (u1->stats()->uptime() > u2->stats()->uptime() ? 1 : -(u1->stats()->uptime() < u2->stats()->uptime())); else return (u2->stats()->uptime() > u1->stats()->uptime() ? 1 : -(u2->stats()->uptime() < u1->stats()->uptime())); case ChatTime : if(order) return (u1->stats()->chatTime() > u2->stats()->chatTime() ? 1 : -(u1->stats()->chatTime() < u2->stats()->chatTime())); else return (u2->stats()->chatTime() > u1->stats()->chatTime() ? 1 : -(u2->stats()->chatTime() < u1->stats()->chatTime())); default : return 0; } } qchat-0.3/src/pluginsinterfaces.h0000644000076500017500000000776511002550244015670 0ustar owerower/*************************************************************************** * Copyright (C) 2007-2008 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef INTERFACES_H #define INTERFACES_H #include #include #include #include #include #include /** * @class QChatBasicPlugin * @author Anistratov Oleg * @brief Basic abstract interface for qchat plugins * * \note If plugin needs to send data it must use for this purpose signal with following signature:\n * \code * void sendData(const QString & plugin_id, * const QMap < QString, QByteArray > & parametrs, * quint64 destination_user_id, * AbstractChatCore::DataType data_type, * const QString & channel_id, * uint channel_type, * const QString & message); * \endcode * * \b plugin_id is used to determine to which plugin data is arrived \n * As \b data_type in most cases you need to use a AbstractChatCore::PLUGIN_DATA * * */ class QChatBasicPlugin { private: QString m_path; public: virtual ~QChatBasicPlugin(){}; virtual void load() = 0; virtual void unload() = 0; /** * @brief Path to plugin * \return full path to plugin */ const QString& path() const {return m_path;} void setPath(const QString& p){m_path = p;} /** * @brief Plugin's icon * \return pointer to plugin's icon or NULL pointer if there is no icon */ virtual QIcon* icon() const = 0; /** * @brief Plugin's settings page * \return pointer to widget with plugin's settings or NULL pointer if plugin have no settings */ virtual QWidget* settingsPage() const = 0; /** * @brief Name of a plugin * \return name of a plugin */ virtual QString name() const = 0; /** * @brief Information about plugin * \return 'about information' which will be placed in 'about plugin' section */ virtual QString about() const = 0; /** * @brief Must process data which arrived from network * @param parametrs - QMap with key - QString parametrName and value - QByteArray parametrValue */ virtual void processData(QMap parametrs) = 0; }; /** @class QChatWidgetPlugin @author Anistratov Oleg @brief Abstract interface for qchat plugins with GUI */ class QChatWidgetPlugin : public QChatBasicPlugin { public: virtual ~QChatWidgetPlugin(){}; /** * @brief Plugin's main widget * \return Plugin's main widget */ virtual QWidget* widget() = 0; // virtual void updateMenus(QMenu*) const = 0; /** * @brief Setting up toolbar object with plugin's actions * * This function is calls when plugin's widget is activating, it must setup toolbar object with plugin's actions */ virtual void setupToolBar(QToolBar*) const = 0; }; Q_DECLARE_INTERFACE(QChatBasicPlugin, "QChat.QChatBasicPlugin/0.1"); Q_DECLARE_INTERFACE(QChatWidgetPlugin, "QChat.QChatWidgetPlugin/0.1"); #endif qchat-0.3/src/treeitem.cpp0000644000076500017500000001343111002604005014272 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "treeitem.h" #include int TreeItem::m_sortingOrder = 0; int TreeItem::m_sortingColumn = 0; TreeItem::TreeItem(const QList & data, TreeItem * parent, QString name): m_parent(parent), m_name(name) { if(parent) parent->appendChild(this); m_data.insert(Qt::DisplayRole, data); for(int i = 0; i < m_data.size(); i++) m_columns.append(i); } TreeItem::~TreeItem() { foreach(TreeItem* item, m_children) delete item; } const TreeItem* const TreeItem::child(int row) const { return (m_children.count() > row && row >= 0 ? m_children[row] : NULL); } void TreeItem::appendChild(TreeItem* child) { m_children.append(child); child->setParent(this); } QVariant TreeItem::data(int column, int role, bool with_hidden) const { int visible_cols = m_data[role].count() - m_hiddenColumns.size() * !with_hidden; int col = -1; int i; for(i = 0; i < m_data[role].count(); i++) { if(!m_hiddenColumns.contains(i)) col++; if(col == column) break; } bool ok = visible_cols > column && column >= 0;// && i < m_data[role].count(); return (ok ? m_data[role][with_hidden ? column : i/*m_columns[column]*/] : QVariant()); } int TreeItem::row() const { if(m_parent) return m_parent->children()->indexOf(const_cast(this)); return 0; } int TreeItem::childCount() const { return m_children.count(); } int TreeItem::columnCount() const { return m_data[Qt::DisplayRole].count() - m_hiddenColumns.size(); } void TreeItem::setData(const QList< QVariant > & data, int role) { if(m_data.contains(role)) m_data[role] = data; else m_data.insert(role, data); } QList TreeItem::takeChildren() { QList ch(m_children); foreach(TreeItem* item, m_children) item->setParent(NULL); m_children.clear(); return ch; } void TreeItem::deleteChild(TreeItem* item) { if(m_children.contains(item)) { m_children.removeAll(item); delete item; } } void TreeItem::setData(int column, const QVariant & data, int role) { if(m_data.contains(role) && m_data[role].size() >= column) m_data[role][column] = data; else if(columnCount() >= column) { QList data_; for(int i = 0; i < columnCount(); i++) if(column == i) data_.append(data); else data_.append(""); m_data.insert(role, data_); } } // void TreeItem::insertColumn(int after, const QVariant& col_data) // { // if(after > columnCount()) // return; // // QList new_data; // int i = 0; // // QMapIterator< int, QList > all_data(m_data); // // while(all_data.hasNext()) // { // all_data.next(); // // i = -1; // new_data.clear(); // foreach(QVariant data, all_data.value()) // { // if(i == after) // { // if(all_data.key() == Qt::DisplayRole) // new_data.append(col_data); // else // new_data.append(""); // // new_data.append(data); // } // else // new_data.append(data); // // i++; // } // // setData(new_data, all_data.key()); // } // } void TreeItem::hideColumn(int column) { // int sz = m_columns.size(); if(!m_hiddenColumns.contains(column)) m_hiddenColumns.append(column); foreach(TreeItem* item, m_children) item->hideColumn(column); // for(int i = 0; i < sz; i++) // if(m_columns[i] == column) // { // m_columns.remove(i); // break; // } } void TreeItem::showColumn(int column) { m_hiddenColumns.removeAll(column); foreach(TreeItem* item, m_children) item->showColumn(column); // int sz = m_columns.size(); // int prev = -1; // int next = m_columns[0]; // // for(int i = 0; i < sz; i++) // { // next = m_columns[i]; // // if(prev < column && next > column) // { // m_columns.insert(i, column); // break; // } // // prev = next; // } } void TreeItem::sortChildren(int column, Qt::SortOrder order) { m_sortingColumn = column; foreach(TreeItem* item, m_children) item->setSortingColumn(column); qSort(m_children.begin(), m_children.end(), TreeItem::LessThan); foreach(TreeItem* item, m_children) item->sortChildren(column, order); } bool TreeItem::LessThan(TreeItem * i1, TreeItem * i2) { return i1->data(sortingColumn(), Qt::DisplayRole, true).toString() < i2->data(sortingColumn(), Qt::DisplayRole, true).toString(); } int TreeItem::realColumn(int column) const { int col = -1; int i; for(i = 0; i < m_data[Qt::DisplayRole].count(); i++) { if(!m_hiddenColumns.contains(i)) col++; if(col == column) break; } return i; } int TreeItem::visibleCols(bool with_hidden, int role) const { return m_data[role].count() - m_hiddenColumns.size() * !with_hidden; } qchat-0.3/src/messagetreeitem.h0000644000076500017500000000333310772507513015327 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef MESSAGETREEITEM_H #define MESSAGETREEITEM_H #include "treeitem.h" class SingleMessage; /** @author Anistratov Oleg */ class MessageTreeItem : public TreeItem { private: SingleMessage* m_message; public: MessageTreeItem(const QList &data, TreeItem *parent = 0, QString = ""); ~MessageTreeItem(); QVariant data(int column, int role = Qt::DisplayRole, bool = 0) const; void setMessage(SingleMessage* theValue){m_message = theValue;} SingleMessage* message() const {return m_message;} void sortChildren(int column, Qt::SortOrder order); static bool LessThan(TreeItem* i1, TreeItem* i2); }; #endif qchat-0.3/src/filtrationrule.h0000644000076500017500000000460211001121003015153 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef FILTRATIONRULE_H #define FILTRATIONRULE_H #include #include #include #include class Message; /** @author Anistratov Oleg */ class FiltrationRule { private: QString m_name; bool m_isRegExp; /// is rule activated now bool m_activated; QList m_packetType; QList m_srcIp; QList m_srcUid; QString m_messageFilter; QList m_userName; QList m_compName; public: FiltrationRule(); ~FiltrationRule(); bool checkMessage(Message*); void setActivated(bool theValue){m_activated = theValue;} bool activated() const {return m_activated;} void setIsRegExp(bool theValue){m_isRegExp = theValue;} bool isRegExp() const {return m_isRegExp;} void setUserNames(const QString&); void setCompNames(const QString&); void setIPs (const QString&); void setMessageFilter(const QString& value){m_messageFilter = value;} QString userNames () const; QString compNames () const; QString IPs () const; const QString & messageFilter() const {return m_messageFilter;} void setName( const QString& theValue ){m_name = theValue;} QString name() const {return m_name;} void save(QSettings*) const; void load(QSettings*); }; #endif qchat-0.3/src/messagetreeitem.cpp0000644000076500017500000000673410773235475015700 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "messagetreeitem.h" #include "singlemsgshistorymodel.h" #include "singlemessage.h" #include "qchaticon.h" MessageTreeItem::MessageTreeItem(const QList & data, TreeItem* parent, QString name): TreeItem(data, parent, name), m_message(NULL) { } MessageTreeItem::~MessageTreeItem() { qDebug("[~MessageTreeItem]"); } void MessageTreeItem::sortChildren(int column, Qt::SortOrder order) { setSortingColumn(column); setSortingOrder (order); foreach(TreeItem* item, *children()) item->setSortingColumn(column); qStableSort(children()->begin(), children()->end(), MessageTreeItem::LessThan); foreach(TreeItem* item, *children()) item->sortChildren(column, order); } bool MessageTreeItem::LessThan(TreeItem* item1, TreeItem* item2) { bool res; MessageTreeItem* i1 = static_cast(item1); MessageTreeItem* i2 = static_cast(item2); if(i1 && i2 && i1->message() && i2->message()) { switch(sortingColumn()) { case SingleMsgsHistoryModel::DateCol : res = i1->message()->receiveTime() < i2->message()->receiveTime(); break; case SingleMsgsHistoryModel::IpCol : res = i1->message()->srcIp() < i2->message()->srcIp(); break; case SingleMsgsHistoryModel::NicknameCol : res = i1->message()->userName() < i2->message()->userName(); break; case SingleMsgsHistoryModel::MessageCol : res = i1->message()->msg() < i2->message()->msg(); break; default : res = (i1->data(sortingColumn(), Qt::DisplayRole).toString() < i2->data(sortingColumn(), Qt::DisplayRole).toString()); } } else res = (i1->data(sortingColumn(), Qt::DisplayRole).toString() < i2->data(sortingColumn(), Qt::DisplayRole).toString()); return sortingOrder() == Qt::AscendingOrder ? res : !res; } QVariant MessageTreeItem::data(int column, int role, bool with_hidden) const { int visible_cols = visibleCols(with_hidden, Qt::DisplayRole); int real_column = realColumn(column); bool ok = visible_cols > column && column >= 0; if(real_column == 0 && role == Qt::DecorationRole) { if(ok && m_message && m_message->messageWgt()) return QIcon(QChatIcon::icon( (m_message->isNew() ? "message-unread" : "message-opened")) ); else return QVariant(); } else return TreeItem::data(column, role, with_hidden); return QVariant(); } qchat-0.3/src/treemodel.cpp0000644000076500017500000000705110770470774014466 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "treemodel.h" #include "treeitem.h" TreeModel::TreeModel(QObject *parent) : QAbstractItemModel(parent) { } TreeModel::~TreeModel() { delete m_rootItem; } //\************************** QVariant TreeModel::data(const QModelIndex & index, int role) const { if(!index.isValid()) return QVariant(); TreeItem *item = static_cast(index.internalPointer()); return item->data(index.column(), role); } //\************************** QVariant TreeModel::headerData(int section, Qt::Orientation orientation, int role) const { if(orientation == Qt::Horizontal && role == Qt::DisplayRole) return m_rootItem->data(section); return QVariant(); } //\************************** QModelIndex TreeModel::index(int row, int column, const QModelIndex & parent) const { if(!hasIndex(row, column, parent)) return QModelIndex(); TreeItem *parentItem; if(!parent.isValid()) parentItem = m_rootItem; else parentItem = static_cast(parent.internalPointer()); TreeItem* childItem = const_cast(parentItem->child(row)); if(childItem) return createIndex(row, column, childItem); else return QModelIndex(); } //\************************** QModelIndex TreeModel::parent(const QModelIndex & index) const { if(!index.isValid()) return QModelIndex(); TreeItem *childItem = static_cast(index.internalPointer()); TreeItem *parentItem = childItem->parent(); if(parentItem == m_rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } //\************************** int TreeModel::rowCount(const QModelIndex & parent) const { TreeItem *parentItem; if(parent.column() > 0) return 0; if(!parent.isValid()) parentItem = m_rootItem; else parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } //\************************** int TreeModel::columnCount(const QModelIndex & parent) const { if(parent.isValid()) return static_cast(parent.internalPointer())->columnCount(); else return m_rootItem->columnCount(); } //\************************** Qt::ItemFlags TreeModel::flags(const QModelIndex & index) const { if(!index.isValid()) return 0; return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } void TreeModel::appendToRoot(TreeItem* item) { if(!item) return; item->setParent(m_rootItem); m_rootItem->appendChild(item); } void TreeModel::clear() { delete m_rootItem; m_rootItem = createRootItem(); reset(); } qchat-0.3/src/textbrowser.cpp0000644000076500017500000000227010776633176015077 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "textbrowser.h" TextBrowser::TextBrowser(QWidget *parent) : QTextBrowser(parent) { } TextBrowser::~TextBrowser() { } qchat-0.3/src/chatcore.h0000755000076500017500000002242511004407736013735 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef CHATCORE_H #define CHATCORE_H #include #include #include #include #include #include #include #include #include #include #include #include #include "globals.h" #include "abstractchatcore.h" class ChatWgt; class NLAmarok; class ReceiverThread; class SenderThread; class LargeDatagram; class UserInfo; class QChatSettings; class QC_DatagramHeader; class UserProfile; class Smile; class SingleMsgsHistoryModel; class SingleMessage; class PluginManager; struct CmdArgs { int port_in; int port_out; QString chat_log_dir; QString settings_dir; bool show_help; bool show_version; bool show_author; QString unknown_option; CmdArgs() : port_in(-1), port_out(-1), show_help(false), show_version(false), show_author(false), unknown_option(""){} }; class TcpReceiverThread; class MessageFilter; /** * @author Anistratov Oleg * @brief Class contains itself a core of non gui functionality of QChat * * Class manages sending and receiving data over network, preprocessing it(or fully processing) and sending to next level to ChatWgt or appropriate ChannelWgt * */ class ChatCore : public QThread, public AbstractChatCore { Q_OBJECT public: enum Mode{Serverless, Server, Combined}; private: /// Shows whether user is logined on server or not bool m_loggedIn; /// ReceiverThread object using for tcp mode(server mode) TcpReceiverThread* m_tcpReceiver; /// ReceiverThread object using for usd mode(serverless mode) ReceiverThread* m_udpReceiver; QByteArray m_smilesParam; /// Stores main window geometry QByteArray m_geometry; /// Stores main window state QByteArray m_state; QString m_lang; int m_needCheckIp; QMap m_channelsStates; QString m_nowListening; bool m_nlIsNew; #if defined(Q_OS_LINUX) NLAmarok* m_nlAmarok; #endif ChatWgt* m_chatWgt; ReceiverThread* m_receiver; SenderThread* m_sender; UserInfo* m_myInfo; QChatSettings* m_settings; QMap m_profiles; UserProfile* m_currentProfile; QSettings* m_qsettings; QTimer* m_statusTimer; QUdpSocket m_socketOut; // NowListening QString m_nlTitle; QString m_nlArtist; QString m_nlAlbum; static QTimer* m_chatTimer; quint32 m_chatTime; Mode m_mode; // user id on server int m_uid; PluginManager* m_pluginManager; public: SingleMsgsHistoryModel* m_smhModel; private: QString homePath(){return QDir::homePath ();} MessageFilter* filter(){return QChatSettings::settings()->messageFilter();} public: ChatCore(QObject *parent = 0); ~ChatCore(); const QChatSettings* const constSettings(){return QChatSettings::settings();} QChatSettings* settings(){return QChatSettings::settings();} const QByteArray & geometry() const {return m_geometry;} const QByteArray & state() const {return m_state;} int needCheckIp() const {return m_needCheckIp;} QByteArray channelState(const QString & ch) const {return m_channelsStates.value(ch);} void setChatWgt(ChatWgt* chw){m_chatWgt = chw;} void run(){exec();} void stopThreads(); bool initSettings(QString); void slot_loadSettings(); UserProfile* readProfile(const QString &); void writeProfile(const UserProfile*); QStringList profiles() const; const QString & currentProfile() const; /** * * @param uid unique user id. in serverless mode users IP address serves as uid. * */ void prepareDatagramWrapper(AbstractChatCore::DataType dtgrm_type, quint64 uid, const QString & msg = "", AbstractChatCore::ChannelType chnnl_type = Common, quint64 dtgrm_id = 0, quint64 dtgrm_num = 0); /// otsylaet dannye nahodyaschiesya v $m_outputBuffer po addressu $addr void sendData(quint64); void startThreads(); void processData(); quint32 initSendingFile (quint64, const QString &, QObject*); void initReceivingFile(QObject*); /** * adding all smiles in $message to $m_parametrs in reason that smiles on receiver side * are looking such as smiles on sender side * @param message - message to process */ void processSmiles(QString); void nextSmile(const QString &); ReceiverThread* receiver() {return m_receiver;} TcpReceiverThread* tcpReceiver(){return m_tcpReceiver;} ReceiverThread* udpReceiver(){return m_udpReceiver;} void initMode(Mode, bool = false); void saveSettings(bool); SingleMsgsHistoryModel* smhModel(){return m_smhModel;} void initPlugins(); PluginManager* pluginManager(){return m_pluginManager;} UserInfo* getUserInfo(quint64 uid); bool loggedIn(); public slots: void slot_prepareAndSend (const QString &, quint64, AbstractChatCore::DataType, const QString & = "", AbstractChatCore::ChannelType = Common, QByteArray* = NULL); void slot_sendMessage (const QString &, quint64, AbstractChatCore::ChannelType, QTextDocument*); void slot_statusAnswer (const QString &, quint64, AbstractChatCore::ChannelType ch_type = Common, bool changed = 0, bool = 0); void slot_infoAnswer (const QString &, quint64, AbstractChatCore::ChannelType ch_type = Common, uchar = 0); void slot_avatarAnswer (const QString &, quint64, AbstractChatCore::ChannelType ch_type = Common); void slot_privateChatRequest(const QString &, quint64); void slot_infStatusChanged (const QString & ); void slot_singleMessage (const QString & msg, quint64, bool/*, quint32 ch_type = 0*/); void slot_msgsHistoryAnswer (const QString &, quint64, const QByteArray &, AbstractChatCore::ChannelType); void slot_msgsNumAnswer (const QString &, quint64, quint32, AbstractChatCore::ChannelType); void slot_requestFragments (char*, quint32, quint32, quint64); void slot_processData (char*, quint16); void slot_processLargeData(LargeDatagram*); void slot_bindInputPort(int); void slot_acceptReceiving(quint16, quint64); void slot_saveSettings(); void slot_setNl(const QString &, const QString &, const QString &); /** * * @param reason reason of rejecting:\n * 0 - rejected(receiving didn't ever began)\n * 1 - cancelled */ void slot_rejectReceiving(quint16, quint64, int reason); void slot_confirmReceivingFile(quint8, quint16, quint64); void slot_openSocketError(quint16); /** * setting the profile with name $name(if it exists) to be current profile * @param name name of profile to load */ void slot_loadProfile (const QString & name); void slot_renameProfile(const QString &, const QString &); void slot_deleteProfile(const QString &); void slot_updateChatTime(){m_chatTime += 1;} void setChannelState(const QString & ch, const QByteArray & ba) {m_channelsStates.insert(ch, ba);} void sendPluginData (const QString &, const QMap &, quint64, AbstractChatCore::DataType, const QString &, uint, const QString &); void createReceiverConnections(); void slot_setMode(); void slot_login(const QHostAddress&, const QString&); void disconnectFromServer(); void changeLogin(const QString&); void changeProtocolVersion(uint); void slot_disconnectedFromServer(); public: void setLang(const QString & value){m_lang = value;} const QString & lang() const {return m_lang;} signals: void closed (); void singleMessageIn (SingleMessage*, bool); void privateChatRequest (const QString &, quint64); void profileLoaded (const QString &); void chatDataReceived (QC_DatagramHeader*); void wantSendLargeData (char*, quint16, char* , quint32, quint64, quint32); void wantSendFile (char*, quint16, const QString &, quint64, quint32); void wantChangeInputPort(quint16); void wantLogin(const QString&, const QHostAddress&, uint, const QString&); void loginFinished(int, const QString&); void disconnectedFromServer(); }; #endif qchat-0.3/src/qchat.cpp0000755000076500017500000002057411004461046013575 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchat.h" #include #include #include "chatcore.h" #include "chatwgt.h" #include "qchateventfilter.h" #include "qchaticon.h" #include "qchatsettings.h" QChat::QChat(QObject *parent) : QObject(parent), m_chat(NULL), m_core(NULL) { } QChat::~QChat() { qDebug("[QChat::~QChat]\n"); m_core->saveSettings(true); delete m_chat; delete m_core; } void QChat::start(int argc, char *argv[], QApplication* app) { // QSplashScreen *splash = new QSplashScreen(QPixmap(":/images/splash.png")); // splash->show(); QTime t, tt; QChatEventFilter* eventFilter; QChatSettings::initGeneralOptions(); t.start(); tt.start(); m_app = app; // Processing command line arguments // ********************************* CmdArgs* args = processCmdArgs(argc, argv); if(!args->unknown_option.isEmpty()) { unknownOptionMessage(args->unknown_option); delete args; delete m_core; exit(1); } if(args->show_version) { printf("%s\n", Globals::VersionStr.toLocal8Bit().data()); delete args; delete m_core; exit(0); } if(args->show_help) { helpMessage(); delete args; delete m_core; exit(0); } if(args->show_author) { authorMessage(); delete args; delete m_core; exit(0); } app->setQuitOnLastWindowClosed(false); m_core = new ChatCore; qDebug("Time elapsed: %d ms", t.restart()); qDebug("QChat: [Loading settings...]\n"); // splash->showMessage(tr("Loading settings..."), Qt::AlignBottom | Qt::AlignCenter, Qt::red); QChatSettings::setLoggingDir(args->chat_log_dir); m_core->initSettings(args->settings_dir); m_core->slot_loadSettings(); if(args->port_in > 0) QChatSettings::settings()->setOption("InputPort", (args->port_in)); if(args->port_out > 0) QChatSettings::settings()->setOption("OutputPort", args->port_out); delete args; // ********************************* QChatIcon::initIcons(); qDebug("Time elapsed: %d ms", t.restart()); qDebug("QChat: [Creating Main Window...]\n"); // splash->showMessage(tr("Creating Main Window..."), Qt::AlignBottom | Qt::AlignCenter, Qt::red); m_chat = new ChatWgt(m_core); m_chat->setCursor(QCursor(Qt::WaitCursor)); m_core->setChatWgt(m_chat); m_chat->fillProfilesCmbx(m_core->profiles(), m_core->currentProfile()); qDebug("Time elapsed: %d ms", t.restart()); qDebug("QChat: [Starting threads...]\n"); // splash->showMessage(QObject::tr("Starting threads..."), Qt::AlignBottom | Qt::AlignCenter, Qt::red); m_core->startThreads(); connect(m_chat, SIGNAL( singleMessageOut (QString, quint64, bool)), m_core, SLOT (slot_singleMessage (QString, quint64, bool))); connect(m_core, SIGNAL( singleMessageIn (SingleMessage*, bool)), m_chat, SLOT (slot_singleMessageIn (SingleMessage*, bool))); connect(m_core, SIGNAL( privateChatRequest(QString, quint64)), m_chat, SLOT (slot_privateChat (QString, quint64))); connect(m_core, SIGNAL(chatDataReceived(QC_DatagramHeader*)), m_chat, SLOT (slot_processData(QC_DatagramHeader*))); connect((QObject*)m_core->tcpReceiver(), SIGNAL(wantReceiveFile (QString, quint16, quint64)), m_chat , SLOT (slot_receiveFile(QString, quint16, quint64))); connect((QObject*)m_core->udpReceiver(), SIGNAL(wantReceiveFile (QString, quint16, quint64)), m_chat , SLOT (slot_receiveFile(QString, quint16, quint64))); connect(app , SIGNAL(focusChanged(QWidget*, QWidget*)), m_chat, SLOT (slot_focusChanged(QWidget*, QWidget*))); connect(m_chat, SIGNAL(closed()), app , SLOT (quit())); connect(m_chat, SIGNAL(wantChangeStyleSheet(QString)), this, SLOT(setStyleSheet(QString))); m_core->initPlugins(); qDebug("Time elapsed: %d ms", t.restart()); qDebug("QChat: [Creating channel 'Main'...]\n"); // splash->showMessage(QObject::tr("Creating channel 'Main'..."), Qt::AlignBottom | Qt::AlignCenter, Qt::red); m_chat->slot_addChannell("Main"); qDebug("Time elapsed: %d ms", t.restart()); qDebug("QChat: [Restoring Window Geometry...]\n"); // splash->showMessage(tr("Restoring Window Geometry..."), Qt::AlignBottom | Qt::AlignCenter, Qt::red); m_chat->restoreAndShow(); qDebug("Time elapsed: %d ms", t.restart()); qDebug("QChat: [Finishin initialization]\n"); // splash->showMessage(tr("Ready to Chat :)"), Qt::AlignBottom | Qt::AlignCenter, Qt::red); // splash->finish(m_chat); m_chat->setCursor(QCursor(Qt::ArrowCursor)); eventFilter = new QChatEventFilter(this); app->installEventFilter(eventFilter); eventFilter->setChatWgt(m_chat); AbstractChatCore::setProtocolVersion(QChatSettings::settings()->intOption("ProtocolVersion")); connect(eventFilter, SIGNAL(wantHide2Tray()), this, SLOT(hide2tray())); qDebug("Time elapsed: %d ms", t.restart()); qDebug("QChat: [Ready to Chat :)]\n"); qDebug("Starting Time: %d ms", tt.elapsed()); } void QChat::reloadStyleSheet() { m_app->setStyleSheet(m_styleSheet); } void QChat::setStyleSheet(const QString & filename) { QFile file(filename); QByteArray ba; file.open(QFile::ReadOnly | QFile::Unbuffered); // etogo bolee chem dostatochno, i v sluchae esli budet vybran ochen' bol'shoi fail // ne budet popytki zagruzit' ego tselikom v pamyat' if(file.size() < 1024 * 1024) ba = file.readAll(); file.close(); m_styleSheet = QString().fromUtf8(ba); m_app->setStyleSheet(m_styleSheet); } void QChat::hide2tray() { QWidget* wgt = QApplication::activeWindow(); if(wgt) wgt->close(); } void QChat::unknownOptionMessage(const QString& msg) { printf("%s\n", tr("Unknown option: %1\nUse -h for list of available options.").arg(msg).toLocal8Bit().data()); } void QChat::helpMessage() { QString msg; msg = tr ( " List of available options:\n" " -h, --help Prints this message\n" " -v, --version Prints version of QChat\n" " --author Information about author\n" " --settingsdir Directory with settings\n" " --logdir Directory for saving chat logs\n" ); printf("%s\n", msg.toLocal8Bit().data()); } void QChat::welcomeMessage() { printf("%s\n", tr("QChat %1 - Network chat").arg(Globals::VersionStr).toLocal8Bit().data()); } void QChat::authorMessage() { welcomeMessage(); printf("%s\n", tr("Author: Ower ").toLocal8Bit().data()); } CmdArgs* QChat::processCmdArgs(int argc, char* argv[]) { int i; CmdArgs* args = new CmdArgs; for(i = 1; i < argc; i++) { if(!strcmp("--logdir", argv[i])){ if(++i < argc) args->chat_log_dir = QString().fromLocal8Bit(argv[i]);} else if(!strcmp("--settingsdir", argv[i])){ if(++i < argc) args->settings_dir = QString().fromLocal8Bit(argv[i]);} else if(!strcmp("--iport", argv[i])){ if(++i < argc) args->port_in = atoi(argv[i]);} else if(!strcmp("--oport", argv[i])){ if(++i < argc) args->port_out = atoi(argv[i]);} else if(!strcmp("-h", argv[i]) || !strcmp("--help", argv[i])) args->show_help = true; else if(!strcmp("-v", argv[i]) || !strcmp("--version", argv[i])) args->show_version = true; else if(!strcmp("--author", argv[i])) args->show_author = true; else { args->unknown_option = argv[i]; break; } } return args; } qchat-0.3/src/messagewithcheckbox.cpp0000644000076500017500000000370310703762766016536 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "messagewithcheckbox.h" MessageWithCheckBox::MessageWithCheckBox(const QString & title, const QString & msg, const QString & qstn, int* res, QWidget* parent) : QDialog(parent), m_result(res) { QGridLayout* grid = new QGridLayout(this); m_msg = new QLabel(msg, this); m_icon = new QLabel(this); m_question = new QCheckBox(qstn, this); m_okBtn = new QPushButton(tr("Ok"), this); grid->addWidget(m_icon , 0, 0, Qt::AlignCenter); grid->addWidget(m_msg , 0, 1); grid->addWidget(m_question, 1, 0, 1, 2); grid->addWidget(m_okBtn , 2, 0, 1, 2, Qt::AlignCenter); grid->setRowStretch(0, 1); grid->setRowStretch(1, 2); grid->setHorizontalSpacing(20); grid->setVerticalSpacing(20); grid->setMargin(20); m_icon->setAlignment(Qt::AlignCenter); connect(m_okBtn, SIGNAL(clicked()), this, SLOT(finish())); setModal(true); setWindowTitle(title); } qchat-0.3/src/shortcutseditor.cpp0000644000076500017500000001240610772032343015737 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "shortcutseditor.h" #include #include #include "qchatsettings.h" #include "shortcutgrabber.h" ShortcutsEditor::ShortcutsEditor(QWidget *parent) : QDialog(parent) { QGridLayout* grid = new QGridLayout(this); QStringList list; list.append(tr("Action")); list.append(tr("Shortcut")); m_treeWgt = new QTreeWidget(this); m_grabShortcutDlg = new ShortcutGrabber(this); m_okBtn = new QPushButton(tr("Ok"), this); m_cancelBtn = new QPushButton(tr("Cancel"), this); m_defaultsBtn = new QPushButton(tr("Defaults"), this); m_clearShortcutBtn = new QPushButton(tr("Clear Shortcut"), this); grid->addWidget(m_treeWgt , 0, 0, 5, 1); grid->addWidget(m_okBtn , 0, 1); grid->addWidget(m_cancelBtn , 1, 1); grid->addWidget(m_defaultsBtn , 2, 1); grid->addWidget(m_clearShortcutBtn, 3, 1); m_treeWgt->setColumnCount(2); m_treeWgt->setHeaderLabels(list); m_treeWgt->setAlternatingRowColors(true); connect(m_treeWgt, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(grabShortcutDlg(QTreeWidgetItem*, int))); connect(m_treeWgt, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)), this, SLOT (currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*))); connect(m_okBtn , SIGNAL(clicked()), this, SLOT(applyChanges())); connect(m_cancelBtn , SIGNAL(clicked()), this, SLOT(reject())); connect(m_defaultsBtn , SIGNAL(clicked()), this, SLOT(defaults())); connect(m_clearShortcutBtn, SIGNAL(clicked()), this, SLOT(clearCurrentShortcut())); m_shortcuts = QChatSettings::settings()->allShortcuts(); init(); m_clearShortcutBtn->setEnabled(false); setWindowTitle("Configure Shortcuts"); m_treeWgt->setAnimated(true); } ShortcutsEditor::~ShortcutsEditor() { } void ShortcutsEditor::init() { QMapIterator< QString, QList > sh(m_shortcuts); QStringList list; QTreeWidgetItem* item; QString group; QMap top_lvl_items; QTreeWidgetItem* group_item; while(sh.hasNext()) { sh.next(); list.clear(); list.append(QChatSettings::settings()->shortcutDisplayName(sh.key())); if(sh.value().size() > 0) list.append((sh.value()[0]).toString()); group = QChatSettings::settings()->shortcutGroup(sh.key()); if(!top_lvl_items.contains(group)) { group_item = new QTreeWidgetItem(m_treeWgt, QStringList(group)); top_lvl_items.insert(group, group_item); } else group_item = top_lvl_items[group]; item = new QTreeWidgetItem(group_item, list); item->setData(0, Qt::UserRole, QVariant(sh.key())); } m_treeWgt->sortItems(0, Qt::AscendingOrder); m_treeWgt->expandAll(); m_treeWgt->resizeColumnToContents(0); m_treeWgt->resizeColumnToContents(1); } void ShortcutsEditor::grabShortcutDlg(QTreeWidgetItem* item, int) { QString act_name = item->data(0, Qt::UserRole).toString(); if(m_shortcuts.contains(act_name)) { if(m_grabShortcutDlg->execute()) { QKeySequence seq = m_grabShortcutDlg->sequence(); // if(!m_shortcuts[act_name].contains(seq)) m_shortcuts[act_name].clear(); m_shortcuts[act_name].append(seq); item->setText(1, seq.toString()); } } } void ShortcutsEditor::applyChanges() { QChatSettings::settings()->setAllShortcuts(m_shortcuts); accept(); } void ShortcutsEditor::defaults() { QChatSettings prefs; m_treeWgt->clear(); m_shortcuts = prefs.allShortcuts(); init(); m_clearShortcutBtn->setEnabled(false); m_treeWgt->show(); } void ShortcutsEditor::clearCurrentShortcut() { QTreeWidgetItem* current = m_treeWgt->currentItem(); if(current) { QString act_name = current->data(0, Qt::UserRole).toString(); if(m_shortcuts.contains(act_name)) m_shortcuts[act_name].clear(); m_clearShortcutBtn->setEnabled(false); current->setText(1, ""); } } void ShortcutsEditor::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* /*previous*/) { if(!current) return; QString act_name = current->data(0, Qt::UserRole).toString(); m_clearShortcutBtn->setEnabled((m_shortcuts.contains(act_name) && m_shortcuts[act_name].size() > 0)); } qchat-0.3/src/channelwgt.cpp0000755000076500017500000010526111002650540014621 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "channelwgt.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include "chatwgt.h" #include "chatcore.h" #include "msghistory.h" #include "userslist.h" #include "userslistwgt.h" #include "message.h" #include "statuseditwgt.h" #include "chattextwgt.h" #include "inputrichtextwgt.h" #include "userwgt.h" #include "userinfo.h" #include "usersstatisticswgt.h" #include "usersstatisticsmodel.h" #include "userstatistics.h" #include "textformattingwgt.h" #include "formattingtoolbar.h" #include "qchaticon.h" #include "userlisticonconfigurewgt.h" #include "userlisticonformat.h" ChannelWgt::ChannelWgt(QString name_, QWidget *parent, AbstractChatCore::ChannelType type, quint64 dest_uid) : QWidget(parent), m_logFile (NULL), m_type (type), m_destUid (dest_uid), m_name (name_), m_usersNum (0), m_passwordSize (0), m_messageSize (0), m_displayInfoMsgs (true), m_soundOnMessageIn(true), m_requestsRest (0) { m_parent = (ChatWgt*)parentWidget(); QSplitter* lv_split; QSplitter* rv_split; QSplitter* h_split; m_smilesFromSender = new QList; m_chatMsgs = new MsgHistory; m_users = new UsersList; m_statusWgt = new StatusEditWgt(this); m_file = new QFile(); mw_grid = new QGridLayout(this); mw_chatTextStack = new QStackedWidget(this); mw_usersStack = new QStackedWidget(this); lv_split = new QSplitter(Qt::Vertical); rv_split = new QSplitter(Qt::Vertical); h_split = new QSplitter(Qt::Horizontal); mw_chatText = new ChatTextWgt(this); mw_clearChatText = new ChatTextWgt(this); mw_inputText = new InputRichTextWgt(this); mw_usersList = new UsersListWgt(this); mw_usersStatistics = new UsersStatisticsWgt(this); m_sendBtn = new QPushButton(this); m_refreshUlBtn = new QPushButton(this); m_sysMessagesChbx = new QCheckBox(this); m_refreshTimer = new QTimer(this); m_statusChangedTimer = new QTimer(this); m_initTimer = new QTimer(this); m_usersModel = new UsersStatisticsModel(this); m_splitters.append(lv_split); m_splitters.append(rv_split); m_splitters.append(h_split); m_usersModel->setUsers(m_users); mw_usersStatistics->setModel(m_usersModel); mw_usersStatistics->setSortingEnabled(true); mw_clearChatText->setSmilesFromSender(m_smilesFromSender); mw_chatText ->setSmilesFromSender(m_smilesFromSender); m_status = m_statusWgt->status(); m_oldStatus = m_statusWgt->status(); m_statusDescription = m_statusWgt->description(); mw_clearChatText->hide(); mw_chatTextStack->addWidget(mw_chatText); mw_chatTextStack->addWidget(mw_clearChatText); mw_usersStack->addWidget(mw_usersList); mw_usersStack->addWidget(mw_usersStatistics); mw_grid->setMargin(1); lv_split->addWidget(m_sysMessagesChbx); lv_split->addWidget(mw_chatTextStack); lv_split->addWidget(mw_inputText); lv_split->addWidget(m_sendBtn); rv_split->addWidget(m_statusWgt); rv_split->addWidget(mw_usersStack); rv_split->addWidget(m_refreshUlBtn); h_split ->addWidget(lv_split); h_split ->addWidget(rv_split); resize(800, 370); QList tmplst; tmplst.append(590); tmplst.append(210); h_split ->setSizes(tmplst); tmplst.clear(); tmplst.append(25); tmplst.append(300); tmplst.append(70); tmplst.append(25); lv_split->setSizes(tmplst); tmplst.clear(); tmplst.append(25); tmplst.append(370); tmplst.append(25); rv_split->setSizes(tmplst); mw_grid->addWidget(h_split , 0, 0); m_refreshUlBtn ->setMaximumHeight(25); m_sendBtn ->setMaximumHeight(25); m_sysMessagesChbx->setMaximumHeight(24); mw_inputText ->setMinimumHeight(30); connect(m_statusChangedTimer, SIGNAL(timeout()), this , SLOT(slot_statusChanged())); connect(m_refreshTimer , SIGNAL(timeout()), this , SLOT(slot_statusRequest())); connect(m_sendBtn , SIGNAL(clicked()), mw_inputText, SLOT(sendMsg())); connect(m_sendBtn , SIGNAL(clicked()), mw_inputText, SLOT(setFocus())); connect(m_refreshUlBtn , SIGNAL(clicked()), this , SLOT(slot_refreshUL())); connect(m_sysMessagesChbx , SIGNAL(clicked()), this , SLOT(slot_chbxInfChgd())); connect(mw_inputText , SIGNAL(wantSend()), this, SLOT(slot_msgOut ())); connect(mw_usersList , SIGNAL(itemDoubleClicked(UserWgt*)), m_parent , SLOT (slot_showUserInfo(UserWgt*))); connect(mw_usersList , SIGNAL(itemDoubleClicked(UserWgt*)), this , SLOT (slot_infoRequest (UserWgt*))); connect(m_statusWgt , SIGNAL(statusChanged()), this , SLOT (slot_startStatusChangedTimer())); connect(m_statusWgt , SIGNAL(editing()), m_statusChangedTimer, SLOT(stop())); connect(h_split, SIGNAL(splitterMoved(int, int)),this, SLOT(slot_controlSplitter(int, int))); connect((QObject*)mw_usersStatistics->horizontalHeader(), SIGNAL(sectionClicked(int)), mw_usersStatistics , SLOT(sortByColumn(int))); connect(mw_usersStatistics, SIGNAL(sorted()), this , SLOT (updateUsersView())); if(m_parent) { connect(mw_usersList , SIGNAL(singleMessage (const QString &, quint64, bool)), m_parent , SIGNAL(singleMessage (const QString &, quint64, bool))); connect(mw_usersList , SIGNAL(wantPrivateChat (const QString &, quint64)), m_parent , SLOT (slot_privateChat(const QString &, quint64))); connect(mw_usersList , SIGNAL(wantSendFile (quint64)), m_parent , SLOT (slot_sendFile (quint64))); } FormattingToolBar* obj = m_parent->formattingToolBar(); connect(obj, SIGNAL(wantSetBold (bool)), mw_inputText, SLOT(setBold(bool))); connect(obj, SIGNAL(wantSetItalic (bool)), mw_inputText, SLOT(setItalic(bool))); connect(obj, SIGNAL(wantSetUnderline(bool)), mw_inputText, SLOT(setUnderline(bool))); connect(obj, SIGNAL(wantSetColor (const QColor&)) , mw_inputText, SLOT(setColor(const QColor&))); connect(obj, SIGNAL(wantSetFontFamily(const QString&)), mw_inputText, SLOT(setFontFamily(const QString&))); connect(obj, SIGNAL(wantSetFontSize (const QString&)), mw_inputText, SLOT(setFontSize(const QString&))); connect(obj, SIGNAL(wantSetTextStyle (int)) , mw_inputText, SLOT(setTextStyle(int))); connect(obj, SIGNAL(wantCreateTable (uint, uint)) , mw_inputText, SLOT(createTable(uint, uint))); connect(mw_inputText, SIGNAL(currentCharFormatChanged(const QTextCharFormat&)), obj , SLOT (currentCharFormatChanged(const QTextCharFormat&))); mw_clearChatText->text()->verticalScrollBar()->setValue(mw_clearChatText->text()->verticalScrollBar()->maximum()); mw_chatText ->text()->verticalScrollBar()->setValue(mw_chatText ->text()->verticalScrollBar()->maximum()); m_refreshTimer->start(QChatSettings::settings()->usersListRefreshInterval() * 1000); if(!QChatSettings::loggingDir().isEmpty()) { QString filename = QChatSettings::loggingDir() + "/" + m_name + "_" + QDateTime::currentDateTime().toString("hh:mm:ss_dd.MM.yy") + ".log"; m_logFile = new QFile(filename); if(!m_logFile->open(QIODevice::WriteOnly | QIODevice::Unbuffered)) { qWarning("[ChannelWgt::ChannelWgt]: Couldn't open log file(%s) for writing. Disabling logging for channel %s", filename.toLocal8Bit().data(), m_name.toLocal8Bit().data()); delete m_logFile; m_logFile = NULL; } } retranslate(); } //\***************************************************************************** ChannelWgt::~ChannelWgt() { qDebug("[~ChannelWgt '%s']", m_name.toLocal8Bit().data()); emit wantSaveState(m_name, saveState()); slot_disconnected(); delete m_logFile; } //\***************************************************************************** UserWgt* ChannelWgt::findUser(quint64 uid) const { return m_users->findUser(uid); } //\***************************************************************************** void ChannelWgt::setFocus2InputText() { mw_inputText->setFocus(); } //\***************************************************************************** void ChannelWgt::processData(QC_DatagramHeader* Hdr) { qDebug("[ChannelWgt::processData]"); switch(Hdr->type) { case AbstractChatCore::MESSAGE : qDebug("[ChannelWgt::processData]: Message"); emit wantActivate(); getSmilesFromData(Hdr); addMsg(Hdr); break; case AbstractChatCore::STATUS_REQUEST : qDebug("[ChannelWgt::processData]: StatusRequest"); sendStatusAnswer(Hdr->src_ip, 0, Hdr->programVersion < 14); break; case AbstractChatCore::STATUS_ANSWER : qDebug("[ChannelWgt::processData]: StatusAnswer"); addUser(Hdr); break; case AbstractChatCore::CONNECTED : qDebug("[ChannelWgt::processData]: Connected"); addUser(Hdr); addInfoMsg(Hdr); break; case AbstractChatCore::DISCONNECTED : qDebug("[ChannelWgt::processData]: Disconnected"); addInfoMsg(Hdr); hideUser(Hdr); break; case AbstractChatCore::INF_STATUS_CHNGD : qDebug("[ChannelWgt::processData]: StatusChanged"); addUser(Hdr); addInfoMsg(Hdr); break; case AbstractChatCore::INFO_REQUEST : qDebug("[ChannelWgt::processData]: UserInfoRequest"); sendInfoAnswer(Hdr); break; case AbstractChatCore::INFO_ANSWER : qDebug("[ChannelWgt::processData]: UserInfoAnswer"); addUserInfo(Hdr); addUser(Hdr); break; case AbstractChatCore::MSGS_HISTORY_REQUEST : qDebug("[ChannelWgt::processData]: Msgs Request"); qDebug("[ChannelWgt::processData]: par.size = %d", ChatCore::getParametr("MaxMsgsHistorySize", Hdr->parametrs).size()); emit sendMsgsHistory(m_name, Hdr->src_ip, m_chatMsgs->toByteArray(ChatCore::getParametr("MaxMsgsHistorySize", Hdr->parametrs).toLongLong()), m_type); break; case AbstractChatCore::MSGS_HISTORY_ANSWER : { qDebug("[ChannelWgt::processData]: Msgs Answer"); int diff_time = time(NULL) - Hdr->tm; m_chatMsgs->fromByteArray(ChatCore::getParametr("MsgsHistory", Hdr->parametrs)); for(uint i = 0; i < m_chatMsgs->size(); i++) { m_chatMsgs->msg(i)->setReceiveTime(m_chatMsgs->msg(i)->receiveTime() + diff_time); m_chatMsgs->msg(i)->setIsHtml(Hdr->protocolVersion >= 4); } rebuildChatText(); break; } case AbstractChatCore::MSGS_NUM_REQUEST : qDebug("[ChannelWgt::processData]: Msgs Num Request"); emit sendMsgsNum(m_name, Hdr->src_ip, m_chatMsgs->size(), m_type); break; case AbstractChatCore::MSGS_NUM_ANSWER : qDebug("[ChannelWgt::processData]: Msgs Num Answer"); msgsNumAnswer(Hdr); break; case AbstractChatCore::AVATAR_REQUEST : { qDebug("[ChannelWgt::processData]: Avatar Request"); QByteArray ba = ChatCore::getParametr("IconHash", Hdr->parametrs); if(ba.isEmpty() || UserInfo::myInfo()->avatarHash() != ba) emit avatarAnswer(m_name, Hdr->src_ip, m_type); break; } case AbstractChatCore::AVATAR_ANSWER : qDebug("[ChannelWgt::processData]: Avatar Answer"); addAvatar(Hdr); break; } } //\***************************************************************************** void ChannelWgt::slot_msgOut() { if(!mw_inputText->toPlainText().isEmpty()) { if(m_type == 1) { emit sendMessage(m_name, m_destUid, m_type, mw_inputText->document()->clone()); emit sendMessage(m_name, Globals::localhost(), m_type, mw_inputText->document()->clone()); } else emit sendMessage(m_name, QChatSettings::settings()->broadcast().toIPv4Address(), m_type, mw_inputText->document()->clone()); mw_inputText->clear(); } } //\***************************************************************************** void ChannelWgt::addInfoMsg(QC_DatagramHeader* Hdr) { Message* msg = new Message(Hdr); logMessage(Hdr); m_chatMsgs->addMsg(msg); mw_chatText->addMsg(msg); } //\***************************************************************************** void ChannelWgt::addMsg(QC_DatagramHeader* Hdr) { if(QChatSettings::settings()->boolOption("IsExecuteCommandOnIncomingMessage") && !QChatSettings::settings()->executeCommandOnIncomingMsg().isEmpty()) { QProcess pr; pr.startDetached(QChatSettings::settings()->executeCommandOnIncomingMsg()); } logMessage(Hdr); Message* msg = new Message(Hdr); m_chatMsgs->addMsg(msg); mw_chatText->addMsg(msg); mw_clearChatText->addMsg(msg); } //\***************************************************************************** void ChannelWgt::addMsg2Chat(Message* msg) { if(msg) { qDebug("[ChannelWgt::addMsg2Chat]: adding: %s\n", msg->msg().toLocal8Bit().data()); mw_chatText->addMsg(msg); if(!isSystemMsg(msg->type())) mw_clearChatText->addMsg(msg); } } //\***************************************************************************** void ChannelWgt::addUser(QC_DatagramHeader* Hdr) { UserWgt* usr; UserInfo* info; UserStatistics* stats; QByteArray buf; qDebug("[ChannelWgt::addUser]: uid = %s", QHostAddress(Hdr->src_ip).toString().toAscii().data()); if(!(usr = m_users->enableIfExists(Hdr->src_ip))) { info = new UserInfo(); if(!info) return; stats = new UserStatistics; if(!stats) return; usr = new UserWgt(); if(!usr) return; usr->setInfo(info); usr->setStats(stats); m_users->addUser(usr); } else info = usr->info(); // this is only needed in server mode usr->info()->setUid(Hdr->src_ip); addUserInfo(usr, Hdr); mw_usersList->addUser(usr); m_usersModel->resort(); updateUsersView(); } //\***************************************************************************** void ChannelWgt::hideUser(QC_DatagramHeader* Hdr) { UserWgt* user; if(m_users->exists(Hdr->src_ip)) { user = m_users->findUser(Hdr->src_ip); if(user) { mw_usersList->hideUser(user); user->info()->setEnabled(false); } } m_usersModel->resort(); updateUsersView(); } //\***************************************************************************** void ChannelWgt::addUserInfo(QC_DatagramHeader* Hdr) { UserWgt* usr = m_users->findUser(Hdr->src_ip); if(NULL == usr) { usr = new UserWgt(); usr->setInfo(new UserInfo()); m_users->addUser(usr); } addUserInfo(usr, Hdr); } void ChannelWgt::addUserInfo(UserWgt* usr, QC_DatagramHeader* Hdr) { QByteArray buf; QPixmap* icon, *tmp; QCryptographicHash md5_hash(QCryptographicHash::Md5); bool need_avatar = true; if(!(buf = ChatCore::getParametr("IpAddress" , Hdr->parametrs)).isNull()) usr->info()->setIP((QString().fromUtf8(buf)).toLongLong()); usr->info()->setGender(QString().fromUtf8(ChatCore::getParametr("Gender", Hdr->parametrs)).toInt()); if(!(buf = ChatCore::getParametr("OS" , Hdr->parametrs)).isNull()) usr->stats()->setOs(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("Uptime" , Hdr->parametrs)).isNull()) usr->stats()->setUptime((QString().fromUtf8(buf)).toLong()); if(!(buf = ChatCore::getParametr("ChatTime" , Hdr->parametrs)).isNull()) usr->stats()->setChatTime((QString().fromUtf8(buf)).toLong()); if(!(buf = ChatCore::getParametr("LastName" , Hdr->parametrs)).isNull()) usr->info()->setLastName (QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("FirstName" , Hdr->parametrs)).isNull()) usr->info()->setFirstName (QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("SecondName" , Hdr->parametrs)).isNull()) usr->info()->setSecondName (QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("DateOfBorn" , Hdr->parametrs)).isNull()) usr->info()->setDateOfBorn(QDate().fromString(QString().fromUtf8(buf))); if(!(buf = ChatCore::getParametr("Address" , Hdr->parametrs)).isNull()) usr->info()->setAddress(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("HomePhone" , Hdr->parametrs)).isNull()) usr->info()->setHomePhone(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("MobilePhone", Hdr->parametrs)).isNull()) usr->info()->setMobilePhone(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("WorkPhone" , Hdr->parametrs)).isNull()) usr->info()->setWorkPhone(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("e-mail" , Hdr->parametrs)).isNull()) usr->info()->setE_mail(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("ICQ" , Hdr->parametrs)).isNull()) usr->info()->setICQ(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("Homepage" , Hdr->parametrs)).isNull()) usr->info()->setHomepage(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("AboutInfo" , Hdr->parametrs)).isNull()) usr->info()->setAboutInfo(QString().fromUtf8(buf)); if(!(buf = ChatCore::getParametr("StatusDescription", Hdr->parametrs)).isNull()) usr->info()->setStatusDescription(QString().fromUtf8(buf)); // if(!(buf = ChatCore::getParametr("Gender", Hdr->parametrs)).isNull()) // usr->info()->setGender(QString().fromUtf8(buf).toInt()); usr->info()->setStatus (Hdr->status); buf = ChatCore::getParametr("Icon", Hdr->parametrs); if(!buf.isNull()) { md5_hash.addData(buf); usr->info()->setAvatarHash(md5_hash.result()); icon = new QPixmap(); icon->loadFromData(buf); need_avatar = false; } else icon = usr->info()->avatar(); tmp = drawUsersIcon(icon, usr->info()); usr->setIcon(QIcon(*tmp)); delete tmp; if(!need_avatar) delete icon; buf = ChatCore::getParametr("PhotoOk", Hdr->parametrs); if(buf.isNull()) { buf = ChatCore::getParametr("Photo", Hdr->parametrs); if(!buf.isNull()) usr->info()->setPhoto(buf); buf = ChatCore::getParametr("PhotoHash", Hdr->parametrs); usr->info()->setPhotoHash(buf); } buf = ChatCore::getParametr("PictureOk", Hdr->parametrs); if(buf.isNull()) { buf = ChatCore::getParametr("Picture", Hdr->parametrs); if(!buf.isNull()) usr->info()->setPicture(buf); buf = ChatCore::getParametr("PictureHash", Hdr->parametrs); usr->info()->setPictureHash(buf); } if(need_avatar) { ChatCore::addParametr("IconHash", usr->info()->avatarHash(), m_parametrs); emitSomeData(AbstractChatCore::AVATAR_REQUEST, "", Hdr->src_ip); } usr->info()->setProgramVerName(Hdr->versionName); usr->info()->setNickname (Hdr->name); usr->info()->setCompName (Hdr->comp_name); usr->info()->setStatus (Hdr->status); usr->info()->setStatusDescription(QString().fromUtf8(ChatCore::getParametr("StatusDescription", Hdr->parametrs))); usr->setData(Qt::StatusTipRole, usr->info()->nickname() + tr(" on ") + usr->info()->compName() + "[" + QHostAddress(usr->info()->ip()).toString() + "]" + tr(" running QChat ") + usr->info()->programVerName() ); usr->setData(Qt::ToolTipRole, usr->info()->statusDescription()); } //\***************************************************************************** void ChannelWgt::slot_refreshUL() { qDebug("\n[ChannelWgt::slot_refreshUL]\n"); mw_usersList->clear(); m_users->disableAll(); // slot_statusRequest(); slot_deepRefreshUL(); } //\***************************************************************************** void ChannelWgt::slot_chbxInfChgd() { if(m_sysMessagesChbx->checkState() == Qt::Checked) { mw_chatTextStack->setCurrentIndex(1); m_displayInfoMsgs = false; } if(m_sysMessagesChbx->checkState() == Qt::Unchecked) { m_displayInfoMsgs = true; mw_chatTextStack->setCurrentIndex(0); } } //\***************************************************************************** void ChannelWgt::sendInfoAnswer(QC_DatagramHeader* Hdr) { uchar photo_ok = 0; uchar pic_ok = 0; QByteArray ba; if(m_status != Globals::INVISIBLE) { UserInfo::myInfo()->setStatus(m_name, m_status); UserInfo::myInfo()->setStatusDescription(m_name, m_statusWgt->description()); ba = ChatCore::getParametr("PhotoHash" , Hdr->parametrs); if(!ba.isEmpty()) photo_ok = UserInfo::myInfo()->photoHash() == ba; ba = ChatCore::getParametr("PictureHash", Hdr->parametrs); if(!ba.isEmpty()) pic_ok = UserInfo::myInfo()->pictureHash() == ba; emit infoAnswer(m_name, Hdr->src_ip, m_type, pic_ok | (2 * photo_ok)); } } //\***************************************************************************** void ChannelWgt::sendStatusAnswer(quint64 uid, bool changed, bool send_icon) { if(m_status != Globals::INVISIBLE) { UserInfo::myInfo()->setStatus(m_name, m_status); UserInfo::myInfo()->setStatusDescription(m_name, m_statusDescription); if(m_type == 1) { emit statusAnswer(m_name, Globals::localhost(), m_type, changed, send_icon); emit statusAnswer(m_name, m_destUid, m_type, changed, send_icon); } else emit statusAnswer(m_name, uid, m_type, changed, send_icon); } } //\***************************************************************************** void ChannelWgt::slot_infoRequest(UserWgt* user) { m_parametrs.clear(); if(QFile::exists(user->info()->pictureFilename())) ChatCore::addParametr("PictureHash", user->info()->pictureHash(), m_parametrs); if(QFile::exists(user->info()->photoFilename())) ChatCore::addParametr("PhotoHash" , user->info()->photoHash() , m_parametrs); emit sendSomeData(m_name, user->info()->uid(), AbstractChatCore::INFO_REQUEST, "", m_type, &m_parametrs); } //\***************************************************************************** void ChannelWgt::slot_statusChanged() { UserInfo::myInfo()->setStatus (m_name, m_status = m_statusWgt->status()); UserInfo::myInfo()->setStatusDescription(m_name, m_statusDescription = m_statusWgt->description()); sendStatusAnswer(QChatSettings::settings()->broadcast().toIPv4Address(), m_oldStatus != m_status); m_oldStatus = m_status; } //\***************************************************************************** void ChannelWgt::slot_startStatusChangedTimer() { m_statusChangedTimer->setInterval(1 * 1000); m_statusChangedTimer->setSingleShot(true); m_statusChangedTimer->start(); } void ChannelWgt::getSmilesFromData(QC_DatagramHeader * Hdr) // TODO rewrite { m_smilesFromSender->clear(); QFile file; QString fname; QString str; QByteArray barr_hash; QByteArray barr1; QByteArray barr = ChatCore::getParametr("Smiles", Hdr->parametrs); QByteArray sm_ba; QCryptographicHash md5_hash(QCryptographicHash::Md5); int len; qDebug("[ChannelWgt::getSmilesFromData]: Smiles = %s", QString().fromUtf8(barr).toLocal8Bit().data()); for(int i = 0; i < barr.size(); i++) { sm_ba.clear(); for(; barr.at(i) != 0 && i < barr.size(); i++) sm_ba.append(barr.at(i)); str = QString().fromUtf8(sm_ba); qDebug("[ChannelWgt::getSmilesFromData]: str = %s", str.toLocal8Bit().data()); barr1 = ChatCore::getParametr("Smile" + str, Hdr->parametrs); md5_hash.addData(barr1); barr_hash = md5_hash.result(); md5_hash.reset(); fname = QDir::tempPath() + "/smile"; fname.append('_'); len = barr_hash.size(); for(int i = 0; i < len; i++) fname.append(QString::number((uchar)barr_hash.at(i), 16)); file.setFileName(fname); if(file.open(QIODevice::WriteOnly | QIODevice::Unbuffered)) file.write(barr1); else qWarning("[ChannelWgt::getSmilesFromData]: couldn't open file %s for writing", fname.toLocal8Bit().data()); file.close(); m_smilesFromSender->append(Smile(QStringList(str), fname)); } } void ChannelWgt::initChannel() { emit sendSomeData(m_name, QChatSettings::settings()->broadcast().toIPv4Address(), AbstractChatCore::MSGS_NUM_REQUEST, "", m_type, NULL); m_msgsReqSent = QTime::currentTime(); m_msgsReqReceived = m_msgsReqSent; connect(m_initTimer, SIGNAL(timeout()), this, SLOT(slot_finMsgsHistoryReq())); m_msgsReqNum = 0; m_initTimer->setSingleShot(true); m_initTimer->start(QChatSettings::settings()->historyReqTimeout()); slot_statusRequest(); slot_connected(); } void ChannelWgt::rebuildChatText() { mw_chatText ->clear(); mw_clearChatText->clear(); for(uint i = 0; i < m_chatMsgs->size(); i++) addMsg2Chat(m_chatMsgs->msg(i)); } void ChannelWgt::slot_finMsgsHistoryReq() { qDebug("\n[ChannelWgt::slot_finMsgsHistoryReq]: num = %d\n", m_msgsReqNum); ChatCore::addParametr("MaxMsgsHistorySize", QString().setNum(QChatSettings::settings()->nHistoryMsgs()).toUtf8(), m_parametrs); // FIXME !!! if(m_msgsReqNum > 0) emit sendSomeData(m_name, m_msgsReqAddr.toIPv4Address(), AbstractChatCore::MSGS_HISTORY_REQUEST, "", m_type, &m_parametrs); } void ChannelWgt::msgsNumAnswer(QC_DatagramHeader* Hdr) { uint num = QString(ChatCore::getParametr("MsgsNum", Hdr->parametrs)).toULongLong(); if(num > m_msgsReqNum && (QChatSettings::settings()->nHistoryMsgs() < 0 || (int)m_msgsReqNum < QChatSettings::settings()->nHistoryMsgs())) { m_msgsReqNum = num; m_msgsReqAddr = QHostAddress(Hdr->src_ip); m_msgsReqReceived = QTime::currentTime(); } } void ChannelWgt::retranslate() { m_sendBtn ->setText(tr("Send")); m_refreshUlBtn ->setText(tr("Refresh")); m_sysMessagesChbx ->setText(tr("Hide System Messages")); } void ChannelWgt::emitSomeData(AbstractChatCore::DataType data_type, const QString & msg, quint64 uid) const { if(m_type == 1) { emit sendSomeData (m_name, m_destUid, data_type, msg, m_type, &m_parametrs); emit sendSomeData (m_name, Globals::localhost(), data_type, msg, m_type, &m_parametrs); } else if(uid == 0) // FIXME !!! emit sendSomeData (m_name, QChatSettings::settings()->broadcast().toIPv4Address(), data_type, msg, m_type, &m_parametrs); else emit sendSomeData (m_name, uid, data_type, msg, m_type, &m_parametrs); } void ChannelWgt::slot_changeUlRefreshInterval(uint erval) { if(erval == 0) m_refreshTimer->stop(); else m_refreshTimer->start(erval * 1000); } void ChannelWgt::slot_changeUlDeepRefreshInterval(uint /*erval*/) { } void ChannelWgt::slot_controlSplitter(int idx, int /*pos*/) { if((double)idx / (double)width() <= 0.5) { mw_usersStack->setCurrentIndex(1); m_usersModel->resort(); updateUsersView(); } else mw_usersStack->setCurrentIndex(0); } void ChannelWgt::updateUsersView() { m_usersModel->resetModel(); mw_usersStatistics->reset(); mw_usersStatistics->setModel(m_usersModel); } void ChannelWgt::slot_deepRefreshUL() { if(!m_requestsRest) { QTimer* t = new QTimer; m_requestsRest = 3; connect(t, SIGNAL(timeout()), this, SLOT(nextStatusRequest())); t->start(1000); slot_statusRequest(); } else slot_statusRequest(); } QByteArray ChannelWgt::saveState() const { // Format: // 2 bytes - splittersStatesSize // 3x: // 2 bytes - splitter[i] State Size(SSS) // SSS bytes - splitter[i] state , i = (1, 3) // // from splittersStatesSize to state.size(); - usersstatisticswgt state QByteArray state, tmp; char sz[2]; for(int i = 0; i < m_splitters.size(); i++) { tmp = m_splitters[i]->saveState(); catUS2str(sz, tmp.size()); state.append(sz[0]); state.append(sz[1]); state.append(tmp); } catUS2str(sz, state.size()); state.prepend(sz[1]); state.prepend(sz[0]); state.append(mw_usersStatistics->saveState()); return state; } void ChannelWgt::restoreState(const QByteArray & state) { QByteArray tmp; char sz2[2]; uint sz; uint state_sz; if(state.size() < 2) return; sz2[0] = state.at(0); sz2[1] = state.at(1); state_sz = str2US(sz2) + 2; if((uint)state.size() < state_sz) return; for(uint i = 0, j = 2; i < (uint)m_splitters.size(); i++) { if(j + 2 > state_sz) break; sz2[0] = state.at(j++); sz2[1] = state.at(j++); sz = str2US(sz2); if(j + sz > state_sz) break; tmp = state.mid(j, sz); m_splitters[i]->restoreState(tmp); j += sz; } mw_usersStatistics->restoreState(state.mid(state_sz, state.size() - state_sz)); if((double)m_splitters[2]->sizes()[1] / (double)width() >= 0.5) { mw_usersStack->setCurrentIndex(1); m_usersModel->resort(); updateUsersView(); } else mw_usersStack->setCurrentIndex(0); updateUsersView(); } void ChannelWgt::nextStatusRequest() { slot_statusRequest(); m_requestsRest--; if(!m_requestsRest) if(qobject_cast(sender())) delete sender(); } void ChannelWgt::addAvatar(QC_DatagramHeader * Hdr) { UserWgt* usr; QByteArray buf; QPixmap* icon, *tmp; usr = m_users->findUser(Hdr->src_ip); if(!usr) m_users->findHidden(Hdr->src_ip); if(!usr) return; buf = ChatCore::getParametr("Icon", Hdr->parametrs); if(!buf.isNull()) { icon = new QPixmap(); if(!buf.isEmpty()) icon->loadFromData(buf); tmp = drawUsersIcon(icon, usr->info()); usr->setIcon(QIcon(*tmp)); delete usr->info()->avatar(); usr->info()->setAvatar(icon); delete tmp; } buf = ChatCore::getParametr("IconHash", Hdr->parametrs); usr->info()->setAvatarHash(buf); updateUsersView(); } QPixmap* ChannelWgt::drawUsersIcon(const QPixmap* avatar_icon, UserInfo* info) { QPixmap* status_pix = NULL; QPixmap* gender_pix = NULL; QPixmap* result_pix; QPixmap tmp_icon; QPainter painter; bool disabled = true; QString icon_name; UserListIconFormat fmt = *(QChatSettings::settings()->iconFormat()); int status_wd = fmt.statusWidth(); int status_he = fmt.statusHeight(); int gender_wd = fmt.genderWidth(); int gender_he = fmt.genderHeight(); int avatar_wd = fmt.avatarWidth();; int avatar_he = fmt.avatarHeight(); int total_wd = fmt.totalWidth(); int total_he = fmt.totalHeight(); bool draw_gender = gender_wd > 0 && gender_he > 0; bool draw_status = status_wd > 0 && status_he > 0; // avatar_wd = total_wd - status_wd - gender_wd; assert(NULL != info); switch(info->status()) { case Globals::READY4CHAT : icon_name = "status/user-ready-for-chat"; disabled = false; break; case Globals::FREE : icon_name = "status/user-online"; disabled = false; break; case Globals::BUSY : icon_name = "status/user-busy"; break; case Globals::DND : icon_name = "status/user-dnd"; break; case Globals::INACTIVE : icon_name = "status/user-away"; break; case Globals::AWAY : icon_name = "status/user-away-extended"; break; } if(avatar_icon) { if(disabled) // tmp_icon = QIcon(*avatar_icon).pixmap(avatar_wd, avatar_he, QIcon::Disabled); tmp_icon = QIcon(*avatar_icon).pixmap(avatar_wd, avatar_he, QIcon::Disabled); else tmp_icon = QIcon(*avatar_icon).pixmap(avatar_wd, avatar_he);//*avatar_icon; } if(draw_gender) switch(info->gender()) { case 'm' : gender_pix = QChatIcon::newPixmap("user-male" , gender_wd, gender_he); break; case 'f' : gender_pix = QChatIcon::newPixmap("user-female", gender_wd, gender_he); break; default : gender_pix = QChatIcon::newPixmap("unknown" , gender_wd, gender_he); } result_pix = new QPixmap(total_wd, total_he); QPixmap tmp(total_wd, total_he); tmp.fill(Qt::black); result_pix->setAlphaChannel(tmp); if(draw_status) { status_pix = QChatIcon::newPixmap(icon_name, status_wd, status_he); tmp = QPixmap(status_pix->width(), status_pix->height()); tmp.fill(QColor(200, 200, 200)); status_pix->setAlphaChannel(tmp); } int g_wd = (gender_wd + fmt.genderXoffset()) * draw_gender; int s_wd = (status_wd + fmt.statusXoffset()) * draw_status; painter.begin(result_pix); if(draw_gender) painter.drawPixmap(fmt.genderXoffset(), fmt.genderYoffset(), *gender_pix); if(draw_status) painter.drawPixmap(fmt.statusXoffset(), fmt.statusYoffset(), *status_pix); painter.drawPixmap((s_wd > g_wd ? s_wd : g_wd) + fmt.avatarXoffset(), (total_he - tmp_icon.height()) / 2 /*fmt.avatarYoffset()*/, tmp_icon); painter.drawLine(fmt.totalWidth(), 0, fmt.totalWidth(), fmt.totalHeight()); painter.end(); delete status_pix; delete gender_pix; return result_pix; } void ChannelWgt::redrawIcons() { UserListIconFormat* fmt = QChatSettings::settings()->iconFormat(); mw_usersList->setIconSize(QSize(fmt->totalWidth(), fmt->totalHeight())); for(uint i = 0; i < m_users->num(); i++) { UserWgt* usr = m_users->user(i); if(usr) { usr->setSizeHint(QSize(1, fmt->totalHeight())); usr->setIcon(QIcon(*drawUsersIcon(usr->info()->avatar(), usr->info()))); } } } void ChannelWgt::keyPressEvent(QKeyEvent* ev) { QKeySequence seq = ev->key() + ev->modifiers(); if(QChatSettings::settings()->shortcuts("RefreshUsersList").contains(seq)) slot_refreshUL(); } void ChannelWgt::setAnimationsRunning(bool b) { mw_clearChatText->playPauseAnimations(b); mw_chatText ->playPauseAnimations(b); } void ChannelWgt::logMessage(QC_DatagramHeader* Hdr) { if(m_logFile) { Message msg(Hdr); QDateTime date_time; QTextDocument doc; doc.setHtml(msg.msg()); QString msg_str(QChatSettings::settings()->strOption("DisplayMessagesFormat")); QString tm_fmt = msg_str.section(QString("%time%"), 1, 1); date_time.setTime_t(msg.receiveTime()); msg_str.replace(QRegExp("%time%([^<]*)%time%"), date_time.toString(tm_fmt)); msg_str.replace("%user", msg.userName()); msg_str.replace("%comp", msg.compName()); if(msg.requested()) msg_str.prepend(">"); msg_str.append(doc.toPlainText() + "\n"); m_logFile->write(msg_str.toUtf8()); } } qchat-0.3/src/messagewithcheckbox.h0000644000076500017500000000341510703763102016164 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef MESSAGEWITHCHECKBOX_H #define MESSAGEWITHCHECKBOX_H #include #include #include #include #include /** @author Anistratov Oleg */ class MessageWithCheckBox : public QDialog { Q_OBJECT private: QLabel* m_msg; QLabel* m_icon; QCheckBox* m_question; QPushButton* m_okBtn; int* m_result; public: MessageWithCheckBox(const QString &, const QString &, const QString &, int*, QWidget* = 0); ~MessageWithCheckBox(){}; void setIcon(const QPixmap & pix){m_icon->setPixmap(pix);} public slots: void finish(){*m_result = (m_question->checkState() == Qt::Unchecked); accept();} }; #endif qchat-0.3/src/qchateventfilter.h0000644000076500017500000000276410777006703015523 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHATEVENTFILTER_H #define QCHATEVENTFILTER_H #include class ChatWgt; /** @author Anistratov Oleg */ class QChatEventFilter : public QObject { Q_OBJECT private: ChatWgt* m_chatWgt; public: QChatEventFilter(QObject *parent = 0); ~QChatEventFilter(); void setChatWgt(ChatWgt*); protected: bool eventFilter(QObject*, QEvent*); signals: void wantHide2Tray(); }; #endif qchat-0.3/src/qchattrayicon.h0000644000076500017500000000323510675724717015027 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHATTRAYICON_H #define QCHATTRAYICON_H #include #include #include /** @author Anistratov Oleg */ class QChatTrayIcon : public QSystemTrayIcon { Q_OBJECT private: QMovie* m_movie; public: QChatTrayIcon(QIcon, QObject *parent = 0); ~QChatTrayIcon(){}; void setStaticIcon(const QString & fname) {m_movie->stop(); setIcon(QIcon(fname));} void setAnimatedIcon(const QString & fname){m_movie->setFileName(fname); m_movie->start();} private slots: void nextFrame(){setIcon(QIcon(m_movie->currentPixmap()));} }; #endif qchat-0.3/src/textbrowser.h0000644000076500017500000000324310777133027014534 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef TEXTBROWSER_H #define TEXTBROWSER_H #include #include #include /** @author Anistratov Oleg */ class TextBrowser : public QTextBrowser { Q_OBJECT public: TextBrowser(QWidget *parent = 0); ~TextBrowser(); protected: bool viewportEvent(QEvent* ev){emit viewportChanged(); return QTextBrowser::viewportEvent(ev);} void hideEvent(QHideEvent* /*ev*/){emit viewportVisible(false);} void showEvent(QShowEvent* /*ev*/){emit viewportVisible(true);} signals: void viewportChanged(); void viewportVisible(bool); }; #endif qchat-0.3/src/treemodel.h0000644000076500017500000000421010770461367014123 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef TREEMODEL_H #define TREEMODEL_H #include class TreeItem; class MsgsHistory; /** @author Anistratov Oleg */ class TreeModel : public QAbstractItemModel { Q_OBJECT private: TreeItem* m_rootItem; public: TreeModel(QObject *parent = 0); ~TreeModel(); Qt::ItemFlags flags (const QModelIndex &index) const; QVariant data (const QModelIndex &index, int role) const; QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index (int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent (const QModelIndex &index) const; int rowCount (const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; TreeItem* rootItem() const {return m_rootItem;} void setRootItem(TreeItem* item){m_rootItem = item;} void appendToRoot(TreeItem*); void clear(); protected: virtual TreeItem* createRootItem() = 0; }; #endif qchat-0.3/src/chatcore_settings.cpp0000644000076500017500000004634311002616450016203 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "chatcore.h" #include "globals.h" #include #include #include "inputtextwgt.h" #include "qchatsettings.h" #include "userinfo.h" #include "userprofile.h" #include "channelwgt.h" #include "userlisticonformat.h" //\***************************************************************************** bool ChatCore::initSettings(QString dirName) { QString home = homePath(); QFile file; QDir settingsDir(home); QString path; if(!dirName.isEmpty()) { path = dirName + QString("/settings.ini" ); m_qsettings = new QSettings(path, QSettings::IniFormat); } else if(home.isEmpty()) { return false; } else { dirName = QString("%1/%2").arg(home).arg(".qchat"); if(!QDir(dirName).exists()) { printf("[ChatCore::initSettings]: settingsDir does not exists...\n"); if(settingsDir.mkdir(".qchat")) printf(" created!\n"); else { printf(" and cannot create :(\n"); return false; } } // TODO sdelat' proverku na readOnly i v etom sluchae vyvodit' dialog vybora faila nastroek path = dirName + QString("/settings.ini"); m_qsettings = new QSettings(path, QSettings::IniFormat); if(!QDir(QChatSettings::loggingDir()).exists()) { printf("[ChatCore::initSettings]: chatLogDir does not exists...\n"); if(QDir("").mkpath(QChatSettings::loggingDir())) printf(" created!\n"); else { printf(" and cannot create :(\n"); QChatSettings::setLoggingDir(""); } } } printf("[ChatCore::initSettings]: settingsDir = %s\n", dirName.toLocal8Bit().data()); QChatSettings::setSettingsDir(dirName); if(QFile::exists(dirName + "/Charmap")) InputTextWgt::initChars(dirName + "/Charmap"); #ifdef Q_OS_LINUX else if(QFile::exists(QApplication::applicationDirPath() + "/../share/qchat/Charmap")) InputTextWgt::initChars(QCoreApplication::applicationDirPath() + "/../share/qchat/Charmap"); #else else if(QFile::exists(QApplication::applicationDirPath() + "/Charmap")) InputTextWgt::initChars(QApplication::applicationDirPath() + "/Charmap"); #endif return true; } //\***************************************************************************** void ChatCore::slot_saveSettings() { saveSettings(false); } void ChatCore::saveSettings(bool on_quit) { // FIXME !!! settings()->setMode(QChatSettings::Serverless); QByteArray data; QByteArray ba; QBuffer buffer; qDebug("[ChatCore::saveSettings]"); QChatSettings::settings()->saveGeneralOptions(m_qsettings); m_qsettings->beginGroup("Network"); m_qsettings->setValue ("Broadcast" , QChatSettings::settings()->realBroadcast().toString()); QStringList ipList; foreach(QHostAddress ip, QChatSettings::settings()->ipList()) ipList.append(ip.toString()); m_qsettings->setValue("IPList", ipList); m_qsettings->endGroup (); //*************************** QMapIterator pr(m_profiles); QStringList profiles; while (pr.hasNext()) { pr.next(); writeProfile(pr.value()); profiles << pr.key(); } //********************************** m_qsettings->setValue("ProfileNames", profiles); m_qsettings->setValue("LastProfile" , m_currentProfile->name()); m_qsettings->setValue("Language" , m_lang); if(m_chatWgt && on_quit) { m_qsettings->setValue("Geometry", m_chatWgt->saveGeometry()); m_qsettings->setValue("MainWindowState", m_chatWgt->saveState()); QList l = m_chatWgt->channels(); foreach(ChannelWgt* c, l) setChannelState(c->name(), c->saveState()); } m_qsettings->setValue("ChannelsStates", QStringList(m_channelsStates.keys())); QMapIterator ch(m_channelsStates); while (ch.hasNext()) { ch.next(); m_qsettings->setValue(ch.key() + "ChannelState", ch.value()); } m_qsettings->sync(); // FIXME !!! settings()->setMode((QChatSettings::Mode)m_mode); } //\***************************************************************************** void ChatCore::slot_loadSettings() { QNetworkAddressEntry addr; QString str; QStringList profiles; QChatSettings::settings()->loadGeneralOptions(m_qsettings); m_qsettings->beginGroup("Network"); if(!QChatSettings::settings()->boolOption("AllowDifferentPorts")) QChatSettings::settings()->setOption("OutputPort", QChatSettings::settings()->option("InputPort")); //******************************* addr.setIp(QHostAddress(QString(m_qsettings->value("IP").toByteArray().data ()))); addr.setBroadcast(QHostAddress(QString(m_qsettings->value("Broadcast").toByteArray().data ()))); QStringList ipList; ipList = m_qsettings->value("IPList").toStringList(); foreach(QString ip, ipList) QChatSettings::addIpListEntry(QHostAddress(ip)); QList all_i = QNetworkInterface::allInterfaces(); QList valid_a; // get all valid(that can broadcast) interfaces foreach(QNetworkInterface i, all_i) foreach(QNetworkAddressEntry a, i.addressEntries()) { if(a.broadcast().isNull()) continue; valid_a.append(a); } // this will be used to determine do we need to // warning user about problems with network settings m_needCheckIp = 1 + valid_a.isEmpty(); // if network settings was not set yet // or they are is broken we are try to set correct ones if(addr.ip().isNull() && !valid_a.isEmpty()) addr = valid_a[0]; else if(addr.broadcast().isNull() && !valid_a.isEmpty()) addr.setBroadcast(valid_a[0].broadcast()); // are network settings corresponds any of existing interface? foreach(QNetworkAddressEntry a, valid_a) if((a.ip() == addr.ip()) && (a.broadcast() == addr.broadcast())) { m_needCheckIp = 0; break; } QChatSettings::settings()->setOption("IP", addr.ip().toString()); QChatSettings::settings()->setOption("Broadcast", addr.broadcast().toString()); QHostAddress tmp; tmp = QHostAddress(m_qsettings->value("CustomIP").toString()); if(!tmp.isNull()) addr.setIp(tmp); tmp = QHostAddress(m_qsettings->value("CustomBroadcast").toString()); if(!tmp.isNull()) addr.setBroadcast(tmp); QChatSettings::settings()->setOption("CustomIP", addr.ip().toString()); QChatSettings::settings()->setOption("CustomBroadcast", addr.broadcast().toString()); //******************************* m_qsettings->endGroup(); //*************************** profiles = m_qsettings->value("ProfileNames", QStringList()).toStringList(); str = m_qsettings->value("LastProfile" , "Default").toString(); m_geometry = m_qsettings->value("Geometry").toByteArray(); m_state = m_qsettings->value("MainWindowState").toByteArray(); m_lang = m_qsettings->value("Language").toString(); QStringList channels = m_qsettings->value("ChannelsStates", QStringList()).toStringList(); foreach(QString s, channels) m_channelsStates.insert(s, m_qsettings->value(s + "ChannelState").toByteArray()); // m_channelsStates.insert("Main", m_qsettings->value("MainChannelState").toByteArray()); if(profiles.isEmpty()) m_profiles.insert("Default", readProfile("Default")); else foreach(QString s, profiles) m_profiles.insert(s, readProfile(s)); slot_loadProfile(str); } //\***************************************************************************** UserProfile* ChatCore::readProfile(const QString & name) { UserInfo* info = new UserInfo; QChatSettings* prefs = new QChatSettings; UserProfile* profile = new UserProfile(name, prefs, info); QByteArray ba; m_qsettings->beginGroup("Profiles"); m_qsettings->beginGroup(name); prefs->loadOptions(m_qsettings); m_qsettings->beginGroup("Warnings"); m_qsettings->endGroup();// m_qsettings->beginGroup("Warnings"); m_qsettings->beginGroup("UserInfo"); info->setGender (m_qsettings->value("Gender" , 0).toInt()); info->setNickname (m_qsettings->value("NickName" , QString(QHostInfo::localHostName())).toString()); info->setLastName (m_qsettings->value("LastName" , "").toString()); info->setFirstName (m_qsettings->value("FirstName" , "").toString()); info->setSecondName (m_qsettings->value("SecondName" , "").toString()); info->setDateOfBorn (m_qsettings->value("DateOfBorn" , "").toDate ()); info->setAddress (m_qsettings->value("Address" , "").toString()); info->setHomePhone (m_qsettings->value("HomePhone" , "").toString()); info->setWorkPhone (m_qsettings->value("WorkPhone" , "").toString()); info->setMobilePhone(m_qsettings->value("MobilePhone", "").toString()); info->setE_mail (m_qsettings->value("e-mail" , "").toString()); info->setICQ (m_qsettings->value("ICQ" , "").toString()); info->setHomepage (m_qsettings->value("Homepage" , "").toString()); info->setAboutInfo (m_qsettings->value("About" , "").toString()); m_qsettings->endGroup();// m_qsettings->beginGroup("UserInfo"); info->setPhoto (m_qsettings->value("Photo" , "/").toString()); info->setPicture(m_qsettings->value("Picture", "/").toString()); m_qsettings->beginGroup("Preferences"); QColor c(Qt::red); ba = QByteArray(); ba = m_qsettings->value("MyMessagesColor", QByteArray().append(c.red()) .append(c.green()) .append(c.blue())).toByteArray(); prefs->setMyColor(QColor((quint8)ba[0], (quint8)ba[1], (quint8)ba[2])); c = QColor(Qt::gray); ba = QByteArray(); ba = m_qsettings->value("SystemMessagesColor", QByteArray().append(c.red()) .append(c.green()) .append(c.blue())).toByteArray(); prefs->setSysColor(QColor((quint8)ba[0], (quint8)ba[1], (quint8)ba[2])); c = QColor(Qt::black); ba = QByteArray(); ba = m_qsettings->value("BaseColor" , QByteArray().append(c.red()) .append(c.green()) .append(c.blue())).toByteArray(); prefs->setBaseColor(QColor((quint8)ba[0], (quint8)ba[1], (quint8)ba[2])); prefs->setSmilesThemePath (m_qsettings->value("SmilesTheme", QChatSettings::defaultSmilesDir()).toString()); prefs->setSmilesPolicy ((QChatSettings::SmilesPolicy)m_qsettings->value("SmilesPolicy", (int)QChatSettings::AlwaysUseSmilesFromSender).toInt()); prefs->setExecuteCommandOnIncomingMsg(m_qsettings->value("ExecuteCommandOnIncomingMessage", "").toString()); prefs->setNHistoryMsgs(m_qsettings->value("MaximumMessagesHistoryNumber", -1).toInt()); prefs->setHistoryReqTimeout(m_qsettings->value("MessagesHistoryRequestTimeout", 5000).toInt()); // msecs prefs->setUsersListRefreshInterval(m_qsettings->value("UsersListRefreshInterval", 60).toInt()); // secs prefs->setUsersListDeepRefreshInterval(m_qsettings->value("UsersListDeepRefreshInterval", 600).toInt()); // secs prefs->iconFormat()->restore(m_qsettings->value("UserListIconFormat", UserListIconFormat().save()).toByteArray()); prefs->setToolbarIconsSize(m_qsettings->value("ToolBarIconsSize", 22).toInt()); m_qsettings->beginGroup("MessageFilter"); prefs->messageFilter()->load(m_qsettings); m_qsettings->endGroup(); m_qsettings->endGroup();// m_qsettings->beginGroup("QChatSettings"); m_qsettings->beginGroup("Shortcuts"); QStringList all_shortcuts = m_qsettings->value("AllShortcuts").toStringList(); QStringList shortcuts; foreach(QString name, all_shortcuts) { if(!prefs->shortcutExists(name)) continue; shortcuts = m_qsettings->value(name).toStringList(); bool first = true; foreach(QString shrtct, shortcuts) { // if we have >= 1 non empty sequences for action we need to reset default sequences if(!QKeySequence(shrtct).toString().isEmpty() && first) { first = false; prefs->clearShortcut(name); } prefs->addShortcut(name, QKeySequence(shrtct)); } } m_qsettings->endGroup();// m_qsettings->beginGroup("Shortcuts"); m_qsettings->beginGroup("StatusDescriptions"); prefs->setStatusDescription(m_qsettings->value("Ready4Chat").toString(), Globals::READY4CHAT); prefs->setStatusDescription(m_qsettings->value("Free" ).toString(), Globals::FREE); prefs->setStatusDescription(m_qsettings->value("Busy" ).toString(), Globals::BUSY); prefs->setStatusDescription(m_qsettings->value("Dnd" ).toString(), Globals::DND); prefs->setStatusDescription(m_qsettings->value("Inactive" ).toString(), Globals::INACTIVE); prefs->setStatusDescription(m_qsettings->value("Away" ).toString(), Globals::AWAY); prefs->setStatusDescriptions(m_qsettings->value("DescriptionsHistory").toStringList()); m_qsettings->endGroup();// m_qsettings->beginGroup("StatusDescriptions"); m_qsettings->beginGroup("NowListening"); prefs->setNlMode(m_qsettings->value("SendWithMessage", false).toBool() + m_qsettings->value("SetInStatus" , false).toBool() * 2); m_qsettings->endGroup();// m_qsettings->beginGroup("NowListening"); m_qsettings->endGroup();// m_qsettings->beginGroup(name); m_qsettings->endGroup();// m_qsettings->beginGroup("Profiles"); return profile; } //\***************************************************************************** void ChatCore::writeProfile(const UserProfile* profile) { QChatSettings* prefs = profile->prefs(); UserInfo* info = profile->info(); QByteArray bpic; QByteArray ba; QByteArray data; QBuffer buffer; m_qsettings->beginGroup("Profiles"); m_qsettings->beginGroup(profile->name()); prefs->saveOptions(m_qsettings); m_qsettings->setValue("Photo" , info->photoFilename ()); m_qsettings->setValue("Picture" , info->pictureFilename()); m_qsettings->beginGroup("Warnings"); m_qsettings->endGroup();// m_qsettings->beginGroup("Warnings"); m_qsettings->beginGroup("UserInfo"); m_qsettings->setValue("Gender" , info->gender()); m_qsettings->setValue("NickName" , info->nickname()); m_qsettings->setValue("LastName" , info->lastName()); m_qsettings->setValue("FirstName" , info->firstName()); m_qsettings->setValue("SecondName" , info->secondName()); m_qsettings->setValue("DateOfBorn" , info->dateOfBorn()); m_qsettings->setValue("Address" , info->address()); m_qsettings->setValue("HomePhone" , info->homePhone()); m_qsettings->setValue("WorkPhone" , info->workPhone()); m_qsettings->setValue("MobilePhone" , info->mobilePhone()); m_qsettings->setValue("e-mail" , info->e_mail()); m_qsettings->setValue("ICQ" , info->icq()); m_qsettings->setValue("Homepage" , info->homepage()); m_qsettings->setValue("About" , info->aboutInfo()); m_qsettings->endGroup();// m_qsettings->beginGroup("UserInfo"); m_qsettings->beginGroup("Preferences"); ba = QByteArray(); ba = QByteArray().append(prefs->myColor().red()) .append(prefs->myColor().green()) .append(prefs->myColor().blue()); m_qsettings->setValue("MyMessagesColor" , ba); ba = QByteArray(); ba = QByteArray().append(prefs->sysColor().red()) .append(prefs->sysColor().green()) .append(prefs->sysColor().blue()); m_qsettings->setValue("SystemMessagesColor" , ba); ba = QByteArray(); ba = QByteArray().append(prefs->baseColor().red()) .append(prefs->baseColor().green()) .append(prefs->baseColor().blue()); m_qsettings->setValue("BaseColor" , ba); m_qsettings->setValue("SmilesTheme" , prefs->smilesThemePath()); m_qsettings->setValue("SmilesPolicy" , prefs->smilesPolicy()); m_qsettings->setValue("ExecuteCommandOnIncomingMessage" , prefs->executeCommandOnIncomingMsg()); m_qsettings->setValue("MaximumMessagesHistoryNumber" , prefs->nHistoryMsgs()); m_qsettings->setValue("MessagesHistoryRequestTimeout" , prefs->historyReqTimeout()); m_qsettings->setValue("UsersListRefreshInterval" , prefs->usersListRefreshInterval()); m_qsettings->setValue("UsersListDeepRefreshInterval" , prefs->usersListDeepRefreshInterval()); m_qsettings->setValue("UserListIconFormat" , prefs->iconFormat()->save()); m_qsettings->setValue("ToolBarIconsSize" , prefs->toolbarIconsSize()); m_qsettings->beginGroup("MessageFilter"); prefs->messageFilter()->save(m_qsettings); m_qsettings->endGroup(); m_qsettings->endGroup();// m_qsettings->beginGroup("QChatSettings"); m_qsettings->beginGroup("Shortcuts"); m_qsettings->setValue("AllShortcuts", QStringList(prefs->allShortcuts().keys())); QMapIterator< QString, QList > sh(prefs->allShortcuts()); QStringList shortcuts; while(sh.hasNext()) { sh.next(); shortcuts.clear(); foreach(QKeySequence seq, sh.value()) shortcuts.append(seq.toString()); m_qsettings->setValue(sh.key(), shortcuts); } m_qsettings->endGroup();// m_qsettings->beginGroup("Shortcuts"); m_qsettings->beginGroup("StatusDescriptions"); m_qsettings->setValue("Ready4Chat", prefs->statusDescription(Globals::READY4CHAT)); m_qsettings->setValue("Free" , prefs->statusDescription(Globals::FREE)); m_qsettings->setValue("Busy" , prefs->statusDescription(Globals::BUSY)); m_qsettings->setValue("Dnd" , prefs->statusDescription(Globals::DND)); m_qsettings->setValue("Inactive" , prefs->statusDescription(Globals::INACTIVE)); m_qsettings->setValue("Away" , prefs->statusDescription(Globals::AWAY)); m_qsettings->setValue("DescriptionsHistory", prefs->statusDescriptions()); m_qsettings->endGroup();// m_qsettings->beginGroup("StatusDescriptions"); m_qsettings->beginGroup("NowListening"); m_qsettings->setValue("SendWithMessage", prefs->nlMode() & 1); m_qsettings->setValue("SetInStatus" , prefs->nlMode() & 2); m_qsettings->setValue("Format" , prefs->strOption("NLFormat")); m_qsettings->endGroup();// m_qsettings->beginGroup("NowListening"); m_qsettings->endGroup();// m_qsettings->beginGroup(profile->name()); m_qsettings->endGroup();// m_qsettings->beginGroup("Profiles"); } //\***************************************************************************** qchat-0.3/src/edituserinfodlg.h0000644000076500017500000001006410765566704015343 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef EDITUSERINFODLG_H #define EDITUSERINFODLG_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class PixLabel; class UserInfo; /** @author Anistratov Oleg */ class EditUserInfoDlg : public QDialog { Q_OBJECT private: QString m_profileName; quint64 m_userUid; QGridLayout* m_grid; QLineEdit* m_lastNameEdit; QLineEdit* m_firstNameEdit; QLineEdit* m_secondNameEdit; QLineEdit* m_nickNameEdit; QLineEdit* m_homePhoneEdit; QLineEdit* m_workPhoneEdit; QLineEdit* m_mobilePhoneEdit; QLineEdit* m_e_mailEdit; QLineEdit* m_homepageEdit; QLineEdit* m_icqEdit; QDateEdit* m_dateOfBornEdit; QLineEdit* m_addressEdit; QTextEdit* m_aboutInfoEdit; QPushButton* m_applyBtn; QPushButton* m_okBtn; QPushButton* m_cancelBtn; PixLabel* m_setPhoto; PixLabel* m_setPic; QComboBox* m_genderCmbx; QLabel* m_statusLab; QLineEdit* mw_statusDescription; QString m_photoFilename; QString m_pictureFilename; bool m_edited; bool m_readOnly; QLabel* m_applyLab; QLabel* m_okLab; QLabel* m_cancelLab; QLabel* m_photoLab; QLabel* m_pictureLab; QLabel* m_nickLab; QLabel* m_lastNameLab; QLabel* m_firstNameLab; QLabel* m_secondNameLab; QLabel* m_bornLab; QLabel* m_addressLab; QLabel* m_homePhoneLab; QLabel* m_workPhoneLab; QLabel* m_mobilePhoneLab; QLabel* m_emailLab; QLabel* m_icqLab; QLabel* m_homepageLab; QLabel* m_aboutLab; QLabel* m_genderLab; public: EditUserInfoDlg(QWidget *parent = 0); ~EditUserInfoDlg(); void retranslate(); void setReadOnly(bool); bool readOnly () const {return m_readOnly;}; quint64 userUid () const {return m_userUid;} void toggleVisible(){if(isHidden()) show(); else hide();} public slots: void slot_sendInfo (); void slot_edited () {m_applyBtn->setEnabled(m_edited = true);} void slot_notEdited() {m_applyBtn->setEnabled(m_edited = false);} void slot_cancel (); void slot_loadInfo (const UserInfo*); void slot_accept (); protected: void closeEvent(QCloseEvent * ev) { slot_cancel(); ev->accept(); } void changeEvent(QEvent *ev) { if(ev->type() == QEvent::LanguageChange) retranslate(); else QDialog::changeEvent(ev); } signals: void infoChanged (); void nickNameChanged(const QString &); void wantChangeNickname(const QString &); }; #endif qchat-0.3/src/treeitem.h0000644000076500017500000000566211004454354013762 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef TREEITEM_H #define TREEITEM_H #include #include #include /** @author Anistratov Oleg */ class TreeItem { private: QMap< int, QList > m_data; TreeItem* m_parent; QList m_children; QString m_name; QList m_hiddenColumns; QVector m_columns; static int m_sortingOrder; static int m_sortingColumn; public: TreeItem(const QList &data, TreeItem *parent = 0, QString = ""); virtual ~TreeItem(); int visibleCols(bool, int) const; const TreeItem* const child(int row) const; void appendChild(TreeItem* child); int childCount() const; int columnCount() const; int row() const; virtual QVariant data(int column, int role = Qt::DisplayRole, bool = 0) const; TreeItem *parent() const {return m_parent;} QList* children(){return &m_children;} const QString& name() const {return m_name;} void setParent(TreeItem* parent){m_parent = parent;} void setData (const QList &data, int role = Qt::DisplayRole); void setData (int column, const QVariant &data, int role = Qt::DisplayRole); QList takeChildren(); void deleteChild(TreeItem*); // void insertColumn(int after, const QVariant&); void hideColumn (int column); void showColumn (int column); /// returns real number of column with visible number @param column int realColumn(int column) const; static void setSortingOrder(int theValue){m_sortingOrder = theValue;} static int sortingOrder() {return m_sortingOrder;} static void setSortingColumn(int theValue){m_sortingColumn = theValue;} static int sortingColumn() {return m_sortingColumn;} virtual void sortChildren(int column, Qt::SortOrder order); static bool LessThan(TreeItem* i1, TreeItem* i2); }; #endif qchat-0.3/src/formattingtoolbar.cpp0000644000076500017500000001345311002616351016224 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "formattingtoolbar.h" #include "colorchooser.h" #include "qchaticon.h" #include #include #include #include #include FormattingToolBar::FormattingToolBar(QWidget* parent) : QToolBar(parent), m_tableRows(0), m_tableCols(0) { QFontDatabase db; QGridLayout* grid; m_fontFamilyCmbx = new QFontComboBox(this); m_fontSizeCmbx = new QComboBox(this); m_textStyleCmbx = new QComboBox(this); m_colorPicker = new ColorPicker; m_tableSizeDlg = new QDialog(0); grid = new QGridLayout(m_tableSizeDlg); m_enterTableSizeLab = new QLabel(m_tableSizeDlg); m_rowsLab = new QLabel(m_tableSizeDlg); m_colsLab = new QLabel(m_tableSizeDlg); // creating table size dlg // ************************ QPushButton* btn = new QPushButton(tr("Ok"), m_tableSizeDlg); QSpinBox* rows = new QSpinBox(m_tableSizeDlg); QSpinBox* cols = new QSpinBox(m_tableSizeDlg); grid->addWidget(m_enterTableSizeLab, 0, 0, 1, 2); grid->addWidget(m_rowsLab , 1, 0); grid->addWidget(m_colsLab , 1, 1); grid->addWidget(rows , 2, 0); grid->addWidget(cols , 2, 1); grid->addWidget(btn , 3, 0, 1, 2); connect(rows, SIGNAL(valueChanged(int)), this, SLOT(setTableRows (int))); connect(cols, SIGNAL(valueChanged(int)), this, SLOT(setTableCols(int))); connect(btn , SIGNAL(clicked()) , this, SLOT(createTable())); connect(btn , SIGNAL(clicked()) , m_tableSizeDlg, SLOT(accept())); // ************************ // FIXME disabling lists while current verion of qt4.3 have a problems with images in lists // addWidget(m_textStyleCmbx); m_textStyleCmbx->hide(); addWidget(m_fontFamilyCmbx); addWidget(m_fontSizeCmbx); (m_setBoldAct = addAction(tr("Bold")))->setCheckable(true); (m_setItalicAct = addAction(tr("Italic")))->setCheckable(true); (m_setUnderlineAct = addAction(tr("Underline")))->setCheckable(true); m_insertTableAct = addAction(tr("Insert Table")); addWidget(m_colorPicker); m_textStyleCmbx->addItem("Standard"); m_textStyleCmbx->addItem("Bullet List (Disc)"); m_textStyleCmbx->addItem("Bullet List (Circle)"); m_textStyleCmbx->addItem("Bullet List (Square)"); m_textStyleCmbx->addItem("Ordered List (Decimal)"); m_textStyleCmbx->addItem("Ordered List (Alpha lower)"); m_textStyleCmbx->addItem("Ordered List (Alpha upper)"); connect(m_textStyleCmbx, SIGNAL(activated(int)), this, SIGNAL(wantSetTextStyle(int))); m_fontSizeCmbx->setEditable(true); foreach(int sz, db.standardSizes()) m_fontSizeCmbx->addItem(QString::number(sz)); m_fontSizeCmbx->setCurrentIndex(m_fontSizeCmbx->findText(QString::number(QApplication::font().pointSize()))); connect(m_setBoldAct , SIGNAL(triggered(bool)), this, SIGNAL(wantSetBold(bool))); connect(m_setItalicAct , SIGNAL(triggered(bool)), this, SIGNAL(wantSetItalic(bool))); connect(m_setUnderlineAct, SIGNAL(triggered(bool)), this, SIGNAL(wantSetUnderline(bool))); connect(m_insertTableAct , SIGNAL(triggered(bool)), m_tableSizeDlg, SLOT(exec())); connect(m_colorPicker , SIGNAL(colorChanged(QColor)), this, SIGNAL(wantSetColor(QColor))); connect(m_fontFamilyCmbx, SIGNAL(activated(QString)) , this, SIGNAL(wantSetFontFamily(QString))); connect(m_fontSizeCmbx , SIGNAL(activated(QString)) , this, SIGNAL(wantSetFontSize(QString))); retranslate(); setIcons(); } FormattingToolBar::~FormattingToolBar() { qDebug("[~FormattingToolBar]"); delete m_tableSizeDlg; } void FormattingToolBar::currentCharFormatChanged(const QTextCharFormat & fmt) { m_fontFamilyCmbx->setCurrentIndex(m_fontFamilyCmbx->findText(QFontInfo(fmt.font()).family())); m_fontSizeCmbx ->setCurrentIndex(m_fontSizeCmbx ->findText(QString::number(fmt.font().pointSize()))); m_setBoldAct->setChecked(fmt.font().bold()); m_setItalicAct->setChecked(fmt.font().italic()); m_setUnderlineAct->setChecked(fmt.font().underline()); m_colorPicker->setColor(fmt.foreground().color()); } void FormattingToolBar::retranslate() { m_setBoldAct ->setText(tr("Bold")); m_setItalicAct ->setText(tr("Italic")); m_setUnderlineAct ->setText(tr("Underline")); m_enterTableSizeLab->setText(tr("Enter table size")); m_rowsLab ->setText(tr("Rows count:")); m_colsLab ->setText(tr("Columns count:")); m_tableSizeDlg ->setWindowTitle(tr("Insert Table")); } void FormattingToolBar::setIcons() { m_setBoldAct ->setIcon(QChatIcon::icon("format-text-bold")); m_setItalicAct ->setIcon(QChatIcon::icon("format-text-italic")); m_setUnderlineAct->setIcon(QChatIcon::icon("format-text-underline")); m_insertTableAct ->setIcon(QChatIcon::icon("insert-table")); } qchat-0.3/src/login2serverdlg.h0000644000076500017500000000461211004415345015243 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef LOGIN2SERVERDLG_H #define LOGIN2SERVERDLG_H #include #include #include #include #include #include #include #include "qchatsettings.h" /** @author Anistratov Oleg */ class Login2ServerDlg : public QDialog { Q_OBJECT private: // QLineEdit* m_ipEdit; // QLineEdit* m_loginEdit; QComboBox* m_ipCmbx; QComboBox* m_loginCmbx; QPushButton* m_loginBtn; QPushButton* m_abortBtn; QLabel* m_ipLab; QLabel* m_loginLab; QStringList* m_lastServers; QStringList* m_lastLogins; QLabel* m_descriptionLab; bool m_finished; public: Login2ServerDlg(QStringList*, QStringList*, QWidget *parent = 0, const QString& = "", const QString& = ""); ~Login2ServerDlg(); void retranslate(); protected: void changeEvent(QEvent *ev) { if(ev->type() == QEvent::LanguageChange) retranslate(); else QWidget::changeEvent(ev); } public slots: void slot_login(); void abort(); void loginRejected(const QString&); void loginAccepted(const QString&); void loginFinished(int, const QString&); signals: void wantLogin(const QHostAddress&, const QString&); void wantAbort(); void loginSuccessful(); }; #endif qchat-0.3/src/smilelabel.h0000644000076500017500000000411710767206572014263 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SMILELABEL_H #define SMILELABEL_H #include #include #include #include #include /** @author Anistratov Oleg */ class SmileLabel : public QLabel { Q_OBJECT private: QMovie* m_movie; QString m_filename; QStringList m_smileStrings; bool m_inited; bool m_selected; public: SmileLabel(QWidget *parent = 0); ~SmileLabel(); bool inited() const {return m_inited;} bool load (const QString &); void setSmileText(const QStringList & list); void setFilename (const QString & fname) { m_inited = (!(m_filename = fname).isEmpty() && !m_smileStrings.isEmpty () && m_movie->isValid()); } int pixmapWidth(); int pixmapHeight(); void unselect(); bool selected() const {return m_selected;} protected: void mousePressEvent(QMouseEvent* ev); void mouseMoveEvent (QMouseEvent* ev); signals: void clicked(const QString &); void hovered(); }; #endif qchat-0.3/src/userlisticonformat.h0000644000076500017500000000741210766635405016107 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERLISTICONFORMAT_H #define USERLISTICONFORMAT_H #include #include /** @author Anistratov Oleg */ class UserListIconFormat { private: int m_totalWidth; int m_totalHeight; int m_statusWidth; int m_statusHeight; int m_statusXoffset; int m_statusYoffset; int m_genderWidth; int m_genderHeight; int m_genderXoffset; int m_genderYoffset; int m_avatarWidth; int m_avatarHeight; int m_avatarXoffset; int m_avatarYoffset; QString m_text; public: UserListIconFormat(int = 32 + 32 + 5 , int = 33, int = 22, int = 22, int = 10, int = 10, int = 32, int = 32, int = 0, int = 0, int = 32, int = 32, int = 0, int = 0); ~UserListIconFormat(); int totalWidth () const {return m_totalWidth;} int totalHeight () const {return m_totalHeight;} int statusWidth () const {return m_statusWidth;} int statusHeight () const {return m_statusHeight;} int statusXoffset() const {return m_statusXoffset;} int statusYoffset() const {return m_statusYoffset;} int genderWidth () const {return m_genderWidth;} int genderHeight () const {return m_genderHeight;} int genderXoffset() const {return m_genderXoffset;} int genderYoffset() const {return m_genderYoffset;} int avatarWidth () const {return m_avatarWidth;} int avatarHeight () const {return m_avatarHeight;} int avatarXoffset() const {return m_avatarXoffset;} int avatarYoffset() const {return m_avatarYoffset;} void setTotalWidth (int theValue){m_totalWidth = theValue;} void setTotalHeight (int theValue){m_totalHeight = theValue;} void setStatusWidth (int theValue){m_statusWidth = theValue;} void setStatusHeight (int theValue){m_statusHeight = theValue;} void setStatusXoffset(int theValue){m_statusXoffset = theValue;} void setStatusYoffset(int theValue){m_statusYoffset = theValue;} void setGenderWidth (int theValue){m_genderWidth = theValue;} void setGenderHeight (int theValue){m_genderHeight = theValue;} void setGenderXoffset(int theValue){m_genderXoffset = theValue;} void setGenderYoffset(int theValue){m_genderYoffset = theValue;} void setAvatarWidth (int theValue){m_avatarWidth = theValue;} void setAvatarHeight (int theValue){m_avatarHeight = theValue;} void setAvatarXoffset(int theValue){m_avatarXoffset = theValue;} void setAvatarYoffset(int theValue){m_avatarYoffset = theValue;} QByteArray save() const; bool restore(const QByteArray&); void setText(const QString& theValue){m_text = theValue;} QString text() const {return m_text;} }; #endif qchat-0.3/src/animatedsmile.h0000644000076500017500000000366110777134707014772 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef ANIMATEDSMILE_H #define ANIMATEDSMILE_H #include #include #include #include /** @author Anistratov Oleg */ class AnimatedSmile : public QObject { Q_OBJECT private: QMovie* m_smile; QTextDocument* m_document; int m_pos; QString m_filename; bool m_running; static QMap m_allSmiles; public: AnimatedSmile(QObject *parent = 0); ~AnimatedSmile(); void init(int, const QString&, QTextDocument*); void start(){m_smile->start(); m_running = true; nextFrame();} void stop(){m_smile->stop(); m_running = false;} void setPaused(bool b){/*m_smile->setPaused(b);*/ m_running = !b;} bool animated(){return true;} void pauseIfHidden(int, int); public slots: void nextFrame(); }; #endif qchat-0.3/src/globals.h0000755000076500017500000000767411004400602013562 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef GLOBALS_H #define GLOBALS_H #include "qchatsettings.h" #include "logwgt.h" #include #include #include #include #include #define DEBUG 0 class UserInfo; // const unsigned short MAX_PACKET_LEN = 10000; const unsigned short MAX_PACKET_LEN = 65535 - 1024; //\***************************************************************************** struct QC_DatagramHeader { unsigned short programVersion; unsigned short protocolVersion; unsigned long long dest_ip; unsigned long long src_ip; unsigned char type; /// tip paketa(iz enum DataType) unsigned long id; /// id paketa(dlya fragmentirovannyh paketov),esli 0,to paket fragment odin unsigned long num; /// nomer paketa (pakety s dannymi nachinayutsya s 1(pervogo:) !!! unsigned long long tm; /// vremya otpravki unsigned long long receive_tm;/// vremya polucheniya unsigned long chnnl_id;///id kanala, v kotryi poslano soobsch. etc unsigned char comp_name_len; unsigned char name_len; unsigned long msg_len; unsigned long parametrs_len; QString name; QString comp_name; QString msg; QString versionName; QColor color; quint16 status; QByteArray parametrs;/// soderzhit razlichnye dopolnitel'nye parametry bool isHtml; QC_DatagramHeader(){} }; //***************************************************************************** class Globals { public: static const uint VersionID; static const uint Revision; static const char* VersionsTable[15]; static QString VersionStr; static QString StatusStr[7]; static QString m_profileName; static QChatSettings* m_settings; static UserInfo* m_info; static LogWgt* m_log; static void addMessage(const QString & str, const QColor & color = QColor(Qt::black)) {if(m_log) m_log->addMessage(str, color);} static void addInfo (const QString & str) {if(m_log) m_log->addInfo(str);} static void addError (const QString & str) {if(m_log) m_log->addError(str);} Globals(){} ~Globals(){} static quint32 localIp(QHostAddress* br); static QList validInterfeices(); static uint localhost(){if(QChatSettings::settings()->mode() == QChatSettings::Server) return 1; return 0x7f000001;} enum StatusID{BUSY = 0, FREE = 1, READY4CHAT = 2, DND = 3, INACTIVE = 4, AWAY = 5, INVISIBLE = 6}; }; bool isSystemMsg(quint16 type); char* datadup(const char* src, int n); unsigned long long str2ULL(const char* str); unsigned long str2UL (const char* str); unsigned short str2US (const char* str); int catULL2str(char* str, unsigned long long num); int catUL2str (char* str, unsigned long num); int catUS2str (char* str, unsigned short num); #endif qchat-0.3/src/src.pro0000755000076500017500000001130011004454531013266 0ustar owerower HEADERS += chatwgt.h \ channelwgt.h \ message.h \ msghistory.h \ userinfo.h \ addchanneldialog.h \ userslist.h \ chattextwgt.h \ edituserinfodlg.h \ pixlabel.h \ userslistwgt.h \ userwgt.h \ inputtextwgt.h \ largedatagram.h \ receiverthread.h \ senderthread.h \ largedatagramout.h \ logwgt.h \ singlemessagewgt.h \ filetransferwgt.h \ preferencesdlg.h \ colorlabel.h \ globals.h \ chatcore.h \ smileswgt.h \ picturescrollarea.h \ statuseditwgt.h \ nlamarok.h \ userprofile.h \ smilelabel.h \ qchat.h \ userstatistics.h \ usersstatisticswgt.h \ usersstatisticsmodel.h \ qchattrayicon.h \ messagewithcheckbox.h \ singlemsgshistory.h \ singlemsgshistoryview.h \ aboutqchat.h \ pluginsinterfaces.h \ qchatsocket.h \ tcpreceiverthread.h \ login2serverdlg.h \ textformattingwgt.h \ inputrichtextwgt.h \ colorchooser.h \ qchateventfilter.h \ formattingtoolbar.h \ qchaticon.h \ userlisticonformat.h \ qchatmainwindow.h \ userlisticonconfigurewgt.h \ iplisteditor.h \ shortcutgrabber.h \ shortcutbutton.h \ shortcutseditor.h \ singlemsgshistorymodel.h \ treeitem.h \ messagetreeitem.h \ treemodel.h \ singlemessage.h \ qchatsettings.h \ pluginmanager.h \ plugin.h \ animatedsmile.h \ textbrowser.h \ messagefilter.h \ filtrationrule.h \ filtrationruleeditor.h \ messagefiltereditor.h \ abstractprotocol.h \ protocolversion3.h \ protocolversion4.h \ option.h \ abstractchatcore.h SOURCES += main.cpp \ chatwgt.cpp \ channelwgt.cpp \ message.cpp \ msghistory.cpp \ userinfo.cpp \ addchanneldialog.cpp \ userslist.cpp \ chattextwgt.cpp \ edituserinfodlg.cpp \ pixlabel.cpp \ userslistwgt.cpp \ userwgt.cpp \ inputtextwgt.cpp \ chatcore_settings.cpp \ largedatagram.cpp \ receiverthread.cpp \ senderthread.cpp \ largedatagramout.cpp \ logwgt.cpp \ singlemessagewgt.cpp \ filetransferwgt.cpp \ preferencesdlg.cpp \ colorlabel.cpp \ globals.cpp \ chatcore.cpp \ smileswgt.cpp \ picturescrollarea.cpp \ statuseditwgt.cpp \ nlamarok.cpp \ userprofile.cpp \ smilelabel.cpp \ qchat.cpp \ userstatistics.cpp \ usersstatisticswgt.cpp \ usersstatisticsmodel.cpp \ qchattrayicon.cpp \ messagewithcheckbox.cpp \ singlemsgshistory.cpp \ singlemsgshistoryview.cpp \ aboutqchat.cpp \ qchatsocket.cpp \ tcpreceiverthread.cpp \ login2serverdlg.cpp \ textformattingwgt.cpp \ inputrichtextwgt.cpp \ colorchooser.cpp \ qchateventfilter.cpp \ formattingtoolbar.cpp \ qchaticon.cpp \ userlisticonformat.cpp \ qchatmainwindow.cpp \ userlisticonconfigurewgt.cpp \ iplisteditor.cpp \ shortcutgrabber.cpp \ shortcutbutton.cpp \ shortcutseditor.cpp \ singlemsgshistorymodel.cpp \ treeitem.cpp \ messagetreeitem.cpp \ treemodel.cpp \ singlemessage.cpp \ qchatsettings.cpp \ pluginmanager.cpp \ plugin.cpp \ animatedsmile.cpp \ textbrowser.cpp \ messagefilter.cpp \ filtrationrule.cpp \ filtrationruleeditor.cpp \ messagefiltereditor.cpp \ abstractprotocol.cpp \ protocolversion3.cpp \ protocolversion4.cpp \ option.cpp \ abstractchatcore.cpp TRANSLATIONS = translations/qchat_uk.ts \ translations/qchat_ru.ts \ translations/qchat_pl.ts \ translations/qchat_es.ts \ translations/qchat_de.ts \ translations/qchat_sr.ts ; RESOURCES = images.qrc CONFIG += release \ warn_on QT += network xml \ svg TEMPLATE = app TARGET = bin/qchat unix { bin.path = /usr/bin/ bin.files = bin/* icons.path = /usr/share/qchat/icons/ icons.files = icons/* statusicons.path = /usr/share/qchat/icons/status statusicons.files = icons/status/* emoticons.path = /usr/share/qchat/emoticons/ emoticons.files = emoticons/* translations.path = /usr/share/qchat/translations translations.files = translations/*.qm stylesheets.path = /usr/share/qchat/stylesheets stylesheets.files = stylesheets/* INSTALLS += bin translations stylesheets emoticons icons statusicons system(mkdir bin/ 2>/dev/null) system(touch bin/qchat) system(chmod 755 bin/qchat) } CONFIG -= debug qchat-0.3/src/userlisticonconfigurewgt.h0000644000076500017500000000527410766635332017325 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERLISTICONCONFIGUREWGT_H #define USERLISTICONCONFIGUREWGT_H #include #include #include #include class UserListIconFormat; #include "userlisticonformat.h" /** @author Anistratov Oleg */ class UserListIconConfigureWgt : public QWidget { Q_OBJECT private: UserListIconFormat m_format; QLabel* m_textLab; QLabel* m_totalLab; QLabel* m_genderLab; QLabel* m_statusLab; QLabel* m_avatarLab; QLabel* m_heightLab; QLabel* m_widthLab; QLabel* m_xOffsetLab; QLabel* m_yOffsetLab; // QSpinBox* m_spacingSpbx; QSpinBox* m_totalWidthSpbx; QSpinBox* m_totalHeightSpbx; QSpinBox* m_genderWidthSpbx; QSpinBox* m_genderHeightSpbx; QSpinBox* m_statusWidthSpbx; QSpinBox* m_statusHeightSpbx; QSpinBox* m_avatarWidthSpbx; QSpinBox* m_avatarHeightSpbx; QSpinBox* m_genderXSpbx; QSpinBox* m_genderYSpbx; QSpinBox* m_statusXSpbx; QSpinBox* m_statusYSpbx; QSpinBox* m_avatarXSpbx; QSpinBox* m_avatarYSpbx; QLineEdit* m_textEdit; public: UserListIconConfigureWgt(QWidget *parent = 0, const UserListIconFormat& = UserListIconFormat()); ~UserListIconConfigureWgt(); void retranslate(); void setFormat(const UserListIconFormat&); public slots: void changeFormat(); signals: void formatChanged(const UserListIconFormat&); }; #endif qchat-0.3/src/colorchooser.h0000644000076500017500000000401410764575614014652 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef COLORCHOOSER_H #define COLORCHOOSER_H #include #include #include #include #include #include #include class ColorLabel; /** @author Anistratov Oleg */ class ColorPicker : public QFrame { Q_OBJECT private: QGridLayout* grid ; QColor m_color; QToolButton* m_button; QList m_baseColors; QList m_colors; QList m_colorLabels; int m_colorsNum; int m_maxColors; private: void changeRows(); public: ColorPicker(QWidget *parent = 0); ~ColorPicker(){}; void redrawLabels(); void setButtonColor(); protected: void wheelEvent(QWheelEvent*); public slots: void selectColorDialog(); void colorClicked(); void setColorsNum(int); void setColor(QColor color); signals: void colorChanged(QColor); }; #endif qchat-0.3/src/iplisteditor.h0000644000076500017500000000367310767053162014666 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef IPLISTEDITOR_H #define IPLISTEDITOR_H #include #include #include #include #include #include /** @author Anistratov Oleg */ class IpListEditor : public QWidget { Q_OBJECT private: QCheckBox* m_useIpListChbx; QPushButton* m_showEditorBtn; QTextEdit* m_ipListEdit; QPushButton* m_okBtn; QPushButton* m_cancelBtn; QDialog* m_editorDlg; public: void retranslate(); public: IpListEditor(QWidget *parent = 0); ~IpListEditor(); protected: void changeEvent(QEvent *ev) { if(ev->type() == QEvent::LanguageChange) retranslate(); else QWidget::changeEvent(ev); } public slots: void init(); void showEditor(); void applyChanges(); void discardChanges(); void setUseIpList(int); }; #endif qchat-0.3/src/pluginmanager.cpp0000644000076500017500000000711311002647771015326 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "pluginmanager.h" #include #include #include #include "pluginsinterfaces.h" #include "plugin.h" #include "qchatsettings.h" PluginManager::PluginManager(QObject *parent) : QObject(parent) { } PluginManager::~PluginManager() { } void PluginManager::getPlugins() { QStringList dirs; QDir pluginsDir; #if defined(Q_OS_LINUX) dirs.append(QCoreApplication::applicationDirPath() + "/../lib/qchat/plugins"); #else dirs.append(QCoreApplication::applicationDirPath() + "/plugins"); #endif dirs.append(QChatSettings::settings()->settingsDir() + "/plugins"); QChatBasicPlugin* plug; QChatWidgetPlugin* wgt; qDebug("[PluginManager::getPlugins]: Loading plugins...\n"); foreach(QString d, dirs) { pluginsDir.setPath(d); foreach(QString fileName, pluginsDir.entryList(QDir::Files)) { QString path = pluginsDir.absoluteFilePath(fileName); QPluginLoader* loader = new QPluginLoader(path); Plugin* info = new Plugin; QObject* plugin = loader->instance(); plug = qobject_cast(plugin); wgt = qobject_cast(plugin); qDebug("[PluginManager::getPlugins]: loading: %s\n", path.toLocal8Bit().data()); if(wgt) { plug = wgt; info->setType(Plugin::Widget); } if(plug || wgt) { info->setPath(path); info->setName(plug->name()); info->setPlugin(loader); connect(plugin, SIGNAL(sendData(const QString &, const QMap &, quint64, AbstractChatCore::DataType, const QString &, uint, const QString &)), this, SIGNAL (sendData(const QString &, const QMap &, quint64, AbstractChatCore::DataType, const QString &, uint, const QString &))); qDebug("[PluginManager::getPlugins]: loaded: %s(%s)\n", fileName.toLocal8Bit().data(), plug->name().toLocal8Bit().data()); // delete plugin; // loader->unload(); m_plugins.append(info); } } } } Plugin * PluginManager::getPluginByPath(const QString & path) { foreach(Plugin* pl, plugins()) if(pl->path() == path) return pl; return NULL; } void PluginManager::load(const QString & path) { Plugin* plugin = getPluginByPath(path); if(plugin) plugin->load(); } void PluginManager::unload(const QString & path) { Plugin* plugin = getPluginByPath(path); if(plugin) plugin->unload(); } qchat-0.3/src/abstractprotocol.cpp0000644000076500017500000000225211002154512016043 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "abstractprotocol.h" AbstractProtocol::AbstractProtocol() { } AbstractProtocol::~AbstractProtocol() { } qchat-0.3/src/filetransferwgt.h0000644000076500017500000000616510772536453015365 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef FILETRANSFERWGT_H #define FILETRANSFERWGT_H #include #include #include #include #include #include #include #include /** @author Anistratov Oleg */ class FileTransferWgt : public QWidget { Q_OBJECT private: QGridLayout* m_grid; QPushButton* m_cancelBtn; QPushButton* m_acceptBtn; QPushButton* m_rejectBtn; QProgressBar* m_progress; QCheckBox* m_autoCloseChbx; quint16 m_id; quint64 m_uid; // uid of sender or receiver quint64 m_ip; // ip of sender or receiver QString m_filename; bool m_finished; bool m_receiving; // esli false - to otobrazhaet peredachu faila bool m_accepted; QLabel* m_filenameLab; QString m_userName; public: FileTransferWgt(const QString &, bool receiving = 0, QWidget *parent = 0); ~FileTransferWgt(); void retranslate(); void init(); void setUserName(const QString& name){m_userName = name;} void setID (quint16 id ){m_id = id;} void setIp (quint64 ip ){m_ip = ip;} void setUid (quint64 uid){m_uid = uid;} bool cmp (quint16 id, quint64 uid) const {return (id == m_id && uid == m_uid);} public slots: void slot_selfDestroy(); void slot_setProgress(quint8, quint16, quint64); void slot_accept(); void slot_reject(); void slot_kill (quint16 id){if(id == m_id) slot_selfDestroy();} void slot_cancelledByReceiver(quint16 id); void slot_cannotSend (quint16 id); void slot_rejectedByReceiver (quint16 id); void slot_cancelledBySender (quint16 id, quint64 ip); void slot_receivingTimeout (quint16 id, quint64 ip); void slot_sendingTimeout (quint16 id); protected: void closeEvent(QCloseEvent* ev) { slot_reject(); ev->accept(); } signals: void accepted(const QString &, quint16, quint64); void rejected(quint16, quint64, int); void cancel (quint16); }; #endif qchat-0.3/src/addchanneldialog.cpp0000644000076500017500000000413210665277442015744 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "addchanneldialog.h" #include AddChannelDlg::AddChannelDlg(QWidget *parent) : QDialog(parent) { QGridLayout* grid = new QGridLayout(this); m_okBtn = new QPushButton(this); m_cancelBtn = new QPushButton(this); m_editChannelName = new QLineEdit (this); m_lab = new QLabel (this); grid->addWidget(m_lab , 0, 0); grid->addWidget(m_editChannelName , 0, 1); grid->addWidget(m_okBtn , 1, 0); grid->addWidget(m_cancelBtn , 1, 1); setModal(false); connect(m_okBtn , SIGNAL(clicked()), this, SLOT(setValues())); connect(m_cancelBtn, SIGNAL(clicked()), this, SLOT(reject ())); retranslate(); } void AddChannelDlg::setValues() { hide(); if(!m_editChannelName->text().isEmpty()) emit dataAccepted(m_editChannelName->text()); accept(); } void AddChannelDlg::retranslate() { setWindowTitle(tr("Add Channel")); m_okBtn ->setText(tr("&Ok" )); m_cancelBtn ->setText(tr("&Cancel")); m_lab ->setText(tr("Channel's Name:")); } qchat-0.3/src/largedatagram.h0000644000076500017500000001051011001414117014711 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef LARGEDATAGRAM_H #define LARGEDATAGRAM_H #include #include #include #include #include "globals.h" /** @author Anistratov Oleg */ class LargeDatagram : public QObject { Q_OBJECT private: quint8 m_remain; // pokazyvaet skol'ko protsentov ostalos' peredat' QString m_filename; QFile m_file; bool m_isFile; bool m_fileInited; bool m_inited; QString m_senderName; QString m_senderCompName; quint16 m_programVersion; quint16 m_protocolVersion; quint64 m_destIP; quint64 m_srcIP; quint8 m_packetType; quint32 m_datagramID; quint32 m_channelType; quint64 m_totalSize; quint32 m_totalFragments; quint16 m_fragmentSize;// razmery fragmentov quint16 m_lastFragmentSize;// razmer poslednego fragmenta /// после того, как будет отправлен запрос на пересылку недостающих фрагментов, необходумо будет знать /// после прихода какого фрагмента, в случае необходимости, посылать повторный запрос на пересылку фрагментов /// поэтому m_lastFragmentNum наибольший номер среди недостающих фрагментов quint32 m_lastFragmentNum; quint64 m_firstFragmentTime; quint64 m_finalFragmentTime; quint64 m_currentSize; quint32 m_fragmentsRemain; char* m_fragments; // pokazyvaet kakie fragmenty polucheny, a kakie - net char* m_data; /// запрашивает недостающие фрагменты, если ничего не было получено в течение m_requestInterval миллисекунд QTimer* m_requestTimer; /// если ничего не было получено в течение m_selfDestroyInterval миллисекунд - происходит уничтожение объекта QTimer* m_selfDestroyTimer; quint32 m_requestInterval; quint32 m_selfDestroyInterval; uint m_destUid; public: LargeDatagram(quint64 IP, quint32 ID, QObject* parent = 0); ~LargeDatagram(); const QString & filename() const {return m_filename;} quint16 id() const {return m_datagramID;} quint64 ip() const {return m_srcIP;} bool cmp(quint64 IP, quint32 ID) const {return (IP == m_srcIP && ID == m_datagramID);} bool complete() const {return (m_inited && !m_fragmentsRemain);} void initDatagram (const char* dtgrm, quint32 dtgrm_len); void addFragment (const char* dtgrm, quint32 dtgrm_len); void addFileFragment (const char* dtgrm, quint32 dtgrm_len); void allocateSpace(); void clear(); bool fillHeader(QC_DatagramHeader*); public slots: void slot_fragmentsRequest (); void slot_selfDestroy (); void slot_initFile(const QString & filename); uint destUid() const {return m_destUid;} signals: void completed (LargeDatagram*); void wantFragments (char*, quint32, quint32, quint64); void wantDie (LargeDatagram*); void percentsRemain(quint8, quint16, quint64); void readyReceive (quint16, quint64); }; #endif qchat-0.3/src/userslistwgt.h0000644000076500017500000000471010770010667014720 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USERSLISTWGT_H #define USERSLISTWGT_H #include #include #include #include #include class UserWgt; class UserListIconFormat; #include "userinfo.h" /** @author Anistratov Oleg */ class UsersListWgt : public QListWidget { Q_OBJECT friend class ChannelWgt; private: QMenu* m_menu; QAction* m_singleMessageAct; QAction* m_showInfoAct; QAction* m_sendFileAct; QAction* m_privateChatAct; public: UsersListWgt (QWidget *parent = 0); ~UsersListWgt(); void retranslate(); void hideUser(UserWgt*); void addUser (UserWgt*); void clear (); public slots: void send_itemDoubleClicked(QListWidgetItem* item); void slot_singleMessage(); void slot_sendFile (); void slot_privateChat (); signals: void itemDoubleClicked(UserWgt*); void singleMessage (const QString &, quint64, bool); void wantPrivateChat (const QString &, quint64); void wantSendFile (quint64); protected: void mousePressEvent (QMouseEvent * ev); void changeEvent(QEvent *ev) { if(ev->type() == QEvent::LanguageChange) retranslate(); else QListWidget::changeEvent(ev); } void dropEvent(QDropEvent* event); void dragEnterEvent ( QDragEnterEvent * event ); void dragMoveEvent(QDragMoveEvent *event); }; #endif qchat-0.3/src/main.cpp0000755000076500017500000000644511004455136013425 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include #include #include #include #include #include #if defined(Q_OS_WIN) # include #endif #include "qchat.h" #include "globals.h" #include "qchatsocket.h" #include #include #include "userinfo.h" void myMessageOutput(QtMsgType type, const char *msg) { switch (type) { case QtDebugMsg: // fprintf(stdout, "Debug: %s\n", msg); break; case QtWarningMsg: fprintf(stderr, "Warning: %s\n", msg); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s\n", msg); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s\n", msg); } } int main(int argc, char *argv[]) { #if defined(Q_OS_WIN) bool custom_style = false; for(int i = 0; i < argc; i++) { if(!strcmp("-style", argv[i])) { custom_style = true; break; } } #endif qInstallMsgHandler(myMessageOutput); QApplication app(argc, argv); // Q_INIT_RESOURCE(images); #if defined(Q_OS_WIN) if(!custom_style) QApplication::setStyle(new QPlastiqueStyle); #endif qRegisterMetaType ("unsigned long long"); qRegisterMetaType ("QHostAddress"); qRegisterMetaType ("quint8" ); qRegisterMetaType ("quint16"); qRegisterMetaType ("quint32"); qRegisterMetaType ("quint64"); qRegisterMetaType ("QTextCursor"); qRegisterMetaType ("QModelIndex"); qRegisterMetaType ("QTextCharFormat"); qRegisterMetaType("QNetworkAddressEntry"); qRegisterMetaType< QMap >("QMap"); qRegisterMetaType ("AbstractChatCore::DataType"); qRegisterMetaType("QIODevice::OpenMode"); qRegisterMetaType("OpenMode"); qRegisterMetaType("OpenMode"); qRegisterMetaType("UserInfo"); qRegisterMetaType("AbstractChatCore::ChannelType"); QChat chat; chat.start(argc, argv, &app); return app.exec(); } qchat-0.3/src/inputrichtextwgt.h0000644000076500017500000000446310765001404015573 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef INPUTRICHTEXTWGT_H #define INPUTRICHTEXTWGT_H #include #include #include #include #include #include #include "inputtextwgt.h" /** @author Anistratov Oleg */ class InputRichTextWgt : public QWidget { Q_OBJECT private: InputTextWgt* m_inputText; public: InputRichTextWgt(QWidget *parent = 0); ~InputRichTextWgt(); QString toPlainText () const {return m_inputText->toPlainText();} QTextDocument* document() const {return m_inputText->document();} void clear(); void mergeFormat(const QTextCharFormat&); public slots: void changeTextCharMap(){m_inputText->changeTextCharMap();} void sendMsg (){m_inputText->sendMsg();} void append(const QString & str){ m_inputText->append(str);} void setFocus () {m_inputText->setFocus();} void setBold (bool); void setItalic (bool); void setUnderline (bool); void setColor (const QColor&); void setFontFamily(const QString&); void setFontSize (const QString&); void setTextStyle (int); void createTable (uint, uint); signals: void wantSend(); void currentCharFormatChanged(const QTextCharFormat &); }; #endif qchat-0.3/src/message.cpp0000644000076500017500000000423411004401450014102 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "message.h" #include QString getParametr(QString par, QString str); Message::Message(QC_DatagramHeader* Hdr, quint64 src_ip) : m_isIncoming(false) { if(Hdr) { m_version = Hdr->programVersion; m_msg = Hdr->msg; m_userName = Hdr->name; m_compName = Hdr->comp_name; m_srcUid = Hdr->src_ip; m_srcIp = src_ip; m_sendTime = Hdr->tm; m_receiveTime = Hdr->receive_tm; m_type = Hdr->type; m_color = Hdr->color; m_isHtml = Hdr->isHtml; } else { m_version = 0; m_srcUid = 0; m_srcIp = 0; m_sendTime = 0; m_receiveTime = 0; m_color = Qt::black; m_isHtml = 0; } m_requested = false; } Message::~Message() { qDebug("[~Message]"); } void Message::setMsg(const QC_DatagramHeader* Hdr) { m_version = Hdr->programVersion; m_msg = Hdr->msg; m_userName = Hdr->name; m_compName = Hdr->comp_name; m_srcIp = Hdr->src_ip; m_sendTime = Hdr->tm; m_receiveTime = Hdr->receive_tm; m_isHtml = Hdr->isHtml; } qchat-0.3/src/shortcutbutton.h0000644000076500017500000000316410767253166015263 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SHORTCUTBUTTON_H #define SHORTCUTBUTTON_H #include #include #include /** @author Anistratov Oleg */ class ShortcutButton : public QPushButton { Q_OBJECT private: QKeySequence m_sequence; private: int validKey(int); void setShortcutText(QKeyEvent*); public: ShortcutButton(QWidget *parent = 0); ~ShortcutButton(); protected: void keyPressEvent(QKeyEvent*); void keyReleaseEvent(QKeyEvent*); signals: void sequenceAccepted(const QKeySequence&); }; #endif qchat-0.3/src/receiverthread.h0000644000076500017500000000620411002136035015120 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef RECEIVERTHREAD_H #define RECEIVERTHREAD_H #include "globals.h" #include #include #include #include #include class LargeDatagram; /** @author Anistratov Oleg */ class ReceiverThread : public QThread { Q_OBJECT private: bool m_opened; bool m_finished; LargeDatagram** m_datagrams; quint32 m_datagramsNum; quint32 m_datagramsMaxNum; char* m_buffer; quint16 m_bufferSize; QUdpSocket* m_socket; QSocketNotifier* m_socketNotifier; quint32 m_port; private: LargeDatagram* findDatagram (quint64 IP, quint32 ID) const; void removeDatagram(LargeDatagram* dtgrm ); public: ReceiverThread(QObject *parent = 0); ~ReceiverThread(); virtual void run(); quint32 getValidID(quint64 IP) const; LargeDatagram* addDatagram(quint64 IP, quint32 ID); public slots: void receiving(); virtual void changePort(quint16); void deleteDatagram(LargeDatagram* dtgrm); void slot_acceptDatagram(const QString & filename, quint16, quint64); void slot_rejectDatagram(quint16, quint64); virtual int readData(char*, uint); signals: void dataReceived (char*, quint16); void largeDataReceived (LargeDatagram*); void wantFragments (char*, quint32, quint32, quint64); void fragmentsRequest (char* dtgrm, quint32 dtgrm_len); /// resend signal from LargeDatagram void percentsRemain (quint8, quint16, quint64); void percentsConfirmed (quint8, quint16, quint64); void wantReceiveFile (const QString &, quint16, quint64); void readyReceive (quint16, quint64); void receivingAccepted (quint16); void receivingRejected (quint16); void receivingCancelled(quint16); void receivingTimeout (quint16, quint64); void sendingCancelled (quint16, quint64); void openSocketError (quint16 port); void dtgrmFinished (quint16); void portChanged (quint16); }; #endif qchat-0.3/src/qchattrayicon.cpp0000644000076500017500000000243210675721402015344 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchattrayicon.h" QChatTrayIcon::QChatTrayIcon(QIcon icon, QObject *parent) : QSystemTrayIcon(icon, parent) { m_movie = new QMovie(this); connect(m_movie, SIGNAL(frameChanged (int)), this, SLOT(nextFrame())); } qchat-0.3/src/messagefilter.cpp0000644000076500017500000000635711001130557015324 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "messagefilter.h" #include "filtrationrule.h" #include "message.h" MessageFilter::MessageFilter() { } MessageFilter::~MessageFilter() { } bool MessageFilter::isGoodMessage(Message* msg) { foreach(FiltrationRule* fr, m_whiteRules) if(fr->activated() && fr->checkMessage(msg)) return true; return false; } bool MessageFilter::isBadMessage(Message* msg) { foreach(FiltrationRule* fr, m_blackRules) if(fr->activated() && fr->checkMessage(msg)) return true; return false; } bool MessageFilter::validateMessage(Message * msg, bool blacklist) { return (blacklist ? !isBadMessage(msg) : isGoodMessage(msg)); } void MessageFilter::save(QSettings* settings) const { int i = 0; settings->setValue("BlackRulesNumber", m_blackRules.size()); settings->setValue("WhiteRulesNumber", m_whiteRules.size()); settings->beginGroup("BlackRules"); foreach(FiltrationRule* fr, m_blackRules) { settings->beginGroup(QString("Rule%1").arg(i++)); fr->save(settings); settings->endGroup(); } settings->endGroup(); settings->beginGroup("WhiteRules"); foreach(FiltrationRule* fr, m_whiteRules) { settings->beginGroup(QString("Rule%1").arg(i++)); fr->save(settings); settings->endGroup(); } settings->endGroup(); } void MessageFilter::load(QSettings* settings) { int black_rules_num; int white_rules_num; FiltrationRule* fr; black_rules_num = settings->value("BlackRulesNumber").toInt(); white_rules_num = settings->value("WhiteRulesNumber").toInt(); settings->beginGroup("BlackRules"); for(int i = 0; i < black_rules_num; i++) { fr = new FiltrationRule; settings->beginGroup(QString("Rule%1").arg(i)); fr->load(settings); settings->endGroup(); m_blackRules.append(fr); } settings->endGroup(); settings->beginGroup("WhiteRules"); for(int i = 0; i < white_rules_num; i++) { fr = new FiltrationRule; settings->beginGroup(QString("Rule%1").arg(i)); fr->load(settings); settings->endGroup(); m_whiteRules.append(fr); } settings->endGroup(); } void MessageFilter::removeRule(FiltrationRule* rule) { m_whiteRules.removeAll(rule); m_blackRules.removeAll(rule); delete rule; } qchat-0.3/src/pixlabel.cpp0000644000076500017500000001253110766273620014301 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "pixlabel.h" #include #include #include #include #include "picturescrollarea.h" PixLabel::PixLabel(QString label, QWidget* parent) : QLabel(label, parent), m_filename(""), m_lastdir ("/"), m_label (label), m_readOnly(false) { m_pixmap = new QPixmap(); m_menu = new QMenu (this); m_cancelAct = new QAction(this); m_fullSizeAct = new QAction(this); m_fullPicture = new QLabel(0); m_scrollPic = new PictureScrollArea; m_menu->addAction(m_cancelAct); m_menu->addAction(m_fullSizeAct); connect(this , SIGNAL(clicked ( )), this, SLOT(slot_choosePictureDlg())); connect(m_cancelAct , SIGNAL(triggered(bool)), this, SLOT(slot_cancelPicture ())); connect(m_fullSizeAct, SIGNAL(triggered(bool)), this, SLOT(slot_showFullSize ())); setScaledContents (true); setAlignment(Qt::AlignCenter); setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); retranslate(); } void PixLabel::retranslate() { m_cancelAct ->setText(tr("Cancel Picture")); m_fullSizeAct->setText(tr("Full Size")); } //\***************************************************************************** void PixLabel::slot_choosePictureDlg() { if(m_readOnly) return; qDebug("[PixLabel::slot_choosePictureDlg]: Old_Filename = %s", m_filename.toLocal8Bit().data()); QString new_filename; QString image_formats = ""; QList list = QImageReader::supportedImageFormats (); for(int i = 0; i < list.size(); i++) image_formats += QString("*.") + QString().fromUtf8(list[i].data()) + " "; new_filename = QFileDialog::getOpenFileName(this, tr("Choose Picture"), m_lastdir, image_formats, 0, QFileDialog::DontResolveSymlinks); if(!new_filename.isEmpty()) { if(!m_pixmap) { m_pixmap = new QPixmap(); assert(NULL != m_pixmap); } if(m_pixmap->load(new_filename)) { setScaledContents(false); setPixmap(m_pixmap->scaled(width(), height(), Qt::KeepAspectRatio)); m_filename = new_filename; emit changed(); } } if(!new_filename.isEmpty()) m_lastdir = new_filename; qDebug("[PixLabel::slot_choosePictureDlg]: New_Filename = %s", m_filename.toLocal8Bit().data()); } //\***************************************************************************** void PixLabel::freePixmap() { setText(m_label); *m_pixmap = QPixmap(); } //\***************************************************************************** void PixLabel::slot_cancelPicture () { if(!m_readOnly) { m_filename = ""; freePixmap(); emit changed(); } } //\***************************************************************************** void PixLabel::slot_setPixmap(const QPixmap & pix) { if(!m_pixmap) { m_pixmap = new QPixmap(pix); assert(NULL != m_pixmap); } else *m_pixmap = pix; if(m_pixmap->isNull()) { qDebug("[PixLabel::slot_setPixmap]: pixmap is null"); setText(m_label); } else { setScaledContents(false); setPixmap(m_pixmap->scaled(width(), height(), Qt::KeepAspectRatio)); qDebug("[PixLabel::slot_setPixmap]: pixmap is NOT null"); } } //\***************************************************************************** void PixLabel::slot_setPixmap(const QPixmap* pix) { if(pix) { if(!m_pixmap) { m_pixmap = new QPixmap(*pix); assert(NULL != m_pixmap); } else *m_pixmap = *pix; if(m_pixmap->isNull()) setText(m_label); else { setScaledContents(false); setPixmap(m_pixmap->scaled(width(), height(), Qt::KeepAspectRatio)); } } } //\***************************************************************************** void PixLabel::slot_showFullSize () { if(!m_pixmap->isNull()) { m_fullPicture->setWindowTitle(tr("Full Size of Picture")); m_fullPicture->setPixmap(*m_pixmap); m_fullPicture->setScaledContents(true); m_scrollPic->setWidget((QWidget*)m_fullPicture); m_scrollPic->setWidgetResizable(true); // FIXME nado chto-to bolee adekvatnoe, chem +4 :) m_scrollPic->setMaximumWidth (m_pixmap->width() + 4); m_scrollPic->setMaximumHeight(m_pixmap->height() + 4); m_scrollPic->resize(800, 600); m_scrollPic->move(x(), y()); m_scrollPic->show(); } } //\***************************************************************************** qchat-0.3/src/qchaticon.h0000644000076500017500000000331610765264034014116 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHATICON_H #define QCHATICON_H #include #include /** @author Anistratov Oleg */ class QChatIcon { private: static QMap m_icons; static QMap m_iconPaths; private: static void drawPixmap(QPixmap*, const QString & icon_name, const QSize&); public: QChatIcon(); ~QChatIcon(); static void initIcons(); static const QIcon & icon(const QString &); static const QString & iconPath(const QString &); static QPixmap* newPixmap(const QString &, int = -1, int = -1); static QPixmap pixmap (const QString &, int = -1, int = -1); }; #endif qchat-0.3/src/formattingtoolbar.h0000644000076500017500000000503210765003620015667 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef FORMATTINGTOOLBAR_H #define FORMATTINGTOOLBAR_H #include #include #include #include #include #include class ColorPicker; /** @author Anistratov Oleg */ class FormattingToolBar : public QToolBar { Q_OBJECT private: QFontComboBox* m_fontFamilyCmbx; QComboBox* m_fontSizeCmbx; QComboBox* m_textStyleCmbx; QAction* m_setBoldAct; QAction* m_setItalicAct; QAction* m_setUnderlineAct; QAction* m_insertTableAct; ColorPicker* m_colorPicker; QDialog* m_tableSizeDlg; int m_tableRows; int m_tableCols; QLabel* m_enterTableSizeLab; QLabel* m_rowsLab; QLabel* m_colsLab; public: FormattingToolBar(QWidget*); ~FormattingToolBar(); void retranslate(); void setIcons(); private slots: void setTableRows (int val){m_tableRows = val;} void setTableCols (int val){m_tableCols = val;} void createTable(){emit wantCreateTable(m_tableRows, m_tableCols);} public slots: void currentCharFormatChanged(const QTextCharFormat &); signals: void wantSetBold(bool); void wantSetItalic(bool); void wantSetUnderline(bool); void wantSetColor(const QColor&); void wantSetFontFamily(const QString&); void wantSetFontSize(const QString&); void wantSetTextStyle(int); void wantCreateTable(uint, uint); }; #endif qchat-0.3/src/plugin.cpp0000644000076500017500000000402211002644401013752 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "plugin.h" #include "pluginsinterfaces.h" Plugin::Plugin() : m_plugin(NULL), m_type(Basic), m_isLoaded(false) { } Plugin::~Plugin() { } bool Plugin::load() { if(m_plugin->load()) { QChatBasicPlugin* plug = instanceBasic(); if(plug) { plug->load(); m_isLoaded = true; return 1; } else m_plugin->unload(); } return 0; } bool Plugin::unload() { QChatBasicPlugin* plug = instanceBasic(); if(plug) { plug->unload(); delete plug; m_plugin->unload(); m_isLoaded = false; return 1; } return 0; } QObject* Plugin::instance() { return m_plugin->instance(); } QChatWidgetPlugin* Plugin::instanceWgt() { return qobject_cast(m_plugin->instance()); } QChatBasicPlugin* Plugin::instanceBasic() { QChatBasicPlugin* pl = qobject_cast(m_plugin->instance()); if(!pl) pl = qobject_cast(m_plugin->instance()); return pl; } qchat-0.3/src/nlamarok.cpp0000644000076500017500000000711210771514571014303 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "nlamarok.h" #include NLAmarok::NLAmarok(QObject *parent) : QObject (parent), m_updated (false), m_artist (""), m_album (""), m_title (""), m_nRequests(0) { m_processArtist = new QProcess(this); m_processAlbum = new QProcess(this); m_processTitle = new QProcess(this); m_updateTimer = new QTimer (this); connect(m_updateTimer , SIGNAL(timeout()) , this, SLOT(update())); connect(m_processAlbum , SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(updateAlbum(int))); connect(m_processArtist, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(updateArtist(int))); connect(m_processTitle , SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(updateTitle(int))); m_updateTimer->start(5 * 1000); } NLAmarok::~NLAmarok() { qDebug("[~NLAmarok]"); } void NLAmarok::requestArtist() { if(!m_processArtist->pid()) { m_processArtist->start("dcop amarok player artist"); m_nRequests++; } } void NLAmarok::requestAlbum() { if(!m_processAlbum->pid()) { m_processAlbum->start("dcop amarok player album"); m_nRequests++; } } void NLAmarok::requestTitle() { if(!m_processTitle->pid()) { m_processTitle->start("dcop amarok player title"); m_nRequests++; } } void NLAmarok::updateArtist(int code) { if(!code) { QString str; str = QString().fromUtf8(m_processArtist->readAllStandardOutput()); if(str[str.size() - 1] == '\n') str.remove(str.size() - 1, 1); if(str != m_artist) { m_artist = str; m_updated = true; } } m_nRequests--; if(!m_nRequests && m_updated) { emit updated(m_title, m_artist, m_album); m_updated = false; } } void NLAmarok::updateAlbum(int code) { if(!code) { QString str; str = QString().fromUtf8(m_processAlbum->readAllStandardOutput()); if(str[str.size() - 1] == '\n') str.remove(str.size() - 1, 1); if(str != m_album) { m_album = str; m_updated = true; } } m_nRequests--; if(!m_nRequests && m_updated) { emit updated(m_title, m_artist, m_album); m_updated = false; } } void NLAmarok::updateTitle (int code) { if(!code) { QString str; str = QString().fromUtf8(m_processTitle->readAllStandardOutput()); if(str[str.size() - 1] == '\n') str.remove(str.size() - 1, 1); if(str != m_title) { m_title = str; m_updated = true; } } m_nRequests--; if(!m_nRequests && m_updated) { emit updated(m_title, m_artist, m_album); m_updated = false; } } qchat-0.3/src/userinfo.cpp0000644000076500017500000001333310766267636014346 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "userinfo.h" #include "globals.h" #include #include #include #include #include #include UserInfo* UserInfo::m_myInfo = 0; UserInfo::UserInfo(const QHostAddress& addr, const QString & nick, int uid) : m_enabled (0), m_programVerID (0), m_programVerName (""), m_status (Globals::FREE), m_ip (addr.toIPv4Address()), m_compName (""), m_statusDescription(""), m_gender (0), m_nickname (nick), m_avatar (NULL), m_uid (uid) { } UserInfo::UserInfo(QC_DatagramHeader* hdr) : m_enabled (0), m_programVerID (0), m_programVerName (""), m_status (Globals::FREE), m_ip (hdr->src_ip), m_compName (""), m_statusDescription(""), m_gender (0), m_nickname (hdr->name), m_avatar (NULL), m_uid (hdr->src_ip) { } //\***************************************************************************** UserInfo::~UserInfo() { qDebug("[~UserInfo]\n"); } //\***************************************************************************** void UserInfo::setPhoto(const QByteArray & ba) { QCryptographicHash md5_hash(QCryptographicHash::Md5); QFile file; QByteArray hash; md5_hash.addData(ba); hash = md5_hash.result(); m_photoFilename = QDir::tempPath() + "/photo_" + m_nickname; int len = hash.size(); for(int i = 0; i < len; i++) m_photoFilename.append(QString::number((uchar)hash.at(i), 16)); file.setFileName(m_photoFilename); if(file.open(QIODevice::WriteOnly | QIODevice::Unbuffered)) { file.write(ba); file.close(); } else qWarning("[UserInfo::setPhoto]: couldn't open '%s'", m_photoFilename.toLocal8Bit().data()); } //\***************************************************************************** void UserInfo::setPicture(const QByteArray & ba) { QCryptographicHash md5_hash(QCryptographicHash::Md5); QFile file; QByteArray hash; md5_hash.addData(ba); hash = md5_hash.result(); m_pictureFilename = QDir::tempPath() + "/picture_" + m_nickname; int len = hash.size(); for(int i = 0; i < len; i++) m_pictureFilename.append(QString::number((uchar)hash.at(i), 16)); file.setFileName(m_pictureFilename); if(file.open(QIODevice::WriteOnly | QIODevice::Unbuffered)) { file.write(ba); file.close(); } else qWarning("[UserInfo::setPicture]: couldn't open '%s'", m_pictureFilename.toLocal8Bit().data()); } //\***************************************************************************** QPixmap* UserInfo::newIcon(uint wd, uint he, bool disabled) const { QPixmap* pix = NULL; QPixmap* icon = new QPixmap(wd, he); if(!m_pictureFilename.isEmpty()) pix = new QPixmap(m_pictureFilename); else if(!m_photoFilename.isEmpty()) pix = new QPixmap(m_photoFilename); if(pix) { if(disabled) *icon = QIcon(*pix).pixmap(32, 32, QIcon::Disabled); else *icon = pix->scaled(wd, he, Qt::KeepAspectRatio, Qt::SmoothTransformation); delete pix; return icon; } delete icon; return NULL; } //\***************************************************************************** QImage* UserInfo::newIconImg(uint wd, uint he) const { QImage* pix = NULL; QImage* icon = new QImage; m_avatarHash.resize(0); if(!m_pictureFilename.isEmpty()) { pix = new QImage(m_pictureFilename); m_avatarHash = m_pictureHash; } else if(!m_photoFilename.isEmpty()) { pix = new QImage(m_photoFilename); m_avatarHash = m_photoHash; } if(pix) { *icon = pix->scaled(wd, he, Qt::KeepAspectRatio, Qt::SmoothTransformation); delete pix; return icon; } delete icon; return NULL; } //\***************************************************************************** void UserInfo::setPictureOrPhoto(const QString & fname, QString & mmbr_fname, QByteArray & hash) { QFile file; QByteArray ba; QCryptographicHash md5_hash(QCryptographicHash::Md5); if(!fname.isNull()) { mmbr_fname = fname; if(fname.isEmpty()) hash = QByteArray(); else { file.setFileName(mmbr_fname); if(file.open(QIODevice::ReadOnly)) { ba = file.readAll(); md5_hash.addData(ba); hash = md5_hash.result(); } else { qWarning("[UserInfo::setPictureOrPhoto]: couldn't open '%s'", mmbr_fname.toLocal8Bit().data()); hash = QByteArray(); } } } if(!m_pictureFilename.isEmpty()) m_avatarHash = m_pictureHash; else if(!m_photoFilename.isEmpty()) m_avatarHash = m_photoHash; else m_avatarHash.clear(); } qchat-0.3/src/singlemsgshistoryview.cpp0000644000076500017500000001764610777005652017205 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "singlemsgshistoryview.h" #include #include #include #include #include "singlemessage.h" #include "singlemsgshistorymodel.h" #include "qchaticon.h" SingleMsgsHistoryView::SingleMsgsHistoryView(QWidget *parent) : QWidget(parent), m_model(NULL) { QGridLayout* grid = new QGridLayout(this); QGridLayout* btns_grid = new QGridLayout(0); m_treeView = new QTreeView(this); m_layoutCmbx = new QComboBox(this); m_viewFormatLab = new QLabel(this); m_nextNewMessageBtn = new QToolButton(this); m_prevNewMessageBtn = new QToolButton(this); m_nextOpenedMessageBtn = new QToolButton(this); m_prevOpenedMessageBtn = new QToolButton(this); m_closeAllNewMessagesBtn = new QToolButton(this); m_closeAllOpenedMessagesBtn = new QToolButton(this); m_currentCloseChbx = new QCheckBox(this); m_nextNewMessageAct = new QAction(this); m_prevNewMessageAct = new QAction(this); m_nextOpenedMessageAct = new QAction(this); m_prevOpenedMessageAct = new QAction(this); m_closeAllNewMessagesAct = new QAction(this); m_closeAllOpenedMessagesAct = new QAction(this); m_treeView->header()->setClickable(true); m_treeView->header()->setMovable(false); m_treeView->setSortingEnabled(true); grid->addWidget(m_viewFormatLab , 0, 0); grid->addWidget(m_layoutCmbx , 0, 1); grid->addWidget(m_treeView , 1, 0, 1, 3); btns_grid->addWidget(m_currentCloseChbx, 0, 4); btns_grid->addWidget(new QLabel(tr("New Messages :"), this), 0, 0); btns_grid->addWidget(m_prevNewMessageBtn , 0, 1); btns_grid->addWidget(m_nextNewMessageBtn , 0, 2); btns_grid->addWidget(m_closeAllNewMessagesBtn , 0, 3); btns_grid->addWidget(new QLabel(tr("Opened Messages :"), this), 1, 0); btns_grid->addWidget(m_prevOpenedMessageBtn , 1, 1); btns_grid->addWidget(m_nextOpenedMessageBtn , 1, 2); btns_grid->addWidget(m_closeAllOpenedMessagesBtn, 1, 3); btns_grid->setColumnStretch(4, 1); grid->addLayout(btns_grid, 2, 0, 1, 3); grid->setColumnStretch(1, 1); grid->setColumnStretch(2, 1); connect(m_treeView , SIGNAL(doubleClicked(QModelIndex)), this, SIGNAL(doubleClicked(QModelIndex))); connect(m_layoutCmbx, SIGNAL(currentIndexChanged(int)) , this, SLOT (setTreeLayout(int))); connect(m_treeView->header(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)), this, SLOT(sort(int, Qt::SortOrder))); connect(m_nextNewMessageBtn , SIGNAL(clicked()), this, SLOT(nextNewMessage())); connect(m_prevNewMessageBtn , SIGNAL(clicked()), this, SLOT(prevNewMessage())); connect(m_nextOpenedMessageBtn , SIGNAL(clicked()), this, SLOT(nextOpenedMessage())); connect(m_prevOpenedMessageBtn , SIGNAL(clicked()), this, SLOT(prevOpenedMessage())); connect(m_closeAllNewMessagesBtn , SIGNAL(clicked()), this, SLOT(closeAllNewMessages())); connect(m_closeAllOpenedMessagesBtn, SIGNAL(clicked()), this, SLOT(closeAllOpenedMessages())); connect(m_nextNewMessageAct , SIGNAL(triggered(bool)), this, SLOT(nextNewMessage())); connect(m_prevNewMessageAct , SIGNAL(triggered(bool)), this, SLOT(prevNewMessage())); connect(m_nextOpenedMessageAct , SIGNAL(triggered(bool)), this, SLOT(nextOpenedMessage())); connect(m_prevOpenedMessageAct , SIGNAL(triggered(bool)), this, SLOT(prevOpenedMessage())); connect(m_closeAllNewMessagesAct , SIGNAL(triggered(bool)), this, SLOT(closeAllNewMessages())); connect(m_closeAllOpenedMessagesAct, SIGNAL(triggered(bool)), this, SLOT(closeAllOpenedMessages())); resize(800, 600); retranslate(); updateShortcuts(); } SingleMsgsHistoryView::~SingleMsgsHistoryView() { } void SingleMsgsHistoryView::retranslate() { m_layoutCmbx->clear(); m_layoutCmbx->addItem(tr("Direction / IP - Nickname / Date | Message"), SingleMsgsHistoryModel::IpUserDate); m_layoutCmbx->addItem(tr("Direction / Date | IP | Nickname | Message"), SingleMsgsHistoryModel::Date); m_viewFormatLab->setText(tr("View Format:")); m_nextNewMessageBtn ->setText(tr("Next new message")); m_prevNewMessageBtn ->setText(tr("Previous new message")); m_nextOpenedMessageBtn ->setText(tr("Next opened message")); m_prevOpenedMessageBtn ->setText(tr("Previous opened message")); m_closeAllNewMessagesBtn ->setText(tr("Close all new messages")); m_closeAllOpenedMessagesBtn->setText(tr("Close all opened messages")); m_nextNewMessageBtn ->setToolTip(tr("Next new message")); m_prevNewMessageBtn ->setToolTip(tr("Previous new message")); m_nextOpenedMessageBtn ->setToolTip(tr("Next opened message")); m_prevOpenedMessageBtn ->setToolTip(tr("Previous opened message")); m_closeAllNewMessagesBtn ->setToolTip(tr("Close all new messages")); m_closeAllOpenedMessagesBtn->setToolTip(tr("Close all opened messages")); m_currentCloseChbx->setText(tr("Close current message before switching to next")); m_nextNewMessageBtn ->setIcon(QIcon(QChatIcon::icon("go-next"))); m_prevNewMessageBtn ->setIcon(QIcon(QChatIcon::icon("go-previous"))); m_nextOpenedMessageBtn ->setIcon(QIcon(QChatIcon::icon("go-next"))); m_prevOpenedMessageBtn ->setIcon(QIcon(QChatIcon::icon("go-previous"))); m_closeAllNewMessagesBtn ->setIcon(QIcon(QChatIcon::icon("dialog-close"))); m_closeAllOpenedMessagesBtn->setIcon(QIcon(QChatIcon::icon("dialog-close"))); } void SingleMsgsHistoryView::setTreeLayout(int idx) { if(m_model) { m_model->rebuildTree(m_layoutCmbx->itemData(idx).toInt()); m_treeView->expandAll(); m_treeView->resizeColumnToContents(0); m_treeView->resizeColumnToContents(1); m_treeView->resizeColumnToContents(2); m_treeView->resizeColumnToContents(3); m_treeView->header()->setClickable(true); } } void SingleMsgsHistoryView::sort(int column, Qt::SortOrder order) { if(m_model) m_model->sort(column, order); // m_treeView->sortByColumn(column, order); } void SingleMsgsHistoryView::setModel(QAbstractItemModel * model) { m_model = (SingleMsgsHistoryModel*)model; m_treeView->setModel(model); // m_model->rebuildTree(SingleMsgsHistoryModel::IpUserDate); } void SingleMsgsHistoryView::update() { if(m_model) m_model->update(); } void SingleMsgsHistoryView::updateShortcuts() { QChatSettings* prefs = QChatSettings::settings(); m_nextNewMessageAct ->setShortcut(prefs->shortcut("NextNewMessage")); m_prevNewMessageAct ->setShortcut(prefs->shortcut("PrevNewMessage")); m_nextOpenedMessageAct ->setShortcut(prefs->shortcut("NextOpenedMessage")); m_prevOpenedMessageAct ->setShortcut(prefs->shortcut("PrevOpenedMessage")); m_closeAllNewMessagesAct ->setShortcut(prefs->shortcut("CloseAllNewMessages")); m_closeAllOpenedMessagesAct->setShortcut(prefs->shortcut("CloseAllOpenedMessages")); } qchat-0.3/src/singlemessage.cpp0000644000076500017500000000265710773234114015330 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "singlemessage.h" #include "singlemessagewgt.h" SingleMessage::SingleMessage(QC_DatagramHeader* Hdr, quint64 src_ip) : Message(Hdr, src_ip), m_messageWgt(NULL), m_isNew(false) { } SingleMessage::~SingleMessage() { } bool SingleMessage::activate() { if(m_messageWgt) { m_messageWgt->hide(); m_messageWgt->show(); return 1; } return 0; } qchat-0.3/src/userlisticonformat.cpp0000644000076500017500000000615511002123512016414 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "userlisticonformat.h" #include "globals.h" UserListIconFormat::UserListIconFormat(int tw, int th, int sw, int sh, int sx, int sy, int gw, int gh, int gx, int gy, int aw, int ah, int ax, int ay) : m_totalWidth (tw), m_totalHeight (th), m_statusWidth (sw), m_statusHeight (sh), m_statusXoffset(sx), m_statusYoffset(sy), m_genderWidth (gw), m_genderHeight (gh), m_genderXoffset(gx), m_genderYoffset(gy), m_avatarWidth (aw), m_avatarHeight (ah), m_avatarXoffset(ax), m_avatarYoffset(ay), m_text ("%nick") { } UserListIconFormat::~UserListIconFormat() { } QByteArray UserListIconFormat::save() const { QByteArray ba; char size[2]; catUS2str(size, m_text.toUtf8().size()); ba.append(m_totalWidth); ba.append(m_totalHeight); ba.append(m_statusWidth); ba.append(m_statusHeight); ba.append(m_genderWidth); ba.append(m_genderHeight); ba.append(m_statusXoffset); ba.append(m_statusYoffset); ba.append(m_genderXoffset); ba.append(m_genderYoffset); ba.append(m_avatarWidth); ba.append(m_avatarHeight); ba.append(m_avatarXoffset); ba.append(m_avatarYoffset); ba.append(size[0]); ba.append(size[1]); ba.append(m_text.toUtf8()); return ba; } bool UserListIconFormat::restore(const QByteArray & ba) { char sizeArr[2]; int size; if(ba.size() < 14) return false; m_totalWidth = ba[0]; m_totalHeight = ba[1]; m_statusWidth = ba[2]; m_statusHeight = ba[3]; m_genderWidth = ba[4]; m_genderHeight = ba[5]; m_statusXoffset = ba[6]; m_statusYoffset = ba[7]; m_genderXoffset = ba[8]; m_genderYoffset = ba[9]; m_avatarWidth = ba[10]; m_avatarHeight = ba[11]; m_avatarXoffset = ba[12]; m_avatarYoffset = ba[13]; if(ba.size() < 16) return false; sizeArr[0] = ba[14]; sizeArr[1] = ba[15]; size = str2US(sizeArr); if(ba.size() < 16 + size) return false; m_text = QString().fromUtf8(ba.right(size)); return true; } qchat-0.3/src/statuseditwgt.cpp0000644000076500017500000001511010772030714015400 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "statuseditwgt.h" #include "globals.h" #include #include "qchaticon.h" StatusEditWgt::StatusEditWgt(QWidget *parent) : QWidget(parent) { m_grid = new QGridLayout(this); m_editStatusBtn = new QToolButton(this); m_statusEdit = new QLineEdit (this); m_statusCmbx = new QComboBox (this); m_descriptionsMenu = new QMenu(this); m_grid->addWidget(m_editStatusBtn , 0, 0); m_grid->addWidget(m_statusCmbx , 0, 1); m_grid->addWidget(m_statusEdit , 1, 0, 1, 2); m_editStatusBtn->setMenu(m_descriptionsMenu); m_statusCmbx->addItem(QChatIcon::icon("status/user-ready-for-chat"), Globals::StatusStr[Globals::READY4CHAT], Globals::READY4CHAT); m_statusCmbx->addItem(QChatIcon::icon("status/user-online"), Globals::StatusStr[Globals::FREE] , Globals::FREE); m_statusCmbx->addItem(QChatIcon::icon("status/user-busy"), Globals::StatusStr[Globals::BUSY] , Globals::BUSY); m_statusCmbx->addItem(QChatIcon::icon("status/user-dnd"), Globals::StatusStr[Globals::DND] , Globals::DND); m_statusCmbx->addItem(QChatIcon::icon("status/user-away"), Globals::StatusStr[Globals::INACTIVE] , Globals::INACTIVE); m_statusCmbx->addItem(QChatIcon::icon("status/user-away-extended"), Globals::StatusStr[Globals::AWAY] , Globals::AWAY); m_statusCmbx->addItem(QChatIcon::icon("status/user-invisible"), Globals::StatusStr[Globals::INVISIBLE] , Globals::INVISIBLE); m_grid->setMargin(0); m_statusCmbx->setMaximumHeight(25); m_statusCmbx->setCurrentIndex(1); m_statusEdit->setMaximumHeight(25); m_statusEdit->hide(); m_editStatusBtn->setIcon(QChatIcon::icon("im-status-message-edit")); connect(m_statusEdit , SIGNAL(textChanged(QString)) , this, SLOT(slot_setStatusDescription(QString))); connect(m_editStatusBtn, SIGNAL(pressed()) , this, SLOT(slot_editStatusClicked())); connect(m_statusCmbx , SIGNAL(currentIndexChanged(int)), this, SLOT(slot_statusChanged ())); connect(m_descriptionsMenu, SIGNAL(triggered(QAction*)), this, SLOT(setDescription(QAction*))); connect(m_descriptionsMenu, SIGNAL(aboutToHide()) , this, SLOT(changeStatus())); connect(m_statusEdit , SIGNAL(returnPressed()), this, SLOT(hideEditor())); setMaximumHeight(25); retranslate(); } void StatusEditWgt::retranslate() { m_editStatusBtn->setToolTip(tr("Edit status description")); } void StatusEditWgt::slot_statusChanged() { if(status() != Globals::INVISIBLE) m_statusEdit->setText(QChatSettings::settings()->statusDescription(status())); m_statusEdit->setReadOnly(status() == Globals::INVISIBLE); if(!m_statusEdit->isHidden()) m_statusEdit->setText(QChatSettings::settings()->statusDescription(status())); showDescriptionsMenu(); } void StatusEditWgt::showDescriptionsMenu() { m_descriptionsMenu->clear(); m_descriptionsMenu->addAction(tr("New Message..."))->setData(0); m_descriptionsMenu->addAction(tr("Empty Message")) ->setData(1); if(!QChatSettings::settings()->nowListening().isEmpty()) m_descriptionsMenu->addAction(tr("Now Listening")) ->setData(2); QString s = QChatSettings::settings()->statusDescription(status()); if(qobject_cast(sender()) && !s.isEmpty()) m_descriptionsMenu->addAction(tr("Remove Description (%1)").arg(s))->setData(4); m_descriptionsMenu->addSeparator(); foreach(QString s, QChatSettings::settings()->statusDescriptions()) m_descriptionsMenu->addAction(s)->setData(3); emit editing(); if(qobject_cast(sender())) m_descriptionsMenu->popup(QCursor::pos() + QPoint(1, 1)); else m_editStatusBtn->showMenu(); } void StatusEditWgt::setDescription(QAction* act) { switch(act->data().toInt()) { case 0 : m_lastText = QChatSettings::settings()->statusDescription(status()); m_statusEdit->setText(m_lastText); m_statusEdit->show(); m_statusEdit->setFocus(); m_statusEdit->selectAll(); setMaximumHeight(55); setMinimumHeight(55); emit editing(); break; case 1 : QChatSettings::settings()->setStatusDescription("", status()); m_description = ""; emit statusChanged(); break; case 2 : m_lastText = QChatSettings::settings()->nowListening(); m_description = m_lastText; emit statusChanged(); break; case 3 : m_lastText = act->text(); QChatSettings::settings()->setStatusDescription(m_lastText, status()); QChatSettings::settings()->removeStatusDescription(m_lastText); QChatSettings::settings()->appendStatusDescription(m_lastText); m_description = m_lastText; emit statusChanged(); break; case 4 : QChatSettings::settings()->removeStatusDescription(QChatSettings::settings()->statusDescription(status())); if(QChatSettings::settings()->statusDescriptions().size()) m_description = QChatSettings::settings()->statusDescriptions()[0]; else m_description = ""; QChatSettings::settings()->setStatusDescription(m_description, status()); break; } } void StatusEditWgt::hideEditor() { m_statusEdit->hide(); setMaximumHeight(25); setMinimumHeight(25); changeStatus(); } void StatusEditWgt::slot_editStatusClicked() { if(m_statusEdit->isHidden()) showDescriptionsMenu(); else hideEditor(); } void StatusEditWgt::changeStatus() { if(m_lastText != m_statusEdit->text() && !qobject_cast(sender())) QChatSettings::settings()->appendStatusDescription(m_statusEdit->text()); if(m_statusEdit->isHidden()) emit statusChanged(); } qchat-0.3/src/qchatsocket.cpp0000644000076500017500000001210511004410754014772 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchatsocket.h" #include #include "globals.h" #include "userinfo.h" QChatSocket::QChatSocket(QObject* parent, QTcpSocket* soc) : QObject(parent), AbstractChatCore(), m_bufferSize(64 * 1024), m_state(Unconnected), m_fullDtgrmSize(0), m_currentDtgrmSize(0), m_newDtgrmReady(0), m_nickname("") { setProtocolVersion(4); m_buffer = (char*)malloc(m_bufferSize); assert(NULL != m_buffer); m_dtgrm = (char*)malloc(m_bufferSize); assert(NULL != m_dtgrm); if(soc) m_socket = soc; else m_socket = new QTcpSocket(); connect(m_socket, SIGNAL(disconnected()), this, SIGNAL(disconnected())); connect(m_socket, SIGNAL(readyRead()) , this, SLOT(processNewData())); } QChatSocket::~QChatSocket() { qDebug("[~QChatSocket]"); } void QChatSocket::processNewData() { QTcpSocket* socket = qobject_cast(sender()); int dataSize; char* buf; if(socket) { while((dataSize = socket->bytesAvailable())) { // if full new packet was received but didn't read yet if(m_newDtgrmReady) { emit newDtgrm(); continue; } dataSize = socket->read(m_buffer, m_bufferSize); buf = m_buffer; while((buf = appendData(buf, dataSize))) { while(m_newDtgrmReady) { emit newDtgrm(); continue; } } while(m_newDtgrmReady) { emit newDtgrm(); continue; } } } } void QChatSocket::login(const QString& nick, const QString& /*pwd*/) { m_nickname = nick; prepareDatagram(AbstractChatCore::WANT_LOGIN, 0, "Login", UserInfo::myInfo()->compName(), 0, nick); sendData(); } void QChatSocket::sendData() { if(largeDtgrm()) { // quint32 id = m_sender->getValidID(); // if(id) // { // emit wantSendLargeData(header(), headerSize(), data(), dataSize(), addr, ID); // setNULLdataAndHeader(); // } } else if(state() == QAbstractSocket::ConnectedState) { quint16 size = outputBufferSize() <= MAX_PACKET_LEN ? outputBufferSize() : (MAX_PACKET_LEN); // FIXME setPacketSize(outputBufferSize()); int bs = write(outputBuffer(), size); qDebug("[QChatSocket::sendData]: dtgrm size = %d, sent = %d\n", size, bs); } clearParametrs(); } int QChatSocket::readDtgrm(char* dest, int maxSize) { int size = maxSize < m_fullDtgrmSize ? maxSize : m_fullDtgrmSize; if(maxSize < m_fullDtgrmSize) qWarning("[QChatSocket::readDtgrm]: maxSize < m_fullDtgrmSize!!!"); memcpy(dest, m_dtgrm, size); m_currentDtgrmSize = 0; m_fullDtgrmSize = 0; m_newDtgrmReady = false; return size; } /** * * @return pointer to rest of the buffer(which was not processed) or NULL of all data was processed */ char* QChatSocket::appendData(const char* buf, int& size) { char* dtgrm = m_dtgrm + m_currentDtgrmSize; int min_size = protocolLen(); int bytes_write; if((size + m_currentDtgrmSize) < min_size) { m_currentDtgrmSize += size; memcpy(dtgrm, buf, size); size = 0; return NULL; } if(m_currentDtgrmSize < min_size) { int diff = min_size - m_currentDtgrmSize; memcpy(dtgrm, buf, diff); buf += diff; size -= diff; dtgrm += diff; m_currentDtgrmSize = min_size; m_fullDtgrmSize = packetSize(m_dtgrm); if(qstrncmp(m_dtgrm, programId(), programIdLen() - (protocolVersion() < 4 ? 2 : 0)) || protocolVersion(m_dtgrm) != protocolVersion()) { size = 0; m_fullDtgrmSize = 0; m_currentDtgrmSize = 0; return NULL; } } if(m_fullDtgrmSize <= 0) { } bytes_write = (size <= m_fullDtgrmSize - m_currentDtgrmSize) ? size : m_fullDtgrmSize - m_currentDtgrmSize; memcpy(dtgrm, buf, bytes_write); m_currentDtgrmSize += bytes_write; size -= bytes_write; if(m_currentDtgrmSize == m_fullDtgrmSize) { m_newDtgrmReady = true; memcpy(m_dtgrm, AbstractChatCore::programId(), AbstractChatCore::programIdLen()); } if(size) return (char*)(buf + bytes_write); return NULL; } qchat-0.3/src/preferencesdlg.cpp0000755000076500017500000011061011002636461015457 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "preferencesdlg.h" #include "globals.h" #include #include #include #include #include #include #include #include "qchatsettings.h" #include "colorlabel.h" #include "pluginsinterfaces.h" #include "pluginmanager.h" #include "plugin.h" #include "userlisticonconfigurewgt.h" #include "iplisteditor.h" #include "chatcore.h" #include "chatwgt.h" #include "messagefiltereditor.h" PreferencesDlg::PreferencesDlg(QWidget *parent) : QDialog(parent) { m_profileName = ""; m_edited = false; createWidgets(); QVBoxLayout* btns_box = new QVBoxLayout(0); QVBoxLayout* msgs_sect_vbox = new QVBoxLayout(0); QGridLayout* grid = new QGridLayout(this); QGridLayout* colors_grid = new QGridLayout(m_colorsGrbx); QGridLayout* network_grid = new QGridLayout(m_networkGrbx); QGridLayout* misc_grid = new QGridLayout(m_miscGrbx); QGridLayout* nl_grid = new QGridLayout(m_nowListeningGrbx); QGridLayout* smiles_grid = new QGridLayout(m_smilesThemesGrbx); QGridLayout* users_list_grid = new QGridLayout(m_usersListGrbx); QGridLayout* style_sheets_grid = new QGridLayout(m_styleSheetsGrbx); QGridLayout* plugins_grid = new QGridLayout(m_pluginsGrbx); QGridLayout* iconFormat_grid = new QGridLayout(m_iconFormatGrbx); QGridLayout* filtration_grid = new QGridLayout(m_filtrationGrbx); QGridLayout* protocols_grid = new QGridLayout(m_protocolsGrbx); m_iconFormatWgt = new UserListIconConfigureWgt(this, *QChatSettings::settings()->iconFormat()); connect(m_iconFormatWgt, SIGNAL(formatChanged(UserListIconFormat)), this, SIGNAL(formatChanged(UserListIconFormat))); // Setting up group boxes //******************************************** // Colors m_myColor ->setMinimumWidth (100); m_myColor ->setMaximumHeight(25); m_sysColor ->setMinimumWidth (100); m_sysColor ->setMaximumHeight(25); m_baseColor ->setMinimumWidth (100); m_baseColor ->setMaximumHeight(25); m_myColor ->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); m_sysColor ->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); m_baseColor ->setFrameStyle(QFrame::StyledPanel | QFrame::Plain); colors_grid->addWidget(m_myColorLab , 0, 0); colors_grid->addWidget(m_myColor , 0, 1); colors_grid->addWidget(m_sysColorLab , 1, 0); colors_grid->addWidget(m_sysColor , 1, 1); // TODO fully remove baseColor settings m_baseColorLab->hide(); m_baseColor ->hide(); // colors_grid->addWidget(m_baseColorLab , 2, 0); // colors_grid->addWidget(m_baseColor , 2, 1); colors_grid->addWidget(m_colorWholeMsgChbx , 3, 0, 1, 2); colors_grid->addWidget(m_colorWholeSysMsgChbx, 4, 0, 1, 2); colors_grid->setColumnStretch(1, 1); // Network m_portOutSpbx->setMaximum(65535); m_portInSpbx ->setMaximum(65535); m_applyBtn ->setEnabled(false); m_protocolsBgrp->addButton(m_protocolV3Rbtn); m_protocolsBgrp->addButton(m_protocolV4Rbtn); protocols_grid->addWidget(m_protocolV3Rbtn); protocols_grid->addWidget(m_protocolV4Rbtn); network_grid->addWidget(m_networkIfLab , 0, 0); network_grid->addWidget(m_networkIfCmbx, 0, 1); network_grid->addWidget(m_ipLab , 1, 0); network_grid->addWidget(m_ipEdit , 1, 1); network_grid->addWidget(m_broadcastLab , 2, 0); network_grid->addWidget(m_broadcastEdit, 2, 1); network_grid->addWidget(m_portInLab , 3, 0); network_grid->addWidget(m_portInSpbx , 3, 1); network_grid->addWidget(m_portOutLab , 4, 0); network_grid->addWidget(m_portOutSpbx , 4, 1); network_grid->addWidget(m_ipListEditor , 5, 0, 1, 2); network_grid->addWidget(m_useCompressionChbx, 6, 0, 1, 2); network_grid->addWidget(m_protocolsGrbx, 7, 0, 1, 2); network_grid->setRowStretch(5, 1); //Now Listening nl_grid->addWidget(m_nlInStatusChbx); nl_grid->addWidget(m_nlWithMessageChbx); nl_grid->addWidget(m_nlFormatLab); nl_grid->addWidget(m_nlFormatEdit); // Misc misc_grid->addWidget(m_activateOnMsgInChbx, 0, 0); misc_grid->addWidget(m_isCommandOnIncomingChbx , 1, 0); misc_grid->addWidget(m_commandOnIncomingEdit, 2, 0); //Smiles smiles_grid->addWidget(m_smilesThemeChooser , 0, 0, 1, 2); smiles_grid->addWidget(m_smilesPolicyLab , 1, 0); smiles_grid->addWidget(m_smilesPolicyCmbx , 1, 1); smiles_grid->addWidget(m_useAnimatedSmilesChbx, 2, 0, 1, 2); // Users List users_list_grid->addWidget(m_ulRefreshIntervalLab , 0, 0); users_list_grid->addWidget(m_ulRefreshIntervalSpbx , 0, 1); iconFormat_grid->addWidget(m_iconFormatWgt , 0, 0); // users_list_grid->addWidget(m_ulDeepRefreshIntervalLab , 1, 0); // users_list_grid->addWidget(m_ulDeepRefreshIntervalSpbx, 1, 1); // Style Sheets style_sheets_grid->addWidget(m_styleSheetsChooser); // Plugins plugins_grid->addWidget(m_pluginsChooser , 0, 0, 1, 2); plugins_grid->addWidget(m_loadUnloadPluginBtn, 1, 1); plugins_grid->setRowStretch(0, 1); // Filtration filtration_grid->addWidget(m_messageFilterEditor); //******************************************** btns_box->addWidget(m_okBtn ); btns_box->addWidget(m_applyBtn ); btns_box->addWidget(m_cancelBtn ); msgs_sect_vbox->addWidget(m_colorsGrbx); msgs_sect_vbox->addWidget(m_miscGrbx); grid->addWidget(m_sectionsChooser, 0, 0, 2, 1); grid->addWidget(m_sections , 0, 1, 2, 2); grid->addLayout(btns_box , 0, 3); grid->setColumnStretch(1, 1); setupSections(); setupConnections(); retranslate(); resize(400, 200); } //\***************************************************************************** PreferencesDlg::~PreferencesDlg() { qDebug("[~PreferencesDlg]"); } void PreferencesDlg::slot_setMsgColorMode (int mode) {QChatSettings::settings()->setOption("ColorWholeMessage", (mode));} void PreferencesDlg::slot_setSysMsgColorMode(int mode) {QChatSettings::settings()->setOption("ColorWholeSystemMessage", (mode));} void PreferencesDlg::slot_setActivateOnMsgIn(int mode) {QChatSettings::settings()->setOption("ActivateOnMessageIn", (mode));} void PreferencesDlg::slot_setSoundOnMsgIn (int mode) {QChatSettings::settings()->setOption("SoundOnMessageIn", (mode));} void PreferencesDlg::slot_setNlWithMessage (int mode) {QChatSettings::settings()->setNlMode(m_nlInStatusChbx->isChecked() * 2 | (mode == Qt::Checked));} void PreferencesDlg::slot_setNlInStatus (int mode) {QChatSettings::settings()->setNlMode(m_nlWithMessageChbx->isChecked () | (mode == Qt::Checked) * 2);} void PreferencesDlg::slot_setExecuteCommandMode(int mode) { mode = (mode == Qt::Unchecked ? 0 : 1); QChatSettings::settings()->setOption("IsExecuteCommandOnIncomingMessage", (mode)); m_commandOnIncomingEdit->setEnabled(mode); } //\***************************************************************************** void PreferencesDlg::init() { QChatSettings* settings = QChatSettings::settings(); if(!QChatSettings::settings()->boolOption("AllowDifferentPorts")) { m_portOutLab ->hide(); m_portOutSpbx->hide(); m_portInLab->setText(tr("Input/Output Port : ")); connect(m_portInSpbx, SIGNAL(valueChanged(int)), m_portOutSpbx, SLOT(setValue(int))); } else { m_portOutLab ->show(); m_portOutSpbx->show(); m_portInLab->setText(tr("Input Port : ")); disconnect(m_portInSpbx, SIGNAL(valueChanged(int)), m_portOutSpbx, SLOT(setValue(int))); } m_myColor ->setColor(settings->myColor()); m_sysColor ->setColor(settings->sysColor()); m_baseColor->setColor(settings->baseColor()); // CheckBoxes: if(QChatSettings::settings()->boolOption("ColorWholeMessage")) m_colorWholeMsgChbx ->setCheckState(Qt::Checked); else m_colorWholeMsgChbx ->setCheckState(Qt::Unchecked); if(QChatSettings::settings()->boolOption("ColorWholeSystemMessage")) m_colorWholeSysMsgChbx ->setCheckState(Qt::Checked); else m_colorWholeSysMsgChbx ->setCheckState(Qt::Unchecked); slot_setExecuteCommandMode(settings->boolOption("IsExecuteCommandOnIncomingMessage") ? Qt::Checked : Qt::Unchecked); m_isCommandOnIncomingChbx->setCheckState(settings->boolOption("IsExecuteCommandOnIncomingMessage") ? Qt::Checked : Qt::Unchecked); m_useCompressionChbx->setCheckState(QChatSettings::settings()->boolOption("UseCompression") ? Qt::Checked : Qt::Unchecked); m_useAnimatedSmilesChbx->setCheckState(settings->boolOption("UseAnimatedSmiles") ? Qt::Checked : Qt::Unchecked); m_smilesPolicyCmbx->setCurrentIndex((int)settings->smilesPolicy()); // NowListening int mode = settings->nlMode(); if(mode & 1) m_nlWithMessageChbx->setCheckState(Qt::Checked); else m_nlWithMessageChbx->setCheckState(Qt::Unchecked); if(mode & 2) m_nlInStatusChbx->setCheckState(Qt::Checked); else m_nlInStatusChbx->setCheckState(Qt::Unchecked); m_nlFormatEdit->setText(settings->strOption("NLFormat")); m_oldPortIn = settings->intOption("InputPort"); m_portOutSpbx->setValue(settings->intOption("OutputPort")); m_portInSpbx ->setValue(m_oldPortIn); m_ipEdit ->setText (settings->hostAddressOption("IP").toString()); if(settings->boolOption("ActivateOnMessageIn")) m_activateOnMsgInChbx ->setCheckState(Qt::Checked); else m_activateOnMsgInChbx ->setCheckState(Qt::Unchecked); if(settings->boolOption("SoundOnMessageIn")) m_soundOnMsgInChbx ->setCheckState(Qt::Checked); else m_soundOnMsgInChbx ->setCheckState(Qt::Unchecked); //************************* m_broadcastEdit->clear(); QString str = m_ipEdit->text(); QString broadcast = QHostAddress(settings->realBroadcast()).toString(); QStringList list = str.split("."); m_broadcastEdit->setText(broadcast); reloadNetworkIfs(); //************************* m_commandOnIncomingEdit ->setText (settings->executeCommandOnIncomingMsg()); m_displayMsgFmtEdit ->setText (settings->strOption("DisplayMessagesFormat")); m_msgsHistoryIntervalSpbx ->setValue(settings->historyReqTimeout()); m_msgsHistoryNumSpbx ->setValue(settings->nHistoryMsgs()); m_ulRefreshIntervalSpbx ->setValue(settings->usersListRefreshInterval()); m_ulDeepRefreshIntervalSpbx->setValue(settings->usersListDeepRefreshInterval()); m_commandOnIncomingEdit->home(0); m_displayMsgFmtEdit->home(0); m_nlFormatEdit->home(0); m_profileName = QChatSettings::profileName(); m_edited = false; m_applyBtn->setEnabled(false); m_messageFilterEditor->setFilter(settings->messageFilter()); if(settings->intOption("ProtocolVersion") == 3) m_protocolV3Rbtn->setChecked(true); else if(settings->intOption("ProtocolVersion") == 4) m_protocolV4Rbtn->setChecked(true); if(settings->mode() == QChatSettings::Server) { m_protocolV4Rbtn->setEnabled(false); m_protocolV3Rbtn->setEnabled(false); m_protocolV4Rbtn->setChecked(true); } else { m_protocolV4Rbtn->setEnabled(true); m_protocolV3Rbtn->setEnabled(true); } setWindowTitle(tr("Preferences [Profile: ") + m_profileName + "]"); } //\***************************************************************************** void PreferencesDlg::slot_chooseColor() { QColor color = QColorDialog::getColor(((ColorLabel*)sender())->color(), this); if(color.isValid()) { ((ColorLabel*)sender())->setColor(color); edited(); } } //\***************************************************************************** void PreferencesDlg::edited() { m_edited = true; m_applyBtn->setEnabled(true); } //\***************************************************************************** void PreferencesDlg::slot_setPrefs() { int idx; if(QChatSettings::profileName() == m_profileName) { switch(Sections(m_sectionsChooser->currentRow())) { case Network : break; case Messages : break; case Filtration : break; case Smiles : idx = m_smilesThemeChooser->currentRow(); if(idx >= 0) emit wantChangeSmileTheme(m_smilesThemes[idx]); break; case Misc : break; case StyleSheets : idx = m_styleSheetsChooser->currentRow(); if(idx >= 0) emit styleSheetChanged(m_styleSheets[idx]); break; case Plugins : break; case LastSection : break; } QChatSettings::settings()->setMyColor (m_myColor ->color()); QChatSettings::settings()->setSysColor (m_sysColor ->color()); QChatSettings::settings()->setBaseColor(m_baseColor ->color()); QChatSettings::settings()->setOption ("OutputPort", m_portOutSpbx->value()); QString str = ""; if(!m_networkIfCmbx->currentIndex()) { str = m_broadcastEdit->text(); if(!QHostAddress(str).isNull()) QChatSettings::settings()->setOption("CustomBroadcast", str); str = m_ipEdit->text(); if(!QHostAddress(str).isNull()) QChatSettings::settings()->setOption("CustomIP", str); } str = m_broadcastEdit->text(); if(!QHostAddress(str).isNull()) QChatSettings::settings()->setOption("Broadcast", str); str = m_ipEdit->text(); if(!QHostAddress(str).toString().isEmpty()) QChatSettings::settings()->setOption("IP", str); emit ipTextChanged(str); if(QChatSettings::settings()->intOption("InputPort") != (int)m_portInSpbx->value()) emit portChanged(m_portInSpbx->value()); QChatSettings::settings()->setExecuteCommandOnIncomingMsg(m_commandOnIncomingEdit->text()); QChatSettings::settings()->setOption("NLFormat", m_nlFormatEdit->text()); QChatSettings::settings()->setOption("DisplayMessagesFormat", m_displayMsgFmtEdit->text()); QChatSettings::settings()->setHistoryReqTimeout(m_msgsHistoryIntervalSpbx->value()); QChatSettings::settings()->setNHistoryMsgs(m_msgsHistoryNumSpbx->value()); QChatSettings::settings()->setUsersListRefreshInterval(m_ulRefreshIntervalSpbx->value()); QChatSettings::settings()->setUsersListDeepRefreshInterval(m_ulDeepRefreshIntervalSpbx->value()); emit ulRefreshIntervalChanged(m_ulRefreshIntervalSpbx->value()); emit ulDeepRefreshIntervalChanged(m_ulDeepRefreshIntervalSpbx->value()); QChatSettings::settings()->setOption("UseAnimatedSmiles", m_useAnimatedSmilesChbx->checkState() == Qt::Checked); QChatSettings::settings()->setSmilesPolicy(m_smilesPolicyCmbx->currentIndex()); emit useAnimatedSmiles(m_useAnimatedSmilesChbx->checkState() == Qt::Checked); } m_edited = false; m_applyBtn->setEnabled(false); } //\***************************************************************************** void PreferencesDlg::slot_cancel() { m_edited = false; m_applyBtn->setEnabled(false); reject(); } //\***************************************************************************** void PreferencesDlg::slot_validateIp(const QString & str) { if((QHostAddress(str).isNull())) return; edited(); } void PreferencesDlg::retranslate() { m_myColorLab ->setText(tr("Color of My Messages : ")); m_sysColorLab ->setText(tr("Color of System Messages : ")); m_baseColorLab ->setText(tr("Base Color for Messages : ")); m_ipLab ->setText(tr("IP Address : ")); m_broadcastLab ->setText(tr("Broadcast Address : ")); m_nlFormatLab ->setText(tr("Now Listening string : \n(%t - Track, %a - Artist, %b - alBum)")); m_colorsGrbx ->setTitle(tr("&Colors")); m_networkGrbx ->setTitle(tr("&Network")); m_miscGrbx ->setTitle(tr("&Misc")); m_nowListeningGrbx ->setTitle(tr("Now &Listening (from Amarok1)")); m_smilesThemesGrbx ->setTitle(tr("Choose smiles theme:")); m_usersListGrbx ->setTitle(tr("Users List")); m_styleSheetsGrbx ->setTitle(tr("Choose Style Sheet :")); m_pluginsGrbx ->setTitle(tr("Available Plugins :")); m_iconFormatGrbx ->setTitle(tr("Users List Icon Format :")); m_filtrationGrbx ->setTitle(tr("Filtration rules :")); m_protocolsGrbx ->setTitle(tr("Choose protocol version :")); m_okBtn ->setText (tr("&OK")); m_cancelBtn ->setText (tr("&Cancel")); m_applyBtn ->setText (tr("&Apply")); m_colorWholeMsgChbx ->setText (tr("Color Whole Message")); m_colorWholeSysMsgChbx ->setText (tr("Color Whole System Message")); m_activateOnMsgInChbx ->setText (tr("Activate Window on Incomin Messages")); m_soundOnMsgInChbx ->setText (tr("Play Sound on Incomig Messages")); m_nlWithMessageChbx ->setText (tr("Send 'Now Listening' with messages")); m_nlInStatusChbx ->setText (tr("Set 'Now Listening' in status description")); m_portOutLab ->setText (tr("Output Port : ")); m_portInLab ->setText (tr("Input Port : ")); m_profileSection ->setText(tr("Profile")); m_miscSection ->setText(tr("Misc")); m_messagesSection ->setText(tr("Messages")); m_networkSection ->setText(tr("Network")); m_smilesSection ->setText(tr("Smiles")); m_styleSheetsSection ->setText(tr("Style Sheets")); m_pluginsSection ->setText(tr("Plugins")); m_filtrationSection ->setText(tr("Filtration")); m_isCommandOnIncomingChbx ->setText(tr("Execute command on incoming messages :")); m_displayMsgFmtLab ->setText(tr("Messages display format : ")); m_msgsHistoryIntervalLab ->setText(tr("Messages history request interval : ")); m_msgsHistoryNumLab ->setText(tr("Maximum number of messages in history answer : ")); m_ulRefreshIntervalLab ->setText(tr("Refresh Interval : ")); m_ulDeepRefreshIntervalLab->setText(tr("Deep Refresh Interval : ")); m_networkIfLab ->setText(tr("Choose Network Settings :")); m_msgsHistoryIntervalSpbx ->setSuffix(tr(" ms", "milliseconds")); m_ulRefreshIntervalSpbx ->setSuffix(tr(" s", "seconds")); m_ulDeepRefreshIntervalSpbx->setSuffix(tr(" s", "seconds")); m_loadUnloadPluginBtn ->setText(tr("Load Plugin")); m_useCompressionChbx ->setText(tr("Use Compression")); m_useAnimatedSmilesChbx ->setText(tr("Use Animated Smiles")); m_smilesPolicyLab ->setText(tr("Smiles Policy :")); int idx = m_smilesPolicyCmbx->currentIndex(); m_smilesPolicyCmbx->clear(); m_smilesPolicyCmbx->addItem(tr("Don't use Graphic Smiles")); m_smilesPolicyCmbx->addItem(tr("Use only smiles from local theme")); m_smilesPolicyCmbx->addItem(tr("Use smiles from sender")); m_smilesPolicyCmbx->addItem(tr("Always use smiles from sender")); m_smilesPolicyCmbx->setCurrentIndex(idx); m_protocolV3Rbtn->setText(tr("Old protocol")); m_protocolV4Rbtn->setText(tr("New protocol")); setWindowTitle(tr("Preferences")); } void PreferencesDlg::createWidgets() { m_messageFilterEditor = new MessageFilterEditor(this); m_colorsGrbx = new QGroupBox(this); m_networkGrbx = new QGroupBox(this); m_miscGrbx = new QGroupBox(this); m_nowListeningGrbx = new QGroupBox(this); m_smilesThemesGrbx = new QGroupBox(this); m_usersListGrbx = new QGroupBox(this); m_styleSheetsGrbx = new QGroupBox(this); m_pluginsGrbx = new QGroupBox(this); m_iconFormatGrbx = new QGroupBox(this); m_filtrationGrbx = new QGroupBox(this); m_protocolsGrbx = new QGroupBox(this); m_sectionsChooser = new QListWidget(this); m_smilesThemeChooser = new QListWidget(this); m_styleSheetsChooser = new QListWidget(this); m_pluginsChooser = new QListWidget(this); m_networkSection = new QListWidgetItem(); m_messagesSection = new QListWidgetItem(); m_smilesSection = new QListWidgetItem(); m_miscSection = new QListWidgetItem(); m_profileSection = new QListWidgetItem(); m_styleSheetsSection = new QListWidgetItem(); m_pluginsSection = new QListWidgetItem(); m_filtrationSection = new QListWidgetItem(); m_sections = new QStackedWidget(this); m_myColor = new ColorLabel(this, QChatSettings::settings()->myColor()); m_sysColor = new ColorLabel(this, QChatSettings::settings()->sysColor()); m_baseColor = new ColorLabel(this, QChatSettings::settings()->baseColor()); m_okBtn = new QPushButton(this); m_cancelBtn = new QPushButton(this); m_applyBtn = new QPushButton(this); m_ipEdit = new QLineEdit(this); m_broadcastEdit = new QLineEdit(this); m_portOutSpbx = new QSpinBox (this); m_portInSpbx = new QSpinBox (this); m_colorWholeMsgChbx = new QCheckBox(this); m_colorWholeSysMsgChbx = new QCheckBox(this); m_activateOnMsgInChbx = new QCheckBox(this); (m_soundOnMsgInChbx = new QCheckBox(this))->hide(); m_nlWithMessageChbx = new QCheckBox(this); m_nlInStatusChbx = new QCheckBox(this); m_portOutLab = new QLabel(this); m_portInLab = new QLabel(this); m_myColorLab = new QLabel(this); m_sysColorLab = new QLabel(this); m_baseColorLab = new QLabel(this); m_ipLab = new QLabel(this); m_broadcastLab = new QLabel(this); m_nlFormatLab = new QLabel(this); m_displayMsgFmtLab = new QLabel(this); m_msgsHistoryIntervalLab = new QLabel(this); m_msgsHistoryNumLab = new QLabel(this); m_ulRefreshIntervalLab = new QLabel(this); m_ulDeepRefreshIntervalLab = new QLabel(this); m_networkIfLab = new QLabel(this); m_smilesPolicyLab = new QLabel(this); m_commandOnIncomingEdit = new QLineEdit(this); m_isCommandOnIncomingChbx = new QCheckBox(this); m_nlFormatEdit = new QLineEdit(this); m_displayMsgFmtEdit = new QLineEdit(this); m_msgsHistoryIntervalSpbx = new QSpinBox(this); m_msgsHistoryNumSpbx = new QSpinBox(this); m_ulRefreshIntervalSpbx = new QSpinBox(this); m_ulDeepRefreshIntervalSpbx = new QSpinBox(this); m_networkIfCmbx = new QComboBox(this); m_ipListEditor = new IpListEditor(this); m_loadUnloadPluginBtn = new QPushButton(this); m_useCompressionChbx = new QCheckBox(this); m_useAnimatedSmilesChbx = new QCheckBox(this); m_smilesPolicyCmbx = new QComboBox(this); m_protocolsBgrp = new QButtonGroup(this); m_protocolV3Rbtn = new QRadioButton(this); m_protocolV4Rbtn = new QRadioButton(this); m_sectionsChooser->insertItem(Network , m_networkSection); m_sectionsChooser->insertItem(Messages , m_messagesSection); m_sectionsChooser->insertItem(Filtration , m_filtrationSection); m_sectionsChooser->insertItem(Smiles , m_smilesSection); m_sectionsChooser->insertItem(Misc , m_miscSection); m_sectionsChooser->insertItem(StyleSheets, m_styleSheetsSection); m_sectionsChooser->insertItem(Plugins , m_pluginsSection); m_msgsHistoryNumSpbx ->setRange(-1, 100000); m_msgsHistoryIntervalSpbx ->setRange(0, 100000); m_ulRefreshIntervalSpbx ->setRange(0, 100000); m_ulDeepRefreshIntervalSpbx->setRange(0, 100000); } void PreferencesDlg::setupConnections() { connect(m_sectionsChooser, SIGNAL(currentRowChanged(int)), this, SLOT(slot_activateSection(int))); connect(m_myColor , SIGNAL(clicked()), this, SLOT(slot_chooseColor())); connect(m_sysColor , SIGNAL(clicked()), this, SLOT(slot_chooseColor())); connect(m_baseColor, SIGNAL(clicked()), this, SLOT(slot_chooseColor())); connect(m_okBtn , SIGNAL(clicked()), this, SLOT(slot_setPrefs())); connect(m_okBtn , SIGNAL(clicked()), this, SLOT(slot_accept ())); connect(m_applyBtn , SIGNAL(clicked()), this, SLOT(slot_setPrefs())); connect(m_cancelBtn, SIGNAL(clicked()), this, SLOT(slot_cancel ())); connect(m_colorWholeSysMsgChbx, SIGNAL(stateChanged(int)), this, SLOT(slot_setSysMsgColorMode(int))); connect(m_colorWholeMsgChbx , SIGNAL(stateChanged(int)), this, SLOT(slot_setMsgColorMode (int))); connect(m_activateOnMsgInChbx , SIGNAL(stateChanged(int)), this, SLOT(slot_setActivateOnMsgIn(int))); connect(m_soundOnMsgInChbx , SIGNAL(stateChanged(int)), this, SLOT(slot_setSoundOnMsgIn (int))); connect(m_nlInStatusChbx , SIGNAL(stateChanged(int)), this, SLOT(slot_setNlInStatus (int))); connect(m_nlWithMessageChbx , SIGNAL(stateChanged(int)), this, SLOT(slot_setNlWithMessage (int))); connect(m_portInSpbx , SIGNAL(valueChanged(int)), this, SLOT(edited())); connect(m_portOutSpbx , SIGNAL(valueChanged(int)), this, SLOT(edited())); connect(m_msgsHistoryIntervalSpbx , SIGNAL(valueChanged(int)), this, SLOT(edited())); connect(m_msgsHistoryNumSpbx , SIGNAL(valueChanged(int)), this, SLOT(edited())); connect(m_ulRefreshIntervalSpbx , SIGNAL(valueChanged(int)), this, SLOT(edited())); connect(m_ulDeepRefreshIntervalSpbx, SIGNAL(valueChanged(int)), this, SLOT(edited())); connect(m_ipEdit , SIGNAL(textChanged (QString)), this, SLOT(slot_validateIp(QString))); connect(m_broadcastEdit , SIGNAL(textChanged (QString)), this, SLOT(slot_validateIp(QString))); connect(m_commandOnIncomingEdit, SIGNAL(textChanged (QString)), this, SLOT(edited())); connect(m_nlFormatEdit , SIGNAL(textChanged (QString)), this, SLOT(edited())); connect(m_displayMsgFmtEdit , SIGNAL(textChanged (QString)), this, SLOT(edited())); if(!QChatSettings::settings()->boolOption("AllowDifferentPorts")) connect(m_portInSpbx, SIGNAL(valueChanged(int)), m_portOutSpbx, SLOT(setValue(int))); connect(m_networkIfCmbx, SIGNAL(activated(int)), this, SLOT(setNetworkIf(int))); connect(m_isCommandOnIncomingChbx, SIGNAL(stateChanged(int)), this, SLOT(slot_setExecuteCommandMode(int))); connect(m_loadUnloadPluginBtn, SIGNAL(clicked()), this, SLOT(loadOrUnloadPlugin())); connect(m_useCompressionChbx , SIGNAL(stateChanged(int)), this, SLOT(setUseCompression(int))); connect(m_smilesPolicyCmbx , SIGNAL(activated(int)) , this, SLOT(edited())); connect(m_useAnimatedSmilesChbx, SIGNAL(stateChanged(int)), this, SLOT(edited())); connect(m_protocolV3Rbtn, SIGNAL(toggled(bool)), this, SLOT(protocolChanged())); connect(m_protocolV4Rbtn, SIGNAL(toggled(bool)), this, SLOT(protocolChanged())); } void PreferencesDlg::setupSections() { QList list; m_sectionsChooser->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Minimum); m_sectionsChooser->setFixedWidth(150); // Network m_sections->insertWidget(Network, setupSectionLayout(m_networkGrbx)); list.append(m_colorsGrbx); list.append(m_miscGrbx); list.append(m_displayMsgFmtLab); list.append(m_displayMsgFmtEdit); list.append(m_msgsHistoryIntervalLab); list.append(m_msgsHistoryIntervalSpbx); list.append(m_msgsHistoryNumLab); list.append(m_msgsHistoryNumSpbx); // Messages m_sections->insertWidget(Messages, setupSectionLayout(list)); // Filtration m_sections->insertWidget(Filtration, m_filtrationGrbx); // Smiles connect(m_smilesThemeChooser, SIGNAL(currentRowChanged(int)), this, SLOT(edited())); m_sections->insertWidget(Smiles, m_smilesThemesGrbx); // Misc list.clear(); #if defined(Q_OS_LINUX) list.append(m_nowListeningGrbx); #else m_nowListeningGrbx->hide(); #endif list.append(m_usersListGrbx); list.append(m_iconFormatGrbx); m_sections->insertWidget(Misc, setupSectionLayout(list)); // StylesSheets connect(m_styleSheetsChooser, SIGNAL(currentRowChanged(int)), this, SLOT(edited())); m_sections->insertWidget(StyleSheets, m_styleSheetsGrbx); // Plugins m_sections->insertWidget(Plugins, m_pluginsGrbx); connect(m_pluginsChooser, SIGNAL(currentRowChanged(int)), this, SLOT(updatePluginButtons(int))); m_ulDeepRefreshIntervalSpbx->hide(); m_ulDeepRefreshIntervalLab->hide(); } QWidget* PreferencesDlg::setupSectionLayout(QList list) { QWidget* wgt = new QWidget(0); QVBoxLayout* vbox = new QVBoxLayout(wgt); int i; vbox->setMargin(0); for(i = 0; i < list.size(); i++) vbox->addWidget(list[i]); vbox->addStretch(); return wgt; } QWidget* PreferencesDlg::setupSectionLayout(QWidget* w, bool add_stretch) { QWidget* wgt = new QWidget(0); QGridLayout* grid = new QGridLayout(wgt); grid->setMargin(0); grid->addWidget(w, 0, 0); if(add_stretch) grid->setRowStretch(1, 1); return wgt; } void PreferencesDlg::slot_activateSection(int idx) { int idx_; int edited = m_edited; switch(idx) { case Network : reloadNetworkIfs(); m_ipListEditor->init(); break; case Messages : break; case Filtration : m_messageFilterEditor->refresh(); break; case Smiles : reloadSmileThemeList(); if((idx_ = m_smilesThemes.indexOf(QChatSettings::settings()->smilesThemePath())) >= 0) m_smilesThemeChooser->setCurrentRow(idx_); m_edited = edited; m_applyBtn->setEnabled(edited); break; case Misc : break; case StyleSheets : reloadStyleSheetsList(); m_edited = edited; m_applyBtn->setEnabled(edited); break; case Plugins : reloadPluginsList(); break; } m_sections->setCurrentIndex(idx); } void PreferencesDlg::reloadSmileThemeList() { QDir dir(QChatSettings::settings()->settingsDir() + "/smiles"); m_smilesThemes.clear(); m_smilesThemeChooser->clear(); emoticonsThemesFromDir(dir); #if defined(Q_OS_LINUX) dir.setPath(QDir::homePath() + "/.kde/share/emoticons"); emoticonsThemesFromDir(dir); #endif #if defined(Q_OS_LINUX) dir.setPath(QCoreApplication::applicationDirPath()); if(dir.cd("../share/emoticons")) emoticonsThemesFromDir(dir); if(dir.path() != "/usr/share/emoticons" && dir.cd("/usr/share/emoticons")) emoticonsThemesFromDir(dir); #else dir.setPath(QCoreApplication::applicationDirPath() + "/emoticons"); emoticonsThemesFromDir(dir); #endif } void PreferencesDlg::reloadStyleSheetsList() { QDir dir(QChatSettings::settings()->settingsDir() + "/stylesheets"); QFile file; QStringList list; bool ok = 1; m_styleSheets.clear(); m_styleSheetsChooser->clear(); list = dir.entryList(); for(int i = 0; i < list.size(); i++) { if(list[i] == "." || list[i] == ".." || !QFileInfo(dir.absolutePath() + "/" + list[i]).isFile()) continue; m_styleSheetsChooser->addItem(list[i]); m_styleSheets.append(dir.absolutePath() + "/" + list[i]); } #if defined(Q_OS_LINUX) dir.setPath(QCoreApplication::applicationDirPath()); ok = dir.cd("../share/qchat/stylesheets"); #else dir.setPath(QCoreApplication::applicationDirPath() + "/stylesheets"); #endif if(ok) { list = dir.entryList(); for(int i = 0; i < list.size(); i++) { if(list[i] == "." || list[i] == ".." || !QFileInfo(dir.absolutePath() + "/" + list[i]).isFile()) continue; m_styleSheetsChooser->addItem(list[i]); m_styleSheets.append(dir.absolutePath() + "/" + list[i]); } } } void PreferencesDlg::emoticonsThemesFromDir(QDir dir) { QFile file; if(dir.exists()) foreach(QString em_dir, dir.entryList()) { if(em_dir == "." || em_dir == ".." || QFileInfo(dir.absolutePath() + "/" + em_dir).isFile() || !QFile(dir.absolutePath() + "/" + em_dir + "/emoticons.xml").exists()) continue; m_smilesThemeChooser->addItem(em_dir); m_smilesThemes.append(dir.absolutePath() + "/" + em_dir + "/"); } } void PreferencesDlg::reloadNetworkIfs() { QList all_i = QNetworkInterface::allInterfaces(); m_networkIfCmbx->clear(); m_networkIfCmbx->addItem(tr("Custom (not recommended)")); m_addressEntries.clear(); foreach(QNetworkInterface i, all_i) foreach(QNetworkAddressEntry e, i.addressEntries()) { if(e.broadcast().isNull()) continue; m_addressEntries.append(e); m_networkIfCmbx->addItem(i.name()); } for(int i = 0; i < m_addressEntries.size(); i++) if((m_addressEntries[i].ip() == QHostAddress(QChatSettings::settings()->hostAddressOption("IP"))) && (m_addressEntries[i].broadcast() == QChatSettings::settings()->realBroadcast())) { m_networkIfCmbx->setCurrentIndex(i + 1); m_ipEdit ->setEnabled(false); m_broadcastEdit->setEnabled(false); } } void PreferencesDlg::setNetworkIf(int idx) { m_ipEdit ->setEnabled(!idx); m_broadcastEdit->setEnabled(!idx); if(!idx) { m_broadcastEdit->setText(QChatSettings::settings()->hostAddressOption("CustomBroadcast").toString()); m_ipEdit ->setText(QChatSettings::settings()->hostAddressOption("CustomIP").toString()); } else { QNetworkAddressEntry e = m_addressEntries[idx - 1]; m_broadcastEdit->setText(e.broadcast().toString()); m_ipEdit->setText(e.ip().toString()); } } int PreferencesDlg::addSection(QWidget* section, const QString & name) { if(section) { m_sectionsChooser->addItem(name); m_sections ->addWidget(section); return m_sectionsChooser->count() - 1; } return 0; } void PreferencesDlg::setupPluginsSection(QList< QObject * > plugins) { QChatBasicPlugin* plugin; m_pluginsChooser->clear(); foreach(QObject* obj, plugins) { plugin = qobject_cast(obj); if(plugin) m_pluginsChooser->addItem(plugin->name()); } } void PreferencesDlg::setIconFormat(const UserListIconFormat & fmt) { m_iconFormatWgt->setFormat(fmt); } void PreferencesDlg::removeSection(QWidget* section) { int idx; if(section) { if((idx = m_sections->indexOf(section)) >= 0/*LastSection*/) { m_sections->removeWidget(section); delete m_sectionsChooser->takeItem(idx); } } } void PreferencesDlg::reloadPluginsList() { ChatWgt* wgt = qobject_cast(parentWidget()); QListWidgetItem* item; if(wgt) { m_pluginsChooser->clear(); foreach(Plugin* pl, wgt->core()->pluginManager()->plugins()) { item = new QListWidgetItem(pl->name() + (pl->isLoaded() ? tr(" (Loaded)") : tr(" (Not loaded)")), m_pluginsChooser); item->setData(Qt::UserRole, pl->path()); item->setData(Qt::UserRole + 1, pl->isLoaded()); m_pluginsChooser->addItem(item); } } } void PreferencesDlg::updatePluginButtons(int row) { if(row >= 0) { bool loaded = false; QListWidgetItem* item = m_pluginsChooser->currentItem(); if(item) loaded = item->data(Qt::UserRole + 1).toBool(); m_loadUnloadPluginBtn->setText(loaded ? tr("Unload plugin") : tr("Load plugin")); m_loadUnloadPluginBtn->setEnabled(true); } else m_loadUnloadPluginBtn->setEnabled(false); } void PreferencesDlg::loadOrUnloadPlugin() { QListWidgetItem* item = m_pluginsChooser->currentItem(); QString path; bool loaded; if(item) { path = item->data(Qt::UserRole).toString(); loaded = item->data(Qt::UserRole + 1).toBool(); if(loaded) emit wantUnloadPlugin(path); else emit wantLoadPlugin(path); m_loadUnloadPluginBtn->setText(loaded ? tr("Unload plugin") : tr("Load plugin")); reloadPluginsList(); } } void PreferencesDlg::hidePluginsSection() { m_sectionsChooser->takeItem(Plugins); m_sections->removeWidget(m_pluginsGrbx); } void PreferencesDlg::setUseCompression(int state) { QChatSettings::settings()->setOption("UseCompression", (state == Qt::Checked)); } void PreferencesDlg::protocolChanged() { if(sender() == m_protocolV3Rbtn) { m_useCompressionChbx->setEnabled(false); emit wantChangeProtocol(3); } else if(sender() == m_protocolV4Rbtn) { m_useCompressionChbx->setEnabled(true); emit wantChangeProtocol(4); } } qchat-0.3/src/shortcutseditor.h0000644000076500017500000000371610767311056015415 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef SHORTCUTSEDITOR_H #define SHORTCUTSEDITOR_H #include #include #include #include #include #include class ShortcutGrabber; /** @author Anistratov Oleg */ class ShortcutsEditor : public QDialog { Q_OBJECT private: QTreeWidget* m_treeWgt; ShortcutGrabber* m_grabShortcutDlg; QPushButton* m_okBtn; QPushButton* m_cancelBtn; QPushButton* m_defaultsBtn; QPushButton* m_clearShortcutBtn; QMap< QString, QList > m_shortcuts; private: void init(); public: ShortcutsEditor(QWidget *parent = 0); ~ShortcutsEditor(); public slots: void grabShortcutDlg(QTreeWidgetItem*, int); void applyChanges(); void defaults(); void clearCurrentShortcut(); void currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*); }; #endif qchat-0.3/src/chatwgt.h0000644000076500017500000002061511004405050013565 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef CHATWGT_H #define CHATWGT_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "messagewithcheckbox.h" #include "userlisticonformat.h" class LogWgt; class AddChannelDlg; class EditUserInfoDlg; class PreferencesDlg; class ChatCore; class ChannelWgt; class SmilesWgt; class UserWgt; class InputTextWgt; class QChatTrayIcon; class Message; class SingleMsgsHistoryView; class QChatWidgetPlugin; class FormattingToolBar; struct QC_DatagramHeader; #include "userinfo.h" #include "singlemsgshistorymodel.h" /** @author Anistratov Oleg */ class ChatWgt : public QMainWindow { Q_OBJECT friend class ChatCore; private: QLabel* m_profilesLab; QTranslator* m_translator; ChatCore* m_chatCore; QToolButton* m_addChannelBtn; QToolButton* m_delChannelBtn; QComboBox* m_profilesCmbx; QTabWidget* mw_tabs; QToolBar* m_mainToolBar; QToolBar* m_profilesToolBar; QToolBar* m_pluginsToolBar; FormattingToolBar* m_formattingToolBar; QList m_toolbars; QMenuBar* m_menuBar; QMenu* m_menuFile; QMenu* m_menuView; QMenu* m_menuSettings; QMenu* m_menuHelp; QMenu* m_menuTranslations; QMenu* m_menuToolbars; QAction* m_connectToServerAct; QAction* m_disconnectFromServerAct; QAction* m_setServerModeAct; QAction* m_setServerlessModeAct; QAction* m_showSettingsAct; QAction* m_showPreferencesAct; QAction* m_showSmilesAct; QAction* m_showEditShortcutsAct; QAction* m_exitAct; QAction* m_addChannelAct; QAction* m_delChannelAct; QAction* m_aboutAct; QAction* m_aboutQtAct; QAction* m_licenseAct; QAction* m_writeSettingsAct; QAction* m_addProfileAct; QAction* m_deleteProfileAct; QAction* m_renameProfileAct; QAction* m_translatePlAct; QAction* m_translateUkAct; QAction* m_translateRuAct; QAction* m_translateEnAct; QAction* m_translateEsAct; QAction* m_translateDeAct; QAction* m_translateSrAct; QAction* m_showMainTBarAct; QAction* m_showProfilesTBarAct; QAction* m_showPluginsTBarAct; QAction* m_showFormattingTBarAct; QAction* m_showSingleMessagesAct; QAction* m_showPluginsAct; QAction* m_broadcastMessageAct; QAction* m_toolButtonsSizeDefault; QAction* m_toolButtonsSize16; QAction* m_toolButtonsSize24; QAction* m_toolButtonsSize32; QAction* m_toolButtonsSize48; LogWgt* mw_log; SmilesWgt* mw_smiles; QList mw_channels; SingleMsgsHistoryView* m_smhView; AddChannelDlg* m_addChannelDlg; EditUserInfoDlg* m_userInfoDlg; PreferencesDlg* m_preferencesDlg; QChatTrayIcon* m_trayIcon; QTimer* m_activityTimer; int m_cursorX; int m_cursorY; // QList m_widgetPlugins; QList m_allPlugins; QTabWidget* m_pluginsTabs; QStackedWidget* m_widgetsStack; QScrollArea* m_smilesScrllArea; bool m_hidePlugins; QListWidget* m_sectionsWgt; private: void retranslate (); void createActions(); void createWidgets(); void setupLayout (); void updateShortcuts(); void setIcons (); void createChannel(const QString &, quint64 = 0); QMenu* createPopupMenu(); public: ChatWgt(ChatCore* chc, QWidget* parent = 0); ~ChatWgt(); QString currentChannelName() const ; ChannelWgt* findChannel(const QString & name , quint32 = 0) const ; ChannelWgt* findChannel(quint64, quint32 = 0) const ; void fillProfilesCmbx(const QStringList & profiles, const QString & current); const QList channels() const {return mw_channels;} void restoreAndShow(); QChatWidgetPlugin* isPLugin(QWidget*); UserInfo* findUser(quint64); FormattingToolBar* formattingToolBar(){return m_formattingToolBar;} void addToolbar(QToolBar*); ChatCore* core(){return m_chatCore;} void setHidePlugins(bool b){m_hidePlugins = b;} SingleMsgsHistoryView* smhView() const {return m_smhView;} public slots: void setLanguage(); void slot_addChannell (const QString & name){createChannel(name);} void slot_privateChat (const QString & name, quint64 uid){createChannel(name, uid);} void slot_delChannell (); void slot_sendFile (quint64); void slot_receiveFile (const QString &, quint16, quint64); void slot_singleMessageIn(SingleMessage*, bool); void slot_about(); void slot_aboutQt(); void slot_license(); void slot_showSettings(); void slot_showPreferences(); void slot_showUserInfo(UserWgt*); void slot_showSmiles(); void slot_activateWindow(); void slot_insertSmile(const QString &); void slot_openSocketError(quint16); void slot_exit(); void slot_trayIconClicked(QSystemTrayIcon::ActivationReason); void slot_setCurrentProfileName(const QString &); void slot_reloadProfileData (); void slot_editProfileName(); void slot_addProfile (); void slot_delProfile (); void slot_changeSmileTheme(const QString &); void slot_focusChanged(QWidget*, QWidget*); void slot_processData(QC_DatagramHeader*); void activity(); void slot_showSingleMessagesHistory(); void showSingleMessage(const QModelIndex &); void showPlugins(); void pluginSwitched(); void setupPluginToolBar(QWidget*); void connect2server(); void disconnectFromServer(); void disconnectedFromServer(); void chvisConnectToServerAct(); void swapConnectDisconnectAct() { bool vis = m_connectToServerAct->isVisible(); m_disconnectFromServerAct->setVisible(vis); m_connectToServerAct ->setVisible(!vis); } void setToolbarsIconsSize(); void setToolButtonsStyle (); void changeIconFormat(const UserListIconFormat&); void showConfigureShortcuts(); void sendBroadcastMessage(); void loadPlugin(const QString&); void unloadPlugin(const QString&); void setAnimationsRunning(bool); void setMode(); protected: void keyPressEvent(QKeyEvent* ev); void mousePressEvent(QMouseEvent * ev){ QWidget::mousePressEvent(ev);} void closeEvent(QCloseEvent* ev); signals: void singleMessageOut (const QString &, quint64, bool); void singleMessage (const QString &, quint64, bool); void closed (); void wantLoadProfile (const QString &); void wantRenameProfile(const QString &, const QString &); void wantDeleteProfile(const QString &); void wantChangeStyleSheet(const QString &); }; #endif qchat-0.3/src/filtrationrule.cpp0000644000076500017500000001115111001227411015515 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "filtrationrule.h" #include #include #include "message.h" FiltrationRule::FiltrationRule() : m_isRegExp(false), m_activated(true) { } FiltrationRule::~FiltrationRule() { } bool FiltrationRule::checkMessage(Message* msg) { if( (m_packetType.contains(msg->type ()) || m_packetType.isEmpty()) && (m_srcIp .contains(msg->srcIp ()) || m_srcIp .isEmpty()) && (m_srcUid .contains(msg->srcUid ()) || m_srcUid .isEmpty()) && (m_userName .contains(msg->userName()) || m_userName .isEmpty()) && (m_compName .contains(msg->compName()) || m_compName .isEmpty())) { if(m_messageFilter.isEmpty()) if(m_packetType.isEmpty() && m_srcIp .isEmpty() && m_srcUid .isEmpty() && m_userName .isEmpty() && m_compName .isEmpty()) return false; else return true; QStringList words = m_messageFilter.split("\n"); QRegExp rx; if(isRegExp()) { foreach(QString s, words) { rx.setPattern(s); if(msg->msg().contains(rx)) return true; } } else { foreach(QString s, words) if(msg->msg().contains(QRegExp("\\b" + QRegExp().escape(s) + "\\b"))) return true; } } return false; } void FiltrationRule::setUserNames(const QString & str) { if(str.isEmpty()) { m_userName.clear(); return; } QStringList list = str.split("\n"); m_userName.clear(); foreach(QString s, list) if(!m_userName.contains(s)) m_userName.append(s); } void FiltrationRule::setIPs(const QString & str) { if(str.isEmpty()) { m_srcIp.clear(); return; } QStringList list = str.split("\n"); QHostAddress addr; quint64 ip; m_srcIp.clear(); foreach(QString s, list) { addr.setAddress(s); ip = addr.toIPv4Address(); if(ip != 0 && !m_srcIp.contains(ip)) m_srcIp.append(ip); } } void FiltrationRule::setCompNames(const QString & str) { if(str.isEmpty()) { m_compName.clear(); return; } QStringList list = str.split("\n"); m_compName.clear(); foreach(QString s, list) if(!m_compName.contains(s)) m_compName.append(s); } QString FiltrationRule::userNames() const { QString res; foreach(QString s, m_userName) res += s + '\n'; res.remove(res.size() - 1, 1); return res; } QString FiltrationRule::compNames() const { QString res; foreach(QString s, m_compName) res += s + '\n'; res.remove(res.size() - 1, 1); return res; } QString FiltrationRule::IPs() const { QString res; foreach(quint64 ip, m_srcIp) res += QHostAddress(ip).toString() + '\n'; res.remove(res.size() - 1, 1); return res; } void FiltrationRule::save(QSettings* settings) const { settings->setValue("Name" , m_name); settings->setValue("IsRegExp" , m_isRegExp); settings->setValue("Activated" , m_activated); settings->setValue("IPs" , IPs()); settings->setValue("UserNames" , userNames()); settings->setValue("CompNames" , compNames()); settings->setValue("MessageFilter", messageFilter()); } void FiltrationRule::load(QSettings* settings) { setName (settings->value("Name").toString()); setIsRegExp (settings->value("IsRegExp").toBool()); setActivated (settings->value("Activated").toBool()); setIPs (settings->value("IPs").toString()); setUserNames (settings->value("UserNames").toString()); setCompNames (settings->value("CompNames").toString()); setMessageFilter(settings->value("MessageFilter").toString()); } qchat-0.3/src/animatedsmile.cpp0000644000076500017500000000472511004062542015304 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "animatedsmile.h" #include #include #include QMap AnimatedSmile::m_allSmiles; AnimatedSmile::AnimatedSmile(QObject *parent) : QObject(parent), m_smile(NULL), m_document(NULL), m_running(false) { } AnimatedSmile::~AnimatedSmile() { disconnect(m_smile, SIGNAL(frameChanged(int)), this, SLOT(nextFrame())); } void AnimatedSmile::init(int pos, const QString& smile, QTextDocument* doc) { Q_ASSERT(!m_cursor && !m_smile); QFile file(smile); QCryptographicHash hash(QCryptographicHash::Md5); QByteArray result; if(!file.open(QIODevice::ReadOnly)) return; hash.addData(file.readAll()); result = hash.result(); m_smile = m_allSmiles[result]; if(!m_smile) { m_smile = new QMovie(smile); m_allSmiles.insert(result, m_smile); } m_filename = smile; m_document = doc; m_pos = pos; connect(m_smile, SIGNAL(frameChanged(int)), this, SLOT(nextFrame())); } void AnimatedSmile::nextFrame() { if(m_running && m_smile && m_document) { QTextCursor cur(m_document); m_document->addResource(QTextDocument::ImageResource, QUrl(m_filename), m_smile->currentImage()); cur.setPosition(m_pos); cur.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor); cur.insertImage(m_filename); } } void AnimatedSmile::pauseIfHidden(int min, int max) { setPaused(!(m_pos >= min && m_pos <= max)); } qchat-0.3/src/qchat.h0000644000076500017500000000346311002126413013227 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower@users.sourceforge.net * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHAT_H #define QCHAT_H #include #include class ChatWgt; class ChatCore; struct CmdArgs; /** @author Anistratov Oleg */ class QChat : public QObject { Q_OBJECT private: ChatWgt* m_chat; ChatCore* m_core; QApplication* m_app; QString m_styleSheet; private: void unknownOptionMessage(const QString&); void helpMessage(); void welcomeMessage(); void authorMessage(); CmdArgs* processCmdArgs(int argc, char* argv[]); public: QChat(QObject *parent = 0); ~QChat(); void start(int argc, char *argv[], QApplication* app); public slots: void reloadStyleSheet(); void setStyleSheet(const QString &); void hide2tray(); }; #endif qchat-0.3/qchat-server/0000755000076500017500000000000011004570726013601 5ustar owerowerqchat-0.3/qchat-server/qchatserversocket.h0000644000076500017500000000254410757622400017520 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHATSERVERSOCKET_H #define QCHATSERVERSOCKET_H #include "qchatsocket.h" /** @author Anistratov Oleg */ class QChatServerSocket : public QChatSocket { Q_OBJECT public: QChatServerSocket(QObject *parent = 0, QTcpSocket* = 0); ~QChatServerSocket(); }; #endif qchat-0.3/qchat-server/user.cpp0000644000076500017500000000240311002651142015250 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "user.h" #include "globals.h" #include "assert.h" #include "abstractchatcore.h" User::User() : m_socket(NULL), m_uid(0) { m_info = new UserInfo; } User::~User() { // delete m_info; } qchat-0.3/qchat-server/user.h0000644000076500017500000000400511002644473014726 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef USER_H #define USER_H #include #include "userinfo.h" #include "userstatistics.h" #include "qchatserversocket.h" /** @author Anistratov Oleg */ class User { private: QChatServerSocket* m_socket; UserInfo* m_info; UserStatistics* m_stats; QString m_login; uint m_uid; QStringList m_channels; public: User(); ~User(); void setSocket(QChatServerSocket* s){m_socket = s;} const QString & login() const {return m_login;} void setLogin(const QString& l){m_login = l;} void setUid( const uint& theValue ){m_uid = theValue;} uint uid() const {return m_uid;} void addChannel (const QString & ch){if(!m_channels.contains(ch)) m_channels.append(ch);} void removeChannel(const QString & ch){m_channels.removeAll(ch);} const QStringList & channels() const {return m_channels;} UserInfo* info(){return m_info;} }; #endif qchat-0.3/qchat-server/qchatserver.h0000644000076500017500000000577611004406772016317 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #ifndef QCHATSERVER_H #define QCHATSERVER_H #include #include #include #include "user.h" #include "abstractchatcore.h" #include "qchatserversocket.h" class MsgHistory; class Message; /** @author Anistratov Oleg */ class QChatServer : public QObject, public AbstractChatCore { Q_OBJECT private: char* m_buffer; int m_bufferSize; QMap m_users; QTcpServer m_server; QList* m_newConnections; QString m_welcomeMessage; uint m_nextUid; QMap m_channelsHistory; QList m_bannedLogins; QList m_bannedIPs; QChatServerSocket* m_currentSocket; public: QChatServer(QObject *parent = 0); ~QChatServer(); QString checkLogin(const QString &); void canLogin(); uint login(QChatServerSocket*, const QString&); void rejectLogin(QChatServerSocket*, const QString &); int sendData(QChatServerSocket*, uint = 0); void addMessage(const QString& channel, Message* msg); void msgsHistoryAnswer(const QString & ch_name_id, quint64 uid, const QByteArray & msgs, AbstractChatCore::ChannelType type, QChatServerSocket*); void msgsNumAnswer(const QString & ch_name_id, quint64 uid, QChatServerSocket*); void setUserLogin(const QString&); void sendInstruction(const QString&, const QString&); void kickUser (const QString&); void banUser (const QString&); void unbanUser (const QString&); void kickIp (const QString&); void banIp (const QString&); void unbanIp (const QString&); void processInstructions(int); public slots: void processNewConnections(); void processDisconnect(); void processNewData(); }; #endif qchat-0.3/qchat-server/qchat-server.pro0000644000076500017500000000203311004455466016730 0ustar owerowerSOURCES += main.cpp \ qchatserver.cpp \ user.cpp \ ../src/globals.cpp \ qchatserversocket.cpp \ ../src/qchatsocket.cpp \ ../src/userinfo.cpp \ ../src/message.cpp \ ../src/msghistory.cpp \ ../src/abstractprotocol.cpp \ ../src/protocolversion3.cpp \ ../src/protocolversion4.cpp \ ../src/option.cpp \ ../src/abstractchatcore.cpp HEADERS += qchatserver.h \ user.h \ ../src/globals.h \ qchatserversocket.h \ ../src/qchatsocket.h \ ../src/userinfo.h \ ../src/message.h \ ../src/msghistory.h \ ../src/abstractprotocol.h \ ../src/protocolversion3.h \ ../src/protocolversion4.h \ ../src/option.h \ ../src/abstractchatcore.h TEMPLATE = app QT += network DESTDIR = . INCLUDEPATH += ../src TARGET = bin/qchat-server unix { bin.path = /usr/bin/ bin.files = bin/* translations.path = /usr/share/qchatserver/translations translations.files = translations/*.qm INSTALLS += bin translations system(mkdir bin/ 2>/dev/null) system(touch bin/qchat-server) system(chmod 755 bin/qchat-server) } CONFIG -= debug qchat-0.3/qchat-server/qchatserversocket.cpp0000644000076500017500000000246410757622416020063 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchatserversocket.h" QChatServerSocket::QChatServerSocket(QObject *parent, QTcpSocket* sock) : QChatSocket(parent, sock) { // connect(this, SIGNAL(newDtgrm()) , this, SLOT(sendData())); } QChatServerSocket::~QChatServerSocket() { } qchat-0.3/qchat-server/main.cpp0000644000076500017500000001135111004570704015226 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include #include "qchatserver.h" void myMessageOutput(QtMsgType type, const char *msg) { switch (type) { case QtDebugMsg: // fprintf(stdout, "Debug: %s\n", msg); break; case QtWarningMsg: fprintf(stderr, "Warning: %s\n", msg); break; case QtCriticalMsg: fprintf(stderr, "Critical: %s\n", msg); break; case QtFatalMsg: fprintf(stderr, "Fatal: %s\n", msg); } } void printHelp() { printf("QChat Server - server application for lan chat\n"); printf(" Available options:\n"); printf(" --kick kick user with login from the server\n"); printf(" --ban ban user on by login\n"); printf(" --unbun unban user on by login\n"); printf(" --kickip kick user with IP address from the server\n"); printf(" --banip ban user by IP address\n"); printf(" --unbunip unban user by IP address\n"); printf(" --unbunall unban all users by login\n"); printf(" --unbunallip unban all users by IP address\n"); printf(" -h, --help prints this message\n"); } int main(int argc, char *argv[]) { qInstallMsgHandler(myMessageOutput); QCoreApplication app(argc, argv); QStringList kick_users; QStringList ban_users; QStringList unban_users; // QList kick_ips; // QList ban_ips; // QList unban_ips; QStringList kick_ips; QStringList ban_ips; QStringList unban_ips; QHostAddress addr; bool options = false; bool unbunAll = false; bool unbunAllIPs = false; for(int i = 1; i < argc; i++) { if(!strcmp(argv[i], "--kick") && (++i < argc)) { kick_users.append(argv[i]); options = true; } else if(!strcmp(argv[i], "--ban") && (++i < argc)) { ban_users.append(argv[i]); options = true; } else if(!strcmp(argv[i], "--unban") && (++i < argc)) { if(addr.setAddress(argv[i])) { unban_ips.append(argv[i]); options = true; } } else if(!strcmp(argv[i], "--kickip") && (++i < argc)) { if(addr.setAddress(argv[i])) { kick_ips.append(argv[i]); options = true; } } else if(!strcmp(argv[i], "--banip") && (++i < argc)) { if(addr.setAddress(argv[i])) { ban_ips.append(argv[i]); options = true; } } else if(!strcmp(argv[i], "--unbanip") && (++i < argc)) { unban_users.append(argv[i]); options = true; } else if(!strcmp(argv[i], "--unbanall")) { unbunAll = true; options = true; } else if(!strcmp(argv[i], "--unbanallip")) { unbunAllIPs = true; options = true; } else if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { unban_users.append(argv[i]); printHelp(); exit(0); } else { printf("Unknown option: %s\nUse -h for list of available options\n", argv[i]); exit(1); } } QChatServer serv; foreach(QString u, kick_users) serv.sendInstruction(u, "Kick"); foreach(QString u, ban_users) serv.sendInstruction(u, "Ban"); foreach(QString u, unban_users) serv.sendInstruction(u, "Unban"); foreach(QString u, kick_ips) serv.sendInstruction(u, "KickIp"); foreach(QString u, ban_ips) serv.sendInstruction(u, "BanIp"); foreach(QString u, unban_ips) serv.sendInstruction(u, "UnbanIp"); if(unbunAll) serv.sendInstruction("", "UnbanAll"); if(unbunAllIPs) serv.sendInstruction("", "UnbanAllIPs"); if(options) exit(0); app.exec(); } qchat-0.3/qchat-server/qchatserver.cpp0000644000076500017500000003440611004570610016633 0ustar owerower/*************************************************************************** * Copyright (C) 2007 by Anistratov Oleg * * ower86@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 * * as published by the Free Software Foundation; * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * ***************************************************************************/ #include "qchatserver.h" #include "globals.h" #include "assert.h" #include "message.h" #include "msghistory.h" QChatServer::QChatServer(QObject *parent) : QObject (parent), AbstractChatCore(), m_buffer (NULL), m_bufferSize (65535), m_welcomeMessage("Welcome to qchat"), m_nextUid(101) { m_newConnections = new QList; m_buffer = (char*)malloc(m_bufferSize); assert(NULL != m_buffer); if(!m_server.listen(QHostAddress::Any, 61100)) { qWarning("[QChatServer::QChatServer]: could not start listening of incoming connections. Maybe another server is already running."); exit(1); } connect(&m_server, SIGNAL(newConnection()), this, SLOT(processNewConnections())); printf("QChat server version 0.1.1 started\n"); } QChatServer::~QChatServer() { } void QChatServer::processNewConnections() { QChatServerSocket* s; char* buf; while(m_server.hasPendingConnections()) { s = new QChatServerSocket(this, m_server.nextPendingConnection()); if(s->peerAddress() != QHostAddress("127.0.0.1") && m_bannedIPs.contains(s->peerAddress())) { delete s; return; } connect(s, SIGNAL(disconnected()), this, SLOT(processDisconnect())); connect(s, SIGNAL(newDtgrm()) , this, SLOT(processNewData())); buf = (char*)malloc(MAX_PACKET_LEN); assert(NULL != buf); m_newConnections->append(s); } } void QChatServer::processDisconnect() { QChatServerSocket* s = qobject_cast(sender()); User* usr; QString login; if(s) { usr = m_users[s]; if(usr) { login = usr->login(); foreach(QString ch, usr->channels()) { clearParametrs(); addParametr("Channel", ch.toUtf8()); // TODO fill other users data too prepareDatagram(AbstractChatCore::DISCONNECTED, Common, usr->login(), usr->info()->compName(), usr->uid(), "Disconnected"); foreach(QChatServerSocket* soc, m_users.keys()) sendData(soc, usr->uid()); } } printf("%s disconnected\n", QString("%1(%2)").arg(login).arg(s->peerAddress().toString()).toAscii().data()); qDebug("[QChatServer::processDisconnect]: %s disconnected", s->peerAddress().toString().toAscii().data()); delete m_users.take(s); } } void QChatServer::processNewData() { User* user; int dataSize; uint uid; bool loggedIn; QString expectedLogin; char* ip_port; m_currentSocket = qobject_cast(sender()); if(m_currentSocket) { ip_port = QString(m_currentSocket->peerAddress().toString() + ":%1").arg(m_currentSocket->peerPort()).toAscii().data(); qDebug("[QChatServer::processNewData]: New Data from %s", ip_port); loggedIn = m_users.contains(m_currentSocket); dataSize = m_currentSocket->readDtgrm(m_buffer, m_bufferSize); if(dataSize < 0) { qWarning("[QChatServer::processNewData](%s): error while reading from socket", ip_port); return; } if(dataSize < (int)protocolLen()) { qWarning("[QChatServer::processNewData](%s): dataSize < ProtocolLen (%d < %d). Ignoring this packet\n", ip_port, dataSize, AbstractChatCore::protocolLen()); return; } switch(packetType(m_buffer)) { case INSTRUCTION: if(m_currentSocket->peerAddress() == QHostAddress::LocalHost) processInstructions(dataSize); return; } if(!loggedIn) { // if(qstrncmp(m_buffer, programId(), programIdLen() - (protocolVersion() < 4 ? 2 : 0))) // { // qWarning("[QChatServer::processNewData](%s): [ID_ERROR!]. Ignoring this packet\n", ip_port); // return; // } if(packetType(m_buffer) != WANT_LOGIN) { qWarning("[QChatServer::processNewData](%s): Other than WANT_LOGIN packet from not logged in user. Ignoring this packet\n", ip_port); return; } expectedLogin = message(m_buffer, dataSize); setUserLogin(expectedLogin); } else// if(SrcIp(m_buffer) > 1) { // qDebug("[QChatServer::processNewData](%s): data from logged in user(uid=%d)", ip_port, srcIp(m_buffer)); QString nick = userName(m_buffer, dataSize); uint dest_uid = destIp(m_buffer); if(m_users[m_currentSocket]) uid = m_users[m_currentSocket]->uid(); user = m_users[m_currentSocket]; // sending paket only if nickname in this packet corresponds to user's login if(user->login() == nick && uid > 100) { setInputBuffer(m_buffer, dataSize); fillHeader(); QString channel_name = QString().fromUtf8(getParametr("Channel", hdr()->parametrs)); switch(hdr()->type) { case AbstractChatCore::CONNECTED : m_users[m_currentSocket]->addChannel(channel_name); break; case AbstractChatCore::DISCONNECTED : m_users[m_currentSocket]->removeChannel(channel_name); break; case AbstractChatCore::MESSAGE : addMessage(channel_name, new Message(hdr())); break; case AbstractChatCore::MSGS_HISTORY_REQUEST : if(m_channelsHistory.contains(channel_name)) msgsHistoryAnswer(channel_name, hdr()->src_ip, m_channelsHistory[channel_name]->toByteArray(getParametr("MaxMsgsHistorySize", hdr()->parametrs).toLongLong()), (AbstractChatCore::ChannelType)hdr()->chnnl_id, m_currentSocket); return; case AbstractChatCore::MSGS_NUM_REQUEST : if(m_channelsHistory.contains(channel_name)) msgsHistoryAnswer(channel_name, hdr()->src_ip, m_channelsHistory[channel_name]->toByteArray(getParametr("MaxMsgsHistorySize", hdr()->parametrs).toLongLong()), (AbstractChatCore::ChannelType)hdr()->chnnl_id, m_currentSocket); return; } setOutputBuffer(m_buffer, dataSize); // if destination user_id is empty it means msg is broadcast if(dest_uid == 0) { foreach(QChatServerSocket* s, m_users.keys()) sendData(s, uid); } else if(dest_uid == 1) { sendData(m_currentSocket, uid); } else { foreach(QChatServerSocket* s, m_users.keys()) { if(m_users[s]->uid() == dest_uid) { sendData(s, uid); break; } } } } else { // qDebug("[QChatServer::processNewData](%s): !data from logged in user(uid=%d)", ip_port, srcIp(m_buffer)); setInputBuffer(m_buffer, dataSize); fillHeader(); if(hdr()->type == AbstractChatCore::CHANGE_LOGIN) setUserLogin(nick); } } } } QString QChatServer::checkLogin(const QString & login) { if(m_bannedLogins.contains(login)) return tr("This login is banned"); foreach(User* u, m_users.values()) if(login == u->login()) return tr("This login is already in use"); return ""; } int QChatServer::sendData(QChatServerSocket* socket, uint src_uid) { /* if(largeDtgrm()) { quint32 ID = m_sender->getValidID(); if(ID) { emit wantSendLargeData(header(), headerSize(), data(), dataSize(), addr, ID); setNULLdataAndHeader(); } } else */ // FIXME setPacketSize(outputBufferSize()); setSrcIp(outputBuffer(), src_uid); int bs = socket->write(outputBuffer(), outputBufferSize()); socket->flush(); qDebug("[QChatServer::sendData]: dtgrm size = %d, sent = %d\n", outputBufferSize(), bs); return bs; // quint16 size = outputBufferSize() <= MAX_PACKET_LEN ? outputBufferSize() : (MAX_PACKET_LEN); clearParametrs(); } uint QChatServer::login(QChatServerSocket* socket, const QString & lgn) { User* user = new User; user->setSocket(socket); user->setLogin(lgn); user->setUid(m_nextUid++); m_users.insert(socket, user); m_newConnections->removeAll(socket); // strncpy(m_buffer, AbstractChatCore::programId(), programIdLen()); // setInputBuffer(m_buffer, dataSize()); // fillHeader(); user->info()->setCompName(compName(m_buffer, m_bufferSize)); return m_nextUid - 1; } void QChatServer::rejectLogin(QChatServerSocket* socket, const QString & reason) { prepareDatagram(AbstractChatCore::LOGIN_REJECTED, socket->peerAddress().toIPv4Address(), "", "", 0, reason); sendData(socket); } void QChatServer::addMessage(const QString& channel, Message* msg) { MsgHistory* history; if(!m_channelsHistory.contains(channel)) { history = new MsgHistory(); m_channelsHistory.insert(channel, history); } else history = m_channelsHistory[channel]; history->addMsg(msg); } void QChatServer::msgsHistoryAnswer(const QString & ch_name_id, quint64 dest_uid, const QByteArray & msgs, AbstractChatCore::ChannelType type, QChatServerSocket* soc) { addParametr("Channel" , ch_name_id.toUtf8()); addParametr("MsgsHistory", msgs); prepareDatagram(AbstractChatCore::MSGS_NUM_ANSWER, dest_uid, "Server", "Server", 0, "", type, 0, 0); sendData(soc); } void QChatServer::msgsNumAnswer(const QString & ch_name_id, quint64 dest_uid, QChatServerSocket* soc) { addParametr("Channel", ch_name_id.toUtf8()); addParametr("MsgsNum", QString().setNum(quint32(100)).toUtf8()); prepareDatagram(AbstractChatCore::MSGS_HISTORY_ANSWER, dest_uid, "Server", "Server", 0, "", Common, 0, 0); sendData(soc); } void QChatServer::sendInstruction(const QString & user, const QString & instruction) { prepareDatagram(INSTRUCTION, 1, user, "Server", 1, instruction, Common, 0, 0); QChatServerSocket socket; // qDebug("[QChatServer::sendKickUser]: connecting to %s:%d", addr.toString().toAscii().data(), port); socket.connectToHost(QHostAddress::LocalHost, 61100); if(socket.waitForConnected(10000)) sendData(&socket, 1); } void QChatServer::kickUser(const QString & user) { QMapIterator it(m_users); printf("Kicking user %s...\n", user.toLocal8Bit().data()); while(it.hasNext()) { it.next(); if(it.value()->login() == user) { // TODO send message with reason of disconnection it.key()->disconnectFromHost(); printf("%s was kicked\n", user.toLocal8Bit().data()); return; } } printf("%s was not found on this server\n", user.toLocal8Bit().data()); } void QChatServer::processInstructions(int dataSize) { QString user = userName(m_buffer, dataSize); if(destIp(m_buffer) == 1 && srcIp(m_buffer) == 1 && packetType(m_buffer) == INSTRUCTION && compName(m_buffer, dataSize) == "Server") { if(message(m_buffer, dataSize) == "Kick") kickUser(user); else if(message(m_buffer, dataSize) == "Ban") banUser(user); else if(message(m_buffer, dataSize) == "Unban") unbanUser(user); if(message(m_buffer, dataSize) == "KickIp") kickIp(user); else if(message(m_buffer, dataSize) == "BanIp") banIp(user); else if(message(m_buffer, dataSize) == "UnbanIp") unbanIp(user); else if(message(m_buffer, dataSize) == "UnbanAll") m_bannedLogins.clear(); else if(message(m_buffer, dataSize) == "UnbanAllIPs") m_bannedIPs.clear(); } } void QChatServer::banUser(const QString& user) { printf("Banning user %s...\n", user.toLocal8Bit().data()); if(!m_bannedLogins.contains(user)) m_bannedLogins.append(user); kickUser(user); } void QChatServer::unbanUser(const QString& user) { printf("Unbanning user %s...\n", user.toLocal8Bit().data()); m_bannedLogins.removeAll(user); } void QChatServer::kickIp(const QString & ip) { QHostAddress addr; if(addr.setAddress(ip)) foreach(QChatServerSocket* s, m_users.keys()) if(s->peerAddress() == addr) s->disconnectFromHost(); } void QChatServer::banIp(const QString & ip) { QHostAddress addr; if(addr.setAddress(ip)) { if(!m_bannedIPs.contains(addr)) m_bannedIPs.append(addr); kickIp(ip); } } void QChatServer::unbanIp(const QString & ip) { QHostAddress addr; if(addr.setAddress(ip)) m_bannedIPs.removeAll(addr); } void QChatServer::setUserLogin(const QString & expectedLogin) { QString error = checkLogin(expectedLogin); User* user = NULL; int uid = 0; if(m_users.contains(m_currentSocket)) user = m_users[m_currentSocket]; if(expectedLogin.isEmpty()) { rejectLogin(m_currentSocket, "Expected Login is empty"); return; } if(error.isEmpty()) { if(user) { user->setLogin(expectedLogin); uid = user->uid(); } else uid = login(m_currentSocket, expectedLogin); prepareDatagram(AbstractChatCore::LOGIN_ACCEPTED, uid, expectedLogin, "Server", uid, m_welcomeMessage); sendData(m_currentSocket, uid); printf("%s is logged in\n", QString("%1(%2)").arg(expectedLogin).arg(m_currentSocket->peerAddress().toString()).toAscii().data()); } else rejectLogin(m_currentSocket, error); } qchat-0.3/qchat.pro0000644000076500017500000000006311004455054013012 0ustar owerowerTEMPLATE = subdirs SUBDIRS = src \ qchat-server \ qchat-0.3/COPYING0000644000076500017500000004316210704006274012234 0ustar owerower 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. qchat-0.3/README0000644000076500017500000000167111004457032012054 0ustar owerowerQChat - crossplatform network chat Copyright (C) 2007-2008 by Anistratov Oleg ******** REQUIREMENTS ******** Qt 4.3 is required ******** INSTALLATION ******** qmake && make && make install ******** SMILES ******** You need copy directories with smiles in $HOME/.qchat/smiles. QChat supports Kopete's format of smiles. On linux except ~/.qchat/smiles qchat also trying to find smiles in ~/.kde/share/emoticons and /usr/share/emoticons. On Windows you need to copy smiles to ~/.qchat/smiles or emoticons/ subdir in directory where you installed QChat. Additional smiles could be downloaded from www.kde-look.org. ******** TRANSLATIONS ******** Available Ukrainian, Russian, Polish, Spanish, German and Serbian translations. If you want translate QChat into different language and do not know how - please contact me via email. ******** ICONS ******** Icons used in QChat was taken from Oxygen icon theme.